Ghidra, as you should know already, is a disassembler and decompiler for unprofessional folks who can’t cough up a couple thousands dollars and pass background check to buy a disassembler and decompiler the experts use. And here’s a list of things that would make Ghidra
better or much better for me. I know it’s opensource but I’d rather not touch large codebases written in Java (or any codebases written in Java really). Disclaimer: by the time of writing this I’m still using Ghidra
9.2 even if 9.2.2 has been available for months, but I doubt any of the things mentioned here are implemented already.
First of all, there’s a bug with x86 disassembly: while rep movsX
is recognized and works fine, some of the code I’ve seen uses repne movsX
which is treated as simple movsX
even by disassembler. Initially I was confused by this bug and only disassembling instruction bytes with ndisasm
proved that it’s not a compiler (or assembly author) missed a prefix but rather Ghidra
ignoring it entirely. Some other rarely seen instructions that involve FPU operation and an addressing with segment registers (e.g. ES
, FS
or GS
; if you don’t have an idea what those are for—be thankful for that) and explicit offsets are disassembled incorrectly, consuming a byte more than required (and thus making the following instruction to be disassembled incorrectly as well).
And speaking about assembly, current program text search is nice since you can search inside a specific part of an instruction (e.g. MOVSD.REP
in instruction name or 0x800
in its operand) but it would be even better to have a more generic search by a regular expression. Quite often I want to locate a specific instruction doing e.g. shift left by five. The problem is that there are many shift instructions and even more instructions with an operand having 5 somewhere in it. And I don’t know the exact operand register so searching for shl eax, 5
first, then shl ebx, 5
and all the way to shl dh, 5
is tedious. The same can be said about dumping listing and searching there. It will work as intended though.
Beside the issues above and idiosyncratic x86 assembly syntax (it does not bother me much though) I have nothing else to complain in disassembler, so let’s move to the decompiler issues.
I suspect that decompiler output is not stored permanently, but it would be nice to mark some function as being “decompiled, it’s fine, do not touch it, I mean it”. Looks like the process of function being decompiled again and again even if you change something not related to it in any way is annoying not just to me. So it would be nice to mark some large decompiled function as permanently decompiled so it’s not re-decompiled on a subsequent visit to it.
And speaking of functions, it would be nice if functors (aka function pointers) would be supported instead of just detecting that this variable is a pointer to function. When arguments are passed by stack, decompiler usually can detect that. But when arguments are passed in registers you have to trace the registers and their values by hand. Of course you’d need a monstrous syntax to specify a type for e.g. a function that accepts three arguments in designated registers but I can still wish for it, can’t I?
Another thing I often wish for is being able to tell decompiler that after a certain point the variable is no longer valid and it should treat subsequent uses of that register or stack as a new variable. A very common example is when a first argument (usually some context pointer) is moved to a register (or it is passed in a register already), some fields are read from the context, context value is stored to some local variable and the initial register is used for example as a loop variable that gets decompiled to something monstrous like for (ctx = (Context*)0; ctx < (Context*)42; ctx = (Context*)((int)ctx + 1)) { ... }
and it also screws types for variables involved in the same expression as this loop counter.
Of course not all of these things can be easily implemented, and maybe some of them would require architectural changes. But I prefer to cherish my ignorance on Ghidra
internal details and just point out what I’d find good to have in principle.
I use radare2 only.
Not a bad choice.