第三章 静态分析技术
解释型语言和编译型语言:https://zhuanlan.zhihu.com/p/37721614
反汇编与反编译
3.1 文件类型分析
工具:PEID、Exeinfo PE、CFF Explorer、StudyPE等
3.2 反汇编引擎
详细介绍:https://bbs.kanxue.com/thread-205590.htm
汇编引擎:ODAssembler、Keystone、AsmJit
反汇编引擎:ODDisasm、BeaEngine、Udis86、Capstone
性能:Udis86>BeaEngine>Capstone.
解码能力:Capstone>BeaEngine>Udis86(Udis86不支持寄存器分析,其他解码能力相近)。
平台支持:Capstone>Udis86;Udis86=BeaEngine。
x86扩展指令集:Capstone>Udis86;Udis86~BeaEngine。
如果需要一个在 x86-64下性能好、解码能力强的反汇编引擎,而且不需要寄存器分析之类的特性,那么 Udis86 更合适;
如果需要寄存器分析功能,那么 BeaEngine与 Capstone 更合适;
如果需要支持ARM架构,那么Capstone更合适。
对汇编引擎来说,如果对指令集、多平台的支持要求极高,Keystone比较合适;
如果喜欢函数式的汇编方式,或者不希望暴露汇编的过程,可以使用 AsmJit。
3.3 静态反汇编
IDA按区块来装载PE文件。
第一阶段:将程序的代码和数据分开,分别标记函数并分析其参数调用,分析跳转、调用等指令关系并给标签赋值。
第二阶段:如果 IDA 能够识别文件的编译类型,就装载对应的编译器特征文件,然后给各函数赋名。随后,IDA会创建一个数据库,其组件分别保存在扩展名为 .id0、id1、.nam和.i的4个文件里,这些文件的格式为IDA专用,在关闭当前项目时,这4个文件将被存档为一个 IDB 文件。一旦 IDA 创建了数据库,就不需要再访问这个可执行文件了,除非使用 IDA的集成调试器调试这个可执行文件本身。再次分析该目标文件时,IDA只需要打开现有数据库,就会将界面恢复为上次关闭时的状态。
IDA的配置文件:ida.cfg(最好用UE等工具打开)
GUI配置文件:idagui.cfg
交叉参考快捷键:X
重命名快捷键:N
可以手动创建一个函数
显示为代码:C
十六进制显示:U
数据类型转换:D
定义为子程序:P
查找地址跳转:G
字符串:A
可以以数组形式显示、创建结构体、枚举类型
库函数识别:https://blog.youkuaiyun.com/abel_big_xu/article/details/124388798
FLIRT介绍:https://www.cnblogs.com/zUotTe0/p/12729390.html
IDA动态调试:https://blog.youkuaiyun.com/m0_52164435/article/details/124871122
https://blog.youkuaiyun.com/qq_35364808/article/details/115988619
修改可执行文件:Patch program
3.4 十六进制工具
WinHex、Hiew、UE、010Editor
3.5 静态分析技术应用实例
GetModuleHandle函数:https://blog.youkuaiyun.com/huhaoxuan2010/article/details/77967348
https://learn.microsoft.com/zh-cn/windows/win32/api/libloaderapi/nf-libloaderapi-getmodulehandlea
DialogBoxParamA:https://learn.microsoft.com/zh-cn/windows/win32/api/winuser/nf-winuser-dialogboxparama
关键判断处
“jnz”修改为“jz”
小练习
移去“Okay,for now,mission failed”对话框。
GetCommandLineA函数:https://learn.microsoft.com/zh-cn/windows/win32/api/processenv/nf-processenv-getcommandlinea
.text:0040123B处:“push 0”修改为“jmp 0x0040124E”
显示一个 MessageBox 对话框,上面显示了用户输人的字符。再显示一个对话框,用于告知用户输入的序列号是正确的还是错误的(“Good”或“Badserial" ).将按钮标题由“NotReversed”改为“_Reversed-”。
修改代码
使序列号为“pediy”
自定义算法(取代原来的算法)
00401270 83F9 05 cmp ecx, 5
00401273 75 58 jnz short 004012CD ; 检测文本长度是否为5,不是的话跳到错误对话框
00401275 BA 00304000 mov edx, 00403000 ; ASCII "pediy"
0040127A 8A18 mov bl, byte ptr [eax]
0040127C 8A38 mov bh, byte ptr [eax]
0040127E 3ADF cmp bl, bh ; 逐个字符比较
00401280 75 4B jnz short 004012CD ; 不相等的话说明输入错误
00401282 40 inc eax ; 加一,用以比较下一个字符
00401283 42 inc edx
00401284 49 dec ecx ; 循环的次数减一
00401285 74 31 je short 004012B8 ; 比较完了,序列号正确,跳转到正确的分支
00401287 ^ EB F1 jmp short 0040127A ; 循环