我试图解决(如没有采取跳跃)下面的代码,但我觉得这是一个问题22。
XOR EDX,EDI (00268725,00000000)
XOR EAX,ECX (AF51B153, user input)
OR EDX, EAX (00268725,EAX)
JNZ some address
这里有什么诀窍。我试图将最后一个OR设为0但是如果我在最后一条指令中输入将抵消为0的值,那么在前一条指令中它显然会混乱。
答案 0 :(得分:0)
没有办法做到这一点。在您显示的代码中,条件分支始终。为什么会这样?好吧,让我们分析一下代码:
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
的值并不重要。没有值可以让OR 00268725
得到0.从OR函数中获得0的唯一方法是两个输入都为0,并且你知道EDX
总是非零。
因此,该指令的结果(在EDX
中)总是非零,因此零标志(ZF
)将永远不会设置。这意味着JNZ
将总是接受分支。