When doing Static code analysis on a disassembled app, I usually end up seeing many calls to registers (CALL EAX for example), which is constructed in runtime, which leaves me clueless on how to decide/figure out what does the code do when the call is done.

I was wondering how do you guys go through this in extreme cases where dynamic analysis might not be an option.


Last year, I released an IDB for a piece of large, complex malware written in C++, which made regular use of virtual functions, which produce patterns of indirect call instructions like the ones your question discusses. I conducted that analysis purely statically, and I may release more IDBs like it later this year that were also done via static analysis.

The short answer to your question is that you need to figure out where the indirect calls will resolve at runtime. C++ VTables make this process especially simple. If you can figure out the base type that is being used at the site of the indirect call, then according to the rules of the C++ type system, any class derived from that base type might legally be substituted for that base type at runtime. In other words:

  1. Reconstruct the inheritance hierarchy for the program under analysis.
  2. For each class with a VTable, determine the address of its corresponding VTable.
  3. While analyzing the program, determine the reach of the types used in the program.
  4. At the call site of any given indirect call, combine all of the above information to determine the set of types that might be used, the addresses of the VTables for those types, and consequently the set of destinations for the indirect call.

I had a bad practice in a similar case 10 years ago (that's an obfuscated code of malware that I could not use debugger to analyze) and I tried to write a simple CPU emulator to run that code (because that time I didn't get a working opensource code or library so I decided a simple one).

Now we have some CPU emulator engine/framework (unicorn engine,...) so you could try in a similar easier way :) or if the code is "simple", you can dump & try to debug it like debug the shellcode.

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.