I am programming a crypter for PE files. The decrypter stub is written in assembly and the crypter in c++. I successfully encrypted some executables and they run without any problems. (e.g. WinXP's explorer.exe, calc.exe etc.) But I found out that it only works if the executable doesn't have a .rdata section. Does anybody know why this could be (I think that the import table is there)? And which of the 16 data directories do I need to preserve? (I always leave the import table and the export table). What shall I do wiht the tls table and all the others? The .reloc section is also skipped.

Before crypting:

-------------
MZ HEADER
-------------

PE_HEADER

-------------

.text
-------------
+import
+space (0's)
-------------

.data

-------------

etc.

-------------

----------------------------------------------------------

After crypting:

-------------
MZ HEADER
-------------

PE_HEADER

-------------

.text(crypted)
-------------
+import(skipped)
+space (0's) (<== decrypter stub is somewhere there; new entrypoint)
-------------

.data(crypted)

-------------

etc. (crypted)

-------------
Posted on 2005-02-14 04:16:08 by asmpower
The .rdata section contains AT LEAST 2 things: the Debug Directory (a bunch of debug stuff in exe files) and the Description string (if any).
It may or may not contain initialized data.
It may or may not contain relocations.
Don't follow patterns, follow specs.
Posted on 2005-02-15 05:21:37 by Homer
Thank you for your reply. I also need to know which of the IMAGE_DATA_DIRECTORY's you can not encrypt. Until now, I skip the import/export table and relocations. Bound imports and the IAT are set to zero (RVA and size). What about the tls etc.? I mean, which tables does the PE loader need to map the exe into memory except of imports and exports?
Posted on 2005-02-15 07:33:21 by asmpower
when parsing section table for .rdata section you are proably over encrypting the data, by this i mean your taking the amount of data to encrypt as SizeOfData and not VirtualSize:



/* dwX = VirtualAddress */

if (dwX >= pSecHdr->SizeOfRawData)
{
dwSizeTbl[dwGlobalCount] = pSecHdr->SizeOfRawData;
}
else
{
dwSizeTbl[dwGlobalCount] = dwX;
}


If your writing a real compressor or protector your not to supposed to perserve and DataDirectory entries because the entire file will be encrypted.
Posted on 2005-02-15 18:57:41 by archphase