【问题标题】:gdb:How to print value at memory address in ASMgdb:如何在 ASM 中的内存地址打印值
【发布时间】:2015-04-06 02:20:52
【问题描述】:
   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

如何打印最后一条指令中$0x1 的内容? 我尝试了所有组合

x/d 0x1
x/d $0x1
x/s $0x1
...
...

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

最终,我试图找出传递给scanf 的参数,即“%d %d %c”

【问题讨论】:

    标签: assembly x86 gdb reverse-engineering


    【解决方案1】:

    $1 有一个立即值,它只是数字1。这不是地址。它正在检查sscanf 的返回值,即处理的项目数。转换后的值当然会放在内存中作为参数传递给sscanf 的指针处。

    在您的示例中,格式字符串位于0x804a73d,您应该可以使用x/s 0x804a73d 打印它。

    出于效率原因,代码使用mov 将项目放入堆栈而不是push。您可以在堆栈上的适当偏移处看到参数。它们从 (%esp) 开始,每个是 4 个字节:

    第一个参数(要读取的字符串):

       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)
    

    【讨论】:

    • 那么我现在的问题是:当我没有看到任何推送指令时,我如何知道作为参数传递给 scanf 的内容?
    • @filposs 将movs 查找到(%esp)、4(%esp) 等内存地址。这类似于push,但不必每次都递减%esp。
    • 您知道它在那里似乎完全没有问题!你介意向我解释一个有见地的方法来确定这一点吗?在所有的 mov 指令中,我怎么知道它是这个? (它是 %d %d)
    • @Jester 谢谢! mov指令中的参数是否总是按降序排列?
    • 不,可以是任何顺序。您必须注意堆栈偏移量。
    猜你喜欢
    • 1970-01-01
    • 2020-10-23
    • 2021-12-30
    • 1970-01-01
    • 2017-02-21
    • 2023-04-08
    • 2015-08-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多