如果这是一项家庭作业,那么它实际上是一项相当棘手的任务。 (尽管我可能忽略了一个简单的方法。)
让我们重点关注这段代码的效果memory。为简单起见,我假设您对此代码的影响不感兴趣寄存器,尽管我无法确定是否看到调用此函数的代码。
encryptL:
push eax
... ; ignoring this code because its effect on eax is undone by the following pop
pop eax
... ; code not affecting eax
movzx ecx, [eax]
... ; code not affecting eax
mov [eax], cl
ret
所以输入一个地址(eax
)。该地址处的字节被放入cl
,经过一些变换后,cl
被放回同一地址。
我们需要弄清楚这些变换是什么,然后反转它们。
ror cl, 1
xor cl, 0x96
push ecx
... ; ignoring this code because its effect on ecx is undone by the following pop
pop ecx
xor ecx, edx
因此,应用了旋转和两个异或cl
。
异或是一个内卷化 https://en.wikipedia.org/wiki/Involution_(mathematics),所以我们不必更改这两条指令。
的逆rol
当然是ror
,尽管这并不完全正确。对进位标志的影响无法反转,但在这种情况下,该影响被忽略,所以我们很好。
但是我们忽略的所有代码又如何呢?仔细检查后,您会发现它只是用来计算edx
用于xor ecx,edx
。
不幸的是,原始(未加密)值[eax]
参与该计算。
解密时,原始值成为最终值,即结果xor ecx,edx
。
我们似乎遇到了先有鸡还是先有蛋的问题。当它依赖于相同计算的结果时如何执行计算?
效果应该很明显[eax]
的计算edx
,是 8 种可能情况中的一种,由于以下陈述:
and cl, 0x7
这意味着我们可以使用循环来尝试所有不同的可能性,直到找到一个计算结果与我们在[eax]
。
该循环与加密器中的循环非常相似:
X:
add dl, 2
sub cl, 1
jg X
但是,循环的退出条件会有所不同。
mov bl,0 ; using bl as a loop counter (similar to cl in original loop)
X:
inc bl
add dl,2 ; same as in the original loop
mov cl,[eax] ; fetch encrypted byte from memory
xor ecx,edx ; try transforming cl with the current value of dl
xor ebx,ecx ; compare cl with the loop counter (bl)
and bl,7 ; only compare the 3 least significant bits
jg X ; if not zero, try again with the next possible value of dl
Since xor
是可交换和结合的,我们可以重写这段代码。
而不是递增bl
直到匹配为止cl
,我们将减少cl
直到其(部分)变换后的值为零(模 8)。
mov cl,[eax] ; fetch encrypted byte from memory
X:
add dl,2 ; same as in the original loop
sub cl,1 ; same as in the original loop
push ecx
xor ecx,edx ; transform cl with the current value of dl
and cl,7 ; only consider the 3 least significant bits
pop ecx ; restore cl (without clobbering flags)
jg X ; if equal, then we found the right starting point
至于其余的代码,可以保持原样。主要是计算的初始部分edx
, 前[eax]
参与其中。
这是完整的解决方案:
encryptL:
push eax
xchg eax, ecx
neg al
inc eax
rol al, 1
rol al, 1
mov ebx, eax
pop eax
push ebx
pop edx
movzx ecx, [eax]
push ecx
X:
add dl,2
sub cl,1
push ecx
xor ecx,edx
and cl,7
pop ecx
jg X
pop ecx
xor ecx,edx
xor cl,0x96
rol cl,1
mov [eax],cl
ret
免责声明:我没有测试它,所以它很可能不起作用。我将把调试留给你。