1

Here is my question:

given a marked C code component, how I can find its corresponding assembly instructions in the compiler produced assembly program?

It should be very easy if the marked component is a function, as long as there is no overlapped assembly program, we can just do a linear search and recognize the function in the compiler-produced code.

Then how about the marked component is a loop statement? Or even an arithmetic statement? Is there any good solution at this time?

Could anyone give me some help? Thank you!

2

TL;DR: Hope for some magic numbers, or string constants you can xref, or you're in for a lot of manual work.

Searching for an arithmetic statement that doesn't include a very specific magic number, or searching for a loop without any surrounding context, is bound to fail. There's just too much code that's way too similar in your program. So you should at least try to find your function, then match the disassembled function to your source code.

But, you should clarify your use case a bit. What do you have? And what are you looking for?

For example, if you have full source code, compile your program with debugging information, and you have everything you need. But this isn't a question for RE.

Or, you have full source code, have delivered a binary to a customer, and for some reason, want the customer to patch the binary instead of sending a new version to them. In this case, recompiling the same version of your program with the same compiler settings should yield some binary code that, except global variable references and jump destinations, should be the same as your delivered binary had. Comparing partial byte sequences should do the trick, and this is more or less how IDA's FLIRT and many antivirus programs work. Still not a question for RE though.

Or, you have a binary, and suspect it includes some open source library. Comparing the binary with the version of the library you compiled yourself will probably not help you, because unless you use the exact same version of library, compiler version, compiler flags, and probably phase of the moon, your compiler won't produce what the original compiler produced. In this case, magic numbers, or string xrefs, are sometimes helpful. For example, in this question, the OP is looking for which part of the library does some TEA encryption. In his case it's easy as he has a .so with exported symbols, but if he didn't, searching for byte sequences 0x9e3779b9 and/or 0xC6EF3720 could help. This is what binwalk does. Also, those libraries often have error message strings, finding them and their xrefs leads you to the compiled version of the function. If you're lucky, the source code has some assert()-like macros that didn't get commented out during release compile, in that case you get a very nice match between source code and binary.

If this doesn't work, things start getting hairy. Once when i had a similar problem, i ended up writing an IDA script that counted the number of call statements per function, and the number of jumps backwards, i.e. loops. I ran this over the binary i wanted to re, and also over the code i was looking for. Then, i manually matched functions to each other based on the number of calls they had, the number of loops, and their respective position in the source code. You can probably try to be clever and automate the matching, depending on how often you need this.

If the compiler optimized a lot, you really need to analyze a lot of stuff manually. If your function is small, it might get inlined by the compiler, and suddenly the arithmetic expression you're looking for is repeated in dozens of places. Your loop might get unrolled so there's no loop left to find.

And the creator of the software might have modified the original source so you can't match it to the binary any more. I reversed some software a year ago that gets some encrypted HTML from somewhere and renders it to a bitmap. From the strings within the binary, it was easy to determine that the software uses the dillo code to do the rendering. But i just wasn't able to match the binary code to the source - first, because i didn't know which version of dillo got used, and second, because they modified the code to decrypt just as much as needed on the fly, and overwrite the decrypted HTML with junk as soon as they didn't need it anymore. So every character comparison and each of the standard string function calls was (probably) replaced in the source, then the replacements got inlined (or were macros in the first place). This trashed my loop counts, subroutine call counts, and everything - i don't think there's any good, automated way through this kind of mess.

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.