我不是大神,所以文章哪里写的不对的地方还请各位大佬指出。
直接来到算法部分0x0040104B处,分析发现算法很简短,主要分成了两部分。
第一部分:
0040105C A1 21214000 mov eax, dword ptr [0x402121]
00401061 B9 02000000 mov ecx, 0x2
00401066 99 cdq
00401067 F7F1 div ecx
00401069 8BF0 mov esi, eax
0040106B B8 44554536 mov eax, 0x36455544
00401070 8B0D 21214000 mov ecx, dword ptr [0x402121]
00401076 C1C0 06 rol eax, 0x6
00401079 32E0 xor ah, al
0040107B 02C1 add al, cl
0040107D 49 dec ecx
0040107E ^ 75 F6 jnz short 00401076
00401080 3D 85180704 cmp eax, 0x4071885
第二部分:
00401094 A1 25214000 mov eax, dword ptr [0x402125]
00401099 B9 02000000 mov ecx, 0x2
0040109E 99 cdq
0040109F F7F1 div ecx
004010A1 8BF0 mov esi, eax
004010A3 B8 52495343 mov eax, 0x43534952
004010A8 8B0D 25214000 mov ecx, dword ptr [0x402125]
004010AE C1C0 06 rol eax, 0x6
004010B1 32E0 xor ah, al
004010B3 02C1 add al, cl
004010B5 49 dec ecx
004010B6 ^ 75 F6 jnz short 004010AE
004010B8 3D 27D1004B cmp eax, 0x4B00D127
不难发现这两个部分的算法几乎是一致的,只是每次操作的数据不一样。所以只要逆向出第一个算法,就可以轻易逆向出第二个算法了。
这里直接枚举并不合适,因为这个至少要循环0x20202020次,每次枚举的时间复杂度都是成倍增加的,直接枚举不知道得枚举到什么时候呢。
所以就需要有个快速的方法逆向出注册码。
分析这个代码的时候,画了一个流程图。

于是就可以根据最后比较的数据来反推循环次数,因为反推的时候循环次数要从1开始递增,所以这些运算都应该写成逆运算的形式,即把后面的代码放到前面去,add换成sub,xor不变,rol换成ror,最后将被比较的数据和待运算的数据互换位置。
于是就可以写出如下的代码:
mov eax,0x04071885
xor ecx,ecx
LOOP_:
inc ecx
sub al,cl
xor ah,al
ror eax,6
cmp eax,0x36455544
jnz LOOP_
mov Time,ecx
结果出的很快,第一次出来的结果是0x0DBD76F6。因为有不可显示的字符,所以我加了一个判断,如果计算出来的是这个,就继续计算。
最后能得到注册码的前四位"isd4"。当然也可以继续往下,不止一组。
计算后四位的思路也是一样的,代码如下:
mov eax,0x4B00D127
xor ecx,ecx
LOOP_1:
inc ecx
sub al,cl
xor ah,al
ror eax,6
cmp eax,0x43534952
jnz LOOP_1
mov Time,ecx
这段代码能算出注册码的后四位"ever"。
最后合在一起得到注册码为"isd4ever"。

最后放一个完整的计算代码吧。
代码写的很挫,大佬们不要喷我 = =
可以在这个代码的基础上加上循环来计算出所有满足条件的值。
#include <stdio.h>
int main(int argc,char *argv[])
{
int Time = 0
_asm
{
mov eax,0x04071885
xor ecx,ecx
LOOP_:
inc ecx
sub al,cl
xor ah,al
ror eax,6
cmp eax,0x36455544
jnz LOOP_
cmp ecx,0x0DBD76F6
je LOOP_
mov Time,ecx
}
printf("%0.4s",&Time)
_asm
{
mov eax,0x4B00D127
xor ecx,ecx
LOOP_1:
inc ecx
sub al,cl
xor ah,al
ror eax,6
cmp eax,0x43534952
jnz LOOP_1
mov Time,ecx
}
printf("%0.4s",&Time)
while(1)
return 0
}