首页
社区
课程
招聘
[原创]听鬼哥说关于个别软件的保护绕过分析
发表于: 2014-8-18 12:11 29888

[原创]听鬼哥说关于个别软件的保护绕过分析

2014-8-18 12:11
29888

听鬼哥说关于个别软件的保护绕过分析
软件介绍:跟电脑上面的按键精灵类似
目的:免费使用

第一步:分析软件的相关功能



通过简单使用软件,可以得到以下几点:
1.软件未注册版本只能使用30分钟;
2.可以通过注册码,注册文件两种方式注册;
3.原包正常可用,除使用时间限制外其他功能正常

第二步:猜测可用突破点

1.根据提示可使用30分钟进行突破
在res/values.xml中发现相关内容”toast_tryTime”,表示我们可以这样做.
2.分析注册码相关使用算法,写出相关注册机代码
在lib/libjni.so中发现相关注册算法,这样方式可用.
其实到这里先简单说一下,如果上面两种方式可用,那么就很简单,此文也就不必写出的,所以有耐心的同学继续往下看,这里写我的分析过程,方便同学们以后遇到软件的思路拓展。

第三步:开始尝试

我们先进行简单的,去根据限制时间的提示寻找上下文内容。



通过相关搜索,可以看到只有一个gt.smali文件。
下面已经对这个字符串使用的上下文写了注释,直接参考一下即可。



注释已经很详细了,最简单的,我们直接修改那个判断if-nez改为if-eqz即可。或者可以根据这个判断的含义,在if-nez上面写上一句
const/4 v0, 0x1 ,不等于0则跳,我们写做1,肯定直接跳到下面的执行流程上,而不执行提示使用限制时间。

好了,我们重新打包,运行测试。。。。



然后运行我们刚才录制的一段脚本,然后提示如上图所示。
前面两步测试已经说过,软件所有功能都正常使用,所以这里有错误提示,那么我们就继续跟进错误查看。
Unicode编码一下,继续搜索:有两个文件都存在,这里只列举一个



相关代码已经注释清楚,这里我们还按照简单的思路走,修改if的判断,(搜索出来的文件,都修改下)然后重新打包,继续运行。。。

又提示其他错误了。。。



然后又是一段漫长的过程,追踪代码,然后到最终无果。。。

到了这里,我们就应该思考,软件是不是有其他验证,否则的话,我们上面的修改就已经起作用了。

第四步:再次思考

通过上面的尝试,我们猜测到软件有防护,所以我们从注册方面入手,查看smali中注册的相关内容,第三步中,已经发现那个a()方法是注册成功与否的标志,那么我们跟进。



看到上图的注释,我们可以了解,这里是通过检测本地的一个文件,取出三个数值,来调用valid方法判断软件是否注册,这三个字符串具体的含义,我们稍后分析。

从这里,我们则继续看valid方法,那个是主要判断注册成功与否的方法。



看到这里,我们就有眉目了,是调用的so里面的算法了,那么我们就挂起IDA来继续分析,同时,如果核心代码在so里面,那么我们只修改so而可以不用对dex进行任何操作,所以这里我们可以先观察看看,排除此软件的验证是对dex的。



说起来修改so,有难的,有简单的,这里我们是通过java代码跟进,所以知道这里这个方法的返回值是布尔类型的,所以,最简单的方法,不外于直接返回数值true。

查看一下上下文,发现有这个,名称简单猜测,是打开调试Log的信息,这里,我们需要的是他的代码,即



Movs                 r0,#0
BX                 LR
了解ARM汇编的,很容易看出这个代码意思,将0赋值给R0,然后执行返回方法。
所以这里我们需要修改的是将true,也就是1赋值给R0,然后返回。

点击Hex-View查看一下:
Mov  R0,  #0   对应的16进制为 00 20
BX   LR       对应的16进制为 70 47

我们简单修改一下,将这四个字节改为 01 20 70 47,然后点击Apply Changes ,(快捷键F2),查看IDA-View 窗口,发现一切正常,那我么就直接操作valid方法去:



如上图所示,我们就修改完了,一切正常,那么我们就记录下内存,movs  R0 ,#1的地址,然后用010Editor之类工具跳转到对应地址,修改为上面所述4个字节,好了,这样起码我们没有对dex进行任何操作,那么如果此软件是对dex进行验证的话,那么我们就可以直接绕过了。

注明:不熟悉ARM语法的直接找找资料看即可,网上很多,上面的修改是为了方便叙述介绍其他地方引用相关指令来直接修改,熟练掌握arm汇编,自己计算即可。所以这里不必问如果此so没有类似指令,是不是就不能破解了这类问题了。

我们使用zip打开apk包,替换掉lib/libjni.so , 然后签名重新运行。

再次运行后,我们发现软件已经注册成功:



但是在播放脚本的时候,还是出错,错误又回到了我们最初修改dex时候的。



好吧,到这里再做一步,对软件原包进行重新签名,安装运行。。。

一样的错误,所以,现在我们应该确定是签名或者md5类的验证了。

大致浏览了下smali和so,都没发现验证,功力太低,没办法。。

那么我们就继续想其他方法吧

第五步:打坐思考

经过了上面一系列的操作和尝试,我们现在应该静下心来思考一下了。。。

目前我们还可使用的方法如下:
1.分析注册算法
2.不操作原包的情况下修改,即hook方面的

跟进valid方法,就可以追寻到注册算法相关内容了,我动态调试了下:



相关参数之类的,看着不是太难,不过本身我C++方面能力比较差,从恢复重写算法来说难度还是比较大,所以也先放弃了这个方法。

然后我们就想hook方面的东西吧,反正注册成功与否的判断方法我们有了,那么接下来操作就应该比较简单了。。。

话说,手里的hook代码还有很多bug,时灵时不灵的,于是向朋友求助索取了一份hook代码,目前还没看完,所以这里先不用hook的方法,等我分析完毕之后,重新补充下。。。

此软件的使用,必须是root情况下的,所以手机肯定必须得root,那么,我们有root,又是本地使用的,何必再多费心思呢。

于是shell下进入data/data/net.aisence.Touchelper/lib下面



记得修改下权限之类的。。。

现在大家就知道要做什么操作了,我们直接rm libjni.so文件,然后将上述第四步修改完毕的so直接替换一下不就行了。

然后重新打包,运行,播放一个脚本,没限制时间提示,打开注册状态页面,显示已经注册。。。

通过上述操作,我们已经可以正常使用此软件了,那么,软件是不是每一次都会重新还原覆盖lib这个文件夹呢?

其实,测试不测试,都没啥太大效果了,因为我们必须有root权限的,如果会还原那么现在我们还没使用hook方式的时候,我们直接重新写个apk来操作lib文件夹下libjni.so的替换不就是了,权限够大,没啥事的,就是每次使用麻烦一点而已。

或者,可以直接写个apk来启动触摸精灵,然后启动软件几秒钟后,替换那个文件。。

第六步:更好方式的破解

看到这里,相信大家对上述的操作都有了了解,上文都是采用比较简单的方式来破解的,但是还有更好的方法破解,因为时间和技术问题,上文没有对那些方法进行继续分析使用,例如直接hook掉这个函数,再或者写个注册机,有兴趣的朋友,欢迎继续分析下去,发出来文章分享~

排盘看的不舒服的,可以直接下载doc文档即可

原包,这里就不上传了,做个软件不容易,这里只提供思路分析。。

听鬼哥说关于个别软件的保护绕过分析.doc

补充上一些动态分析的过程,可以查看到注册相关东西,有兴趣的请继续完善注册。

CM

使用cydia那个hook框架,已经写出来hook java的相关代码,稍后写出文章。。

使用hook的方法测试,相关代码和分析都写在博客里面,有兴趣的可以参考,测试。。

http://blog.csdn.net/guiguzi1110/article/details/39023349


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

