说三道四技术文摘-感悟人生的经典句子
说三道四 > 文档快照

Andorid APK反逆向解决方案:梆梆加固原理探寻

HTML文档下载 WORD文档下载 PDF文档下载
Android市场充斥着大量的盗版软件,让“如何使程序代码免受盗版篡改”成为开发者面临的头等大事。通过梆梆加固对App进行加固保护,可有效防止应用在运营推广过程中被破解、盗版、二次打包、注入、反编译等破坏。

目前Android市场充斥着大量的盗版软件,开发者的官方应用被“打包党”们恶意篡改。如何使程序代码免受盗版篡改就成了开发者面临的头等大事,今天我们将分析一个不错的解决方案——梆梆加固


梆梆加固

通过对App进行加固保护,梆梆可以有效防止移动应用在运营推广过程中被破解、盗版、二次打包、注入、反编译等破坏,保障程序的安全性、稳定性,对移动应用的整体逻辑结构进行保护,保证了移动应用的用户体验。

一、梆梆加固逆向分析过程

首先我们通过对APK加固前后文件结构的比较,来了解梆梆加固对APK文件所做的处理。为了使分析过程足够简单,我新建一个最简单的测试程序,并上传到梆梆加固,整个加固过程大概需要4天的时间才可以完成,这是一个漫长的等待过程。

该测试程序包含了Activity、Service、ContentProvider、BroadcastRecevier四大组件、Application、普通类、Jni调用等7类对象,目的就是全面的了解梆梆的加固效果。

1. apk加固前后静态文件结构及动态运行时对比分析

(1)加固前后静态文件结构变化(左为加固前,右为加固后)


加固后apk新增以下文件:

  • assets\meta-data\manifest.mf  //APK文件列表SHA1-Digest
  • assets\meta-data\rsa.pub        //RSA公钥信息
  • assets\meta-data\rsa.sig         //数字签名文件
  • assets\classes.jar                    //已加密原classes.dex文件
  • assets\com.example.hellojni    //ARM平台二进制可执行文件
  • assets\com.example.hellojni.x86  //x86功能同上
  • libs\armeabi\libsecexe.so        //ARM平台共享库文件
  • libs\x86\libsecexe.so               //x86功能同上

加固后修改文件:

  • AndroidMainfest.xml  //(如果应用配置有Application信息,则该文件加固前后相同,如果应用未配置Application信息,则该文件加固前后不相同,梆梆会配置Application信息为自己实现类)
  • classes.dex

对classes.dex进行反编译,观察代码树结构变化:(左为加固前,右为加固后)

 

(2)加固前后动态运行时变化

运行原程序,系统仅创建一个相关进程,但是加固的程序,系统会为其同时创建三个相关程序进程:


进程启动顺序:597进程创建605进程,605进程又创建了607进程

通过查看maps文件获取597进程映射文件信息:


通过map文件可以看出,597进程为主进程,Android各组件在该进程中运行。

605和607进程并无与apk文件相关文件信息,通过cmdline查看启动参数:

初步怀疑该进程为assets\com.example.hellojni可执行文件运行结果。

2. 梆梆加固保护效果分析

我们通过逆向分析加固后的app,来看看梆梆加固对app的保护效果。

程序代码的第一执行点是Application对象,首先查看TestApplication类对象。


程序的Util类完成大部分的java层逻辑:


ACall类主要完成对libsecexe.so JNI的调用:


查看libsecexe.so文件导出函数,发现所有函数名都经过加密处理,与我们平时jni调用产生的函数名并不同。平时jni产生的函数名应该为这样格式:Java_com_secapk_wrapper_ACall_{函数名}。


抗静态分析:

  • Util类通过MyClassLoader完成对加密classes.jar的动态加载,内存中解密classes.jar,完成动态加载。
  • jni方法对应so函数名的混淆。

抗动态调试: 

  • 当使用IDA动态调试该程序时,程序无法建立连接调试。

梆梆加固可以常用的有效的逆向分析方法。

二、梆梆加固技术实现关键点猜想

1. 如何使DexClassLoader动态加载组件具有生命周期?

根据APK文件是否在AndroidManifest.xml配置Applicaiton信息,梆梆加固会做不同的处理。

