PC微信逆向:使用HOOK获取好友列表和群列表

news/2024/11/22 21:24:42/

文章目录

    • 获取好友列表的切入点
    • 定位查询好友信息的函数
      • 定位微信号的地址
      • 一次错误的尝试
      • 再次查找目标函数
      • 成功定位获取好友信息的函数
    • 定位获取好友列表的函数
    • 示例代码
    • 实际效果
    • 预告

获取好友列表目前有三种方法,第一种就是二叉树遍历,通过一层一层的往下读取来拿到所有的好友列表。第二种是通过在内存里面找好友的地址列表。第三种就是通过查找微信数据库来获取列表

获取好友列表的切入点

要想获取微信的好友列表,就必须找到微信读取好友列表的地方。突破口在于微信在点击个人名片时,会获取当前联系人的详细信息,然后显示在右侧。

那么我们可以大胆猜测 微信在登陆的时候,需要先调用这个call,循环拿到所有好友的详细信息,然后再显示到右侧

在这里插入图片描述

第一步:我们首先要找到微信获取好友详细信息的函数。这个函数在读取好友列表时必然会被调用,第二步,再通过这个函数找到获取好友列表的地方。

另外还有一种方法就是通过好友的数量,先搜索当前好友的数量,然后删除一个,再次搜索。直到找到保存好友数量的地址。

定位查询好友信息的函数

那么如何找到查询好友信息的函数呢?突破口在于当前窗口的微信号,只要找到微信号的地址,然后对微信号下内存写入断点,栈回溯分析就能找到我们需要的函数。

定位微信号的地址

在这里插入图片描述

首先搜索当前的微信号,勾选Unicode

在这里插入图片描述

接着切换联系人,再次扫描

在这里插入图片描述

最终会剩下五个结果,我们需要逐个排查每一个结果

一次错误的尝试

在这里插入图片描述

随便找一个地址,下内存写入断点。然后切换当前联系人窗口,断点断下。删除内存断点。

我们需要找到一个地址,地址里面包含联系人的所有信息

在这里插入图片描述

在堆栈的地址中我们发现了一个返回地址,返回地址下面有微信的个人数据。那么这个有可能就是我们需要的call

切换当前窗口联系人,等待断点断下

在这里插入图片描述

此时,堆栈和eax寄存器中保存了当前联系人的所有数据

在这里插入图片描述

继续往下拉会发现eax中保存有签名和国家等信息。也就是说这个call里面保存了当前聊天窗口的好友的所有信息。

接着我们删除好友,让好友列表刷新,看看这个地方会不会断下来。如果会断下来,那么这个地方就有可能保存了所有好友的信息。

在这里插入图片描述

删除之后,断点并未断下,那么这个call就不是我们想要的

再次查找目标函数

继续找另外一个地址,下内存写入断点

在这里插入图片描述

此时再次搜索返回地址,你会发现在压入返回地址前的一个参数中有一个完整的好友信息

在这里插入图片描述

这个call将一个完整的好友信息压入堆栈,那么说明这个call之前好友信息已经被查询出来了。我们需要继续往上找, 反汇编窗口跟随这个call

在这里插入图片描述

在函数头部的位置下断点

在这里插入图片描述

等程序断下时在堆栈中找到返回地址

在这里插入图片描述

然后在找到的上一层函数下断点,断下之后按F8单步步过,看看这个函数的作用是什么

在这里插入图片描述

在这个call执行完毕之后,edi里面保存的就是好友的所有信息。那么说明这个call的作用就是查询当前好友的详细信息!

成功定位获取好友信息的函数

接着我们F7进入这个函数,看看好友的详细信息具体是从哪里个函数中查询出来的
在这里插入图片描述

单步到这里我们发现在进入临界区之后有一个函数,这个函数将微信ID的指针压入栈,我们F8步过函数查看一下返回值

在这里插入图片描述

此时eax里保存了当前好友的所有详细信息。通过参数和返回值也就可以猜到这个call的作用是通过微信ID获取详细信息。那么我们第一步就算是大功告成了。

定位获取好友列表的函数

我们重新载入微信,然后在找到的获取好友详细信息的函数下断点

