海天一色001 发表于 2020-11-27 13:01

160个Crackme之047学习笔记

本帖最后由 海天一色001 于 2020-11-27 13:08 编辑

第46个CM程序又是一个ReverseMe程序,目前还是不会,所以先隔过去吧。看看第47个CM。
打开DueList.2.exe,直接弹出信息框,大意应该是时间过期了,请注册并将密钥文件放在CM所在的目录中。

第一步、查壳:

ASM程序,无壳。
第二步、追码:
(本想爆破的,结果发现爆破比追码还麻烦,从整个过程看爆破也不是简单的一两处jmp或nop就行了,还需要改动更多的地方,所以先直接找出算法,写出注册机来。写出注册机后,劲儿也泄了,爆破就不搞了!)

1、判断有无密钥文件(due-cm2.dat)
从信息框的内容猜测要先创建一个密钥文件放入CM所在目录中,具体文件名用OD来查看:

ASM程序最大的特点是简洁,一眼就看到了0040106E处的注释中文件名为“due-cm2.dat”,而这个文件名是CreateFileA函数的重要参数,基本上就是密钥文件名了!
00401063处的注释为Mode=OPEN_EXISTING,说明必须要先存在文件,否则会出错,返回-1。
在CM当前目录内创建一个空白的文本文件,名字改为due-cm2.dat,然后再运行CM程序,果然跳过了时间过期的提示,但又弹出一个新的错误提示:

百度一下,意思是“您当前的密钥文件无效... 请从软件作者那里获得一个有效的密钥文件!”
这应该是读取了due-cm2.dat文件的内容,并经过注册算法计算后发现密钥文件的内容不正确,所以要求获得有效的密钥文件。
关闭信息框,切换回OD中,向下拉滑块,很快看到了这个错误提示信息框的代码:

004010F5处跳过这个错误弹出框,应该是关键跳,试着改为jmp,保存为DueList.2_jmp.exe并运行一下,仍然弹出这个错误信息窗口。
向下查看代码,004010F7处有一个跳转来的标志,说明将004010F5这一句指令跳过去了。
点击一下004010F7这一行指令,看到信息窗口中显示有4个跳转来源:“跳转来自 004010B2, 004010BF, 004010D6, 00401155”。 应该是这四个跳转来源中的某一个或几个跳过了004010F5处的指令。
向上来到004010B2这个最早一个跳转的来源处查看代码,发现004010B0、004010B2两处是根据ReadFile函数的返回值来进行跳转的指令,通过百度学习,大致理解ReadFile如下图注释:

所以在0040109A处下断,关闭OD,然后往due-cm2.dat文件中随意写入了70多个字符保存,重新用OD打开DueList.2.exe,F9运行,程序来到0040109A处,F8单步向下,运行完004010A9处指令后,地址栏中0040211A至0040215F处存入了due-cm2.dat中前70位字符,00402173处为标志符“F”,也就是16进制0x46,10进制数70;

(为了弄明白ReadFile函数的这些参数,还将due-cm2.dat文件反复修改,折腾了好几次,先是用记事本创建的密钥文件,然后在文件中输入了70多个可打印字符,然后又修改成16位、18位,而从OD运行过程中又发现不仅有可打印字符,还有0x1等控制字符或不可打印字符,只得改用UE这类十六进制编辑器来修改密钥文件,修改一次,执行一次OD,查看地址栏中的数据等,更好地理解了这个函数的作用。)

2、判断文件内容是否为空
继续向下至004010AE处进行检测eax的内容,如果密钥文件无内容则跳往失败提示的004010F7处;

此时因为due-cm2.dat中有内容,ReadFile函数读取成功,返回值为1,所以004010B0处指令运行,不运行004010B2处跳往失败提示的指令,对密钥文件的内容进行第二步检验:

3、判断文件内容是否有18个字符:
从004010B4运行至004010B8处,判断密钥文件内容是否有18个字符,如果少于18个则失败,不少于18个则继续向下检验。

所以密钥文件最少有18个字符就行了,而不必象我上面一口气弄出了70多个字符。

4、判断密钥文件中是否有2个ASC值为0x1的字符
从004010C1到004010D6处,判断密钥文件中是否有不少于两个字符的ASC值为0x1且中间不能有ASC值为0x0的字符:

