CMU Bomblab(汇编小笔记)
以下从x64架构为准
1. 相关指令:
1.1 objdump: 用于给出所有汇编指令
objdump -d
Display assembler contents of executable sections
1 |
|
1.2 gdb
1 |
|
1 |
|
x 按十六进制格式显示变量。
d 按十进制格式显示变量。
u 按十六进制格式显示无符号整型。
o 按八进制格式显示变量。
t 按二进制格式显示变量。
a 按十六进制格式显示变量。
c 按字符格式显示变量。
f 按浮点数格式显示变量。
切换栈帧:
1 |
|
显示所有寄存器
1 |
|
看寄存器的值
1 |
|
1.3 strings
如果从汇编中看到某些关键字符, 可以这样获取一整句话:
1 |
|
2. Bomblab实验操作
- 开启汇编窗口(好查看对应的汇编代码)
1 |
|
- 打断点
在进每个阶段前且在readline前打断点
1 |
|
1 |
|
- 开始运行,进行调试
1 |
|
3. 看汇编
x86系统中,栈的地址是从高地址往低地址, push栈帧的时候, rsp(stack pointer
)减少四个字节.
3.1 通用寄存器(64位寄存器)
0x8(%rsp) 表示上一个变量(一般第一个)
bomb中将string_length的返回值放在EAX中
EAX: accumulator, 加法乘法指令的缺省寄存器
EBX: base基地址寄存器,在内存寻址时存放基地址
ECX: counter计数器, 重复(REP)前缀指令和LOOP指令的内定计数器
EDX: 存放整数除法产生的余数
ESI/EDI: source/destination index, 字符串操作指令里, DS:ESI指向源串, ES:EDI指向目标串
EBP: base pointer, 高级语言函数调用时的frame pointer保存地方
如:
1 |
|
ESP: 专门用作堆栈的顶部指针
3.2 其他寄存器:
R0~R12 是64位工作寄存器, 其中R12有可能被linker修改,所以函数开头经常对R12进行保护
1 |
|
当函数参数少于7个时, 从左到右参数依次放入寄存器:
- rdi
- rsi
- rdx
- rcx
- r8
- r9
3.3 条件跳转指令和比较指令:
test
指令主要将两个操作数按位与, 并根据结果设置标志寄存器
(结果不会写回到目标操作数), test
的两个寄存器只有都是空(全0)时或者不同时, ZF才会被置位
注意: addq src, dst -> dst = dst + src, 会将结果写回到目标寄存器上
test
指令位与运算结果为0的话, ZF(Zero Flag)设为0.
je
是jz(jump if zero)的别称.jne
就是反过来的条件跳转指令
1 |
|
cmpb
: 判断是否相等, 然后置ZF为1:
cmpl
:
For >, there is ja for unsigned and jg for signed (jump if above and jump if greater).
For <, there is jb for unsigned and jl for signed (jump if below and jump if less).
1 |
|
(%edx)
表示 %edx中所保存的地址指向单元的内容(即取指针所指内容)
3.4 寄存器操作:
https://stackoverflow.com/questions/19748074/meaning-of-0x8rsp
0x8(%rsp)
means "get the location on the stack that is 8 bytes away from the stack pointer %rsp
lea
: 和mov很像, 不过有其他作用
其他:
因为不同同学的bomb内容不同, 我帮的一位同学比网上的版本要稍微复杂一些,共计19小时,bingo~
这篇笔记只是零星随笔, 帮助自己回忆汇编, 日后有机会会综合整理