Python微信消息
Qwertyuiop2016 人气:0前言
之前说了怎么写机器码到内存,然后调用。现在说说怎么优化。
第二次优化
再看一遍c语言的代码
void SendText( wchar_t* wsTextMsg) { // 发送的好友,filehelper是文件传输助手 wchar_t wsWxId[0x10] = L"filehelper"; 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"); // 发消息的函数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; } }
上面的代码真正发消息的是asm里面的代码,之前的c代码都是在组装内存数据。那我们是不是可以用Python组装数据,只讲下面的汇编转为机器码写入内存调用,这样就少了很多无用的机器码。
改完的SendText函数如下
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;
}
}
汇编代码:
[]里面包含的类型和变量名其实就是地址,只需要将地址改成用Python构造的地址就可以了
完整代码如下:
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)
第三次优化
直接在Python里写汇编,然后自动转机器码写入内存。使用的是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)
加载全部内容