我有这段代码:
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;
}
答案 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;
}
由于pHeader
是buffer
的别名,因此您将返回本地变量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
。