views:

90

answers:

2

Here's an example of what I mean...

  • User runs LOADER.EXE program
  • LOADER.EXE downloads another EXE but keeps it all in memory without saving it to disk
  • Runs the downloaded EXE just as it would if it were executed from disk, but does it straight from memory

I've seen a few applications like this, and I've never seen an example or an explanation of how it works.

Does anyone know?

Another example is having an encrypted EXE embedded in another one. It gets extracted and decrypted in memory, without ever being saved to disk before it gets executed.

I've seen that one used in some applications to prevent piracy.

Edit: As a side-note, do programs like UPX work like this? I looked at the code but it is hard to decipher for me, and I'm asking mainly out of curiosity, I don't have a need for it.

+1  A: 

Well if you know where the offset to the entry point of an executable is and you know what parameters it takes then all you need to do is call the function at address "exeBase + entryPointOffset" using a function pointer.

Its worth noting that OS's, on x86 systems at least, tend to not allow you to execute memory that is marked as data. Under windows, for example, this can be changed using the "Virtual ProtectEx" function to mark the memory as executable.

In fact, back in the good old days, this was a common system to save memory. You'd have "overlays" such that you could save memory by swapping the code in and out as needed.

Goz
Would that really work? How can you be certain that there is no jump to an absolute address inside the executable code (which would be resolved at load time)?
Nikola Gedelovski
The absolute address fixups are in the EXE data. That's how Vista's ASLR feature works. Nevertheless, the loader probably moves its bootstrap code out of the way so the EXE loads at its normal base address.
Hans Passant
@Hans: I'm pretty sure that exe's don't (although they *could*) include a relocation section since the exe are the first thing allocated in the address space and therefore never has to be relocated (ASLR is only for .dll's).@Goz: This won't work since the sections in the raw file data are not page aligned: see the PE spec on the difference between file offsets and RVA's.
Simon Buchan
Note that when the wrapper is created, it will know what EXE it's wrapping. It can therefore pick another base address.
MSalters
+2  A: 

A lot of programs that do this just unzip to %TEMP% (I know I do), but the big boys essentially re-implement the OS executable loader, which has to:

  • Map the executable into memory. This is not as simple as it sounds, as the .exe contains multiple 'sections', which must be loaded with page alignment (they must start at addresses that are multiples of 4K) and they each have specific requests - read only, copy on write, zero initialized, etc....
  • Satisfy static imports, by updating the import table section, normally using LoadLibrary() and GetProcAddress().
  • In the case of dlls (which are actually almost identical, the important difference is that they have exports as well as imports), the loader might also have to rebase the dll, if the memory address it was compiled to load at was already in use (which is quite common). This is normally impossible for exe's, though, because they do not include the relocation section which lists the places in the loaded code which need to be updated, because normally they are the first thing loaded into a process, and therefore can't be blocked by something. This means a loader has to have an unusual load address for it's own exe that won't block the loaded exe.

In summary: this is a lot of work. If you are interested, take a look at the PE format specification, which describes .exe and .dll files, and the VirtualAlloc() function.

Simon Buchan
Wow, that sounds much more involved than I thought. Do you have any experience with UPX? Does it even work like this? (I don't know much about packers).I was hoping to be able to come across some source code that demonstrates this that would be somewhat easy to follow.
guitar-
@guitar: I just had a quick look at the code. The loader stub is pretty macro heavy assembly, but it looks like the packer is preprocessing a lot if this work, so the stub can just decompress a already aligned file into memory, and then get the imports. This obviously isn't enough for your 2nd and 3rd example. The packer stuff in http://upx.hg.sourceforge.net/hgweb/upx/upx/file/c3853d205747/src/pefile.cpp is closer, but I'm sure there less special-cased examples elsewhere.
Simon Buchan
This seems like a good start, though it's not quite commercial quality. http://code.google.com/p/egodust/source/browse/trunk/pe.c
Simon Buchan
Thanks, Simon, you rock. :)
guitar-