逆向工程核心原理第三章
准备阶段
软件:Ollydbg,visual studio community
使用visual studio创建一个名为LittleEndian的c++控制台项目,粘入以下代码,然后运行生成x86(Win32)的LittleEndian.exe文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
BYTE b = 0x12;
WORD w = 0x1234;
DWORD dw = 0x12345678;
char str[] = "abcde";
int main()
{
byte lb = b;
WORD lw = w;
DWORD ldw = dw;
char* lstr = str;
return 0;
}
字节序
字节序指多字节数据在计算机内存中存放的字节顺序,字节序主要分为大端序和小端序。大端序:数据的高位储存在低位内存地址(高位在前,低位在后这种符合我们人类的书写习惯,例如书写时:个位在后,十位在前);小端序:数据的低位储存在高位内存地址(低位在前,高位在后,这种更符合计算机读取内存的方式,因为CPU读取内存中的数据时,是从低地址向高地址方向进行读取的,而运算也是从低位开始的)
用以下例子来展示同一数据用大端序和小端序储存时有何不同
1
2
3
4BYTE b = 0x12;
WORD w = 0x1234;
DWORD dw = 0x12345678;
char str[] = "abcde";Type Name Size 大端序类型 小端序类型 BYTE b 1 [12] [12] WORD w 2 [12][34] [34][12] DWORD dw 4 [12][34][56][78] [78][56][34][12] char[] str 6 [61][62][63][64][65][00] [61][62][63][64][65][00]
用OD查看小端序
Ollydbg打开我们的LittleEndian.exe文件,如图先用搜索字符串的方式定位到我们的main函数所在位置,在函数开始位置"00641750"设下断点
运行调试,然后F8逐步运行至"00641775"位置,可以看到左下方位于代码窗口和数据窗口之间出现了"ds:[0064A000]=12",结合我们的代码和"00641775"的汇编指令可知,此时程序正在获取全局变量"b=0x12"的值,点击左下角数据窗口,Ctrl + G 输入"0064A000"地址跳转查看"0064A000"的数据,可以看到数据正是我们的0x12
找到全局变量b所在位置后,其余全局变量也很容易找到,这里直接可以看出其余变量紧跟在全局变量b之后,从图可以看到WORD和DWORD类型采用的是小端序的方式储存
逆向工程核心原理第四章
IA-32寄存器
- 通用寄存器(32位,8个):EAX、EBX、ECX、EDX、ESI、EDI、EBP、ESP
- 段寄存器(16位,6个):CS、DS、SS、ES、FS、GS
- 程序状态与控制寄存器(32位,1个):EFLAGS
- 指令指针寄存器(32位,1个):EIP
E(Extended)开头的寄存器代表,该寄存器在16位CPU(IA-16)时就已经存在
通用寄存器
- EAX、EBX、ECX、EDX、ESI、EDI、EBP、ESP,这8个寄存器均有对应的16位寄存器,其中AX~DX还可细分位高(H)、低(L)两种独立的寄存器。以EAX为例,如果需要用全部4个字节则使用EAX,如果只使用2个字节则AX(EAX低16位),如果使用一个字节可以使用AH(AX高8位)或者AL(AX低8位)
31==>16 | 15==>8 | 7==>0 | 16-bit | 32-bit |
---|---|---|---|---|
AH | AL | AX | EAX | |
BH | BL | BX | EBX | |
CH | CL | CX | ECX | |
DH | DL | DX | EDX | |
BP | EBP | |||
SI | ESI | |||
DI | EDI | |||
SP | ESP |
下面用Ollydbg演示EAX、AX、AH、AL使用时的效果,首先可以用Ollydbg任意打开一个exe可执行文件,这里还是用上面的LittleEndian.exe为例
按空格快捷键,修改程序下一句运行的汇编指令,这里修改为
mov eax, 0x12345678
,可以看到修改前,左边的寄存器EAX值为0x00FF5DC0,保存后按F7运行查看结果运行后可以看到寄存器EAX结果变为了"0x12345678",修改EAX值成功
下面测试AX,同样按空格,修改汇编指令,输入
mov ax, 0x8765
,保存后按F7运行查看结果运行可以看到寄存器EAX由原来的"0x12345678"变成了"0x12348765",说明AX寄存器为EAX寄存器的低16位
同样地接着来测试AH,空格修改下一句汇编指令为
mov ah, 0xFF
,保存后按F7运行,可以看到寄存器EAX的值由原来的"0x12348765"变为了"0x1234FF65",说明AH寄存器为AX寄存器的高8位同样地测试AL,修改汇编指令为
mov al, 0x00
,保存后按F7运行,可以看到寄存器EAX最后两位由原来的"65"变为了"00",所以AL寄存器位于AX和EAX的低8位
小结
- 学习和测试了通用寄存器的使用,了解了低位和高位寄存器使用时的具体效果,其他寄存器的使用有待后面继续学习补充