参考了 lovefire[BCG] 兄的文章 :P
“直接用 OD 装入程序。载入完成后,在 CPU 窗口中右击,选择“搜索”->“字串参考”,然后在出现的窗口中搜索 SearchNum,一共有两处,分别下断点。” (呵呵,lovefire的原话)
其实可以直接在这个地方下断:
00406836 . 8BCE mov ecx,esi ; |
00406838 . 889C24 5C010000 mov byte ptr ss:[esp+15C],bl ; |
0040683F . E8 9C090000 call PicHunte.004071E0 ; \这个CALL就是注册算法Call
呵呵,笔记比较乱,整理了一下,
004072EB |> /8B8424 F0000000 /mov eax,dword ptr ss:[esp+F0] ; 用户名入eax cnbragon
004072F2 |. |BD 07000000 |mov ebp,7 ; ebp=7
004072F7 |. |8A1C01 |mov bl,byte ptr ds:[ecx+eax] ; 取c的ascii值的hex63=>eax
|1)第一次ecx=0,所以就取用户名的第一个字符c=>bl ascii 99(d)
|2)第二次ecx=1,所以就取用户名的第二个字符n=>bl ascii 110(d)
|3)..三..ecx=2,..................三......b=>bl ascii 98(d)
|4)..四..ecx=3,..................四......r=>bl ascii 114(d)
004072FA |. |8BC1 |mov eax,ecx
|1) ecx=>eax=0;
|2) ecx=>eax=1;
|3) ecx=>eax=2;
|4) ecx=>eax=3
004072FC |. |99 |cdq
004072FD |. |F7FD |idiv ebp ; eax/=7
|1) eax=0 ,edx=0
|2) eax=0 ,edx=1
|3) eax=0 ,edx=2
|4) eax=0 ,edx=3
004072FF |. |0FBEC3 |movsx eax,bl ;
|1) eax=c
|2) eax=n
|3) eax=b
|4) eax=r
00407302 |. |BB 09000000 |mov ebx,9 ; ebx=9
00407307 |. |0FBE5414 10 |movsx edx,byte ptr ss:[esp+edx+10] ; 从"seamoon"中取对应字符
|1)第一次edx=0,所以第一次取得是's' s=>edx=115
|2)第二次edx=1,所以第二次取得是'e' e=>edx=101
|3)..三..edx=2,......三........'a' a=>edx=97
|4)..四..edx=3,......四........'m' m=>edx=109
0040730C |. |03D6 |add edx,esi ; edx=edx+esi,esi是注册名长度8
|1)edx=115+8=123 (d)
|2)edx=101+8=109 (d)
|3)edx=97+8=105 (d)
|3)edx=109+8=117 (d)
0040730E |. |8D144A |lea edx,dword ptr ds:[edx+ecx*2]
|1)第一次ecx=0,所以还是把123给edx
|2)第二次ecx=1,所以把edx+2=>edx=111
|3)..三..ecx=2,......edx+4=>edx=109
|3)..四..ecx=3,......edx+6=>edx=123
00407311 |. |03C2 |add eax,edx ;
|1)第一次呢是99+123=222(d)
|2)第二次呢是eax=eax+edx=110+111=221
|3)..三......eax=eax+edx=98+109=207
|4)..四......eax=eax+edx=114+123=237
00407313 |. |99 |cdq
00407314 |. |F7FB |idiv ebx ; eax/=9 edx%=9
|1)edx=6 倒数第二位注册码
|2)edx=5 ......三........
|3)edx=0 ......四........
|4)edx=3 ......五........
00407316 |. |80C2 30 |add dl,30 ; 好,余数就是对应的注册码65038774(倒过来:))
00407319 |. |41 |inc ecx ; ecx++
0040731A |. |8817 |mov byte ptr ds:[edi],dl ; 送edi指向的地方
0040731C |. |4F |dec edi ; edi-1
0040731D |. |3BCE |cmp ecx,esi ; 有没有取完,呵呵
0040731F |.^\7C CA \jl short PicHunte.004072EB
//这段代码是用 用户名 和 "seamoon"进行运算
//本人表达能力有限,:(,还是看我的程序吧:P
00407323 |> \8D46 4D lea eax,dword ptr ds:[esi+4D] ; esi中是注册名长度,所以这里是取注册名长度+4D
00407326 |. B9 09000000 mov ecx,9 ; ecx=9
0040732B |. 99 cdq
0040732C |. F7F9 idiv ecx ; eax/=ecx(9) edx为余数
0040732E |. 8B8424 EC000000 mov eax,dword ptr ss:[esp+EC] ; 假码入eax
00407335 |. 80C2 30 add dl,30 ; 余4 这个是注册码的最后一位
00407338 |. 885434 10 mov byte ptr ss:[esp+esi+10],dl
0040733C |. C64434 11 00 mov byte ptr ss:[esp+esi+11],0 ; 0也送过去?
00407341 |. 8D7424 10 lea esi,dword ptr ss:[esp+10] ; 这个就是真码了