上传的附件:
收藏
免费 3
支持
分享
最新回复 (32)
雪    币: 76
活跃值: (13)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
mark  收藏
2014-8-18 12:14
0
雪    币: 185
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
赞美小鬼的分析,先坐再看
2014-8-18 13:11
0
雪    币: 729
活跃值: (1306)
能力值: ( LV9,RANK:160 )
在线值:
发帖
回帖
粉丝
4
mark  鬼哥
2014-8-18 14:29
0
雪    币: 3901
活跃值: (6150)
能力值: ( LV13,RANK:550 )
在线值:
发帖
回帖
粉丝
5
不错。。学习了.
2014-8-18 15:03
0
雪    币: 94
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
mark鬼哥。向鬼哥学习!
2014-8-18 17:04
0
雪    币: 5
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
感觉很不靠谱,你有测试可以无限循环超过30分钟吗
2014-8-22 23:44
0
雪    币: 507
活跃值: (130)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
8
你看一下30分钟的上下文,了解下软件正常的执行流程,就明白了
2014-8-23 12:33
0
雪    币: 5
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
按你说的,试了下,只有四分钟了-_-||
2014-8-23 20:44
0
雪    币: 507
活跃值: (130)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
10
(⊙o⊙)…楼上留个邮箱给我,或者私信发我一下,我发你我改完的so试试吧,我这边无限循环开着,无压力的
用IDA中操作的,修改然后查看是正常,但是IDA是没有修改so的,只是辅助分析而已,保存的是你分析当前文件的数据库。
而没有用010Editor之类16进制工具跳转到对应地址进行修改,修改后修改权限所以多次使用测试后,相当于没有替换so,30分钟的时间到期的..
有时间希望楼主一起来研究下这个注册算法,达到一劳永逸的效果最好~
2014-8-24 21:17
0
雪    币: 11096
活跃值: (17617)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
很认真的分析文章,来支持了
2014-8-24 21:31
0
雪    币: 253
活跃值: (107)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
感谢分享,只要移动so档案,就会造成程式异常。
2014-8-28 03:15
0
雪    币: 507
活跃值: (130)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
13
得修改相应权限的。chomd 777 libjni.so

此软件在测试的时候是有一些问题:
替换后,修改一下权限,可以使用一段时间。
一段时间后,应该是超过30分钟以后,程序好像是会还原成最初的那个so,也就是试用版的,不过试用版的我开了50分钟好像是没问题了。
希望有时间,跟楼主一起分析掉那个注册算法,直接做好注册机,达到一劳永逸的效果。
这个注册算法,在IDA动态调试时可以看到的,有密钥,输入的注册码,IMEI等相关信息,这几天正在看c++相关资料,希望楼主能早一步搞定~

今天有时间的话,我继续分析下注册算法看下,希望有兴趣的朋友一起来搞哈~
2014-8-28 10:14
0
雪    币: 253
活跃值: (107)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
您注册算法的地方追错了,不是那,应该是另外一个地方,注册机应该不太容易,我全部追完了,卡在RSA 1024Bit的私钥没有(要算不容易,可以去研究看看,目前还没人破成功),没办法写注册机,大概只能强破了。

关键在License::init中
2014-9-1 13:49
0
雪    币: 507
活跃值: (130)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
15
init:方法是检测的时候调用的,不是注册的哦。

可以看一下那个xrefs的引用~init方法被TouchelperLicense_time和TouchelperLicense_valid这两个方法所调用,一个是检测注册的有效期时间,一个是检测是否已经注册。

在动态调试的时候,对 doRegister 下断点,然后在输入序列号之后,则会断住,帖子上我也更新了那个CM.rar的压缩包,是一些动态调试的截图。

