A native code to C/C++ decompiler
derevenets.com
derevenets.com
void fun_401000() {
}
I'm sure I hit upon some edge case and much better output can be had from this tool if I play with it some more, but for a first impression, not so good. But I'm definitely going to keep this one around, it looks promising.https://www.hex-rays.com/products/ida/index.shtml
The author has implemented a decompiler plugin over the top of IDA and it works on the real-world code. The point here is to annotate the disassembly bottom-up and then decompile.
https://www.hex-rays.com/products/decompiler/index.shtml
I don't want to bash the author of Snowman - this kind of research is serious fun. Yet, IDA has an insane lead.
https://www.hex-rays.com/products/ida/support/download_freew...
I'm not saying you should buy IDA, just that I think IDA is severely mispriced.
My stance is that the tool is very specialized, unique and the cost is reasonable for professional usecases.
IDA's price is so low that it actually harms the market for professional reverse engineering tools. Most useful products you can build --- tracers, visualizers, emulators, pattern matchers, debuggers --- fit into IDA's orbit. As products, as "feature/function/benefit" statements, they are subsets of IDA. But they're chained down by IDA's price. Just like IDA, they have to serve a small market of users who make tens of thousands of dollars per week using the tools, but the market optics make it hard to charge even a significant fraction of the (low) total cost of IDA.
It's sort of hilarious to me to see what Hopper is doing to the market. "Ruining it entirely" wouldn't be far from the truth. I'm only sort of complaining. Viscerally, I'm thrilled that Hopper exists.
AV jobs pay shit.
That's for projects denominated in billable days. Talented specialists do even better, on fixed-price projects for specific targets. Rates get higher for cryptographic work, as well.
I am not talking about selling vulnerabilities. I have never sold a vulnerability to anyone, nor have I (to my knowledge) done any software security work for any division of the USG or any other government, nor would I.
Don't work in AV. There are worse things about AV than the pay scale.
The only other one I remember is Sourcer (sr) for MS-DOS.
For example, the Itanium C++ ABI (http://mentorembedded.github.io/cxx-abi/, perhaps Itanium's only real legacy) adopted by Linux/ELF and other platforms, leaves a huge amount of fingerprints on a binary. It'd take a very conscious effort, including hand-crafting linker scripts, to generate a C binary that a tool would incorrectly think was C++.
Back in the 90's there was one targeted specifically to executables produced by Borland compilers.
Once you get some C code that does things with structures and function pointers like a C++ compiler would do, I think it's not impossible to turn those back into classes if you can recognise the patterns that a C++ compiler uses to compile C++ constructs like classes, virtual functions, etc.
I'm afraid that hasn't been true for a number of years. Turn on the optimizer and the resulting assembly can be totally unrecognizable as a translation of what you actually wrote. The compiler takes all kinds of steps both to eliminate redundant operations (via CSE, loop unrolling, etc.) and to take advantage of the weird quirks of modern CPU architectures, like out-of-order execution.
printf(...);
for (...) {...}
The printf never executed. So I fired up gdb and confirmed the segfault was happening where I thought it was, but the for loop was being initialized before the printf. Even with debugging on and optimization off. Could be a bug in clang (I didn't think to try it with gcc), but even so it shows that the way things should work in theory don't necessarily dictate the way they do work in practice. class data fields -> structure members
non-static methods (ctors/dtors included) -> functions with an extra 'this' pointer parameter
inheritance -> extended structures with matching prefices
virtual functions -> structure with function pointers
operator overloading -> methods with special names
default arguments -> automatically inserted by compiler
function overloading -> types encoded in name of function
templates -> whatever code they generate
exceptions -> special library functions are used, e.g. _CxxThrowException()
Some of those don't decompile so well (e.g. template-generated code, although a refactoring tool might be of help), and things like operators and overloaded functions are probably more of a stylistic choice than a difference in the generated code, but for the most part it doesn't look impossible to get some C++ features to show up in decompiled code. (And given that many of the C++-level optimisations revolve around removing unnecessary code, they could make the C to C++ step even easier.)The decompiler could do with a bit of work making dynamic library imports more symbolic. Following the puts call chain quickly disappears into a non-local jump to an address with no further references.
[EDIT: Very informative replies below, thanks!]
You can also see that GCC did strength reduction of printf("thing\n") to puts("thing").
It won't, for me, recompile back into the source application. So that is a limitation, but even with that limitation it is extremely useful (and the fact it looks the C/C++ back to the ASM, makes altering the ASM directly trivial).
Targeting something like Clang specifically, where you have access not only to the assembler & a potential source, but also a whole AST & intermediate data structures, would be pretty interesting.
if (__JCR_END__ == 0 || 1) { return;
That said, I still don't know how you could get this code generated. If you make an equivalent piece of code with _JCR_END__ as a volatile int, you still get an infinite loop which has the mov op for reading the _JCR_END__ value but it doesn't bother to test it. IE. gcc still reads the variable but optimizes the loop to a while (1). I can't think of anyway to trick gcc into generating asm like this.
I question whether you can get any real use out of this...
Just the fact of giving symbolic names to memory addresses and replacing Assembly opcodes by more meaningful instructions can make wonders trying to understand some code.
Or try and fix up Boomerang on other OSes, I suppose.
I guess also historically most of the tools for creating, modifying, and examining binaries for a given platform have been native to that platform, rather than cross tools. That's surely because most people (with the exception of embedded developers) do much more native development than cross development. I can get a small number of packages on my Linux machine that will deal with Windows executables in some relatively shallow way, but I have tons of programs already installed that do complicated and specific things to Linux ELF binaries even though I don't typically use those programs on a day-to-day basis.