gdb catch系统调用条件和字符串comparisson

时间:2016-06-10 08:34:32

标签: linux debugging gdb system-calls

我想catch系统调用(更具体地说是access)并根据字符串比较在其上设置condition(显然是 的参数>字符串)。

具体示例:调试ls时,我想抓住access系统调用以获取特定路径名(the 1st argument

  

int access(const char * pathname,int mode);

到目前为止,我已成功手动检查access的路径名参数(请参阅[1])。

我尝试使用this blog post

catch syscall access
condition 1 strcmp((char*)($rdi), "/etc/ld.so.preload") == 0

但失败了(请参阅[2]),因为gdb告诉我一个段错误和Evaluation of the expression containing the function (strcmp@plt) will be abandoned.。但是gdb建议set unwindonsignal on

我试过了:

set unwindonsignal on
catch syscall access
condition 1 strcmp((char*)($rdi), "/etc/ld.so.preload") == 0

但又失败了(请参阅[3]),但出现类似错误并提出建议set unwindonsignal off ...

我搜索了The program being debugged was signaled while in a function called from GDB.错误消息,但是(我认为)我找不到相关内容。

任何帮助或想法?

[1]

$ gdb ls
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1
...
Reading symbols from ls...(no debugging symbols found)...done.
(gdb) catch syscall access
Catchpoint 1 (syscall 'access' [21])
(gdb) r
Starting program: /bin/ls 

Catchpoint 1 (call to syscall access), 0x00007ffff7df3537 in access () at ../sysdeps/unix/syscall-template.S:81
81  ../sysdeps/unix/syscall-template.S: No such file or directory.
(gdb) x /s $rdi
0x7ffff7df6911: "/etc/ld.so.nohwcap"
(gdb) c
Continuing.

Catchpoint 1 (returned from syscall access), 0x00007ffff7df3537 in access () at ../sysdeps/unix/syscall-template.S:81
81  in ../sysdeps/unix/syscall-template.S
(gdb) x /s $rdi
0x7ffff7df6911: "/etc/ld.so.nohwcap"
(gdb) c
Continuing.

Catchpoint 1 (call to syscall access), 0x00007ffff7df3537 in access () at ../sysdeps/unix/syscall-template.S:81
81  in ../sysdeps/unix/syscall-template.S
(gdb) x /s $rdi
0x7ffff7df9420 <preload_file.9747>: "/etc/ld.so.preload"

[2]

$ gdb ls
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1
...
Reading symbols from ls...(no debugging symbols found)...done.
(gdb) catch syscall access
Catchpoint 1 (syscall 'access' [21])
(gdb) condition 1 strcmp((char*)($rdi), "/etc/ld.so.preload") == 0
(gdb) info breakpoints
Num     Type           Disp Enb Address            What
1       catchpoint     keep y                      syscall "access" 
    stop only if strcmp((char*)($rdi), "/etc/ld.so.preload") == 0
(gdb) r
Starting program: /bin/ls 

Program received signal SIGSEGV, Segmentation fault.
0x0000000000000000 in ?? ()
Error in testing breakpoint condition:
The program being debugged was signaled while in a function called from GDB.
GDB remains in the frame where the signal was received.
To change this behavior use "set unwindonsignal on".
Evaluation of the expression containing the function
(strcmp@plt) will be abandoned.
When the function is done executing, GDB will silently stop.

Catchpoint 1 (returned from syscall munmap), 0x0000000000000000 in ?? ()

[3]

$ gdb ls
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1
...
Reading symbols from ls...(no debugging symbols found)...done.
(gdb) set unwindonsignal on
(gdb) catch syscall access
Catchpoint 1 (syscall 'access' [21])
(gdb) condition 1 strcmp((char*)($rdi), "/etc/ld.so.preload") == 0
(gdb) r
Starting program: /bin/ls 

Program received signal SIGSEGV, Segmentation fault.
0x0000000000000000 in ?? ()
Error in testing breakpoint condition:
The program being debugged was signaled while in a function called from GDB.
GDB has restored the context to what it was before the call.
To change this behavior use "set unwindonsignal off".
Evaluation of the expression containing the function
(strcmp@plt) will be abandoned.

Catchpoint 1 (returned from syscall munmap), 0x00007ffff7df3537 in access () at ../sysdeps/unix/syscall-template.S:81
81  ../sysdeps/unix/syscall-template.S: No such file or directory.
(gdb) x /s $rdi
0x7ffff7df6911: "/etc/ld.so.nohwcap"

1 个答案:

答案 0 :(得分:4)

您可以像这样使用gdb内部函数$_streq

(gdb) catch syscall access
Catchpoint 1 (syscall 'access' [21])
(gdb) condition 1 $_streq((char *)$rdi, "/etc/ld.so.preload")
(gdb) ru
Starting program: /bin/ls 

Catchpoint 1 (call to syscall access), 0x00007ffff7df3537 in access ()
    at ../sysdeps/unix/syscall-template.S:81
81      ../sysdeps/unix/syscall-template.S: No such file or directory.
(gdb) p (char *)$rdi
$1 = 0x7ffff7df9420 <preload_file> "/etc/ld.so.preload"