简单算法-韩语小词典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");
}
―――――――――――――――――――――――――――――――――――――――――――
【最后总结】:
这里介绍了如何找到算法核心,方便我等菜鸟们步入算法分析时代。希望各位小鸟们加油哟~
[课程]Android-CTF解题方法汇总!