id0:二叉树数据库
id1:文件包含描述每个程序字节的标记
nam:包含IDA NAME窗口的数据库
til:本地数据库有关信息
与图标视图一一对应,通常打开两个视图分别对比工作,按住shift+;可以添加自己的注释。
F:为重点查看函数,常规函数
L:为库函数(动态链接库)
A:字符串
I:系统导入函数(基本不用看)(粉色导航代)
Sub_XXXXXX 子函数
loc_xxxxxx 地址处指令
byte_xxxxxx 8位数据
word_xxxxxx 16位数据
dword_xxxxxx 32位数据
unk_xxxxxx 未知,unknow
查找字符串对应的位置
同步反汇编窗口,更好的监视
唯一接口,输出的函数,和main一样
列出二进制导入的函数,系统导入的
识别所有函数名称
查看结构体,双击进入结构体内部查看详细信息
IDA自动识别枚举代码类型
可看到克重头文件包含库
右键鼠标可以插入自己要的库
查看上层函数,本级函数级内部调用了些什么函数,与图表视图同步查看工作最好。
需要自己分析的问题
比如:未初始化的变量
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
蓝色为常用函数,双击进入导航函数内部,与图表结合使用。
g键:跳转地址
1。先要保护现场
2。讲参数按照调用约定放在被运行栈帧上,这样这个栈帧的栈顶指针就会发生改变
3。如果有必要,调用函数会配置一个栈指针,保存调用方希望保持不变的内容(寄存器值)
4。被调用函数为它可能需要的任何局部变量发配空间,需要栈帧栈顶向上(-操作)开辟地方
5。被调用函数返回值存放在EAX或者存放在可以立即被调用到的地方
6。一旦函数完成其他操作,任何局部变量都释放了
7。调用地方如果重新获得控制权,删除再栈中开辟的空间(+操作)
8。完成“序言(3,4)”“过程(5,6)”“尾声(6,7)”
C的调用约定_cdecl(参数从右向左一次入栈),清理方式:调用者清理(“老子”清理“儿子”)
对于参数可变化的:printf("XXXXX");
VOID demo_cdecl(int w,int x,int y,int z)
asm
push w
push x
push y
push z
call demo(进入了函数,开始执行了。。。。。。)
add esp,16 4*sizeof(int)
标准调用_stdcall
VOID demo_stdcall(int w,int x,int y,int z)
push w
push x
push y
push z
call demo(进入了函数,开始执行了。。。。。。)
ret 16
快速调用_fastcall
VOID demo_fastcall(int w,int x,int y,int z)
前两个(ECX=W,edx=x)参数将被分配给ECX,EDX
剩下的都被按照_stdcall调用约定
ret 8
C++调用约定
使用this指针
VC提供了 thiscall调用,将this传递给而ecx
GC++中被当做静态,存放在栈顶
1. 搜索数据库
2. 文本搜索 ALT+T
3. 二进制搜索 ALT+B
右键哑名可以重命名(Rename),改一处所有变量全部会跟着改变。快捷键点击哑名按n键,空格还原变量名。
arg_0(栈变量)
var_4(普通变量)
一个函数只能拥有一个arg_0
shift+; 对程序注释
右键鼠标常数转换对应进制常数
删除函数:右键函数体(交叉引用)-> 编辑 -> 函数 -> 删除函数
编辑函数:右键函数体 -> 编辑函数(还有局部变量和寄存器保存功能)
函数 -> 编辑 -> 转换为代码(转换为数据)
或者:左键点击函数体,按C转换代码,按D转换数据
改变数据大小,比如db改为dw:选项 -> 设置数据类型
(1)了解使用寄存器的方式,可以推断出数据类型的和、大小,如果一条指令从内存中加了一个32位的寄存器,相关的内存保存了一个4字节的类型
(2)函数原型分配参数数据类型,IDA维护一个庞大的函数原型,分析传递的参数类型,让他与某个内存的地址关联起来,CRITICAL_SECTION(Windows的数据类型)
(3)分析字节序列,知道肯能的数据类型,扫描2进制,知道字符串内容
name generation(命名生成)
转换数组:编辑 -> 转换为数组组合
全局:mov dword_21365c, 10
局部:mov [ebp+var_c], 10
结构体界面,按insent健,起名字后OK,按d健插入数据(在按d为类型大小变换),在ends按a为插入字符串,右键菜单转换数据数组,按n健重命名,按u键删除字段,按delete删除结构体。
编辑 -> 结构体变量,在数据中转换为结构体。
alt+k :堆结构体
文件 -> 加载文件 -> 分析 C 头文件
文件 -> 生成文件 -> 数据库转存为idc文件
ecx=this
class A:
{
public:
A();
virtual void vfunc1()=0;
virtual void vfunc2();
virtual void vfun3();
virtual void vfun4();
private:
(虚拟指针)
int x;
int y;
};
class B:public A
{
public:
B();
virtual void vfunc1();
virtual void vfunc2();
virtual void vfunc5();
private:
int z;
};
void call_vfunc(A* a)
{
a->vfun3();
}
int main()
{
A *a_ptr =new B();
call_vfunc(a_ptr);
}
B::vfunc3()
push ebp
mov ebp,esp //保存现场
mov eax,[ebp+10d] //a_ptr 4个函数+虚拟指针指向虚函数表
mov edx,[eax] //*a_ptr 1 将虚拟表指针内容放入edx
mov ecx,[ebp+10d] //*a_ptr 将虚拟表指针放入cx,继承作用
mov eax,[edx+8] //a->vfun3();2 0,4,8 取第三个函数也就是vfun8 a->vfun3();
call eax //3 call就是调用a->vfun3()
// 2个可以简写为:mov eax,[edx+B_Vtable.vfunc3]
jmp:if跳转
call:函数调用
上箭头:引用出在上方
下箭头:引用处在下方
j: jmp
r: read 读数据区的某数据
w: weite 往某变量写数据
o: 偏移 offset引用
p: 调用子程序
详细:https://blog.csdn.net/hgy413/article/details/50594320
交叉应用附近,点击变量,右键跳转到交叉引用列表,或者按x
查看函数调用
查看函数调用图