[反汇编练习] 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幸福
楼主要多学点底层的东西 谢谢分享,学习中 不错的资料,谢谢楼主共享,学习一下。 {:17_1086:}论坛太喜欢抽筋了,这个星期我知道的都3次了 hukai007 发表于 2014-6-27 15:23
楼主要多学点底层的东西
{:301_992:}亲,给点详细的建议吧!! 我用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 果断学习到了 大家一起共同进步啊
页:
[1]
2