5

I am toying with writing a basic PE packer, whose job is simply to execute the attached target PE in memory. I have spent a couple of days getting intimate with the format, and I think that I have grasped it well enough for the purpose. These are the methods I use:

  1. Firstly, the target is bundled with the loader by being inserted into the .data section of a nasm generated object file, which is later compiled together with the loader.
  2. Upon execution, the Image Data Directory is examined, and the Import Address Table properly bound by loading the needed libraries and functions.
  3. The PE and all of its sections need to be properly laid out in memory, hence ImageBase and SizeOfImage are read, and sufficient virtual memory is allocated for the next two operations.
  4. PE headers are written into the new location.
  5. Section data is gathered via section headers, and every section gets written into the new memory space, each into its designated virtual address. Proper permissions via VirtualProtect() are also set.
  6. Finally, OptionalHeader.AddressOfEntryPoint gets called.

The loader, of course, has an exotic image base, as to not conflict with the standard 0x00400000 base. My problems lies somewhere along there. Almost every .exe has its relocations table stripped, so there's no way to do a base relocation if the desired base address is unavailable. The loader having a non-standard image base solves the problem to an extent. The target's desired base is only available in about 50% of runs. I've tried to find out what might occupy the memory in the other 50%, and have found out that it's almost always a section view. Of what, or whose, I don't know. I've tried to use both NtUnmapViewOfSection and NtFreeVirtualMemory, but they don't solve the problem. The first seems to introduce memory corruption and the second does nothing. Is there any way of claiming that memory? Here's a screenshot from ProcessHacker: .

All ideas are welcome.

3

You might want to:

  1. give your packer stub have the same standard ImageBase
  2. allocates memory somewhere else
  3. relocate the (EIP-independant, for convenience) stub code there
  4. to rebuild the original code at the original ImageBase without any risk.
| improve this answer | |
  • That's the exact same thing I thought of in between asking the question and coming here to check for answers! Yes, I think that'll do it. – hauzer Aug 30 '13 at 19:09
0

Try getting code inspiration from process hollowing.

Here's one that remotely runs it on a new space: https://github.com/hasherezade/libpeconv/tree/master/run_pe https://github.com/m0n0ph1/Process-Hollowing

Try:

  1. run the packer loader from a newly allocated memory (copy loader shellcode to and run from RWX allocated mem.)
  2. unmap loader PE image, realloc, and replace it with new PE image
  3. dynamically import functions from new PE image
  4. jump to entry point of new PE image

I haven't dug deep about resource loading yet. But if the new PE image uses LoadResource, it might read the loader's instead. Not sure about this.

You can get more ideas from debugging a UPX packed sample.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.