单步运行过程中又发现密钥文件中含有0x1这类控制字符或不可打印字符,而记事本无法写入这类字符,所以改用UE这类十六进制编辑器来修改密钥文件due-cm2.dat,修改一次保存后关闭编辑器,再重新执行OD,观察程序运行情况:

5、判断第一个0x1前字符ASC值累加和是否为0x1D5
从004010D8至004010ED的循环作用是依次取密钥文件中第一个0x1之前字符的ASC值进行累加,保存到esi中,并与0x1D5比较,不等则失败,相等则跳到下一步检验步骤去。

因为0至8的ASC累加值为0x1D4,所以再次用UE修改due-cm2.dat文件,前9位就是“012345679”,第10位为0x1,然后第11位至15位写入“abcde”5个字符,第16位改成0x1,第17、18位写入“fg”两个字符,使密钥文件符合不少于18位,其中有两个字符ASC值为0x1,且第一个0x1之前字符的ASC累加值为0x1D5的要求。

关闭UE,重新用OD加载CM程序,F9运行到0040109A处,F8单步向下,很轻松来到004010F5处,跳过了失败提示框:

6、生成注册用户名
00401114处至00401137处的循环应该是取前两个0x1之间的每一个字符,依次与密钥文件第N(N从1开始,最多到15)个字符进行异或运算得出注册用户名:
单步运行,查看具体算法:
在00401116处序数递增1位,00401117处依次取前两个0x1之间的每一个字符;
在0040111D至00401128处判断读取的字符ASC值是否为0x0或0x1,或者esi值是否为0xF,不是继续顺序执行指令,是则跳出异或运算的循环,跳至00401139处;
在0040112A和00401130处进行异或运算得出用户名存入ds:中。

此时得出的用户名为“QSQWQ”;

7、判断第二个0x1后字符ASC值和是否为0x1B2
从0040113C至0040114D处是一个ASC值累加的循环,结果存入esi中;

单步至00401155处,此时esi=0xCD,不等于0x1B2,又要跳向失败,所以在Z标志位的“0”上双击改成“1”,使跳转不成立,
继续向下运行程序,到00401168处弹出窗口,显示注册成功信息:

这应该是成功标志了。整个注册算法应该是这7步了。

因为密钥文件还不符合要求,所以继续修改:
在OD中取消0040109A处断点,在00401114处下断,然后关闭OD,用UE打开due-cm2.dat,修改文件内容:
前10个字符先不改变,保证第5步之前都没问题;第6步中在最后增加一个0xE5,重新用OD加载CM程序,F9运行,此时地址栏结果如下:

F8单步向下,运行到00401139处时,此时地址栏数据已显示了用户名“QSQWQ”:

继续向下到00401168处弹出窗口,显示注册成功信息:

所以这个due-cm2.dat是完全符合要求的一个密钥文件了。

在单步过程中,我还曾认为前两个0x1之间可以有超过15个以上的字符存在,因为在前两个0x1之间不管有多少字符,只要遇到0x0时异或运算结束;或者两个0x1之间不少于15个字符时则只异或前15位,之后的字符不参与异或运算,第二个0x1之后字符ASC值累加得为0x1B2就行。
为了验证自己的想法,继续修改密钥文件,然后查看CM运行情况,并用OD检查问题所在:
修改due-cm2.dat中第一个0x1之后的字符,使前两个0x1之间后的字符有17位,第二个0x1后的字符改成了0xB2、0x9B、0x65:

运行CM程序,没有任何反应,在window系统进程中找到了DueList.2.exe,说明CM程序还在运行,但还没运行到显示窗口的地方,中间陷入死循环了。
关掉CM进程,将DueList.2.exe载入OD,F9运行,F8单步向下:

当生成注册用户名的循环读取到第16个字符“p”时,esi=0xF,不再进行异或运算,而是跳到00401139处,读取下一个字符“q”,进入到判断ASC累加值是否是0x1B2的循环中。
然后在这个循环中遇到了第二个0x1,在0040113C与00401148之间陷入了死循环,CM程序无法继续正常向下运行。
结合各个步骤判断,前两个0x1之间只能有不超过15个字符,整个密钥文件中第二个0x2之前字符不能为0x0,在第二个0x1之后参与累加运算的字符不能为0x0,当累加值为0x1B2之后可以为0x0。
再改due-cm2.dat如下图所示,第一个0x1之后的第16位改成0x1,后面改成0xB2、0x9B、0x65、0x0、0x1:

