Skip to content

Comparison with stack pointer results in register0x00000004 instead of unaff_r1 or similar #3771

@Pokechu22

Description

@Pokechu22

Describe the bug
The following code sample that uses addic. to perform a null check on the stack pointer decompiles weirdly.

To Reproduce
Steps to reproduce the behavior:

  1. Download and extract addic.zip.
  2. Import addic.bin. Use 32-bit powerpc (default variant and compiler) as the language.
  3. Open the imported file, and allow analysis to happen.
  4. Look at the decompile window.

Expected behavior

I would expect something like this to show up:

void FUN_00000000(int param_1,uint param_2)
{
  short local_6;
  
  if (unaff_r1 != (undefined *)-6) {
    local_6 = *(short *)(param_1 + 4);
  }
  if ((ushort)(local_6 - 1) < param_2) {
    param_2 = (uint)(ushort)(local_6 - 1);
  }
  func_0x00010000(param_1,param_2);
  return;
}

Alternatively, I would expect this (since normally, it's impossible for the stack pointer to be null), though it probably doesn't make sense to hide details like this when analyzing malicious code (instead of code that's just jank/broken).

void FUN_00000000(int param_1,uint param_2)
{
  short local_6 = *(short *)(param_1 + 4);

  if ((ushort)(local_6 - 1) < param_2) {
    param_2 = (uint)(ushort)(local_6 - 1);
  }
  func_0x00010000(param_1,param_2);
  return;
}

Actual behavior

The following shows up:

void FUN_00000000(int param_1,uint param_2)
{
  short local_6;
  
  if ((undefined *)register0x00000004 != (undefined *)0x6) {
    local_6 = *(short *)(param_1 + 4);
  }
  if ((ushort)(local_6 - 1) < param_2) {
    param_2 = (uint)(ushort)(local_6 - 1);
  }
  func_0x00010000(param_1,param_2);
  return;
}

Attachments
addic.zip

Environment (please complete the following information):

  • OS: Windows 10
  • Java Version: 16.0.1
  • Ghidra Version: 10.1
  • Ghidra Origin: official ghidra-sre.org distro

Additional context
Here's the disassembly:

                             //
                             // ram 
                             // ram:00000000-ram:0000004f
                             //
                             **************************************************************
                             *                                                            *
                             *  FUNCTION                                                  *
                             **************************************************************
                             undefined FUN_00000000()
             undefined         r3:1           <RETURN>
             undefined4        Stack[0x4]:4   local_res4                              XREF[2]:     0000000c(W), 
                                                                                                   00000040(R)  
             undefined2        Stack[-0x6]:2  local_6                                 XREF[3]:     0000001c(W), 
                                                                                                   00000020(R), 
                                                                                                   00000030(W)  
             undefined4        Stack[-0x10]:4 local_10                                XREF[1]:     00000000(W)  
                             FUN_00000000
        00000000 94 21 ff f0     stwu       r1,local_10(r1)
        00000004 7c 08 02 a6     mfspr      r0,LR
        00000008 7c aa 2b 78     or         r10,r5,r5
        0000000c 90 01 00 14     stw        r0,local_res4(r1)
        00000010 34 01 00 0a     addic.     r0,r1,0xa
        00000014 41 82 00 0c     beq        LAB_00000020
        00000018 a0 03 00 04     lhz        r0,0x4(r3)
        0000001c b0 01 00 0a     sth        r0,local_6(r1)
                             LAB_00000020                                    XREF[1]:     00000014(j)  
        00000020 a1 01 00 0a     lhz        r8,local_6(r1)
        00000024 39 08 ff ff     subi       r8,r8,0x1
        00000028 55 09 04 3e     rlwinm     r9,r8,0x0,0x10,0x1f
        0000002c 7c 04 48 40     cmplw      r4,r9
        00000030 b1 01 00 0a     sth        r8,local_6(r1)
        00000034 40 81 00 08     ble        LAB_0000003c
        00000038 7d 24 4b 78     or         r4,r9,r9
                             LAB_0000003c                                    XREF[1]:     00000034(j)  
        0000003c 48 00 ff c5     bl         SUB_00010000
        00000040 80 01 00 14     lwz        r0,local_res4(r1)
        00000044 7c 08 03 a6     mtspr      LR,r0
        00000048 38 21 00 10     addi       r1,r1,0x10
        0000004c 4e 80 00 20     blr

This was simplified from a more complex function, but the original function was definitely using addic. with r1 (the stack pointer) and skipping over dereferencing it if the address would be null. I don't know why it was doing that, as if the stack pointer were null other bad things would happen (including earlier code breaking). But getting register0x00000004 in the output seems odd.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions