吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 3429|回复: 8
收起左侧

[原创] 160个Crackme之034学习笔记

[复制链接]
海天一色001 发表于 2020-5-29 20:17
第34个CM程序,从160个CM的CHM文件中可以看出采用的是Keyfile验证方式,也就是要有一个验证文件,里面有相应的信息,才能象第32个CM一样正常打开程序。
001.png
打开CM程序,标题栏里显示3.0版本,未破解字样。点击File菜单项,只有一个“Exit”退出命令,点击就结束了程序;Help菜单内是“About”命令,没有可以利用的地方。
002.png
第一步、查壳:
003.png
无壳,ASM汇编程序:
第二步、爆破:
用OD载入Cruehead.3.exe,先中文搜索,很容易看到了各种文本提示内容,和第32个CM一样,看到了CRACKME3.KEY这个keyfile文件名,再向下有一个正确提示和两个错误提示: 004.png
和第32个CM一样,先在CM所在目录新建一个CRACKME3.KEY文件,这是一个注册表文件,感觉里面应该要写点什么东西吧。先不管那么多,再打开CM程序,和没有CRACKME3.KEY一样,程序界面及菜单项均无任何改变。双击0040118C这一行进入CPU窗口,上下观察代码,在00401188和0040118A两句应该是关键比较和关键跳,跳过了正确提示 ;
005.png
在0040119B处是一个call,跟入查看,这里应该是经计算后得到弹出正确提示框。
006.png
返回0040119B处,将0040118A处的跳转命令nop掉试一试,将修改后的可执行文件命名为Cruehead.3.nop.exe,运行一下,主窗口和正确提示框同时出现:
007.png
应该是爆破成功了,但主窗口的标题栏中还显示出“Uncracked”的未破解字样,没有完全破解成功。
第三步、追码:
从爆破成功的弹出框中看到内容第一行,应该是说是被某某某破解,所以在“Cracked by:”后面是名字,应该是写在CRACKME3.KEY这个注册表文件中的吧。重载程序,F8单步从头开始向下运行,至00401016到0040102D处要读取“CRACKME3.KEY”的注册表文件,如果不存在,则不弹出注册窗口:
[Asm] 纯文本查看 复制代码
00401016  |.  6A 00         push 0x0                                        ; /hTemplateFile = NULL  模板文件:为空
00401018  |.  68 80000000   push 0x80                                       ; |Attributes = NORMAL文件标志和属性:为一般文件
0040101D  |.  6A 03         push 0x3                                        ; |Mode = OPEN_EXISTING创建属性:文件必须存在,如果文件或设备不存在,那么CreateFile调用会失败
0040101F  |.  6A 00         push 0x0                                        ; |pSecurity = NULL安全属性:为空
00401021  |.  6A 03         push 0x3                                        ; |ShareMode = FILE_SHARE_READ|FILE_SHARE_WRITE  共享模式:允许共享读写
00401023  |.  68 000000C0   push 0xC0000000                                 ; |Access = GENERIC_READ|GENERIC_WRITE  读取方式:可读、可写
00401028  |.  68 D7204000   push Cruehead.004020D7                          ; |CRACKME3.KEY  文件设备名:CRACKME3.KEY
0040102D  |.  E8 76040000   call <jmp.&KERNEL32.CreateFileA>                ; \CreateFileA 返回值:执行成功,则返回文件句柄

  00401032处,因为上一句执行成功,此时eax=0x44,所以00401035处会跳走到读取CRACKME3.KEY这个文件的内容:
[Asm] 纯文本查看 复制代码
00401043  |> \A3 F5204000   mov dword ptr ds:[0x4020F5],eax                 ;  D
00401048  |.  B8 12000000   mov eax,0x12
0040104D  |.  BB 08204000   mov ebx,Cruehead.00402008
00401052  |.  6A 00         push 0x0                                        ; /pOverlapped = NULL 参数设为NULL表示不是异步读取操作
00401054  |.  68 A0214000   push Cruehead.004021A0                          ; |pBytesRead = Cruehead.004021A0从文件中实际读取的字节数
00401059  |.  50            push eax                                        ; |BytesToRead = 12(18.) 要读入的字符数
0040105A  |.  53            push ebx                                        ; |Buffer = Cruehead.00402008 用于保存读入数据的缓冲区
0040105B  |.  FF35 F5204000 push dword ptr ds:[0x4020F5]                    ; |D
00401061  |.  E8 30040000   call <jmp.&KERNEL32.ReadFile>                   ; \ReadFile  调用成功,返回非0调用不成功,返回为0
00401066  |.  833D A0214000>cmp dword ptr ds:[0x4021A0],0x12                ;  文件中不能少于18个字符
0040106D  |.^ 75 C8         jnz short Cruehead.00401037                     ;  不等跳向失败

