Demystifying LOWORD macro pseudocode into valid C

1

From IDA decompilation of a subroutine into C pseudocode, I encountered this line of code:

LOWORD(v9) = *(BYTE *)v6);

Where v9, v6 are 32-bit integers.

LOWORD is a macro defined in windef.h as follows:

#define LOWORD(l) ((WORD)(((DWORD_PTR)(l)) & 0xffff))

Obviously it's a macro, so I can't assign things to it. I am interested an implementation which would be valid C, but I am unsure of the decompiler's intent here. From my guess, the intent is to dereference the LOWORD of v9, and assign the byte value pointed by v6, but I would like to make sure.

In the event that it may be necessary, here is the context of the pseudocode. All types are 32-bit integers:

if (*(BYTE *)v6) {
    LOWORD(v9) = *(BYTE *)v6);
    do {
        v7 = v7 & 0xFFFF0000 | (unsigned __int16)(v7 + v9);
        v9 = *++v8;
        if (*v8) {
            v7 = (unsigned __int16)v7 | ((*v8++ + (v7 >> 16)) << 16);
            v9 = *v8;
        }
    } while (v9);
}
c
windows
pseudocode
decompiling
ida
asked on Stack Overflow Feb 27, 2021 by daedsidog

1 Answer

1

The windef.h macro you show is not the one being used by IDA, since as you noticed you cannot use the result of such a macro as an lvalue.

From my guess, the intent is to dereference the LOWORD of v9, and assign the byte value pointed by v6

Not quite. The intent is to replace the low word (that is the lower 2 bytes) of the variable v9 (which is an int) with the right hand side.

So in IDA, this:

LOWORD(a) = b;

Can be seen as this:

a = (a & 0xffff0000) | b;

The way to write such a macro in C would be something like:

#define LOWORD(x) (*((uint16_t*)&(x)))

Which is a possibly more convoluted, yet more versatile way of doing the same thing, and can be used both as an lvalue and an rvalue.

answered on Stack Overflow Feb 27, 2021 by Marco Bonelli • edited Feb 27, 2021 by Marco Bonelli

User contributions licensed under CC BY-SA 3.0