I see many reverse engineering lessons and every second person does reverse engineer using Ghidra decompiler and not disassembler as both are available in the same platform. I assume that reversing using decompiler is easy than disassembler(understanding the assembly of the code). Do I'm thinking right? let's say I'm using Ghidra then when should I see disassembler and when decompiler? Plus If we have now a free decompiler available in Ghidra then the need for a disassembler is gone and there is no need of understanding the assembly when we have a decompiler?
-
4both have their strengths and weakness a disassembler is like learning from kindergarten learning the basics ,having a sound understanding of the alphabets and numerics ,and multiplication tables so that calculus comes off the head , decompiler islike saylearning japanese in a crash course so that you can go by in japan for few months of stay and this is a question that is opinion based please refrain from asking opinion based questions– blabbFeb 3, 2021 at 14:30
-
3Decompilers give you a best guess of what the code does at a high level. In some instances decompilers get it wrong. Malicious binaries may be written to confuse decompilers. Disassemblers show you exactly what the binary does. Often, you'll end up using both and not rely on just the decompiler.– user1720897Feb 13, 2021 at 6:47
-
1Actually I have been misled many times by decompilers and often find myself consulting the disassembly when having a decompiler available. If decompilers worked as well as you seem to think they do it'd be awesome and they would indeed obviate the need for disassemblers. However, in the real world it's a mixed bag which is why oftentimes you have a way to synchronize between both views or can only decompile individual units (like functions).– 0xC0000022L ♦May 27, 2021 at 23:28
4 Answers
Although these terms are being used interchangeably, there is an intrinsic difference between disassembler and decompiler definitions traditionally. Let's first consider common steps involved in converting low level code to high level human readable code. This is similar to compilation where you convert high level code to low level machine code or an executable.
- Syntax analysis + semantic analysis
- Intermediate code
- Control flow recovery
- Control flow and data flow analysis
- Variable recovery and type recovery
- Advance structure recovery, etc.
- High level representation.
Note that these levels differ according to algorithm of the decompiler.
Now historically disassembly and decompilation are used interchangeably. But, now a days the terms are generally used in following context.
- Disassembler: converts low level code to assembly
- Decompiler: Converts low level code to high level representation like C or C++ (mostly C).
In my personal opinion, decompiler involves advance analysis and most importantly type and advance structure recovery for high level and user-readable representation. I'd personally use disassembler for analyses like symbolic analysis, code similarity or maybe something like fuzzing where actual high level representation may not be needed. And I'd prefer decompiler, when I'd like to interpret the underlying code or general working of the program. As program is better conceivable that way.
References
Wang, Shuai, Pei Wang, and Dinghao Wu. "Reassembleable disassembling." 24th {USENIX} Security Symposium ({USENIX} Security 15). 2015.
Andriesse, Dennis, et al. "An in-depth analysis of disassembly on full-scale x86/x64 binaries." 25th {USENIX} Security Symposium ({USENIX} Security 16). 2016.
Wang, Ruoyu, et al. "Ramblr: Making Reassembly Great Again." NDSS. 2017.
"Introduction to Decompilation vs. Disassembly" Hex-Rays SA
It depends on the reverse engineering, most use decompilers to speed up your work, this helps a lot to locate necessary calls, let's say you are at your job and need to quickly find an X algorithm to deliver your work, so if you were to use only one disassembler you would take much more work time analyzing and converting the small assembly instructions and equivalent high level code, decompilers are wonderful they simplify your life, but don't get stuck in that because it's not enough, let's say that in my example I find the algorithm sought with decompilers to obtain the operation closest to the desired one uses the disassembler and compares its analyzed pseudocode with the decompilers, all this to bring the maximum to the original, also depends on the work to be carried out, good studies.
In addition to other answers, my take is that "Reverse Engineering" from executable code means "get the source code from the executable code".
With that definition, if the program being reverse engineered was written in C, we need a C decompiler to effectively reverse engineer it; similarly, if it was written in Java, we need a Java decompiler. If we use a disassembler on the first case, we can understand the logic and deduce the workings of the code, but we have nothing close to the original source code. If we use a bytecodes explorer for Java, we can follow the execution in the JVM, and understand what the code is doing; but very far from the source code again.
The only time a disassembler would do proper reverse engineering for the source code is when the code was originally written in assembly language.
Of course there are other definitions for reverse engineering; if you want to get the APIs called on a mobile app, for example, you don't need the source code; you use a network analyzer and follow the HTTP protocol requests / responses. Then you can implement calls to the service in whatever language you want. Just clarifying that all the purpose of a decompiler is to get the source code back, and that starts from assuming the language the code was written on.
Disassembler: Converts machine code (executable binary) to human readable Assembly code.
Decompiler: Converts machine code (executable binary) to higher level languages such as C/C++.
-
2Hi and welcome to RE.SE. Without wanting to discourage you: how do you think this adds value to the existing answers? The accepted answer even has a very similar wording when defining the terms.– 0xC0000022L ♦May 27, 2021 at 23:24
-
1@0xC0000022L Mainly because the disassemblers and decompilers do not accept "low level code" as input as stated in other answers. It is important to clarify that Low level code in general is still human readable, and at the lowest level (assembly code) is formed by mnemonics. The main purpose of decompilers and disassemblers is to read Hex or binary data (opcodes) from an executable and convert it to low level/high level human readable code.– AlirezaMay 29, 2021 at 1:10