关掉UE,运行CM程序,这次弹出成功窗口:

此时的用户名中含有控制字符,在文本框中显示不出来,使用小方格代替。

三、编写注册机
看着简单,编写注册机时还是很麻烦:
用VB6编写的过程中不断出现问题,自己水平有限,但总算是大部分都解决了。
进入生成exe文件环节前,想最后调试一下,结果出了大问题,正常运行的get指令此时不能运行了,说是VB不支持的自动化类型!!!
想着是不是自己的编译环境出问题了,先生成一个exe文件运行下,仍是这个458代码的错误!换了虚拟机、换了VB软件,均无法修改这个错误。
在论坛上专门发了一帖求助,至今没有答复。可能是使用的VB的大神太少,或者是无法重现错误,没法解答吧。
以前编写其他注册机时就发现VB有很大限制,只是它相对接近自然语言才一直使用,现在解决不了问题,只好先换成C语言吧。
C语言刚开始接触,也是一大堆问题,但总算是写出了注册机,代码可能重复啰嗦,请勿见笑!
编写注册机时只想到字符超出15个的问题,未考虑不输入字符的问题,也暂时想告一段落,暂不修改了。
虽然VB编写的注册机不能用,但和C的源码都附上吧,如有兴趣的大神请指正!
附件,含CM原程序、密钥文件、注册机、OD的调试文件等。
百度链接:https://pan.baidu.com/s/1NEpyyUefbKcoJvMGG_9OmQ
提取码:p8dk。

winddyj 发表于 2021-2-18 02:41

看楼主的经历和我差不多,也是当初只有basic的时候学的,后来就直接VB了
VB6已经多少年不维护了,毛病也不少,有时候感觉小小的问题要折腾一天来解决
前一阵有人发过VisualFreeBasic,试用了一下,感觉还不错,软件也一直在更新
界面/用法和VB差不多,代码直接能兼容VB
就拿这个047来说,30分钟分析清楚注册文件用手写出来注册文件,却用了3个小时都写不出注册机
生成的文件不是最后面没有00,就是前面莫名给加了几个字节,实在折腾不下去准备放弃的时候
把代码复制到VFB,一遍过{:1_909:}VB真的是棒棒的
http://www.yfvb.com/soft-48.htm 可以下载VFB试一下
附上我用VFB编译的软件和原码,楼主可以感受下这软件,除了生成的软件稍大点,其它没毛病

@海天一色001

海天一色001 发表于 2020-11-28 21:39

jht168888 发表于 2020-11-28 21:06
这个是我想学习而没时间学习的东西,我也好想象楼主一样这么牛

你好!楼主其实一点也不牛。
我也是没多少时间学习,这一个CM花了三个多月才算完成。
160个CM三年多还只练习了40个左右!
自己兴趣所在,所以一直坚持。
累在其中,乐也在其中。
边破解边写笔记,遇到问题上网查,请教大神,反复检查自己的代码。
坚持吧,你绝对会成为大牛的!

scn123 发表于 2020-11-27 14:26

学习中多多分享,{:1_921:}

刀大喵 发表于 2020-11-27 14:43

写的很详细 受教{:1_893:}

lowellddh 发表于 2020-11-27 14:49

感谢楼主的学习分享~

康熙 发表于 2020-11-27 16:43


感谢楼主的学习分享~

youdu123 发表于 2020-11-27 17:48

学习下感谢分享

Airey 发表于 2020-11-27 18:23

是我大意了啊,没有闪!不过学习下感谢分享!!

我来了老大 发表于 2020-11-27 23:51

谢谢dalao分享,很详细,受教了!

D-pojie520 发表于 2020-11-28 01:28

做个笔记,有空继续学习。

wanshiz 发表于 2020-11-28 06:41

研得深。谢谢楼主分享。
页: [1] 2 3
查看完整版本: 160个Crackme之047学习笔记