同时,我已经给您发邮件了,是我对这个软件使用cydia那个框架写的个java注入的代码和分析,请批评指正~~
2014-9-1 20:00
0
雪    币: 253
活跃值: (107)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
我想你还是搞错了,你追到最后的东西是要传到对方伺服器的东西。他会回传一个key.dat档案到你手机中的/data/data/net.aisence.Touchelper/license/key.dat,这个跟注册文件激活是一样的档案,他开启程式后会来检测这个档案,"License::init:方法是检测的时候调用的,不是注册的哦",这完全是不对的,他是用来检测档案是否正确,并会用License::decrypt->RSA_public_decrypt来让RSA用公钥解码,成为注册档案,在用License::valid来验证是否注册完成。
下面是公开金钥:(E, N)
#define MODULUS "00e33741e366d4f209e5e24f702a0fa644e51a99ee6d4b156c801e1789f70aed0c9b1f40dd232300897a44bd28b60560ff3e84d1fa493aa00fdcdcc69be7753e8975765a9a6472eade77373677769fb95e7d7f89208d1af67a210bd75ce2487564c53779602b38f73d272f5763985866744edb644dcde4d5ec0223ec6bd0c0f5df"
#define PUBLIC_EXPONENT 65537
只是很奇怪的,我用IDA去追输入128byte的资料总是返回-1,我用C++写得却OK,最后就是要推算私钥运气好的话几个月,运气不好的或几年。
2014-9-1 22:29
0
雪    币: 10
活跃值: (82)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
ibk
17
怎么不顺便把文件上传上来
2014-9-2 15:09
0
雪    币: 253
活跃值: (107)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
没文件,自己创一个吧。
2014-9-2 15:14
0
雪    币: 113
活跃值: (633)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
只该valid是无效的,假破解,还有个暗桩,不知道lz什么版本,我说的最新版
2014-9-11 10:47
0
雪    币: 253
活跃值: (107)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
当然有暗桩,把libtouchelper.so Dump出来就可以找到了,只要Key.dat正确就可以绕过。
2014-9-11 17:03
0
雪    币: 113
活跃值: (633)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
我是用另一种方法再加上hook so绕过验证的,只是在提醒lz这样还是不完全
2014-9-15 12:27
0
雪    币: 253
活跃值: (107)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
错了,我已经Dump出来了,档案跟3.3.0差不了多少,暗桩位置也一样,改完在加密回去,并更改libinit.so的参数(或者把RSA的KEY更改,直接写一个Key.dat也可以),几乎就可以了,新出来的3.8.4还没改就初始化错误,有人跟我一样吗?
2014-9-15 14:52
0
雪    币: 507
活跃值: (130)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
23
@peecehood @ztxbeyond ,两位朋友方便的话,可以简单写下文字过程。最近一直在忙着写代码,没怎么继续深入研究此软件了,两位的方法看着都可行。修改密钥,修改验证方法,都可以保证软件正常使用。
2014-9-16 00:49
0
雪    币: 253
活跃值: (107)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
本着志在研究,不为破解为目的(其实购买也很便宜,能支持就支持吧,不过我这边不太好买),大概说一下我是怎样破的好了(不详细说明只说过程)。
首先我已经把所有暗桩拔了,测试好几个小时OK,总共修改档案有三个libinit.so、libjni.so、libtouchelper.so,安装之后他会把所有so放入data,第一次执行,会把libinit.so改名为.tedaemon放入bin中(libeditor.so也会,但不是重点),然后执行脚本利用这个so执行档来做libtouchelper.so解码并动态连结,之后就开始执行脚本。
三个目的:
一、libtouchelper.so解码之后修改两个暗桩,一个是libjni.so与libinit.so的MD5比对利用(比对的延迟时间是用乱数,因此破解不完全就会不定时跳出),另一个是三十分钟。
二、libinit.so只要apk签名有改libtouchelper.so解码就会错误(你有办法解码就有办法知道哪里错误)。
三、libjni.so就照鬼谷子c教程改就好了。

另一种方式:
一、libjni.so修改Key.dat公钥。
二、libtouchelper.so解码之后修改Key.dat公钥,并更改加密方式,必须跟新的签名一样,将libjni.so的MD5修改libinit.so不变。
三、自己跑出Key.dat。
2014-9-16 23:48
0
雪    币: 253
活跃值: (107)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
@ztxbeyond 也说说吧,如何HOOK,SO?
2014-9-17 00:20
0
游客
登录 | 注册 方可回帖
返回
//