首页
社区
课程
招聘
【原创】【PC微信逆向】一、64位PC微信逆向分析:Hook微信自身日志
发表于: 2025-5-28 16:33 4481

【原创】【PC微信逆向】一、64位PC微信逆向分析:Hook微信自身日志

2025-5-28 16:33
4481

一、前言

近期分析了一下64位的PC微信,对其中的一些内容做一些分享。本期分享内容:Hook微信自身日志。

本次分析使用版本:3.9.12.51。

二、逆向分析

众所周知,PC微信的主要业务功能均实现于WechatWin.dll,使用IDA分析。

一般日志都会存在格式化字符串,比如%s、{}等,直接在IDA中搜索。

随便选择一个看着很像(带有一些微信业务属性的,比如消息、图片等)的,追踪一下。

定位到函数sub_182627590,进去看看。

函数内发现代码获取了时间和线程ID并格式化,基本可以确定这里就是日志函数了。并发现代码循环处理字符串后在尾部添加结束符\x00。

将Hook点选择在添加结束符\x00之后,即0x18262780F处。这时候字符串已经组装完毕。

调试发现在0x18262780F处,rdx指向字符串。

三、Hook

64位的Hook和32位的有点区别,32位一般在Hook点直接jmp XXXXXXXX(立即数地址)或者call XXXXXXXX(立即数地址)即可,但是64位不支持直接jmp/call立即数地址,所以这里采用mov rax,XXXXXXXXXXXXXXXX(立即数地址),然后jmp rax的方式来Hook。由于这种方式会改写rax的值,所以在这之前还得保存一下rax的值,并在跳转后恢复,防止rax的值丢失。

梳理一下Hook流程:

  1. 保存rax
  2. mov rax并jmp rax,就跳转到我们自己的Hook代码处
  3. 恢复rax
  4. 保存寄存器环境,由于64位没有pushad指令,只能手动保存
  5. 调用我们的功能代码
  6. 恢复寄存器环境,由于64位没有popad指令,只能手动恢复
  7. 执行因为Hook操作而被覆盖的原始代码
  8. 再次保存rax
  9. mov eax并jmp eax,返回到本来的功能代码处
  10. 恢复rax,随后即可正常执行

四、先手动Hook

(一)Hook点

(二)Hook代码

五、编写代码自动Hook

(一)定义偏移地址

1
2
3
// 这里wxbase为wechatwin.dll的基地址
uint64_t hookaddr_wxlog = 0x18262780F - 0x180000000 + wxbase;
uint64_t retaddr_wxlog = 0x18262781C - 0x180000000 + wxbase;

(二)编写功能函数

这里rdx就是字符串指针,可以根据情况编写功能函数,比如输出到文件等。

1
2
3
void hookdeal_wxlog(uint64_t rdx) {
 
}

