《逆向工程核心原理》学习笔记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位
小结
  • 学习和测试了通用寄存器的使用,了解了低位和高位寄存器使用时的具体效果,其他寄存器的使用有待后面继续学习补充