某PB进销存暴力解除试用次数限制 一把辛酸泪~~~~~~
【软件名称】某进销存软件【软件语言】powerbuilder
【所用工具】peid、OD、shudepb、powerbuilder 11.5、winhex、bcompare、SQL Server Management Studio
【破解方式】暴力解除试用次数限制
那天,妹子跟我说,她在找一个进销存软件,经过几翻对比,最终决定用某知名品牌。
试用之后,妹子觉得还不错,客服告知只能用20次,如需要购买正版,需要几K软妹币。
在确定试用版和正式版没有功能差异之后,我就开始动手了。
由于妹子得到了客服不少帮助,就不透露软件名字了,看完之后猜到的,按我的过程来破解也只需要2分钟。(真的只有2分钟!!)
拿到软件后,首先尝试了开关20次,看看软件提示啥,如图
然后我才去看了下是什么语言写的。VC++7.0 ,很好,我真的天真地以为是C++写的!!!
OD,字符串,啥也没有。真的是什么也没有啊~~~
既然没办法通过字符串资源来下断点,也只能通过弹窗来了,SO EASY,bp MessageBoxA,bp MessageBoxW,bp MessageBoxExA,bp MessageBoxExW 全下了。
没想到我又跪了。如图:
这是神马啊,这么难看的堆栈让我怎么面对。一直在pbvm115.dll里面打转,根本出不来啊,关键跳转去哪了?比较20次的又去哪了?
然后我花了一天的时间,进入了一个新的世界! ----- PowerBuilder!!!
有没有被亮瞎,在网上找了好久好久好久,反编译PB的资料非常少,基本都是用 pbkiller shudepb PBDeCompiler 这三个工具。其中pbkiller对于PB10以上的版本编译出来的完全无效,而后面两个坑爹的都是收费的,网上流传的只有demo版本,而demo版本都有反编译出的代码行数限制。貌似核心的代码都看不到。我也没太多时间去一个个看了,只能换个思路先临时解决下20次的问题。
软件试用次数限制,那么使用次数一定是藏在某个地方,文件或者注册表。发现把数据库还原之后又可以继续使用了,看来使用次数在数据库当中。
通过对比使用前后的数据库,最后确定有两个字段发生了变化。sys_yh 中存储了使用次数,pbcatvcs中存储了一个MD5的值。如图:
如果只修改使用次数,就会提示数据库文件已损坏。必须两个一起修改才行。
在cmd5上查询结果:
已查到,这是一条付费记录,密文类型:md5(md5(md5($pass)))。请点击购买
哥灵机一动,难道pass就是使用次数? 果然是!
密文就是把使用次数 第一次加密后,结果转换成小写,对结果再加密一次,结果转换成小写,对结果再加密一次,再转换成小写…………
修改数据库中的字段之后,就可以继续使用了。现在写个小程序修改下字段就好了,又花费了2天。因为我脑子有问题居然用PB来写,中间遇到的问题多到 数据库怎么连接、函数怎么添加、全局变量在哪定义、是否需要datawindow………直到写完才发现我要是用C#早就写完了。
程序运行如图:
赶紧扔给妹子,现在就不急了,我可以慢慢研究怎么破解它了,破解之路才刚刚开始。
重新打开shudepb和PBDeCompiler,对比之后发现还是shudepb更有良心,显示的代码要多一些。仔细排查之后(后来才发现有全局搜索的功能)找到了比较20次的关键代码,如下:
CHOOSE CASE gi_money //0
CASE 0 //0
runtimes = 20 //14 /*此处通过全局变量控制试用次数为20次 */
CASE 1 //0
runtimes = 5000 //88 13
CASE 2 //0
runtimes = 200 //c8
CASE ELSE //0
runtimes = 20 //14
END CHOOSE //0
SELECT Top 1 gz , yh_no INTO :li_gz, :ls_no From sys_yhUSING sqlca; /*从数据库表sys_yh中读取软件使用次数 */
IF sqlca.sqlcode <> 0 THEN //10
gs_errtext = sqlca.sqlerrtext
ROLLBACK USING sqlca;
messagebox("SQL ERROR",gs_errtext)
RETURN -1
END IF //10
SELECT cs1 INTO :ls_cs From pbcatvcsUSING sqlca; /*从数据库表pbcatvcs中读取使用次数的密文 */
IF sqlca.sqlcode <> 0 THEN //16
gs_errtext = sqlca.sqlerrtext
ROLLBACK USING sqlca;
messagebox("SQL ERROR",gs_errtext)
RETURN -1
END IF //16
ls_zcs = string(li_gz)
ls_mm5 = encrypt(ls_zcs) /*对使用次数进行加密*/
IF (ls_cs <> ls_mm5 OR li_gz < 0) THEN //23
messagebox("提示","数据库文件已损坏,请联系开发公司修复.电话:*********")
HALT CLOSE
RETURN -1
ELSE //23
IF runtimes < li_gz THEN //28 /*如果使用次数大于最大试用次数,弹出对话框并且退出程序*/
messagebox("升级提示","您使用的软件需要升级后才能继续使用,请与开发公司联系!电话:**********")
HALT CLOSE
RETURN 0
ELSEIF (runtimes - li_gz) < 5 THEN //28
END IF //28
li_gz ++
ls_zcs = string(li_gz)
ls_mm5 = encrypt(ls_zcs) /*使用次数自加后,重新加密并写入数据库*/
update sys_yh Set gz =:li_gz Where yh_no =:ls_noUSING sqlca;
IF sqlca.sqlcode <> 0 THEN //37
gs_errtext = sqlca.sqlerrtext
ROLLBACK USING sqlca;
messagebox("SQL ERROR",gs_errtext)
RETURN -1
END IF //37
(在帖子里面添加代码没有PB的类别,就选了个类似的)
了解了代码之后,就确定了破解的方向了,在我的想象中,有一双滑板鞋,哦,不好意思,在我的想象中,只要把开始的 runtimes赋值为0,后面的关键比较改为 IF runtimes > li_gz THEN,就可以无限制地使用这个软件了。
现在的问题转化为如何在4M的代码中找到这部分的代码?????
我又查阅了无数的资料后,终于想出了一个死办法。既然这是解释性的语言,那我自己写个程序,把这个函数放进来,再加个标记不就知道这段代码长什么样子啦。
于是,我编(chao)写(xi)了人生当中第二个PB的程序,第一个可真的是我自己写的!
先编译一次生成二进制,再修改了如上图的地方,再编译一次。(为什么我要赋值为43981呢? 因为43981 = 0xABCD,方便我去找关键的代码,事实证明我的决策是英明的,因为这个二货的PB即使是完全一样的代码,连续编译两次也是多处不一样)
再用bcompare把N多个不同处一个个过了一遍,找到了关键地方,如图:
我加的ABCD到这里变成了 CDAB,不知为什么PB的二进制是把高位存在高地址的?不过也没有关系了,顺着这个标记,也找到了上面runtimes赋值的几个关键值。 0x14=200x1388=5000(不是8813 是1388) 0xC8=200 0x14=20
好了,现在再用winhex打开原程序,搜索这个8813,有很多个,但是只有一个地方附近的代码是和我的这个小程序长的一样的,找到了之前,把前面的那个14 改成了 0 。如下图
到这个时间,破解已经完成了一半了,第二步就是把那个< 改成 >。可是这个更难。
因为两个问题:
1、数字还好说,都是十六进制,可是这个符号编译过来之后是什么东西,我不知道啊。
2、就算我知道符号是什么二进制,在哪修改又是个问题啊
没关系,继续上大招,自己写一个,再对比(旁白:这么傻的招数真的好意思叫大招?!!)
把之前的工程文件再修改下,使它和反编译出来的那个关键代码完全一样
再编译,再对比。 得出了两个结论
1、 = 是 a8 ,<> 是 b8 ,> 是 C8,< 是 d4
2、在我的测试程序中,那个<号的地址是8120,那个代表5000的8813的地址是7f10 两者相差 0x210,如果没有意外的话,在我的想象中,进销存软件中,代表5000的8813的地址是b7394,加上0x210=B75A4就应该是我要修改的关键判断的代码,按下图进行修改。(不知道为什么这个小于号是D2,好像不同的电脑都会有些区别)
修改完成之后,修改数据库中使用次数为100次,再次打开软件,正常运行
再用shudepb反汇编一下,请看对比图:
成功!
总结:
爆破这个程序只需要用winhex修改如下两个地方
B736A处修改14为00
B75A4处修改D2为C8
就可以无限制使用了。(现在知道为什么我说破解这个只需要2分钟了吧)
程序和破解后的程序我也不提供了,毕竟也不是什么大众的软件,真猜到了就自己破解吧,反正也就两分钟
本文主要是提供思路,以及有以下问题请大神解答:
究竟怎么才能对PB的程序进行动态调试?
真的找不到资料,万一下次用shudepb看不到任何关键代码,我就歇菜了
后续:
后来想修改下程序的标题。发现标题原来是加密后存在config.ini中。
程序每次启动时都从这个中读取密文,解密之后再与程序中内置的几个名称进行匹配,不匹配也是直接退出。
所以要修改的话,需要修改config.ini和程序中的字符串资源
程序中的字符串之所以各种软件都读不到是因为,它在把字符串转为ASCII之后,又转了字节序,如:
吾爱破解对应的ASCII码是
54 3e 72 31 78 34 89 e3
程序中是
3d 54 31 72 34 78 e3 89
根据此办法,以后修改PB的字符串终于可以实现了。
最好有个大神写个工具,针对PB程序搜索字符串。。。。
后续的后续:
目前手上还有一个未完成的任务,就是微信聊天记录读取工具,论坛上的都是旧版的,没有我要的导出成漂亮的HTML的功能。
@风吹屁屁凉大神,能不能把你之前破解的思路大概讲下,我已经油尽灯枯了
对了,请各位看在我这么认真努力的份上,使劲打赏,多谢 !!!!!!!!!!!!!!!!!!!!
不错!论坛PB的分析乃至网络上的都太少了,加进鼓励期待更多分析! tmsdy 发表于 2014-11-19 19:22
使用次数的判断、数据库是否被修改的判断等 是在主程序中,不在pbd中。其它的pbd都是其它的功能模块。。
...
期待哪位高手弄一个就像.NET程序那样的集反汇编,修改,编译三位一体的趁手工具,那么PB其实弄起来是很简单的,这种解释类的语言,其实比汇编语言容易看懂的多了,只是现如今没有针对它用的手术刀{:1_918:} 火钳留名其实小白一个 看不到 但是顶起来 膜拜大神,那个微信聊天记录查看器都往的差不多了,导出html失效的问题是因为导出需要调用它线上的模块,作者把那地址去掉了,其实可以把那内容保存下来,自己换个地址应该就有效了,不影响功能使用就不用保存了吧,破解好像它加了虚拟机?记得不太清楚了,忘的都差不多了,期待你来搞定他! 果然大神啊 分析的很细 话说不能用暂停回溯法搞他吗?,图中不是都看见提示框了么?(原谅我比较小白) 给楼主加分,继续努力。 看到pb的基本不办法了,太难了. PB到底是什么意思?p-code?也不对啊 Hmily 发表于 2014-11-19 18:38
不错!论坛PB的分析乃至网络上的都太少了,加进鼓励期待更多分析!
多谢大神!!!!!
发错版块真是不好意思啊~~
不过,我的问题还没解决 。。。PB怎么动态调试的说。。