《逆向工程核心原理》学习笔记2
逆向工程核心原理第三章
准备阶段
- 软件:Ollydbg,visual studio community
- 使用visual studio创建一个名为LittleEndian的c++控制台项目,粘入以下代码,然后运行生成x86(Win32)的LittleEndian.exe文件
#include "windows.h"
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读取内存中的数据时,是从低地址向高地址方向进行读取的,而运算也是从低位开始的)
- 用以下例子来展示同一数据用大端序和小端序储存时有何不同
BYTE 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文件,如图先用搜索字符串(abcd)的方式定位到我们的main函数所在位置(现在vs编译器搞了一大堆乱七八糟的东西进去,找main都很蛋疼),在函数开始位置"00641750"设下断点
- 双击即可跳转到使用abcd的地方
- 运行调试,然后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位
小结
- 学习和测试了通用寄存器的使用,了解了低位和高位寄存器使用时的具体效果,其他寄存器的使用有待后面继续学习补充