rizinorg / rizin

UNIX-like reverse engineering framework and command-line toolset.
https://rizin.re
GNU Lesser General Public License v3.0
2.66k stars 357 forks source link

mips function call represented as **(code **) #1812

Open ctlayon opened 2 years ago

ctlayon commented 2 years ago

Work environment

Questions Answers
OS/arch/bits (mandatory) Linux 5.14.10-arch1-1 x86_64 GNU/Linux
File format of the file you reverse (mandatory) ELF
Architecture/bits of the file (mandatory) mips32r2
rizin -v full output, not truncated (mandatory) rizin 0.3.0-git @ linux-x86-64

commit: b80cadf7564bc5271abf6a8f01f95f94ea48400d, build: 2021-10-11__12:24:46

Expected behavior

I expect when rz-ghidra decompiles a jalr instruction it should be recognized as a function call similar to a bal or jal (testing suggests these are being decompiled correctly).

Actual behavior

rizin appears to type the jalr as (code ) which results in a wonky display and removes the function call context.

Steps to reproduce the behavior

I've attached a dummy binary test_mips32r2.zip that demonstrates both the good function call display via jal and a bad function call display via jalr. Screenshot: image

// mipsel-linux-gnu-gcc main.c test_mips32r2  

#include <stdio.h>

void dummy() {
    printf("RZ-GHIDRA dummy bal function call\n");

}

int main()
{
    printf("RZ-GHIDRA dummy jalr function call\n");
    dummy();
    return 0;
}
XVilka commented 1 year ago

Still happens:

[0x00400590]> pdf @ main
            ; UNKNOWN XREF from section..dynsym @ +0x64
            ; DATA XREF from entry0 @ 0x4005a8
╭ int main (int argc, char **argv, char **envp);
│           ; arg int argc @ a0
│           ; var int32_t var_10h @ stack - 0x10
│           ; var int32_t var_8h @ stack - 0x8
│           ; var int32_t var_4h @ stack - 0x4
│           0x00400784      addiu sp, sp, -0x20
│           0x00400788      sw    ra, (var_4h)
│           0x0040078c      sw    fp, (var_8h)
│           0x00400790      move  fp, sp
│           0x00400794      lui   gp, 0x42                             ; 'B'
│           0x00400798      addiu gp, gp, -0x6ff0
│           0x0040079c      sw    gp, (var_10h)
│           0x004007a0      lui   v0, 0x40                             ; '@'
│           0x004007a4      addiu a0, v0, 0x9b4                        ; 0x4009b4 ; "RZ-GHIDRA dummy jalr function call" ; int32_t arg1 ; str.RZ_GHIDRA_dummy_jalr_function_call
│           0x004007a8      lw    v0, -sym._MIPS_STUBS(gp)             ; [data.00411058:4]=0x400900 sym.imp.puts
│           0x004007ac      move  t9, v0
│           0x004007b0      jalr  t9
│           0x004007b4      nop
│           0x004007b8      lw    gp, (var_10h)
│           0x004007bc      jal   sym.dummy                            ; sym.dummy
│           0x004007c0      nop
│           0x004007c4      lw    gp, (var_10h)
│           0x004007c8      move  v0, zero
│           0x004007cc      move  sp, fp
│           0x004007d0      lw    ra, (var_4h)
│           0x004007d4      lw    fp, (var_8h)
│           0x004007d8      addiu sp, sp, 0x20
│           0x004007dc      jr    ra
╰           0x004007e0      nop
[0x00400590]> pdg @ main

// WARNING: Variable defined which should be unmapped: var_8h
// WARNING: Variable defined which should be unmapped: var_4h
// WARNING: Unknown calling convention yet parameter storage is locked
// WARNING: [rz-ghidra] Matching calling convention n32 of function main failed, args may be inaccurate.
// WARNING: [rz-ghidra] Matching calling convention n32 of function sym.dummy failed, args may be inaccurate.

undefined4 main(int argc)
{
    int arg1;
    int32_t var_10h;
    int32_t var_8h;
    int32_t var_4h;

    // str.RZ_GHIDRA_dummy_jalr_function_call
    arg1 = 0x4009b4;
    (*_data.00411058)();
    sym.dummy(arg1);
    return 0;
}
[0x00400590]> pdg @ sym.dummy

// WARNING: Variable defined which should be unmapped: var_8h
// WARNING: Variable defined which should be unmapped: var_4h
// WARNING: Unknown calling convention yet parameter storage is locked
// WARNING: [rz-ghidra] Matching calling convention n32 of function sym.dummy failed, args may be inaccurate.

void sym.dummy(int arg1)
{
    int32_t var_10h;
    int32_t var_8h;
    int32_t var_4h;

    // str.RZ_GHIDRA_dummy_bal_function_call
    (*_data.00411058)(0x400990);
    return;
}
[0x00400590]>