【文章标题】: 一个挺有创意的crackme算法分析+注册机
【文章作者】: 壹只老虎
【作者邮箱】: tiger..tiger@163.com
【作者QQ号】: 609841314
【软件名称】: step4.exe
【软件大小】: 31kb
【下载地址】: 自己搜索下载
【加壳方式】: ASPack 1.06b / 1.061b
【保护方式】: ASPack 1.06b / 1.061b
【编写语言】: Borland C++ 1999
【使用工具】: peid+od+windows计算器
【操作平台】: xp
【软件介绍】: 五个crackme中的第四个,算法分析,写的有点特别!
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
先说明一下,本人破解经验不多,所以才会觉得这个crackme有点创意,高手见笑了!呵呵!
前几天就分析好了,今天写个破文拿出来共享一下,请大家多多指教!呵呵!
再介绍一下这个Crackme的特点:点击运行后,首先弹出提示框,"step4 has not been solved",然后打开一个窗口,
上面有一个关闭按钮!其他什么也没有了!嘿嘿!是不是有点特别呢!我开始的时候也不知道怎么办!嘿嘿!看我一步一步分析!
不是很难!倒是有点意思的!
1:peid查壳-->ASPack 1.06b / 1.061b,好说,我还是写的详细点,以便新手看得明白点!
这个壳算是初级壳把!看看我们怎么脱壳!首先od载入,会异常的!然后确定!shift+f9过去,然后选择否!
好了,开始分析!f8四次,在esp上下硬件访问断点, f9一次,f8一次,选择不重建输入表的方式脱壳!保存为3.exe,
打开LoarPE,点击"PE编辑器",选择未脱壳的文件,修改入口点地址为3.EXE的入口地址(1000),"确定","重建PE",
选择 3.EXE,确定,ok,修复成功!!
2:好了,修复好了,我们现在运行下看看,点击运行后,首先弹出提示框,"step4 has not been solved",然后打开一个窗口,
上面有一个关闭按钮!其他什么也没有了!郁闷哦,什么都没有哦!有个输入框也好啊!现在什么也没有!晕了!
3:好了想想把!的确有点特别哦!没遇见过!在想想!刚才什么也没输入就来个错误提示!嘿嘿!是不是想到什么了呢!
对!文件或者注册表!嘿嘿!不过!先别忙去注册表监视!因为现在没用的!呵呵!为什么了!看后面就知道了!
4:既然想到了注册表,不管3721,也不知道对不对,先试试再说吧!od载入脱壳后的程序!先看看有没有敏感的字符串把!嘿嘿!
字符串参考,看到了这个,嘿嘿!"Step4 has not been solved",双击来到这里看看!
主函数模块
00401150 /$ 55 push ebp
00401151 |. 8BEC mov ebp,esp
00401153 |. 53 push ebx
00401154 |. 8B5D 08 mov ebx,dword ptr ss:[ebp+8]
00401157 |. 6A 19 push 19 ; /Arg3 = 00000019
00401159 |. 6A 30 push 30 ; |Arg2 = 00000030
0040115B |. 68 F4C54000 push 43.0040C5F4 ; |Arg1 = 0040C5F4 ASCII "12345678"
00401160 |. E8 3B120000 call 43.004023A0 ; \43.004023A0
00401165 |. 83C4 0C add esp,0C
00401168 |. 6A 19 push 19 ; /Arg3 = 00000019
0040116A |. 6A 30 push 30 ; |Arg2 = 00000030
0040116C |. 68 0DC64000 push 43.0040C60D ; |Arg1 = 0040C60D ASCII "admin"
00401171 |. E8 2A120000 call 43.004023A0 ; \43.004023A0
00401176 |. 83C4 0C add esp,0C
00401179 |. E8 0A010000 call 43.00401288 ; 这里很关键,跟进去看看!
0040117E |. A3 30C64000 mov dword ptr ds:[40C630],eax
00401183 |. E8 CC000000 call 43.00401254 ; 这里也要根进去!里面有算法!
00401188 |. A3 4CA14000 mov dword ptr ds:[40A14C],eax ; 注册名运算后的数据-->0040a14c
0040118D |. A1 30C64000 mov eax,dword ptr ds:[40C630] ; 注册码数据送eax
00401192 |. 3B05 4CA14000 cmp eax,dword ptr ds:[40A14C] ; 关键比较
00401198 75 18 jnz short 43.004011B2 ; 关键跳转,跳向失败
0040119A |. 68 30000400 push 40030 ; /Style = MB_OK|MB_ICONEXCLAMATION|MB_APPLMODAL|40000
0040119F |. 68 9DA14000 push 43.0040A19D ; |Title = "You Did It!"
004011A4 |. 68 54A14000 push 43.0040A154 ; |Text = "Congradulations, you have figured out Step4
Step4 unlock code is: 6DEWS3"
004011A9 |. 53 push ebx ; |hOwner
004011AA |. E8 E37E0000 call 43.00409092 ; \MessageBoxA
004011AF |. 5B pop ebx
004011B0 |. 5D pop ebp
004011B1 |. C3 retn ; 下面就错误了
004011B2 |> 68 30000400 push 40030 ; /Style = MB_OK|MB_ICONEXCLAMATION|MB_APPLMODAL|40000
004011B7 |. 68 C3A14000 push 43.0040A1C3 ; |Title = "Not Done"
004011BC |. 68 A9A14000 push 43.0040A1A9 ; |Text = "Step4 has not been solved"
004011C1 |. 53 push ebx ; |hOwner
004011C2 |. E8 CB7E0000 call 43.00409092 ; \MessageBoxA
004011C7 |. 5B pop ebx
004011C8 |. 5D pop ebp
004011C9 \. C3 retn
好吧!不管!现在我们现在这里下个断点再说!嘿嘿!
00401150 /$ 55 push ebp
f9运行起来了!嘿嘿!没有探出对话框,断下来了!
开始单步分析把!
前面我都写了注释了!heihei!
下面我跟进
00401179 |. E8 0A010000 call 43.00401288
这个call要根近来看看的!很重要的!
00401288 /$ 55 push ebp
00401289 |. 8BEC mov ebp,esp
0040128B |. 53 push ebx
0040128C |. 56 push esi
0040128D |. 57 push edi
0040128E |. BB 28C64000 mov ebx,43.0040C628
00401293 |. BE 0DC64000 mov esi,43.0040C60D ; ASCII "0000000000000000000000000"
00401298 |. BF 4CA14000 mov edi,43.0040A14C
0040129D |. 68 34C64000 push 43.0040C634 ; /pHandle = 43.0040C634
004012A2 |. 68 19000200 push 20019 ; |Access = KEY_READ
004012A7 |. 6A 00 push 0 ; |Reserved = 0
004012A9 |. 68 E6A14000 push 43.0040A1E6 ; |Subkey = "Software\Step4"
004012AE |. 68 02000080 push 80000002 ; |hKey = HKEY_LOCAL_MACHINE
004012B3 |. E8 B67C0000 call 43.00408F6E ; \RegOpenKeyExA
004012B8 |. 68 50A14000 push 43.0040A150 ; /pBufSize = 43.0040A150
004012BD |. 68 F4C54000 push 43.0040C5F4 ; |Buffer = 43.0040C5F4
004012C2 |. 68 2CC64000 push 43.0040C62C ; |pValueType = 43.0040C62C
004012C7 |. 6A 00 push 0 ; |Reserved = NULL
004012C9 |. 68 F5A14000 push 43.0040A1F5 ; |ValueName = "Serial"
004012CE |. FF35 34C64000 push dword ptr ds:[40C634] ; |hKey = 0
004012D4 |. E8 9B7C0000 call 43.00408F74 ; \RegQueryValueExA
004012D9 |. 68 50A14000 push 43.0040A150 ; /pBufSize = 43.0040A150
004012DE |. 56 push esi ; |Buffer => 43.0040C60D
004012DF |. 68 2CC64000 push 43.0040C62C ; |pValueType = 43.0040C62C
004012E4 |. 6A 00 push 0 ; |Reserved = NULL
004012E6 |. 68 FCA14000 push 43.0040A1FC ; |ValueName = "Name"
004012EB |. FF35 34C64000 push dword ptr ds:[40C634] ; |hKey = 0
004012F1 |. E8 7E7C0000 call 43.00408F74 ; \RegQueryValueExA
004012F6 |. FF35 34C64000 push dword ptr ds:[40C634] ; /hKey = NULL
004012FC |. E8 677C0000 call 43.00408F68 ; \RegCloseKey
00401301 |. 68 F4C54000 push 43.0040C5F4 ; /Arg1 = 0040C5F4 ASCII "00000000000000000000000000000000000000000000000000"
00401306 |. E8 CD2E0000 call 43.004041D8 ; \43.004041D8
0040130B |. 59 pop ecx ; ecx=注册码字符串,esi=注册名字符串
0040130C |. A3 30C64000 mov dword ptr ds:[40C630],eax ; eax=edx=注册码数据
00401311 |. 33C0 xor eax,eax ; eax=0
00401313 |. 8903 mov dword ptr ds:[ebx],eax
00401315 |. EB 13 jmp short 43.0040132A
00401317 |> 8B13 /mov edx,dword ptr ds:[ebx]
00401319 |. 33C9 |xor ecx,ecx ; ecx=0
0040131B |. 8A0C16 |mov cl,byte ptr ds:[esi+edx] ; cl=按位取注册名数据的ascii码
0040131E |. 010F |add dword ptr ds:[edi],ecx ; ecx=[0040a14c]+ecx
00401320 |. 6907 77070000 |imul eax,dword ptr ds:[edi],777 ; eax=ecx*1911
00401326 |. 8907 |mov dword ptr ds:[edi],eax ; eax-->0040a14c
00401328 |. FF03 |inc dword ptr ds:[ebx]
0040132A |> 56 push esi
0040132B |. E8 50110000 |call 43.00402480 ; eax=注册名长度(<=10时)(>10时为25)
00401330 |. 59 |pop ecx ; ecx=注册名字符串
00401331 |. 3B03 |cmp eax,dword ptr ds:[ebx] ; 循环次数为eax
00401333 |.^ 77 E2 \ja short 43.00401317 ; >就跳
00401335 |. A1 30C64000 mov eax,dword ptr ds:[40C630] ; eax=注册码数据
0040133A |. 5F pop edi ; 注意:0040a14c保存了注册名计算后的数据
0040133B |. 5E pop esi
0040133C |. 5B pop ebx
0040133D |. 5D pop ebp
0040133E \. C3 retn
好了,进来了!我们看到什么了!仔细看看下面一段
004012A9 |. 68 E6A14000 push 43.0040A1E6 ; |Subkey = "Software\Step4"
004012AE |. 68 02000080 push 80000002 ; |hKey = HKEY_LOCAL_MACHINE
004012B3 |. E8 B67C0000 call 43.00408F6E ; \RegOpenKeyExA
004012B8 |. 68 50A14000 push 43.0040A150 ; /pBufSize = 43.0040A150
004012BD |. 68 F4C54000 push 43.0040C5F4 ; |Buffer = 43.0040C5F4
004012C2 |. 68 2CC64000 push 43.0040C62C ; |pValueType = 43.0040C62C
004012C7 |. 6A 00 push 0 ; |Reserved = NULL
004012C9 |. 68 F5A14000 push 43.0040A1F5 ; |ValueName = "Serial"
004012CE |. FF35 34C64000 push dword ptr ds:[40C634] ; |hKey = 0
004012D4 |. E8 9B7C0000 call 43.00408F74 ; \RegQueryValueExA
004012D9 |. 68 50A14000 push 43.0040A150 ; /pBufSize = 43.0040A150
004012DE |. 56 push esi ; |Buffer => 43.0040C60D
004012DF |. 68 2CC64000 push 43.0040C62C ; |pValueType = 43.0040C62C
004012E4 |. 6A 00 push 0 ; |Reserved = NULL
004012E6 |. 68 FCA14000 push 43.0040A1FC ; |ValueName = "Name"
004012EB |. FF35 34C64000 push dword ptr ds:[40C634] ; |hKey = 0
004012F1 |. E8 7E7C0000 call 43.00408F74 ; \RegQueryValueExA
004012F6 |. FF35 34C64000 push dword ptr ds:[40C634] ; /hKey = NULL
004012FC |. E8 677C0000 call 43.00408F68 ; \RegCloseKey
看见没有,这里是注册表键值啊!
位置是多少呢!嘿嘿!看了就知道!很明显是这两个!如下!
[HKEY_LOCAL_MACHINE\SOFTWARE\Step4]
"Serial"
"Name"
好了,你可以继续分析!自然会失败了!呵呵!想想啊!这里两个地方的数据是怎么产生的呢?我们从头到尾都没输如果数据阿!
好到这里就好了!好了!我们打开注册表去找找这两个键看看!我找啊!找啊!找了很久,没找到!好奇怪哦!怎么办!找不到阿!
嘿嘿!没关系!没有的话!我们就给他建一个试试看行不行!
在HKEY_LOCAL_MACHINE\SOFTWARE下面新建一个项"Step4",然后在这个项里面新建两个字符串,名字就叫"Serial"和"Name",
Name 的数据设置为tiger, Serial 数据设置为12345678,好了,关闭注册表,od重新载入脱壳后的程序,运行,断下来了!
按照上面的方法,来跟中,具体注释就看上面面的了!我都写好了!赫赫!
下面从这里分析出来后!就到达!
0040117E |. A3 30C64000 mov dword ptr ds:[40C630],eax
这里就直接过去好了!
然后又看见一个call,这里要根进去看看了,里面的算法很简单,但是也很关键!看看下面的分析
跟进
00401183 |. E8 CC000000 call 43.00401254
分析如下:
00401254 /$ 55 push ebp
00401255 |. 8BEC mov ebp,esp ; 设注册名计算后的数据为num
00401257 |. 8135 4CA14000 1063>xor dword ptr ds:[40A14C],83746310 ; num=num xor 2205442832
00401261 |. 8135 4CA14000 1ED4>xor dword ptr ds:[40A14C],54ADD41E ; num=num xor 1420678174
0040126B |. 8135 4CA14000 E9DE>xor dword ptr ds:[40A14C],ABCDDEE9 ; num=num xor 2882395881
00401275 |. 810D 4CA14000 1232>or dword ptr ds:[40A14C],12323212 ; num=num or 305279506
0040127F |. A1 4CA14000 mov eax,dword ptr ds:[40A14C] ; eax=num
00401284 |. 5D pop ebp
00401285 \. C3 retn
00401286 90 nop
00401287 90 nop
00401288 /$ 55 push ebp
这里出来马上就是关键比较了,总的说来,注册名经过n次运算后,把结果和注册码比较,相等就成功了!呵呵!
好了!就这样!下面说说注册机的编写!
5:注册机编写如下:
unit key;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, WinSkinData, jpeg, ExtCtrls;
type
TForm1 = class(TForm)
SkinData1: TSkinData;
Label1: TLabel;
Label2: TLabel;
Edit1: TEdit;
Edit2: TEdit;
Button1: TButton;
Button2: TButton;
Button3: TButton;
Image1: TImage;
Label3: TLabel;
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button2Click(Sender: TObject);
begin
Application.MessageBox('本注册机由 壹只老虎 制作!QQ:609841314','关于',MB_ICONINFORMATION+MB_OK);
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
Close;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
name:string;
code:Longword;
i:integer;
begin
name:=edit1.Text;
code:=0;
if length(name)>10 then
begin
for i:=1 to 25 do
code:=(code+48)*1911;
end
else
begin
for i:=1 to length(name) do
code:=1911*(ord(name[i])+code);
end;
code:=2205442832 xor code;
code:=code xor 1420678174;
code:=code xor 2882395881;
code:=code or 305279506;
edit2.Text:=inttostr(code);
end;
end.
好了,就这样了!欢迎大家一起交流!共同进步!
--------------------------------------------------------------------------------
【经验总结】
这个东西是挺有意思的!呵呵!这次收获不少!欢迎大家一起交流!
--------------------------------------------------------------------------------
【版权声明】: BY:壹只老虎
2006年08月28日 22:19:47
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
上传的附件: