1.寄存器rax,eax,ax,ah,al

  我们时常能够在IDA中看到不同的寄存器,在它的汇编代码中可以看见像rax,eax等这些寄存器,实际上它们指的是同一个寄存器,只是位数不一样而已。下表说明了rax, eax, ax, ah, al之间的区别。

寄存器(以rax为例) 位数(二进制) 位数(十六进制)
rax 全 64 位 全 16 位
eax 低 32 位 低 8 位
ax 低 16 位 低 4 位
ah ax的高8位 ax的高2位
al ax的低8位 ax的低2位

  其它寄存器例如rbx, rcx, rdx也是如此,但是寄存器rdi, rsi, rsp, rbp, rip的16位形式di, si, sp, bp, ip就不能够再细分为低8位或者高8位了。

2.不同寄存器的功能

  接下来介绍不同寄存器的功能。

通用寄存器

寄存器名称 具体 其它形式 用途
EAX 累加(Accumulator)寄存器 RAX,AX(AH、AL) 常用于乘、除法和函数返回值
EBX 基址(Base)寄存器 RBX,BX(BH、BL) 常做内存数据的指针, 或者说常以它为基址来访问内存.
ECX 计数器(Counter)寄存器 RCX,CX(CH、CL) 常做字符串和循环操作中的计数器
EDX 数据(Data)寄存器 RDX,DX(DH、DL) 常用于乘、除法和 I/O 指针
ESI 来源索引(Source Index)寄存器 RSI,SI 常做内存数据指针和源字符串指针
EDI 目的索引(Destination Index)寄存器 RDI,DI 常做内存数据指针和目的字符串指针
ESP 堆栈指针(Stack Point)寄存器 RSP,SP 只做堆栈的栈顶指针; 不能用于算术运算与数据传送
EBP 基址指针(Base Point)寄存器 RBP,BP 只做堆栈指针, 可以访问堆栈内任意地址, 经常用于中转 ESP 中的数据, 也常以它为基址来访问堆栈; 不能用于算术运算与数据传送

  再来小结一下CTF逆向中常用寄存器的用途。

  eax:函数返回值存放寄存器。有时程序会判断字符串长度调用strlen函数,长度(结果)就会放在eax寄存器里;在比对字符串是否为正确的flag或其它目标字符串时(这个过程通常封装在函数里)也会将结果放到eax中,一般地,匹配则函数末尾会有指令“mov eax, 1”,不匹配则有指令“xor eax, eax”(自身异或后为0),最后返回到母函数时会有指令“test eax, eax”,即自身做“且”运算同时不改变eax里的值,再跳转到不同的代码段。

  ebx:最近用的不是特别多,可能在访问指针类型数据时用的较多。

  ecx:在循环操作中用的比较多,比如for循环里的i值就可能放到ecx里,不断的自增或自减,最后与某个内存基址相加以访问不同的内存空间。

  edx:乘除法用的比较多,特别注意IDA中的imul, idiv指令,观察edx寄存器是否会发生什么变化。

  esi, edi:常被用来做字符串指针寄存器,经常同lea指令结合使用。有字符串处理时可以看看这两个寄存器。

  esp, ebp:esp是栈顶地址寄存器,存放栈顶地址;ebp则为当前栈帧(Stack Frame)的基地址寄存器,存放当前所处栈帧的基地址。一般esp地址小于等于ebp地址,当esp地址减小的时候,说明系统在分配栈空间,反之则是回收栈空间。这两个寄存器在函数调用时经常用到,因为要保护现场,子函数执行完毕后就是靠这俩寄存器恢复到母函数的现场。

指令指针寄存器

寄存器名称 具体 其它形式 用途
EIP 指令指针(Instruction Pointer)寄存器 RIP,IP 总是指向下一条指令的地址; 所有已执行的指令都被它指向过.

  这个寄存器肯定是不能作为数据存储的,因为下一条指令的地址必须要给出。

3.CTF路线图

  点击放大