在Debugger中跟踪指针的地址

时间:2015-01-23 18:19:14

标签: c++ pointers

我有这段代码:

    void WriteToConsole(IMAGE_NT_HEADERS *ntHeader)
    {
    std::cout << "AddressOfEntryPoint = " <<
        ntHeader->OptionalHeader.AddressOfEntryPoint << std::endl;
    }
    void main()
    {
    //something
    IMAGE_NT_HEADERS *NtHeader = GetWinNTHeader(dosHeader->e_lfanew);
    WriteToConsole(NtHeader);
    }

为什么NtHeader和ntHeader的地址不同? 我正在使用调试器跟踪地址。

IMAGE_NT_HEADERS * GetWinNTHeader(long offset)
{
    // IMAGE_NT_HEADERS size is 120
    char buffer[120];
    file.seekg(offset);
    file.read(buffer, 120);
    IMAGE_NT_HEADERS* pHeader = (IMAGE_NT_HEADERS*)(buffer);
    if (IsBadReadPtr(pHeader, sizeof(IMAGE_NT_HEADERS)))
        return NULL;
    if (pHeader->Signature != IMAGE_NT_SIGNATURE)
        return NULL;
    return pHeader;
}

3 个答案:

答案 0 :(得分:2)

我想您正在使用一些调试器来查看NtHeader的值 价值&#34;变化&#34;因为它已经在堆栈上分配,并且在你调用WriteToConsole后你离开了它的范围,导致NtHeader的重新分配。

编辑:

在main()中分配NtHeader的事实使得这个问题有点无意义,因为如果程序即将退出,为什么你会关心变量值呢?

答案 1 :(得分:0)

这就是你想要的东西我想:

#include <iostream>
#include <string>

using namespace std;

 void WriteToConsole(char *&ntHeader)
    {
    std::cout << "AddressOfEntryPoint = " <<
       &ntHeader  << std::endl;
    }


int main()
{

    //something
    char *NtHeader = "hello";
std::cout << "AddressOfEntryPoint = " <<
       &NtHeader  << std::endl;
    WriteToConsole(NtHeader);

return 0;
}

输出: AddressOfEntryPoint = 0x7fff7a90b168 AddressOfEntryPoint = 0x7fff7a90b168

现在,如果你改变它以通过指针传递,

void WriteToConsole(char *ntHeader)

adn这样称呼WriteToConsole(NtHeader);

然后你得到不同的地址。 AddressOfEntryPoint = 0x7fffae028ca8 AddressOfEntryPoint = 0x7fffae028c88

如果您不想创建副本并希望使用相同的地址,则始终通过引用传递。

答案 2 :(得分:0)

无论您的函数尝试做什么,底层问题都是您返回本地变量的地址。这是未定义的行为。

基本上,你这样做:

IMAGE_NT_HEADERS * GetWinNTHeader(long offset)
{
    // IMAGE_NT_HEADERS size is 120
    char buffer[120];
    //...
    IMAGE_NT_HEADERS* pHeader = (IMAGE_NT_HEADERS*)(buffer);
    //...
    return pHeader;  
}

由于pHeaderbuffer的别名,因此您将返回本地变量buffer的地址。

解决方案基本上是 - don't do this。永远不要返回指向局部变量的引用或指针。

这是一个解决方案,使用结构:

struct HeaderBuffer
{
   char buffer[120];
};

HeaderBuffer GetWinNTHeader(long offset)
{
    // IMAGE_NT_HEADERS size is 120
    HeaderBuffer hBuffer;
    file.seekg(offset);
    file.read(hBuffer.buffer, 120);
    IMAGE_NT_HEADERS* pHeader = (IMAGE_NT_HEADERS*)(hBuffer.buffer);
    if (IsBadReadPtr(pHeader, sizeof(IMAGE_NT_HEADERS)))
        hBuffer.buffer[0] = 0;
    else
    if (pHeader->Signature != IMAGE_NT_SIGNATURE)
       hBuffer.buffer[0] = 0;
    return hBuffer;
}

 void WriteToConsole(IMAGE_NT_HEADERS *ntHeader)
 {
    std::cout << "AddressOfEntryPoint = " <<
        ntHeader->OptionalHeader.AddressOfEntryPoint << std::endl;
 }

来电者看起来像这样:

 int main()
 {
    HeaderBuffer buf = GetWinNTHeader(dosHeader->e_lfanew);
    IMAGE_NT_HEADERS *NtHeader = static_cast<IMAGE_NT_HEADERS*>(buf.buffer);
    WriteToConsole(NtHeader);
 }

注意:这还没有编译,所以请注意这一点。

基本上,该函数返回一个包含在struct中的char缓冲区。我们返回一个没有信息的缓冲区(char缓冲区的NULL为0)而不是返回strlen