Windows: Get function address in C++

I'm trying to get the function address to copy its content into a buffer using memcpy.

The problem I'm having is with getting function address. Here is my code:

__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);
}

I created a little test program where I try to print function address with different ways.

I'm using Visual Studio and had turn off the optimization and inline function expansion(but used noinline anyway). all the print statements print same output( 0x00d213ca screenshot) but when I put my cursor(inside VS) on gio function it shows totally different address( 0x00d218c0 screenshot).

When I right click on gio function and Go To Dissasembler I jump to the address which was shown when I put my cursor on it( 0x00d218c0 screenshot). Which clearly shows where this function really is.

I got little confused here, seems like I don't understand something.

Why do print statements show incorrect value? What is the way to get the "real" function address?


Visual Studio "lies" to you here. When you print either funcptr or gio you see the actual address, that is the address you jump to when writing

gio() // or funcptr()

With Incremental Linking enabled this value is different from what Visual Studio tells you when you hover over gio because of thunking, see /INCREMENTAL.

May contain jump thunks to handle relocation of functions to new addresses.

To figure out the address of your code you can either disable Incremental Linking or
use the 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));

But there might be a simpler way that I'm not aware of.

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

上一篇: 我可以从Java 9 Nashorn引擎运行ECMAScript 6吗?

下一篇: Windows:以C ++获取函数地址