参考教程:https://www.wangan.com/docs/551
http://blog.nsfocus.net/linux-overflow-vulnerability-exploitation/
IDA F5不能正确反编译的情况:
https://bbs.pediy.com/thread-212429.htm
原因在于IDA用F5是通过;判断eax作为函数返回值
笔记:逆向003.zip
伪代码查看交叉引用是x,汇编代码ctrl+x和x一样
一、使用IDA分析程序
- IDA 的快速启动界面(打开一个可执行文件)
- 打开一个新的应用程序时,IDA的自动识别功能
- 关闭IDA的时候,会自动的提示是否需要保存当前的数据文件(.idb),文件中存储了分析的过程中存在的函数名称等数据,以及 EXE 程序的本体,以后再次进行分析就不需要源文件。
二、 认是IDA的界面
- 主界面的默认布局如下,其中保存了多个不同的窗口,如果不小心关闭了窗口,可以通过菜单中的 VIEW -> OPEN Subview 再次打开指定的窗口,每一个窗口都可以同时存在多个
- IDA 代码显示界面
- IDA 的内存窗口使用,可以通过右键修改内存的显示方式
- IDA 导出窗口,查看导出函数,找到 OEP
- IDA 导入窗口,查看导入函数
- IDA 名称窗口,可以通过 F1 查看具体的类型
- IDA 的函数窗口,可以查看函数的信息
- IDA 字符串窗口,配合交叉引用有很大的作用
- IDA 区段窗口:使用的比较少,主要是查看区段属性
- IDA 签名窗口(Shift + F5 ),合理的使用签名可以让 IDA识别更多的函数,尽量打开一个程序的第一件事情就是加载签名,主要会识别一些库函数,防止不小心分析系统模块
vc32mfc、vc32rtf是常用的载入符号
- IDA 的类型窗口,可以添加内置类型
- 本地类型窗口,当前已经可以使用的一些内置结构体
三、如何查找 main 函数
- 使用 OD 查找 main 函数: 1 + 2 + 3(三个间隔的函数中间一个) + 4
四、使用IDA分析程序
一、局部变量
int _tmain(int argc, _TCHAR* argv[])
{
// 局部变量
int nNum = 1;
float fNum = 2.5;
char ch = 'A';
printf("int %d, float %f, char %c", nNum, fNum, ch);
return 0;
}
使用快捷键 n
可以给函数或者变量或者代码修改名称
- 如果不能确定一个函数的实际名称,尽量不要使用内置的名称
- 对于 IDA 来说,所有的操作都是不可逆的,可以使用 ESC 返回上一层,使用 ctrl+enter 进入函数
IDA中可以使用冒号(:)和分号(;)
对代码进行注释,合理的注释可以更方便的分析可以使用 y
或者菜单项修改变量的类型
二、全局变量
// 全局变量,静态变量
int g_nNum = 1;
static int g_nCount = 2;
float g_fNum = 2.5;
char g_ch = 'A';
int _tmain(int argc, _TCHAR* argv[])
{
printf("int %d, float %f, char %c",
g_nNum, g_fNum, g_ch);
return 0;
}
交叉引用:
int _tmain(int argc, _TCHAR* argv[])
{
int nArr[5] = { 1, 2, 3, 4, 5 };
int n = 2;
nArr[n] = 20;
return 0;
}
函数的模拟栈帧
将类型转换成数组的操作
如果不小心修改了代码,
并且无法还原,可以执行下面的操作
- u: 表示取消这个函数的定义,取消后就是字节
- c: 将目标看作是一段代码进行解释
- p: 将目标看作是一个函数解释,解释函数的过程中会重新构建模拟栈帧
四、 结构体类型
struct MyStruct{
int nNum;
float fNum;
char chA;
};
void Print(MyStruct stc)
{
printf("int %d, y %f, z %c", stc.nNum, stc.fNum, stc.chA);
}
int _tmain(int argc, _TCHAR* argv[])
{
MyStruct stc = { 1, 2.2, 'A' };
stc.fNum = 5.5;
Print(stc);
return 0;
}
添加一个新的结构体
为结构体添加字段
应用结构体
五、一些内置函数的特征
CheckEsp 函数:
用于检查堆栈是否平衡,通常在函数调用后使用
cmp xxx, esp
call j___RTC_CheckEsp
CheckStackVars 函数:
用于检查数组是否越界,原理是判断数组后的 cc 有没有被覆盖
lea edx, dword_411420(全局变量)
call CheckStackVars