原文始发于九世的博客:读取微信内存里的信息
前言
参考链接:https://blog.csdn.net/weixin_30230009/article/details/105100181
需要了解知识:
基址 -> 基址在程序下次运行时是不会改变的
->每次重启进程,模块加载的地址会变
实验过程
寻找对应的信息基本方法如下:
打开CE附加微信进程,搜索微信号等关键字,然后找到基址 (绿色的就是),双击添加到地址列表
PS:这里重启了几次wx,所以CE里的地址和上图对不上 (一开始忘记截了)
对着地址双击就能看到对应的地址
然后OD定位到对应的内存地址去查询
command: dd
我们只需要知道基址然后:模块加载地址+基址
怎么求基址->偏移地址-dll加载地址=基址
这里求手机号基址为例,在od鼠标在内存窗口单机刚刚找到的那个地址点击手机号第一个数字,然后记录下地址,在CE手动添加地址里面输入,类型选字符串
即可看见手机号(手机号长度11所以长度设置11)
dll加载地址,CE点击手动添加地址,输入dll名称,类型选4字节
然后将数值改为十六进制(即可得到地址)
或者你也可以用OD或者Process Explorer里获取加载dll地址
(注:这后面截的图与上方地址对不上)
求出手机号基址
53D0F560:手机号内存地址
52CC0000:dll加载地址
53D0F560-52CC0000=104F560 -> WeChatWin.dll(52CC0000)+104F560=手机号
所以以此类推获取:微信号、微信名称等基址
WeChatWin.dll+104F52C – wx名
WeChatWin.dll+104F690 – wx号地址
WeChatWin.dll+104F560 – 手机号
(找到信息的时候可以切成地址,然后往下滑)
注意事项:遇到指针的话,先获取指针里的值。然后在用这个值当作地址找
在找wx号的时候就遇到了
(算出第一个基址后,求别的时候只需要把后面三个数字给替换掉就知道了,emmmmmm)
此时046F35D0里面的地址放着微信号
(PS:这里地址微信重启过,和上面的图地址对不上)
构造读取
使用的Windows API:OpenProcess、ReadProcessMemory
from ctypes import *
from win32con import *
from ctypes.wintypes import *
from win32process import (EnumProcessModules,GetModuleFileNameEx)
import os
CreateToolhelp32Snapshot=windll.Kernel32.CreateToolhelp32Snapshot
Process32First=windll.kernel32.Process32First
Process32Next=windll.kernel32.Process32Next
OpenProcess = windll.kernel32.OpenProcess
ReadProcessMemory = windll.kernel32.ReadProcessMemory
CloseHandle = windll.kernel32.CloseHandle
TH32CS_SNAPPROCESS=0x00000002
TH32CS_SNAPMODULE = 0x00000008
MAX_MODULE_NAME32 = 255
class PROCESSENTRY32A(Structure): #定义PROCESSENTRY32A类型
_fields_ = [ ( 'dwSize' , c_ulong ) ,
( 'cntUsage' , c_ulong) ,
( 'th32ProcessID' , c_ulong) ,
( 'th32DefaultHeapID' , c_size_t) ,
( 'th32ModuleID' , c_ulong) ,
( 'cntThreads' , c_ulong) ,
( 'th32ParentProcessID' , c_ulong) ,
( 'pcPriClassBase' , c_long) ,
( 'dwFlags' , c_ulong) ,
( 'szExeFile' , c_char * MAX_PATH ) ]
def getprocess_pid(processname):
processimage=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0)
pe32=PROCESSENTRY32A()
pe32.dwSize=sizeof(PROCESSENTRY32A)
ret=Process32First(processimage,pointer(pe32))
while ret:
if pe32.szExeFile.decode()==processname:
return pe32.th32ProcessID
ret=Process32Next(processimage,pointer(pe32))
def getmodule_address(handle,dllname):
for module in EnumProcessModules(handle):
dllpath=GetModuleFileNameEx(handle,module)
print(module,dllpath)
def main():
wetchatwindlladdress=0x63B60000 #枚举WetChatWin.dll加载地址失败,就直接手动定义了
phome = create_string_buffer(11)
wxname=create_string_buffer(20)
wxnumber=c_int(20)
number=create_string_buffer(20)
pid=getprocess_pid("WeChatStore.exe")
print("WeChat PID:{}".format(pid))
process=OpenProcess(PROCESS_ALL_ACCESS,False,pid)
ReadProcessMemory(process,wetchatwindlladdress+0x104F560,byref(phome),11,None)
ReadProcessMemory(process,wetchatwindlladdress+0x104F52C,byref(wxname),20,None)
ReadProcessMemory(process,wetchatwindlladdress+0x104F690,byref(wxnumber),20,None)
print("WX Phome:"+hex(wetchatwindlladdress + 0x104F560),phome.value.decode())
print("WX Name:"+hex(wetchatwindlladdress+0x104F52C),wxname.value.decode())
wxnumberaddress=wxnumber.value #可以不用转十六进制,直接十进制即可,py转十六进制默认是str类型。。hex函数转后填进地址读不到
ReadProcessMemory(process,wxnumberaddress,byref(number),20,None)
print("WX Number:"+number.value.decode())
#getmodule_address(handle,"WeChatWin.dll")
if __name__ == '__main__':
main()
踩坑记录:
* 调用EnumProcess和用Thread32First枚举模块,结果根本不能完全枚举。原本想模仿Process Explorer调用ZwQueryVirtualMemory函数枚举模块,py写起来太麻烦。。算了
这种方法也可以用来干别