00401059 处ReadFile 的BytesToRead参数为0x12,即要读入的字符数为18个,而在00401066处指令是“cmp dword ptr ds:[0x4021A0],0x12”,也就是说实际读取出的字数与要读取的字数进行比较要相等,不等则跳走,失败了。所以在00401061处下断,重载CM程序,再切换到CM程序所在目录,打开CRACKME3.KEY文件,随意输入不少于18个字符并保存文件(我输入的是“qwertyuiopasdfghjklasdfghjklzxcvbnm”共26个字母)。打开CM原程序,仍然没有任何改变;关闭后再打开Cruehead.3.nop.exe,运行一下,主窗口和正确提示框同时出现,且提示框内容已经改变了:
008.png
可以看出后面一串字符肯定不是正确的名字,所以还要切换回OD,F9运行,继续调试:从00401061开始单步向下,到0040106F处,将CRACKME3.KEY文件中的前18个字符“qwertyuiopasdfghjk”压入堆栈;
009.png
运行到00401074处时,先查看了一下ds:[0x4020F9]=0,F7跟入00401311中:
010.png
先将ecx清零,作为下面循环次数的暂存器;再将eax清零,作为serial字符的暂存器;esi存入CRACK3.KEY文件的前18个字符;bl赋值为0x41;al得到第1个字符,再与bl异或,得到的值累加存入ds:[0x4020F9]中,异或的值转换成的字符再存回原字符的位置(待循环结束,经0040133C子程序验证后作为破解者名字出现在正确提示窗口中);然后字符位置向后1位, bl值加1,循环次数加1,总共循环14次求值,其中如果CRACK3.KEY文件的前14个字符中某1个字符和bl异或后的值为0时就会跳出循环;
运行到00401335处,将ds:[0x4020F9]中的值与0x12345678异或后重新存入ds:[0x4020F9]中备用;下一句retn回00401079处,再查看ds:[0x4020F9]= 0x29E;此时0040106F和00401086处注释变成了“ASCII "05&61?2!&:*?)(ghjk”,00401079处运行后,ds:[0x4020F9]= 0x123454E6;
继续运行到00401086处,将处理过的字符串压栈作为0040108B处call的参数继续进行处理, F7跟入0040133C中:
011.png
可以看出这个call的作用是先得到处理过的字符串,然后esi的地址向后0xE(14)位,即来到0x402008+0xE=0x402016处,从CRACK3.KEY文件中第18、17、16、15个字符的16进制ASC值并连接起来赋予eax,然后retn回00401090处:
[Asm] 纯文本查看 复制代码
00401090  |.  83C4 04       add esp,0x4
00401093  |.  3B05 F9204000 cmp eax,dword ptr ds:[0x4020F9]                ;  此处必须相等,否则还是失败!!!!
00401099      0f94c0        sete al                                        ;  if eax = ds:[0x4020F9] then set al=1 else set al =0 endif
0040109C  |.  50            push eax
0040109D  |.  84C0          test al,al
0040109F    ^ 74 96         je short Cruehead.00401037                     ;  跳至主窗口标题后半部分为uncracked的子程序
004010A1  |.  68 0E214000   push Cruehead.0040210E                         ;  CrackMe v3.0
004010A6  |.  E8 9B020000   call Cruehead.00401346                         ;  al=1时,得出主窗口标题后半部分内容为cracked的子程序
004010AB  |.  83C4 04       add esp,0x4004010AE  |>  6A 00         push 0x0                                       ; /Title = NULL
004010B0  |.  68 28214000   push Cruehead.00402128                         ; |No need to disasm the code!
004010B5  |.  E8 9A030000   call <jmp.&USER32.FindWindowA>                 ; \FindWindowA
004010BA  |.  0BC0          or eax,eax
004010BC  |.  74 01         je short Cruehead.004010BF
004010BE  |.  C3            retn
004010BF  |>  C705 76204000>mov dword ptr ds:[0x402076],0x4003

到00401093处将eax与ds:[0x4020F9]进行比较,结合下面的指令并多次调试后可知此处如果不相等,则运行到0040109F处后跳到00401037处,再call 004012F5子程序,将主窗口标题后半部分变成未注册字样(-Uncracked);eax与ds:[0x4020F9]相等,则到0040109F处不跳走而向下,到004010A6处调用00401346子程序,主窗口标题后半部分变成了已注册字样(-Cracked),然后向下就会按照标准的win32程序启动过程,先是FindWindowA函数获得顶层窗口的句柄,LoadIconA加载图标、LoadCursorA加载鼠标指针、RegisterClassA注册类,再到CreateWindowExA创建主窗体等,再利用作者修改后的win32过程函数Cruehead.WndProc()来接收消息,从而弹出正确提示框。
所以注册算法主要是在00401311和0040133C这两个call中。
从追码的过程中,可以看到爆破过程还是不完全的,没有将主窗口的标题改成“Cracked”,而追码中明白了作者的思路,所以应该在0040109F和0040118A处将跳转命令nop掉,保存为Cruehead.3.nop.nop.exe,运行一下,成功了,主窗口标题是“cracked”,弹出提示框也是正确的。
[Asm] 纯文本查看 复制代码
0040109F    ^\74 96         je short Cruehead.00401037                     ;  跳至主窗口标题后半部分为uncracked的子程序
0040118A     /75 17         jnz short Cruehead.004011A3

