开篇PC微信读取联系人常规方法有3种:hook相关调用拦截联系人数据读取内存中包含联系人的二叉树结构解密读取其实,微信本地数据库的前两种方法只使用微信启动后已经读取并存储在内存中的联系人。第一种是拦截进程,第二种是直接获取内存的结果。第一种找到CALL的方法请看:https://blog.csdn.net/qq_3847...不再赘述,我也是新手,也是跟着博客一步步来的。我直接偏移最新版本(2.8.0.121)需要hooks的地址:0x479F07。如果不想自己找CALL,可以直接用OD跳转到WeChatWin.dll+0x479F07地址。已经知道hook的地址,只需要用c++写好dll,注入到微信进程中,就可以获取所有的联系方式了(这个调用在登录的时候会被多次调用,所以需要先注入dll登录)成品软件和dll(软件是aardio写的,dll是c++写的):https://www.lanzous.com/iakfpch效果图:相比第一种方法,第二种方法更简单,dll注入连写都不需要。只读内存中的数据。首先,我们需要找到二叉树根节点的地址。方法可以参考:https://www.jianshu.com/p/b55...(环境音太吵,人声有点低,但讲话还是不错的)最新version(2.8.0.121)二叉树根节点地址:[[WeChatwin.dll+0x161CF54]+0x28+0x84]+0x4,方括号表示地址中的值。这个地址的偏移量也是通过第一个方法的调用找到的,而第一个方法中调用进入的代码就是通过传入的wxid循环二叉树得到wxid对应的好友数据。我们看一下调用中的汇编代码段:然后用aardio实现:importprocess;importconsole;getBTree=function(prcs,esi){//前面不要加var表示全局变量if(!prcs.readNumber(esi+0xD,"byte")){//cmpbyteptrds:[esi+0xD],0x0//wxidwxidAddr=prcs.readNumber(esi+0x10)//获取wxid地址wxidLen=prcs.readNumber(esi+0x14)//获取wxid长度wxid=prcs.readStringUtf16(wxidAddr,wxidLen)//读取Unicode字符串wxid=string.fromUnicode(wxid)//将Unicode字符串转为utf-8//微信微信地址=prcs.readNumber(esi+0x44)微信号长度=prcs.readNumber(esi+0x48)微信号=prcs.readStringUtf16(微信地址,微信号长度)微信号=string.fromUnicode(微信信号)//昵称昵称地址=prcs.readNumber(esi+0x8C)nicknamelength=prcs.readNumber(esi+0x8C+0x4)nickname=prcs.readStringUtf16(nicknameaddress,nicknamelength)nickname=string.fromUnicode(nickname)//备注地址=prcs.readNumber(esi+0x78)remarklength=prcs.readNumber(esi+0x78+0x4)remark=prcs.readStringUtf16(remarkaddress,remarklength)备注=string.fromUnicode(备注)//v1v1Addr=prcs.readNumber(esi+0x58)v1Len=prcs.readNumber(esi+0x5C)v1=prcs.readStringUtf16(v1Addr,v1Len)v1=string.fromUnicode(v1)//未知a1a1Addr=prcs.readNumber(esi+0xCC)a1Len=prcs.readNumber(esi+0xD0)a1=prcs.readStringUtf16(a1Addr,a1Len)//未知a2a2Addr=prcs.readNumber(esi+0xE0)a2Len=prcs.readNumber(esi+0xE4)a2=prcs.readStringUtf16(a2Addr,a2Len)console.writeText(string.format("%s|%s|%s|%s",tostring(wxid),tostring(微信ID),tostring(昵称),tostring(note))+'\n')左节点地址=prcs.readNumber(esi)getBTree(prcs,左节点地址)右节点地址=prcs.readNumber(esi+0x8)getBTree(prcs,右节点地址)}}varreadData=function(){console.open()prcs=process.find("WeChat.exe")if(null==prcs){console.writeText('未找到微信进程,操作前请先打开微信登录!')return}wechatwinAddr=prcs.getModuleBaseAddress('WeChatWin.dll')ecx=prcs.readNumber(wechatwinAddr+0x161CF54)+0x28+0x84ebx=prcs.readNumber(ecx)//movebx,dwordptrds:[ecx]esi=prcs.readNumber(ebx+0x4)//movesi,dwordptrds:[ebx+0x4]esi为二叉树的根节点getBTree(prcs,esi)console.pause('Pressanykeytoclose!')}readData()在汇编代码中做了很多比较,因为需要比较传入的微信号和内存中的数据,我们不需要全部比较,递归读取左右即可二叉树的节点,效果不会释放。只需下载aardio并运行一次。