通过上传Applicaiton不同配置的APK文件,我们发现:

  • 当APK配置有Applicaition信息时,梆梆加固重写Application类
  • 当APK未配置Application信息时,梆梆加固新建类,并在AndroidManifest.xml中配置自己Application类


因此Applicaiton就是程序的第一执行点。

我们知道DexClassLoader加载的类是没有组件生命周期的,也就是说即使DexClassLoader通过对dex的动态加载完成了对组件类的加载,当系统启动该组件时,还会出现加载类失败的异常。我已经在“Android APK加壳技术方案”中提出了一种使DexClassLoader加载组件类具有生命周期的方法。

运行加固后的程序并通过Mat内存分析工具查看类加载情况:


如上图所示,组件类的加载类已经被修改为com.secapk.wrapper.MyClassLoader类,可以得出结论,该方式和我提出方式基本相同,通过修改系统组件类ClassLoader来实现。

2. 如何混淆native方法在so库函数对应关系?

jni方法注册方式有两种:

  • 通过javah产生函数头,该种方式产生的方法具有固定的格式。该方式使逆向分析人员比较容易获取java层native方法对应的本地方法。
  • 在JNI_OnLoad方法中手动注册jni方法,不易查找对应关系。

使用第二种方式可以实现混淆java层native方法和so函数的对应关系。

#include <string.h>#include <jni.h>JNIEXPORT jstring JNICALL abcdefghijklmn( JNIEnv* env,jobject thiz ){    return (*env)->NewStringUTF(env, "Hello from JNI !");}JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved){	JNIEnv* env = NULL;	jint result = -1;	if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_4) != JNI_OK) {		return JNI_ERR;	}    JNINativeMethod gMethods[] = {	    { "stringFromJNI", "()Ljava/lang/String;", (void*)abcdefghijklmn },    };	jclass clazz = (*env)->FindClass(env, "com/example/hellojni/HelloJni");		if (clazz == NULL) {		return JNI_ERR;	}	if ((*env)->RegisterNatives(env, clazz, gMethods, sizeof(gMethods) / sizeof(gMethods[0])) < 0){		return JNI_ERR;	}	/* success -- return valid version number */	result = JNI_VERSION_1_4;	return result;}

以上代码中的字符串都是明文(比如“stringFromJNI”),如果这些文明字符串都换成密文的话,再通过运行时解密,相应的对应关系更不易看出。

3. 如何使DexClassLoader加载加密的dex文件?

虽然不了解梆梆加固是怎么做的,不过通过分析它的运行逻辑,我推测了一种可行的实现方案:了解该方案需要对Android DexClassLoader的整个加载流程需要有清晰的了解。

首先推断assets\classes.jar是一个加密的jar包。正常的DexClassLoader加载的流程如下:会有一个DexOpt产生odex过程。但是梆梆加固后的应用DexClassLoader加载过程并没有该过程的log信息。


推断加密的jar包里面含有odex文件,如果不是odex文件的话,DexClassLoader肯定会在运行时释放未加密的odex文件到目录,这样的话被保护的逻辑也就泄露了。

DexClassLoader加载过程会在java层和C层产生不同的数据结构,java层并没有实质性的数据,所有的数据都在c层,我们可用通过底层代码完成dex数据的解析。底层dex分析是可以支持byte[]数组的,解密odex数据,传递过去就行了。这样java层就可以调用了。

以下是大概伪代码实现步骤:

