简体   繁体   English

写入和读取结构到文件

[英]Write and read struct to file

I'm having problems trying to save a struct to a new PE section and then reading. 我在尝试将结构保存到新的PE部分然后阅读时遇到问题。 The struct looks like: 该结构看起来像:

    #pragma pack(push, 1)
typedef struct _SCRIPT_STRUCT
{
     DWORD dwKeySize;
     unsigned char *lpKeyBuffer;
     DWORD dwScriptSize;
     unsigned char *lpScriptBuffer;
} SCRIPT, *PSCRIPT;
#pragma pack(pop)

lpKeyBuffer is a random hex values (0-255) array and lpScriptBuffer contains an encrypted (RC4) script (in Lua if that matters). lpKeyBuffer是一个随机的十六进制值(0-255)数组,而lpScriptBuffer包含一个加密的(RC4)脚本(如果重要的话,请使用Lua)。

I think the struct is successfully written in the new section created but I can't read the buffers. 我认为该结构已成功写入创建的新部分中,但我无法读取缓冲区。

(Writting): (写作):

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

(Reading): (读):

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

The DWORD outputs are correct but the last printf shows strange symbols. DWORD输出正确,但最后一个printf显示奇怪的符号。

You can't save pointers to a file from one process, and read them from another process and expect it to work. 您不能从一个进程中保存指向文件的指针,而不能从另一进程中读取它们并期望它能工作。 Pointers are generally unique per process, especially to dynamically allocated data. 指针通常在每个进程中都是唯一的,尤其是对于动态分配的数据而言。 When you read a pointer from a file from another process (even if it's the same program) that pointer will no longer point to the allocated data, it will just be a "random" stray pointer, and dereferencing it (like you do when printing it as a string) will lead to undefined behavior . 当您从另一个进程(即使是同一程序)的文件中读取指针时,该指针将不再指向分配的数据,它将只是一个“随机”杂散指针,并对其取消引用(就像您在打印时所做的那样)它作为字符串)将导致未定义的行为

You need to save the string separately from the structure. 您需要将字符串与结构分开保存。 When reading it's easy since you have the sizes of the variable-length data, and you know where (in relation to the structure) the data is saved. 读取时很容易,因为您具有可变长度数据的大小,并且知道数据的存储位置(相对于结构)。


The comment from shrike made me think and take a closer look at the code you present. shrike的评论使我思考并仔细研究了您提供的代码。 It's not complete so this is all guess work, but the actual problem might actually be something different from what I described above. 它还不完整,所以这都是猜测工作,但是实际问题实际上可能与我上面描述的有所不同。

Lets take a look at a few lines from your "reading" code (which doesn't actually show any reading): 让我们看一下您的“阅读”代码中的几行内容(实际上并没有显示任何阅读内容):

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;

Now assuming you read the structure into a character buffer lpScriptBuffer (similar to how you use one when writing, not really needed though), then you still have the same problem with the pointers I told about above, but there is another issue: You reassigning the pointers to point to some newly allocated memory. 现在假设您将结构读入一个字符缓冲区lpScriptBuffer (类似于在编写时使用它的方式,尽管实际上并不需要),那么您在上述指针上仍然遇到相同的问题,但是还有另一个问题:您重新分配指向一些新分配的内存的指针。 This is all well and good, but the problem here is that you don't actually try to initialize that memory. 这一切都很好,但是这里的问题是您实际上并没有尝试初始化该内存。 Not that you really can't with the code you show, but that's beside the point. 并不是说您真的不能使用显示的代码,但这是不重要的。 The problem with you not initializing the memory is precisely that, it's uninitialized and therefore will have an indeterminate contents, seemingly random, and most likely not valid text. 您不初始化内存的问题恰恰在于,它尚未初始化,因此将具有不确定的内容,看似随机,并且很可能是无效的文本。 Using uninitialized memory is, like dereferencing stray pointers, undefined behavior . 与取消引用杂散指针一样,使用未初始化的内存也是未定义的行为


There is also yet another issue: You writing out of bounds of the memory you allocate. 还有另一个问题:您超出了分配的内存范围。 As you hopefully knows, indexes in array are zero-based. 如您所希望的那样,数组中的索引从零开始。 So if you allocate size bytes then valid indexes are from (and including) 0 to size - 1 . 因此,如果分配size字节,则有效索引从0 (到包括)到size - 1

Since you allocate eg tScript.dwKeySize bytes of memory then the top index is tScript.dwKeySize - 1 but then you use tScript.dwKeySize as index, which is out of bounds and again will lead to undefined behavior. 由于您分配了例如tScript.dwKeySize字节的内存,因此顶部索引是tScript.dwKeySize - 1但随后您使用tScript.dwKeySize作为索引,这超出了范围,并再次导致未定义的行为。

You need to allocate tScript.dwKeySize + 1 bytes instead, if the size doesn't already include the string terminator. 如果大小尚未包含字符串终止符,则需要分配tScript.dwKeySize + 1个字节。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM