.net程序的破解实践与理解一、爆力破解篇:改代码(写给新手,超详细)

查看 168|回复 10
作者:zhj777   
  首先声明哈,本人新手一个,下面所写只是本人做为新手对.net程序破解的一点实践与理解,没有什么技术含量,只是想对和我一样刚入门的小菜们有一点点启示和即将入门的小菜们一点引领,还请各位大牛们不要笑话,发现问题不吝提醒。在调试过程中也遇到了编译的问题,望大牛们看到给指导一下。本帐子只限技术交流,还请大家支持正版。
  手上有一程序,前段时间使用时发现帐号已过期,于是就想看看自己能不能解决,用die查壳,发现是.net的,于是扔进dnspy里弄了半天一无进展,于是在吾爱上搜索.net程序恶补,今天读到lmze2000大牛的《[.NET逆向] xxx程序 V3.30 .net破解注册教程,全局爆点》https://www.52pojie.cn/thread-600334-1-1.html,于是试着下载下软件来研究,按照大牛的思路很快能就找到关键点并解决了问题,可像咱这种二把刀分析算法还是有一定难度的,于是就想着按照一个小白的思路能不能解决,于是就有了这篇文章。下面开始我的摸索过程:用到的工具die_win64_portable_3.09_x64、dnspy6.1.8吾爱网盘上都有,程序在lmz2000大牛https://www.52pojie.cn/thread-600334-1-1.html的帖子页面也有。打开die,如图加载程序也可直接拖进去


1.png (57.89 KB, 下载次数: 0)
下载附件
2024-8-13 07:50 上传



2.png (102.47 KB, 下载次数: 0)
下载附件
2024-8-13 07:50 上传



3.png (61.3 KB, 下载次数: 0)
下载附件
2024-8-13 07:51 上传

挺干净,没有红色提醒。那先运行起来点帮助---注册看看,显示“注册码不对”,那就搜索“注册码”三个字吧,把程序扔时dnspy里,点搜索(放大镜图标),右边要选“数字/字符串”,稍等一会就搜出两个方法。


4.png (102.41 KB, 下载次数: 0)
下载附件
2024-8-13 07:57 上传



5.png (51.63 KB, 下载次数: 0)
下载附件
2024-8-13 07:57 上传



6.png (48.4 KB, 下载次数: 0)
下载附件
2024-8-13 07:58 上传

 
双击第一个“cmdOK_Click”进去,看到了我们的关键字“注册码不对!”点右边滑动条下的三角或转动鼠标滑轮,往下来又看到一个,再住下来还有一个。再往下来,就看到“注册成功”的关键字了。


7.png (50.71 KB, 下载次数: 0)
下载附件
2024-8-13 08:04 上传



8.png (65.63 KB, 下载次数: 0)
下载附件
2024-8-13 08:04 上传



9.png (60.04 KB, 下载次数: 0)
下载附件
2024-8-13 08:12 上传

再往下走,还有一个“你已注册了本程序,谢谢!”,上面方法名是frmRegister_Load(),看名字是注册窗口加载。也就是注册过了,再打开注册窗口就不能注册了,就会显示“你已注册了本程序,谢谢!”。那先回到第一个“注册码不对”的地方,在bool flag3....这一行右键-添加断点(或F9下断),


10.png (45.22 KB, 下载次数: 0)
下载附件
2024-8-13 08:13 上传



11.png (50.54 KB, 下载次数: 0)
下载附件
2024-8-13 08:17 上传



12.png (131.65 KB, 下载次数: 0)
下载附件
2024-8-13 08:18 上传

然后,点“启动”来加载程序,弹出“调试程序”对话框,别的地方不用管,直接点“确定”,跑起来后,点“帮助”,


13.png (51.81 KB, 下载次数: 0)
下载附件
2024-8-13 08:21 上传



14.png (63.73 KB, 下载次数: 0)
下载附件
2024-8-13 08:21 上传



