海天一色001 发表于 2019-8-3 15:47

160个Crackme之033学习笔记

本帖最后由 海天一色001 于 2019-8-3 15:51 编辑

第33个CM程序,打开程序,选择“Help—Register”命令,输入name/serial=“52pojie/1234567890”,点击“OK”按钮,注册窗口消失,弹出两次错误提示框:
   
第一步、查壳:

无壳,ASM汇编程序:第二步、爆破:用OD载入Cruehead.1.exe,先中文搜索,很容易看到了各种文本提示内容,有一个正确提示和两个错误提示:

双击“Good work!”这一行进入CPU窗口:

向下查看,0040134D到00401361处是弹出正确提示框的子程序代码,00401362到0040137D处是错误提示框的子程序代码,再向下004013AD到004013BC处又是错误提示框的代码。从上图看到正确提示框最后一行代码是retn,说明这一段应该是一段子程序,要有调用的地址。点击0040134D这一行,信息栏中出现“本地调用来自 0040124C”的提示;

再向下点击第一段错误提示框的子程序开始行00401362处,信息栏中出现“本地调用来自 00401245”的提示:

第二段错误提示框的代码被包含于0040137E到004013C1处的子程序中,点击子程序首行0040137E处,信息栏中出现含“本地调用来自 0040122D”的提示。

注意看了一下这三个调用来源,地址基本上是在一起的,所以在任一信息栏中右键点击“本地调用来自 XXXXXXXX”这一行,选择“转到CALL来自XXXXXXXX”命令,均可来到调用来源处查看相应代码,

这里我返回第二段错误提示的代码调用地址0040122D处:仔细观察上下文代码,0040122D、00401245两处调用错误子程序,那么将其改为调用正确提示的子程序地址0040134D,那么不就行了吗?下图为已修改过的代码,存为可执行文件Cruehead.1.call.sucess.exe,运行一下,如果不输入name/serial,点击OK按钮,注册窗口消失,不弹出正确提示;随意输入name/serial,则弹出两次正确提示,还没有完全爆破成功。

将修改的两处call 正确提示子程序处撤消修改,再来看这一段代码:00401228处得到name字符串,0040122D调用第二个错误子程序(这里注释成第二个错误子程序是错误的),在0040122D处下断,F9运行CM程序,选择“Help—Register”命令,输入name/serial=“52pojie/1234567890”,点击“OK”按钮,程序中断,F7跟入0040137E处:

F8单步向下,运行到0040138B处,跳转到004013AC处成立,会弹出失败提示框,也就是说name字符的最小值是大写字母A,所以在寄存器窗口将双击标志位“C”的值“1”,将其改变为“0”,使跳转不成立,然后继续单步向下,一直到004013C1处,retn到00401232处。可以看出这段代码的作用是先判断name输入框中的每一个字符的ASC值是否不小于0x41,如果小于则弹出失败提示框,这就是在注册窗口输入name/serial=“52pojie/1234567890”后会出现两次错误提示的原因了,第一次是name字符串不合要求,第二次是serial不匹配name。如果字符的ASC值大于0x5A则减去0x20,然后在004013C2处对name字符串进行运算处理。所以要爆破,可以在0040137E处直接retn掉,或者在0040122D处nop掉,根本不对name进行任何判断和处理,就不会弹出第一次错误提示框了。F8继续向下,可以看出00401241处为关键比较,00401243处是关键跳,跳到正确提示框。

所以爆破的话,将0040122D处nop掉,将00401243处je改成jmp,将修改后的文件保存为可执行文件Cruehead.1.nop_jmp.exe,运行一下,随意在name/serial文本框中输入任意字符,点击“OK”按钮,弹出正确提示,爆破成功。第三步,追码:再来查找注册算法:Ctrl+F2重载CM程序,F9运行,因为爆破中已经对0040137E处进行了大致分析,知道name\字符串的要求,所以在注册界面输入name/serial=“wapojie/1234567890”,点击“OK”按钮,程序中断于0040122D处。上下观察代码,00401228处,将存储name字符串的地址压栈,作为下一行指令中0040137E这个call的参数,得到结果存入eax中;00401233处,将存储serial字符串的地址压栈,调用004013D8处的子程序;继续向下将结果存入ebx中,比较eax和ebx,相等则跳向正确,不等则失败。可知0040122D和00401238处的调用的两个call分别对name/serial进行运算,这两个call内就是注册算法了。
F7跟入0040137E这个call中,F8向下:前面已经对0040137E至0040139A处进行了分析,直接到0040139C处,将esi(name.text)压栈到作为下一行004013C2这个call的参数;F8向下,F72进入004013C中,

