1

我试图找出段错误的原因,并使用 gdb 的 btrace 将其缩小到 PLT。段错误发生在从 PLT 跳转到 GOT 的过程中,我将其解释为表示 PLT 在执行过程中损坏。根据下面的分析,这种解释是否正确?PLT 腐败的罪魁祸首是什么?堆栈溢出?我相信在这种情况下,在 GOT 地址上安装一个观察点可能会有所帮助。会watch -l 0x55555562f048是正确的方法吗?欢迎其他调试想法。


对于上下文,段错误发生在调用strlenin 函数期间foo

int foo(char * path, ...) {
    ...
    if (strlen(path) >= PATH_MAX) {

相应的装配线是:

0x58114 <foo+212>    cmpq   $0x0,-0x4c8(%rbp)
0x5811c <foo+220>    jne    0x5812a <foo+234>
0x5811e <foo+222>    lea    0xb96fb(%rip),%rdi        # 0x111820
0x58125 <foo+229>    callq  0x376c0 <__ubsan_handle_nonnull_arg@plt>
0x5812a <foo+234>    mov    -0x4c8(%rbp),%rax
0x58131 <foo+241>    mov    %rax,%rdi
0x58134 <foo+244>    callq  0x37090 <strlen@plt>

首先,path与 NULL ( cmpq $0x0,-0x4c8(%rbp)) 进行比较,我相信在这种情况下,它只是为 ubsan 仪器添加的。没有遵循该分支,程序跳转到<foo+234>,它为strlen调用设置,通过移动pathrax然后rdi,最后调用strlen@pltrecord btracegdb此之前运行会产生以下指令历史记录:

(gdb) record btrace
(gdb) c
136        0x00005555555ac114 <foo+212>:        cmpq   $0x0,-0x4c8(%rbp)
137        0x00005555555ac11c <foo+220>:        jne    0x5555555ac12a <foo+234>
138        0x00005555555ac12a <foo+234>:        mov    -0x4c8(%rbp),%rax
139        0x00005555555ac131 <foo+241>:        mov    %rax,%rdi
140        0x00005555555ac134 <foo+244>:        callq  0x55555558b090 <strlen@plt>
141        0x000055555558b090 <strlen@plt+0>:   jmpq   *0xa3fb2(%rip)  # 0x55555562f048 <strlen@got.plt>

在这里,我们看到它path不为空,因此程序跳转到<foo+234>,并为strlen调用 ( mov, mov, callq <strlen@plt>) 设置。最后执行的指令是到GOT ( ) 中jmpq *0xa3fb2(%rip)的条目,因此程序崩溃并且 gdb 丢失了上下文(报告它)。strlenstrlen@got.pltCannot find bounds of current function

4

0 回答 0