ntc*_*tc2 20 c debugging assembly gdb
如何让GDB在打印功能中做多余的解引用
x/s
?
当我尝试显式解引用时,x/
我得到错误"尝试取消引用通用指针".使用x/
多次是有效的,因为每次使用都包含隐式解引用,但这很烦人,因为我必须复制并粘贴每个中间结果.
考虑非常有用的C程序,example.c
:
#include <stdio.h>
int main(int argc, char **argv) {
printf("argv[0] = %s\n", argv[0]);
}
Run Code Online (Sandbox Code Playgroud)
如果我构建它并将其加载到GDB中,我看到它argv
存储在
0xc(%ebp)
,因为它的双重因素作为第二个参数传递到第26行printf
(即0x4(%esp)
)中:
$ gcc -o example example.c
$ gdb example
(gdb) disass main
Dump of assembler code for function main:
0x080483e4 <+0>: push %ebp
0x080483e5 <+1>: mov %esp,%ebp
0x080483e7 <+3>: and $0xfffffff0,%esp
0x080483ea <+6>: sub $0x10,%esp
0x080483ed <+9>: mov 0xc(%ebp),%eax
0x080483f0 <+12>: mov (%eax),%edx
0x080483f2 <+14>: mov $0x80484e0,%eax
0x080483f7 <+19>: mov %edx,0x4(%esp)
0x080483fb <+23>: mov %eax,(%esp)
0x080483fe <+26>: call 0x8048300 <printf@plt>
0x08048403 <+31>: leave
0x08048404 <+32>: ret
End of assembler dump.
Run Code Online (Sandbox Code Playgroud)
我在突破printf
和带参数运行程序first
和
second
:
(gdb) break *main + 26
Breakpoint 1 at 0x80483fe
(gdb) run first second
Starting program: /var/tmp/SO-attempt-to-dereference-generic-pointer/example first second
Run Code Online (Sandbox Code Playgroud)
我尝试argv[0]
在GDB中打印,但是我得到了"通用指针"错误:
Breakpoint 1, 0x080483e5 in main ()
(gdb) x/s **(0xc + $ebp)
Attempt to dereference a generic pointer.
Run Code Online (Sandbox Code Playgroud)
但是,通过使用'x/xw'手动取消引用几次,我最终能够打印argv[0]
(和argv[1]
):
(gdb) x/xw 0xc + $ebp
0xbfffeba4: 0xbfffec34
(gdb) x/xw 0xbfffec34
0xbfffec34: 0xbfffedc8
(gdb) x/s 0xbfffedc8
0xbfffedc8: "/var/tmp/SO-attempt-to-dereference-generic-pointer/example"
(gdb) x/xw 0xbfffec34 + 4
0xbfffec38: 0xbfffee03
(gdb) x/s 0xbfffee03
0xbfffee03: "first"
(gdb)
Run Code Online (Sandbox Code Playgroud)
但这是烦人的和间接的(因为指针编程不会是?)
ntc*_*tc2 27
解决方案是在解除引用之前强制转换指针.
例如,从我们上面的位置开始:
(gdb) x/s **((char ***) (0xc + $ebp))
0xbfffedc8: "/var/tmp/SO-attempt-to-dereference-generic-pointer/example"
(gdb) x/s *(*((char ***) (0xc + $ebp)) + 1)
0xbfffee03: "first"
(gdb) x/s *(*((char ***) (0xc + $ebp)) + 2)
0xbfffee09: "second"
Run Code Online (Sandbox Code Playgroud)
请注意,堆栈地址0xc + $ebp
本身是指向该堆栈位置内容的指针,因此我们需要char ***
而不是
char **
.
归档时间: |
|
查看次数: |
23046 次 |
最近记录: |