代码:
for( int i = 0; i < 0x10; i++ ) {
serialvar = (((magic1 * i + serialvar) << 0x10) ^ serialvar) + 0x13371337;
serialvar = (((i * magic1 + serialvar) >> 0x10) ^ serialvar) + 0x73317331;
}
我知道,为了扭转某些事物,所有事情都必须以相反的顺序进行。但是,我很困惑,因为这非常复杂,并且似乎需要一个先验值才能反转当前值,否则将无法获得当前值?而且我们正在移位位,因此有可能永远丢失值。
IE。如果forward为
x + 1
,则向后为x - 1
。现在,如果我们拥有serialvar的最终值,是否可以反转此循环以找到未知值serialvar?
最佳答案
与这里的答案相反,这是可以解决的,而无需任何强加于人。
循环和加法很容易反转。剩下的是这两个异或运算:
serialvar ^= (magic1 * i + serialvar) << 0x10;
serialvar ^= (i * magic1 + serialvar) >> 0x10;
让我们将0x10低位称为低部分,将0x10高位称为高部分。
在第一个操作中,很容易看到下部不受影响。但这也是此操作中唯一重要的部分,因为较高的部分被移出了。因此,此操作实际上是它自己的逆运算。
第二个操作稍微复杂一些。这次,高部分不受影响。除了加法
i * magic1 + serialvar
的低位部分溢出并将总和的高位部分加1的情况外,您几乎不需要关心低位部分。因此,此操作始终采用以下两种形式之一:
serialvar ^= (i * magic1 + (serialvar & 0xFFFF0000)) >> 0x10; // no overflow
serialvar ^= (i * magic1 + (serialvar & 0xFFFF0000) + 0x10000) >> 0x10;
现在,每种形式都不依赖于
serialvar
的低位部分,因此每种形式都是其自身的逆形式。因此,您可以简单地尝试这两种方法,并通过应用原始操作来验证哪种方法正确。完整的代码如下:
serialvar = key;
// compute an inverse
for (int i = 0xF; i >= 0; --i) {
serialvar -= 0x73317331;
unsigned int serialvar0 = serialvar ^ ((i * magic1 + (serialvar & 0xFFFF0000)) >> 0x10);
unsigned int serialvar1 = serialvar ^ ((i * magic1 + (serialvar & 0xFFFF0000) + 0x10000) >> 0x10);
if (serialvar == (serialvar0 ^ ((i * magic1 + serialvar0) >> 0x10)))
serialvar = serialvar0;
else
serialvar = serialvar1;
serialvar -= 0x13371337;
serialvar ^= (magic1 * i + serialvar) << 0x10;
}
cout << hex << serialvar << endl;
// verification
for (int i = 0; i < 0x10; i++) {
serialvar = (((magic1 * i + serialvar) << 0x10) ^ serialvar) + 0x13371337;
serialvar = (((i * magic1 + serialvar) >> 0x10) ^ serialvar) + 0x73317331;
}
if (serialvar == key)
cout << "success" << endl;
如果两项检查均成功,则可能存在多个逆,但我没有对此进行研究,因为这并不是必须的。