好的,所以我开始处理一些汇编。我从以下说明开始:
test al, al
jne 0x1000bffcc
使用调试器,我希望代码不跳转到地址0x1000bffcc
,所以我在jne
指令上设置了一个断点,然后使用以下lldb命令反转al寄存器:
expr $al = 1
这样做效果很好,所以我一直坚持到偶然发现以下非常相似的指令对:
test al, al
je 0x1000bffcc
虽然这看起来很相似,但反转al
寄存器似乎没有影响。它不断跳到地址0x1000bffcc
。所以我做了一些研究,发现测试用al
本身运行一个逻辑AND
,然后相应地设置零标志或ZF
。这就引出了两个问题:
- 为什么在第一个例子中反转
al
寄存器有帮助 - 为什么它在第二个例子中不起作用
- 在第二个示例中,我如何使用调试器使代码不跳转
非常感谢你的帮助!
test al, al
jne 0x1000bffcc
test
指令执行两个操作数的逻辑和,并根据结果(不存储在任何位置)设置CPU标志寄存器。如果al
为零,则anded结果为零,并设置Z标志。如果al
为非零,则清除Z标志。(其他标志,如Carry、oVerflow、Sign、Parity等也受到影响,但此代码没有测试它们的指令。)
如果未设置Z标志,jne
指令将更改EIP。同一操作还有另一个助记符jnz
。
如果让test
指令执行,然后在条件跳转指令之前更改al
,则条件跳转仍将执行更改al
之前要执行的操作。这是因为al
的值不再影响条件跳转。如果您在测试前更改了值,那么它将按预期工作。
至于为什么更改它有时会产生影响:这一定是因为al
的修订值正在影响其他逻辑。
若要使用调试器使指令不跳转,请更改标志以设置Z标志。它可能被称为ZF,或者您可能必须修改EFLAGS寄存器中的位。如何执行此操作因调试器及其修订版而异。