整体的方法主要是修改WeChatWin.dll这个模块的内存 由于微信版本的迭代,WeChatWin.dll这个版本的偏移会有变化当前我测试的3.9.0.28如下 0x2E2E354,0x2E6E7C4,0x2E50314,0x2E50FE4,0x2E6B39C,0x2E6FD6C
| Version键值 | 微信版本 | 关键地址 |
|---|---|---|
| 63090c37 | 3.9.12.55 | Text |
| 6309001c | 3.9.0.28 | WeChatWin.dll+2E50FE4 |
上面的键值可以在注册表中找到

用下面脚本会找到Wechat.exe的pid,然后列出WeChatWin的基地址,最后写入,我是将所有关键偏移都写成了微信3.9.12.55版本的Version键值(这个可以在注册表中看到),然后登入后就是显示的3.9.12.55,实际我安装的是3.9.0.28,之后可以愉快的测试漏洞了(ps下面的偏移不同版本需要修改,可以在CE中找到的,搜索内存中的键值就可以了)
import ctypes
import struct
import psutil
import win32api
import win32con
LIST_MODULES_ALL = 0x03
def get_wechat_pid():
for proc in psutil.process_iter(['pid', 'name']):
if proc.info['name'] and proc.info['name'].lower() == 'wechat.exe':
return proc.info['pid']
raise Exception("WeChat.exe not found.")
def get_module_base_address(pid, dll_keyword):
h_process = win32api.OpenProcess(win32con.PROCESS_ALL_ACCESS, False, pid)
EnumProcessModulesEx = ctypes.windll.psapi.EnumProcessModulesEx
GetModuleFileNameExW = ctypes.windll.psapi.GetModuleFileNameExW
EnumProcessModulesEx.restype = ctypes.c_bool
module_handles = (ctypes.c_void_p * 1024)()
needed = ctypes.c_ulong()
if not EnumProcessModulesEx(h_process.handle, ctypes.byref(module_handles),
ctypes.sizeof(module_handles), ctypes.byref(needed), LIST_MODULES_ALL):
raise ctypes.WinError()
count = needed.value // ctypes.sizeof(ctypes.c_void_p)
for i in range(count):
h_mod = module_handles[i]
mod_path = ctypes.create_unicode_buffer(260)
GetModuleFileNameExW(h_process.handle, h_mod, mod_path, ctypes.sizeof(mod_path))
if dll_keyword.lower() in mod_path.value.lower():
print(f"[+] 找到模块: {mod_path.value}")
print(f"[+] 模块基地址: 0x{h_mod:08X}")
return h_mod
raise Exception(f"{dll_keyword} not found in process.")
def write_memory(pid, address, data_bytes):
PROCESS_ALL_ACCESS = 0x1F0FFF
h_process = win32api.OpenProcess(PROCESS_ALL_ACCESS, False, pid)
old_protect = ctypes.c_ulong()
size = len(data_bytes)
# 修改页面权限
ctypes.windll.kernel32.VirtualProtectEx(
int(h_process), ctypes.c_void_p(address), size,
win32con.PAGE_EXECUTE_READWRITE, ctypes.byref(old_protect)
)
# 写入内存
written = ctypes.c_size_t()
ctypes.windll.kernel32.WriteProcessMemory(
int(h_process), ctypes.c_void_p(address),
data_bytes, size, ctypes.byref(written)
)
# 恢复权限
ctypes.windll.kernel32.VirtualProtectEx(
int(h_process), ctypes.c_void_p(address), size,
old_protect.value, ctypes.byref(ctypes.c_ulong())
)
if written.value != size:
raise Exception("WriteProcessMemory did not write all bytes.")
if __name__ == "__main__":
pid = get_wechat_pid()
print(f"[+] WeChat PID: {pid}")
base_addr = get_module_base_address(pid, "WeChatWin.dll")
offset_list = [0x2E2E354,0x2E6E7C4,0x2E50314,0x2E50FE4,0x2E6B39C,0x2E6FD6C]
for i in offset_list:
target_addr = base_addr + i
print(f"[+] 目标地址: 0x{target_addr:X}")
value = 0x63090c37
data_bytes = struct.pack("<I", value)
write_memory(pid, target_addr, data_bytes)
print(f"[+] 成功写入 0x{value:08X} 到 0x{target_addr:X}")
用上面的方法可以退回V4登录微信V3版本,但实际使用会发现会出现各种灵异现象——譬如少个人……
不知道有没有更简洁有效没毛病的办法?