本帖最后由 海天一色001 于 2017-5-2 11:07 编辑
继续160个CrackMe中的第四个,Ckme。解压后有两个文件,一个exe文件,一个文本。看了一下文本文件,知道了没有“确定”等按键,以及注册成功会出现一幅图,可对自己破解没有什么帮助。老规矩,先查壳,无壳,Delphi编的。
先试着输入www.52pojie.cn,不行,最后两个字母输入不了,看来还有长度限制啊。再输入注册码,一长串的“1”,没有长度限制。输入完成,没有任何动静。鼠标到处动一动,有提示,鼠标进入输入框时会悬浮提示“如果注册成功,程序中会出现朱茵小姐的一幅靓照”;鼠标进入到界面中间的矩形阴影,鼠标旁边会显示“?”,同时有悬浮提示“如果注册成功,程序中会出现朱茵小姐的一幅靓照”。但是点击却没任何反应。
拖入OD中,习惯性先中文搜索,找到“注册成功”的字符串:
先试着双击进入CPU窗口,来到这里,向上查找,地址00458092处看到了一个jnz的跳,但这个跳是向上的,那就继续向上查找一下:
很快又有一个跳,地址0045803B处,jnz XCKme.004580B3,跳过了注册成功,
那么这就很可能是关键跳了,先Nop掉试试:
因为此时OD显示了程序的状态是“运行”,所以切换到CKme程序看看,仍没动静,不死心地再用鼠标点击灰色的图片框,美丽的朱茵小姐出来了!成功!爆破了赶紧保存起来!
好了,又该追码了!这次不知道要追多长时间!
因为在0045803B处跳转会跳过成功,那么注册算法肯定在这一句之前了。
向上来到段首地址00457FB8处下断,重载程序,F9运行,输入用户名和注册码,鼠标点击图片框的位置,程序断下来了:
F8单步向下:
[Asm] 纯文本查看 复制代码 00457FB8 /. 55 push ebp
00457FB9 |. 8BEC mov ebp,esp
00457FBB |. B9 04000000 mov ecx,0x4
00457FC0 |> 6A 00 /push 0x0
00457FC2 |. 6A 00 |push 0x0
00457FC4 |. 49 |dec ecx
00457FC5 |.^ 75 F9 \jnz XCKme.00457FC0 ; 循环跳4次,不知道什么意思?
00457FC7 |. 51 push ecx
00457FC8 |. 53 push ebx
00457FC9 |. 56 push esi
00457FCA |. 8BF0 mov esi,eax
00457FCC |. 33C0 xor eax,eax
00457FCE |. 55 push ebp
00457FCF |. 68 FD804500 push CKme.004580FD
00457FD4 |. 64:FF30 push dword ptr fs:[eax]
00457FD7 |. 64:8920 mov dword ptr fs:[eax],esp
00457FDA |. 33DB xor ebx,ebx
00457FDC |> 8D55 F4 /lea edx,[local.3]
00457FDF |. 8B86 D4020000 |mov eax,dword ptr ds:[esi+0x2D4]
00457FE5 |. E8 5EB3FCFF |call CKme.00423348
00457FEA |. 8B45 F4 |mov eax,[local.3] ; 取用户名
00457FED |. E8 8ABBFAFF |call CKme.00403B7C
00457FF2 |. 83C0 1E |add eax,0x1E
00457FF5 |. 8D55 F8 |lea edx,[local.2]
00457FF8 |. E8 07FBFAFF |call CKme.00407B04
00457FFD |. FF75 F8 |push [local.2] ; 42?
00458000 |. 8D55 F0 |lea edx,[local.4]
00458003 |. 8B86 D4020000 |mov eax,dword ptr ds:[esi+0x2D4]
00458009 |. E8 3AB3FCFF |call CKme.00423348
0045800E |. FF75 F0 |push [local.4] ;
00458011 |. 8D55 EC |lea edx,[local.5]
00458014 |. 8BC3 |mov eax,ebx
00458016 |. E8 E9FAFAFF |call CKme.00407B04
0045801B |. FF75 EC |push [local.5]
0045801E |. 8D45 FC |lea eax,[local.1]
00458021 |. BA 03000000 |mov edx,0x3
00458026 |. E8 11BCFAFF |call CKme.00403C3C
0045802B |. 43 |inc ebx ; ebx累加1,加到19
0045802C |. 83FB 13 |cmp ebx,0x13
0045802F |.^ 75 AB \jnz XCKme.00457FDC
00458031 |. 81BE 0C030000>cmp dword ptr ds:[esi+0x30C],0x85 ;比较真假?
0045803B 75 76 jnz XCKme.004580B3 ; 跳过成功
这一段两个循环都不知道是干什么用的,特别是下面一个,18次!
反复在这一段中查找,始终没找到怎样根据用户名计算出注册码的!!!!!只在堆栈窗口中看到了42www.52poje.18这样的字符串,难道是注册码?42和18是根据用户名算出来的吗?
先试试用户名www.52poje.,注册码42www.52poje.18,不正确!
而且比较时cmp dword ptr ds:[esi+0x30C],0x85也跟上面的循环没有关系啊!!!!!!
是不是还要在跳下面继续计算,最后才得出注册码?
思路卡死了!
不死心地向上翻着反汇编窗口的代码,忽然看到了这里的东东,有两个ascii字符串出现很可疑: "Sun Bird"和"dseloffc-012-OK"。
继续向上看看:有两个赋值语句,自动注释了刚才看到的两个字符串,还多了两个字“黑头”!
继续向上,又看到了字符串:“CKM”、“Tform1”、“Panel1Click”、“Panel1DblClick”、“KeyUp”、“chkcode”、“FormCreate”、“ Label6”、“ Panel1” Label4 Image1 Edit2 Edit1之类。根据我浅薄的编程知识,我猜测这些都是Delphi编程时使用的控件及事件名称,常用的标签Label1至6,文本编辑框Edit1和Edit2,图片等。其中的chkcode最值得怀疑,检查什么代码呢?应该是注册码吧!
但是从OD里找了好几遍,也只是在内存中找到了一个“chkcode”的名称,没有其他的地方。
实在是只从OD中找不到了,还是用一下专用的工具吧。从吾爱破解工具包中找到E2A,打开,导入Ckme.exe,在Form1上右键点击选择所有窗体,在自己认为的事件及控件前的小加号上点击,最终如图所示,记下这些事件的地址:
再回到OD中,Ctrl+G,输入00457C40,OK,来到chkcode事件的段首,先删除原来的断点,再在这里下断,F9运行,输入用户名,刚点击注册码的文本框,还没开始输入任何字符呢,程序就中断到这里了!
单步运行,走到00457CB6地址处,在信息栏中看到了如下内容!这个该不会就是注册码吧?复制下来试一试:
复制到注册码的文本框中,一点击窗体,又断下来了,F9运行一下,还是断在这里!
哦,忘了取消断点!赶紧F2切换取消断点,再F9运行,注册成功了!点击鼠标得好几下,程序太不灵敏了,是不是有什么问题啊?
在注册码中看到了“黑头SUN Bird”、“17”“dseloffc-012-OK”、“www.52pojie.”这四个字符串,其中两个是程序中内存中原有的,一个是输入的用户名,还有一个“17”好象在什么地方也见到了?这个17是怎么出来的?还得回头找一找啊。
在00457C40处下断,重新开始运行,感觉在注册码处一输入就断在段首了,说明是只要有注册码就开始判断真假码了,那么真码应该在用户名出来时就生成了。报着这个念头先运行一下,到地址00457C6F处,堆栈中存的是"黑头Sun Bird";地址00457C7F处,push [local.2] ; 堆栈中的数值是17,但不是在这里被赋值的!地址00457C82处,堆栈中存的是"dseloffc-012-OK",地址00457C96处堆栈中存着"www.52pojie.",到地址00457CB6处,堆栈中已经是生成的注册码"黑头Sun Bird17dseloffc-012-OKwww.52pojie."了。
再返回看一看到底在哪里。重新载入程序,F9运行,在用户名粘贴入“www.52pojie.”,再点击注册码的文本框,程序又断下来了。17是在00457C7F之前的,这一回要认真观察一下:
到00457C66地址处,mov esi,dword ptr ds:[ebx+0x2F8]指令的结果是esi=0xc;下一句是esi=esi+0x5=0x11,那么16进制的11转换成10进制就是17了!17的来历知道了,可是0xc(10进制的12)是从哪儿来的?以前的crackme中有用户名长度,这个是不是?数一数,还真是12个字符!!!
为了更准确些,继续试验下去:对00457C66下断,先输入12个“1”作为用户名,再随意输入注册码,断下来了!单步运行,至下图处,注册码在信息栏中已显示出来,果然是程序中固有的两个字符串与用户名的长度加上五、用户名字符串连接而成的。将这个注册码复制到程序文本框中,点击鼠标,注册成功!
再换个注册名试一试,这一次用“吾爱破解”四个汉字作为用户名试试:这一次在00457C66地址处,ds:[00951C6C]=00000008,1个汉字占两个字符的位置,所以不是4而是8了。下一句结果是8+5=13,继续向下,注册码又出来了,是“黑头Sun Bird13dseloffc-012-OK吾爱破解”:
再拷贝入文本框,运行,又是费了好大劲点了N次鼠标,注册成功!
那么生成注册码的代码如下:
[Asm] 纯文本查看 复制代码 00457C66 |. 8BB3 F8020000 mov esi,dword ptr ds:[ebx+0x2F8] ; esi=0xc,用户名长度的16进制数值
00457C6C |. 83C6 05 add esi,0x5 ; 0xc+0x5=0x11,16进制的11转换成10进制就是17!
00457C6F |. FFB3 10030000 push dword ptr ds:[ebx+0x310] ; ds:[00951C84]=00951F24, (ASCII "黑头Sun Bird")
00457C75 |. 8D55 F8 lea edx,[local.2]
00457C78 |. 8BC6 mov eax,esi
00457C7A |. E8 85FEFAFF call CKme.00407B04
00457C7F |. FF75 F8 push [local.2] ; ss:[0012FC90]=00955F9C, (ASCII "17")
00457C82 |. FFB3 14030000 push dword ptr ds:[ebx+0x314] ; ds:[00951C88]=00951F40, (ASCII "dseloffc-012-OK")
00457C88 |. 8D55 F4 lea edx,[local.3]
00457C8B |. 8B83 D4020000 mov eax,dword ptr ds:[ebx+0x2D4]
00457C91 |. E8 B2B6FCFF call CKme.00423348
00457C96 |. FF75 F4 push [local.3] ; ss:[0012FC8C]=009557D8, (ASCII "www.52pojie.")
00457C99 |. 8D83 18030000 lea eax,dword ptr ds:[ebx+0x318]
00457C9F |. BA 04000000 mov edx,0x4
00457CA4 |. E8 93BFFAFF call CKme.00403C3C ; 不明白什么作用的call
00457CA9 |. 33D2 xor edx,edx
00457CAB |. 8B83 F4020000 mov eax,dword ptr ds:[ebx+0x2F4]
00457CB1 |. E8 AAB5FCFF call CKme.00423260
00457CB6 |. 8B93 18030000 mov edx,dword ptr ds:[ebx+0x318] ; ds:[00951C8C]=009557F4, (ASCII "黑头Sun Bird17dseloffc-012-OKwww.52pojie.")
注册算法就很简单了,四个字符串连接:“黑头Sun Bird”+“用户名长度+5”+ “dseloffc-012-OK”+用户名!
注册机还是用VB编吧,Delphi编程自己还不会,先练练VB再说!
偷了个懒,直接将crackme003的注册机复制过来,修改一番:在窗体上text1的属性栏中找到长度属性MaxLength,值填入12,表示只能填入12个字符
按钮事件的代码如下:
[Visual Basic] 纯文本查看 复制代码 Private Sub Command1_Click()
'未考虑变量的类型,
Dim str1, lend, str2, str3
If Text1.Text <> "" Then
str1 = (Text1.Text)
lend = LenB(StrConv(Str1,vbFormUnicode)) ‘lend = len(Str1),原来的len将汉字和英文都识别为1个字符
str2 = lend + 5
str3 = "黑头Sun Bird" & str2 & "dseloffc-012-OK" & str1
Text2.Text = str3
Else: MsgBox ("用户名不能为空")
End If
End Sub
运行以后,很快发现问题,VB将1个汉字作为1个字符,但Ckme把汉字作为2个字符,这就导致了中间数字用户名长度的错误,致使无法注册。从网上找了一下VB中的函数,改成LenB,加上参数,这下纯汉字和其他字符串作为用户名都成功了。
OK,这次练习结束,上传到论坛吧!!!
对应的Ckme及自己爆破的程序备份及注册机源程序均已上传百度云盘,链接: http://pan.baidu.com/s/1skMkJY9 密码: 86pm |