1. 启动函数
功能: 检索新进程命令指针, 环境指针, 全局变量初始化, 内存堆栈初始化
比如:
GetCommandLineA 命令指针
GetStartupInfoA 启动信息
GetModuleHandleA 执行文件基地址
编译器自动加入的代码:
- 00401020>/$ 55 push ebp
- 00401021 |. 8BEC mov ebp, esp
- 00401023 |. 6A FF push -1
- 00401025 |. 68 A0504000 push 004050A0
0040102A |. 68 7C1C4000 push 00401C7C ; SE 处理程序安装
- 0040102F |. 64:A1 0000000>mov eax, dword ptr fs:[0]
- 00401035 |. 50 push eax
- 00401036 |. 64:8925 00000>mov dword ptr fs:[0], esp
- 0040103D |. 83EC 10 sub esp, 10
- 00401040 |. 53 push ebx
- 00401041 |. 56 push esi
2. 函数及其参数
反编译分析时, 将注意力集中在函数的识别以及参数的传递上
函数多以 call(保存函数返回信息) 地址为跳转 也有动态计算或者寄存器传地址
函数的参数传递方式有三种:
堆栈方式
寄存器方式
全局变量
3. 函数的返回值
1. return 操作符返回值
od 遇到了一个 bug 就是不是每个指令都会下到 int3 断点 从而 debug 时 F8 单步有一些代码是一起执行的.(这让想起了原子操作)
一般的返回值时存放在 eax 寄存器中, 如果超过了容量则会放到 edx 寄存器中.
2. 通过参数按照传引用的方式返回
注意 ds 和 ss 的区别 然后一般通过引用来传值需要使用变量的地址, 在调用某个函数时再把变量的地址传给函数.
3. 通过全局变量返回
4. 数据结构
逆向算法和数据结构
1. 局部变量
1. 堆栈分配局部变量
在堆栈中进行分配, 分配完在释放. 或者直接存放在寄存器中.
分配 [ebp-xxx]
访问 [ebp+xxx]
初始化局部变量的两种方法:
- mov [ebp-xxx],5
- push 5
2. 利用寄存器存放局部变量
堆栈占用两个寄存器, 编译器会利用剩下的 6 个通用寄存器尽可能的有效存放局部变量. 寄存器不够时才会使用堆栈, 且局部变量的生命周期比较短, 需要确定时那个寄存器存放的那个变量.
2. 全局变量
全局变量存放在内存区, 静态 pe 的. data 的可读写区域的固定地址上. 访问时即访问硬编码的特定地址即可.
(静态变量 static 作用范围有限)
如果是常量 则在只可读区域内.
3. 数组
来源: http://www.bubuko.com/infodetail-2700339.html