Skip to content

PowerPC SVR4 64bit parameters read from wrong registers #8057

@nshp

Description

@nshp

Version and Platform (required):

  • Binary Ninja Version: 5.3.9369-dev (f52453d9)

Bug Description:
64bit register parameters in PPC SVR4 are "aligned" in terms of their offset from arg1/r3. Binja doesn't know that. That is, a function like:

int math2(int a, unsigned long long b)

Will take a in r3, skip r4, and take b in r5:r6.

Steps To Reproduce:
Dumb repro source:

int
blackhole(char c)
{
    *(volatile char *)0x41414140 = c;
    return (*(volatile int *)0x42424240);
}

int
math2(int a, unsigned long long b)
{
    blackhole(a >> 24);
    blackhole(a >> 16);
    blackhole(a >> 8); 
    blackhole(a);
    for (unsigned i=0;i < 8;i++) {
        blackhole(b >> (8 * (i % 8)));
    }   
    return (0);
}

unsigned long long
math(unsigned long long a)
{
    return ((a << 3) | (a >> 61));
}

void _start(void)
{
    unsigned long long foo;

    foo = math(0x0102030405060708ULL);

    blackhole(math(0x1121314151617181ULL));

    math2(0xcafebeef, foo);

    return;
}

Build: powerpc-none-eabi-gcc test.c -o test

Binary: polygonal entropy splits intuitively

HLIL in _start:

01800424        r3, r4 = math(0x1020304, 0x5060708)
01800440        int32_t r4_1 = math(0x11213141, 0x51617181)
01800454        blackhole(r4_1.b & 0xff)
01800468        math2(0xcafebeef, r4_1, r3, r4)

The extra r4_1 argument to math2 is incorrect. Not catastrophic here in this tiny case, but in my real binaries, printf calls with %llus sprinkled in get super messed up and confusing.

Of course this should also be concatenating the upper/lower halves back together in theory, but I imagine that's a separate, larger issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions