【问题标题】:Windows: Get function address in C++Windows:在 C++ 中获取函数地址
【发布时间】:2018-02-24 19:56:27
【问题描述】:

我正在尝试使用 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 并关闭了优化和内联函数扩展(但无论如何都使用了 noinline)。所有打印语句都打印相同的输出(0x00d213cascreenshot),但是当我将光标(在 VS 内)放在gio 函数上时,它显示完全不同的地址(0x00d218c0screenshot)。

当我右键单击 gio 函数和 Go To Dissasembler 时,我会跳转到当我将光标放在它上面时显示的地址 (0x00d218c0 screenshot)。这清楚地表明了这个函数的真正位置。

我在这里有点困惑,好像我不明白什么。

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

【问题讨论】:

  • 我认为这样的问题是最近才出现的。没有优化的函数是通过跳转到函数体的调度表调用的。函数指针存储调度表条目地址,而调试器可能显示函数体地址。
  • @IInspectable 而这个地址是用来打印函数地址字节的。 “我尝试用不同的方式打印函数地址”
  • 那么我如何获得实际地址?
  • @ZhaniBaramidze:函数指针的大小不需要与数据指针的大小相同。 printf 格式说明符 %p 仅用于数据指针。
  • 您能否提供一些我可以阅读的关于调度表的信息?

标签: c++ windows function pointers


【解决方案1】:

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

gio() // or funcptr()

启用Incremental Linking 后,由于thunking,当您将鼠标悬停在gio 上时,该值与Visual Studio 告诉您的值不同,请参阅/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));

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-07-25
    • 2020-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-25
    • 1970-01-01
    相关资源
    最近更新 更多