这是一个小循环,以name字符串的长度作为循环次数,作用是将name字符串得到的每一个ASC值进行累加,值存入edi中,循环结束返回004013A2处,继续F8运行,004013A2到004013C1处,edi = edi xor 0x5678,再存入eax中,返回00401232处,此时eax=0x5477;F8向下,到00401238处F7进入004013D8:

这里也有一个循环,作用是将每一个serial中的字符ASC值减去0x30,乘以0xA,再加上下一个字符ASC值减去0x30,得到新的结果,这个结果再乘以0xA,这样循环次数到serial字符串长度值时结束。如果注册码只是数字的话,其实就是将注册码的数字所有的0全部去掉得到的值再乘以10,再与4660(0x60)异或得到ebx的值。如果注册码中含有其他字符,暂时不考虑。程序验证注册码的算法出来了,用name字符串的ASC值累加,得到的值与0x5678异或,最终存储到eax中;将注册码中所有的0全部去掉得到的值再乘以10,再与4660(0x60)异或得到ebx的值;如果eax=ebx,则注册码正确。所以注册机算法就是先得到name字符串,将每个字符的ASC值相加,得到的值分别与0x5678、0x1234异或后转换成10进制数即可(不知道serial用字母行不行,没试验这一点):VB形式的代码如下:【刚开始时没有“If Len(name) > 11 Then name = Mid(name, 1, 11)”这一句,所以在name字符串长度超过11位之后生成的注册码中出现了错误,在OD中自己将API函数基本上都注释了一遍,所以发现了在004012C4和004012E4这两个API函数GetDlgItemTextA中对文本长度进行了限制,最多只有11位】
Option Explicit
Private Sub Command1_Click()
Dim name As String
Dim NameInt, n(), serial, i As Integer
    name = Text1.Text
    If name = "" Then
      Text1.Text = "WAPOJIE"
      Text2.Text = "17987"
      Exit Sub
    End If
    If Len(name) > 11 Then name = Mid(name, 1, 11)
    ReDim n(1 To Len(name))
    For i = 1 To Len(name)
      n(i) = Asc(Mid(name, i, 1))
      If n(i) > 90 Then n(i) = n(i) - 32
      NameInt = NameInt + n(i)
    Next i
    serial = NameInt Xor 17484
    Text1.Text = name
    Text2.Text = serial
End Sub
Private Sub Text1_KeyPress(KeyAscii As Integer)
    If KeyAscii < 65 Or KeyAscii > 122 Then KeyAscii = 0
End Sub附件,含CM原程序、爆破后的程序、注册机、OD的调试文件等。百度链接是:http://pan.baidu.com/s/1skMkJY9,密码: 86pm,160个CM、我已练习过的前33个crackme程序(不含012)都在里面。

海天一色001 发表于 2020-5-29 19:44

本帖最后由 海天一色001 于 2020-5-29 19:45 编辑

此用户无法显示 发表于 2020-3-6 10:47
楼主是不发帖了吗,最后给的是注册算法?感谢感谢
谢谢你!发帖肯定会继续的。因为学习这些是我的兴趣,必定会坚持下去的。但学习这些需要比较完整的时间,而为了生活,时间上不可能完全由自己掌握。
最后是用VB编写的注册算法。我也只会用VB,所以可能很吃力。

wbz_007 发表于 2019-8-3 16:20

沙发,学习了

274358889 发表于 2019-8-3 18:02

学习了。

佚丶名 发表于 2019-8-3 19:56

收藏了有空看看

sketch_pl4ne 发表于 2019-8-3 21:28

先mark一下

yaohui2 发表于 2019-8-3 21:55

谢谢分享,学习了

sweetxxtea 发表于 2019-8-3 22:19

马克,强强强

tengzhou22 发表于 2019-8-4 06:43

谢谢分享

laikehua 发表于 2019-8-4 09:29


谢谢分享

ding2734 发表于 2019-8-4 10:30

这个跟教程一样,赞一个,准备照着学
页: [1] 2
查看完整版本: 160个Crackme之033学习笔记