汇编基础
汇编指令集
- x86/x64
- ARM
- MIPS
常用的汇编指令
- 运算指令
- 数据转移指令
- 跳转指令
- 栈操作指令
x86寄存器
ARM寄存器
寄存器传参和栈传参
010editer
Template的语法类似于C结构体,可以自己直接编写并加载,且支持基本的C语言语法。
ida
ida的快捷键 定义数据的操作就是d 按u 是undefined成未定义的方式 按c 变成代码 按p 手动变成函数 按shift+F12,可以看到所有的字符串 按y统一编辑
调试器
- 步进 —— 单步执行,遇到call调用时会跟进而不是跳过去
- 步过 —— 单步执行,遇到call时会和别的指令一样跳过去
- 运行至指定位置 —— 相当于临时下断点,碰到循环时可以方便的跳过去
- 运行 —— 直接跑起来,而不是一条一条指令执行起来
命令行调试器
- gdb
- WINDBG
图形界面调试器
- OllyDBG(win下的老牌调试器,仅支持32位)
- x64dbg (OD已死,x64统一天下) 支持32和64位 仍在活跃开发中 插件相对较少 快捷键与OD相同
- IDA内置调试器 支持多种后端 支持远程调试
搭建调试环境
linux
ida下有一个dbgsrv中有一堆远程调试的东西
android虚拟机
机器先root 安装Xposed框架 安装XInstaller,在其他设置中勾选调试应用
去除软件保护
- 侦壳 — PEiD、ExeInfo……
- 脱壳
- 搜索脱壳机 热门壳:UPX、ASPack
- ESP定律快速脱壳(只能针对压缩壳)
- 去除花指令 使用OD脚本 手动总结特征码+修改
- 去除混淆 .net反混淆神器de4dot
定位验证代码
拿到flag:破除保护外壳、理解程序过程、找到验证函数、逆推得到flag 1. 正面长驱直入(文件比较小) - 从程序的入口点开始,逐步分析 - 层层深入最后抵达验证函数 - 静态分析 2. 从信息输入/输出处寻找(文件比较大)
常见算法分析与逆向
CTF中常见的类型
1.没算法; - 直接输出flag 2.常见的算法; - 简单异或 - 带雪崩效应的异或(雪崩效应:前面值的结果会导致后面值结果的改变) - 加密算法(RSA、AES) - 散列算法(MD5、SHA1) - 解方程 3.有趣的算法; - 走迷宫 - ……(各种脑洞)
加速CTF解题
1.边信道攻击 - CTF中可以使用pintools - 原理:监测程序执行指令数 - 应用: - 逐字节验证的题目 2.Google大法好 - 加_双引号_搜索S-Box等常量快速确定算法 3.逆向小trick - 快速找main位置 - 寻找一个大跳转 - 快速定位关键位置 - 从Function List靠前的位置开始乱翻 - 从main函数旁边翻 - 编译时不同的原文件会被分别编译为.o再由编译器合并 - 应对MFC程序 - 使用_xspy_工具查看消息处理函数 - 拖上去看感兴趣的函数就可以,比如OnClick OnCommand - 手动加载Signature - 碰到无法自动识别库函数时 - (Shift - F5) View -> Open Subviews -> Signature - (Shift - F11) View -> Open Subviews -> Type Libraries 4.调试小技巧 - 如何得知MessageBox后在程序在哪里继续运行 - 在OD或x64dbg中找到内存布局列表(OD:Alt-M,或查看 -> 内存) - 找到自己程序的代码段(通常是.text,按F2)(下区段断点) - 返回程序点击即可
CTF未来趋势
真实的逆向
目前的CTF: - 代码量小 - 结构简单 单文件 - 编码单一 - 现代语言特性少 面向过程 - 加密壳/优化少 - 语言常见 C C++ ASM 现实: - 代码量巨大 - 结构复杂 大量静态库 动态库 - 各种乱码 - 大量线代语言特性 OO、Template - 优化和加密壳十分常见 - 语言可能十分神奇 Go 、VB 、Delphi
IDA高级使用
1.设置字符串编码&格式 - 快捷键:Alt-A - 可以设置字符串类型 - 可以设置字符串编码 2.导入/导出数据 - 快捷键:Shift-E - Edit -> Import/Export Data - 操作:选定后按快捷键 - 可以方便地提取数据或修改idb数据库 3.选定大段数据 - 快捷键:Alt-L - Edit -> Begin Selection 4.批量应用类型 - 组合技能 - 操作: - 设置好第一个类型 - 利用刚才的技巧选定数据 - 按d弹出建立数据对话框 - 不勾选Create as array 5.设置间接跳转地址 - 快捷键:Alt-F11 - Edit -> Plugins -> Change the callee address 6.修复跳转表 7.IDAPython - IDA自带支持脚本 - 可以使用几乎所有IDA提供的API - 可以快速完成大量重复性操作 - 可以方便的了解IDA内部的数据和结构
HexRays出错处理
- 常见F5出错信息 格式:XXX;XXX
- positive sp value
- 成因:IDA会自动分析SP寄存器的变化量,由于缺少调用约定(栈调用约定与C调用约定),参数个数等信息,导致分析出错
- 解决方案
- 推荐:在Option -> Generala中设置显示Stack pointer,然后去检查对应地址附件调用的函数的调用约定以及栈指针变化
- 不推荐:在对应地址处按Alt-K然后输入一个较大的负值(有风险)
- call analysis failed
- 成因:F5在分析调用时,未能成功解析参数位置/参数个数
- 解决方案:
- 对于简介调用(类似call eax等),可使用_设置调用地址_的方法解决
- 对于直接调用,查看_调用目标的type_是否正确设置。_可变参数_是引发这种错误的主要原因之一
- cannot connvert to microcode
- 成因:部分指令无法被反编译
- 解决方案:
- 最常见起因是函数中间_有未设置成指令的数据字节_,按C将其设置为指令即可
- 其次常见的是_x86中的rep前缀_,比如_repXX jmp_等,可以将该指令的第一个字节(repXX前缀对应的位置)patch为0x90(NOP)
- stack frame is too big
- 成因:在分析栈帧时,IDA出现异常,导致分析出错
- 解决方案:
- 找到明显不合常理的_stack variable offset_,双击进入栈帧界面,按u键_删除对应stack variable_
- 如果是壳导致的原因,先用OD等软件脱壳
- 可能由化痔灵导致,手动或自动检查并去除花指令
- 十分罕见
- local variable allocation falled
- 成因:分析函数时,有部分变量对应的区域_发生重叠_,多见于ARM平台出现Point、Rect等8字节、16字节、32字节结构时尤其多见
- 解决方案:
- 修改对应参数为多个int
- 修改ida安装目录下的hexrays.cfg中的HOJGNORE-OVERLAPS
- F5分析结果不正确
- 成因:F5会自动删除其认为不可能到达的死代码
- 常见起因是一个函数错误的被标注成了noreturn函数
- 解决方案
- 进到目前反编译结果,找到最后被调用的函数(被错误分析的函数),双击进入再返回(破事HexRays重新分分析相应函数)
- 如果上述方案不成功,那么尽到被错误分析的函数,按Tab切换到反汇编界面,按Alt-P进入界面取消函数的Does not return属性
- positive sp value
HexRays高级使用 (F5高级使用)
- 自定义寄存器传参
- 组合技
- 使用IDA中的_ussercall和userpurge调用约定
- 设置范例
- int_usercall test (intal );
- <>中为对应值的位置
- 第一个<>中为返回值位置,注意返回值的位置即使不变也要填写
- HexRays源码级调试
- 注意:
- F5中显示的变量很可能不是变量原来的值,尤其是寄存器变量,尽量在赋值位置断下并查看值
- 对于优化后的代码,F5调用bug很多
- F5的单步不太稳定,在ARM平台可能会跑飞
- F5的运行至指定位置功能同样不稳定,可能会跑飞
- 注意:
编写IDA processor
32位和64位混合时,手动加载(Munual Load)
见招拆招 -IDA加载头文件
导入头文件 如果能拿到程序的一部分头文件,比如程序公开的API接口,那么可以通过头文件让IDA了解这个结构并辅助分析 改可变参数,…三个点
恢复符号
- 找程序的旧版本
- 大量的程序早起版本中安全意识不够强,没有删除符号等各种信息,可以利用搜索引擎搜索旧版本参考利用
- 对于苹果应用,可以使用AppAdmin获取低版本应用
- Rizzo匹配
- 看程序自带的string
- 许多程序自带了大量调试信息
- Google搜索源代码
- 许多程序早期版本或其他分支源码被流出过
- 大量库开源
- 按获得信息搜索源码(因为大量程序其实直接套用Stack Overflow答案或直接套用CSDN代码)
- 自己制作Signature
- IDA提供自动制作Signature的工具
- 请打开IDASDK68文件夹,找到flair68文件夹
多角度切入
-
一个功能会有多个切入位置
-
例如想让Win10 14393允许关闭UAC时运行 Windows Store App就有如下切入点:
-
(反向)注册表中EnableLUA键值控制UAC开闭
-
(反向)“无法使用内置管理员账户”提示
-
(
正向
)从Store App启动流程入手
- Calcexe
- AppxLauncher.exe
-
直觉硬上
- 如何区分用户代码
- 用户代码一般在程序靠前的地方
- 用户代码一般不会有奇怪算法
- 库函数同样分布在一起,如果发现了_S_consturct之类的典型库函数字符串,那么那一片就都不用看了。
搞定虚表
- 虚表是业界难题
- 虚函数的处理会因为编译器采取的ABI的不同而不同
- IDA本身不支持虚表的各种操作,而且似乎并没有要支持的意思,于是有各路大神开发了插件
- HexraysCodeXplorer
- hexrays_tool
- HexRaysPyTools
- 最后一个经过测试效果最好
首先是安装插件
- 快捷键:Shift-F
- 右键 -> Deep Scan Variable
- 操作:
- 在构造函数中执行上述操作,等待扫描完毕
- 按Alt-F8打开Structure Builder,看到有黄色部分后选择不正确的field点Disable
- 清除所有的黄色部分后即可点击Finalize,在新弹出的窗口中修改名称
推荐书目
《加密与解密》 《IDA Pro权威指南》 《软件调试》