如何逆转这个方程式?

时间:2018-12-11 13:28:23

标签: java string encryption reverse-engineering

下面的代码行位于j循环中,其中ansString递增,000\Qg$M!*P000\gQYA+ h000\M|$skd 000\Qo}plsd000\是一串ASCII字符,例如ansString[j] = ((char)(paramString[j] >> j % 8 ^ paramString[j]));

paramString

我在弄清楚如何进行XOR时遇到了麻烦,而其他所有运算符都被颠倒了以找到docker pull avnerner/fontello_server docker run -it -p 3000:3000 -d avnerner/fontello_server 。感谢任何帮助。

2 个答案:

答案 0 :(得分:6)

右移(>>)和模(%)是不可逆的操作:

在正确的移位的情况下,下溢位会丢失,因此反转a >> b会给您带来2 ^ b个不同的可能结果。

对于模运算符,在x % 8 = y中,如果x的最大长度为8位,则有32种可能的值。 (那就是每个x * 8 + y都适合8位)

异或运算是唯一的可逆运算。如果有

a ^ b = c

然后

c ^ b = a

因此,对于多个输入,您将具有相同的输出。例如,让我们假设j = 0

j % 8 = 0 % 8 = 0

paramString[j] >> (j % 8) = paramString[0] >> 0 = paramString[0]

paramString[0] ^ paramString[j] = paramString[0] ^ paramString[0] = 0

这意味着对于您的第一个字符和随后的第8个字符(这是其索引j为8的倍数的每个字符,因此j % 8 = 0)的结果将为0,无论原始字符是(如您可以在示例输出字符串中看到)。

这就是为什么即使对所有可能的输入都进行暴力破解(总共256 * n个可能的输入字符串,即n个字符串长度),您也无法确定原始输入是什么,因为许多输入都会产生相同的输出。

答案 1 :(得分:1)

如果j是运行索引,您将知道每次迭代中的偏移量。这样,您就可以找到前缀并解密该字符串。

例如对于j = 2(0..7是位位置,两位数字是XORed位,x为0):

Original:   0  1  2  3  4  5  6  7
Shifted:    x  x  0  1  2  3  4  5
Encrypted:  0  1 02 13 24 35 46 57 

如您所见,前两位数字保持不变。然后用这两位数字来加密接下来的两位,依此类推。

因此,要用j = 2进行解密,您会发现一个未加密的2位数字前缀。可用于解密接下来的2位(02和13):

Encrypted:  0  1 02 13 24 35 46 57 
Shift-Mask: x  x  0  1  x  x  x  x
Temp1:      0  1  2  3 24 35 46 57

现在我们知道前4位数字,还有接下来2位的解密位:

Temp1:      0  1  2  3 24 35 46 57
Shift-Mask: x  x  x  x  2  3  x  x
Temp2:      0  1  2  3  4  5 46 57

再次:

Temp2:       0  1  2  3  4  5 46 57
Shift-Mask3: x  x  x  x  x  x  4  5
Decrypted3:  0  1  2  3  4  5  6  7 <- Original string

基于此思想,您可以构建解密算法