4

What is the exact reason for dumping a process when the Program Counter is at OEP? I haven't found a decent answer.

This Link says:

In order to identify the IAT structure, Import Reconstructor needs to know the OEP of our application (of the unpacked code).

This leaves me with the following questions:

  1. But how does knowing OEP relate to IAT?
  2. When application is unpacked in memory, can't we get pointer to IAT just by walking through PE header and getting address of IT - and then of IAT?
  3. Why don't we dump application not at OEP but say on jmp leading to OEP? Or one-two instructions after OEP?
5

But how does knowing OEP relate to IAT?

OEP does not relate to the IAT, but is used by import reconstruction tools to find the location of IAT-like structures created by the packer.

When application is unpacked in memory, can't we get pointer to IAT just by walking through PE header

This is exactly why import reconstruction is needed. Because the malware intentionally ruins the IAT in some way or another, only keeping a small set of mandatory functions in it, leaving the work of resolving most of the APIs as part of the unpacking code. Therefore import reconstruction will require we find the IAT by other means (because the PE defined IAT is incomplete/fake).

Why don't we dump application not at OEP but say on jmp leading to OEP? Or one-two instructions after OEP?

When dumping, it is import to have executed all code related to descrambling the packed code. Otherwise, OEP might not be valid executable code. Other than that (and import reconstruction related issues) it is perfectly fine to dump and just adjust the PE's Entry Point to the OEP. Most dumping tools will allow that.


Aside from answering your specific questions, here are the types of packers with regard to their IAT manipulation and what's needed to get a functional IAT in a dumped PE:

  1. When a packer does not change the original import table, import reconstruction is unnecessary. Most PE dumpers will copy the original import table when it's valid or dump it with the PE.

  2. Some packers carry another PE that is hidden at first, and only decrypt/descramble it in it's entirety. Those packers will also carry the IAT in-tact and most dumpers will get the IAT automatically.

  3. Some packers will create their own alternative IAT and implement their own version of API loading/resolving. For those packers, an import reconstruction utility will need to locate that alternative (or, shall we say real?) IAT and create a new IAT in the reconstructed PE from scratch (based on those APIs actually pointed by the original IAT). Import reconstruction will then find ranges of "IAT looking" offsets and make sure they reside in the same location when the PE is loaded. The OEP is therefore scanned for calls that use offset tables that might be suspected as being such an alternative IAT.

  4. Some packers will not create a single IAT, but instead many small IAT tables, such that you would no longer call them "Tables". In those cases, the import reconstruction tool must encounter enough of those small tables and reconstruct each of them separately. In those cases it is even more important not to leave any piece of code still packed, as APIs only used by those pieces of code will not be reconstructed.

  5. Another type of packers make it even harder to resolve APIs for static disassembly (although do not prevent execution of the dumped PE) by dropping the concept of import tables and instead resolve the API requested every time an API call is made. This is usually done by assigning a key/hash that is not trivially recognizable to any API, and walk over DLLs and Export tables every time a call is made, generating the same key/hash for APIs until the correct key is found. This usually mean import reconstruction is not needed to execute and debug the dumped PE, but a human reverse engineer will have difficulties understanding which APIs are being called.

  • 2
    Following up on this, methods 3 and 4 are pretty common. The most advanced technqiues don't use any API functions, but try to find the libraries in memory to parse their export table. Typically a hash function is used to obfuscate the names it is looking for – Nordwald Mar 23 '17 at 13:57
  • @NirIzr Wow, thanks a lot! You've really sorted things out (in addition to Nordwald's excellent answer). – greenpiece Mar 24 '17 at 10:30
3

I think there is something mixed up here.

But how does knowing OEP relate to IAT?

It does not (for benign software). However, the article you linked analyzes a packed executable. Often, malware tries to hide its imports my not using the official IAT, but by creating their own at runtime. The Tools should help you to reconstruction somewhat of a 'normal' IAT.

When application is unpacked in memory, can't we get pointer to IAT just by walking through PE header and getting address of IT - and then of IAT?

Why should the unpacked payload have its own PE header? I've seen a lot of malware and this is very seldomly the case.

Why don't we dump application not at OEP but say on jmp leading to OEP? Or one-two instructions after OEP?

To make sure you got the normal payload. Often analysts try to recrate a PE file for it (by reconstructing the IAT, establishing a header, ..) to make analysis more comfy.

In this article, they try to 'fix' the binary

  • Thank you! Your answer clarifies a lot of things. I missed the fact that IAT of the packed executable is different from the original IAT of the unpacked application. And that code may be modified right after its first instruction in general case (if I got your idea right). It's a pity I can accept only one answer. – greenpiece Mar 24 '17 at 10:30

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.