簡體   English   中英

Windows:使用C ++獲取函數地址

[英]Windows: Get function address in 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 -> %x\n", gio);
    printf("gio p -> %p\n", gio);
}

我創建了一個小測試程序,我嘗試以不同的方式打印函數地址。

我正在使用Visual Studio並關閉了優化和內聯函數擴展(但無論如何都使用了無內聯)。 所有的打印語句打印相同的輸出( 0x00d213ca 截圖 ),但當我把我的光標(在VS內)放在gio函數上時,它顯示完全不同的地址( 0x00d218c0 截圖 )。

當我右鍵單擊gio函數並Go To Dissasembler我跳轉到我將光標放在其上時顯示的地址( 0x00d218c0 screenshot )。 這清楚地表明了這個功能的真正含義。

我在這里有點困惑,似乎我不明白的東西。

為什么print語句顯示不正確的值? 獲取“真實”功能地址的方法是什么?

Visual Studio在這里“謊言”給你。 當您打印funcptrgio您會看到實際地址,即您在寫入時跳轉到的地址

gio() // or funcptr()

啟用增量鏈接后,此值與Visual Studio在您因為thunking將鼠標懸停在gio時所說的不同,請參閱/ INCREMENTAL

可能包含跳轉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));

但可能有一種我不知道的簡單方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM