Apk脱壳圣战之 脱掉“360结构加固”的壳

摘要: 一、序言如今流行的结构加固服务平台有:梆梆结构加固,爱数据加密,360结构加固,腾迅结构加固,在以前的一一篇文章中介公司绍了:怎样脱掉 爱数据加密 的壳,如今这儿要脱掉...

一、序言

如今流行的结构加固服务平台有:梆梆结构加固,爱数据加密,360结构加固,腾迅结构加固,在以前的一一篇文章中介公司绍了:怎样脱掉 爱数据加密 的壳,如今这儿要脱掉此外一个服务平台的壳:360结构加固,由于拥有以前的脱壳工作经验,许多基本专业知识和提前准备工作中这儿也不详尽详细介绍了,以便可以脱掉她家的壳,用一个例例来来去去360服务平台开展结构加固,随后开展脱壳。下边就来刚开始脱壳:

 

二、剖析360结构加固的基本原理

最先取得结构加固以后的apk,这儿以便便捷查询內部信息内容,先无需dex2jar+jd-gui专用工具开展剖析了,立即应用大家以前剖析了源代码的一个专用工具:Jadx,立即查询:

 

下边再说看一下他的AndroidManifest.xml文档:

寻找了他的通道Activity了,可是这儿沒有android:debuggable= true ,因此程序不是能被调节的,因此大家必须加上这一特性,随后在开展回编译程序开展调节,这时候候就必须应用到apktool专用工具了:

好啦,这儿见到,360结构加固以便避免apktool反编译程序作用,加上了一个qihoo特性,这一特性apktool不了解就出错了,可是大家以前的一一篇文章早已详细介绍了:Apktool专用工具不正确修补,大家拥有apktool源代码,能够立即开展修补的,随后开展反编译程序:

反编译程序取得成功了,查询他的AndroidManifest.xml文档內容:

确实,是有一个特性qihoo,这一便是Android系统软件在分析apk文档的情况下,发觉不会有的特性立即忽略,可是apktool专用工具却不容易,360结构加固便是运用这一系统漏洞来提升反编译程序难度系数的,可是大家以前的一一篇文章中介公司绍了怎样修补,这儿修补非常简单了。因此说要是拥有apktool源代码,全都好干了。

随后大家在加上android:debuggable特性:

随后回编译程序:

 

这时候候见到,在回编译程序的情况下也是出错了,说找不着这一特性,以便便捷这儿立即把android:qihoo给弄死,由于实际上他沒有一切功效的,便是以便影响反编译程序工作中的,因此立即除掉就可以,随后在回编译程序:

好啦,回编译程序取得成功,随后在开展签字装包就可以。这儿也不在详细介绍了。

 

那麼从上边大家能看到,实际上360结构加固以便避免反编译程序,就运用了Android系统软件自身在分析apk的情况下,碰到不了解的特性立即忽略,而apktool专用工具却不容易的系统漏洞来给AndroidManifest.xml中加上一个搞混反编译程序的特性:qihoo,幸亏大家有源代码,能够修补这一难题,在开展反编译程序就可以,这儿也期待apktool官方网站可以立即修补这一系统漏洞。以便回编译程序取得成功,大家能够立即把这一特性删掉。要不然回编译程序也是会出错的。这一特性仅仅360以便搞混反编译程序工作中,因此删掉对程序逻辑性沒有一切危害的。

 

三、开启系统软件的调节总电源开关

这儿就需要刚开始详细介绍文中的第一个关键了:怎样不在必须反编译程序的状况下,加上android:debuggable特性,便可以开展调节。

这一如今早已有许多专用工具能够干了,先来讲说实际的基本原理吧:

实际上Android中有一些常见的配备信息内容全是储放在一个文档中,例如机器设备的系统软件,版本号号,cpu型号规格等信息内容,而这一文档部位在:

/system/build.prop

大家查询文档的內容,能看到许多机器设备的信息内容,并且这种ro开始的表明这种特性值是写保护的,不可以开展改动的。

同时Android中出示了2个指令来实际操作这种信息内容:getprop和setprop指令:

查询系统软件的sdk版本号号

