@TOC
内存图
exe 程序运行时 内存的划分,定义
代码区
可读可执行
存放 if,else,while 等你写的代码.
堆栈
参数,局部变量,临时数据. 比如: 一些中间结果就是临时数据
当堆栈执行完毕,其中的数据变成 垃圾数据
堆
可读可写
动态申请的,大小是可变的.
全局变量区
可读可写
存放了全局变量
常量区
只读
存放常量的地方
详解
全局变量
int g,n = 10;
int Function()
{
int x = 2;
int y = 3;
return g+n+x+y;
}
全局变量 在程序编译完毕后的地址 已经确定下来了.
全局变量所占内存会一直存在,直到整个进程结束
全局变量反汇编识别
MOV 寄存器 , byte/word/dword ptr:ds[2012345678]
通过寄存器宽度 或者 byte/word/dword 判断全局变量的宽度
最后一行 mov [arr (00427320)],eax.等同于
mov dword ptr:[00427320] ,eax
这里最后eax 的mov 和 add, mov 是一个死的地址. 所以是一个全局变量. 这个地址是一个基质
局部变量
函数内的变量
ebp - 4. 大多是局部变量
参数判断
判断参数有几个参数
这里 代表着 不同参数调用方式之后的堆栈平衡的方式
平衡堆栈, ret 参数. 4 字节存放一个参数 .以此类推. 分别是1,2,3,4 个参数
fastCall 传递参数使用 寄存器传递参数
案例
1
这种情况下,可能都是参数,也可能只有几个是参数
有时候我们看不到 调用代码的地方. 也就看不到 push 操作
2
我们跟到代码中.
1 不考虑 ebp,esp
2 只找给别人赋值的寄存器,eax,ecx,edx,ebx,esi,edi
3 找到以后追查其来源. 如果该寄存器中的值不是在函数内赋值.
那么一定是传递进来的参数
1 寄存器 + ret 4 = 参数个数
2 寄存器 + [ebp + 8 ] + [ebp + 0x ] = 参数个数
图: ret 4 代表有一个压栈的参数
IF
# ebp保存的是 栈低的地址. 将 ebp 内部的值入栈
push ebp
# 栈顶 的值 赋给 ebp.
mov ebp,esp
# 开辟 0x40 个字节. 开辟堆栈空间完成
sub esp,0x40
# 将ebx 的值入栈
push ebx
# 将 esi的值入栈
push esi
# 将edi的值入栈
push edi
# 将 ebp - 40h 的值 是一个地址值,将该地址值内部数据的地址给 edi 存储
lea edi,[ebp - 40h]
# 填充堆栈空间数据
mov ecx,10h
mov eax,0cccccccch
rep stos dword ptr:[edi]
主要功能
主要分析识别 if 语句
看到一些影响标志位的 语句,看到 jcc指令语句之后. 很可能就是 if 语句