question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Fix virtual method calls in decompiler (ARM/ARM64)

See original GitHub issue

Hello,

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:open
  • Created 4 years ago
  • Reactions:1
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
astrelskycommented, Mar 7, 2020

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.

/* WARNING: Could not recover jumptable at .... Too many branches */
/* WARNING: Treating indirect jump as call */

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:

  • Right-click on the br x3 instruction
  • Select “Modify Instruction Flow…”
  • Choose “Call Return” instruction flow

This 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++ and aarch64-linux-gnu-g++

Issue1598.tar.gz

0reactions
astrelskycommented, Mar 9, 2020

@astrelsky Great, didn’t know that trick! From my side that answers my question.

I mean, it would be awesome if it’s possible to create a reference (maybe even automatically) in the decompiler but AFAIK that’s not possible at the moment, right?

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 use my_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?

Read more comments on GitHub >

github_iconTop Results From Across the Web

Pure virtual method called - cross compiling - Stack Overflow
A small toy program that has no virtual functions at all causes the same error ("pure virtual function called") when std::thread is created....
Read more >
JEB Change Log - JEB Decompiler by PNF Software
See the latest changes, additions, and fixes that went into JEB. ... for constructor inlining call optimization - Java Rendering: Support for virtual...
Read more >
The Ultimate Disassembly Framework – Capstone – The ...
Welcome. Capstone is a lightweight multi-platform, multi-architecture disassembly framework. Our target is to make Capstone the ultimate disassembly engine ...
Read more >
ARM Compiner c++ error (class, virtual, override) - Keil forum
At this code the methos and constructor calling should to be the next: ... construction for correct overriding virtual class methods.
Read more >
[Mods]Samsung ¬Android Mods Collection ... - XDA Forums
and fix it ... Yes sir,you are correct. ... const-string v0, "face_quick_unlock" const/4 v1, 0x0 invoke-static {v0, v1}, Lcom/android/wubydax/GearUtils ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found