Fix virtual method calls in decompiler (ARM/ARM64)
See original GitHub issueHello,
I have a minor problem with the decompiler and virtual methods; and I’m wondering if a solution exists:
Let’s say I have a function call (I’ll use pseudo-C++, I hope I reversed it correctly):
foo(my_class, param)
Let’s assume for the example that param
is an long
. This translates to something like
mov x0, my_class
mov x1, param
bl foo
my_class
has a member my_other_class
. foo()
will do nothing than call a virtual method bar()
of my_other_class
with the same parameter in a thisclass-fashion:
myclass::foo(param)
{
foo.my_other_class_obj::bar(param)
}
The binary I have at the moment, has the following ARM assembly to present that:
ldr x0,[x0, #0x8]
ldr x2,[x0]
ldr x3,[x2, #0x16]
br x3
I already managed to get the following representation in the decompiler defining a struct for my_class
and one for the vtable of my_other_class
with func *
entries:
void foo(my_class * this, long param)
{
/* WARNING: Could not recover jumptable at 0x12345678. Too many branches
*/
/* WARNING: Treating indirect jump as call */
(*this->my_other_class_obj->vtable->bar)*();
}
It clearly lacks the this
(x0) and the param
(x1) parameter, though.
I would assume it is somehow possible to tell the decompiler that a call happens and to override the signature afterwards. But at the moment I’m not able to do that.
Is this somehow possible?
Moreover, it would be great if I can teach the decompiler to put a reference to the function there. But AFAIK that’s not possible? I only know that I could give the br
a COMPUTED_CALL
reference…
Issue Analytics
- State:
- Created 4 years ago
- Reactions:1
- Comments:5 (3 by maintainers)
I was able to replicate this and it appears to occur for all processors not just ARM/AARCH64. The root cause appears to be that the indirect jumps are not being considered for shared return analysis.
The second warning says that it is considering it as a call and not a call return. However, the decompiler still determined the
br x3
as the instruction causing the return for some reason.You can circumvent this issue by performing the following:
br x3
instructionThis may be replicated with the attached main.cpp and Makefile. Any version of g++v3 > for any architecture can be used but the Makefile is using
arm-linux-gnueabi-g++
andaarch64-linux-gnu-g++
Issue1598.tar.gz
I don’t think it’s a good idea to create a reference here due to the nature of virtual calls. The function being called may not always be
my_other_class_obj::bar
. I would instead recommend to set a comment in the listing of all potential functions that could be called. If you insist on setting a reference, maybe usemy_other_class_obj::bar
as the primary and then all other potential functions would be secondary references?@GhidorahRex I’m not sure that the “hiding” of the function parameters due to the missing return flow is intended behavior. Should this be considered a bug?