美团Android资源混淆保护实践

前言

Android应用中的APK安全性一直遭人诟病,市面上充斥着各种被破解或者汉化的应用,破解者可以非常简单的通过破解工具就能对一个APK进行反编译、破解、汉化等等,这样就可以修改原有代码的逻辑、添加新代码、添加或修改资源、或者更有甚者植入病毒等等,从而破坏原有APK的安全和用户体验,最终伤害到用户和原有的开发者。 而事物都是有两方面的,有矛就有盾,针对Android应用安全的各种方案应运而生,大家比较熟悉一般是各类加壳加固的工具,我们可以使用这些工具来保护我们的APK,加壳加固是另外一个话题了,我们这里不对加壳加固进行介绍,后续如果有机会会单独开一个话题讨论,我们在开发过程中可以通过ProGuard或者DexGuard来保护我们的代码,从而实现相对的代码安全,但我们的资源呢?我们往往忽略对资源文件的保护,那这里将要分享的是如果采用常规方式对APK中的资源文件进行保护。

资源安全

资源安全这个话题目前大家关注度不算太高,相比较而言大家更关注代码安全,目前市面上各类APP基本都使用了ProGuard来保护代码的安全,但对资源文件的保护力度都不大,其实资源文件是存在比较大的安全隐患,那资源会有哪些安全隐患呢?下面我们通过一个比较简单的例子来说明下保护资源文件的重要性。

我们先用最常见的apktool工具来反编译一个应用来看看,通过运行下面命令就能进行反编译;

    apktool d -s xxx.apk

反编译成功后我们来看下反编译得到的文件结构(见下图);

通过上图中的目录结构,我们可以看到这个应用的资源文件大概有:anim、drawable、layout、menu、values等等,我们可以通过修改这些文件夹下的资源文件,并通过apktool进行回编译(apktool b 命令)就能创建一个经过修改过的APK应用,例如我们修改下图中红色横线所标示的layout文件,就能往原有APK的支付信息(根据资源名称猜测这个layout的意图)中添加一些我们自己的东西;

这个问题主要是因为我们在开发过程中倡导命名的规范性,一般都要求在命名时做到见名知意,这样能够方便我们自己的理解和维护,但同时这也方便了破解者,破解者可以轻松的根据文件名称来猜测这个文件的意图和作用,从而做破坏性的修改。

通过这个例子我们可以看出目前资源安全的重要性,那如何做到资源安全呢?安全都是相对的,没有绝对的安全,我们接下来要讨论的是类似Proguard方式的对我们的资源进行保护。我们主要是通过修改AAPT工具来对资源进行保护,为了方便理解,下面先讲一下Android应用是怎么查找资源的。

Android查找资源的流程

在Android系统中,每一个应用程序一般都会配置很多资源,用来适配不同密度、大小和方向的屏幕,以及适配不同的国家、地区和语言等等。这些资源是在应用程序运行时自动根据设备的当前配置信息进行适配的。这也就是说,给定一个相同的资源ID,在不同的设备配置之下,查找到的可能是不同的资源。 这个查找过程对应用程序来说,是完全透明的,这个过程主要是靠Android资源管理框架来完成的,而Android资源管理框架实际是由AssetManager和Resources两个类来实现的。其中,Resources类可以根据ID来查找资源,而AssetManager类根据文件名来查找资源。事实上,如果一个资源ID对应的是一个文件,那么Resources类是先根据ID来找到资源文件名称,然后再将该文件名称交给AssetManager类来打开对应的文件的。基本流程如下图:

通过上图我们可以看到Resources是通过resources.arsc把Resource的ID转化成资源文件的名称,然后交由AssetManager来加载的。 而Resources.arsc这个文件是存放在APK包中的,他是由AAPT工具在打包过程中生成的,他本身是一个资源的索引表,里面维护者资源ID、Name、Path或者Value的对应关系,AssetManager通过这个索引表,就可以通过资源的ID找到这个资源对应的文件或者数据。

AAPT介绍

AAPT是Android Asset Packaging Tool的缩写,它存放在SDK的tools/目录下,AAPT的功能很强大,可以通过它查看查看、创建、更新压缩文件(如 .zip文件,.jar文件, .apk文件), 它也可以把资源编译为二进制文件,并生成resources.arsc, AAPT这个工具在APK打包过程中起到了非常重要作用,在打包过程中使用AAPT对APK中用到的资源进行打包,这里不对AAPT这个工具做过多的讨论,只看一下AAPT这个工具在打包过程中起到的作用,下图是AAPT打包的流程:

