Click here to Skip to main content
15,921,837 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hey,
I know that I can simply load content of .exe in binary mode and I'll be able to get its binary representation but how about reading its binary representation from its process's memory? I've created a simple program which uses VirtualQueryEx and ReadProcessMemory to get the binary representation. It works for simple console applications (I tried only created by myself). So I got the binary representation of some other program from its process's memory and saved it to a file.exe. Unfortunately I couldn't run such application - no error occurs, it just doesn't open. So I have compared the original .exe's binary from disc with what I read from memory and it seems like the memory that I have read is not completely the same as the binary representation of the .exe on the disc! It turned out that the memory I read differs slightly in a few places, although the sizes are the same. All other places are completly the same. How is that possible? I assume that every casual application consists of dos header -> PE header -> Section header and then fro section header I can find all other sections.
What's interesting is that I've created this program a couple of weeks ago and I'm almost sure that it worked correctly by then but it no longer does... Is that possible that the exe's binary representation in memory is different from its binary on disc?

PS: I'm using Windows 8 64 bit
Posted
Comments
pasztorpisti 25-Sep-13 12:45pm    
I haven't played around with PE files for a long time but after dumping you have to undo the relocations done on the code of the PE file by the loader. Another thing that is problematic is restoring the import table, I don't exactly remember the details but I'm afraid it can't always be done and it can be difficult. As far as I remember the IAT is overwritten by the PE loader and the OriginalFirstThunk table that would mirror the contents of IAT is optional and isnt always present, for this reason you have to find out function imformation from the actual function pointers written to IAT and that can be difficult. And of course there can be other problems too that I dont remember.
Savail 25-Sep-13 13:17pm    
Thanks for answer! I will look into some info connected with relocations. Anyway, according to my previous comment... I have just checked which fields in IMAGE_SECTION_HEADER are different in my dumped .exe and the original. It turns out that my .exe has IMAGE_SECTION_HEADER::PointerToRawData zeroed while the original .exe has it filled with some address. Wierd...
Well, I hope I'll be able to solve my problem thanks to the info you provided! Thanks a lot!
pasztorpisti 25-Sep-13 15:12pm    
PointerToRawData is the offset of the section in the file, it is meaningless in memory. You can easily reconstruct them when writing out the sections to the file. You also have to make sure that you start writing out the section in the file to an offset that is a multiple of IMAGE_OPTIONAL_HEADER.FileAlignment and FileAlignment must be a multiple of the disk sector size. Usually FileAlignment is either 512 or 4K, I recommend using one of these. In case of invalid file alignment the windows loader will refuse to load your module.
EDIT: To learn about PE relocations taking a look at this code may come handy: http://www.codeproject.com/script/Articles/ViewDownloads.aspx?aid=430684 read the LoadDLL.c file.

1 solution

Of course you cannot do such things in such a simple way. Even if you managed to copy the executable segment memory correctly. This is not how the memory is filled in when PE file is loaded. It's done via the system loader which actually makes a lot of work.

The PE describes some chunks of memory (even if this is a one chunk) using some relative addressing which is not operational per se. When the new process is created, it receives its own memory space. This thing is quite complex, as the memory could be fragmented, paging is used, virtual memory is used, and so one. For the process, it looks like a flat memory. In this space, executable code is translated to convert all addresses in the addresses in the provided address space.

If you mechanically copy the memory into some other PE file, it won't be a correctly structured PE file.

—SA
 
Share this answer
 
Comments
Savail 25-Sep-13 11:57am    
Actually, I guess it might be a correctly structured PE file cause I managed to create identically the same .exe from simple console program's process memory. It's strange that my method doesn't work for some more complex programs. The first difference between my .exe fro memory and the original .exe I've found in section header and it was only 2 bytes! The rest was all ok until next differences...
I just don't know where do these differences come from and how to fix them
Sergey Alexandrovich Kryukov 25-Sep-13 12:00pm    
Unfortunately, I don't know either, based on your information. Curious why would you do all that...
—SA
pasztorpisti 25-Sep-13 12:39pm    
Dumping PE files is a classic way of breaking some applications that are packed with antidebug exe compressors. By dumping you can bypass the antidebug code of the decompressor. Of course there are many tricks to prevent this kind of dumping and the headers of a packed application doesn't contain the sections for the original app but for cracking you usually don't need a functioning exe, just easier to reverse-engineer code and some offsets that can be patched after decompression. An old tool I used in the old days for dumping PE sections from memory was procdump.exe by g-rom (not the procdump of sysinternals). This way you can write a crack that somehow detects the end of decompression and then patches the decompressed code and you can create the patches by reverse engineering the dumped (but not necessarily functioning) exe bytes of the uncompressed prog.
Sergey Alexandrovich Kryukov 25-Sep-13 12:41pm    
Great points, thank you.
—SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900