frida项目
- frida文档
- Golang Bindings
- pc微信hook范例
- Pin/DynamoRIO/Frida 二进制动态插桩
macos
- Clutch 拆壳?
- Cycript 运行时分析
- 发现头文件 classdump
- 官网的class-dump不支持dump swift files导致。 https://github.com/AloneMonkey/MonkeyDev/blob/master/bin/class-dump
- SendLocationMsgFromUser
- 运行调试方法: frida-trace -m “-[FFProcessReqsvrZZ FFProcessTReqZZ*]” 微信
- objective-c hook方法
–Apple M1,逆向环境设置与我自己遇到了很多坑逐一解决,给后来的同学一个参考吧
–MacOS微信逆向分析-Frida
- FFProcessTReqZZ 发文字信息
问题
Failed to attach: unable to access process with pid 87944 from the current user account
87944 已经被追踪(守护进程?)所以无法被frida hook
cat /proc/18486/status | grep TracerPid
系统完整性保护
windows
- 看雪ollydbg资源
- PC微信frida
- 使用frida微信Hook_Coder的博客-程序员秘密_frida 微信
- Frida知识小记
- ddl注入原理
- PC微信逆向:分析通用设置数组 cheatEngine
- 重点参考:PC微信逆向:发送与接收消息的分析与代码实现
- 付费课程 2021微信逆向分析
- 【原创】PC微信逆向分析の强制输出微信调式信息
- cheat engine
- ollydbg ? Ollydbg使用教程学习总结(一)
- OllyDbg截取PC WeChat的数据库key – BH4LM
- PC 微信逆向:破解聊天記錄文件!
- 使用OllyDbg从零开始Cracking 第十章-断点
- 关键!!pc微信hook实战记录1
- 重要 植物大战僵尸逆向过程
- bilibili指针偏移教学
- 对dll的hook ?
- WeChatWin.dll 是微信的关键dll ModAdress:0x65990000
- dll 是动态加载的, 基址会变,但是 函数的偏移量是不会变的
- 如何获取dll的基址?
- dll注入方式
- 每次只能读取到一个字符的原因,应为找的地方不对,是最初始的,此处每个字符后面都跟上了字符串终止符号00,由于readUtf8String读到00就停了所以读不到后面,还要往后找
- iOS逆向 微信消息界面分析 部分吻合
OD基本快捷键及功能:
F2 下断点,也就是指定断点的地址
F3 加载一个可执行程序,进行调试分析
F4 程序执行到光标处
F5 缩小、还原当前窗口
F7 单步步入
F8 单步步过
单步步过就是碰到call不进入call,单步步入就是进入call中执行。。。
单步步过相当于单步步入后执行到ret指令的下一条。。。
F9 直接运行程序,遇到断点处,程序暂停
Ctrl+F2 重新运行程序到起始处,一般用于重新调试程序
Ctrl+F9 执行到函数返回处,用于跳出函数实现
Alt+F9 执行到用户代码处,用于快速跳出系统函数
Ctrl+G 输入十六进制地址,快速定位到该地址处
idaPro
- 设置dll基址 使用IDA打开DLL时,一开始会弹出以下对话框,勾选“Manual load” / 手动加载
- ida代码视图 蓝色箭头只有一个后续、 红色no、绿色yes
- 获取伪代码 F5 需要用ida 而不是ida64
- xref 交叉引用 ctrl+x 获取鼠标选定函数的调用者
- function calls 获取该函数调用的函数
- idapro的调试和ollydbg差不多,有方便的便利方法:搜索->查询文本 (art+t)可以找到关键字。
- IDAPython基础教程一
- ida python文档
- idapython笔记
pc 发送消息的地址
Executable modules, item 112
Base=65990000
Size=02680000 (40370176.)
Entry=672D7B60 WeChatWi.
Name=WeChatWi
File version=3.6.0.18
Path=C:\Program Files (x86)\Tencent\WeChat[3.6.0.18]\WeChatWin.dll
- step1 找到地址流程:ce 通过字符串查找地址
- step2 ollydbg attach wechat -> Execute modules -> wechatWin -> view code in cpu -> Ctrl+g 查询地址
需要学习的知识点
1、如何定位函数
- ce找到的地址
ctrl+g 搜索
出位置,再右击写入断点
, 接着再发送消息,此时可以断到(断点到后取消写入断点),再点击ctrl+k
查看调用栈,调用来自显示的就是函数地点,从函数地址下断,触发断点后 看寄存器 esp堆栈窗口中跟随(右下侧看) 或 ebp堆栈窗口中跟随
2、如何稳定debug - od无法正常debug 的快捷处理方式 OllyDbg调试总是进入RtlRaiseException 异常处理函数
整体思路
- 主动发送方法hook 手机客户端发送的同步方法,也要hook, 另外客户端登出->要预警
- 客户端掉线重连
1、CE 找关键词,定位存储信息的地址。在通过谁修改了这个地址获取一些关键信息
2、再ollydbg中 存储地址处 写入内存断点, 命中断点后查找调用栈,再一步一步debug 从esp堆栈窗口检索关键字,直到定位函数
定位的函数信息
Wechat Version: 3.7.0.30
WechatWin 基址: 67D50000
函数地址: 6912C730 偏移为: base + 0x13DC730
唯一触发函数地址 base + 0x737818 / 0x7372A0
可能是最终调用 base + 0x13EBE60
$+368 >|770148F8 返回到 KERNELBA.770148F8 来自 ntdll.RtlUnicodeToUTF8N
$+36C >|00000020
$+370 >|00910860
$+374 >|00000064
$+378 >|11041380 UNICODE "wxid_sfjlk5mowetkxx"
$+37C >|00000020
$+380 >|00000000
$+384 >|04CB52D8
$+388 >|113A9158 返回到 113A9158
$+38C >|00000000
$+390 >|00000000
$+394 >|772B7904 返回到 ntdll.772B7904 来自 ntdll.77273C30
$+398 >|113A94A0 UNICODE "hangzhou" //收到的内容
// onEnter:function(args) {
// console.log(id:${new ObjC.Object(args[2])} toUsrName:${new ObjC.Object(args[3])} thumbImgData:${new ObjC.Object(args[4])} imgData:${new ObjC.Object(args[5])} imgInfo:${new ObjC.Object(args[6])}
)
//
// }
汇编
- 搞懂函数调用前后堆栈恢复的过程
- 逆向工程核心原理 第七章 栈帧 p49开始很重要 概要: 汇编中如何分辨静态变量、函数入参,以及入参顺序,函数调用栈帧逻辑!
- 寄存器的作用?
- 通用寄存器如下:
- EAX (针对操作数和结果数据的) 累加器
- EBX (DS断中的数据指针) 基址寄存器
- ECX (字符串和循环操作符的) 计数器
- EDX (I/O 指针) 数据寄存器
- EBP (SS段中栈内数据指针) 扩展基址指针寄存器
- ESI (字符串操作源指针) 源变址寄存器
- EDI (字符串操作目标指针) 目的变址寄存器
- ESP (SS段中栈指针) 栈指针寄存器
- 段寄存器
- 调用前
PUSH EBP 先把ebp保存到栈中
MOV EBP, ESP 保存ESP到EBP中
//函数体
//无论ESp如何变化,EBP都保持不变,可以安全访问函数的局部变量、参数
MOV ESP, EBP //将函数其实地址返回给esp
POP EBP //函数返回前弹出保存在栈中的EBP值
RETN //函数终止
环境变量的范例
范例源代码 long a=1 , b=2
汇编如下
SUB ESP-8 // 两个long 8个字节 ESP由高到低减去8个字节
MOV DWORD PTR SS:[EBP-4],1 // 环境变量申明
MOV DWORD PTR SS:[EBP-8],2 // 环境变量申明
调用函数前的参数组装范例
范例源代码: add(xxx, a,b)
MOV EAX, DWORD PTR SS:[EBP-8] 入参是逆向的
PUSH EAX
MOV ECX, DWORD PTR SS:[EBP-4]
PUSH ECX
PUSH 401133a //最后push入栈的是第一个参数
CALL 0x231aa3
范例源代码: add(long a, long b)
PUSH EBP 先把ebp保存到栈中
MOV EBP, ESP 保存ESP到EBP中
MOV EAX, DWORD PTR SS:[EBP+8] // 前8字节保存的是 EBP 寄存器 32位 8字节 所以从8开始取入参
MOV EAC, DWORD PTR SS:[EBP+C] // 4字节
疑问,
- 为什么参数进入 EAX,ECX 更多的参数遵循什么逻辑?
- MOV EAX, DWORD PTR SS:[EBP+8] // 为什么从 +8 开始而不是 +4 猜测的解释:前8字节保存的是 ESP 寄存器 32位 8字节 所以从8开始取入参