海天一色001 发表于 2021-1-11 12:57

160个Crackme之048学习笔记

本帖最后由 海天一色001 于 2021-1-11 13:03 编辑

第48个CM程序看名字和上一个应该是同一个人或组织的产品,打开程序,左侧是选择框及检查、关闭按钮,右侧是一个提示,你应当使用一个资源编辑器?

随意选择了几个框,点击Check按钮,弹出错误提示:

第一步、查壳:

无壳,ASM编程。
第二步、爆破:
提示用一个资源编辑器,那先试试Restorator:

打开只看到右侧显示出2个按钮控件、18个复选框控件、1个标签控件,找不到更多有用的信息,有一个复选框控件的标题是“732”,可能有用吧。
不管了,拖入OD中查看:
ASM程序,从开头向下查看,很快来到两个弹出信息框处,上面一个是正确提示,下面是注册失败信息。先从这里做文章吧!

从0040116F处看到一个跳转指令,从正确处跳走,来到失败提示,

所以将这一句nop掉,保存为DueList.3_nop.exe,打开,直接点击Check按钮,或者随意选择几个检查框后再点击Check按钮,均弹出以下正确信息框,爆破成功。

第三步、追码:
返回OD,撤消0040116F处的修改,然后向上反着查看代码:
0040116F处为关键跳,00401162处为关键比较,那么就需要再向上找到eax值的来历;
再向上一句,eax的值来自于ds:;
再向上,一个向上到00401127处的跳转,跟随来到00401127处,查看上下的代码,大致确定从00401117处到00401160处为一个比较完整的判断注册的代码:

00401117至00401121处将esi清零作为循环变量名(edx清零,系统回调返回用?),ds:和ds:均被初始化为0;
00401127至00401167处依次将复选框的ID(内存地址0x4020FE到0x402110处的值)传递给ecx(遇0x4D时跳走(不取0x4D),执行00401162处指令),再传递给ds:作为当前值暂存起来;
然后判断复选框是否选中。如果选中,则用当前字节值乘以下一个字节值再乘以当前的序数(esi),乘积累加至ds:中,若没选中(eax=0),继续下一个。
最后的累加值ds:*0x4D后与0xF35466比较,相同则成功。
归纳一下,从第一个复选框开始,每一个选中的复选框ID乘以相邻的ID,累加值等于0x328FE(0xF35466/0x4D)则成功注册。
怪不得要用到一个资源编辑器,目的是找出这18个复选框的ID分别是什么。
再次用Restorator打开CM程序:

如上图先选中默认查看模式,再选中编辑模式,就可以查看编辑程序各个控件的信息了。

此时再分别点击控件,右侧显示出上面一行第1个复选框ID为97(0x61),第二个为73(0x49),具体如下表:

再从OD中查看内存中的数据,发现数据顺序不一样:

这个顺序对应程序界面,应该是16,1,2,0,7,5,6,9,10,3,11,12,13,14,15,17,4,8

这样看来这个程序注册算法思路相对简单一些,简单描述就是从数组N个元素中选中M个元素(0<M<=N),使其和等于特定值。
说起来简单,但编写注册机时却发现这个程序实现功能却是十分麻烦:
还是先用VB来编写注册机程序:
首先想到的就是利用数组,在数组中将内存地址中的ID和其对应程序界面上的序号一一对应起来。
用Mid_Result(0 To 17, 0 To 1)来存储当前值*下一位置值*下一序数生成的中间值及对应的ID顺序:
    Dim Mem_ID: Mem_ID = Array(22, 73, 94, 21, 39, 38, 33, 37, 29, 89, 83, 55, 49, 72, 93, 12, 97, 82, 77)      '内存地址中的ID
    Dim ID_num: ID_num = Array(16, 1, 2, 0, 7, 5, 6, 9, 10, 3, 11, 12, 13, 14, 15, 17, 4, 8)                  '程序界面上对应内存地址中的ID顺序
    Dim Mid_Result(0 To 17, 0 To 1)                                                               'Mid_Result(i,0)为计算出的中间值,Mid_Result(i,1)是对应程序界面上的序号
      For i = 0 To 17
            Num = ID_num(i)                                                                     '将程序界面上的ID对应到内存地址中的ID顺序
            Mid_Result(i, 0) = Mem_ID(Num) * Mem_ID(Num + 1) * (Num + 1)                           '当前值*下一位置值*下一序数
            Mid_Result(i, 1) = ID_num(i)
      Next
再对生成的中间数组以第一维的数值进行排序即Mid_result(i,0)进行降序排序,目的是减少运算次数及时间:
For i = 0 To 16
            For j = i + 1 To 17
                If Mid_Result(i, 0) < Mid_Result(j, 0) Then
                  Tmp1 = Mid_Result(i, 0): Mid_Result(i, 0) = Mid_Result(j, 0): Mid_Result(j, 0) = Tmp1
                  Tmp2 = Mid_Result(i, 1): Mid_Result(i, 1) = Mid_Result(j, 1): Mid_Result(j, 1) = Tmp2
                End If
            Next j
      Next i
(排序代码在注册机程序最终没用上)
再往下,一开始的想法,先选第一个元素,与207102比较,相等,则说明只有这一个元素正确,输出结果,从第二个元素开始检测两个或两个元素以上的组合;大于,则跳过,检测第二个元素;小于,则再选中第二个元素,检测它们的累加值,如果等于207102说明这两个元素正确,输出,再检测下一组;如果小于207102,则再累加第三个元素;如果大于207102,则跳过第二个元素,用第一个元素与第三个元素相加后再检测。以此类推,最终得到所有可用的组合。
从网上查找了大量参考资料,倒是了解了一大堆的名词,01背包、动态规划等等,原理知道了,代码却是看不大明白!
最后还是从Excel Home论坛上找到了一些凑数的VBA代码,相对好理解一些,虽然还有部分代码不是很明白,但不影响自己抄袭并做了一些修改,才有了这个注册机。说实话,自己的水平太差了,明知道程序还可以优化,却优化不了!
附件,含CM原程序、密钥文件、注册机及源码(被抄袭的xls文件)、OD的调试文件,等等。
百度链接:https://pan.baidu.com/s/1NEpyyUefbKcoJvMGG_9OmQ
提取码:p8dk。

略略略啦啦啦 发表于 2021-1-11 13:36

强啊楼主

liss302 发表于 2021-1-11 13:51

干的漂亮!{:1_921:}{:1_921:}{:1_921:}

wanjiia778 发表于 2021-1-11 15:03

l厉害!!!!!!

dokuro 发表于 2021-1-11 15:08

给你点赞

159753qwe 发表于 2021-1-11 17:34

这个。。。有啥用

Borisding18 发表于 2021-1-19 09:31

感谢分享

caiji1 发表于 2021-1-19 16:02

感谢分享
页: [1]
查看完整版本: 160个Crackme之048学习笔记