44018723 发表于 2014-6-26 22:32

[反汇编练习] 160个CrackMe之019

[反汇编练习] 160个CrackMe之018.本系列文章的目的是从一个没有任何经验的新手的角度(其实就是我自己),一步步尝试将160个CrackMe全部破解,如果可以,通过任何方式写出一个类似于注册机的东西。其中,文章中按照如下逻辑编排(解决如下问题):1、使用什么环境和工具2、程序分析3、思路分析和破解流程4、注册机的探索----------------------------------提醒各位看客: 如果文章中的逻辑看不明白,那你一定是没有亲手操刀!OD中的跳转提示很强大,只要你跟踪了,不用怎么看代码就理解了!----------------------------------1、工具和环境:WinXP SP3 + 52Pojie六周年纪念版OD + PEID + 汇编金手指。160个CrackMe的打包文件。下载地址: http://pan.baidu.com/s/1xUWOY密码: jbnq注:1、Win7系统对于模块和程序开启了随机初始地址的功能,会给分析带来很大的负担,所以不建议使用Win7进行分析。2、以上工具都是在52PoJie论坛下的原版程序,NOD32不报毒,个人承诺绝对不会进行任何和木马病毒相关内容。http://images.cnitblog.com/blog/573547/201406/152219166701903.png 2、程序分析:想要破解一个程序,必须先了解这个程序。所以,在破解过程中,对最初程序的分析很重要,他可以帮助我们理解作者的目的和意图,特别是对于注册码的处理细节,从而方便我们反向跟踪和推导。和上一节一样,打开CHM,选择第19个Brad Soblesky.2.exe,保存下来。运行程序,程序界面如下:http://images.cnitblog.com/blog/573547/201406/262134032167035.png3、思路分析和破解流程又见信息框,哈哈哈!PEID查看: Microsoft Visual C++ 6.0和以前的一样,直接上步骤:1、打开OD,将exe拖到OD窗口中,等程序暂停后,直接点击运行按钮(F9),不用理会。2、在exe中输入伪码:bbdxf   123123。点击OK按钮,弹出错误信息框,不要关闭。3、在OD中点击暂停按钮(Ctrl+F12),再点击堆栈K按钮(Ctrl+K),可以看到当前堆栈情况。

和上一个一模一样,右键->show call。4、反汇编窗口看到如下信息:00401618|.^\EB AD         \jmp short 004015C7
0040161A|>8B45 F0       mov eax,
0040161D|.50            push eax
0040161E|.68 54404000   push 00404054                            ;ASCII "%lu"
00401623|.8D4D DC       lea ecx,
00401626|.51            push ecx
00401627|.E8 52070000   call <jmp.&MFC42.#2818>
0040162C|.83C4 0C       add esp,0xC
0040162F|.8D4D DC       lea ecx,
00401632|.E8 79020000   call 004018B0
00401637|.50            push eax                                 ; /Arg1
00401638|.8D4D E8       lea ecx,                        ; |
0040163B|.E8 80020000   call 004018C0                            ; \Brad_Sob.004018C0
00401640|.85C0          test eax,eax
00401642|.0F85 FF000000 jnz 00401747
00401648|.8D8D ACFEFFFF lea ecx,
0040164E|.E8 19070000   call <jmp.&MFC42.#540>
00401653|.C645 FC 03    mov byte ptr ss:,0x3
00401657|.6A 66         push 0x66
00401659|.8D8D ACFEFFFF lea ecx,
0040165F|.E8 02070000   call <jmp.&MFC42.#4160>
00401664|.B9 07000000   mov ecx,0x7
00401669|.BE 58404000   mov esi,00404058                         ;ASCII "Correct!!                     "
0040166E|.8DBD 48FEFFFF lea edi,
00401674|.F3:A5         rep movs dword ptr es:,dword ptr ds>
00401676|.66:A5         movs word ptr es:,word ptr ds:
00401678|.A4            movs byte ptr es:,byte ptr ds:
00401679|.B9 11000000   mov ecx,0x11
0040167E|.33C0          xor eax,eax
00401680|.8DBD 67FEFFFF lea edi,dword ptr ss:
00401686|.F3:AB         rep stos dword ptr es:
00401688|.AA            stos byte ptr es:
00401689|.B9 07000000   mov ecx,0x7
0040168E|.BE 78404000   mov esi,00404078                         ;ASCII "<BrD-SoB>                  "
00401693|.8DBD 14FFFFFF lea edi,
00401699|.F3:A5         rep movs dword ptr es:,dword ptr ds>
0040169B|.66:A5         movs word ptr es:,word ptr ds:
0040169D|.B9 11000000   mov ecx,0x11
004016A2|.33C0          xor eax,eax
004016A4|.8DBD 32FFFFFF lea edi,dword ptr ss:
004016AA|.F3:AB         rep stos dword ptr es:
004016AC|.66:AB         stos word ptr es:
004016AE|.B9 06000000   mov ecx,0x6
004016B3|.BE 98404000   mov esi,00404098                         ;ASCII "Incorrect!!, Try Again."
004016B8|.8DBD 78FFFFFF lea edi,
004016BE|.F3:A5         rep movs dword ptr es:,dword ptr ds>
004016C0|.B9 13000000   mov ecx,0x13
004016C5|.33C0          xor eax,eax
004016C7|.8D7D 90       lea edi,
004016CA|.F3:AB         rep stos dword ptr es:
004016CC|.B9 07000000   mov ecx,0x7
004016D1|.BE B0404000   mov esi,004040B0                         ;ASCII "Correct way to go, You Got It."
004016D6|.8DBD B0FEFFFF lea edi,
004016DC|.F3:A5         rep movs dword ptr es:,dword ptr ds>
004016DE|.66:A5         movs word ptr es:,word ptr ds:
004016E0|.A4            movs byte ptr es:,byte ptr ds:
004016E1|.B9 11000000   mov ecx,0x11
004016E6|.33C0          xor eax,eax
004016E8|.8DBD CFFEFFFF lea edi,dword ptr ss:
004016EE|.F3:AB         rep stos dword ptr es:
004016F0|.AA            stos byte ptr es:
004016F1|.6A 40         push 0x40
004016F3|.68 D0404000   push 004040D0                            ;ASCII "CrackMe"
004016F8|.8D8D ACFEFFFF lea ecx,
004016FE|.E8 AD010000   call 004018B0
00401703|.50            push eax
00401704|.8B8D 40FEFFFF mov ecx,
0040170A|.E8 75060000   call <jmp.&MFC42.#4224>
0040170F|.C645 FC 02    mov byte ptr ss:,0x2
00401713|.8D8D ACFEFFFF lea ecx,
00401719|.E8 42060000   call <jmp.&MFC42.#800>
0040171E|.C645 FC 01    mov byte ptr ss:,0x1
00401722|.8D4D DC       lea ecx,
00401725|.E8 36060000   call <jmp.&MFC42.#800>
0040172A|.C645 FC 00    mov byte ptr ss:,0x0
0040172E|.8D4D E8       lea ecx,
00401731|.E8 2A060000   call <jmp.&MFC42.#800>
00401736|.C745 FC FFFFF>mov ,-0x1
0040173D|.8D4D EC       lea ecx,
00401740|.E8 1B060000   call <jmp.&MFC42.#800>
00401745|.EB 70         jmp short 004017B7
00401747|>8D8D 44FEFFFF lea ecx,
0040174D|.E8 1A060000   call <jmp.&MFC42.#540>
00401752|.C645 FC 04    mov byte ptr ss:,0x4
00401756|.6A 67         push 0x67
00401758|.8D8D 44FEFFFF lea ecx,
0040175E|.E8 03060000   call <jmp.&MFC42.#4160>
00401763|.6A 40         push 0x40
00401765|.68 D8404000   push 004040D8                            ;ASCII "CrackMe"
0040176A|.8D8D 44FEFFFF lea ecx,
00401770|.E8 3B010000   call 004018B0
00401775|.50            push eax
00401776|.8B8D 40FEFFFF mov ecx,
0040177C|.E8 03060000   call <jmp.&MFC42.#4224>
向上查找,很容易地找到了一个跳转 jnz 00401747 ,逻辑上很难明白到底对不对,但是我们可以试试,选中它,右键->Binary->Fill with Nops。回到exe,试试,哈哈!http://images.cnitblog.com/blog/573547/201406/262134068418909.png
4、注册机的探索我们已经知道了关键跳转,那他的附近肯定有判断条件,刚好,他的上面有一个call,我们跟进去看看,F8只到返回:004018C0/$55            push ebp
004018C1|.8BEC          mov ebp,esp
004018C3|.51            push ecx
004018C4|.894D FC       mov ,ecx
004018C7|.8B45 08       mov eax,
004018CA|.50            push eax                                 ; /Arg2
004018CB|.8B4D FC       mov ecx,                        ; |
004018CE|.8B11          mov edx,dword ptr ds:               ; |
004018D0|.52            push edx                                 ; |Arg1
004018D1|.E8 0A000000   call 004018E0                            ; \Brad_Sob.004018E0
004018D6|.83C4 08       add esp,0x8
004018D9|.8BE5          mov esp,ebp
004018DB|.5D            pop ebp
004018DC\.C2 0400       retn 0x4
004018DF      CC            int3
004018E0/$55            push ebp                                 ;// 上面的函数跳到这里
004018E1|.8BEC          mov ebp,esp
004018E3|.8B45 0C       mov eax,
004018E6|.50            push eax                                 ; /s2 = "3524958250"
004018E7|.8B4D 08       mov ecx,                        ; |
004018EA|.51            push ecx                                 ; |s1 = "123123"
004018EB|.FF15 B4314000 call dword ptr ds:[<&MSVCRT._mbscmp>]    ; \_mbscmp
004018F1|.83C4 08       add esp,0x8
004018F4|.5D            pop ebp
004018F5\.C3            retn
很容易看出,这个Call就是用来比较两个字符串的。5、返回关键跳转附近代码,向上查看与算法相关东西:004014E4|.68 8F204000   push 0040208F                            ;SE handler installation
004014E9|.64:A1 0000000>mov eax,dword ptr fs:
004014EF|.50            push eax
004014F0|.64:8925 00000>mov dword ptr fs:,esp
004014F7|.81EC B4010000 sub esp,0x1B4
004014FD|.56            push esi
004014FE|.57            push edi
004014FF|.898D 40FEFFFF mov ,ecx
00401505|.C745 F0 45632>mov ,0x81276345               ;// 常量在这里赋值
0040150C|.68 AC414000   push 004041AC
00401511|.8D4D EC       lea ecx,
00401514|.E8 77080000   call <jmp.&MFC42.#537>
00401519|.C745 FC 00000>mov ,0x0
00401520|.68 B0414000   push 004041B0
00401525|.8D4D E8       lea ecx,
00401528|.E8 63080000   call <jmp.&MFC42.#537>
0040152D|.C645 FC 01    mov byte ptr ss:,0x1
00401531|.68 B4414000   push 004041B4
00401536|.8D4D DC       lea ecx,
00401539|.E8 52080000   call <jmp.&MFC42.#537>
0040153E|.C645 FC 02    mov byte ptr ss:,0x2
00401542|.8D45 EC       lea eax,
00401545|.50            push eax
00401546|.68 E8030000   push 0x3E8
0040154B|.8B8D 40FEFFFF mov ecx,
00401551|.E8 34080000   call <jmp.&MFC42.#3097>
00401556|.8D4D E8       lea ecx,
00401559|.51            push ecx
0040155A|.68 E9030000   push 0x3E9
0040155F|.8B8D 40FEFFFF mov ecx,
00401565|.E8 20080000   call <jmp.&MFC42.#3097>
0040156A|.8D4D EC       lea ecx,
0040156D|.E8 DE020000   call 00401850
00401572|.8945 E4       mov ,eax
00401575|.837D E4 05    cmp ,0x5                        ;// name 的长度比较
00401579|. /7D 43         jge short 004015BE
0040157B|. |6A 40         push 0x40
0040157D|. |68 20404000   push 00404020                            ;ASCII "CrackMe"
00401582|. |68 28404000   push 00404028                            ;ASCII "User Name must have at least 5 characters."
00401587|. |8B8D 40FEFFFF mov ecx,
0040158D|. |E8 F2070000   call <jmp.&MFC42.#4224>
00401592|. |C645 FC 01    mov byte ptr ss:,0x1
00401596|. |8D4D DC       lea ecx,
00401599|. |E8 C2070000   call <jmp.&MFC42.#800>
0040159E|. |C645 FC 00    mov byte ptr ss:,0x0
004015A2|. |8D4D E8       lea ecx,
004015A5|. |E8 B6070000   call <jmp.&MFC42.#800>
004015AA|. |C745 FC FFFFF>mov ,-0x1
004015B1|. |8D4D EC       lea ecx,
004015B4|. |E8 A7070000   call <jmp.&MFC42.#800>
004015B9|. |E9 F9010000   jmp 004017B7
004015BE|> \C745 E0 00000>mov ,0x0
004015C5|.EB 09         jmp short 004015D0
004015C7|>8B55 E0       /mov edx,
004015CA|.83C2 01       |add edx,0x1
004015CD|.8955 E0       |mov ,edx
004015D0|>8B45 E0      mov eax,
004015D3|.3B45 E4       |cmp eax,
004015D6|.7D 42         |jge short 0040161A
004015D8|.8B4D E0       |mov ecx,
004015DB|.51            |push ecx                              ; /Arg1
004015DC|.8D4D EC       |lea ecx,                     ; |
004015DF|.E8 1C030000   |call 00401900                           ; \Brad_Sob.00401900
004015E4|.0FBED0      |movsx edx,al
004015E7|.8B45 F0       |mov eax,
004015EA|.03C2          |add eax,edx
004015EC|.8945 F0       |mov ,eax
004015EF|.8B4D E0       |mov ecx,
004015F2|.C1E1 08       |shl ecx,0x8
004015F5|.8B55 F0       |mov edx,
004015F8|.33D1          |xor edx,ecx
004015FA|.8955 F0       |mov ,edx
004015FD|.8B45 E0       |mov eax,
00401600|.83C0 01       |add eax,0x1
00401603|.8B4D E4       |mov ecx,
00401606|.0FAF4D E0   |imul ecx,
0040160A|.F7D1          |not ecx
0040160C|.0FAFC1      |imul eax,ecx
0040160F|.8B55 F0       |mov edx,
00401612|.0FAFD0      |imul edx,eax
00401615|.8955 F0       |mov ,edx
00401618|.^ EB AD         \jmp short 004015C7
0040161A|>8B45 F0       mov eax,
0040161D|.50            push eax
0040161E|.68 54404000   push 00404054                            ;ASCII "%lu"
00401623|.8D4D DC       lea ecx,
00401626|.51            push ecx
00401627|.E8 52070000   call <jmp.&MFC42.#2818>
0040162C|.83C4 0C       add esp,0xC
0040162F|.8D4D DC       lea ecx,
00401632|.E8 79020000   call 004018B0                            ;// 字符串比较,它的返回值是eax
00401637|.50            push eax                                 ; /Arg1 = ASCII "3524958250"
00401638|.8D4D E8       lea ecx,                        ; |
0040163B|.E8 80020000   call 004018C0                            ; \Brad_Sob.004018C0
00401640|.85C0          test eax,eax
00401642|.0F85 FF000000 jnz 00401747                           ;// 关键跳转
在这里面有一个大的循环,应该就是处理算法部分,并且对于Name部分,他还有长度判断:0040157B|.6A 40         push 0x40
0040157D|.68 20404000   push 00404020                            ;ASCII "CrackMe"
00401582|.68 28404000   push 00404028                            ;ASCII "User Name must have at least 5 characters."
00401587|.8B8D 40FEFFFF mov ecx,
0040158D|.E8 F2070000   call <jmp.&MFC42.#4224>
至少5个字符。算法循环处理部分分析如下:004015B9|. /E9 F9010000   jmp 004017B7
004015BE|> |C745 E0 00000>mov ,0x0                        ;// 开始处理
004015C5|. |EB 09         jmp short 004015D0
004015C7|> |8B55 E0       /mov edx,
004015CA|. |83C2 01       |add edx,0x1                           ;// 序号+1
004015CD|. |8955 E0       |mov ,edx
004015D0|> |8B45 E0      mov eax,                     ;// 初始值为0
004015D3|. |3B45 E4       |cmp eax,                     ;与Name的长度比较
004015D6|. |7D 42         |jge short 0040161A
004015D8|. |8B4D E0       |mov ecx,
004015DB|. |51            |push ecx                              ; /Arg1 = ASCII "bbdxf"
004015DC|. |8D4D EC       |lea ecx,                     ; |
004015DF|. |E8 1C030000   |call 00401900                           ; \Brad_Sob.00401900
004015E4|. |0FBED0      |movsx edx,al                            ;// 取第一个字符的ANSII值,放在al中
004015E7|. |8B45 F0       |mov eax,                     ;// 这是一个常量
004015EA|. |03C2          |add eax,edx
004015EC|. |8945 F0       |mov ,eax                     ;// eax = 812763A7; 然后又存进去
004015EF|. |8B4D E0       |mov ecx,                     ;// 序号,初值0
004015F2|. |C1E1 08       |shl ecx,0x8                           ;// 左移8位
004015F5|. |8B55 F0       |mov edx,
004015F8|. |33D1          |xor edx,ecx                           ;// 异或
004015FA|. |8955 F0       |mov ,edx                     ;// 存进去
004015FD|. |8B45 E0       |mov eax,
00401600|. |83C0 01       |add eax,0x1                           ;// 序号+1
00401603|. |8B4D E4       |mov ecx,                     ;// Name长度
00401606|. |0FAF4D E0   |imul ecx,                      ;// 带符号乘法,Name长度*序号
0040160A|. |F7D1          |not ecx                                 ;// 取反
0040160C|. |0FAFC1      |imul eax,ecx                            ;// 序号*ecx
0040160F|. |8B55 F0       |mov edx,                     ;// 取出来
00401612|. |0FAFD0      |imul edx,eax                            ;// 与刚才的结果相乘
00401615|. |8955 F0       |mov ,edx                     ;// 存进去
00401618|.^|EB AD         \jmp short 004015C7
0040161A|> |8B45 F0       mov eax,
0040161D|. |50            push eax                                 ;eax=D21A982A
0040161E|. |68 54404000   push 00404054                            ;ASCII "%lu"
00401623|. |8D4D DC       lea ecx,
00401626|. |51            push ecx
00401627|. |E8 52070000   call <jmp.&MFC42.#2818>                  ;// 格式化字符串
0040162C|. |83C4 0C       add esp,0xC
0040162F|. |8D4D DC       lea ecx,
00401632|. |E8 79020000   call 004018B0                            ;// 字符串比较,它的返回值是eax
00401637|. |50            push eax                                 ; /Arg1 = ASCII "3524958250"
00401638|. |8D4D E8       lea ecx,                        ; |
0040163B|. |E8 80020000   call 004018C0                            ; \Brad_Sob.004018C0
00401640|. |85C0          test eax,eax
00401642|. |0F85 FF000000 jnz 00401747                           ;// 关键跳转
大概的流程是:。。。直接看C++代码吧,我也说不清楚:// CrackMeDemo.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "iostream"

