| 
注册时间2004-12-1
阅读权限255
最后登录1970-1-1UID2 总坛主   
 
 TA的每日心情|  | 开心 2024-12-1 11:04
 | 
|---|
 签到天数: 12 天 [LV.3]偶尔看看II | 
 
| 【破文标题】as3852711的超小KeyGenMe算法简析+ASM注册机源码 【破文作者】飘云/P.Y.G
 【官方主页】https://www.chinapyg.com
 【作者博客】http://blog.piaoyunsoft.com
 【破解平台】WinXp SP3
 【破解工具】PEiD0.94、OD
 【作者邮箱】[email protected]
 【软件名称】as3852711的超小KeyGenMe
 【软件大小】4.7KB
 【原版下载】https://www.chinapyg.com/viewthr ... &extra=page%3D1
 
 感谢as3852711为我们带来了这个好东西,麻雀虽小五脏俱全啊~~ 这个KeyGenMe很有代表性~
 我就作为教程来讲解下~
 
 
 至于怎么来到关键地方,就不多说了~ 如果找不到下面的代码,那么您还不适合看本文~
 补习基础断点先~~
 
 算法函数:
 复制代码004013C8  push    ebp
004013C9  mov     ebp, esp
004013CB  sub     esp, 50
004013CE  push    esi
004013CF  push    ebx
004013D0  mov     dword ptr [ebp-10], 1        ;  初始值j
004013D7  add     esp, -0C
004013DA  mov     eax, dword ptr [ebp+C]
004013DD  push    eax                          ; /s
004013DE  call    <jmp.&msvcrt.strlen>         ; \strlen
004013E3  add     esp, 10
004013E6  mov     dword ptr [ebp-8], eax
004013E9  add     esp, -0C
004013EC  mov     eax, dword ptr [ebp+10]
004013EF  push    eax                          ; /s
004013F0  call    <jmp.&msvcrt.strlen>         ; \strlen
004013F5  add     esp, 10
004013F8  mov     dword ptr [ebp-4], eax
004013FB  mov     dword ptr [ebp-24], 1
00401402  cmp     dword ptr [ebp-8], 5         ;  用户名必须5位
00401406  jnz     00401520
0040140C  mov     eax, dword ptr [ebp-8]       ;  5
0040140F  mov     edx, eax
00401411  lea     eax, dword ptr [edx+edx]     ;  5 + 5  这里就是注册码的程度  10位
00401414  cmp     dword ptr [ebp-4], eax
00401417  jnz     00401520
0040141D  mov     eax, dword ptr [ebp-8]
00401420  add     eax, -3
00401423  mov     dword ptr [ebp-4], eax
00401426  mov     dword ptr [ebp-C], 0         ;  赋值0
0040142D  lea     esi, dword ptr [esi]
00401430  cmp     dword ptr [ebp-C], 6         ;  i=0    while(i <= 6)
00401434  jle     short 00401440
00401436  jmp     00401500
0040143B  nop
0040143C  lea     esi, dword ptr [esi]
00401440  mov     eax, dword ptr [ebp+C]       ;  载入用户名
00401443  mov     edx, dword ptr [ebp-C]
00401446  add     eax, edx
00401448  cmp     byte ptr [eax], 7A           ;  z
0040144B  jg      004014F0
00401451  mov     eax, dword ptr [ebp+C]
00401454  mov     edx, dword ptr [ebp-C]
00401457  add     eax, edx
00401459  cmp     byte ptr [eax], 60
0040145C  jle     004014F0
00401462  mov     eax, dword ptr [ebp+10]      ;  载入注册码
00401465  mov     edx, dword ptr [ebp-C]
00401468  add     eax, edx
0040146A  cmp     byte ptr [eax], 5A           ;  Z
0040146D  jg      004014F0
00401473  mov     eax, dword ptr [ebp+10]
00401476  mov     edx, dword ptr [ebp-C]
00401479  add     eax, edx
0040147B  cmp     byte ptr [eax], 40           ;  上面一截都是对输入做限制~ 用户名:5位小写字符/注册码10位大写字符~~ 所以可以推断并不是所有用户名都能注册成功的!
0040147E  jle     short 004014F0
00401480  mov     eax, dword ptr [ebp+10]
00401483  mov     ecx, dword ptr [ebp-10]      ;  j
00401486  lea     edx, dword ptr [ecx+eax]     ;  修正注册码位置
00401489  movsx   eax, byte ptr [edx]          ;  Sn[j]
0040148C  mov     edx, dword ptr [ebp-10]      ;  j
0040148F  mov     ecx, dword ptr [ebp+10]
00401492  add     edx, ecx
00401494  lea     ecx, dword ptr [edx-1]       ;  修正注册码位置
00401497  movsx   edx, byte ptr [ecx]          ;  Sn[j-1]
0040149A  sub     eax, edx                     ;  Sn[j] - Sn[j-1]
0040149C  cmp     eax, dword ptr [ebp-C]       ;  if Sn[j] - Sn[j-1] = i
0040149F  jnz     short 004014F0
004014A1  mov     eax, dword ptr [ebp+C]       ;  name
004014A4  mov     ecx, dword ptr [ebp-C]       ;  i
004014A7  lea     edx, dword ptr [ecx+eax]     ;  修正用户名位置
004014AA  movsx   eax, byte ptr [edx]          ;  name[i]
004014AD  mov     edx, dword ptr [ebp-10]      ;  j
004014B0  mov     ecx, dword ptr [ebp+10]
004014B3  add     edx, ecx
004014B5  lea     ecx, dword ptr [edx-1]
004014B8  movsx   edx, byte ptr [ecx]          ;  Sn[j-1]
004014BB  mov     ecx, eax
004014BD  sub     ecx, edx                     ;  name[i] - Sn[j-1]
004014BF  mov     dword ptr [ebp-34], ecx      ;  计算结果A
004014C2  mov     edx, dword ptr [ebp-10]      ;  j
004014C5  add     edx, 2                       ;  k = j + 2
004014C8  mov     ebx, 1D                      ;  0x1D(29)
004014CD  mov     eax, ebx
004014CF  mov     esi, edx
004014D1  cdq
004014D2  idiv    esi                          ;  N = 0x1D(29)/k
004014D4  mov     ecx, eax
004014D6  lea     ebx, dword ptr [ecx+1E]      ;  N + 0x1E(30)
004014D9  cmp     dword ptr [ebp-34], ebx      ;  if A = N
004014DC  jnz     short 004014ED
004014DE  add     dword ptr [ebp-10], 2        ;  j = j + 2
004014E2  mov     eax, dword ptr [ebp-4]
004014E5  mov     edx, eax
004014E7  lea     eax, dword ptr [edx+edx]
004014EA  mov     dword ptr [ebp-4], eax
004014ED  jmp     short 004014F4
004014EF  nop
004014F0  add     dword ptr [ebp-4], -19
004014F4  inc     dword ptr [ebp-C]            ;  i = i + 1
004014F7  jmp     00401430
004014FC  lea     esi, dword ptr [esi]         ;  到这就够了,下面我们整理公式
00401500  add     esp, -8
00401503  mov     eax, dword ptr [ebp-4]
00401506  add     eax, -9
00401509  lea     edx, dword ptr [eax+eax]
0040150C  push    edx
0040150D  mov     eax, dword ptr [ebp+8]
00401510  push    eax
00401511  call    00401548
00401516  add     esp, 10
00401519  jmp     short 0040153A
0040151B  nop
0040151C  lea     esi, dword ptr [esi]
00401520  add     esp, -0C
00401523  push    4                            ; /LanguageID = 4 (LANG_CHINESE)
00401525  push    10                           ; |Style = MB_OK|MB_ICONHAND|MB_APPLMODAL
00401527  push    0                            ; |Title = NULL
00401529  push    00401308                     ; |Text = ""
0040152E  mov     eax, dword ptr [ebp+8]       ; |
00401531  push    eax                          ; |hOwner
00401532  call    <jmp.&USER32.MessageBoxExA>  ; \MessageBoxExA
00401537  add     esp, 0C
0040153A  jmp     short 00401540
0040153C  jmp     short 00401540
0040153E  mov     esi, esi
00401540  lea     esp, dword ptr [ebp-58]
00401543  pop     ebx
00401544  pop     esi
00401545  leave
00401546  retn
【算法总结】
整理一下:
最初:
j = 1
i = 0
公式:
1.name[i] - sn[j-1] = 29/(j+2) + 30
2.sn[j] - sn[j-1] = i
解个方程啊~~ 我们是要求出sn 
那么公式变成如下了:
1.sn[j-1] = name[i] - (29/(j+2) + 30)
2.sn[j] = i + sn[j-1]
;=================================================
;用户名:5位小写字母
;注册码:10位大写字母
;所以可以推断并不是所有用户名都能注册成功的!
;=================================================
【版权声明】 本文纯属技术交流, 原创于PYG官方论坛, 转载请注明作者并保持文章的完整, 谢谢!复制代码;=================================================
;注册算法函数 
;For ASM
;Code By PiaoYun/P.Y.G
;https://www.chinapyg.com
;=================================================
KeyGen proc dwName:DWORD
 
 LOCAL @szTemp[11]:BYTE
 LOCAL @szSn[128]:BYTE
 
 invoke RtlZeroMemory,addr @szTemp,sizeof @szTemp 
 invoke RtlZeroMemory,addr @szSn,sizeof @szSn 
 
 xor esi,esi ;i
 mov edx,1 ;j
 mov edi,edx 
 
 @@:
 cmp     esi, 5
 jge @F
 mov edx,edi
 ;29 div (j + 2) + 30
 add     edx, 2
 mov     ebx, 1Dh
 mov     eax, ebx
 mov     ecx, edx
 cdq
 idiv    ecx
 mov     ecx, eax
 lea     ebx, dword ptr [ecx+1Eh]
 ;name[i] - (29 div (j + 2) + 30
 mov eax,dwName
 movzx eax,byte ptr [esi+eax]
 sub eax,ebx
 ;Sn[j-1]
 mov byte ptr[@szTemp + edi - 1],al
 ;Sn[j]
 add eax,esi
 mov byte ptr[@szTemp + edi],al
 
 inc esi
 add edi,2
 jmp @B
 @@:
 
 invoke lstrcpy,addr @szSn,addr @szTemp
 lea eax,@szSn
 ret
KeyGen endp
 | 
 |