逆向汇编常见知识点
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路线图
点击放大



