将 LOWORD 宏伪代码神秘化为有效的 C

Demystifying LOWORD macro pseudocode into valid C

IDA将一个子程序反编译成C伪代码,遇到这行代码:

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

其中 v9, v6 是 32 位整数。

LOWORDwindef.h中定义的宏,如下:

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

显然这是一个宏,所以我不能给它赋值。我对一个有效的 C 实现很感兴趣,但我不确定反编译器在这里的意图。根据我的猜测,目的是取消引用 v9LOWORD,并分配 v6 指向的字节值,但我想确定一下。

如果有必要,这里是伪代码的上下文。所有类型都是 32 位整数:

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);
}

您显示的 windef.h 不是 IDA 使用的宏,因为正如您所注意到的,您不能将此类宏的结果用作左值。

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

不完全是。目的是用右侧替换变量 v9(这是一个 int)的低位字(即低 2 个字节)。

所以在 IDA 中,这个:

LOWORD(a) = b;

可以这样看:

a = (a & 0xffff0000) | b;

在 C 中编写这样一个宏的方法如下:

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

这可能是一种更复杂但更通用的做同样事情的方法,并且可以用作左值和右值。