我在尝试将结构保存到新的PE部分然后阅读时遇到问题。 结构看起来像:
#pragma pack(push, 1)
typedef struct _SCRIPT_STRUCT
{
DWORD dwKeySize;
unsigned char *lpKeyBuffer;
DWORD dwScriptSize;
unsigned char *lpScriptBuffer;
} SCRIPT, *PSCRIPT;
#pragma pack(pop)
lpKeyBuffer是一个随机的十六进制值(0-255)数组,lpScriptBuffer包含一个加密的(RC4)脚本(如果重要的话,在Lua中)。
我认为结构已在创建的新部分中成功编写,但我无法读取缓冲区。
(书面方式):
SCRIPT tScript;
tScript.dwKeySize = KEY_SIZE;
tScript.lpKeyBuffer = new unsigned char[tScript.dwKeySize];
GenerateKey(tScript.lpKeyBuffer, KEY_SIZE);
tScript.dwScriptSize = szScript.size();
tScript.lpScriptBuffer = new unsigned char[tScript.dwScriptSize];
memcpy(tScript.lpScriptBuffer, szScript.c_str(), tScript.dwScriptSize);
tScript.lpScriptBuffer = (unsigned char*)szScript.c_str();
rc4_encryption(tScript.lpScriptBuffer, tScript.dwScriptSize, tScript.lpKeyBuffer, tScript.dwKeySize);
DWORD dwScriptStructSize = sizeof(DWORD) + tScript.dwKeySize + sizeof(DWORD) + tScript.dwScriptSize;
char lpStructBuffer[dwScriptStructSize];
ZeroMemory(lpStructBuffer, dwScriptStructSize);
memcpy(lpStructBuffer, &tScript, dwScriptStructSize);
//CreateFile, create new section, etc
SetFilePointer(hCurrent, LastHeader->PointerToRawData, NULL, FILE_BEGIN);
WriteFile(hCurrent, lpStructBuffer, dwScriptStructSize, &dwRead, 0);
(读):
SCRIPT tScript;
memcpy(&tScript, lpScriptBuffer, dwSectionSize);
tScript.lpKeyBuffer = new unsigned char[tScript.dwKeySize];
tScript.lpKeyBuffer[tScript.dwKeySize] = 0x00;
tScript.lpScriptBuffer = new unsigned char[tScript.dwScriptSize];
tScript.lpScriptBuffer[tScript.dwScriptSize] = 0x00;
printf("dwScriptSize = %lu\n", tScript.dwScriptSize);
printf("dwKeySize = %lu\n", tScript.dwKeySize);
rc4_encryption(tScript.lpScriptBuffer, tScript.dwScriptSize, tScript.lpKeyBuffer, tScript.dwKeySize);
printf("script: %s\n", tScript.lpScriptBuffer);
DWORD输出正确但最后一个printf显示奇怪的符号。
答案 0 :(得分:4)
您无法从一个进程保存指向文件的指针,并从另一个进程读取它们并期望它能够正常工作。指针通常是每个进程唯一的,尤其是动态分配的数据。当你从另一个进程的文件中读取一个指针(即使它是同一个程序)时,指针将不再指向分配的数据,它只是一个随机的"杂散指针,并取消引用它(就像将其打印为字符串时一样)将导致未定义的行为。
您需要将字符串与结构分开保存。阅读起来很简单,因为您拥有可变长度数据的大小,并且您知道数据的保存位置(与结构相关)。
来自伯劳的评论让我思考并仔细研究你所呈现的代码。它不完整,所以这都是猜测工作,但实际问题实际上可能与我上面描述的不同。
让我们来看看你的#34;阅读"代码(实际上并没有显示任何读数):
SCRIPT tScript;
memcpy(&tScript, lpScriptBuffer, dwSectionSize);
tScript.lpKeyBuffer = new unsigned char[tScript.dwKeySize];
tScript.lpKeyBuffer[tScript.dwKeySize] = 0x00;
tScript.lpScriptBuffer = new unsigned char[tScript.dwScriptSize];
tScript.lpScriptBuffer[tScript.dwScriptSize] = 0x00;
现在假设您将结构读入字符缓冲区lpScriptBuffer
(类似于您在编写时使用的方式,但实际上并不需要),那么您对上面提到的指针仍有同样的问题,但是还有另一个问题:你重新分配指针指向一些新分配的内存。这一切都很好,但问题在于你实际上并没有尝试初始化那个记忆。并不是说你真的可以使用你展示的代码,但这不是重点。你没有初始化内存的问题恰恰是它没有初始化,因此会有一个不确定的内容,看似随机,很可能不是有效的文本。使用未初始化的内存就像解除引用指针一样,未定义的行为。
还有另一个问题:你写出你分配的内存范围。正如您所知,数组中的索引是从零开始的。因此,如果您分配size
个字节,则有效索引来自(包括)0
到size - 1
。
因为您分配了例如tScript.dwKeySize
字节的内存然后顶部索引是tScript.dwKeySize - 1
但是你使用tScript.dwKeySize
作为索引,这超出了界限并再次导致未定义的行为。
如果大小不包含字符串终止符,则需要分配tScript.dwKeySize + 1
个字节。