Python实现向好友发送微信消息优化篇
作者:Qwertyuiop2016 发布时间:2022-02-18 18:07:08
前言
之前说了怎么写机器码到内存,然后调用。现在说说怎么优化。
用Python发送微信消息给好友
第二次优化
再看一遍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)
来源:https://blog.csdn.net/Qwertyuiop2016/article/details/125153276


猜你喜欢
- 便携文档格式 (PDF) 是由 Adobe 开发的格式,主要用于呈现可打印的文档,其中包含有 pixel-perfect 格式,嵌入字体以及
- 最近在开发项目的过程中遇到一个问题,就是在插入一条记录的后要立即获取所在数据库中ID,而该ID是自增的,怎么做?在sql server 20
- 智能聊天一、 概述我们将我们的qq聊天机器人的环境配置好后,其就可以开始接收消息啦!那么,我们除了可以接收特定的消息,是不是还需要接收那些不
- Pycharm代码运行调试,具体内容如下1、准备工作(1)Python版本为2.7或者更高版本(2)已经创建了一个Python工程并且添加了
- Python中使用threading.Condition交替打印两个字符的程序。这个程序涉及到两个线程的的协调问题,两个线程为了能够相互协调
- 暴力的重启服务方案一般服务器重启可以直接通过 kill 命令杀死进程,然后重新启动一个新的进程即可。但这种方法比较粗暴,有可能导致某些正在处
- 方法一:需要在网络条件下安装win+R进入运行框输入命令cmd点击确定进入普通下载:pip install 模块名字例如:输入pi
- #!/bin/sh#code by scpman#功能:检查并修复mysql数据库表#将此脚本加到定时中,脚本执行时,等会读库,列出要修复的
- 本文简介前段时间,黄同学写了一篇《MySQL窗口实战》文章(文章如下),但是里面大多数是以实战练习为主,没有做详细的解释。传送门:MySQL
- 我们到目前为止所谈到的SQL语句相对较为简单,如果再能通过标准的recordset循环查询,那么这些语句也能满足一些更复杂的要求。不过,何必
- 本demo的效果是单选框一有a和b两个选项按钮,单选框二有q和w两个选项按钮,选中a,使得q不可选,w选中;选中b,使得w不可选,q选中下面
- Flask是一个Python编写的Web 微框架,让我们可以使用Python语言快速实现一个网站或Web服务。本文参考自Flask官方文档,
- Pyinstaller库简介:简单来说,就是直接将python语言编写的py程序打包为exe可执行文件,对方不需要安装python环境即可直
- 代码代码很简单,主要是为了熟悉Selenium这个库的函数,为后续的短信轰炸做个铺垫from selenium import webdriv
- 前言orztop是一款实时show full processlist的工具,我们可以实时看到数据库有哪些线程,执行哪些语句等。工具使用方便简
- 我们来使用background 插入flash播放器播放音乐刚刚乱试一翻搞出这个,有意思吗?请在IE6下测试运行代码框<!DOCTYP
- 今天,由于工作需要,我在自己的电脑上配置了Mysql5环境,同时安装了一个phpMyAdmin管理工具,安装完成后,发现在phpMyAdmi
- 前言在项目正式上线之前,我们通常需要通过压测来评估当前系统能够支撑的请求量、排查可能存在的隐藏bug,同时了解了程序的实际处理能力能够帮我们
- 1.前言我在进行DEM数据的裁剪时,发现各个省的数据量非常大,比如说四川省的30m的DEM数据的大小为2G。考虑到有限的电脑磁盘空间,我对T
- 本文实例讲述了python类继承用法。分享给大家供大家参考。具体方法如下:#!/usr/bin/python# Filename: inhe