Assembly gdb:如何在ASM中打印内存地址处的值

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。您可

但我要么 错误:无法访问地址0x1处的内存,或者无法将值转换为整数(即使我尝试将类型更改为c、s、x、a)


最后,我试图找出传递给
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)