GDB 中输出字符串数组
x/10s *((char**)$rsp+3)
x/10s *((char**)($rsp+0x18))
print *(char**)($rsp+0x18)@10
define print_string_array
set $p = (char**)$arg0
while *$p
x/s *$p
set $p++
end
end
define psa
document psa
Print a NULL-terminated string array (char**) with colors.
Usage: psa <address> [max_entries]
end
if $argc == 0
printf "usage: psa <char**> [max]\n"
else
set $base = (char **)$arg0
set $p = $base
set $i = 0
if $argc >= 2
set $max = $arg1
else
set $max = 256
end
while *$p && $i < $max
printf "[%02d] %p │ +0x%04x │ %p → \"%s\"\n", \
$i, \
$p, \
($p - $base) * 8, \
*$p, \
*$p
set $p = $p + 1
set $i = $i + 1
end
if *$p != 0
printf "[!] Output truncated at %d entries. Use 'psa <addr> <max>' to view more.\n", $max
end
end
end关闭 ASLR 后读取超长内容触发缓冲区越界
调试程序时需要固定地址,就关闭了 ASLR 并去掉了 setuid。
程序的 main() 会从 stdin 往 buffer 上写内容,但是触发了 read(0, 0x7fffffffe9b0, 4096) = -1 EFAULT (Bad address)。
原因是这个栈地址加上 4096 会超过 0x00007ffffffde000 0x00007ffffffff000 0x0000000000000000 rw- [stack] 范围,操作系统直接拦截了。
可以用 vmmap 0x7fffffffe9b0+4096 来验证
开启 ASLR 的情况下能用是因为基址随机化后,加后的地址还在可读范围中。
解决方法可以比较直接,用环境变量把栈的空间撑开
env PADDING=$(python3 -c 'print("A" * 4096)') setarch $(uname -m) -R /tmp/guarded-gadgets-easy