- UID
- 38098
注册时间2007-12-1
阅读权限10
最后登录1970-1-1
周游历练
该用户从未签到
|
【破文标题】KGme 算法分析
【破文作者】missviola
【作者邮箱】
【作者主页】
【破解工具】DEDE OD PEID
【破解平台】Windows XP
【软件名称】
【软件大小】
【原版下载】
【保护方式】
【软件简介】
【破解声明】只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
------------------------------------------------------------------------
【破解过程】这几天逛论坛发现as3852711大牛发的一个KGme,自己下载分析了一下,于是就有了这篇破文。首先用PEID查壳,显示Borland Delphi 6.0 - 7.0。用DEDE分析下,发
现“Register”按钮click事件对应的地址为467C30。打开OD在467C30处下断点,F9运行,输入假码123456,点击按钮,crackme断下,F8单步往下走。
00467C30 <K> 55 push ebp ; <[email=-TForm1@Button1Click]-TForm1@Button1Click[/email]
00467C31 8BEC mov ebp,esp
00467C33 83C4 C0 add esp,-40
00467C36 53 push ebx
00467C37 56 push esi
00467C38 33C9 xor ecx,ecx
00467C3A 894D DC mov dword ptr ss:[ebp-24],ecx
00467C3D 894D D8 mov dword ptr ss:[ebp-28],ecx
00467C40 894D CC mov dword ptr ss:[ebp-34],ecx
00467C43 894D E0 mov dword ptr ss:[ebp-20],ecx
00467C46 894D FC mov dword ptr ss:[ebp-4],ecx
00467C49 8BF2 mov esi,edx
00467C4B 8BD8 mov ebx,eax
00467C4D 33C0 xor eax,eax
00467C4F 55 push ebp
00467C50 68 917D4600 push <KGMe.->System.@HandleFinally;>
00467C55 64:FF30 push dword ptr fs:[eax]
00467C58 64:8920 mov dword ptr fs:[eax],esp
00467C5B 8D55 FC lea edx,dword ptr ss:[ebp-4]
00467C5E <K> 8B83 04030000 mov eax,dword ptr ds:[ebx+304] ; *Edit2:TEdit
00467C64 <K> E8 D7B0FCFF call KGMe.00432D40 ; ->Controls.TControl.GetText(TControl):TCaption;取注册码长度
00467C69 8D55 E4 lea edx,dword ptr ss:[ebp-1C]
00467C6C 8B45 FC mov eax,dword ptr ss:[ebp-4]
00467C6F <K> E8 6CB3F9FF call KGMe.00402FE0 ; ->System.@ValExt;
00467C74 DD5D F0 fstp qword ptr ss:[ebp-10]
00467C77 9B wait
00467C78 837D E4 00 cmp dword ptr ss:[ebp-1C],0 ; 检验是否输入了注册码
00467C7C 0F85 D0000000 jnz KGMe.00467D52
00467C82 8D55 E0 lea edx,dword ptr ss:[ebp-20]
00467C85 <K> 8B83 00030000 mov eax,dword ptr ds:[ebx+300] ; *Edit1:TEdit
00467C8B <K> E8 B0B0FCFF call KGMe.00432D40 ; ->Controls.TControl.GetText(TControl):TCaption;取机器码长度
00467C90 8B45 E0 mov eax,dword ptr ss:[ebp-20]
00467C93 <K> E8 F81AFAFF call KGMe.00409790 ; ->SysUtils.StrToFloat(AnsiString):Extended;overload;
00467C98 83C4 F8 add esp,-8
00467C9B DD1C24 fstp qword ptr ss:[esp]
00467C9E 9B wait
00467C9F E8 D0FCFFFF call KGMe.00467974 ; 这个CALL跟进
00467974 55 push ebp
00467975 8BEC mov ebp,esp
00467977 83C4 DC add esp,-24
0046797A 33C0 xor eax,eax
0046797C 8945 EC mov dword ptr ss:[ebp-14],eax
0046797F 8945 E8 mov dword ptr ss:[ebp-18],eax
00467982 8945 DC mov dword ptr ss:[ebp-24],eax
00467985 33C0 xor eax,eax
00467987 55 push ebp
00467988 68 2E7A4600 push KGMe.00467A2E
0046798D 64:FF30 push dword ptr fs:[eax]
00467990 64:8920 mov dword ptr fs:[eax],esp
00467993 DD45 08 fld qword ptr ss:[ebp+8]
00467996 D825 407A4600 fsub dword ptr ds:[467A40] ; 机器码减去9527,记为M1
0046799C DD5D 08 fstp qword ptr ss:[ebp+8]
0046799F 9B wait
004679A0 DD45 08 fld qword ptr ss:[ebp+8]
004679A3 D835 447A4600 fdiv dword ptr ds:[467A44] ; M1再除以139,记为M2
004679A9 DD5D F0 fstp qword ptr ss:[ebp-10]
004679AC 9B wait
004679AD 8D45 E8 lea eax,dword ptr ss:[ebp-18]
004679B0 50 push eax
004679B1 0FB705 20BC4600 movzx eax,word ptr ds:[46BC20]
004679B8 8945 E0 mov dword ptr ss:[ebp-20],eax
004679BB C645 E4 00 mov byte ptr ss:[ebp-1C],0
004679BF 8D55 E0 lea edx,dword ptr ss:[ebp-20]
004679C2 33C9 xor ecx,ecx
004679C4 A1 08BC4600 mov eax,dword ptr ds:[46BC08]
004679C9 E8 2E16FAFF call KGMe.00408FFC
004679CE FF75 E8 push dword ptr ss:[ebp-18]
004679D1 FF35 04BC4600 push dword ptr ds:[46BC04]
004679D7 DD05 FCBB4600 fld qword ptr ds:[46BBFC]
004679DD 83C4 F4 add esp,-0C
004679E0 DB3C24 fstp tbyte ptr ss:[esp]
004679E3 9B wait
004679E4 8D45 DC lea eax,dword ptr ss:[ebp-24]
004679E7 E8 441DFAFF call KGMe.00409730
004679EC FF75 DC push dword ptr ss:[ebp-24]
004679EF 8D45 EC lea eax,dword ptr ss:[ebp-14]
004679F2 BA 03000000 mov edx,3
004679F7 E8 A4CCF9FF call KGMe.004046A0 ; 获取昨天的系统日期
004679FC 8B45 EC mov eax,dword ptr ss:[ebp-14]
004679FF E8 8C1DFAFF call KGMe.00409790
00467A04 DC45 F0 fadd qword ptr ss:[ebp-10] ; 昨天的系统日期同M2相加,记为M3
00467A07 DD5D F8 fstp qword ptr ss:[ebp-8]
00467A0A 9B wait
00467A0B 33C0 xor eax,eax
00467A0D 5A pop edx
00467A0E 59 pop ecx
00467A0F 59 pop ecx
00467A10 64:8910 mov dword ptr fs:[eax],edx
00467A13 68 357A4600 push KGMe.00467A35
00467A18 8D45 DC lea eax,dword ptr ss:[ebp-24]
00467A1B E8 00C9F9FF call KGMe.00404320
00467A20 8D45 E8 lea eax,dword ptr ss:[ebp-18]
00467A23 BA 02000000 mov edx,2
00467A28 E8 17C9F9FF call KGMe.00404344
00467A2D C3 retn
00467CA4 DD5D E8 fstp qword ptr ss:[ebp-18]
00467CA7 9B wait
00467CA8 8D45 D8 lea eax,dword ptr ss:[ebp-28]
00467CAB 50 push eax
00467CAC 0FB705 20BC4600 movzx eax,word ptr ds:[46BC20]
00467CB3 8945 D0 mov dword ptr ss:[ebp-30],eax
00467CB6 C645 D4 00 mov byte ptr ss:[ebp-2C],0
00467CBA 8D55 D0 lea edx,dword ptr ss:[ebp-30]
00467CBD 33C9 xor ecx,ecx
00467CBF A1 08BC4600 mov eax,dword ptr ds:[46BC08]
00467CC4 E8 3313FAFF call KGMe.00408FFC ; 获取当前的系统日期
00467CC9 FF75 D8 push dword ptr ss:[ebp-28]
00467CCC FF35 04BC4600 push dword ptr ds:[46BC04]
00467CD2 8D45 CC lea eax,dword ptr ss:[ebp-34]
00467CD5 50 push eax
00467CD6 0FB705 26BC4600 movzx eax,word ptr ds:[46BC26]
00467CDD 8945 D0 mov dword ptr ss:[ebp-30],eax
00467CE0 C645 D4 00 mov byte ptr ss:[ebp-2C],0
00467CE4 8D55 D0 lea edx,dword ptr ss:[ebp-30]
00467CE7 33C9 xor ecx,ecx
00467CE9 A1 08BC4600 mov eax,dword ptr ds:[46BC08]
00467CEE E8 0913FAFF call KGMe.00408FFC
00467CF3 FF75 CC push dword ptr ss:[ebp-34]
00467CF6 8D45 DC lea eax,dword ptr ss:[ebp-24]
00467CF9 BA 03000000 mov edx,3
00467CFE <K> E8 9DC9F9FF call KGMe.004046A0 ; ->System.@LStrCatN;
00467D03 8B45 DC mov eax,dword ptr ss:[ebp-24]
00467D06 <K> E8 851AFAFF call KGMe.00409790 ; ->SysUtils.StrToFloat(AnsiString):Extended;overload;转换为浮点数
00467D0B DC6D F0 fsubr qword ptr ss:[ebp-10] ; 注册码减去当前的系统日期,记为M4
00467D0E DB7D C0 fstp tbyte ptr ss:[ebp-40]
00467D11 9B wait
00467D12 DD45 E8 fld qword ptr ss:[ebp-18]
00467D15 <K> E8 92AFF9FF call KGMe.00402CAC ; ->System.@TRUNC;
00467D1A 8945 D0 mov dword ptr ss:[ebp-30],eax
00467D1D 8955 D4 mov dword ptr ss:[ebp-2C],edx
00467D20 DF6D D0 fild qword ptr ss:[ebp-30]
00467D23 DB6D C0 fld tbyte ptr ss:[ebp-40]
00467D26 DED9 fcompp ; M3和M4比较,两者要相等
00467D28 DFE0 fstsw ax
00467D2A 9E sahf
00467D2B 74 0E je short KGMe.00467D3B
至此我们已经分析出了这个crackme的算法,我们来总结一下如何得出注册码,首先机器码减去9527,然后除以139,同昨天的系统日期相加,最后还要加上今天的系统日期,这个
就是最终的注册码了。不过到现在我们还有一点不清楚,就是这个crackme的机器码是如何得来的呢?我们在它的FORMCREATE事件这里设置断点来看一下。从DEDE的分析可知,断点
应该下在467DA0。断下以后我们F8单步走,走到467E90这里的CALL,我们F7跟进去看一下。
00468094 53 push ebx
00468095 81C4 F4FDFFFF add esp,-20C
0046809B 8BD8 mov ebx,eax
0046809D 68 00010000 push 100
004680A2 8D8424 10010000 lea eax,dword ptr ss:[esp+110]
004680A9 50 push eax
004680AA 8D4424 10 lea eax,dword ptr ss:[esp+10]
004680AE 50 push eax
004680AF 8D4424 10 lea eax,dword ptr ss:[esp+10]
004680B3 50 push eax
004680B4 8D4424 10 lea eax,dword ptr ss:[esp+10]
004680B8 50 push eax
004680B9 68 00010000 push 100
004680BE 8D4424 24 lea eax,dword ptr ss:[esp+24]
004680C2 50 push eax
004680C3 A1 1CBC4600 mov eax,dword ptr ds:[46BC1C]
004680C8 50 push eax
004680C9 E8 06E4F9FF call <jmp.&kernel32.GetVolumeInformationA>
此时堆栈的内容是这样的:
0012FB94 00972700 |RootPathName = "c:\"
0012FB98 0012FBC0 |VolumeNameBuffer = 0012FBC0
0012FB9C 00000100 |MaxVolumeNameSize = 100 (256.)
0012FBA0 0012FBB4 |pVolumeSerialNumber = 0012FBB4
0012FBA4 0012FBB8 |pMaxFilenameLength = 0012FBB8
0012FBA8 0012FBBC |pFileSystemFlags = 0012FBBC
0012FBAC 0012FCC0 |pFileSystemNameBuffer = 0012FCC0
0012FBB0 00000100 \pFileSystemNameSize = 00000100
这里我们可以看到crackme调用了GetVolumeInoformation这个API函数,返回了c盘的卷序列号,这个序列号转为十进制就是机器码了。我们可以在cmd中切换到c盘,然后输入label
命令就可以看到了。分析到这里,我想这个crackme的算法流程我们已经搞清楚了,最后我用python写了一个注册机(第一次用python写东西,写的不好,希望大侠们见谅),源代
码如下:
# -*- coding: cp936 -*-
import time
import os
import win32api
d=win32api.GetVolumeInformation('C:')
machinecode=d[1]
print ("您的机器码为:%d" % machinecode)
a=time.localtime()
if a[1]<10:
b=int(str(a[0])+ str(a[1]).zfill(2) + str(a[2]))
else:
b=int(str(a[0]) + str(a[1]) + str(a[2]))
regcode=(((machinecode-9527) / 139) + (b-1)) + b
print ("您的注册码是:%d" % regcode)
os.system("pause") |
|