How does decompiling work?

左心房为你撑大大i 提交于 2019-12-31 12:04:08

问题


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?


回答1:


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).




回答2:


Decompiling is essentially the reverse of compiling. That is - taking the object code (binary) and trying to recreate the source code from it.

Decompilation depends on artefacts being left in the object code which can be used to ascertain the structure of the source code.

With C/C++ there isn't much left to help the decompilation process so it's very difficult. However with Java and C# and other languages which target virtual machines, it can be easier to decompile because the language leaves many more hints within the object code.



来源:https://stackoverflow.com/questions/10311189/how-does-decompiling-work

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!