一、PE文件的分析流程。
1. 对于DLL文件,先查看它的导出表,确定一些功能函数。
2. 查看导出表,看调用了那些类型的API。比如可能有如下几类
(1) 文件操作、创建、写、读
(2) 注册表操作,读、写
(3) 提权相关函数(Privage)
(4) 进线程函数
然后根据这写不同类型的导出函数,用X快捷键查看有哪些地方引用了,可以分析出一些sub_0xxxx函数的功能。
3. 用[shift+F12]调出字符串表,再根据这些字符串,查看引用的地方,也可以分析出一些sub_0XXXX函数的功能。
二、主流程分析
1. 对于一个函数内部的分析,或者说,对于一个主流程的分析,其调用栈非常关键,
一般来说,通过调试器或者IDA逐层分析到的栈会有很多层,少则十几层,多则几十层。
栈帧 | 函数 |
1 | Main |
2 | SetDefaultBrowser |
3 | QueryBrowerInfo |
4 | … |
5 | … |
6 | STL函数、BOOST库 |
7 | … |
8 | … |
9 | CRT函数库 |
10 | … |
11 | … |
12 | 操作系统API调用 |
13 | SHRegSetString |
14 | RegCreateKeyEx |
在用IDA分析时,经常会遇到这么多层的栈,一般来说,程序员写的(DIY代码)也就四五层这样,因为根据程序设计的规则,主干功能,调用层次不会写的太深(也就是表格中橙色部分)。大部分程序会调用CRT函数和STL函数库,也有很多软件公司会自己写一些基础类库,这些函数会分布在第六七八层这样,表格中浅蓝色部分。再下面可能会有CRT的运行时函数,这些函数一般IDA会帮助分析出名子,这也占用两三次的栈空间(表格中黄色部分)。再下面就是系统API了,表格中紫色部分。
2. 在分析过程中,要先了解程序的主要功能,大概的逻辑,比如会写某几个注册表键值,会计算一个hash编码,会创建子进程等等,越具体越好。然后再逆向分析,分析过程中我们主要分析程序员DIY的代码,也就是表格中的橙色部分。对于下层的STL等第三方函数库,基本了解功能就好,不要死扣具体逻辑。
3. 对于sub函数,编译器和IDA有固定的编译安排和命名规则,一般对于CRT的或者STL的等这些函数,一般是sub_0000xxxx,也就是偏移比较小的,而且会将同一个cpp的,同一个lib库的函数连接在一起。比如std::string的构造函数和std::string的拷贝、拼接等子函数都是挨着的,比如可能的IDA命名是sub_00001234,sub_00001235,sub_00001236,sub00001237等,偏移是离的很近的。
二、IDA的常用方法-快捷键
1. 查找引用 x 快捷键 可以查找 导入函数 也可以查找 字符串的 引用
2. ESC 快捷键 退回到上一层函数
3. shift+F12 显示字符串列表。