其他分享
首页 > 其他分享> > 附加的探查器库中的c函数地址与主题代码库中的c函数地址不同

附加的探查器库中的c函数地址与主题代码库中的c函数地址不同

作者:互联网

我已经用C语言编写了一个Instrument-er,通过挂接enter和exit调用来记录进入和退出功能.它可以使用旧版代码库正常工作.但是,在挂钩我从git下载的项目时,我保存在主题代码中的extern变量中的函数地址在Profiler库中表现出不同.这搞砸了挂钩函数和保存函数之间的函数指针比较.

主体代码主文件中的函数地址,断点位于当前探查器代码中的_penter hook函数内部
enter image description here

在分析器代码中,同一条目显示了一个不同的地址,该地址的函数名称前面带有“ _”
The same entry is showing a different address with a "_" preceding the function

我不知道它是如何更改地址的,我想知道我是否做错了什么.

我这样做的方法是,有一个外部函数指针数组(及其名称),该数组用主题代码函数在主题主文件中的引用(其中所有函数可用)初始化.在库的挂钩函数(_penter)中,我得到刚输入的函数的地址.因此,我将其与extern数组中的地址进行比较,如果匹配,则记录输入的函数.

来自PROFILE.H的片段(探查器)

extern Signature FuncTable[3000]; 

来自PROFILE.CPP的片段(探查器)

void _stdcall EnterFunc0(unsigned * pStack)
{
    void      * pCaller;
    pCaller = (void *)(pStack[0] - 5); // the instruction for calling _penter is 5 bytes long
    Signature * funct = FuncTable; //the table that has references to functions and their names
    funct = FuncTable;
    while (funct->function)
    {
        //const BYTE * func = (const BYTE *)funct->function;
        if ((void *)(pStack[0] - 5) == (void *)(funct->function))
        {
            int a = 0;
            linesBuffer = linesBuffer + "Entering " + funct->signature + ";";
            linesBuffer = linesBuffer + "\n";
            WriteToFile(false); //function buffers 100kb before writing
            break;
        }
        funct++;
    }
}
extern "C" __declspec(naked) void __cdecl _penter()
{
    _asm
    {
        pushad              // save all general purpose registers
            mov    eax, esp     // current stack pointer
            add    eax, 32      // stack pointer before pushad
            push   eax          // push pointer to return address as parameter to EnterFunc0

            call   EnterFunc0

            popad               // restore general purpose registers
            ret                 // start executing original function
    }
}

SNIPPET FROM main.c(主题代码主文件)

#include "../Profile/Profile.h"
Signature FuncTable[] = {
    { (int)TetrisView_ProcessPauseMenu, "TetrisView_ProcessPauseMenu" },
    { NULL }
};

解决方法:

我认为这是因为增量链接.启用后,您将获得一个增量链接表(ILT). ILT包含一个跳转表.调用函数时,将通过此ILT进行调用.

在FuncTable中,您将获得一个位于ILT中的地址,而不是实际函数的地址.但是在_penter中,其返回地址将是实际函数(这是pCaller中的内容).

关闭增量链接,就可以了.

标签:c,profiler,instrumentation,trace
来源: https://codeday.me/bug/20191012/1901596.html