【文章标题】: skilLa's keyGenMe#3算法分析(检测断点)
【文章作者】: bxm
【作者邮箱】: bxm78@163.com
【保护方式】: name,serial
【编写语言】: MASM32 / TASM32
【使用工具】: OD,计算器
【操作平台】: winxp
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
本打算下常规断点的,可此程序有断点检查功能,只要扫描到有断点,立刻终止程序。无奈,只有静态分析了。
0040105D . 6A 14 push 14 ; /Count = 14 (20.)
0040105F . 68 46304000 push 00403046 ; |Buffer = skilLa's.00403046
00401064 . 68 EC030000 push 3EC ; |ControlID = 3EC (1004.)
00401069 . FF75 08 push dword ptr [ebp+8] ; |hWnd
0040106C . E8 71010000 call <jmp.&user32.GetDlgItemTextA> ; \GetDlgItemTextA
00401071 . 83F8 04 cmp eax, 4 ; name长度与4比较
00401074 . 0F82 C2000000 jb 0040113C ; 小于,跳向失败
0040107A . 6A 0A push 0A ; /Count = A (10.)
0040107C . 68 00304000 push 00403000 ; |Buffer = skilLa's.00403000
00401081 . 68 EA030000 push 3EA ; |ControlID = 3EA (1002.)
00401086 . FF75 08 push dword ptr [ebp+8] ; |hWnd
00401089 . E8 54010000 call <jmp.&user32.GetDlgItemTextA> ; \GetDlgItemTextA
0040108E . 83F8 08 cmp eax, 8 ; serial长度与8比
00401091 . 0F85 A5000000 jnz 0040113C ; 不相等,跳向失败
00401097 . 8D35 00304000 lea esi, [403000] ; serial地址入ESI
0040109D . 83C6 04 add esi, 4 ; ESI+4
004010A0 . 8B06 mov eax, [esi] ; serial后四位入EAX
004010A2 . 8D3D 46304000 lea edi, [403046] ; name地址入EDI
004010A8 . 8B1F mov ebx, [edi] ; name的前四位入EBX
004010AA . 33C3 xor eax, ebx ; EAX与EBX异或
004010AC . 3D 37130000 cmp eax, 1337 ; EAX=1337 ?
004010B1 . 0F85 85000000 jnz 0040113C ; 不等,跳向失败
以上功能,Name长度必须大于等于4,Serial必须等于8,然后用name的前四位与serial的后四异或,结果必须为1337,否则失败。如我输入name为bxm78,则serial的后四位必须为Ukm7。
=========================================================================
004010B7 . 33C0 xor eax, eax ; EAX清0
004010B9 . 33DB xor ebx, ebx ; EBX清0
004010BB . 8D35 00304000 lea esi, [403000] ; serial地址入ESI
004010C1 . 8A06 mov al, [esi] ; serial的第1位入AL
004010C3 . F6E0 mul al ; AL*AL
004010C5 . A3 0B304000 mov [40300B], eax ; 存入[40300B]单元
004010CA . 46 inc esi ; ESI+1
004010CB . 33C0 xor eax, eax ; EAX清0
004010CD . 8A06 mov al, [esi] ; serial的第2位入AL
004010CF . B1 68 mov cl, 68 ; 68入CL
004010D1 . F6E1 mul cl ; AL*CL
004010D3 . 8BD8 mov ebx, eax ; EAX入EBX
004010D5 . A1 0B304000 mov eax, [40300B] ; [40300B]入EAX
004010DA . 2BC3 sub eax, ebx ; EAX-EBX
004010DC . 05 8C0A0000 add eax, 0A8C ; EAX+0A8C
004010E1 . 33DB xor ebx, ebx
004010E3 . 8935 5B304000 mov [40305B], esi ; ESI入[40305B]
004010E9 . F6F0 div al ; 除以AL
004010EB . 61 popad
004010EC . 6A 10 push 10 ; /Style = MB_OK|MB_ICONHAND|MB_APPLMODAL
004010EE . 68 1D304000 push 0040301D ; |Title = "o0ps!!"
004010F3 . 68 0F304000 push 0040300F ; |Text = "Try again... "
004010F8 . FF75 08 push dword ptr [ebp+8] ; |hOwner
004010FB . E8 E8000000 call <jmp.&user32.MessageBoxA> ; \MessageBoxA
可以看出,在004010E9必须要发生异常,否则,注册失败。设serial的第1位为A,第2位为B,则A*A-B*68+0A8C的结果的低8位必须为0,为此,我设计了这样C程序:
int i,j,temp; //i即A,j即B
for(i=0x21;i<0x7B;i++)
{
temp=i*i+0xA8C;
for(j=0x21;j<0x7B;j++)
if((temp-j*0x68)%0x100==0) cout<<char(i)<<" "<<char(j)<<endl;
可以求出好多组可用的数据,如A='B' B='Z'
======================================================================
00401110 > /8B35 5B304000 mov esi, [40305B] ; serial的第2位地址入ESI
00401116 . |46 inc esi ; ESI+1
00401117 . |8A06 mov al, [esi] ; serial的第3位入AL
00401119 . |F7E0 mul eax ; EAX*EAX
0040111B . |A3 0B304000 mov [40300B], eax ; 存入[40300B]单元
00401120 . |46 inc esi
00401121 . |33C0 xor eax, eax
00401123 . |8A06 mov al, [esi] ; serial的第4位入AL
00401125 . |B1 68 mov cl, 68 ; 68入CL
00401127 . |F6E1 mul cl ; AL*CL
00401129 . |8BD8 mov ebx, eax ; EAX入EBX
0040112B . |A1 0B304000 mov eax, [40300B] ; [40300B]入EAX
00401130 . |2BC3 sub eax, ebx ; EAX-EBX
00401132 . |05 8C0A0000 add eax, 0A8C ; EAX+0A8C
00401137 . |83F8 00 cmp eax, 0 ; EAX=0 ?
0040113A . |74 18 je short 00401154 ; 相等,跳向成功
0040113C > |61 popad
0040113D . |6A 10 push 10 ; /Style = MB_OK|MB_ICONHAND|MB_APPLMODAL
0040113F . |68 1D304000 push 0040301D ; |Title = "o0ps!!"
00401144 . |68 0F304000 push 0040300F ; |Text = "Try again... "
00401149 . |FF75 08 push dword ptr [ebp+8] ; |hOwner
0040114C . |E8 97000000 call <jmp.&user32.MessageBoxA> ; \MessageBoxA
00401151 . |60 pushad
00401152 . |EB 16 jmp short 0040116A
00401154 > |61 popad
00401155 . |6A 00 push 0 ; /Style = MB_OK|MB_APPLMODAL
00401157 . |68 24304000 push 00403024 ; |Title = "Wo0!!"
0040115C . |68 2A304000 push 0040302A ; |Text = "Goodboy, now write a keygen"
00401161 . |FF75 08 push dword ptr [ebp+8] ; |hOwner
00401164 . |E8 7F000000 call <jmp.&user32.MessageBoxA> ; \MessageBoxA
00401169 . |60 pushad
0040116A > |EB 45 jmp short 004011B1
0040116C $ |8B4C24 0C mov ecx, [esp+C] ; 结构异常处理程序
00401170 . |8BA1 C4000000 mov esp, [ecx+C4]
00401176 . |64:8F05 00000>pop dword ptr fs:[0]
0040117D . |83C4 04 add esp, 4
00401180 .^\EB 8E jmp short 00401110
设Serial的第3位为C,第4位为D,则C*C-D*68+0A8C=0,为此,设计如下的C程序:
int i,temp;
for(i=0x21;i<0x7B;i++)
{
temp=i*i+0xA8C;
if(temp%0x68==0) cout<<char(i)<<" "<<char(temp/0x68)<<endl;
}
也可以求出多组可用的数据,如C='2',D='2'
附可用注册码:
name:bxm78
serial:BZ22Ukm7 或2222Ukm7
一个name可以对应多个serial,serial只与name的前4位有关。
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!
2006年09月29日 下午 09:44:55
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)