电脑为window11系统,用到工具有IDA,Androidstudio,JEB,jadx,frida等,这段时间学习了一下安卓壳的相关知识,将途中所学记录了下来,学习很多大佬的文章所以难免有雷同之处,请见谅。第一代壳主要是对dex/apk文件整体加密,然后自定义类加载器动态加载dex/apk文件并执行。在动态加载dex/apk文件的时候有落地加载和不落地加载,落地加载就是通过DexClassLoader从磁盘加载dex/apk文件,不落地加载就是通过InMemoryDexClassLoader从内存中加载dex/apk文件。app的启动流程通过将原apk进行加密后保存在加壳apk的dex文件尾部,在加壳apk运行时将dex文件尾部加密的原apk文件解密后进行动态加载。
壳代码需要最早获取到加壳apk的执行时机,所以加壳apk的Application实现了attachContextApplication函数,此函数在handleBindApplication函数中通过调用makeApplicaton进行调用,是一个APP进程最早的执行入口。加壳apk需要进行如下操作步骤:一个源程序,即apk。加壳工具。脱壳程序,释放源程序并加载。看到打包这块想起自己之前每次都懒得写脚本,每次都自己手动重打包。。。这个脚本的话,是linux下的,我改写一下命令后,os.popen无法很完美的实现copy等一些命令,copy也很奇怪,推测是无法对和自身所在盘符不同的文件操作,很难受。将文件都复制到了脚本这里,改用了subprocess,签名的时候需要二次输入密码交互所以用run,其他getoutput即可。具体的作用就是将源程序apk和脱壳程序构建成了下面这个脱壳程序要做的就是在启动流程调用Application的attachBaseContext时点释放我们的源程序并将其替换为我们的application实例。添加android:name=".ProxyApplication"还有替换活动为我们脱壳后实际会运行的活动。先将apk文件的dex提出,然后根据之前加壳时在文件中留下的大小信息,将源apk提取出来。然后将apk存储起来。so需要手动提取一下到目标路径。之后需要通过反射替换一下classloader。这里替换classloader的原因需要了解一下双亲委派模式。这样子在之后加载我们的源程序的活动时,可以正常找到类。安装时如果报这个错的话是因为zipaligned工具自身的问题,这里需要添加在application下添加**android:extractNativeLibs="true"**安装时才不会报错。启动的是我们的源程序。jadx里显示的是我们的壳。一代壳的防护性并不高,frida-dump应该几乎是秒杀一代壳,不多赘述。二代壳完全复现的话感觉时间会花费较多,所以我会以这个项目的代码作为学习。340K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6%4N6%4N6Q4x3X3g2U0L8X3u0D9L8$3N6K6i4K6u0W2j5$3!0E0i4K6u0r3L8s2g2G2P5h3g2K6K9i4q4A6N6g2)9J5c8Y4m8Q4x3V1k6V1M7s2c8Q4x3X3g2Z5N6r3#2D9该项目的代码有两个部分,proccessor和shellproccessor是对apk进行字节提取然后重新打包处理成加壳apk的模块,shell模块最终生成的dex和so集成到加壳的apk中。不过在开始前对dex的文件结构有些了解比较好,因为函数抽取,抽取的就是dex文件中的codeitem,具体是codeItem的insns,它保存了函数的实际字节码。processor的工作流程:shell模块工作流程:Androidmainfest.xml在编译为apk时,会以axml格式存放,不是普通可读的形式,该项目采取的ManifestEditor进行解析。对于Androidmanifest.xml,我们主要的操作是,备份原Application的类名和写入壳的代理application类名。也就是在代理Application中实现一些加载dex或者HOOK等操作。提取xml的代码段:
以及还有相应的写入Application类的操作。我们可以随便找一个dex放010里看一下。然后我们具体提取的是CodeItem的insns,insns是函数实现的具体字节码。提取所用工具为安卓提供的dx工具,同样存放在lib目录下。该项目实现的函数是extractAllMethods,具体的实现先不谈了,结果就是读取所有的classdef(一个类的定义)的所有函数,并是否进行函数抽取。提取的数据怎么存储比较好呢,之前遇到的一道题是直接提取出来作为静态值最后填回去了。该项目的话是存储到了instruction结构体里,再看下这个结构体。这个结构体是专门用来存储方法相关的东西的,如偏移,字节码。这个部分是壳的主要逻辑。Hook这个函数是为了使得我们加载dex时修改dex的属性,使其可写,才能将字节码回填。https://bbs.kanxue.com/thread-266527.htm。具体是给__prot参数追加PROT_WRITE属性类加载的调用链LoadMethod中有两个关键参数DexFile和ClassDataItemIteratorClassDataItemIterator结构体的**code_off **是加载的函数的CodeItem相对于DexFile的偏移。所以LoadMethod是一个绝佳的HOOK点。还有就是LoadMethod不同的安卓版本函数声明可能不同,所以需要做一个版本的不同处理,这个也确实在二代壳的ctf题中有看到。填充insnscodeitem的传递是assets/OoooooOooo。重新加载dex并替换dexElements,使ClassLoader从我们新加载的dex文件中加载类。这里还是之前那个双亲委派机制的原因。这就是二代壳的大致过程,但是详细的具体实现没有过多去分析,后续有需求实现的话会再补充一下,这里有一篇dpt-shell分析文章,比我分析的要详细很多https://tttang.com/archive/1728/整体思路就是遍历类加载器主动调用类,然后再进行dump。然后就是在主动调用的同时dump dex,如HOOK loadmethod,进入前获取dexfile结构体然后离开时根据数据信息来dump出已经填充回去的dex。应该是可行的,但是我并没有去实践。事实上hook的时机应该早一些吧,然后再主动调用,不过这只能应付填充后不会再抽取的吧,好像听说有那种填一条运行然后再抽回去的。
最老实的方法就是找到字节码自己填充回去再分析,这是我之前ctf一道题这样干的。。。。
具体可行脚本这里下次遇到了再实践,暂时先留白,上面为gpt生成,请注意甄别。这个就更没有通解了,之后遇到再说吧。基于oacia大佬的文章分析复现的,有很多重合部分,也有一些我个人在分析中的体悟和疑问。https://bbs.kanxue.com/thread-280609.htm加
...(已截断)
---
来源: 看雪论坛
原文链接: https://bbs.kanxue.com/thread-285870.htm
安卓壳学习记录
362 浏览
18 回复
看雪精华帖预定
请问楼主的一代壳实例有自己跑过吗?似乎存在资源加载问题
是一篇很完整的总结文章了,谢谢楼主分享。期待出后续的onCreate变成了native还原的分析文章。
学习了,总结的很到位
相当 nice 的分析文章,从中有学到知识!
饱饱你太强了
分析的非常棒
Shangwendada
这个原因是基地址问题,需要你自己计算linker上去之后的地址
我打印了字节码 与我ida 里看到的字节码 是一样 的 所以问题就很奇怪
这个原因是基地址问题,需要你自己计算linker上去之后的地址
我打印了字节码 与我ida 里看到的字节码 是一样 的 所以问题就很奇怪
真棒
逆天而行
确实 我也遇到与你一样的问题,后面我用魔改的frida(软件能正常打开) 甚至hook不了 linker 加载的so 中的方法
这个原因是基地址问题,需要你自己计算linker上去之后的地址
确实 我也遇到与你一样的问题,后面我用魔改的frida(软件能正常打开) 甚至hook不了 linker 加载的so 中的方法
这个原因是基地址问题,需要你自己计算linker上去之后的地址
xianyuuuan
看雪精华帖预定
排版有问题,估计得改改有个优把
看雪精华帖预定
排版有问题,估计得改改有个优把
确实 我也遇到与你一样的问题,后面我用魔改的frida(软件能正常打开) 甚至hook不了 linker 加载的so 中的方法
XiaozaYa
请问楼主的一代壳实例有自己跑过吗?似乎存在资源加载问题
一代壳加壳工具脚本似乎也存在一定的问题:signature=hashlib.sha1().digest() 这里的消息摘要计算应该是 signature=hashlib.sha1(new_dex_data[32:]).digest()
请问楼主的一代壳实例有自己跑过吗?似乎存在资源加载问题
一代壳加壳工具脚本似乎也存在一定的问题:signature=hashlib.sha1().digest() 这里的消息摘要计算应该是 signature=hashlib.sha1(new_dex_data[32:]).digest()
我当时跑的话,是没有问题的
?????,分析了一大堆,最后也就得出个正常脱壳流程出来的dex,随便一个内存脱效果都一样啊。。。看半天告诉说还差被native的方法没有还原。。。。这就是看雪的质量莫名其妙的看起来深奥的笔记,无语了,你们是想炫技还是想教学呢?能不能想想来时路,你们真的是在为当初的自己打伞吗?