4

Do disassemblers detect the use of C/C++ standard functions and specify them in the output code, adding the #include line to the appropriate header file (such as stdio.h or even windows.h)?

If not, does the whole big library is being recognized as the developer's own business-logic code, and written fully? Aren't the standard libraries known binary sequences (or can be processed some way to be known, as a binary-code can be different because of addressing)?

Do you know disassemblers that do detect standard functions and properly #include them in the output?

1
  • #include sounds like you are expecting C output. Most disassemblers output assembler code. Also: "standard" libraries, well, there are lots of standards. IDA Pro (as mentioned in an answer below) recognizes lots of standard libraries -- but most likely not "all".
    – Jongware
    Nov 16 '13 at 21:07
2

IDA Pro will do such things thanks to its FLIRT feature. You can take a look here to get more information : What is a FLIRT signature?

1
  • Note also that you can create your own FLIRT signatures using the FLAIR tools available on the Hex-Rays download page (requires a login/password that is provided in the email you receive when you purchase a license). So if your definition of "standard library" differs from IDA's, you have options. Nov 16 '13 at 23:13
9

One thing that's important to realize is that standard runtimes are commonly treated as any other code or library. How compiled code is linked and loaded depends a lot on the platform. .net is very different from c++.

Basically functions have at least three major ways of showing up inside of your binary:

Dynamically linked

This when a function is kept inside of a dynamically loaded library and is the case for many of the functions you'd get through windows.h as you said. Identifying these are generally easy as they're functionally separated and named either through their string name, decorated or undecorated, or through ordinal. Most disassemblers should handle dynamically linked standard functions without issues. This is the most common default for various compiler, runtime and platform options. This depends on the compiler being able to move the function to a separate compilation unit, which is commonly not the case with many templates in C++. Calling conventions are respected and prologue and epilogue are present.

Statically linked and not inlined

This is when a function is included inside of your binary but is functionally separate from other functions. This can be identified using a set of signatures of some form. IDA uses FLIRT signatures. Something like bindiff uses a more varied and complex approach to comparing functions, for instance using flow graph analysis. Usually parameters are passed according to calling convention unless the binary is built with link time optimization in which case the compiler is free to pass arguments in any order it feels like. If you're lucky the binary contains debug information which could allow for significant recovery of function names and parameters.

Statically linked and inlined

This is when a function is included inside of your binary and is not functionally separate from other functions. This generally happens when a function is small enough that the overhead to do a function call is expensive enough to warrant repeating the same function in the calling function or if the function is only called in very few locations, usually once, in the binary. This means that the disassembler has very little information to know that this was originally a separate function and debug information will not help much with recovery of these functions. There will be no function prologue or epilogue. Opcodes can be heavily rearranged/ The only tool I'm aware of that does very limited recovery of this sort of function is Hex-Rays decompiler, not diassembler. I've seen binaries with link time optimization where a function ends up being a massive result of hundreds of nested inlined functions, resulting in a function with thousands of branches. Separating them back out into their original functions would have been a very useful operation to have.

Finally

There is no solution that solves all the cases mentioned above. Hex-Rays IDA combined with their decompiler and BinDiff probably provides the most complete solution I know of. On very reflective platforms such as .net, java or python this isn't much of an issue.

2
  • Do you mean combining IDA decompiler and BinDiff? Or do you mean either IDA+decompiler or BinDiff? How would you use BinDiff to detect a library? May 31 '16 at 12:05
  • You first detect the fact that they've used a lib. The you build the lib yourself using as close as possible compiler settings. Then you bindiff the binary against the library you just built. In my experience this can help a lot. This is of course for static linking with no symbols. May 31 '16 at 12:07

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.