int loadDex(char * dexFileName){char *dvm_lib_path = "/system/lib/libdvm.so";void * handle;DvmGlobals gDvm;handle = dlopen( dvm_lib_path, int mode);

  • 读取dexFileName文件内容并解密到byte数组。

调用dexFileParse函数解析byte数组为DexFile

\dalvik\libdex\DexFile.c

DexFile* dexFileParse(const u1* data, size_t length, int flags)//dlsym(handle, "dexFileParse");

  • 调用allocateAuxStructures转换DexFile为DvmDex(由于该方法为static方法,因此需要按照其逻辑自行实现)。

\dalvik\vm\DvmDex.c

static DvmDex* allocateAuxStructures(DexFile* pDexFile) 

  • 添加DvmDex到gDvm.userDexFiles

\dalvik\vm\Init.c

struct DvmGlobals gDvm; //gDvm = dlsym(handle, "gDvm");

  • 修改MyDexClassLoader中的mDexs对象的mCookie值

mCookie主要用于映射底层DvmDex数据——DexClassLoader.mDexs[0].mCookie值

4. so如何实现程序的反调试?

同Linux反调试基本原理相同,这里提供一种方式就是在JNI_Onload中调用ptrace方法,ptrace被广泛用于调试(比如IDA)和进程代码注入(比如LBE,金山等权限管理功能实现),一个进程只能被一个进程ptrace,如果你自己调用ptarce,这样其它程序就无法通过ptrace调试或者向您的程序进程注入代码。

ptrace(PTRACE_TRACEME,0 ,0 ,0);

通过本人实验,该种方式可以实现so的反调试。

三、总结

通过以上分析,梆梆加固的确可以有效防止移动应用在运营推广过程中被破解、盗版、二次打包、注入、反编译等破坏,不过如果Android恶意软件也通过这种方式加固保护,这将会给移动安全分析人员带来巨大的挑战,因为安全分析人员经常使用的代码静态逻辑分析和动态调试分析在该情况下都失效了。

梆梆官方声称不会对恶意软件进行加固,的确在加固的过程中发现存在安全软件扫描信息和云测试处理流程,不过这些措施只能减少而不能彻底杜绝恶意软件通过梆梆加固保护。如何不被恶意软件利用是梆梆需要解决的问题。

文章来源:jiazhijun'Blog

(责编/唐小引)

VB如何在VB和Delphi中快速实现立体化窗口显示 VB如何在VB中实现绘图区的大十字光标 VB如何在VB中制作不回显的文本框 VB如何制作浮动式窗口 闪烁的Label-VB资料 设定StatusBar的文字成不同的颜色-VB资料 设计一个可中断循环的按钮-VB资料 设置“执行无用户界面”-VB资料 生成一个透明窗体 -VB资料 实现窗体内部的左右移动 -VB资料 实现鼠标移到窗口上时变大,移出窗体时变小(如《东方快车》)-VB资料 实现图片平铺于窗体中-VB资料 使程序的标题条闪烁 -VB资料 使窗口总在最前 -VB资料 使窗体右上角的X按钮失效 -VB资料 VB使用 WIN95 的选择目录对话框 使指定窗口总处于其他窗口之上 -VB资料 通用对话框专辑(全) -VB资料 透明的Form上显示背景透通图 -VB资料 图像在图片框中的滚动 -VB资料 拖动无标题窗口-VB资料 拖动无系统标准标题栏的窗口-VB资料 文本框中光标位置的获得-VB资料 无关联程序时开启“打开方式”窗口 -VB资料 显示 Combo 的下拉条 -VB资料 显示Windows系统的标准ABOUT窗口-VB资料 显示程序的版本 -VB资料 显示窗口的水平和垂直滚动条-VB资料 一劳永逸让VB自动改变控件大小 移动没有标题栏的窗口 -VB资料 隐藏Win95任务栏 -VB资料 Interbase树形结构和递归调用问题,高手请进!!急!!!! 如何选出表中相同的纪录? 下面这些对编程风格的说法是否正确? Interbase树形结构和递归调用问题,高手请进!!急!!!! 请教dos中有没有类似notify的命令用于邮件通知 java有没有RTTI(runtime type information) 在DOS下开发软件,应该如何调用扩展内存? 高分求:Antechinus C# Editor4.2c和JavaScript Editor的注册码! 想自己做个字典软件,但是没有词库 怎样做个链接?链接邮件地址。 如何在工具栏statusbar的右下角(最后一个panel里)做一个走动的时钟 大家讨论一下开发JSP Web站点用什么工具比较好? 我想编一个网页管理软件,有如下要求。。。 大家帮看一下,加注释的一句是什么意思 高分求救!!有关数据同步!! 北京的程序员薪水如何(6000/月)? 大放分﹗﹗即放即給﹗﹗ 关于WinSock通信 我用怎样得到过滤后有多少条记录呢? 存储过程问题,还有些小麻烦,帮帮忙呀,谢谢:) 急~~!关于ChildView类的问问题~~!!请大家帮助。谢谢。 怎么用Container Managed Persistence EntityBean实现对数据库的增删改,最好用jsp调用 如何知道光驱是打开的还是关闭的??? 程序运行一会儿,BDE 数据库引擎空间不够,什么原因?? 在asp.net里怎么引用word对象,和对它进行操作??? 这个问题不好弄! 讨论:关于使用UDP作为服务器主要协议会碰到的问题? 我安装的rh8.0中,/dev/里的东东怎么都是0字节啊?! 请教,有什么工具能把jpeg图片转换为mpeag1视频,使它能在vcd上观看 如何指定PB6.5访问oracle9 i的默认用户名 多线程资源释放的问题 高手救命!!用pb如何实现用热键调出程序的功能 浏览帖子的问题 高难度:列表视图的重绘问题 编写active控件的问题 报错:变量使用了一个VbScript中不支持的Automation类型oMail.send 青帮忙解释一下一段关于显示VARRAY中数据的PL/SQL语句? 有什么工具能转real ->wmv or wma? 有一点点难。 近来十分不爽。大家进来聊天吧 如何让CEdit控件可以输入希腊字母 如何在asp中实现报表打印的问题,急! 平生第一次看演唱会---张学友温州演唱会。张学友真的老了,满脸的沧桑,但诗歌还是唱得那么好…… 数据库中的<input>的问题 早班火车 蓝色心情 三笑大法 般若什么密忘光光啦~ 角落的青苔:射手无弓?混得好糗啊 jennyvenus JennyVenus 你们违约,哼!!!!!!!!!!!!!!!! 请问在jsp或别的java程序中如何调用Delphi做的com组件?问了很久,没人知道吗? 关于JSP支持问题。 求一小段代码! 我有一个点连接<a href="setup/XXXX.exe">下载</a>但我想点下后既要下载还想用用Response.Execute(XXX.asp)来执行一个页面,该怎么做? 请问Delphi的编辑框中,是不是没有自动感应的功能! 注册dll组件,除了regsvr32,还有其它方法吗? document.layers返回是个什么值呢??各位大哥指点一下吧 宁海水泵日夜抽水 800亩水稻暂保平浙江多地高温致旱 杭州农田灌溉设备紧杭州市市管领导干部任前公示通告浙江试点公办初中小学教师校长交流制度浙江建公办初中小学教师校长“县域内”今年杭州市区40℃以上的高温日是之前杭长高铁上跨特大连续桥江山合拢浙江启动抗旱Ⅲ级应急响应 40多万人国家开发银行7亿资金 支持天台山景区杭城上周七天气温破四 本周将告别40浙江遭遇历史罕见旱灾 41.7万人饮杭州为抗旱抽水灌溉农作物 林区实施禁新昌昨44.1℃成最高纪录 杭本周仍杭州地铁5号线余杭段开始勘察 力争明杭州初拟用水应急预案 限制游泳等高耗因高温干旱 浙江103条小河断流82金华明起降雨增多 周末最高温或降至3杭州近100万亩农作物受灾 市财政拿金华市委常委钟关华兼任武义县委书记张鸿铭看望慰问坚守岗位的一线工作人员杭州改革行政审批 基建项目从15个月愿化身石桥,只为等你从桥上过皇马公布欧冠对马竞19人大名单,C罗职场中有这13种烂个性,别想成功了!每日七言 | 活得累是因为心里装了多孤岛曼哈顿:飓风月收入多少才适合贷款买房?看了这个答99%去香港的游客不知道可以这么玩!安帅:要想首回合一样踢球,已准备点球广西将实施阶梯气价 对你来说是降价还油条菜粥他为什么要娶一个妓女? | 一个温暖百名中国工艺美术大师战略联盟签约仪式恒大客场0-0战平FC首尔,小组头名借着Leap Motion入华,再来追踪引关注 各方努力下贺州市区小学午黑莓也做起了触屏手机 别人都可以唯独Google很可能于本月15日在印度男女之间的暗号,你知道多少呢?WCBA新赛季赛程出炉,延续南北分区亚洲海鲜展享誉回归因为一杯水而倒闭的餐厅,看完你明白了
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn 说三道四技术文摘