AAPT这个工具在打包过程中主要做了下列工作: 1. 把”assets”和”res/raw”目录下的所有资源进行打包(会根据不同的文件后缀选择压缩或不压缩),而”res/“目录下的其他资源进行编译或者其他处理(具体处理方式视文件后缀不同而不同,例如:”.xml”会编译成二进制文件,”.png”文件会进行优化等等)后才进行打包; 2. 会对除了assets资源之外所有的资源赋予一个资源ID常量,并且会生成一个资源索引表resources.arsc; 3. 编译AndroidManifest.xml成二进制的XML文件; 4. 把上面3个步骤中生成结果保存在一个*.ap_文件,并把各个资源ID常量定义在一个R.java中;

*.ap这个文件会在生成APK时放入APK包中, *.ap 这个文件本身是一个ZIP包,他里面包含resources.arsc、AndroidManifest.xml、assets以及所有的资源文件,下图是UNZIP后的截图:

可以看出*.ap_这个文件中包含的内容,这个文件存放在build/intermediates/res的目录下,下图是这个文件存放的路径截图:

资源保护

我们这里参考Proguard Obfuscator方式,对APK中资源文件名使用简短无意义名称进行替换,给破解者制造困难,从而做到资源的相对安全;通过上面分析,我们可以看出通过修改AAPT在生成resources.arsc和*.ap_时把资源文件的名称进行替换,从而保护资源。 通过阅读AAPT编译资源的代码,我们发现修改AAPT在处理资源文件相关的源码是能够做到资源文件名的替换,下面是Resource.cpp中makeFileResources()的修改的代码片段:

    static status_t makeFileResources(Bundle* bundle, const sp<AaptAssets>& assets,ResourceTable* table,const sp<ResourceTypeSet>& set,const char* resType){String8 type8(resType);String16 type16(resType);bool hasErrors = false;ResourceDirIterator it(set, String8(resType));ssize_t res;while ((res=it.next()) == NO_ERROR) {if (bundle->getVerbose()) {printf("    (new resource id %s from %s)\n",it.getBaseName().string(), it.getFile()->getPrintableSource().string());}String16 baseName(it.getBaseName());const char16_t* str = baseName.string();const char16_t* const end = str + baseName.size();while (str < end) {if (!((*str >= 'a' && *str <= 'z')|| (*str >= '0' && *str <= '9')|| *str == '_' || *str == '.')) {fprintf(stderr, "%s: Invalid file name: must contain only [a-z0-9_.]\n",it.getPath().string());hasErrors = true;}str++;}String8 resPath = it.getPath();resPath.convertToResPath();String8 obfuscationName;String8 obfuscationPath = getObfuscationName(resPath, obfuscationName);table->addEntry(SourcePos(it.getPath(), 0), String16(assets->getPackage()),type16,baseName, // String16(obfuscationName),String16(obfuscationPath), // resPathNULL,&it.getParams());assets->addResource(it.getLeafName(), obfuscationPath/*resPath*/, it.getFile(), type8);}return hasErrors ? UNKNOWN_ERROR : NO_ERROR;}

上述代码是在ResourceTable和Assets中添加资源文件时, 对资源文件名称进行修改,这就能够做到资源文件名称的替换,这样通过使用修改过的AAPT编译资源并进行打包,我们再用上面讲到的apktool这个工具进行反编译,下图是反编译后的截图:

发现什么变化了吗?在res目录下熟悉的layout、drawable、anim、menu等文件夹不见了,那他们去哪了呢?因为apktool工具把它们放到了unknown文件夹下了,见下图:

让我们来看一下unknown文件夹,你会发现资源文件名已经被简短无意义名称进行替换了,这样会给反编译者制造理解上的困难,反编译者需要消耗一定的时间来搞清楚这些资源文件的作用,资源混淆带来的另外一个好处是能明显减小APK的大小,资源混淆既能保护资源文件的安全又能减小安装包的大小,那我们何乐而不为呢?

这样通过修改AAPT,我们可以在代码零修改的基础下就能做到相对的资源安全,当然安全是相对的,没有绝对的安全。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/477993.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

搞不懂,为啥现在什么公司都在考算法???

昨天在知乎上刷到一个热门问题:程序员需要达到什么水平才能顺利拿到 20k 无压力&#xff1f;其中一个最热门的回答是&#xff1a;“其实&#xff0c;无论你是前端还是后端、想进大厂还是拿高薪&#xff0c;算法都一定很重要。”为什么&#xff0c;算法会如此重要&#xff1f;不…

OpenKG开源系列 | 中文高中地理知识图谱CKGG(南京大学)

OpenKG地址&#xff1a;http://openkg.cn/dataset/ckggGitHub地址&#xff1a;https://github.com/nju-websoft/CKGG数据地址&#xff1a;https://doi.org/10.5281/zenodo.4668711论文地址&#xff1a;https://doi.org/10.1007/978-3-030-88361-4_25开放许可协议&#xff1a;CC…

LeetCode 892. 三维形体的表面积(数学)

1. 题目 在 N * N 的网格上&#xff0c;我们放置一些 1 * 1 * 1 的立方体。 每个值 v grid[i][j] 表示 v 个正方体叠放在对应单元格 (i, j) 上。 请你返回最终形体的表面积。 示例 1&#xff1a; 输入&#xff1a;[[2]] 输出&#xff1a;10示例 2&#xff1a; 输入&#x…

淘宝数据,数据处理,时间序列分析,获客分析,购买路径分析

-- 创建数据库 create database taobao; use taobao; desc use_behaviour;-- 创建表格 create table use_behaviour( user_id int(9), item_id int(9), category_id int(9), behaviour_type varchar(5), timestamps int(14));-- 查询已导入多少条 select count(*) from use_…

谁说发 paper 一定要追快打新?2021年,研究 word2vec 也能中顶会!

文 | jxyxiangyu前言“小夕&#xff0c;小夕&#xff0c;你关注的任务sota又被刷新了&#xff01;”“什么&#xff1f;&#xff01;”还在跑实验的小夕默默流下了辛酸泪不得不说nlp领域的发展真的太快了&#xff0c;炼丹师们不光要时刻关注前沿热点&#xff0c;还要快速做出实…

论文浅尝 | Multilingual LAMA: 探索多语言预训练语言模型中的知识

笔记整理&#xff1a;谭亦鸣&#xff0c;东南大学博士生来源&#xff1a;EACL‘21链接&#xff1a;https://aclanthology.org/2021.eacl-main.284.pdf概述本文关注将语言模型&#xff08;LM&#xff09;视作一个知识库&#xff0c;然后用于解决例如句子填空这样的NLP任务&#…

LeetCode 860. 柠檬水找零(贪心)

1. 题目 在柠檬水摊上&#xff0c;每一杯柠檬水的售价为 5 美元。 顾客排队购买你的产品&#xff0c;&#xff08;按账单 bills 支付的顺序&#xff09;一次购买一杯。 每位顾客只买一杯柠檬水&#xff0c;然后向你付 5 美元、10 美元或 20 美元。你必须给每个顾客正确找零&…

召回粗排精排-级联漏斗(下)

文 | 水哥源 | 知乎saying召回区分主路和旁路&#xff0c;主路的作用是个性化向上管理&#xff0c;而旁路的作用是查缺补漏。推荐系统的前几个操作可能就决定了整个系统的走向&#xff0c;在初期一定要三思而后行。做自媒体&#xff0c;打广告&#xff0c;漏斗的入口有多大很重…

学术联赛 | 运用知识图谱技术,赋能多领域应用 ——“未来杯”AI学术联赛总决赛暨颁奖典礼圆满落幕...

本文转载自公众号&#xff1a;AI学习社。由北京大学软件工程国家工程研究中心主办&#xff0c;华为终端有限公司及中软国际教育科技集团全程战略支持&#xff0c;STEER TECH科技平台、北京乐智元素科技有限公司、艾肯文化传媒&#xff08;北京&#xff09;有限公司、AI TIME承办…

LeetCode 1013. 将数组分成和相等的三个部分

1. 题目 给定一个整数数组 A&#xff0c;只有我们可以将其划分为三个和相等的非空部分时才返回 true&#xff0c;否则返回 false。 形式上&#xff0c;如果我们可以找出索引 i1 < j 且满足 (A[0] A[1] … A[i] A[i1] A[i2] … A[j-1] A[j] A[j-1] … A[A.lengt…

谷歌 | 多任务学习,如何挑选有效的辅助任务?只需一个公式!

文 | 小伟编 | 小轶前言说到多任务学习&#xff0c;大家都不陌生&#xff0c;不管是在学术界还是工业界都已经有了很多成熟的探索与应用。在理想的多任务学习中&#xff0c;各个任务对彼此应当是有益的&#xff0c;所有任务相互促进&#xff0c;从而达到超过单任务学习的效果。…

LeetCode 888. 公平的糖果交换(哈希set)

文章目录1. 题目2. 解题2.1 暴力查找2.2 哈希set1. 题目 爱丽丝和鲍勃有不同大小的糖果棒&#xff1a;A[i] 是爱丽丝拥有的第 i 块糖的大小&#xff0c;B[j] 是鲍勃拥有的第 j 块糖的大小。 因为他们是朋友&#xff0c;所以他们想交换一个糖果棒&#xff0c;这样交换后&#…

OpenKG开源系列 | 面向知识的推理问答编程语言KoPL(清华大学)

OpenKG地址&#xff1a;http://openkg.cn/tool/koplGitHub地址&#xff1a;https://github.com/THU-KEG/KoPL网站地址&#xff1a;https://kopl.xlore.cn开放许可协议&#xff1a;MIT License贡献者&#xff1a;清华大学&#xff08;曹书林、史佳欣、姚子俊、吕鑫、聂麟骁、逄凡…

前端组件化开发实践

前言 一位计算机前辈曾说过&#xff1a; Controlling complexity is the essence of computer programming.随着前端开发复杂度的日益提升&#xff0c;组件化开发应运而生&#xff0c;并随着 FIS、React 等优秀框架的出现遍地开花。这一过程同样发生在美团&#xff0c;面临业务…

LeetCode 937. 重新排列日志文件(自定义排序)

1. 题目 你有一个日志数组 logs。每条日志都是以空格分隔的字串。 对于每条日志&#xff0c;其第一个字为字母数字标识符。然后&#xff0c;要么&#xff1a; 标识符后面的每个字将仅由小写字母组成&#xff0c;或&#xff1b;标识符后面的每个字将仅由数字组成。 我们将这…

预训练时代微调新范式,高性能加速2800%,NLPer赶紧看过来!

一、导读PaddleNLP 是兼具科研学习和产业实践能力的 Python NLP 工具包&#xff0c;提供中文领域丰富的预训练模型和部署工具&#xff0c;被高校、企业开发者广泛应用。近日&#xff0c;PaddleNLP v2.1正式发布&#xff0c;为开发者带来三项重要更新&#xff1a;开箱即用的工业…

论文浅尝 | GaussianPath: 用于知识图谱推理的贝叶斯多跳推理框架

笔记整理&#xff1a;谭亦鸣&#xff0c;东南大学博士生来源&#xff1a;AAAI’21链接&#xff1a;https://ojs.aaai.org/index.php/AAAI/article/view/16565多跳推理由于对下游任务例如问答和图谱补全的可解释性受到关注。多跳推理是一个典型的顺序决策过程&#xff0c;可表述…

AllenAI 发布万能问答系统 MACAW!各类题型样样精通,性能大幅超越 GPT-3!

文 | python前言GPT-3 等超大规模预训练语言模型&#xff0c;在少监督任务&#xff08;few-shot tasks&#xff09;上取得了令人瞩目的成绩。而这篇文章中&#xff0c;AllenAI的研究员提出了大规模生成式问答模型&#xff0c;MACAW。基于多角度预训练&#xff0c;MACAW可以用于…

论文浅尝 | SMBOP: Semi-autoregressive Bottom-up Semantic Parsing

笔记整理&#xff1a;陈永锐&#xff0c;东南大学博士来源&#xff1a;NAACL 2021概述近年来语义解析的事实上的标准解码方法是使用自顶向下的深度优先遍历对目标程序的抽象语法树进行自回归解码。该工作提出了一种替代方法&#xff1a;半自回归自底向上解析器&#xff08;SMBO…

美团酒店Node全栈开发实践

前后端分离的背景 “前后端分离”显然已不是什么新鲜的话题&#xff0c;Zakas在2013年10月份就曾发表过一篇博客《Node.js and the new web front-end》讨论Node背景下新时代的前端。毫无疑问&#xff0c;Node的出现给JavaScript语言带来了新的生机&#xff0c;也使得前端开发者…