以前在看雪曾有位兄台放出一系列闯关cm,今天没事,就找了其中的第三个逆向之。
我找到关键代码的方法也是一时间想到的。即用CE找用户名。然后在下内存断点。很容易就找到了关键处0x401550。
在附件里可以下载到他的cm和我的注册机。下面着重分析一下他的算法。
00401594 lea edx,dword ptr ss:[esp+10]
00401598 /mov cl,byte ptr ds:[eax] ; 转移用户名
0040159A |inc eax
0040159B |mov byte ptr ds:[edx],cl
0040159D |inc edx
0040159E |test cl,cl
004015A0 \jnz short CRECKME_.00401598
004015A2 mov al,byte ptr ss:[esp+16] ; esp+10处,是我们的用户名。
004015A6 test al,al ; 判断第七位非零,即是用户名长度超过六了,玩完。
004015A8 jnz short CRECKME_.004015FA
004015AA mov dl,byte ptr ss:[esp+15]
004015AE test dl,dl ; 原理同上,要第六位非零。即长度达到六,又不多于六
004015B0 je short CRECKME_.004015FA
004015B2 mov eax,dword ptr ds:[ebx+78] ; 得到注册码的数值
004015B5 cmp eax,186A0 ; 要是小于100000就游戏结束
004015BA jl short CRECKME_.004015FA
004015BC movsx esi,byte ptr ss:[esp+12]
004015C1 movsx ecx,byte ptr ss:[esp+11]
004015C6 movsx edi,byte ptr ss:[esp+14]
004015CB add ecx,esi
004015CD movsx esi,byte ptr ss:[esp+10]
004015D2 add ecx,esi ; 前三位相加
004015D4 movsx esi,byte ptr ss:[esp+13]
004015D9 movsx edx,dl
004015DC add esi,edi
004015DE add esi,edx ; 后三位相加
004015E0 cdq
004015E1 mov edi,3E8 ; 用我们的注册码除以3e8,即1000
004015E6 idiv edi
004015E8 cmp ecx,eax ; 商和余数分别前三位的和,后三位的和相比较。不等玩完
004015EA jnz short CRECKME_.004015FA
004015EC cmp esi,edx ; 这是比较余数
004015EE jnz short CRECKME_.004015FA
004015F0 mov eax,dword ptr ds:[ebx]
004015F2 mov ecx,ebx
004015F4 call dword ptr ds:[eax+154]
004015FA mov ecx,dword ptr ss:[esp+94]
00401601 call CRECKME_.00401A49
00401606 pop edi
00401607 pop esi
00401608 pop ebx
00401609 mov esp,ebp
0040160B pop ebp
0040160C retn
到这里就完成了对算法的分析。缕一下思路:
1.输入六位用户名。将其前三位的acaii码相加,得到结果A,后三位的acaii码相加,得到结果B。
2.输入注册码,转成数字后,除以3E8,即十进制的1000。得到了商和余数。其中,商和第一步得到的结果A比较,余数和第一步得到的结果B比较。两者都相等。则成功注册!
3.所以,我们逆推之,用A乘以1000,再加上B.就是我们要的注册码了。
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课