15.png (83.23 KB, 下载次数: 0)
下载附件
2024-8-13 08:21 上传

再点“注册”,输上假注册码,点确定。断下来了,text3里面是咱们的假码,text3.Lenth就是假码的长度,这句的意思就是假码的长度如果小于14或大于15,即假码长度不等于15,那么flag3的值就为true。下一行if(!flag3)是“如果不是flag3的值,即如果不是true,那就是如果是false”就不执行大括号里的跳转语句“goto IL_10E”。


16.png (159.08 KB, 下载次数: 0)
下载附件
2024-8-13 08:52 上传



17.png (38.63 KB, 下载次数: 0)
下载附件
2024-8-13 08:54 上传



18.png (57.71 KB, 下载次数: 0)
下载附件
2024-8-13 08:54 上传

我们的假码是10位,那当我们点F10或下图中箭头走到if(!flag3)这一行时,能看到下面flag3的值是true.那!flag3就是false,那就越过大括号内容,直接来到num2=19。


19.png (115.49 KB, 下载次数: 0)
下载附件
2024-8-13 09:12 上传



20.png (51.25 KB, 下载次数: 0)
下载附件
2024-8-13 09:12 上传



21.png (45.17 KB, 下载次数: 0)
下载附件
2024-8-13 09:13 上传

再走一步就走到“注册码不对!”这一行了,点“继续”运行起来,就显示“注册码不对!”了。


22.png (39.31 KB, 下载次数: 0)
下载附件
2024-8-13 09:16 上传



23.png (34.35 KB, 下载次数: 0)
下载附件
2024-8-13 09:16 上传



24.png (44.5 KB, 下载次数: 0)
下载附件
2024-8-13 09:16 上传

想不让它弹出“注册码不对!”那就让注册码是15位就行了。转动鼠标滑轮来到第二个关键字处下断,然后点“继续”,断下来了。


26.png (41.08 KB, 下载次数: 0)
下载附件
2024-8-13 09:21 上传



27.png (47.55 KB, 下载次数: 0)
下载附件
2024-8-13 09:21 上传

F10再走一步看看flag33里面是什么值,Flag33=true, (!Flag33)就是假,那就执行goto IL958B,若不想让它执行goto IL958B,那就改代码吧。把它改成相反的语句不就行了嘛,即!flag33改成flag33,说干就干,在代码窗口点右键-编辑方法,改好后,点编译。


28.png (57.25 KB, 下载次数: 0)
下载附件
2024-8-13 09:24 上传



29.png (145.39 KB, 下载次数: 0)
下载附件
2024-8-13 09:24 上传



30.png (33.18 KB, 下载次数: 0)
下载附件
2024-8-13 09:24 上传

这下能过了吧,正在得意之时,直接来了一盆冷水,竟然编译不了。这下完了,过不了这火焰山了。再去吾爱上学本事吧,于是又是一番恶补,看到大牛们用IL语言能改,那就试试吧,右键,找到菜单“编辑IL指令”,进入IL指令编辑窗口。有点乱,这去哪里找关键点啊?别急往下转下鼠标滑轮,发现没有?“注册码不对!”几个字。


31.png (58.98 KB, 下载次数: 0)
下载附件
2024-8-13 09:31 上传



32.png (151.18 KB, 下载次数: 0)
下载附件
2024-8-13 09:31 上传



33.png (38.79 KB, 下载次数: 0)
下载附件
2024-8-13 09:31 上传