设定系统软件的sdk版本号号为22,但是这儿并沒有改动取得成功,缘故便是由于ro开始的特性不是容许中后期改动的,改也是能够改动的,必须再次编译程序系统软件镜像系统文档boot.img,可是这儿其实不是自己详细介绍的关键了。

 

即然Android中的一些系统软件特性值储放在一个文档中的,并且这种值是写保护的,自然不但能够根据getprop指令载入,有一个api也是能够立即载入的,便是:System.getProperty( ro.build.version.sdk 实际上这一方式是native层完成的,实际也不剖析了。

那麼这一文档是储存这种特性值的,那麼到底是谁来开展分析载入到运行内存中,可以给每一个app都能浏览到呢?

 

这一工作中便是init.rc过程实际操作的,大家应当掌握了系统软件起动的情况下第一步便是分析init.rc文档,这一文档是在系统软件的网站根目录下,这儿会做许多原始化实际操作,这儿不祥细分化析了,后边再剖析Android中系统软件起动步骤的情况下在详尽剖析。这儿同时候做特性文档的分析工作中,因此,Android 特性系统软件根据系统软件服务出示系统软件配备和情况的管理方法。以便让运作中的全部过程共享资源系统软件运作时需必须的各种各样设定值,系统软件会开拓一个特性储存地区,并出示浏览该运行内存地区的 API。全部过程都可以以浏览特性值,可是仅有 init 过程能够改动特性值,别的过程若想改动特性值,必须向 init 过程传出恳求,最后由 init 过程承担改动特性值。

 

那麼上边说到的是system/build.prop文档。里边关键是系统软件的配备信息内容,实际上也有一个关键文档在网站根目录下边:default.prop:

这儿有一个关键特性:ro.debuggable,对这儿便是关联到系统软件中每一个运用是不是可以被调节的重要。实际上在Android系统软件中一个运用可否被调节是那么分辨的:

当Dalvik虚似机从android运用架构中起动时,系统软件特性ro.debuggable为1,假如该值被置1,系统软件中常有的程序全是能够调节的。假如系统软件中的 ro.debuggable 为0,则会分辨程序的AndroidManifest.xml中application标识中的 android:debuggable原素是不是为true,假如为true则打开调节适用。

 

好啦到这儿,大家能够小结一下了:

Android系统软件中有一个能够调节全部机器设备中的运用的电源开关,在网站根目录中的default.prop文档中的ro.debuggable特性值,假如把这一值设定成1得话,那麼机器设备中常有运用都可以以被调节,即便在AndroidManifest.xml中沒有android:debuggable=true,還是能够调节的。而这种系统软件特性的文档system/build.prop和default.prop,全是init过程来开展分析的,系统软件起动的情况下便会去分析init.rc文档,这一文档中有配备有关系统软件特性的分析工作中信息内容。随后会把这种系统软件特性信息内容分析到运行内存中,出示给全部app开展浏览,这方面信息内容也是运行内存共享资源的。可是这种ro开始的特性信息内容只有init过程开展改动。下边来剖析一下改动这一特性值的三种方法:

 

第一种:立即改动default.prop文档中的值,随后重新启动机器设备

那麼如今假如依照上边的目地:便是不用反编译程序apk,加上android:debuggable特性得话,立即改动default.prop文档,把ro.debuggable特性改为1就可以,可是根据上边的剖析,改动进行以后毫无疑问必须重新启动机器设备的,由于必须让init过程再次分析特性文档,把特性信息内容载入运行内存我国可起功效的。可是并沒有那麼圆满,在实践活动的全过程中,改动了这一特性,結果出現的結果便是机器设备卡死了,实际上想一想也是一切正常的,假如特性可以根据这种文档来改动得话,那么就觉得系统软件会出現各种各样难题了,觉得系统软件不是会让改动这种文档的內容的。

 

第二种:改变系统软件文档,再次编译程序系统软件镜像系统文档,随后刷入到机器设备中

那麼上边改动default.prop文档,結果造成卡死,最后也是沒有改动取得成功,大家也有甚么方法呢?实际上上边早已提及过一次了,便是这种特性文档实际上是在系统软件镜像系统文档boot.img在系统软件起动的情况下,释放出来到实际文件目录中的,换句话说假如大家可以立即改动boot.img中的这一特性就可以,那麼这一实际操作是能够开展的,可是艰难那就是不一一样的圆满,最少我没取得成功过,改动系统软件文档,随后再次编译程序镜像系统文档,最终在刷到机器设备中。这一全过程我试着过是不成功了,但是基础理论上是能够的。并且这类方法假如取得成功了,那麼这一机器设备便是始终能够开展各种各样运用的调节了。

 

第三种:引入init过程,改动运行内存中的特性值

那麼上边立即再次编译程序boot.img,随后在刷到机器设备中的工作中是不成功的,那麼也有别的方式吗?毫无疑问是有的,大家实际上在上边剖析了,init过程会分析这一特性文档,随后把这种特性信息内容分析到运行内存中,给全部app开展浏览应用,因此在init过程的运行内存块中是存有这种特性值的,那麼这时候候就行办了,有一个技术性能够保证了,便是过程引入技术性,大家可使用ptrace引入到init过程,随后改动运行内存中的这种特性值,要是init过程不看重启得话,那麼这种特性值便会见效。好啦,这一方式能够试着,可是这一方式有一个缺点,便是假如init过程挂掉重新启动得话,那麼设定就沒有一切实际效果了,务必再次实际操作了,因此合理期并不是较长,可是一般状况下要是确保机器设备不看重启得话,init过程会一直存有的,并且假如产生了init过程挂了的状况,那麼机器设备毫无疑问会重新启动的。那时候在再次实际操作一下就可以。

 

好啦上边剖析了三种方法去设定系统软件中的调节特性总电源开关,那麼最终一种方法是最可靠的。

这一专用工具使用方法非常简单,最先把exe文件mprop复制到机器设备中的文件目录下,随后运作指令:

./mprop ro.debuggable 1

这一专用工具能够改动运行内存中常有的特性值,包含型号信息内容。

这儿改动进行以后,应用getprop指令在查询值,发觉改动取得成功了,可是必须留意的是,大家改动的是运行内存的值,而并不是文档中的值。因此default.prop文档中的內容是沒有产生转变的。

这时候候,大家可使用Eclipse的DDMS来查询能够调节的运用目录:

自然还可以应用adb jdwp指令来查询能够调节的过程id:

可是可是的是,发觉還是沒有展现机器设备中常有的运用,实际上这儿是有一个关键点难题了,由于大家尽管改动了运行内存值,可是有一个过程大家必须重新启动一下,哪一个过程呢?那么就是adbd这一过程,这一过程是adb的守卫过程,便是机器设备联接信息内容传送后台管理过程,因此爱看到能够调节的过程信息内容得话,那麼必须重新启动这一过程,那样联接信息内容才会升级。

重新启动这一过程非常简单:立即应用stop;start指令就可以

实际上它是2个指令,用分号分隔,最先是弄死过程,随后在重新启动。

运作完指令以后,再去看看DDMS对话框信息内容:

这时候候全部的运用过程全是能够调节的了,这时候候大家在应用dumpsys package指令查询一个运用的包信息内容:

这儿能看到,这一运用的flags标示中并沒有debuggable特性值,可是这一运用是能够调节的。因此见到ro.debuggable这一是总电源开关,要是他为1,打开得话,即便沒有android:debuggable也是能够的了。

 

好啦到这儿,大家来小结一下:

1、大家的目地是如何不在必须反编译程序apk包,加上android:debuggable特性,便可以开展apk的调节?

2、大家根据剖析系统软件特性文档和系统软件起动步骤及其分析系统软件特性文档的步骤,了解了机器设备中有关调节有一个总电源开关特性值:ro.debuggable,默认设置是0,不动启的。那麼这时候候大家便可以猜测有这几类方法能够去改动。

3、剖析了三种方法去改动这一特性值:

第一种方法:立即改动default.prop文档中的这一字段名值,可是可是的是改动不成功,在改动的全过程抽出现卡死,重新启动机器设备以后,特性值還是0。

第二种方法:改动系统软件源代码的编译程序脚本制作,立即改动特性值,随后再次编译程序镜像系统文档boot.img,随后刷入到机器设备中,可是在实践活动的全过程中并沒有取得成功,因此舍弃了,并且这类方法有一个益处便是一旦改动了,要是没有再次刷系统软件,那麼这一字段名将始终合理。

第三种方法:引入到init过程,改动运行内存中的这种系统软件特性值,这类方法完成是非常简单的,可是有一个难题,便是一旦机器设备重新启动,init过程再次分析default.prop文档得话,那麼ro.debuggable值将又再次被清除,必须再度引入改动。

4、最终选用了第三种方法,但是在网上早已有些人写了那样的专用工具,使用方法也非常简单:./mprop ro.debuggable 1;可是改动进行以后,一定要还记得再次起动adbd过程,那样才可以够获得到能够调节运用信息内容。

5、应用专用工具改动进行以后,在Eclipse中的DDMS对话框发觉,机器设备中的全部运用都处在能够调节情况了。换句话说大家的实际操作取得成功了。

 

那麼上边的这一全过程取得成功以后的实际意义還是非常大的:标示着大家之后假如是单纯性的想让一个apk可以被调节,去反编译程序在加上特性值得话,实际上这类方法很高效率的。可让随意一个apk出自于被调节情况。

 

四、刚开始脱壳

说完了上边的一个关键以后,下边大家就刚开始来说解文中的此外一个关键,刚开始脱壳了。

第一步:打开android_server

 

第二步:端口号分享

 

第三步:起动运用

adb shell am start -D -n .e4a.runtime.android.mainActivity

 

第四步:打开IDA,额外过程

 

第五步:设定Debugger Option选择项

 

第六步:运作jdb调节等候

jdb -.sun.jdi.SocketAttach:hostname=127.0.0.1,port=10265

留意:这儿必须留意了,由于大家改了系统软件的ro.debuggable特性,机器设备中常有的运用都处在可调式情况,基本端口号8700早已被占有了,那麼这时候候必须应用被调节程序的特有端口号了,能够在DDMS对话框开展查询。

 

第七步:重要涵数下断点

最先寻找mmap涵数的运行内存详细地址,这儿能够立即应用G键,根据涵数名来自动跳转:

留意:这儿和以前的脱爱数据加密的壳方式将会不一样了,还还记得以前脱爱数据加密的壳的情况下,给fopen和fgets涵数下断点,由于假如有反调节得话,毫无疑问是载入/proc/pid/status文档中的TracerPid字段名值的,随后改动TracerPid数值0就可以,可是这一方式对360结构加固的不太好使了,由于360结构加固的反调节是根据mmap涵数来载入/proc/pid/status,因此这儿必须给mmap涵数下断点了,并且后边还会继续见到给dvmDexFileOpenPartial这一涵数下断点都不管用了,缘故是360结构加固自身在最底层完成掌握析dex的涵数来取代了这一dvmDexFileOpenPartial涵数。可是无论是他自身完成dex分析载入,最后全是必须把dex文档载入到运行内存中,還是得用mmap涵数来开展实际操作。因此在脱360结构加固的壳的情况下mmap涵数是关键。

 

好啦给mmap涵数下了结点,下边就F9运作程序吧:

进到来到mmap的断点处,这儿由于mmap涵数编码较为长,以便节约時间,大家能够在mmap涵数的完毕处下一个断点,随后立即F9运作到涵数的末尾处,由于系统软件中有许多个so必须载入到运行内存中,因此mmap涵数会实行数次,可是实际上大家最关注的是载入大家自身的so文档,即libjiagu.so文档,由于这一才算是大家的native层编码,因此等出現以下页面:

这时候候,表明这一so文档被载入到运行内存中了,也便是程序的native层编码刚开始实行了,留意不可以在F9了,只是应用F8单步伐试:

F8单步运作到这儿的情况下,碰到一个难题,便是F8了许多次,自始至终在这里个地区实行,之后剖析了arm命令以后,发觉原先这儿是一个循环系统,原始值是0,储存在R11中,随后逐渐加1,和R3中储存的阀值作较为,根据查询寄放器的值,发觉R3寄放器中是A7,因此这儿得去改动寄放器R11的值了,要不然大家得单步A7次,这儿立即把R11值改动为A6:

改动寄放器也是非常容易的,立即右击寄放器:

点一下Modify value:

点一下OK,以后再说看一下R11的寄放器的值:

改动取得成功了,这时候候在单步F8,2次以后就实行完后循环系统了,从这儿还可以见到,这一地区也算作以便避免被调节,增加调节成本费的一种方法。再次向下走:

到这儿,实行完BL以后就撤出调节页面了,试着数次都一样,因此猜测反调节毫无疑问在这里里,能够F7跟踪去看看看:

到BLX这儿,每一次以前完也是撤出调节页面,因此这儿还得F7单步进电机入看一下:

这儿见到了一行关键的arm命令:CMP较为命令,并且是和0较为,极可能这儿便是较为TracerPid的值是不是为0,假如不以0就撤出,能够查询R0寄放器的內容:

随后在查询被调节过程的TracerPid的值:

果真R0储存的是TracerPid的值,以便认证恰当性,这儿再次:

果真,运作来到自尽的地区,一直单步运作:

撤出程序了。

 

那麼上边就了解了反调节的地区,就行办了,立即改动寄放器R0的数值0就可以:

随后再次单步F8运作,后边也有一个CMP和0开展较为的地区,大家一样开展置零实际操作,再度单步F8,当运作到这里的情况下:

见到memcpy涵数的情况下,这时候候能够立即运作F9,又会实行到mmap那边,随后先后F9,還是运作来到上边的哪个循环系统,那样先后类推,在这里个全过程中我运作了7次循环系统,改了R0值改了9次,因此这一地区会实行数次是一切正常的,可是这儿在我数次调节以后总了一个好的方式,便是见到数次实行的线路都类似:

mmap涵数=》循环系统=》(MOV R0,R8)BL=》(MOV LR,R4)BLX=》CMP R0,#0=》mmap....

这一全过程中,实际上以便简单大家能够

1》在mmap涵数的刚开始处,完毕处下一个断点,这2个断点是以便后边载入运行内存的dex文档做提前准备

2》在循环系统处下一个断点,这一断点是以便改动循环系统值,节约時间

3》在BL处下一个断点,是以便进到BLX

4》在BLX处下一个断点,是以便进到较为TracerPid处

5》在CMP下断点,是以便改动TracerPid的值

同时在这里个全过程中,必须应用F9,立即自动跳转到下一个断点,高效率,仅有在抵达了CMP处的情况下,要用F8单步伐试,并且这一地区一定要当心,不可以按不对,要不然又得从头开始再说,我吃完许多次亏,也重来啦许多次。要是当见到了memcpy涵数的情况下,再度F9到下一个断点处。更必须留意的是:每一次抵达mmap断点处的情况下,一定需看当今栈信息内容的主视图对话框,看一下是不是出現了classes.dex的字眼,由于最后全是应用mmap来把解密以后的dex载入到运行内存中的,因此这儿一定要留意,是此次调节的关键。

自然这一仅仅本人的调节构思,每一个人都是有自身的构思,要是能取得成功都可以以。

 

就是这样往返搞了几回以后,总算见到了黎明:

当再度赶到了mmap涵数处的情况下,总算见到了classes.dex字眼了,表明这儿刚开始解密dex随后开展载入到运行内存了,这时候候不可以在F9自动跳转了,只是F8单步运作,随后查询R0寄放器的值:

每一次全是实行完__mmap2这一涵数以后,R0就会有值了,每一次见到R0中有值的情况下,能够到Hex View对话框中应用G键刚开始详细地址自动跳转,查询是不是为dex內容:

假如发觉并不是,就還是单步F8,了解mmap涵数完毕,随后再度F9,抵达mmap涵数刚开始处,時刻看紧Hex View,栈对话框,R0寄放器这三个地区的值:

在数次试着以后,总算取得成功了,这儿见到了了解的dex文档的头信息内容,有关dex文档的头顶部信息内容能看本文:Dex文档文件格式分析

因此这儿在头顶部信息内容的第三3个字节数随后持续4个字节数便是dex的长短了,那麼如今拥有dex以内存中的实际上部位,长短尺寸,下边便可令其用Shirt+F2开启脚本制作实行对话框,dump出运行内存中的dex数据信息:

static main(void)
{
auto fp, begin, end, dexbyte;
fp = fopen( E:\dump.dex , wb
begin = 0x755A9000;
//偏位0x20处,取4字节数为dex文档尺寸
end = 0x755A9000 + 0x0004BC38;
for ( dexbyte = begin; dexbyte end; dexbyte ++ )
fputc(Byte(dexbyte), fp);
}

储存到E:dump.dex,随后在应用Jadx专用工具开展查询:

这儿能够查询到源代码了,并且类名,方式名,自变量名全是用汉语来取名的,觉得十分习惯性,可是Java中是适用那么干的,由于Java选用的是Unicode编号的。

 

实例免费下载:detail/jiangwei091041

 

五、脱壳小结

好啦到这儿,大家就取得成功了脱没了360结构加固的壳了,下边来小结一下他的壳的特性和调节必须留意的点:

1、最先360结构加固仍然是外界套一个Application壳:StubApplication,源代码数据加密储放在libjiagu.so,放到了assets文件目录下,在Application起动的情况下,释放出来到运用的沙盒游戏文件目录files下边,随后在应用System.load方式开展载入,这一和爱数据加密的方法是一样的

2、有关360结构加固的反调节,仍然应用的是载入/proc/[pid]/status中的TracerPid字段名值,分辨是不是为0,可是这儿和爱数据加密不一样的是,在学取这一文档的情况下并不是用的fopen系统软件涵数,只是mmap系统软件涵数,因此在处理反调节的情况下必须给这一涵数下断点。

3、360结构加固最底层并不是选用dvmDexFileOpenPartial这一系统软件涵数来分析dex随后载入到运行内存中的,只是自身完成了一个涵数,因此给这一涵数下断点,随后获得主要参数值来dump运行内存中的dex数据信息是难以实现的,可是有一个构思便是无论它用哪一个涵数去分析dex载入到运行内存,最后都得应用mmap这一系统软件涵数来实际操作,因此还得给这一涵数下断点,因此这儿在调节的情况下必须時刻留意的是当断点抵达了mmap涵数处的情况下,必须观查Stack View栈对话框中是不是出現了classes.dex字眼,假如出現了,表明刚开始解密dex文档,提前准备载入到运行内存中了,那麼这时候候必须观查R0寄放器的值,随后在Hex View中自动跳转到特定运行内存详细地址,能够观查到是不是为dex运行内存数据信息

4、在观查是不是为运行内存数据信息的情况下,必须留意dex文档是有自身的文档文件格式的,那麼头信息内容便是个依据,因此大家能够查询开始为:dex.35 那样的內容来分辨这里为dex数据信息,由于dex头顶部信息内容中也是有dex的文档尺寸,那麼这时候候便可令其用脚本制作dump处运行内存中的dex数据信息了。

5、在调节的全过程中,会发觉许多断点数次实行,非常是有一个循环系统,必须大家改动寄放器的值来迅速完毕循环系统,并且在重要处下断点,也是加速调节高效率的。

 

六、技术性概述

1、文中刚开始的情况下详细介绍了根据引入系统软件init过程,改动运行内存中的系统软件特性值:ro.debuggable,让机器设备中常有的运用都可以以被调节,这一作用将对事后反向破译有重特大实际意义,也会省掉了反编译程序的工作中。因此这一方法還是很具备里程数碑实际意义的。

2、在脱爱数据加密的壳的情况下,学习培训来到给fopen和fgets这2个系统软件涵数下断点来处理反调节,在这里里大家又多了一个下断点的好地方便是给mmap下断点,当发觉给fopen涵数下断点不太好使的情况下,在试着给mmap下一个断点吧。

3、在脱爱数据加密的壳的情况下,给dvmDexFileOpenPartial涵数下断点,来获得dex以内存的起止详细地址和尺寸,进而dump处运行内存中的dex数据信息,可是360结构加固并沒有走这一涵数,由于在给这一涵数下断点的情况下,他根本没来到,因此判断它內部应用了别的的涵数去分析dex的,随后载入到运行内存中的,可是假如最终载入到运行内存中,那毫无疑问要采用mmap涵数,因此要是给mmap涵数下断点就可以。

 

 



联系我们

全国服务热线:4000-399-000 公司邮箱:343111187@qq.com

  工作日 9:00-18:00

关注我们

官网公众号

官网公众号

Copyright?2020 广州凡科互联网科技股份有限公司 版权所有 粤ICP备10235580号 客服热线 18720358503

技术支持:凡科小程序