【问题标题】:How to log the stack return address of a function in c++如何在c ++中记录函数的堆栈返回地址
【发布时间】:2012-06-26 08:31:12
【问题描述】:

我想知道如何记录函数的堆栈返回地址?

如果你记录这样的参数:

int (WINAPI *pSend)(SOCKET s, const char* buf, int len, int flags) = send;
int WINAPI MySend(SOCKET s, const char* buf, int len, int flags);

//在DllMain下面

int WINAPI MySend(SOCKET s, const char* buf, int len, int flags)
{
    fopen_s(&pSendLogFile, "C:\\SendLog.txt", "a+");
    fprintf(pSendLogFile, "%s\n", buf);
    fclose(pSendLogFile);
    return pSend(s, buf, len, flags);
}

那我该如何记录 Send 的返回地址呢?

【问题讨论】:

  • 返回地址是指保存的EIP吗?
  • 你想拦截Socks.dll之类的win32 dll的Send函数还是你自己的send函数?

标签: c++ c logging assembly hook


【解决方案1】:

我不确定您要达到什么目标,因此很难知道这是否是正确的答案。我假设您知道自己在做什么,但我会敦促您重新考虑您的设计。

话虽如此,请查看 http://msdn.microsoft.com/en-us/library/64ez38eh 处的内部函数 _ReturnAddress(),它将为您提供将在您从返回中调用 _ReturnAddress() 的函数之后立即执行的指令的地址,以及 _AddressOfReturnAddress() 处的 @ 987654322@ 会给你存储返回地址的地址。

务必仔细阅读文档并理解您返回的地址代表什么。如果您操纵退货地址,请非常小心,因为如果您做错事情,事情可能(并且将会)发展。

【讨论】:

    【解决方案2】:

    您不能以独立于平台/编译器的方式执行此操作。在 Windows 中,您可以使用 StackWalk/StackWalk64 函数。几年前我用过它们。如果您有堆栈中模块的调试信息,您就可以获得函数的名称。

    例如看这个:http://msdn.microsoft.com/en-us/library/windows/desktop/ms680650(v=vs.85).aspx

    【讨论】:

    • 如果这是在我正在挂钩的进程中怎么办?我没有调试信息。
    • 您需要调试信息。根据我的经验,即使使用调试信息(.pdb 文件),您也只能在 90% 的情况下获得合理的结果。如果没有这些信息,利率会下降到 30%。不过这总比没有好。
    • @Pepsi_1 如果您无法重新编译程序(您只有二进制文件,没有源代码)并且没有符号,那么获取函数返回地址并不是一件容易的事。为了得到它们,您需要分析程序的代码或或多或少地逐条指令执行它,以便您可以拦截callret 指令。甚至那些也不能保证在那里并相互平衡。它们可以通过jmp 和其他指令来实现。
    猜你喜欢
    • 1970-01-01
    • 2011-02-02
    • 2020-09-23
    • 1970-01-01
    • 2014-04-21
    • 2021-05-20
    • 2017-02-24
    • 2010-12-14
    相关资源
    最近更新 更多