int _tmain(int argc, _TCHAR* argv[])
{
    char Name = "bbdxf";
    char key = {0};
    int nLen = strlen(Name);
    int uStart = 0x81276345;
    for (int i=0;i<nLen;i++)
    {
      uStart += Name;
      uStart = uStart ^ (i<<8);
      uStart *= (i+1)*(~(nLen*i));

    }
    printf("hex: %X\r\n",uStart);
    printf("Key: %lu\r\n",uStart);
    system("pause");
    return 0;
}
http://images.cnitblog.com/blog/573547/201406/262134098416426.png
BY笨笨D幸福

hukai007 发表于 2014-6-27 15:23

楼主要多学点底层的东西

安之 发表于 2014-6-26 23:09

谢谢分享,学习中

cqcbc 发表于 2014-6-26 23:00

不错的资料,谢谢楼主共享,学习一下。

44018723 发表于 2014-6-26 22:34

{:17_1086:}论坛太喜欢抽筋了,这个星期我知道的都3次了

44018723 发表于 2014-6-27 15:27

hukai007 发表于 2014-6-27 15:23
楼主要多学点底层的东西

{:301_992:}亲,给点详细的建议吧!!

shuguang 发表于 2014-7-18 08:38

我用delpi 7 写了一下注册机,
procedure TForm1.Button1Click(Sender: TObject);
var name,key:string;
    i,j,temp1,temp2,temp3,temp4:integer;
begin
name:=edit1.Text;
temp4:=81276345;
for i:=0 to length(name)-1 do
begin
temp1:= ord(name)+ temp4;
temp2:= i shl 8;
temp3:= temp1 xor temp2;
temp1:=length(name) * i;
temp1:= not temp1;
temp2:= temp1 * (i+1);
temp4:= temp3 * temp2;
end;
edit2.Text:=inttostr(temp4);
end;

为什么结果是有符号的,让结果转化成无符号的怎么做。
十六进制      BFE27B98
十进制有符号 -1075676264
十进制有符号 3219291032

vk929495v 发表于 2014-7-19 12:58

vk929495v 发表于 2014-7-22 21:57

p1114501510 发表于 2014-7-25 09:56

果断学习到了 大家一起共同进步啊
页: [1] 2
查看完整版本: [反汇编练习] 160个CrackMe之019