95B所在的那一行原来是Brfalse.s,那给它改成相反的Brtrue.s不就行了,说干就干,改完后,确定,回到代码窗口,原来的if(!flag33)不见了,变成了if(num5


34.png (50.16 KB, 下载次数: 0)
下载附件
2024-8-13 09:34 上传



35.png (47.82 KB, 下载次数: 0)
下载附件
2024-8-13 09:34 上传



36.png (110.49 KB, 下载次数: 0)
下载附件
2024-8-13 09:34 上传

换个名字,确定。把dnspy中原来的程序移除,重新加载名字带1的那个。通过搜索关键字“注册码”,转动鼠标滑轮重新找到原来这个地方下断。


37.png (52.11 KB, 下载次数: 0)
下载附件
2024-8-13 09:40 上传



38.png (128.64 KB, 下载次数: 0)
下载附件
2024-8-13 09:40 上传



39.png (43.96 KB, 下载次数: 0)
下载附件
2024-8-13 09:41 上传

点启动---帮助---注册,输入15位假码,确定,断下来了。F10走一步,终于过了。然后来到bool flag36 = Module1.yanzheng(ref text2, ref text4) & !File.Exists(RegData.gStrSystemDir + "\\syspbaz735.dll");的上一句num=109处下断,点继续,断下来后。F10走两步,观察flag36的值是false时,就会显示注册码不正确了。那就是让flag36为true就行。观察bool flag36 = Module1.yanzheng(ref text2, ref text4) & !File.Exists(RegData.gStrSystemDir + "\,发现flag36的值是由“yanzheng()这个方法返回的,那就到这里面看看,在“yanzheng()”上点一下左键进去,这里是进行一番计算后,返回一个结果return result,


40.png (40.63 KB, 下载次数: 0)
下载附件
2024-8-13 09:43 上传



41.png (55.46 KB, 下载次数: 0)
下载附件
2024-8-13 09:44 上传



42.png (38.59 KB, 下载次数: 0)
下载附件
2024-8-13 09:44 上传

那不管它,直接让它返回个true不就行了,把其他代码删掉,只保留return true。在代码窗口右键---编辑方法,改完代码后编译(这里能编译了,前面那里就不行,还请大牛指点一下)。保存模块---某八字2.exe,把dnspy中原来的移除,重新加载某八字2.exe,启动。通过关键字“注册码”,再找到bool flag36 = Module...,下断。主程序中点帮助---注册,输入15位假码,确定后断下来,F10往下走,顺利跳过“注册码不对!”。来到RegInfoFlag=true(把true传给注册信息标志),走过“注册成功”。


43.png (29.73 KB, 下载次数: 0)
下载附件
2024-8-13 09:51 上传



44.png (51.74 KB, 下载次数: 0)
下载附件
2024-8-13 09:51 上传



45.png (46.48 KB, 下载次数: 0)
下载附件
2024-8-13 09:51 上传

点继续,让程序跑起来。至此,成功注册。............      但重新启动程序,再点开注册界面,还是要重新注册,   这是咋回事,难道没成功?静心想想这应该是程序重起时还有一个检查。那在那里呢?思索中。。。。,还记得下面这个地方吗?关键点在这个passflag标志。它的值是由Passflag传给的,那Passflag的值又是从哪来的呢?


46.png (47.43 KB, 下载次数: 0)
下载附件
2024-8-13 09:56 上传



47.png (66.06 KB, 下载次数: 0)
下载附件
2024-8-13 09:56 上传



48.png (45.33 KB, 下载次数: 0)
下载附件
2024-8-13 10:00 上传

在passflag上右键---分析,点下面窗口“赋值于”前面的三角,再在frmMain_Load上双击。看到原来是来自于RegInfoFlag。即主程序窗口加载时RegInfoFlag向Passflag传递了这个标志值。注意看上面还有一个CheckIfReg()方法,意思是检查注册信息,有些可疑,一会儿再说,还是先追追踪RegInfoFlag的来历。同样用分析的方法。发现下面“赋值于”中有一个CheckIfReg()方法,


49.png (152.36 KB, 下载次数: 0)
下载附件
2024-8-13 10:03 上传



50.png (38.74 KB, 下载次数: 0)
下载附件
2024-8-13 10:03 上传



51.png (67.6 KB, 下载次数: 0)
下载附件
2024-8-13 10:03 上传

这就更可疑了,在CheckIfReg()上双击进去看看,这里可能是检查注册表里的注册信息是否正确,正确就返回true,错误就返回false。梳理一下流程就是咱们通过注册窗口注册“成功”后,注册信息会被写入注册表,程序重启时会读取注册表里的信息进行检查。咱们通过注册窗口输入的注册信息虽然成功写入注册表,但那些值是不正确的值,程序重启检查时就发现不对了,就返回了false。为了验证咱们的猜想,在RegData.GetRegData处下一断点,点“重新开始”重新启动程序,果然被断下来了。F10往下走,果然是返回了false。


52.png (20.84 KB, 下载次数: 0)
下载附件
2024-8-13 10:12 上传



53.png (101.8 KB, 下载次数: 0)
下载附件
2024-8-13 10:13 上传



54.jpg (79.49 KB, 下载次数: 0)
下载附件
2024-8-13 10:23 上传

.这里返回的值是根据flag标志来返回的,而flag的值与调用的FuncReadRegFile()方法有关系,单击FuncReadRegFile()进去看看,这里应该读取注册表并进行计算验证的地方,最后返回一个结果,那咱也不先不管这些算法了,今天咱就爆破了。编辑方法---删掉其他代码,把reture result改成reture true,


57.jpg (75.91 KB, 下载次数: 0)
下载附件
2024-8-13 10:25 上传



55.jpg (70.4 KB, 下载次数: 0)
下载附件
2024-8-13 10:28 上传



56.jpg (39.13 KB, 下载次数: 0)
下载附件
2024-8-13 10:29 上传

导出模块,保存为***3.exe.运行试下,点开帮助-注册,显示已经注册过了,成功!


54.png (35.73 KB, 下载次数: 0)
下载附件
2024-8-13 10:13 上传

写在最后的总结:
1、这个程序lmze2000大牛已经有过帖子,而且很简练。只所以还有这篇作品只是想从一个新手的角度来考虑找出关键点的思路。
2、作为新手,有时看大牛的帖子感到很是迷茫,感觉有太多的不懂。所以教程写得很详细,希望和我一样的新手入门不迷路,能有继续探索的信心。
3、以上破解过程主要卡在第二个“注册吗不对!”的地方,因为无法通过编译直接改c#代码,(有大牛看到的话请给点拨一下原因),最后只好恶补IL代码知识来解决,不过IL代码确实对新手来说看起来有点陌生,不如C#代码好理解,如果能直接改c#最好了,希望有大牛能解决。

下载次数, 下载附件

不知道改成啥   

不是想打击楼主,一般来说最难的不是搞这个,而是反混淆,去壳这一块
zhj777
OP
  

根据对lmze2000大神帖子的学习和代码一步步分析,现在终于明白me2000大神所说:
“注册码中的第5、6、7、8、13、14位来计算出授权日期,这个日期要在2030年12月份以内,并且大于当前日期。
其中:5/6位拼接年份数据的后2位,然后和20拼接;7/8位拼接月份、13/14位拼接日子数据,第15位应该算是校验位,没发现有啥用。
举例:以第5、6位为例子详解,第5位只能取6、7、B、8、9、C这6个字符,如果是6、7、B则返回1,8、9、C返回2,第6位只能取A/B/C/D/E/F/G/H/I/K这10个字符,分别对应0-9,”只不过最新版的日期改成了2036年(代码中比较年份),所以现在我的注册码换成1234CFAD90as681轻松过了第二个“注册码不对!”的地方。
原来爆破可是费大劲了。
qq465881818   

既然逆向出来了源码了,那就不用去调试了,直接在 vs里写注册机。岂不是蛮好
lauded   

写的很详细,赞
mdictfan   

学习了,谢谢!
life9999   

学习了,谢谢分享
fire1119e   

学习了,感谢楼言主!
xixicoco   

对。net新手很友好,感谢楼主
zif1993   

写的很好,学习了
您需要登录后才可以回帖 登录 | 立即注册

返回顶部