-
Notifications
You must be signed in to change notification settings - Fork 7.3k
Description
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:
- Download and extract addic.zip.
- Import addic.bin. Use 32-bit powerpc (default variant and compiler) as the language.
- Open the imported file, and allow analysis to happen.
- 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.