Python實(shí)現(xiàn)向好友發(fā)送微信消息優(yōu)化篇
前言
之前說了怎么寫機(jī)器碼到內(nèi)存,然后調(diào)用?,F(xiàn)在說說怎么優(yōu)化。
第二次優(yōu)化
再看一遍c語言的代碼
void SendText( wchar_t* wsTextMsg) {
// 發(fā)送的好友,filehelper是文件傳輸助手
wchar_t wsWxId[0x10] = L"filehelper";
WxBaseStruct wxWxid(wsWxId);
// 發(fā)送的消息內(nèi)容
WxBaseStruct wxTextMsg(wsTextMsg);
wchar_t** pWxmsg = &wxTextMsg.buffer;
char buffer[0x3B0] = { 0 };
char wxNull[0x100] = { 0 };
DWORD dllBaseAddress = (DWORD)GetModuleHandleA("WeChatWin.dll");
// 發(fā)消息的函數(shù)call地址
DWORD callAddress = dllBaseAddress + 0x521D30;
__asm {
lea eax, wxNull;
push 0x1;
push eax;
mov edi, pWxmsg;
push edi;
lea edx, wxWxid;
lea ecx, buffer;
call callAddress;
add esp, 0xC;
}
}上面的代碼真正發(fā)消息的是asm里面的代碼,之前的c代碼都是在組裝內(nèi)存數(shù)據(jù)。那我們是不是可以用Python組裝數(shù)據(jù),只講下面的匯編轉(zhuǎn)為機(jī)器碼寫入內(nèi)存調(diào)用,這樣就少了很多無用的機(jī)器碼。
改完的SendText函數(shù)如下
wchar_t wsWxId[0x10] = L"filehelper";
wchar_t wsTextMsg[0x100] = L"test";
WxBaseStruct wxWxid(wsWxId);
WxBaseStruct wxTextMsg(wsTextMsg);
wchar_t** pWxmsg = &wxTextMsg.buffer;
char buffer[0x3B0] = { 0 };
char wxNull[0x100] = { 0 };
DWORD dllBaseAddress = (DWORD)GetModuleHandleA("WeChatWin.dll");;
DWORD callAddress = dllBaseAddress + 0x521D30;
void SendText() {
__asm {
lea eax, wxNull;
push 0x1;
push eax;
mov edi, pWxmsg;
push edi;
lea edx, wxWxid;
lea ecx, buffer;
call callAddress;
add esp, 0xC;
}
}
匯編代碼:

[]里面包含的類型和變量名其實(shí)就是地址,只需要將地址改成用Python構(gòu)造的地址就可以了
完整代碼如下:
import os
import pymem
import ctypes
import time
def convert_addr(addr):
if isinstance(addr, int):
addr = hex(addr)
if addr.startswith("0x") or addr.startswith("0X"):
addr = addr[2:]
if len(addr) < 8:
addr = (8-len(addr))*'0' + addr
tmp = []
for i in range(0, 8, 2):
tmp.append(addr[i:i+2])
tmp.reverse()
return ''.join(tmp)
def WxBaseStruct(process_handle, content):
struct_address = pymem.memory.allocate_memory(process_handle, 20)
bcontent = content.encode('utf-16le')
content_address = pymem.memory.allocate_memory(process_handle, len(bcontent)+16)
pymem.ressources.kernel32.WriteProcessMemory(process_handle, content_address, bcontent, len(bcontent), None)
pymem.memory.write_int(process_handle, struct_address, content_address)
pymem.memory.write_int(process_handle, struct_address+0x4, len(content))
pymem.memory.write_int(process_handle, struct_address+0x8, len(content)*2)
pymem.memory.write_int(process_handle, struct_address+0xC, 0)
pymem.memory.write_int(process_handle, struct_address+0x10, 0)
return struct_address, content_address
def start_thread(process_handle, address, params=None):
params = params or 0
NULL_SECURITY_ATTRIBUTES = ctypes.cast(0, pymem.ressources.structure.LPSECURITY_ATTRIBUTES)
thread_h = pymem.ressources.kernel32.CreateRemoteThread(
process_handle,
NULL_SECURITY_ATTRIBUTES,
0,
address,
params,
0,
ctypes.byref(ctypes.c_ulong(0))
)
last_error = ctypes.windll.kernel32.GetLastError()
if last_error:
pymem.logger.warning('Got an error in start thread, code: %s' % last_error)
pymem.ressources.kernel32.WaitForSingleObject(thread_h, -1)
return thread_h
def main(wxpid, wxid, msg):
process_handle = pymem.process.open(wxpid)
wxNull_address = pymem.memory.allocate_memory(process_handle, 0x100)
buffer_address = pymem.memory.allocate_memory(process_handle, 0x3B0)
wxid_struct_address, wxid_address = WxBaseStruct(process_handle, wxid)
msg_struct_address, msg_address = WxBaseStruct(process_handle, msg)
process_WeChatWin_handle = pymem.process.module_from_name(process_handle, "WeChatWin.dll")
call_address = process_WeChatWin_handle.lpBaseOfDll + 0x521D30
call_p_address = pymem.memory.allocate_memory(process_handle, 4)
pymem.memory.write_int(process_handle, call_p_address, call_address)
format_code = '''
57
8D05 {wxNull}
6A 01
50
8D3D {wxTextMsg}
57
8D15 {wxWxid}
8D0D {buffer}
FF15 {callAddress}
83C4 0C
5F
C3
'''
shellcode = format_code.format(wxNull=convert_addr(wxNull_address),
wxTextMsg=convert_addr(msg_struct_address),
wxWxid=convert_addr(wxid_struct_address),
buffer=convert_addr(buffer_address),
callAddress=convert_addr(call_p_address))
shellcode = bytes.fromhex(shellcode.replace(' ', '').replace('\n', ''))
shellcode_address = pymem.memory.allocate_memory(process_handle, len(shellcode)+5)
pymem.ressources.kernel32.WriteProcessMemory(process_handle, shellcode_address, shellcode, len(shellcode), None)
thread_h = start_thread(process_handle, shellcode_address)
time.sleep(0.5)
pymem.memory.free_memory(process_handle, wxNull_address)
pymem.memory.free_memory(process_handle, buffer_address)
pymem.memory.free_memory(process_handle, wxid_struct_address)
pymem.memory.free_memory(process_handle, wxid_address)
pymem.memory.free_memory(process_handle, msg_struct_address)
pymem.memory.free_memory(process_handle, msg_address)
pymem.memory.free_memory(process_handle, call_p_address)
pymem.memory.free_memory(process_handle, shellcode_address)
pymem.process.close_handle(process_handle)
if __name__ == "__main__":
wxpid = 16892
wxid = "filehelper"
msg = "python test"
main(wxpid, wxid, msg)第三次優(yōu)化
直接在Python里寫匯編,然后自動(dòng)轉(zhuǎn)機(jī)器碼寫入內(nèi)存。使用的是Python的keystone庫
# -*- coding: utf-8 -*-
import os
import pymem
import ctypes
import time
from keystone import Ks, KS_ARCH_X86, KS_MODE_32
def asm2code(asm_code, syntax=0):
ks = Ks(KS_ARCH_X86, KS_MODE_32)
bytes_code, _ = ks.asm(asm_code, as_bytes=True)
return bytes_code
def WxBaseStruct(process_handle, content):
struct_address = pymem.memory.allocate_memory(process_handle, 20)
bcontent = content.encode('utf-16le')
content_address = pymem.memory.allocate_memory(process_handle, len(bcontent)+16)
pymem.ressources.kernel32.WriteProcessMemory(process_handle, content_address, bcontent, len(bcontent), None)
pymem.memory.write_int(process_handle, struct_address, content_address)
pymem.memory.write_int(process_handle, struct_address+0x4, len(content))
pymem.memory.write_int(process_handle, struct_address+0x8, len(content)*2)
pymem.memory.write_int(process_handle, struct_address+0xC, 0)
pymem.memory.write_int(process_handle, struct_address+0x10, 0)
return struct_address, content_address
def start_thread(process_handle, address, params=None):
params = params or 0
NULL_SECURITY_ATTRIBUTES = ctypes.cast(0, pymem.ressources.structure.LPSECURITY_ATTRIBUTES)
thread_h = pymem.ressources.kernel32.CreateRemoteThread(
process_handle,
NULL_SECURITY_ATTRIBUTES,
0,
address,
params,
0,
ctypes.byref(ctypes.c_ulong(0))
)
last_error = ctypes.windll.kernel32.GetLastError()
if last_error:
pymem.logger.warning('Got an error in start thread, code: %s' % last_error)
pymem.ressources.kernel32.WaitForSingleObject(thread_h, -1)
return thread_h
def main(wxpid, wxid, msg):
process_handle = pymem.process.open(wxpid)
wxNull_address = pymem.memory.allocate_memory(process_handle, 0x100)
buffer_address = pymem.memory.allocate_memory(process_handle, 0x3B0)
wxid_struct_address, wxid_address = WxBaseStruct(process_handle, wxid)
msg_struct_address, msg_address = WxBaseStruct(process_handle, msg)
process_WeChatWin_handle = pymem.process.module_from_name(process_handle, "WeChatWin.dll")
call_address = process_WeChatWin_handle.lpBaseOfDll + 0x521D30
call_p_address = pymem.memory.allocate_memory(process_handle, 4)
pymem.memory.write_int(process_handle, call_p_address, call_address)
format_asm_code = '''
push edi;
lea eax,dword ptr ds:[{wxNull:#02x}];
push 0x1;
push eax;
lea edi,dword ptr ds:[{wxTextMsg:#02x}];
push edi;
lea edx,dword ptr ds:[{wxWxid:#02x}];
lea ecx,dword ptr ds:[{buffer:#02x}];
call dword ptr ds:[{callAddress:#02x}];
add esp, 0xC;
pop edi;
ret;
'''
asm_code = format_asm_code.format(wxNull=wxNull_address,
wxTextMsg=msg_struct_address,
wxWxid=wxid_struct_address,
buffer=buffer_address,
callAddress=call_p_address)
shellcode = asm2code(asm_code.encode())
shellcode_address = pymem.memory.allocate_memory(process_handle, len(shellcode)+5)
pymem.ressources.kernel32.WriteProcessMemory(process_handle, shellcode_address, shellcode, len(shellcode), None)
thread_h = start_thread(process_handle, shellcode_address)
time.sleep(0.5)
pymem.memory.free_memory(process_handle, wxNull_address)
pymem.memory.free_memory(process_handle, buffer_address)
pymem.memory.free_memory(process_handle, wxid_struct_address)
pymem.memory.free_memory(process_handle, wxid_address)
pymem.memory.free_memory(process_handle, msg_struct_address)
pymem.memory.free_memory(process_handle, msg_address)
pymem.memory.free_memory(process_handle, call_p_address)
pymem.memory.free_memory(process_handle, shellcode_address)
pymem.process.close_handle(process_handle)
if __name__ == "__main__":
wxpid = 18604
wxid = "filehelper"
msg = "python test msg"
main(wxpid, wxid, msg)到此這篇關(guān)于Python實(shí)現(xiàn)向好友發(fā)送微信消息優(yōu)化篇的文章就介紹到這了,更多相關(guān)Python微信消息內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python實(shí)現(xiàn)aes加密及pycryptodome庫使用
AES算法是高級(jí)加密標(biāo)準(zhǔn),它是一種對(duì)稱加密算法,AES只有一個(gè)密鑰,這個(gè)密鑰既用來加密,也用于解密,這篇文章主要給大家介紹了關(guān)于python實(shí)現(xiàn)aes加密及pycryptodome庫使用的相關(guān)資料,需要的朋友可以參考下2023-10-10
Python實(shí)現(xiàn)PS圖像調(diào)整黑白效果示例
這篇文章主要介紹了Python實(shí)現(xiàn)PS圖像調(diào)整黑白效果,結(jié)合實(shí)例形式分析了Python實(shí)現(xiàn)PS圖像的黑白效果原理與相關(guān)操作技巧,需要的朋友可以參考下2018-01-01
對(duì)Python 簡(jiǎn)單串口收發(fā)GUI界面的實(shí)例詳解
今天小編就為大家分享一篇對(duì)Python 簡(jiǎn)單串口收發(fā)GUI界面的實(shí)例詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-06-06
完美解決Python 2.7不能正常使用pip install的問題
今天小編就為大家分享一篇完美解決Python 2.7不能正常使用pip install的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-06-06
PyTorch之torch.randn()如何創(chuàng)建正態(tài)分布隨機(jī)數(shù)
這篇文章主要介紹了PyTorch之torch.randn()如何創(chuàng)建正態(tài)分布隨機(jī)數(shù)問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-02-02
Django創(chuàng)建一個(gè)后臺(tái)的基本步驟記錄
這篇文章主要給大家介紹了關(guān)于Django創(chuàng)建一個(gè)后臺(tái)的基本步驟,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-10-10

