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“谎言”在这里。 当你打印funcptr
或gio
你会看到实际的地址,这就是写入时跳转到的地址
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