简单算法-韩语小词典2004算法分析
―――――――――――――――――――――――――――――――――――――――――――
【软件名称】:韩语小词典2004
【文章作者】:仙剑太郎
【网站地址】:中国X黑客小组 www.CnXHacker.com
【软件简介】:类似金山词霸式的查询韩语的词典软件.
【软件限制】:注册码方式
【破解声明】:初学Crack,只是感兴趣,没有其它目的。失误之处敬请诸位大侠赐教!
【破解工具】:Ollydbg
―――――――――――――――――――――――――――――――――――――――――――
【破解过程】:
应该是比较旧的软件了,现在也停止升级了.新手来看看怎么分析算法,老鸟来个鼓励呵呵~
打开软件有要求注册的提示,我们进去后,在设置那里点注册,弹出的输入注册码的框框中随便输入,确定后有出错提示....-_-
本机机器码:NNRK-81E2-5NMN
试炼注册码:123456
由于是多语言的,所以不好依据提示的内容来确定位置,可以直接下断MessageBoxA,中断后返回来到如下:
0041B706 |. 68 00E00000 push 0E000 ; /Arg1 = 0000E000
0041B70B |. 8D4C24 08 lea ecx,dword ptr ss:[esp+8] ; |
0041B70F |. C74424 14 000>mov dword ptr ss:[esp+14],0 ; |
0041B717 |. E8 35670300 call MultiDic.00451E51 ; \MultiDic.00451E51
0041B71C |. A1 18ED4700 mov eax,dword ptr ds:[47ED18]
0041B721 |. 894424 00 mov dword ptr ss:[esp],eax
0041B725 |. 8B4C24 18 mov ecx,dword ptr ss:[esp+18]
0041B729 |. C64424 10 01 mov byte ptr ss:[esp+10],1
0041B72E |. 51 push ecx ; /Arg1
0041B72F |. 8D4C24 04 lea ecx,dword ptr ss:[esp+4] ; |
0041B733 |. E8 19670300 call MultiDic.00451E51 ; \MultiDic.00451E51
0041B738 |. 8B5424 04 mov edx,dword ptr ss:[esp+4]
0041B73C |. 8B4424 00 mov eax,dword ptr ss:[esp]
0041B740 |. 6A 00 push 0 ; /Style =
MB_OK|MB_APPLMODAL
0041B742 |. 52 push edx ; |Title
0041B743 |. 50 push eax ; |Text
0041B744 |. FF15 60754600 call dword ptr ds:[<&USER32.GetFocus>] ; |[GetFocus
0041B74A |. 50 push eax ; |hOwner
0041B74B |. FF15 64754600 call dword ptr ds:[<&USER32.MessageBoxA>] ; \MessageBoxA
0041B751 |. 8D4C24 00 lea ecx,dword ptr ss:[esp] ;返回到这里
向上看,OD有个黑色的框连着这段,看开头,如下:
0041B6E0 /$ 6A FF push -1
0041B6E2 |. 68 50274600 push MultiDic.00462750 ; SE handler installation
0041B6E7 |. 64:A1 0000000>mov eax,dword ptr fs:[0]
0041B6ED |. 50 push eax
0041B6EE |. 64:8925 00000>mov dword ptr fs:[0],esp
显示这是一个CALL的入口,在0041B6E0下断,F9运行,看堆栈窗口
=====================================
0012B18C 0040F2B9 返回到 MultiDic.0040F2B9 来自 MultiDic.0041B6E0
=====================================
说明了有个CALL来自0040F2B9,取消断点后,CTRL+G ,0040F2B9,来到如下:
0040F2A8 . /EB 0F jmp short MultiDic.0040F2B9
0040F2AA > |68 30E00000 push 0E030 ; /Arg1 = 0000E030
0040F2AF . |B9 C0104800 mov ecx,MultiDic.004810C0 ; |
0040F2B4 . |E8 27C40000 call MultiDic.0041B6E0 ; \MultiDic.0041B6E0
0040F2B9 > \8D4C24 10 lea ecx,dword ptr ss:[esp+10] ;来到这里
通过0040F2AA前面的>可以看到,有跳转到这里调用出错提示0040F2B4 ,鼠标点一下0040F2AA所在行,沿着红色的
线条向上找,来到这里
0040F230 > \1BC0 sbb eax,eax
0040F232 . 83D8 FF sbb eax,-1
0040F235 > 85C0 test eax,eax
0040F237 75 71 jnz short MultiDic.0040F2AA
很经典的比较方式.在0040F237下断,运行,中断后修改jnz为je,呵,暴破了吧.我们现在要找算法,所以还得继续.
继续向上番,看到有几个CALL,呵有眉目了.
0040F1BF . 50 push eax ; /Arg1
0040F1C0 > . C68424 3C0300>mov byte ptr ss:[esp+33C],1
0040F1C8 . E8 43620000 call MultiDic.00415410 ; \MultiDic.00415410
0040F1CD . 8D8C24 300100>lea ecx,dword ptr ss:[esp+130]
0040F1D4 . 8D5424 18 lea edx,dword ptr ss:[esp+18]
0040F1D8 . 51 push ecx
0040F1D9 . 8D4424 34 lea eax,dword ptr ss:[esp+34]
0040F1DD . 52 push edx
0040F1DE . 50 push eax
0040F1DF . 8D4C24 1C lea ecx,dword ptr ss:[esp+1C]
0040F1E3 . E8 C8620000 call MultiDic.004154B0
0040F1E8 . 8D8C24 300200>lea ecx,dword ptr ss:[esp+230]
0040F1EF . 8D9424 300100>lea edx,dword ptr ss:[esp+130]
0040F1F6 . 51 push ecx ; /Arg2
0040F1F7 . 52 push edx ; |Arg1
0040F1F8 . 8D4C24 18 lea ecx,dword ptr ss:[esp+18] ; |
0040F1FC . E8 5F630000 call MultiDic.00415560 ; \MultiDic.00415560
首先从0040F1C8 的CALL开始,粗跟,大致看到这是机器码的生成,0040F1E3的CALL也是.到第三个CALL
了,0040F1FC,看到push的两个参数了吗呵呵,F2下断,运行后中断看到寄存器显示
================================
EAX 00000001
ECX 0012B1A4
EDX 0012B2C4 ASCII "NNRK-81E2-5NMN"
EBX 00000001
ESP 0012B18C
=================================
呵看到自己的机器码了吧?F7跟进,来到下面:
00415560 /$ 81EC 14020000 sub esp,214
00415566 |. 8BD1 mov edx,ecx
00415568 |. B9 41000000 mov ecx,41
0041556D |. 33C0 xor eax,eax
0041556F |. 53 push ebx
00415570 |. 57 push edi
00415571 |. 8DBC24 140100>lea edi,dword ptr ss:[esp+114]
00415578 |. 8B9C24 200200>mov ebx,dword ptr ss:[esp+220]
0041557F |. F3:AB rep stos dword ptr es:[edi]
00415581 |. B9 41000000 mov ecx,41
00415586 |. 8D7C24 0C lea edi,dword ptr ss:[esp+C]
0041558A |. F3:AB rep stos dword ptr es:[edi]
0041558C |. 8D4424 0B lea eax,dword ptr ss:[esp+B]
00415590 |. 8D4C24 0A lea ecx,dword ptr ss:[esp+A]
00415594 |. 50 push eax ; /Arg5
00415595 |. 51 push ecx ; |Arg4
00415596 |. 8D4424 14 lea eax,dword ptr ss:[esp+14] ; |
0041559A |. 8D8C24 1C0100>lea ecx,dword ptr ss:[esp+11C] ; |
004155A1 |. 50 push eax ; |Arg3
004155A2 |. 51 push ecx ; |Arg2
004155A3 |. 53 push ebx ; |Arg1
004155A4 |. 8BCA mov ecx,edx ; |
004155A6 |. E8 E5020000 call MultiDic.00415890 ; \MultiDic.00415890
004155AB |. 84C0 test al,al
上面004155A6是对机器码的处理,对机器码运算生成一个6位小表,但这个表是没作用的。
继续向下看:
004155BD |. 83C9 FF or ecx,FFFFFFFF
004155C0 |. 33C0 xor eax,eax
004155C2 |. 33F6 xor esi,esi
004155C4 |. F2:AE repne scas byte ptr es:[edi]
004155C6 |. F7D1 not ecx
004155C8 |. 49 dec ecx
004155C9 |. 74 46 je short MultiDic.00415611
004155CB |. 55 push ebp
004155CC |. 8BAC24 2C0200>mov ebp,dword ptr ss:[esp+22C] ;算法核心
004155D3 |> 0FBE441E 01 /movsx eax,byte ptr ds:[esi+ebx+1] ;取机器码偶位数ASCII
004155D8 |. 0FBE141E |movsx edx,byte ptr ds:[esi+ebx]
;取机器码奇位数ASCII
004155DC |. 33C2 |xor eax,edx ;偶位 xor 奇位
004155DE |. B9 1A000000 |mov ecx,1A ;常量0x1A
004155E3 |. 99 |cdq
004155E4 |. F7F9 |idiv ecx ;ecx余eax
004155E6 |. 6A 01 |push 1
004155E8 |. 80C2 41 |add dl,41 ;常数0x41累加
004155EB |. 885424 15 |mov byte ptr ss:[esp+15],dl ;保存1位结果到表的指针
004155EF |. 8D5424 15 |lea edx,dword ptr ss:[esp+15] ;取出新表(这个表没用到,汗!)
004155F3 |. 52 |push edx
004155F4 |. 55 |push ebp
004155F5 |. E8 A6810200 |call MultiDic.0043D7A0 ;连接字符
004155FA |. 8BFB |mov edi,ebx ;机器码先保存起来
004155FC |. 83C9 FF |or ecx,FFFFFFFF
004155FF |. 33C0 |xor eax,eax ;清零
00415601 |. 83C4 0C |add esp,0C
00415604 |. 83C6 02 |add esi,2 ;step=2
00415607 |. F2:AE |repne scas byte ptr es:[edi] ;偶菜不知道这是什么
00415609 |. F7D1 |not ecx
0041560B |. 49 |dec ecx ;记数器-1
0041560C |. 3BF1 |cmp esi,ecx ;循环完了吗?
0041560E |.^ 72 C3 \jb short MultiDic.004155D3
00415610 |. 5D pop ebp ;这里可以做内存注册机
00415611 |> 5E pop esi
00415612 |. 5F pop edi
00415613 |. B0 01 mov al,1
00415615 |. 5B pop ebx
00415616 |. 81C4 14020000 add esp,214
0041561C \. C2 0800 retn 8
好了,基本上算法大概就在上面的
下面用高级语言描述一下算法(顺便复习一下C ^_^),注册机如下:
#include <stdio.h>
void main()
{
/* KeyGen By XJTL www.CnXHacker.com */
int j,k,t=0,l=0,s[20];
char n[20];
printf("******** KeyGen For KCDICT2004 ********\n");
printf("Please Input Your Serial Num:");
scanf("%s",n);
while(n[l]!='\0') l++;
printf("\n Your License Num is : ");
for(k=0;k<l;k+=2)
{
s[t]=n[k+1]^n[k];
s[t]%=0x1A;
s[t]+=0x41;
printf("%c",s[t]);
t++;
}
printf("\n");
}
―――――――――――――――――――――――――――――――――――――――――――
【最后总结】:
这里介绍了如何找到算法核心,方便我等菜鸟们步入算法分析时代。希望各位小鸟们加油哟~
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课