免责声明我是大会新成员,所以如果这是一个愚蠢的问题而我很抱歉,我的术语和一切都很糟糕。
我相信以下代码是链表的x86表示。我正在做“二元炸弹”项目,并一直在跟踪一个不同的炸弹,让我知道我应该采取的步骤。我可以使用命令 x / 3x $ rax 访问$ rax的信息。基于汇编代码和错误中给出的地址,我可以告诉它存储一个节点,该节点指向位于*($ rax + 8)的列表中的下一个节点。出于某种原因,当我尝试查看该位置时,我的终端告诉我它无法访问该位置的内存。为什么会这样?我做错了什么?
错误本身位于汇编代码的底部。不确定它是否可能从我给出的内容中推断出任何答案,但如果是,我想自己解决这个难题,所以请限制答案以解释为什么我无法访问给定位置的内存。 谢谢!
0x00000000004010bc <+0>: push %r13
0x00000000004010be <+2>: push %r12
0x00000000004010c0 <+4>: push %rbp
0x00000000004010c1 <+5>: push %rbx
0x00000000004010c2 <+6>: sub $0x58,%rsp
0x00000000004010c6 <+10>: lea 0x30(%rsp),%rsi
0x00000000004010cb <+15>: callq 0x401576 <read_six_numbers>
0x00000000004010d0 <+20>: lea 0x30(%rsp),%r12
0x00000000004010d5 <+25>: mov $0x0,%r13d
0x00000000004010db <+31>: jmp 0x401103 <phase_6+71>
0x00000000004010dd <+33>: callq 0x401540 <explode_bomb>
0x00000000004010e2 <+38>: jmp 0x401112 <phase_6+86>
0x00000000004010e4 <+40>: add $0x1,%ebx
0x00000000004010e7 <+43>: cmp $0x5,%ebx
0x00000000004010ea <+46>: jg 0x4010ff <phase_6+67>
0x00000000004010ec <+48>: movslq %ebx,%rax
0x00000000004010ef <+51>: mov 0x30(%rsp,%rax,4),%eax
0x00000000004010f3 <+55>: cmp %eax,0x0(%rbp)
0x00000000004010f6 <+58>: jne 0x4010e4 <phase_6+40>
0x00000000004010f8 <+60>: callq 0x401540 <explode_bomb>
0x00000000004010fd <+65>: jmp 0x4010e4 <phase_6+40>
0x00000000004010ff <+67>: add $0x4,%r12
0x0000000000401103 <+71>: mov %r12,%rbp
0x0000000000401106 <+74>: mov (%r12),%eax
0x000000000040110a <+78>: sub $0x1,%eax
0x000000000040110d <+81>: cmp $0x5,%eax
0x0000000000401110 <+84>: ja 0x4010dd <phase_6+33>
0x0000000000401112 <+86>: add $0x1,%r13d
---Type <return> to continue, or q <return> to quit---
0x0000000000401116 <+90>: cmp $0x6,%r13d
0x000000000040111a <+94>: je 0x40114f <phase_6+147>
0x000000000040111c <+96>: mov %r13d,%ebx
0x000000000040111f <+99>: jmp 0x4010ec <phase_6+48>
0x0000000000401121 <+101>: mov 0x8(%rdx),%rdx
0x0000000000401125 <+105>: add $0x1,%eax
0x0000000000401128 <+108>: cmp %ecx,%eax
0x000000000040112a <+110>: jne 0x401121 <phase_6+101>
0x000000000040112c <+112>: mov %rdx,(%rsp,%rsi,8)
0x0000000000401130 <+116>: add $0x1,%rsi
0x0000000000401134 <+120>: cmp $0x6,%rsi
0x0000000000401138 <+124>: je 0x401156 <phase_6+154>
0x000000000040113a <+126>: mov 0x30(%rsp,%rsi,4),%ecx
0x000000000040113e <+130>: mov $0x1,%eax
0x0000000000401143 <+135>: mov $0x6042f0,%edx
0x0000000000401148 <+140>: cmp $0x1,%ecx
0x000000000040114b <+143>: jg 0x401121 <phase_6+101>
0x000000000040114d <+145>: jmp 0x40112c <phase_6+112>
0x000000000040114f <+147>: mov $0x0,%esi
0x0000000000401154 <+152>: jmp 0x40113a <phase_6+126>
0x0000000000401156 <+154>: mov (%rsp),%rbx
0x000000000040115a <+158>: mov 0x8(%rsp),%rax
0x000000000040115f <+163>: mov %rax,0x8(%rbx)
0x0000000000401163 <+167>: mov 0x10(%rsp),%rdx
0x0000000000401168 <+172>: mov %rdx,0x8(%rax)
0x000000000040116c <+176>: mov 0x18(%rsp),%rax
0x0000000000401171 <+181>: mov %rax,0x8(%rdx)
0x0000000000401175 <+185>: mov 0x20(%rsp),%rdx
0x000000000040117a <+190>: mov %rdx,0x8(%rax)
---Type <return> to continue, or q <return> to quit---
0x000000000040117e <+194>: mov 0x28(%rsp),%rax
0x0000000000401183 <+199>: mov %rax,0x8(%rdx)
0x0000000000401187 <+203>: movq $0x0,0x8(%rax)
0x000000000040118f <+211>: mov $0x5,%ebp
0x0000000000401194 <+216>: jmp 0x40119f <phase_6+227>
0x0000000000401196 <+218>: mov 0x8(%rbx),%rbx
0x000000000040119a <+222>: sub $0x1,%ebp
0x000000000040119d <+225>: je 0x4011b0 <phase_6+244>
0x000000000040119f <+227>: mov 0x8(%rbx),%rax
0x00000000004011a3 <+231>: mov (%rax),%eax
0x00000000004011a5 <+233>: cmp %eax,(%rbx)
0x00000000004011a7 <+235>: jle 0x401196 <phase_6+218>
0x00000000004011a9 <+237>: callq 0x401540 <explode_bomb>
0x00000000004011ae <+242>: jmp 0x401196 <phase_6+218>
0x00000000004011b0 <+244>: add $0x58,%rsp
0x00000000004011b4 <+248>: pop %rbx
0x00000000004011b5 <+249>: pop %rbp
0x00000000004011b6 <+250>: pop %r12
0x00000000004011b8 <+252>: pop %r13
0x00000000004011ba <+254>: retq
End of assembler dump.
(gdb) x/3x $rax
0x604950 <input_strings+400>: 0x20342036 0x20352031 0x00322033
(gdb) x/3x *($rax+8)
0x322033: Cannot access memory at address 0x322033
(gdb) x/3x *($rax + 8)
0x322033: Cannot access memory at address 0x322033
答案 0 :(得分:3)
您正在使用rax
访问x/3x $rax
指向的内存。 (所以你的问题标题是错误的。)
x/3x *($rax+8)
有2个问题:
RAX指向的内存看起来像ASCII字符。 (尝试x /16c $rax
或p (char*)$rax
。)不会看起来像一个有效的地址。 (您可以查看less /proc/$(pidof my_bomb)/maps
以查找目标进程已映射的虚拟地址范围。)
您只使用32位数据作为地址。 GDB一般没有asm或寄存器的类型信息,通常默认为int
或int*
。在这种情况下,$rax+8
被视为int*
中的*($rax+8)
,因此您要求GDB将4个字节的内存作为x
命令的参数
x86-64指针长64位,所以你应该使用x /3xg
转储3 x86 qwords(GDB调用&#34; g
iant&#34;而不是默认值32 -bit GDB w
ord。请注意,即使在调试x86目标时,GDB的术语也与典型的32位RISC机器匹配,而不是x86术语。
0x00322033
不太可能是有效地址的低32位,你在编译器生成的代码中找到另一个指针,因为它是奇数。默认情况下,x86-64 System V ABI将64位指针/整数与64位对齐,因此包含指针的结构的起点将位于可被8整除的地址(以8
结尾或十六进制中的0
。
但是如果$rax+8
是一个8字节的指针,在上面的32中有一些非零值,你可以x /3xg *(void **)($rax+8)
或者其他什么,所以表达你&#39 ;重新引用具有指针指针类型,因此将加载整个指针的数据。
或者,您可以复制/粘贴先前x
命令中的地址。或者您可以使用print
命令。例如,在流程中的_start
处(rsp+8
为argv[0]
):
(gdb) p $rsp
$1 = (void *) 0x7fffffffe690
(gdb) p *(void**)($rsp+8)
$4 = (void *) 0x7fffffffe9c5
(gdb) p **(void**)($rsp+8) # oops, always need at least one more * in the type and in the deref
Attempt to dereference a generic pointer.
(gdb) p **(long**)($rsp+8)
$5 = 7955998172649846063
(gdb) p /x **(long**)($rsp+8) # same value, different format (/x isn't default because it's an integer type, not a pointer)
$6 = 0x6e69622f7273752f
(gdb) p **(void*****)($rsp+8) # you can use a zillion *s in the type :P
$7 = (void ***) 0x6e69622f7273752f # this wasn't a linked list!
(gdb) p ***(void*****)($rsp+8)
Cannot access memory at address 0x6e69622f7273752f # ASCII data as a pointer is bogus