简体   繁体   中英

Write and read struct to file

I'm having problems trying to save a struct to a new PE section and then reading. 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).

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.

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. 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. 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 .

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.

You need to allocate tScript.dwKeySize + 1 bytes instead, if the size doesn't already include the string terminator.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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