frida hook微信防撤回(PC端)

PC端:

微信的主要功能都是在WeChat\[3.9.10.27]\WeChatWin.dll动态链接库中实现的

直接进IDA分析

都没有符号表

我们需要找一下实现撤回功能的函数,尝试在字符串里搜索revokeMsg

也是有非常多的字符串

我们需要用frida来hook这些字符串来找出撤回实际调用的函数

先初步写一个脚本找到WeChatWin.dll的基地址

python 复制代码
#wecaht_hook
import frida
import sys

def main(target_process):
    session = frida.attach(target_process)

    jsCode = """

    //找WeChatWin.dll映射到内存的根地址
    const baseAddr = Module.findBaseAddress('WeChatWin.dll');
    console.log("WeChatWin.dll baseAddr: " + baseAddr);

    """
    #js脚本控制注入逻辑
    script = session.create_script(jsCode)

    script.load() #加载脚本
    print("Process attatched successfully!")
    sys.stdin.read() #持续执行

if __name__=='__main__':
    target_process = 15964 #pid
    main(target_process)
'''
WeChatWin.dll baseAddr: 0x7ffb6d8e0000
Process attatched successfully!
'''

任务管理器可以查看pid

成功回显

但是这里输出的地址是个装载之后的虚拟地址,要与ida中函数的地址对应,还需要进行一个转化

这是IDA中的基地址0x180000000

python 复制代码
#wecaht_hook
import frida
import sys

def main(target_process):
    session = frida.attach(target_process)

    jsCode = """

    //找WeChatWin.dll映射到内存的根地址
    const baseAddr = Module.findBaseAddress('WeChatWin.dll');
    console.log("WeChatWin.dll baseAddr: " + baseAddr);

    const revokeMsgFunAddr = resolveAddress('0x1823CC870'); //测试的目标函数地址
    console.log('revokeMsgFunAddr: ' + revokeMsgFunAddr);

    Interceptor.attach(revokeMsgFunAddr, {
        //一旦进入地址的回调函数
        onEnter(args) {
            console.log('test!');
        }
    
    })

    //虚拟地址转化为实际内存地址
    function resolveAddress(addr) {
        const idaBase = ptr(0x180000000);
        const offset = ptr(addr).sub(idaBase); //偏移地址
        const result = baseAddr.add(offset);
        return result;
    }
    """
    #js脚本控制注入逻辑
    script = session.create_script(jsCode)

    script.load() #加载脚本
    print("Process attatched successfully!")
    sys.stdin.read() #持续执行

if __name__=='__main__':
    target_process = 15964
    main(target_process)

然后把这个脚本跑起来,用另一个号发消息并进行撤回操作,逐个函数进行尝试

调试到SyncMgr::ProcessRevokeMsg对应的函数时,有了回显

我们进相应的函数sub_1823CC870进行静态分析

发现多个分支都调用了sub_1826DA2D0函数,且之前的字符串也在其参数当中,这时候再去hook该函数0x1826DA2D0也是有回显的

那么只要跳过这个函数应该就不会撤回了

但是这个位置的if判断过于复杂(或),不容易跳过

那我们就看一下上一级的sub_1823CC870函数在哪里被调用

可以看到是sub_1823E4AD0函数

这里也可以hook一下,确认回显

转成伪代码会发现这里是一个switch语句,当v9==4时就会触发撤回的函数

很显然那是通过cmp edi, 4来比较

那就在这里注入0x1823E4CBA

我们把edi(64位对应的rdi)的值强行修改成不是4的值(这里改成0)

python 复制代码
#wecaht_hook
import frida
import sys

def main(target_process):
    session = frida.attach(target_process)

    jsCode = """

    //找WeChatWin.dll映射到内存的根地址
    const baseAddr = Module.findBaseAddress('WeChatWin.dll');
    console.log("WeChatWin.dll baseAddr: " + baseAddr);

    const revokeMsgFunAddr = resolveAddress('0x1823E4CBA');
    console.log('revokeMsgFunAddr: ' + revokeMsgFunAddr);

    Interceptor.attach(revokeMsgFunAddr, {
        //一旦进入地址的回调函数
        onEnter(args) {
        console.log('called!');
        console.log("original rdi: " + this.context.rdi);
        this.context.rdi = 0;
        console.log("changed rdi: " + this.context.rdi);
        }
    
    })

    //虚拟地址转化为实际内存地址
    function resolveAddress(addr) {
        const idaBase = ptr(0x180000000);
        const offset = ptr(addr).sub(idaBase); //偏移地址
        const result = baseAddr.add(offset);
        return result;
    }
    """
    #js脚本控制注入逻辑
    script = session.create_script(jsCode)

    script.load() #加载脚本
    print("Process attatched successfully!")
    sys.stdin.read() #持续执行

if __name__=='__main__':
    target_process = 15964
    main(target_process)

撤回的消息就被固定了!

当然要在本地持续化利用,直接把dll里面的

这部分指令NOP掉也行

参考:

广东财经大学-信息安全-基于IDA Pro和Frida的微信消息撤回无效实验_哔哩哔哩_bilibili

[原创]hook 微信信息撤回功能-Android安全-看雪-安全社区|安全招聘|kanxue.com

相关推荐
mCell3 小时前
GSAP ScrollTrigger 详解
前端·javascript·动效
gnip3 小时前
Node.js 子进程:child_process
前端·javascript
databook4 小时前
Manim实现脉冲闪烁特效
后端·python·动效
程序设计实验室5 小时前
2025年了,在 Django 之外,Python Web 框架还能怎么选?
python
excel6 小时前
为什么在 Three.js 中平面能产生“起伏效果”?
前端
倔强青铜三6 小时前
苦练Python第46天:文件写入与上下文管理器
人工智能·python·面试
excel7 小时前
Node.js 断言与测试框架示例对比
前端
天蓝色的鱼鱼9 小时前
前端开发者的组件设计之痛:为什么我的组件总是难以维护?
前端·react.js
codingandsleeping9 小时前
使用orval自动拉取swagger文档并生成ts接口
前端·javascript
石金龙10 小时前
[译] Composition in CSS
前端·css