Pwn Note
install tools
yay -S yay -S blackarch/rz-cutter
yay -S aur/rz-jsdec-git
yay -S blackarch/rz-ghidra =>optional
汇编基础
x86 处理器有 8 个 32 位通用寄存器
汇编指令 Instructions
机器指令通常分为 3 类:数据移动指令, 逻辑运算指令和流程控制指令。
<reg32 任意的 32 位寄存器 (%eax, %ebx, %ecx, %edx, %esi, %edi, %esp 或者 %eb)
<reg16 任意的 16 位寄存器 (%ax, %bx, %cx 或者 %dx)
<reg8 任意的 8 位寄存器 (%ah, %al, %bh, %bl, %ch, %cl, %dh, %dl)
<reg 任意的寄存器
<mem 一个内存地址, 例如 (%eax), 4+var, (%eax, %ebx, 1)
<con32 32 位常数
<con16 16 位常数
<con8 8 位常数
<con 任意 32位, 16 位或者 8 位常数
数据移动指令
mov 移动
mov 指令将数据从它的第一个参数 (即寄存器中的内容, 内存单元中的内容, 或者一个常数值)复制到它的第二个参数 (即寄存器或者内存单元) 语法
mov <reg, <reg
mov <reg, <mem
mov <mem, <reg
mov <con, <reg
mov <con, <mem
例子
mov %ebx, %eax ;将 EBX 中的值复制到 EAX 中
mov $5, var(,1) ;将数字 5 存到字节型内存单元 "var"
push 入栈
push 指令将它的参数移动到硬件支持的栈内存顶端 语法
push <reg32
push <mem
push <con32
例子
push %eax ;将 EAX 送入栈
push var(,1) ;将 var 对应的 4 字节大小的数据送入栈中
pop 出栈
pop 指令从硬件支持的栈内存顶端移除4 字节的数据, 并把这个数据放到该指令指定的参数中 ( 即寄存器或者内存单元 )。 语法
pop <reg32
pop <mem
例子
pop %edi ;将栈顶的元素移除, 并放入到寄存器 EDI 中.
pop (%ebx) ;将栈顶的元素移除, 并放入从 EBX 开始的 4 个字节大小的内存单元中.
lea 加载有效地址
lea 指令将其第一个参数指定的内存单元 放入到 第二个参数指定的寄存器中。 汇编语言中 lea 指令和 mov 指令的区别 ? MOV 指令的功能是传送数据,例如 MOV AX,[1000H] ,作用是将 1000H 作 为偏移地址,寻址找到内存单元,将该内存单元中的数据送至 AX; LEA 指令的功能是取偏移地 址,例如 LEA AX,[1000H] ,作用是将源操作数 [1000H] 的偏移地址 1000H 送至 AX。 语法
lea <mem, <reg32
例子
lea (%ebx,%esi,8), %edi ;EBX+8*ESI 的值被移入到了 EDI
lea val(,1), %eax ;val 的值被移入到了 EAX
逻辑运算指令
add 整数相加
#语法
add <reg, <reg
add <mem, <reg
add <reg, <mem
add <con, <reg
add <con, <mem
#例子
add $10, %eax ;EAX 中的值被设置为了 EAX+10.
addb $10, (%eax) ;往 EAX 中的值 所代表的内存单元地址 加上 1 个字节的数字 10.
sub 整数相减
#语法
sub <reg, <reg
sub <mem, <reg
sub <con, <reg
sub <con, <mem
sub %ah, %al ;AL 被设置成 AL-AH
sub $216, %eax ;将 EAX 中的值减去 216
inc 指令让它的参数加 1, dec 指令则是让它的参数减去 1
#语法
inc <reg
inc <mem
dec <reg
dec <mem
#例子
dec %eax ;EAX 中的值减去 1
incl var(,1) ;将 var 所代表的 32 位整数加上 1.
imul 整数相乘
#语法
imul <reg32, <reg32
imul <mem, <reg32
imul <con, <reg32, <reg32
imul <con, <mem, <reg32
#例子
imul (%ebx), %eax ;将 EAX 中的 32 位整数, 与 EBX 中的内容所指的内存单元, 相乘, 然后把结果存到 EAX 中.
imul $25, %edi, %esi ;ESI 被设置为 EDI * 25.
Linux ELF
demo code
#include<stdio.h>
int global_init_var = 10;
int global_uninit_var;
void func(int sum) {
printf("%d\n", sum);
}
void main(void) {
static int local_static_init_var = 20;
static int local_static_uninit_var;
int local_init_val = 30;
int local_uninit_var;
func(global_init_var + local_init_val + local_static_init_var);
}
gcc -m32 -c elf_demo.c -o elfDemo.o #LSB relocatable 可重定位文件
gcc -m32 elf_demo.c -o elfDemo.out # LSB pie executable,dynamically linked
gcc -m32 -static elf_demo.c -o elfDemo_Static.out #LSB executable,statically linked
file -L /usr/lib32/libc.so.6 #LSB shared object,dynamically linked
ldd 命令打印所依赖的共享库
ldd elfDemo.out
ldd elfDemo_static.out
读符号表
readelf -s elfDemo.o
hexdump .shstrtab字段
readelf -x .shstrtab elfDemo.o
gdb 调试
gdb
file elfDemo.o
disassemble main
0x565561bb <+0>: lea ecx,[esp+0x4] #把[esp+0x4]的地址传给ecx
0x565561bf <+4>: and esp,0xfffffff0
0x565561c2 <+7>: push DWORD PTR [ecx-0x4]
0x565561c5 <+10>: push ebp
0x565561c6 <+11>: mov ebp,esp
0x565561c8 <+13>: push ecx
0x565561c9 <+14>: sub esp,0x14
0x565561cc <+17>: call 0x56556205 <__x86.get_pc_thunk.ax>
0x565561d1 <+22>: add eax,0x2e23
0x565561d6 <+27>: mov DWORD PTR [ebp-0xc],0x1e
0x565561dd <+34>: mov ecx,DWORD PTR [eax+0x1c]
0x565561e3 <+40>: mov edx,DWORD PTR [ebp-0xc]
0x565561e6 <+43>: add edx,ecx
0x565561e8 <+45>: mov eax,DWORD PTR [eax+0x20]
0x565561ee <+51>: add eax,edx
0x565561f0 <+53>: sub esp,0xc
0x565561f3 <+56>: push eax
0x565561f4 <+57>: call 0x5655618d <func>
0x565561f9 <+62>: add esp,0x10
0x565561fc <+65>: nop
0x565561fd <+66>: mov ecx,DWORD PTR [ebp-0x4]
0x56556200 <+69>: leave
0x56556201 <+70>: lea esp,[ecx-0x4]
0x56556204 <+73>: ret