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 后读取超长内容触发缓冲区越界

pwn_college

调试程序时需要固定地址,就关闭了 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