我正在尝试解决下面的代码(就像没有进行跳转一样),但我觉得这是一个陷阱22。
XOR EDX,EDI (00268725,00000000)
XOR EAX,ECX (AF51B153, user input)
OR EDX, EAX (00268725,EAX)
JNZ some address
这里有什么诀窍。我正试图将最后一个OR值设为0,但如果我在最后一条指令中输入的值将抵消为0,那么在上一条指令期间,它显然会出错。
- EDI似乎总是00000000。(但我怀疑是否应该)
- EAX似乎总是AF51B153
- EDX似乎总是00268725
没有办法做到这一点。在您显示的代码中,条件分支将始终。为什么会这样?好吧,让我们分析一下代码:
XOR EDX,EDI (00268725,00000000)
如果我读得正确,右边的括号表示法指定执行这行代码时EDX
和EDI
寄存器中的值。如果它们真的都是常量,那么这条指令似乎毫无意义——为什么在运行时用两个常数值进行XOR,而你可以在编译时进行,并将EDX
设置为结果?
无论如何,00268725 XOR 0
==00268725
,因为任何数字XOR 0都是相同的数字
XOR的真值表如下:
| Input | Output |
| A | B | |
|-----|-----|--------|
| 0 | 0 | 0 |
| 0 | 1 | 1 |
| 1 | 0 | 1 |
| 1 | 1 | 0 |
因此,执行此指令后,EDX
包含00268725
,这与您的观察结果一致。
(我不知道你说你怀疑EDI
是否应该包含0是什么意思。寄存器包含一个已定义的值,或者接收到一个不可预测的输入值。在前一种情况下,您可以分析代码。在后者中,你不能。)
XOR EAX,ECX (AF51B153, user input)
这里,AF51B153
(在EAX
中)将与用户输入(在ECX
中)异或。由于用户输入不是一个常数值,我们无法预测结果,但一旦我们看到下一条指令…
OR EDX, EAX (00268725,EAX)
现在,第一条指令(在EDX
中)的结果与第二条指令(EAX
)的结果进行"或"运算。以下是OR函数的真值表:
| Input | Output |
| A | B | |
|-----|-----|--------|
| 0 | 0 | 0 |
| 0 | 1 | 1 |
| 1 | 0 | 1 |
| 1 | 1 | 1 |
由于我们知道EDX
的值是00268725
,所以EAX
的值是多少并不重要。没有任何值可以与00268725
进行OR运算以获得0。从OR函数中得到0的唯一方法是使两个输入都为0,并且您知道EDX
总是非零的。
因此,该指令(在EDX
中)的结果总是非零的,因此零标志(ZF
)将永远不会被设置。这意味着JNZ
将始终获取分支。