C++反汇编与逆向分析实战

今天开始学习这本书,做一些笔记,之前有一些基础,理解的部分便少做些记录了。

IDA Pro 常用快捷键

快捷键 功能
A 结实光标的地址为一个字符的首地址
B 十六进制和二进制进行转换
C 解释光标处地址为一条指令
D 解释光标为止为数据
G 快速查找大对应地址
H 十六进制和十进制转换
K 将数据解释为栈变量
; 添加注释
M 解释为枚举成员
N 重新命名
O 解释数据为一个数据读研偏移量
T 解释数据为一个结构体成员
X 切换师徒到交叉参考模式
Shift +F9 添加结构体

浮点数的编码方式

float:

31 位表示正负
23-30 位表示指数部分
0-22 位表示科学计数法尾数部分

指数部分 01111111 表示为0 ,数字自行加减,加减的数值为科学计数法小数点左右移动的值。

尾数部分 由于最高位一定是1,忽略不计即可,举例1100.11

0 10000010 100110000000000000000

double:

63 位表示正负
52-62 位表示指数部分
0-51 位表示科学计数法尾数部分

基本浮点数指令

浮点寄存器是通过栈结构来实现的 由ST(0)-ST(7) 共8个栈空间组成,每个浮点寄存器占8个字节

每次使用浮点寄存器都是率先使用ST(0),不能越过ST0来访问ST1

浮点寄存器的使用就是压栈出栈的过程。

当ST0 有数据的时候,执行压栈操作后,ST0的数据会被装入ST1。

如无出栈操作则顺序向下压栈,直到浮点寄存器占满,常用浮点指令如下表:

指令名称 使用格式 指令功能
FLD FLD IN 将浮点数IN压入ST0中,IN(mem32/64/80)
FILD FLID IN 将整数IN压入ST0中,IN(mem32/64/80)
FLDZ FLDZ 将0.0压入ST(0)
FLD1 FLD1 将1.0压入ST(0)
FST FST OUT 将 ST0中的数据存入OUT
FSTP FSTP OUT 将 ST0中的数据存入OUT,并执行出栈操作
FIST FIST OUT ST0以整数形式存入OUT地址中
FISTP FIST OUT ST0以整数形式存入OUT地址中,并执行出栈操作
FCOM FCOM IN 将IN地址数据与ST(0)进行比较,影响对应标志位
FTST FTST 比较ST0是否为0.0,影响对应标志位
FADD FADD IN 将IN地址内的数据与ST0做加法运算,结果放入ST0中
FADDP FADDP IN 将IN地址内的数据与ST0做加法运算,结果放入ST0中,并执行出栈操作

其他运算指令类似,只需要在指令前面加F即可

浮点数返回值存放在ST0当中,float同样以8字节处理,参数传递时无法直接push,需要sub ebp,8 再 fstp qword ptr[esp]

指针-引用

引用的本质是指针,反汇编下无引用类型

程序的真正入口

实际上程序的入口并不是main,只是我们定义的程序入口,有启动程序调用程序入口,中间还有一段代码过程。

在VC++6.0中,实际的程序入口是mainCRTstartup,其中代码主要是获取系统版本信息,堆空间初始化,初始化县城环境,宽字符处理代码等

其他版本各不相同

//————————————

详细初始化环境步骤:

GetVersion() 获得系统版本

_heap_init() 初始化堆操作

GetCommandLineA() 获取命令行参数

_crtGetEnvironmentStringA() 获取环境变量信息

_setargv() 根据获取到的信息,配置argv

_setenvp() 根据获取到的信息,配置环境变量

_cinit() 用于全局数据和浮点寄存器的初始化

若没有进行堆初始化,则无法申请内存,会产生错误

通常OD加载函数会停在程序入口处,而不会直接定位到main函数,利用上面的函数,进行下段,可以快速定位到main函数

在VS2003之后,微软加入一个一个防治缓冲区一处的编译选项 /GS,编译器会在每个函数的栈内分配一个随机标记,而这个随机数则由应用程序入口代码负责初始化