注册算法:先读取CRACK3.KEY文件的内容,依次取前14位字符的ASC码与A、B......到N的ASC码分别异或,得到的值再转换成字符,成为破解者名字;异或值累加,再与0x12345678异或后,值的16进制数值形式与第18、17、16、15位字符的16进制ASC值连接起来相同,则破解成功,否则不成功。
注册算法出来了,注册机编写:
[Visual Basic] 纯文本查看 复制代码
Option Explicit
Private Sub Command1_Click()
    Dim Serial, se1, Name, Key As String       'Key文件中的前14个字符、第18至15个字符的16进制数值连接形成的新数值、破解者名字、密钥
    Dim DS004020F9, Bl, i As Integer           'i为循环数,DS004020F9为CM程序中内存地址缓存,Bl依次为A至K的16进制数值
    Dim S() As Integer                         'S()为14个字符分别与A至N异或的值
        Name = Text1.Text                      'Name来自于文本框输入,如果未输入则默认为“[url=http://www.52pojie.cn]www.52pojie.cn[/url]”,Serial为写入注册表文件中的前14位字符
        If Name = "" Then
            Name = "www.52pojie.cn"
            Text1.Text = Name
            Text2.Text = "654jpt7'##.b. hS4"
            Exit Sub
        End If
        If Len(Name) > 14 Then Name = Mid(Name, 1, 14)                      '如果超过14个字符则只取前14个
        If Len(Name) < 14 Then Name = Name & String(14 - Len(Name), " ")    '如果不够14个字符则后面补空格到14个
        'Form1.Print Name
        Bl = 65
        ReDim S(1 To 14)
        For i = 1 To 14                                                     '得到前14个字符
            S(i) = Asc(Mid(Name, i, 1)) Xor Bl
            Bl = Bl + 1
            Serial = Serial & Chr(S(i))
            'Form1.Print "Serial(" & i & ") =" & Serial
            DS004020F9 = DS004020F9 + Asc(Mid(Name, i, 1))
            If S(i) = 0 Then Exit For
        Next i
        'Serial = Trim(Serial):习惯性思维去空格,却忘记了空格也是一个字符!
        If Len(Serial) < 14 Then Serial = Serial & String(14 - Len(Serial), "0")
        DS004020F9 = DS004020F9 Xor &H12345678
        'Form1.Print "DS004020F9=" & DS004020F9
        se1 = Hex(DS004020F9)
        'Form1.Print "se1=" & se1
        For i = 4 To 1 Step -1                                              '得出后4位字符
            Key = Key & Chr(Val("&H" & Mid(se1, 2 * i - 1, 2)))
           'Key = Key & Chr(Val("&H" & Mid(se1, i, 2)))
           'Form1.Print "Key=" & Key
        Next i
        Text2.Text = Serial & Key                                           '一个问题,在Key最前面是空格时连接不到一起来,
        Command2.Visible = True
        End Sub
Private Sub Command2_Click()                                                '生成注册文件
    Open "CRACKME3.KEY" For Output As #1
    Print #1, Text2.Text
    Close
End Sub

用VB编写注册机过程中却是错了一遍又一遍,郁闷了很久,自己猜测是不是CM程序自身有问题?毕竟异或0x12345678的结果大部分前4位是1234,转换成字符是和4,而后4位就多了,如E6、8A之类,这些用chr()函数得不出正确的结果。而且在Text2.Text = Serial & Key这句代码中如果Key第1个字符是空格,则无法连接,只显示了前面Serial的字符,盼请各位大神指教!!!
终于完成了!
附件 034.rar (169.3 KB, 下载次数: 5) ,含CM原程序、爆破后的程序、注册机、OD的调试文件等。百度链接是:http://pan.baidu.com/s/1skMkJY9,密码: 86pm,160个CM、我已练习过的前34个crackme程序(012未能破解)都在里面。

免费评分

参与人数 7威望 +1 吾爱币 +26 热心值 +6 收起 理由
Hmily + 1 + 20 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
ogli324 + 1 谢谢@Thanks!
gaoyuan1234 + 1 + 1 热心回复!
天蝎浪花 + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
YiFaniu + 1 + 1 谢谢@Thanks!
SnowRen + 1 + 1 热心回复!
fengbolee + 1 + 1 用心讨论,共获提升!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

SnowRen 发表于 2020-5-29 21:15
感谢分享,楼主好长时间没发文了
xie7 发表于 2020-5-29 21:19
黄河大鲤鱼 发表于 2020-5-29 21:45
天蝎浪花 发表于 2020-5-29 23:33
后面附的网盘链接没有034哦
gaoyuan1234 发表于 2020-5-31 06:39
感谢分享!!学习学习再学习
斩风 发表于 2020-5-31 14:33
学习了,感谢分享
 楼主| 海天一色001 发表于 2020-5-31 14:57
天蝎浪花 发表于 2020-5-29 23:33
后面附的网盘链接没有034哦

不好意思,已上传了
潜水呀zhtty 发表于 2020-6-6 21:09
支持11111
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-16 12:56

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表