【问题标题】:How to find return instruction in memory如何在内存中找到返回指令
【发布时间】:2015-09-06 14:35:01
【问题描述】:

我有一些调用函数的 C 代码。我正在 Windows 上的 Visual Studio 中编译此代码。有没有一种直接的方法来查看返回指令(操作码)和返回地址? 我尝试在 Visual Studio 中使用内存窗口,但我只看到我的缓冲区“blie”和一些十六进制解释的内存值。我认为 CC 可能是一个操作码,但我希望有一种方法/软件可以清楚地查看返回指令和返回地址。

#include <stdio.h>
#include <stdlib.h>

int foo(char *);

int main(int argc, char *argv[])
{
    if (argc != 1)
        return printf("Supply an argument, dude\n");
    foo(argv[0]);
    return 0;
}

int foo(char *input)
{
    unsigned char buffer[600] = "";

    printf("Adres: %.8X\n", &buffer);
    strcpy(buffer, input);
    return 0;
}

【问题讨论】:

  • 简而言之,不,没有简单的方法。你需要一个成熟的反汇编程序。

标签: c debugging memory opcode


【解决方案1】:

返回地址位于堆栈内存区域(由rsp 寄存器指向,假设您在x86_64),而执行函数返回的代码位于代码内存区域。 如果要查看返回地址,请在 RET 指令处停止进程并查看堆栈顶部。

如果您只想查看生成的代码,您可以使用反汇编程序。当您使用 Windows 时,您可以尝试开源 x64dbg。存在其他选项,例如IDA Pro,您可以在此问题中查看其他选项的列表:https://reverseengineering.stackexchange.com/questions/1817/is-there-any-disassembler-to-rival-ida-pro

【讨论】:

  • 感谢您的回复@halfr。我在 VS 中尝试了以下操作:imgur.com/exRiBzR。当我在 RET 指令处停止时,ESP 在 00FDF988 上。这是否意味着返回地址是 00FDF988?如果是这样,我假设它是内存中的十六进制值之一(a1 15 d5 00),这些值如何转换为 00FDF988?
  • 因为x86little-endian 架构,与字节在内存中的存储方式相比,返回地址必须以“相反”的顺序读取。在您的示例中,esp 指向的字节为a1 15 d5 00,因此返回地址为 00D515A1。
【解决方案2】:

文档摘录:

RET 指令将程序控制权从当前正在执行的程序中转移 执行(被调用的过程)返回到调用它的过程( 调用程序)。控制权的转移是通过复制回报来完成的 指令指针从堆栈指向 EIP 寄存器。

您可以看到返回地址在堆栈上,因此您无法在反汇编中看到它。

关于寻找退货指令 - 不容易。很可能您使用的是 x86 cpu,它是具有可变长度操作码的 CISC(与 RISC 相比)。这意味着为了找到任何操作码,您必须首先“找到”所有操作码。

顺便说一句:您可以在 VS 中查看代码的反汇编。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-21
    • 1970-01-01
    • 1970-01-01
    • 2020-10-28
    • 2012-10-24
    • 1970-01-01
    • 2018-04-08
    相关资源
    最近更新 更多