什么是寄存器
寄存器位于CPU内部,是一些小型存储单元,用于临时保存需要计算的数据、运算结果及CPU运行所需的信息。它们如同CPU的贴身助手,记录当前任务并规划下一步行动,使CPU能够高效地执行任务。
寄存器种类繁多,其中最常见的是通用寄存器。
寄存器(64位/32位)及其作用
| 寄存器 | 作用 |
|---|---|
| RAX/EAX | 通常用于执行加法操作,函数调用的返回值也通常存放在这个寄存器中。 |
| RBX/EBX | 主要用于数据存取。 |
| RCX/ECX | 常作为计数器使用,例如在for循环中。 |
| RDX/EDX | 在读写I/O端口时,用于存放端口号。 |
| RSP/ESP | 栈顶指针,指向栈的顶部。 |
| RBP/EBP | 栈底指针,指向栈的底部,常用于定位函数在栈中的局部变量。 |
| RSI/ESI | 在字符串操作时,用于存放数据源的地址。 |
| RDI/EDI | 在字符串操作时,用于存放目的地址,常与RSI配合使用,执行字符串复制等操作。 |
| R8~R15(64位独有) | 指令寄存器,指向即将执行的指令地址。CPU通过不断取出并执行这些指令来工作,这一过程类似于秘书安排事务,CPU执行任务。 |
ebp+偏移量
指令寄存器对于黑客尤为重要,他们试图通过控制它来执行恶意代码。
汇编基础
了解一些基本的汇编命令,旨在能读懂大部分的反汇编代码,而不是深入学习汇编语言。
0x01 MOV
MOV 是一种数据传送指令,其基本格式为:
mov <目标操作数>, <源操作数>
具体用法包括:
- 常数到寄存器
- 寄存器到寄存器
- 立即数到内存
- 内存到寄存器
- 寄存器到内存
mov eax, 32
将一个明确的数值放入寄存器。
mov ebx, eax
将数据从一个寄存器复制到另一个寄存器。
mov [eax], 42
将立即数42存入地址10000处。
mov eax, [10000]
将地址10000处的值存入寄存器eax。
mov [ebx], eax
将寄存器eax的值存入地址10000处。
MOV
[]
eax
ebx
0x02 LEA
LEA 是一条取地址指令,其基本格式为:
LEA <目标寄存器>, <内存源操作数>
例如:
lea eax, [esi]
这条指令相当于C语言中的:
eax = &*(esi)
具体步骤如下:
- 获取寄存器esi中的地址值。
- 解引用该地址,找到存储的值。
- 计算该值所在的地址,并将其存入eax。
LEA
[eax]
esi
10000
42
0x03 ADD
ADD 是一条算术运算指令,其使用方式与MOV类似:
add <目标操作数>, <源操作数>
等价于C语言中的:
<目标操作数> += <源操作数>
用法与MOV相同,不再赘述。
ADD
MOV
0x04 SUB
SUB 是一条算术运算指令,其使用方式与ADD相同:
sub <目标操作数>, <源操作数>
等价于C语言中的:
<目标操作数> -= <源操作数>
用法与MOV相同,不再赘述。
SUB
ADD
MOV
0x05 AND
AND 是一条逻辑运算指令,表示“与”操作,其基本格式为:
and <目标操作数>, <源操作数>
逻辑运算“与”意味着:遇0则0,只有两个对应的位都为1时,结果的该位才为1。具体用法包括:
- 寄存器 AND 寄存器 -> 寄存器
- 寄存器 AND 立即数 -> 寄存器
- 内存 AND 立即数 -> 内存
- 寄存器 AND 内存 -> 寄存器
AND
0x06 XOR
XOR 是一条逻辑运算指令,表示“异或”操作,其核心功能是:
对两个操作数进行按位“异或”运算,并将结果存放到目标操作数中
XOR
异或逻辑“异或”遵循以下规则:当两个对应的位不相同,结果位则为1;若相同,则结果位为0。此运算符有以下几种应用方式:
- 寄存器与寄存器之间的异或 -> 结果存入第一个寄存器
- 寄存器与立即数之间的异或 -> 结果存入寄存器
- 内存与立即数之间的异或 -> 结果存入内存
- 寄存器与内存之间的异或 -> 结果存入寄存器
指令的基本格式为:XOR <目标操作数>, <源操作数>
CALL 指令用于调用函数。在执行此指令时,CPU 将执行一系列操作,具体细节将在后续章节 PWN入门之四:C语言调用栈 中详细介绍。
CALL
CALL 指令的目标地址可通过以下几种方式指定:
| 寻址方式 | 示例 | 解释 |
|---|---|---|
| 直接调用 (Direct Call) | | 目标地址为明确的符号或固定内存地址,由汇编器/链接器计算实际地址。 |
| 寄存器间接调用 (Register Indirect Call) | | 目标地址存储在寄存器 中,运行时动态决定跳转地址。适用于函数指针调用、虚函数表跳转等场景。 |
| 内存间接调用 (Memory Indirect Call) | | 目标地址位于内存 所指向的位置(双字),用于动态调用。 |
| 远调用 (Far Call) | (16位/特殊场景) | 同时更改代码段寄存器 和指令指针 /,用于跨段调用。现代操作系统(保护模式)中较少直接使用。 |
RET 指令用于从子程序返回到调用者,通过恢复栈上保存的信息来恢复程序的执行流程。其基本格式包括:RET 和 RET n(n 通常为偶数,表示字节数)。具体操作将在后续章节 PWN入门之四:C语言调用栈 中详细介绍。
RET(近返回)(带立即数操作数的返回,RET
CMP 指令用于比较两个操作数,并根据比较结果设置处理器的状态标志位 (FLAGS),是实现条件分支和循环的基础。其基本格式为:CMP <操作数1>, <操作数2>。此指令影响多个标志位,但主要关注的是零标志位 (ZF):如果结果为0,则置1;反之,清0。当 <操作数1> - <操作数2> 的结果为0时,ZF=1。
CMPifZF操作数1 == 操作数2
JMP 是一条无条件跳转指令,其功能在于立即改变程序的执行流程,跳转至指定的目标地址继续执行。这是实现循环、分支和函数调用等非顺序执行逻辑的基础。其基本格式为:JMP <目标地址>。执行 JMP 指令时,CPU 会将程序计数器 (Instruction Pointer) 的值设为目标地址,使程序从该地址开始执行。
JMPEIPRIP<目标地址>
PUSH 和 POP 是栈操作指令,分别用于数据的压栈和弹栈操作。
PUSHPOP

雷达卡


京公网安备 11010802022788号







