Windows:使用C++获取函数地址

Ojs*_*Ojs 7 c++ windows pointers function

我正在尝试使用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 -> %x\n", gio);
    printf("gio p -> %p\n", gio);
}
Run Code Online (Sandbox Code Playgroud)

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

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

当我右键单击gio功能时,Go To Dissasembler我跳到我把光标放在它上面时显示的地址(0x00d218c0 截图).这清楚地表明了这个功能的真正含义.

我在这里有点困惑,似乎我不明白的东西.

为什么print语句显示不正确的值?获取"真实"功能地址的方法是什么?

Axa*_*alo 5

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

gio() // or funcptr()
Run Code Online (Sandbox Code Playgroud)

启用增量链接gio后,此值与 Visual Studio因 thunking 而将鼠标悬停在其上时告诉您的值不同,请参阅/INCRMENTAL

可能包含跳转 thunk 来处理函数到新地址的重定位。

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

// initialize DIA SDK, etc.

void (*fp)() = &foo;
printf("foo(): %p\n\n", 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: %p\n\n", (LPVOID)((size_t)hModule + targetVA));
Run Code Online (Sandbox Code Playgroud)

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