C++ ASM内联如何使用布尔值?

4

假设我有这样的东西...

bool isPatched;

我有几个其他的图形用户界面,其中我设置了 isPatched = true;isPatched = false;isPatched = !isPatched;


void __declspec( naked ) test(void) { //
    __asm {
        PUSHAD
        PUSHFD

        MOV EAX, isPatched
        CMP EAX, 0
        je noPatched
            MOV EAX, DWORD PTR DS:[ESI+0x77C]
            MOV John.oldA, EAX
            MOV EAX, John.A
            MOV DWORD PTR DS:[ESI+0x77C], EAX
            JMP finish
noPatched:
            PUSH EDX
            MOV DWORD PTR DS:[ESI+0x77C], EDX
        finish:
        POPFD
        POPAD

        JMP gotoAddressBack

    }
}

在内联汇编中使用bool运算符是否可行?

我认为它认为isPatched是一个标签...从这个错误信息来看。 error C2094: 标签'isPatched'未定义


1
"test eax,0" 会导致 "je" 在任何时候都跳转。 - sharptooth
isPatched != isPatched 总是为假。你是不是想说 = ! - Linus Kleen
3
要么使用cmp eax, 0,要么使用test eax, eax - sharptooth
什么编译器?由于内联汇编不是C或C++的标准组成部分。 - ctrl-alt-delor
@SSpoke:那些东西不会教你任何东西,我说的是正确的逆向工程,即从汇编语言转换为高级结构,比如这个链接:http://msdn.microsoft.com/en-us/library/ff538086.aspx - Necrolis
显示剩余5条评论
1个回答

4

您想要进行测试或者比较。在这种情况下,测试是最简单的:

XOR EAX,EAX
MOV AL,isPatched //isPatched would be a byte, hence we need correct operand sizes
TEST EAX,EAX
JE NotSet
Set:
//handle true case
JMP End
NotSet:
//handle false case
End:
//continue

根据其他情况,您还可以使用SUBSETccMOVcc


您的问题是作用域问题,当ASM使用isPatched时,它不在作用域内,因此它认为它是一个DWORD,然后在生成地址时无法找到内存标签(符号名称)。您还需要正确使用bool的操作数大小。

MSVC的一个简单测试

bool b = true;
int __declspec( naked ) test(void) {
    __asm {
        xor eax,eax
        MOV al, b
        TEST eax,eax
        JE NotSet
        mov eax,1
NotSet:
        RETN

    }
}

int _tmain(int argc, _TCHAR* argv[])
{
    printf("%d\n", test());
    system("pause");
    return 0;
}

b为真时,输出1;当b为假时,输出0。


是的哈哈,我明白了... 我在想为什么 isPatched 这个全局布尔型变量没有被内联汇编注册,这是不允许的吗? - SSpoke
我用 MOV AL,isPatched 出现了 error C2443: operand size conflict - SSpoke
如果@SSpoke返回false,那么这意味着在你的系统上bool不是一个字节,或者它是BOOL而不是bool(我的示例可以正常运行)。 - Necrolis
“MOV AL,BYTE PTR isPatched” 的错误已经被修复,但现在又出现了“isPatched”标签未定义的错误...尽管它不是一个标签。上面的例子很好。 - SSpoke
@SSpoke:在汇编语言中,所有符号都被称为标签(它是一个内存标签)。通过一些测试,很明显这是一个作用域问题,从我的示例中删除b的定义会产生C2443错误,在此之后添加大小后缀会产生C2094错误。尝试在汇编块之前加上extern bool isPatched - Necrolis
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接