首页
社区
课程
招聘
[原创]一个挺有创意的crackme算法分析+注册机
2006-8-28 22:34 6390

[原创]一个挺有创意的crackme算法分析+注册机

2006-8-28 22:34
6390
【文章标题】: 一个挺有创意的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

[培训]科锐软件逆向50期预科班报名即将截止,速来!!! 50期正式班报名火爆招生中!!!

上传的附件:
  • 4.rar (309.35kb,41次下载)
收藏
免费 7
打赏
分享
最新回复 (5)
雪    币: 263
活跃值: (10)
能力值: ( LV9,RANK:250 )
在线值:
发帖
回帖
粉丝
KAN 6 2006-8-28 22:45
2
0
呵呵,不错
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
周子歆 2006-8-29 17:16
3
0
值得好好地研究一下!
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
leyhom 2006-9-9 16:24
4
0
不知道我分析的对不对,先拿出来让大家看一下,有错之处还请指出

先拿四位的注册名来说
注册名第一位*777=A
注册名第二位+A=B
B*777=C
注册名第三位+C=D
D*777=E
注册名第四位+E=F
F*777=G
XOR G,83746310  引处G是注册名运算后G的值
XOR G,54ADD41E
XOR G,ABCDDEE9
OR 12323212
运算后的结果我们称做H吧

再拿试验码来说
1. 第一位+EDX=A
2. A-30=B
3. B+B=C
4. C*4+4=D
5. D+第二位=E
6. E-30=F    此处的F结果再从第三步开始算起,如F是60,从第三步算C应该是C0,一直进行循环,循环一次把第五步的位数给加一位,直至加到和试验码的位数相稳合。得出的结果我们就称做H吧
此外的H和注册名的H做比较,相等就成功,不等就失败

我分析的就是这样的不知对不对
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
greenlyy 2006-9-14 12:59
5
0
有趣,学习学习……
雪    币: 405
活跃值: (10)
能力值: ( LV9,RANK:1130 )
在线值:
发帖
回帖
粉丝
binbinbin 28 2006-9-22 10:29
6
0
晕倒中~我怎么连脱壳都没脱成功。我的OEP不是1000而是6EC8

"""在esp上下硬件访问断点, ""----这是甚么意思,具体操作??please!
游客
登录 | 注册 方可回帖
返回