如何捕获函数调用

时间:2018-10-01 23:15:01

标签: c++ windows winapi visual-c++ c++14

注意:本主题不是关于调试和尝试,抛出,捕获的问题,我不能直接在函数中放置任何内容,而只能像WINapi那样受外部影响。

如果调用ANY函数,我需要某种方式在我的APP中获取信息。它应该在运行时“捕获”函数调用,我无法为我的APP中存在的每个函数实现任何额外的代码。我认为某些WINAPI应该可以工作,但是我找不到合适的方法来处理来自进程的每个调用。作为信息,拥有三样东西将是一件好事:

  1. 刚刚被调用的函数的entryPoint(地址)。
  2. 很高兴定义此函数的返回类型。
  3. 它的参数例如(int,char)。

P.S。知道我(或其他)进程中当前正在执行多少功能将非常高兴。

4 个答案:

答案 0 :(得分:2)

要在调用应用程序中的函数时执行某些操作,您必须使用/Gh命令行开关Enable _penter Hook Function进行编译,也可能需要使用/GH Enable _pexit Hook Function进行编译。然后,您可以定义_penter函数(也许还有_pexit),该函数在进入(离开)您的应用程序函数时将被调用。

这些开关必须在项目属性-> C / C ++->命令行中手动输入。

功能必须为naked

extern "C" void __declspec(naked) _cdecl _penter( void ) {
    // Save registers.
    _asm {
        push eax
        push ebx
        push ecx
        push edx
        push ebp
        push edi
        push esi
    }  

    // Your code here.

    // Restore registers.
    _asm {
        pop esi
        pop edi
        pop ebp
        pop edx
        pop ecx
        pop ebx
        pop eax
        ret
    }
}

为明显的减速做好准备。

_penter_pleave调用函数时,您会遇到非常讨厌的重入问题和堆栈溢出。使用一些保护变量或仅调用裸函数。

下一步是从PDB文件中提取数据,但是如果您可以描述要使用此信息做什么,这将有所帮助。您打算重新执行性能分析或功能覆盖范围测试吗?

我们不能使用__func__宏,因为我们使用的函数错误。也许生成详细的地图文件就足够了。我们可以获取返回地址并在地图文件中进行查找。

其他链接:

答案 1 :(得分:1)

不,你不能。

功能通常在运行时不存在。他们没有名字。它们的类型只是位。在这种情况下,通话本身就可以消除。

有许多事情与您所描述的有些接近。分析,检测,使用DLL作为代理等。我的意思是,使用调试符号表(例如来自MSVC的pdbs),您可以每秒中断一个进程10次并对其进行概要分析。但是,没有一个满足您的要求,因此答案仍然是否。

答案 2 :(得分:0)

如果可执行文件具有专用的pdb符号文件,则可以编写一个简单的调试器来加载可执行文件并检查可执行文件。您可以在感兴趣的功能上设置软件断点,它将进入调试器。根据遇到的断点,然后可以使用Microsoft调试接口访问SDK(DIA SDK)获取有关该函数参数,返回值等的信息。查找MinDBG,这是一个有关如何编写最简单的调试器的简单Win32调试器。 。另外,请查阅DIA SDK Api的有关如何解密exe的信息。只有在您的可执行文件具有专用符号的情况下,此功能才起作用。

答案 3 :(得分:0)

我没有获得确切的上下文,但是也许您可以编写另一个C ++文件:

  • 覆盖函数

  • 记录参数,时间戳,...

  • 调用覆盖的函数

类似的东西:

void A::foo(a,b,c)
{
  // log timestamp, parameters...
  B::foo(a,b,c);
  // log elapsed time, returned value...
}