Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does decompiling work?

Tags:

I have heard the term "decompiling" used a few times before, and I am starting to get very curious about how it works.

I have a very general idea of how it works; reverse engineering an application to see what functions it uses, but I don't know much beyond that.

I have also heard the term "disassembler", what is the difference between a disassembler and a decompiler?

So to sum up my question(s): What exactly is involved in the process of decompiling something? How is it usually done? How complicated/easy of a processes is it? can it produce the exact code? And what is the difference between a decompiler, and a disassembler?

like image 967
Ephraim Avatar asked Apr 25 '12 07:04

Ephraim


People also ask

Is decompiling code possible?

It is impossible use decompilation for original source code reproduction because original code identifiers, such as variable and function names, are rarely stored in computer code. However, code containing metadata or debugging information may include identifiers.

What is a decompiler used for?

A decompiler is a programming tool that converts an executable program or low-level/machine language into a format understandable to software programmers. It performs theoperations of a compiler, which translates source code into an executable format, but in reverse.

Are decompilers accurate?

Short answer: 99% of the time, decompiled code will not look like the original code, but it should behave the same way. So, assuming the decompiler doesn't make any mistakes, it should be accurate in function, but not in implementation.

Is decompiler legal?

Decompiling is absolutely LEGAL, regardless of what the shills say. At most, you can be sued for unauthorized activity relating to software unless you're redistributing it.


1 Answers

Ilfak Guilfanov, the author of Hex-Rays Decompiler, gave a speech about the internal working of his decompiler at some con, and here is the white paper and a presentation. This describes a nice overview in what are all the difficulties in building a decompiler and how to make it all work.

Apart from that, there are some quite old papers, e.g. the classical PhD thesis of Cristina Cifuentes.

As for the complexity, all the "decompiling" stuff depends on the language and runtime of the binary. For example decompiling .NET and Java is considered "done", as there are available free decompilers, that have a very high succeed ratio (they produce the original source). But that is caused by the very specific nature of the virtual machines that these runtimes use.

As for truly compiled languages, like C, C++, Obj-C, Delphi, Pascal, ... the task get much more complicated. Read the above papers for details.

what is the difference between a disassembler and a decompiler?

When you have a binary program (executable, DLL library, ...), it consists of processor instructions. The language of these instructions is called assembly (or assembler). In a binary, these instructions are binary encoded, so that the processor can directly execute them. A disassembler takes this binary code and translates it into a text representation. This translation is usually 1-to-1, meaning one instruction is shown as one line of text. This task is complex, but straightforward, the program just needs to know all the different instructions and how they are represented in a binary.

On the other hand, a decompiler does a much harder task. It takes either the binary code or the disassembler output (which is basically the same, because it's 1-to-1) and produces high-level code. Let me show you an example. Say we have this C function:

int twotimes(int a) {     return a * 2; } 

When you compile it, the compiler first generates an assembly file for that function, it might look something like this:

_twotimes:     SHL EAX, 1     RET 

(the first line is just a label and not a real instruction, SHL does a shift-left operation, which does a quick multiply by two, RET means that the function is done). In the result binary, it looks like this:

08 6A CF 45 37 1A 

(I made that up, not real binary instructions). Now you know, that a disassembler takes you from the binary form to the assembly form. A decompiler takes you from the assembly form to the C code (or some other higher-level language).

like image 171
kuba Avatar answered Oct 04 '22 23:10

kuba