Windows:以C ++获取函数地址

我试图使用memcpy将函数地址复制到缓冲区中。

我遇到的问题是获取函数地址。 这是我的代码:

__declspec(noinline) int gio()
{
    const char yle[] = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
    return 7;
}

int main(int argc, TCHAR* argv[])
{
    int(*funcptr)() = gio;
    unsigned char *p = (unsigned char *)&funcptr;
    size_t ik;

    for (ik = 0; ik < sizeof funcptr; ik++)
    {
        printf("%02x ", p[ik]);
    }
    putchar('n');

    printf("gio x -> %xn", gio);
    printf("gio p -> %pn", gio);
}

我创建了一个小测试程序,我尝试以不同的方式打印函数地址。

我使用Visual Studio并关闭了优化和内联函数扩展(但仍然使用noinline)。 所有的打印语句打印相同的输出( 0x00d213ca截图),但是当我把我的光标(VS内)放在gio函数上时,它显示完全不同的地址( 0x00d218c0截图)。

当我右键点击gio功能并Go To Dissasembler我跳转到当我将光标放在它0x00d218c0时显示的地址( 0x00d218c0屏幕截图)。 这清楚地显示了这个功能的真实位置。

我在这里有点困惑,好像我不明白的东西。

为什么打印语句显示不正确的值? 获得“真实”功能地址的方法是什么?


Visual Studio“谎言”在这里。 当你打印funcptrgio你会看到实际的地址,这就是写入时跳转到的地址

gio() // or funcptr()

启用增量链接后,此值与Visual Studio因鼠标悬停在gio时告诉您的值不同,请参阅/ INCREMENTAL。

可能包含跳转线来处理功能到新地址的重定位。

要找出您的代码的地址,您可以禁用增量链接或
使用DIA SDK:

// initialize DIA SDK, etc.

void (*fp)() = &foo;
printf("foo(): %pnn", foo);

HMODULE hModule = GetModuleHandle(NULL);
DWORD rva = (DWORD)((size_t)fp - (size_t)hModule);

IDiaSymbol *pDiaSymbol;
hr = pDiaSession->findSymbolByRVA(rva, SymTagPublicSymbol, &pDiaSymbol);
if(FAILED(hr) || !pDiaSymbol)
    return hr;

ULONGLONG targetVA;
hr = pDiaSymbol->get_targetVirtualAddress(&targetVA);
pDiaSymbol->Release();

if(FAILED(hr))
    return hr;

if(hr == S_OK)
    printf("foo is a thunk, actual address: %pnn", (LPVOID)((size_t)hModule + targetVA));

但可能有一种我不知道的简单方法。

链接地址: http://www.djcxy.com/p/41365.html

上一篇: Windows: Get function address in C++

下一篇: Assignment in method call bad practice?