(三)编写Hook功能代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// 申请内存空间
LPVOID memory = VirtualAlloc(NULL, 1000, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
// pop rax(跳转到Hook代码后,恢复rax)
// pushaq + pushfq(保存寄存器环境)
WriteProcessMemory(GetCurrentProcess(), memory, "\x58\x54\x50\x53\x51\x52\x55\x56\x57\x41\x50\x41\x51\x41\x52\x41\x53\x41\x54\x41\x55\x41\x56\x41\x57\x9C", 26, NULL);
// mov rcx,rdx(参数)
// mov rax(给rax赋值地址)
WriteProcessMemory(GetCurrentProcess(), (LPVOID)((uint64_t)memory + 26), "\x48\x89\xD1\x48\xB8", 5, NULL);
// 地址
void (*ptr)(uint64_t) = hookdeal_wxlog;
WriteProcessMemory(GetCurrentProcess(), (LPVOID)((uint64_t)memory + 26 + 5), &ptr, 8, NULL);
// push rbx(传参但是仍然分配栈)
// call rax(调用hookdeal函数)
WriteProcessMemory(GetCurrentProcess(), (LPVOID)((uint64_t)memory + 26 + 5 + 8), "\x53\xFF\xD0", 3, NULL);
// pop rbx(恢复栈)
// popfq + popaq(恢复寄存器环境)
WriteProcessMemory(GetCurrentProcess(), (LPVOID)((uint64_t)memory + 26 + 5 + 8 + 3), "\x5B\x9D\x41\x5F\x41\x5E\x41\x5D\x41\x5C\x41\x5B\x41\x5A\x41\x59\x41\x58\x5F\x5E\x5D\x5A\x59\x5B\x58\x5C", 26, NULL);
// 执行旧的被覆盖的代码
WriteProcessMemory(GetCurrentProcess(), (LPVOID)((uint64_t)memory + 26 + 5 + 8 + 3 + 26), "\x44\x89\x75\x80\x0F\x57\xC0\x0F\x11\x85\xC0\x10\x00\x00", 14, NULL);
// push rax(保存rax)
// mov rax(给rax赋值地址)
WriteProcessMemory(GetCurrentProcess(), (LPVOID)((uint64_t)memory + 26 + 5 + 8 + 3 + 26 + 14), "\x50\x48\xB8", 3, NULL);
// 地址
WriteProcessMemory(GetCurrentProcess(), (LPVOID)((uint64_t)memory + 26 + 5 + 8 + 3 + 26 + 14 + 3), &retaddr_wxlog, 8, NULL);
// jmp rax(跳转回原代码)
WriteProcessMemory(GetCurrentProcess(), (LPVOID)((uint64_t)memory + 26 + 5 + 8 + 3 + 26 + 14 + 3 + 8), "\xFF\xE0", 2, NULL);

(四)Hook原始代码

需要占用14字节的空间。

1
2
3
4
5
6
7
// push rax(保存rax)
// mov rax(给rax赋值地址)
WriteProcessMemory(GetCurrentProcess(), (LPVOID)hookaddr_wxlog, "\x50\x48\xB8", 3, NULL);
// 地址
WriteProcessMemory(GetCurrentProcess(), (LPVOID)(hookaddr_wxlog + 3), &memory, 8, NULL);
// jmp rax(跳转到Hook代码)pop rax(从Hook代码返回后恢复rax)
WriteProcessMemory(GetCurrentProcess(), (LPVOID)(hookaddr_wxlog + 3 + 8), "\xFF\xE0\x58", 3, NULL);

六、最终效果

获取到微信日志。


[培训]Windows内核深度攻防:从Hook技术到Rootkit实战!

收藏
免费 4
支持
分享
最新回复 (23)
雪    币: 1995
活跃值: (2746)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
2
知道字符串存在断点的RDX,可以用异常直接把字符串读出来吧
2025-5-28 22:34
0
雪    币: 1032
活跃值: (80)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
wtujoxk 知道字符串存在断点的RDX,可以用异常直接把字符串读出来吧
用异常劫持执行流吗?感觉更麻烦一些呢
2025-5-28 23:48
0
雪    币: 1995
活跃值: (2746)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
4

按楼主的方案异常获取的,使用特征码搜索应该通用,微信版本3.9.6.37测试通过

上传的附件:
2025-5-29 17:22
1
雪    币: 317
活跃值: (4145)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
开搞4.0了
2025-5-30 09:31
0
雪    币: 220
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
6
Python成长路 开搞4.0了
4.0大佬有找到吗,看ida,4.0完全没有这些字符串了
2025-6-4 17:34
0
雪    币: 220
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
7
Python成长路 开搞4.0了
4.0大佬有找到吗,看ida,4.0完全没有这些字符串了
2025-6-4 17:34
0
雪    币: 5722
活跃值: (4516)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
4.0的发送消息CALL超级难找,我找到了几个疑似的,但是参数补不全,要崩,大神能讲解下吗
2025-6-18 22:36
0
雪    币: 2040
活跃值: (2090)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
9
linghaien 4.0的发送消息CALL超级难找,我找到了几个疑似的,但是参数补不全,要崩,大神能讲解下吗
不难找啊,异步的,你找到add msg queue就可以找到了。。。
2025-6-27 16:38
0
雪    币: 5722
活跃值: (4516)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
FANTASYING 不难找啊,异步的,你找到add msg queue就可以找到了。。。
不太懂,我找到了CALL,但是CALL传了参数还是会崩,你的意思是要自己来触发异步发送消息吗
2025-6-28 13:55
0
雪    币: 1032
活跃值: (80)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
linghaien 不太懂,我找到了CALL,但是CALL传了参数还是会崩,你的意思是要自己来触发异步发送消息吗
我还没计划研究4.0,但是你的这种情况我在3.X系列碰到过,你这边是不是调用完关键CALL之后让控制流继续沿着原来的路径执行下去了?如果是这样的话就会崩,需要调用完关键CALL之后立即转移控制流才行
2025-7-1 16:22
0
雪    币: 0
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
12
mb_xlrydljz 4.0大佬有找到吗,看ida,4.0完全没有这些字符串了
4.0的日志我搞出来了哦
2025-7-6 03:28
0
雪    币: 1032
活跃值: (80)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
wx_ㅤCary 4.0的日志我搞出来了哦[em_013]
围观大佬
2025-7-15 23:06
0
雪    币: 1332
活跃值: (391)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
linghaien 4.0的发送消息CALL超级难找,我找到了几个疑似的,但是参数补不全,要崩,大神能讲解下吗

4.0的 日志搞出来很简单

最后于 2025-7-19 00:05 被酷鸟编辑 ,原因:
2025-7-19 00:05
0
雪    币: 0
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
15
酷鸟 linghaien 4.0的发送消息CALL超级难找,我找到了几个疑似的,但是参数补不全,要崩,大神能讲解下吗 4.0的 日志搞 ...
我也是在这里找出来了啊,但是一call就崩
2025-7-21 14:32
0
雪    币: 1332
活跃值: (391)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
wx_ㅤCary 我也是在这里找出来了啊,但是一call就崩
程序是QT写的,基本都是对象,你用3.0过程的思路去写call肯定崩
2025-7-23 09:14
0
雪    币: 5734
活跃值: (7103)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
17
酷鸟 linghaien 4.0的发送消息CALL超级难找,我找到了几个疑似的,但是参数补不全,要崩,大神能讲解下吗 4.0的 日志搞 ...

2025-7-23 16:12
0
雪    币: 264
活跃值: (420)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
wx_ㅤCary 我也是在这里找出来了啊,但是一call就崩
请问发消息解决了吗
2025-11-4 00:15
0
雪    币: 264
活跃值: (420)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
linghaien 不太懂,我找到了CALL,但是CALL传了参数还是会崩,你的意思是要自己来触发异步发送消息吗
请问发消息解决了吗
2025-11-4 00:15
0
雪    币: 264
活跃值: (420)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
FANTASYING 不难找啊,异步的,你找到add msg queue就可以找到了。。。
哥,可以咨询下找到这个位置怎么调用 程序不会崩吗 
2025-11-4 00:17
0
雪    币: 5722
活跃值: (4516)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
git_gg 哥,可以咨询下找到这个位置怎么调用 程序不会崩吗
都解决几个月了,按这位兄弟的提示就能找到了
2025-11-4 11:49
0
雪    币: 112
活跃值: (234)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
linghaien 都解决几个月了,按这位兄弟的提示就能找到了
老哥 我日志也搞出,大概在哪个日志附件?能否提示下。谢谢
2025-11-10 10:04
0
雪    币: 20
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
23
wx_ㅤCary 4.0的日志我搞出来了哦[em_013]
跪求一个可以输出日志的hook
2025-12-4 15:08
0
雪    币: 220
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
24
我找4.0发送call,找到个一个参数的call,群和内容都在rcx里面。
2025-12-4 15:20
0
游客
登录 | 注册 方可回帖
返回