5

Apologies if this is a duplicate. Don't know what words to search for as that's what the question is about.

I'm relatively new to reverse engineering binaries and while using Ghidra I've noticed that it frequently decompiles the binary to produce functions along these lines:

void FUN_803adb50(void)
{
  int in_r11;
  undefined4 unaff_r26;
  undefined4 unaff_r27;
  undefined4 unaff_r28;
  undefined4 unaff_r29;
  undefined4 unaff_r30;
  undefined4 unaff_r31;
  
  *(undefined4 *)(in_r11 + -0x18) = unaff_r26;
  *(undefined4 *)(in_r11 + -0x14) = unaff_r27;
  *(undefined4 *)(in_r11 + -0x10) = unaff_r28;
  *(undefined4 *)(in_r11 + -0xc) = unaff_r29;
  *(undefined4 *)(in_r11 + -8) = unaff_r30;
  *(undefined4 *)(in_r11 + -4) = unaff_r31;
  return;
}

Which is created from the following disassembly:


                     *                          FUNCTION                          *
                     **************************************************************
                     void __stdcall FUN_803adb50(void)
                       assume GQR0 = 0x0
                       assume GQR1 = 0x0
                       assume GQR2 = 0x40004
                       assume GQR3 = 0x50005
                       assume GQR4 = 0x60006
                       assume GQR5 = 0x70007
                       assume GQR6 = 0x0
                       assume GQR7 = 0x0
                       assume r13 = 0x805dd0e0
                       assume r2 = 0x805e6700
     void              <VOID>         <RETURN>
                     FUN_803adb50
803adb50 93 4b ff e8     stw        r26,-0x18(r11)
                     **************************************************************
                     *                          FUNCTION                          *
                     **************************************************************
                     undefined GetVCTypeSomething()
                       assume GQR0 = 0x0
                       assume GQR1 = 0x0
                       assume GQR2 = 0x40004
                       assume GQR3 = 0x50005
                       assume GQR4 = 0x60006
                       assume GQR5 = 0x70007
                       assume GQR6 = 0x0
                       assume GQR7 = 0x0
                       assume r13 = 0x805dd0e0
                       assume r2 = 0x805e6700
     undefined         r3:1           <RETURN>
                     GetVCTypeSomething
803adb54 93 6b ff ec     stw        r27,-0x14(r11)
803adb58 93 8b ff f0     stw        r28,-0x10(r11)
803adb5c 93 ab ff f4     stw        r29,-0xc(r11)
803adb60 93 cb ff f8     stw        r30,-0x8(r11)
803adb64 93 eb ff fc     stw        r31,-0x4(r11)
803adb68 4e 80 00 20     blr

It happens frequently enough that it must be some kind of common pattern, always with many variables of an undefined type with the "unaff_" prefix which are assigned to an equal number of variables with the "in_" prefix. They also commonly appear at the beginning of the caller functions. My instinct is that it's something related to a class structure (I'm unsure of whether or not the original binary was C or C++) but given that I've had no luck with my searches, I figured I'd ask here.

What (if any) is the common code pattern that would produce such decompiled code?

Bonus points if there's a way to edit the function definition to produce something more legible.

10
  • 4
    Please share the disassembly that created this decompiled code Jun 23, 2020 at 7:38
  • @macro_controller What's the best way of doing that? Editing my question or using an external site such as pastebin?
    – That Guy
    Jun 24, 2020 at 2:16
  • 2
    edit your question Jun 24, 2020 at 7:27
  • 1
    can you add more disassembly lines (until the return instruction)? Please use text (code blocks) instead of pictures if possible. You can remove the xref comments, they're unimportant here and only take up space.
    – Igor Skochinsky
    Jun 25, 2020 at 11:55
  • 1
    @IgorSkochinsky Updated to use text (instead of a picture) and now includes more lines.
    – That Guy
    Jun 26, 2020 at 17:21

2 Answers 2

1

This is a helper function used by PPC EABI conforming compilers for reducing code size. From ctrsavres.asm:

/* Routines for saving integer registers, called by the compiler.  */
/* Called with r11 pointing to the stack header word of the caller of the */
/* function, just beyond the end of the integer save area.  */

Because it is called by the compiler, it doesn't behave like normal a function and accesses r11 directly, without setting it up first (it is set up by the caller).

1
  • Interesting. Are there any settings to display this more... gracefully? Seems a little weird to see it all over, but perhaps that's just to be expected.
    – That Guy
    Jul 7, 2020 at 1:12
3

Regarding unaff_ and in_ prefixes (source):

in or unaff : this typically indicates that a register is read before it is written (and it does not contain a parameter passed to the function)

So, if you encounter them in decompilator, it means that their values are used before they are initialised in the function (they contain the values assigned earlier, in one of the previous functions). To fix that, you can add these registers as arguments to this function (right click -> edit function signature). You can see more details here and here.

As for the pattern you are asking for, the r11 register in ARM (I suppose this is the architecture of your binary) is used for accessing local function variables placed on the stack. So, it seems that your function (probably 6 - argument constructor) initialises some class (having 6 members), which was a type of some local variable (declared in caller function) in the original code.

3
  • Ah excellent. That sounds correct. I believe the architecture of this binary is PowerPC though. Not sure what similarities/differences it has.
    – That Guy
    Jun 24, 2020 at 1:55
  • I see. So at least the first part of my answer is valid. Disassembly should clarify it.
    – bart1e
    Jun 24, 2020 at 6:15
  • 1
    Edited to show disassembly
    – That Guy
    Jun 24, 2020 at 23:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.