|
| 1 | +--- |
| 2 | +created: "2025-12-26" |
| 3 | +updated: "2025-12-26" |
| 4 | +--- |
| 5 | +## 高级语言特性在汇编层面的表现(CTF速成版) |
| 6 | + |
| 7 | +### 一、核心概念速记 |
| 8 | + |
| 9 | +**寄存器基础:** |
| 10 | +- EAX/RAX:返回值、累加器 |
| 11 | +- ESP/RSP:栈指针 |
| 12 | +- EBP/RBP:基址指针 |
| 13 | +- EIP/RIP:指令指针 |
| 14 | +- ESI/RSI、EDI/RDI:源/目的索引 |
| 15 | + |
| 16 | +### 二、具体特性对应 |
| 17 | + |
| 18 | +#### 1. **变量存储** |
| 19 | +```assembly |
| 20 | +; 全局变量(数据段) |
| 21 | +.data |
| 22 | +global_var dd 42 |
| 23 | +
|
| 24 | +; 局部变量(栈上) |
| 25 | +mov [ebp-4], 10 ; int x = 10; |
| 26 | +mov byte [ebp-8], 'A' ; char c = 'A'; |
| 27 | +``` |
| 28 | + |
| 29 | +#### 2. **控制结构** |
| 30 | +```assembly |
| 31 | +; if 语句 |
| 32 | +cmp eax, 10 |
| 33 | +jle less_equal ; if (eax <= 10) |
| 34 | +jg greater ; else |
| 35 | +
|
| 36 | +; while 循环 |
| 37 | +loop_start: |
| 38 | +cmp dword [ebp-4], 0 |
| 39 | +je loop_end |
| 40 | +; 循环体 |
| 41 | +jmp loop_start |
| 42 | +loop_end: |
| 43 | +
|
| 44 | +; switch-case(跳转表) |
| 45 | +mov eax, [ebp-4] ; switch(x) |
| 46 | +jmp [jump_table + eax*4] |
| 47 | +``` |
| 48 | + |
| 49 | +#### 3. **函数调用(x86-64调用约定)** |
| 50 | +```assembly |
| 51 | +; 参数传递:RDI, RSI, RDX, RCX, R8, R9,其余栈 |
| 52 | +; 返回值:RAX |
| 53 | +push rbp |
| 54 | +mov rbp, rsp |
| 55 | +sub rsp, 32 ; 栈空间分配 |
| 56 | +mov rdi, [rbp+16] ; 取第一个参数 |
| 57 | +call function |
| 58 | +add rsp, 32 ; 清理栈 |
| 59 | +pop rbp |
| 60 | +ret |
| 61 | +``` |
| 62 | + |
| 63 | +#### 4. **数据结构** |
| 64 | +```assembly |
| 65 | +; 数组访问 |
| 66 | +mov eax, [array + ecx*4] ; array[i] (int数组) |
| 67 | +
|
| 68 | +; 结构体访问 |
| 69 | +mov eax, [struct + 0] ; struct.field1 |
| 70 | +mov ebx, [struct + 4] ; struct.field2 |
| 71 | +``` |
| 72 | + |
| 73 | +#### 5. **指针操作** |
| 74 | +```assembly |
| 75 | +lea rax, [var] ; &var (取地址) |
| 76 | +mov rbx, [rax] ; *ptr (解引用) |
| 77 | +``` |
| 78 | + |
| 79 | +### 三、CTF重点场景 |
| 80 | + |
| 81 | +#### 1. **栈溢出漏洞识别** |
| 82 | +```assembly |
| 83 | +; 危险函数调用 |
| 84 | +sub rsp, 0x20 ; 只分配32字节 |
| 85 | +lea rdi, [rbp-0x30] ; 缓冲区在rbp-0x30处 |
| 86 | +call gets ; 可能溢出! |
| 87 | +``` |
| 88 | + |
| 89 | +#### 2. **格式化字符串** |
| 90 | +```assembly |
| 91 | +lea rdi, [user_input] ; 用户控制的格式字符串 |
| 92 | +xor eax, eax |
| 93 | +call printf ; 可能泄露内存! |
| 94 | +``` |
| 95 | + |
| 96 | +#### 3. **Shellcode常见模式** |
| 97 | +```assembly |
| 98 | +; execve("/bin/sh", 0, 0) |
| 99 | +push 0x68 |
| 100 | +mov rax, 0x736c2f6e69622f2f |
| 101 | +push rax |
| 102 | +mov rdi, rsp |
| 103 | +xor rsi, rsi |
| 104 | +xor rdx, rdx |
| 105 | +mov rax, 59 |
| 106 | +syscall |
| 107 | +``` |
| 108 | + |
| 109 | +### 四、紧急调试技巧 |
| 110 | + |
| 111 | +1. **GDB快速命令:** |
| 112 | +```bash |
| 113 | +layout asm # 显示汇编 |
| 114 | +b *0x401234 # 断点 |
| 115 | +x/20wx $rsp # 查看栈 |
| 116 | +info registers # 查看寄存器 |
| 117 | +``` |
| 118 | + |
| 119 | +2. **关键特征识别:** |
| 120 | +- `leave; ret` - 函数结尾 |
| 121 | +- `call rax` / `jmp rax` - 间接调用(ROP有用) |
| 122 | +- `add rsp, X` - 栈调整 |
| 123 | + |
| 124 | +3. **漏洞快速判断:** |
| 125 | +- 检查`read`/`gets`/`strcpy`的缓冲区大小 |
| 126 | +- 查找未初始化变量使用 |
| 127 | +- 注意整数溢出->缓冲区溢出链 |
| 128 | + |
| 129 | +### 五、速记口诀 |
| 130 | + |
| 131 | +``` |
| 132 | +变量看栈和内存,循环跳转看标志 |
| 133 | +函数调用看传参,指针就是内存址 |
| 134 | +数组基址加偏移,结构顺序排内存 |
| 135 | +漏洞关注缓冲区,控制流劫持看返回 |
| 136 | +``` |
| 137 | + |
| 138 | +### 六、实战Checklist |
| 139 | + |
| 140 | +1. [ ] 识别调用约定(x86_64通常System V) |
| 141 | +2. [ ] 找到main函数入口(找`__libc_start_main`) |
| 142 | +3. [ ] 标记用户输入点(scanf/read/fgets) |
| 143 | +4. [ ] 跟踪输入流向(寄存器/内存传播) |
| 144 | +5. [ ] 检查边界验证(cmp/jg等) |
| 145 | +6. [ ] 定位危险函数(strcpy/sprintf等) |
| 146 | +7. [ ] 计算偏移量(缓冲区到返回地址) |
| 147 | + |
| 148 | +**注意**:比赛时优先用IDA/Ghidra反编译,结合汇编验证逻辑! |
| 149 | + |
| 150 | +祝比赛顺利!遇到具体问题可临时查此表快速对应。 |
0 commit comments