在这里插入图片描述

登录微信,此时断点断下,接着按F8步过

在这里插入图片描述

此时eax寄存器中保存有联系人的数据,这个函数会调用多次,每调用一次查询一个好友信息。

事实上获取好友列表的call不止这一个地方,但是这个地方拿到的数据是最多的。可以拿到所有的好友列表和群列表以及公众号

函数已经找到了,那么我们只要写一个dll,注入到微信的进程空间中,利用Inline HOOK就能获取到所有的好友列表了

示例代码

部分示例代码如下:

开始HOOK:

VOID StartHook(DWORD hookAdd, LPVOID jmpAdd)
{BYTE JmpCode[HOOK_LEN] = { 0 };//我们需要组成一段这样的数据// E9 11051111(这里是跳转的地方这个地方不是一个代码地址 而是根据hook地址和跳转的代码地址的距离计算出来的)JmpCode[0] = 0xE9;//计算跳转的距离公式是固定的//计算公式为 跳转的地址(也就是我们函数的地址) - hook的地址 - hook的字节长度*(DWORD *)&JmpCode[1] = (DWORD)jmpAdd - hookAdd - HOOK_LEN;//hook第二步 先备份将要被我们覆盖地址的数据 长度为我们hook的长度 HOOK_LEN 5个字节//获取进程句柄HANDLE hWHND = OpenProcess(PROCESS_ALL_ACCESS, NULL, GetCurrentProcessId());//备份数据if (ReadProcessMemory(hWHND, (LPVOID)hookAdd, backCode, HOOK_LEN, NULL) == 0) {MessageBox(NULL, "hook地址的数据读取失败", "读取失败", MB_OK);return;}//真正的hook开始了 把我们要替换的函数地址写进去 让他直接跳到我们函数里面去然后我们处理完毕后再放行吧!if (WriteProcessMemory(hWHND, (LPVOID)hookAdd, JmpCode, HOOK_LEN, NULL) == 0) {MessageBox(NULL, "hook写入失败,函数替换失败", "错误", MB_OK);return;}}

显示好友列表

//显示好友列表
VOID insertUserLists(DWORD userData)
{/*eax + 0x10 wxid 群eax + 0x30 wxid 群eax + 0x44 微信号eax + 0x58 V1数据eax + 0x8C 昵称eax + 0x11C 小头像eax + 0x130 大头像eax + 0x144 未知md5数据eax + 0x1C8 国籍eax + 0x1DC 省份eax + 0x1F0 城市eax + 0x204 添加来源eax + 0x294 朋友圈壁纸*/DWORD wxidAdd = userData + 0x10;DWORD wxuserIDAdd = userData + 0x44;DWORD wxidV1Add = userData + 0x58;DWORD wxNickAdd = userData + 0x8C;DWORD headPicAdd = userData + 0x11C;//DWORD wxNickAdd = userData + 0x8C;wchar_t wxid[0x100] = {0};if ((LPVOID *)wxidAdd) {swprintf_s(wxid, L"%s", *((LPVOID *)wxidAdd));}wchar_t nick[0x100] = { 0 };if ((LPVOID *)wxNickAdd) {swprintf_s(nick, L"%s", *((LPVOID *)wxNickAdd));}wchar_t wxuserID[0x100] = { 0 };if ((LPVOID *)wxuserIDAdd) {swprintf_s(wxuserID, L"%s", *((LPVOID *)wxuserIDAdd));}if (oldWxid[0] == 0 && newWxid[0] == 0) {swprintf_s(newWxid, L"%s", *((LPVOID *)wxidAdd));}if (oldWxid[0] == 0 && newWxid[0] != 0) {swprintf_s(oldWxid, L"%s", newWxid);swprintf_s(newWxid, L"%s", *((LPVOID *)wxidAdd));}if (oldWxid[0] != 0 && newWxid[0] != 0) {swprintf_s(oldWxid, L"%s", newWxid);swprintf_s(newWxid, L"%s", *((LPVOID *)wxidAdd));}if (wcscmp(oldWxid,newWxid) != 0) {LVITEM item = { 0 };item.mask = LVIF_TEXT;item.iSubItem = 0;item.pszText = UnicodeToANSI(wxid);ListView_InsertItem(gHwndList, &item);wxuserIDitem.iSubItem = 1;item.pszText = UnicodeToANSI(wxuserID);ListView_SetItem(gHwndList, &item);item.iSubItem = 2;item.pszText = UnicodeToANSI(nick);ListView_SetItem(gHwndList, &item);}
}

实际效果

在这里插入图片描述

预告

最后,预告下一期,我的微信助手成品即将完成,现已完成大部分功能,再添加几个功能就全部完成了,届时将开放成品和所有源代码

在这里插入图片描述

目前微信机器人的成品已经发布,需要代码请移步Github。还请亲们帮忙点个star

https://github.com/TonyChen56/WeChatRobot


http://www.ppmy.cn/news/339177.html

相关文章

搜狗输入法纯净_最新PC端搜狗输入法,无广告弹窗纯净版

点击蓝字关注我们 使用过搜狗输入法的都知道,它在电脑上会时不时跳出一些弹窗,什么古天乐渣渣辉等你来玩、一刀999级...... 此时有种想换输入法的冲动,冷静下来思考一番后,想起了与“搜狗输入法”之前的点点滴滴,其实它还是很不错的。 搜狗输入法很具有先进性,同时它也是…

控制电脑_用小程序远程控制电脑

远程控制软件,大家已经见过很多了,比如说我们之前介绍过的 Remote Utilities、AnyDesk 等等,但是我今天介绍的这款与其他的有点与众不同。 今天登场的是一款名叫 HiPC 移动助手的软件,首先,我们需要下载 PC 端&#xf…

计算机怎么换桌面皮肤,如何更换电脑腾讯视频上的皮肤样式

如何更换电脑腾讯视频上的皮肤样式 我们经常使用电脑上的腾讯视频软件看视频,在首页上我们可以看到自己的皮肤,当我们觉得不好看而想要换皮肤时,应当怎么做呢,接下来就让小编来教你们吧。 具体如下: 1. 第一步,打开电脑上的腾讯视频进入主页面。 2. 第二步,点击主页面右…

电脑技巧:分享6个实用的资源网站

❤️作者主页:IT技术分享社区 ❤️作者简介:大家好,我是IT技术分享社区的博主,从事C#、Java开发九年,对数据库、C#、Java、前端、运维、电脑技巧等经验丰富。 ❤️个人荣誉: 数据库领域优质创作者🏆&#x…

android动态壁纸的制作教程,巧用Windows自带工具,简易制作动态壁纸教程

Windows 10增加了很多新功能,其中“照片”的“视频制作”功能很是有趣。笔者今天为大家介绍一下如何利用这一系统自带功能,简单制作一个动态壁纸。 把图片做成动态壁纸,总共分4步:1、准备素材,2、素材导入,3、调整效果,4、导出视频。接下来,笔者就为分步讲解以下制作步…

云计算机盒子,网络盒子秒变PC电脑必备装备客厅云电脑

测评信息 测评软件:客厅云电脑V1.0.8 电视盒子:迪优美特X611 四核盒子、华为荣耀盒子Pro 显示设备:优派电竞显示器VP2468 网络接入:中国电信100M光纤(有线上行11MB/S 下行4MB/S) 网络设备:360 C301无线路由器 软件介绍: 客厅云电脑,电视变电脑,让电视像电脑一样上网、娱…

只需要一招,改变你的网易云皮肤(仅限于PC端)

我们废话不多说,直接上才艺。我们首先打开我们的网易云音乐。 第一步:点击设置——关于网易云音乐——下滑至最下面我们可以看到版本号,不确定的同学们可以试着点击检查与更新,来确定一下是不是最新版本。(检查完之后…

校园社交网站(PC端)

项目介绍 校园社交网站是一个前后端分离的项目,项目采用VueNodeMysql,elementUI组件库开发。 在这里插入图片描述 项目技术栈 前端技术栈 vueelementUIaxiosvue-routerWebSocketvue-cliEcharts… 后端技术栈 nodeMySQLWebSocketnode-schedule(计时器…