Assembly gdb:如何在ASM中打印内存地址处的值
但我要么 错误:无法访问地址0x1处的内存,或者无法将值转换为整数(即使我尝试将类型更改为c、s、x、a)Assembly gdb:如何在ASM中打印内存地址处的值,assembly,x86,gdb,reverse-engineering,Assembly,X86,Gdb,Reverse Engineering,但我要么 错误:无法访问地址0x1处的内存,或者无法将值转换为整数(即使我尝试将类型更改为c、s、x、a) 最后,我试图找出传递给scanf的参数,即,“%d%d%c”$1有一个立即值,它只是数字1。这不是地址。它正在检查sscanf的返回值,即处理的项目数。转换后的值当然放在内存中的指针上,这些指针已作为参数传递给sscanf 在您的示例中,格式字符串位于0x804a73d,您应该能够使用x/s 0x804a73d打印该字符串 出于效率考虑,代码使用mov将项目放在堆栈上,而不是push。您可
最后,我试图找出传递给
scanf
的参数,即,“%d%d%c”$1
有一个立即值,它只是数字1
。这不是地址。它正在检查sscanf
的返回值,即处理的项目数。转换后的值当然放在内存中的指针上,这些指针已作为参数传递给sscanf
在您的示例中,格式字符串位于0x804a73d
,您应该能够使用x/s 0x804a73d
打印该字符串
出于效率考虑,代码使用mov
将项目放在堆栈上,而不是push
。您可以在堆栈上的适当偏移处看到参数。它们从(%esp)
开始,每个字节为4个:
第一个参数(要从中读取的字符串):
0x08048c7d:mov 0x30(%esp),%eax
0x08048c81:mov%eax,(%esp)
第二个参数(格式字符串):
0x08048c75:movl$0x804a73d,0x4(%esp)
第三个参数(第一个输出指针):
0x08048c6d:lea0x18(%esp),%eax
0x08048c71:mov%eax,0x8(%esp)
第四个参数(第二个输出指针):
0x08048c65:lea0x1c(%esp),%eax
0x08048c69:mov%eax,0xc(%esp)
那么我现在的问题是:当我看不到任何push指令时,我如何知道什么作为参数传递给scanf?@filposs查找mov
s到内存地址,例如(%esp)
,4(%esp)
,等等。这类似于push
,但是不必每次都减少%esp
。你知道它就在那里似乎一点问题都没有!你介意向我解释一种有见地的方法来确定这一点吗?在所有的mov指令中,我怎么知道是这个?(是%d%d)@Jester谢谢你!指令mov的参数总是按降序排列吗?不,可以是任意顺序。您必须注意堆栈偏移。
0x08048c62 <+0>: sub $0x2c,%esp
0x08048c65 <+3>: lea 0x1c(%esp),%eax
0x08048c69 <+7>: mov %eax,0xc(%esp)
0x08048c6d <+11>: lea 0x18(%esp),%eax
0x08048c71 <+15>: mov %eax,0x8(%esp)
0x08048c75 <+19>: movl $0x804a73d,0x4(%esp)
0x08048c7d <+27>: mov 0x30(%esp),%eax
0x08048c81 <+31>: mov %eax,(%esp)
0x08048c84 <+34>: call 0x80488d0 <__isoc99_sscanf@plt>
=> 0x08048c89 <+39>: cmp $0x1,%eax
x/d 0x1
x/d $0x1
x/s $0x1
...
...
0x08048c7d <+27>: mov 0x30(%esp),%eax
0x08048c81 <+31>: mov %eax,(%esp)
0x08048c75 <+19>: movl $0x804a73d,0x4(%esp)
0x08048c6d <+11>: lea 0x18(%esp),%eax
0x08048c71 <+15>: mov %eax,0x8(%esp)
0x08048c65 <+3>: lea 0x1c(%esp),%eax
0x08048c69 <+7>: mov %eax,0xc(%esp)