写在前面
字符串长度计算
msg1 db "hello, world!" , 0xa, 0
msg1Len equ $-msg1-1; calc len of str
$-msg1-1
表示当前位置的内存地址减去 msg1 的内存地址, 然后再减一(末尾的\0
).
gdb 调试汇编程序
如果默认是带%
这种寄存器, 那就是 at&t 格式的汇编语法, 改成 intel 舒服点(可以写到~/.gdbinit
文件中)
set disassembly-flavor intel
常用的几个指令
disas main # 反汇编 main 函数(.text段)
查看数据格式
用 强大的x
命令 (examine)
首先介绍具体格式
(gdb) h x
Examine memory: x/FMT ADDRESS.
ADDRESS is an expression for the memory address to examine.
FMT is a repeat count followed by a format letter and a size letter.
Format letters are o(octal), x(hex), d(decimal), u(unsigned decimal),
t(binary), f(float), a(address), i(instruction), c(char), s(string)
and z(hex, zero padded on the left).
Size letters are b(byte), h(halfword), w(word), g(giant, 8 bytes).
The specified number of objects of the specified size are printed
according to the format. If a negative number is specified, memory is
examined backward from the address.
Defaults for format and size letters are those previously used.
Default count is 1. Default address is following last thing printed
with this command or "print".
如果什么都不加, 默认是一个byte 的 decimal, 所以对于大于 1字节的整数就会截断.
FMT 是 format+size
这里的字和半字是 64 位下的, 即字表示 4 字节而半字表示 2 字节, 需要注意.
查看寄存器
i r
# 指定的寄存器
(gdb) i r $rax
rax 0xffffffffffffff7b -133
进制转换
(gdb) print /d 0x7b
$1 = 123
使用 shell 命令
shell vi test.lst
单指令执行
这里不能直接用 step(s), 而是要用 stepi(si)
调用系统函数 printf
extern printf
section .data
msg db "hello, world",0xa , 0
fmtstr db "this output str is :%s" , 0
section .bss
section .text
global main
main:
push rbp
mov rbp, rsp
mov rdi, fmtstr
mov rsi, msg
mov rax, 0
call printf
mov rsp, rbp
pop rbp
mov rax, 60
mov rdi, 0
syscall; exit