【问题标题】:How can I know which address belongs to which argument of the function in a Crash Dump我如何知道哪个地址属于故障转储中函数的哪个参数
【发布时间】:2015-11-26 05:33:32
【问题描述】:

我是故障转储分析的新手。这是我的 vmcore 的 bt -f 的输出,我想查看它当时持有的函数 foo 的参数值。我有一台 64 位机器,浏览代码发现foo 只接受一个参数。无论如何,有没有办法知道哪个地址属于哪个参数。

#4 [ffff8807adfaf8c0] foobar at ffffffffa11c7c15 [foo]
   ffff8807adfaf8c8: ffff881033e1d800 ffff8807adfaf8e8 
   ffff8807adfaf8d8: ffff8807adfaf938 ffffffffa11c7ce1

这是最后的寄存器值

RIP: 00007fa64fdfb907  RSP: 00007fff2a187ca0  RFLAGS: 00010246
RAX: 00000000000000a6  RBX: ffffffff8100b072  RCX: 00007fa6506f7390
RDX: 0000000000000000  RSI: 0000000000000000  RDI: 00007fa6508fe910
RBP: 00007fa6508fe8f0   R8: 00007fa6508fe930   R9: 0000000000000000
R10: 00007fff2a1884b0  R11: 0000000000000246  R12: 0000000000000000
R13: 0000000000000000  R14: 0000000000000000  R15: 00007fa6508fe990
ORIG_RAX: 00000000000000a6  CS: 0033  SS: 002b

【问题讨论】:

    标签: linux linux-kernel crash-dumps


    【解决方案1】:

    foobar() 的参数可能是在寄存器中传递的,因此它可能根本不存在于任何内存地址。参数的类型将决定它是在寄存器中传递,还是在内存中传递。

    您在评论中提到该函数的原型是:

    static void foobar(struct bar *b)
    

    因此,第一个参数是常规 INTEGER 类型(由 x86_64 ABI 定义;这包括指针)。要找到该指针参数的值,您需要查看您的foo 函数从入口点到当前指令(即RIP)的反汇编。该值将被传递给%rdi 中的函数。

    但是,%rdi 中的值可能已在函数入口和发生转储的指令之间被覆盖或修改。在这种情况下,您可能需要做一些侦探工作来逆向工作并找到最初传递的参数。

    作为一般方法,我建议:

    • 获取函数的反汇编,从入口点到显示的RIP

    • 看看%rdi 是如何在反汇编中使用的。有没有修改%rdi 的东西?是否有任何函数调用(它们本身可能会覆盖%rdi 值)。如果不是,你的论点是00007fa6508fe910

    • 如果%rdi 被修改,查看是否已复制到另一个寄存器,或保存在堆栈中。如果没有,请查看调用者如何生成该指针,通过查看其反汇编。

    【讨论】:

    • 参数不是整数,是结构体。这种情况我该怎么办?
    • 是结构体还是指向结构体的指针?你能在你的问题中包含 foo 的原型吗?
    • 它是一个指向结构体static void foobar(struct bar *b)的指针
    猜你喜欢
    • 2022-12-11
    • 2022-12-01
    • 2020-07-11
    • 2022-08-13
    • 1970-01-01
    • 2014-02-07
    • 1970-01-01
    • 1970-01-01
    • 2017-07-29
    相关资源
    最近更新 更多