非虫的加固总结:http://www.mottoin.com/89035.html
非root hook:
hook需要更改目标内存空间,应用进程本身当然可以,该进程是属于一个用户的。别的用户想动其它用户的进程就需要权限了,同一个用户动自己的其它进程当然也可以。因此原理上免root hook可实现。
动态符号表dynsym hook
hook掉关键函数(jni_Onload)从而阻止一般断点。基本思路:
- 获取动态库基址(文件头中无,在加载时系统生成的信息中)
- 计算加载头表program header table实际地址
- 取动态信息表dynameic地址
- 取dynsym地址(动态导出导入符号表,有so中定义的各种符号地址)
- 遍历符号表,找到地址对应后更改
ps:代码段一般都只会设置为可读可执行的,因此需要使用mprotect改变内存页为可读可写可执行。
GOT是将代码段所使用的其它模块的函数地址、全局变量地址提出,用别的模块中的函数填入,从而间接使用外部函数。
外部引用查的是什么?如果是提前加载好的全局表应该改节无用,应该是用时查找节。因为该指针函数可以被使用说明全局表已经加载过了。但这个全局表没有给jni用?linker、jni的具体查找函数并调用过程!
将指向后的地址加跳转也行。
相关结构体:
通过符号表hook got
通过重定位表hook got
资源混淆
resources.arsc这个文件是存放在APK包中的,他是由AAPT工具在打包过程中生成的,他本身是一个资源的索引表,里面维护者资源ID、Name、Path或者Value的对应关系。https://www.jianshu.com/p/3cc131db2002
通过resources.arsc这个桥梁,使R.类+名(这个组合名可以锁定资源,给人看的,二进制中只是id)的int值还原到type+名,从而可以用android框架寻找加载资源。
例如value/string.xml添加名-值生成的R.string.名使用该值,编译为id。使用时resources.arsc中通过id找到对应的分类与名,value下的几个分类都被打包在resources.arsc里了,所以string资源可以直接在resources.arsc中通过种类加名找到。还有些xml被加密放在原处(layout),还有些没加密放原处(mipmap):这些按类就是文件夹,名就是文件名路径就能查找到。在Android系统中,Resources类可以根据ID来查找资源,而AssetManager类根据文件名来查找资源
混淆只是将还原时的type+名改变,同时将res中文件名改变。没有做到资源加密。
针对图片加密:当图片资源放在drawable中的时候,能有相应的Id去解析: BitmapFactory.decodeResource(res, id)
如果放置在assets下,就需要根据文件的名字去解析(Android提供AssetManager)。
若使用id解析,其实是框架中的Resources类先根据ID来找到资源文件名称,然后再将该文件名称交给AssetManager类来打开对应的文件的。但是这个过程由框架实现无法更改,所以若自己写应用时加密方式可采用手动从assets中提取自定义加密文件。
若针对任意apk如何加密资源?(所有资源-layout、string、图片特别关注)其实这些都可以手动加载,但是如何在不大量改代码情况下实现自动化。