Android聚合SDK母包反编译出包教程

news2025/2/24 21:34:51

文章目录

  • 【前言】
  • 一、SDK预处理
    • 1、SDK资源合并
      • 1.1、合并res目录下的资源
      • 1.2、合并libs目录
      • 1.3、合并assets目录
      • 1.4、合并AndroidManifest.xml
      • 1.5、合并jar
    • 2、jar转smali
      • 2.1、jar 混淆合并
      • 2.2、jar转dex
      • 2.3、dex转smali
  • 二、母包apk反编译
    • 1、删除母包模板代码
      • 1.1、删掉母包SDK相关的代码:
      • 1.2、删掉插件化加载官方SDK代码:
      • 1.3、删掉AndroidManifest.xml中插件化相关节点(ssbb开头的)
    • 2、修改包名
      • 2.1、读取旧包名
      • 2.2、修改为新包名
      • 2.3、修改旧包名相关的smali文件
    • 3、修改版本号
    • 4、修改版本名
    • 5、设置目标SDK版本/最小SDK版本号
    • 6、修改应用名
    • 7、修改启动页
    • 8、修改应用icon
  • 三、资源合并
    • 1、dex方法数超出`65535`
  • 四、回编译
  • 五、apk签名
    • 1、v1签名(即jar签名)
    • 2、v2签名
  • 六、apk对齐

【前言】

  现在不管是游戏发行,亦或者是游戏买量,都会涉及到1个游戏项目出N个游戏包的情况,在游戏发行场景,1个游戏需要上架多个安卓应用市场,比如:上架oppo、vivo、小米、华为、应用宝、九游之类,那么1个游戏包就需要出包含不同渠道SDK的分包;在游戏买量场景,1个游戏也是需要上架多个推广媒体渠道,比如:上架头条、快手、广点通、百度之类,同时在推广时候往往还需要出各种马甲包,那么1个游戏就需要出好几百个分包,要是每一个游戏包都让研发去对接出包,研发肯定直接给撂摊子不干了。

  1个解决方案是游戏发行或者买量方(后面简称:SP)出一个聚合SDK给研发接,研发接入完成之后,连同游戏代码打包成aar给回SPSP再在IDE中打出不同渠道的分包,这样研发只需要出1个包,可以大大减少了研发的工作量,但是SP自己的工作量并没有减少,依然还是得手动去打N多个包,要是出上百个包的话,估计不吃不喝,一天下来都干不完;当然这个过程也可以通过脚本去实现,不过得熟悉打包涉及的每一个步骤,这样也是可以节省很多时间;

  另1种解决方案也是出一个聚合SDK给研发对接,研发接入完成之后,打一个可以正常运行的apk给回SPSP再反编译把其他渠道的SDK放进来,然后回编译成新的apk,这种方案要是手动实现,难度系数比第1种方案更大,不仅需要熟悉打包涉及的每一个步骤,还需要熟悉apk反编译相关的知识点,同时也得用脚本实现才能达到节省时间的目的;

 鉴于第1种方案比较简单就不在这里展开阐述,下面主要针对第2种解决方案进行讲解

一、SDK预处理

 一般来说,我们SDK某个功能的实现都会引用到第三方SDK代码,比如:获取OAID SDK、媒体渠道SDK、手机号一键登录SDK、推送SDK等,那么第一步就需要把所有用到的SDK进行合并:

1、SDK资源合并

1.1、合并res目录下的资源

  • res目录一般包含以下几个常见的目录:
    layout:存放布局文件
    anim:存放动画定义文件
    drawable/mipmap: 存放图片文件
    color:存放自定义颜色文件
    menu: 存放菜单定义文件
    xml:存放一些配置文件,比如:网络配置、provider配置
    raw:存放不进行压缩的文件
    values:存放字符串、主题样式、颜色、属性、尺寸等的配置文件
  • 合并res目录文件时候,可能会出现文件名冲突的问题,所以这就要求我们在开发自己的SDK时候,需要尽量避免跟第三方SDK的文件名出现冲突,可以在对我们文件命名时候,统一加个前缀,比如:Facebook的资源文件名都会加上com_facebook前缀
  • 同时,需要注意的是,对于values目录下xml文件,比如:
    SDK1 的sdk1_strings.xml中包含<string name="app_name"> xx1</string>
    SDK2 的sdk2_strings.xml中包含<string name="app_name"> xx2</string>
     那么,就算两个SDK的资源文件名是不一样的,但是由于xml中包含相同的节点,到回编译时候还是会报错,所以,需要在资源合并时候把相同的节点处理掉,一种解决方案是可以将sdk1、sdk2 values目录下的所有xml文件都写入到一个新的xml文件中,这里暂且命名为values.xml,每写入一个节点可以判断values.xml中是否存在,若是存在则不再写入,这样就能确保不会存在多个相同节点。

1.2、合并libs目录

目前libs目录主要是包含以下几个常见目录:

  • x86: 可运行于Intel 32/64位处理器的机器,目前比较少见,一般是比较老旧的机子,性能低
    x86_64:可运行于Intel 64位处理器的机器,目前基本模拟器用得比较多
    armeabiIntel 32/64处理器与ARM 32/64处理的机器都能运行,但是性能低,相当于在绝大多数手机上都是需要辅助ABI或动态转码来兼容
    armeabi-v7a:可运行于ARM 32/64位处理器的机器,性能比armeabi高一点,比arm64-v8a低,适用于早期的手机
    arm64-v8a:可运行于ARM 64位处理器的机器,目前市面上的安卓手机基本都是ARM 64位处理器了

     合并libs目录需要注意的是,需要确保libs目录下对应架构目录的so文件是一致的,比如:SDK1 适配 armeabi-v7aarm64-v8a,但是SDK2 只适配armeabi-v7a, 那么合并之后,就只能保留armeabi-v7a这一个目录,要不在ARM64的手机运行时候,因为会优先加载arm64-v8a目录下的so文件,但是在arm64-v8a目录又没有SDK2的so文件,这会就会闪退!

1.3、合并assets目录

 合并assets目录,只要文件名没有出现冲突就OK了

1.4、合并AndroidManifest.xml

 把多个SDK AndroidManifest.xml文件的配置整合到一个AndroidManifest.xml中,需要注意是去掉重复的声明,比如:重复的权限声明、重复的meta-data声明等

1.5、合并jar

 把所有SDK的jar都复制到到同一个文件夹jars中,若是aar中的jar,由于默认的文件名都是classes.jar,故需要根据aar的文件名,重新命名一下,再复制到jars

2、jar转smali

2.1、jar 混淆合并

 混淆主要是用到Android SDK的proguard,一般在SDK的tools/proguard/目录下可以找到
1)一般手动调用proguard去混淆的话,需要在proguard-rules.pro文件增加java与android类库的依赖:

# 一般在sdk/platforms/android-31/目录下
-libraryjars <android.jar的绝对路径>
# 一般在jdk1.8.0_131/jre/lib目录下
-libraryjars <rt.jar的绝对路径>

2)在proguard-rules.pro文件声明需要进行混淆的jar(-injars)以及混淆之后输出的jar(-outjars)
 在这里基本就是把jars目录下所有的jar都写上去即可

-injars <jar1的绝对路径>
-injars <jar2的绝对路径>
-injars <jarN的绝对路径>
-outjars <混淆输出jar的绝对路径>

3)proguard执行混淆的命令

java -jar proguard.jar -ignorewarnings  @<proguard-rules.pro的绝对路径>

【备注】
 假如你不想混淆,但是你又想把jars目录下所有jar合并成一个jar的话,也可以借助proguard命令去实现,你只需在proguard-rules.pro文件声明keep所有的类即可

-keep class **{*;}
-keep interface **{*;}

2.2、jar转dex

 使用android SDK的dx命令即可,一般在android sdk/build-tools/30.0.3/dx.bat目录,也可以直接使用android sdk/build-tools/30.0.3/lib/dx.jar, 命令如下:

java -jar dx.jar --dex --no-warning --output=<dex的输出路径> <需要转dex的jar路径>

 正常情况来说,用上述命令将jar转换成dex即可,但是假如需要转dex的jar里面所包含的方法数超过65535,上述命令就会抛出异常,需要改为用以下命令来处理:

java -jar dx.jar --dex --multi-dex --no-warning --output=<dex存放目录的路径> <需要转dex的jar路径>

 当然除了用dx, 新版的android sdk还可以选用d8来将jar转为dex

java -cp d8.jar "com.android.tools.r8.D8" --lib android.jar --output <dex存放目录的路径> <需要转dex的jar路径>

2.3、dex转smali

 将dex文件转为smali文件,主要是用到baksmali这个jar, 对每个dex依次执行以下命令即可:

java -jar baksmali-2.5.2.jar d -o <smali输出的目录> <需要转smali的dex路径>

二、母包apk反编译

 apk反编译主要是用到Apktool 这个工具,只需简单执行一下以下命令就能将apk反编译为smali文件:

java -jar apktool_2.6.1.jar d <母包apk的绝对路径> --only-main-classes -f -o <反编译输出目录的路径> 

 其中,--only-main-classes 指定只反编译apk根目录下classes[0-9].dex,否则假如assets目录下存在dex文件也会被反编译;
-f 强制清空输出目录
 接下来,简单聊一下反编译之后的一些常见操作

1、删除母包模板代码

1.1、删掉母包SDK相关的代码:

smali/com/sswl/template
smali/com/sswl/templatesdk
smali/com/sswl/channel

1.2、删掉插件化加载官方SDK代码:

smali/ssbb
assets/sswl.so

1.3、删掉AndroidManifest.xml中插件化相关节点(ssbb开头的)

2、修改包名

2.1、读取旧包名

从反编译AndroidManifest.xmlmanifest节点读取package属性的值,这个值就是旧包名,先记录下来,暂且记为oldPackageName

2.2、修改为新包名

manifest节点的package属性值设置为新包名,然后用新包名字符串,全局替换掉AndroidManifest.xml文件中旧包名的字符串

2.3、修改旧包名相关的smali文件

1)将旧包名下的所有smali文件都复制到新包名下,同时删掉旧包名下的所有文件
2)遍历所有的smali文件(注意多个smali文件夹的情况),将旧包名字符串替换成新包名, 包括xxx.xxx.xxxxxx/xxx/xxx两种字符串
3)遍历所有layout文件,将自定义view中跟旧包名字符串替换成新包名,包括xxx.xxx.xxx这种字符串

3、修改版本号

manifest节点的versionCode属性值设置为新版本号即可

4、修改版本名

manifest节点的versionName属性值设置为新版本名即可

5、设置目标SDK版本/最小SDK版本号

查找manifest节点下的uses-sdk节点,若是有找到,把android:targetSdkVersion 的值改为新的值即可,若是没找到新增一个uses-sdk节点在manifest下即可,设置最小SDK版本号同理

<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="11" android:versionName="1.0.11" package="com.sswl.cloud">
    <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="29"/>
</mainfest>

6、修改应用名

1)从AndroidManifest.xml application节点中读取android:label属性的值
2)若是@string/xxx这种格式,则是引用了strings.xml中的值,需要去strings.xml中修改xxx节点的值
3)若是硬编码,即直接就是应用名,则直接修改android:label的值即可

7、修改启动页

有时需要增加品牌的闪屏或者隐私政策页,则需要修改母包的启动页
1)在AndroidManifest.xml application节点下遍历所有的activity节点
2)判断activity节点是否包含属性为android:name="android.intent.action.MAIN"的节点
3)若是包含,则是找到了母包启动activity,将其android:name的值记录下来,并将其包含android:name="android.intent.action.MAIN"节点的intent-filter节点删掉
4)将新增的闪屏activity节点添加的application节点下,并在activity节点添加intent-filter声明指定是启动页

<intent-filter>
     <action android:name="android.intent.action.MAIN" />
     <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>

5)在新的闪屏页显示结束之后,需要设置跳转回原来的启动页

8、修改应用icon

1)从AndroidManifest.xml application节点读取android:icon的值
2)若值是@drawable/xxx,则是引用了drawable目录下的图片, 只需把对应尺寸大小的新icon图片放进去替换掉旧的即可

  • drawable-ldpi: 36 x 36
  • drawable-mdpi: 48 x 48
  • drawable-hdpi: 72 x 72
  • drawable-xhdpi: 96 x 96
  • drawable-xxhdpi:144 x 144
  • drawable-xxxhdpi:192 x 192

3)若值是@mipmap/xxx,则是mipmap目录下的图片,也是按对应尺寸替换掉旧的即可

  • mipmap-ldpi: 36 x 36
  • mipmap-mdpi: 48 x 48
  • mipmap-hdpi: 72 x 72
  • mipmap-xhdpi: 96 x 96
  • mipmap-xxhdpi:144 x 144
  • mipmap-xxxhdpi:192 x 192

三、资源合并

第一步处理完整之后SDK资源,合并到母包反编译后对应资源目录即可,合并处理逻辑同SDK资源合并一致,需要注意的是:

1、dex方法数超出65535

 要是把SDK的.smali代码全部都放进去smali目录下就有可能在回编译时候,因dex方法数超出65535而报错,最简单的一种解决方案是:直接在smali目录的同级目录下新增smali_classesN目录,把SDK的.smali代码放到新增的目录,假如母包反编译的目录结果是这样子:
在这里插入图片描述
 那么,可以新增smali_classes3目录,再把SDK的.smali代码复制过去,若是.smali代码本身有多个目录,则可以继续新增smali_classes4smali_classes5以此类推

四、回编译

借助Apktool进行回编译即可,回编译命令如下:

java -jar apktool_2.6.1.jar b <母包反编译输出的目录> -f -o <回编译apk的绝对路径>

五、apk签名

由于回编译的apk是未签名的apk,故还需要进行签名操作

1、v1签名(即jar签名)

利用jdk的jarsigner进行签名,一般是在jdk1.8.0_131/bin目录下

jarsigner -verbose -keystore <签名文件的绝对路径> -signedjar <已签名apk的绝对路径> <待签名的apk路径> <签名文件别名> -storepass <储存密码> -keypass <钥匙密码>

2、v2签名

建议选用V2签名,使用apksigner进行签名,一般是在android sdk/build-tools/30.0.3目录下,apk在安装时候,校验签名效率更高,安全性也更高

 apksigner sign --ks <签名文件的绝对路径> --ks-key-alias <签名文件别名> --ks-pass pass:<储存密码> --key-pass pass:<钥匙密码> --out <已签名apk的绝对路径>  <待签名的apk路径>

六、apk对齐

v1签名的apk是签名之后再对齐,v2签名的apk需要先对齐后签名,对齐用到zipalign.exe,一般在android sdk/build-tools/30.0.3目录

zipalign  -v 4  <待对齐的apk文件路径>  <已对齐的apk文件保存路径>

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

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

相关文章

初识C++ (五)

作者&#xff1a;小萌新 专栏&#xff1a;初阶C 作者简介&#xff1a;大二学生 希望能和大家一起进步 内容简介&#xff1a;本文会简单的介绍auto关键字 还有nullptr关键字 加油&#xff01; 初识Cauto关键字c语言之前的用法C中的新用法auto使用细则auto不能使用的场景1. 未初…

直击固定资产管理痛点,让企业轻松管理海量固定资产

随着固定资产数量和种类、人员、分支机构越来越多&#xff0c;固定资产管理难度加大。传统人工表格管理固定资产的方式在具体实施过程中&#xff0c;会有种种痛点。 1)资产种类繁多&#xff0c;存放地分散且人员变更频繁&#xff0c;管理难度大。 2)盘点费时费力&#xff0c;手…

云原生Kubernetes 基本概念和术语

一、概述 Kubernetes 中的大部分概念如 Node 、 Pod 、 Replication Controller 、 Service 等都可以看作一 种“资源对象”&#xff0c;几乎所有的资源对象都可以通过 Kubernetes 提供的 kubectl 工具&#xff08;或者 API 编程调用&#xff09;执行增、删、改、查等操作并将…

工作中何如来合理分配核心线程数?

文章目录一 回顾1.1 使用线程池的优点1.2 任务类型1.3 IO密集型任务确定线程数1.4 CPU密集型任务确定线程数1.5 混合型任务确定线程数一 回顾 1.1 使用线程池的优点 降低资源消耗&#xff1a;线程是稀缺资源&#xff0c;如果无限制地创建&#xff0c;不仅会消耗系统资源&…

学习笔记-Windows 安全

Windows 安全 注 : 笔记中拓扑图 drawio 源文件在其图片目录下 免责声明 本文档仅供学习和研究使用,请勿使用文中的技术源码用于非法用途,任何人造成的任何负面影响,与本人无关. 大纲 漏洞利用 LOL RDP 命令行开启RDP多开连接记录凭据窃取绕过组策略限制绕过本地安全策略限制…

手机浏览器怎么下载视频,第三方手机浏览器下载视频的方法

在我们的手机中&#xff0c;总少不了一款手机浏览器。很多人经常使用手机浏览器看视频&#xff0c;那么如何在网页中将喜欢的视频下载下载下来呢&#xff1f;下面给大家讲解UC浏览器、多御安全浏览器、QQ浏览器下载视频的方法&#xff0c;有需要的朋友可以继续往下看。 UC浏览器…

如何写成高性能的代码(三):巧用稀疏矩阵节省内存占用

稀疏矩阵的概念 一个mn的矩阵是一个由m行n列元素排列成的矩形阵列。矩阵里的元素可以是数字、符号及其他的类型的元素。 一般来说&#xff0c;在矩阵中&#xff0c;若数值为0的元素数目远远多于非0元素的数目&#xff0c;并且非0元素分布没有规律时&#xff0c;则称该矩阵为稀…

【数据结构】详解顺序表(图解)

目录一、顺序表的概念1.1、静态顺序表1.2、动态顺序表二、接口实现2.1、开辟一个动态顺序表及初始化2.2、顺序表的增容2.3、顺序表的尾插及尾删2.4、顺序表的头插及头删2.5、顺序表在pos处插入及删除数据2.6、顺序表的销毁及打印2.7、顺序表的查找及修改一、顺序表的概念 顺序表…

【linux/docker】解决ORA-28000: the account is locked

项目场景&#xff1a; oracle11g客户端连接失败 问题描述 java.sql.SQLException: ORA-28000: the account is locked 原因分析&#xff1a; 由于oracle 11g 在默认在default概要文件中设置了密码最大错误次数为10&#xff0c;“FAILED_LOGIN_ATTEMPTS10”&#xff0c;密码错误…

单商户商城系统功能拆解25—营销中心—优惠券

单商户商城系统&#xff0c;也称为B2C自营电商模式单店商城系统。可以快速帮助个人、机构和企业搭建自己的私域交易线上商城。 单商户商城系统完美契合私域流量变现闭环交易使用。通常拥有丰富的营销玩法&#xff0c;例如拼团&#xff0c;秒杀&#xff0c;砍价&#xff0c;包邮…

NumPy数组基础

一、NumPy数组属性 首先我们先了解一下NumPy 数组属性。NumPy 的数组中比较重要 ndarray 对象属性有&#xff1a; 属性说明ndarray.ndim秩&#xff0c;即轴的数量或维度的数量ndarray.shape数组的维度&#xff0c;对于矩阵&#xff0c;n 行 m 列ndarray.size数组元素的总个数…

Python应用开发——串口通信

Python应用开发——串口通信 目录Python应用开发——串口通信前言1 环境搭建2 硬件准备3 代码编写与测试3.1 简单测一下串口收发3.2 补充细节3.3 完善整个收发流程结束语前言 在嵌入式开发中我们经常会用到串口&#xff0c;串口通信简单&#xff0c;使用起来方便&#xff0c;且…

20:访问者模式

1&#xff1a;定义 封装一些作用于某种数据结构中的各元素的操作&#xff0c;它可以在不改变这个数据结构的前提下定义作用于这些元素的新的操作。 2&#xff1a;结构 访问者模式包含以下主要角色: 抽象访问者&#xff08;Visitor&#xff09;角色&#xff1a;定义了对每一个元…

Matlab 高光谱遥感数据处理与混合像元分解

教程从基础、方法、实践三方面对高光谱遥感进行讲解。基础篇&#xff0c;站在学员的角度去理解“高光谱”&#xff0c;用大家能听的懂的语言去讲述高光谱的基本概念和理论&#xff0c;帮助学员深入理解这项技术的底层科学机理。方法篇&#xff0c;将高光谱技术与MATLAB工具结合…

Yolov5:强大到你难以想象──新冠疫情下的口罩检测

初识Yolov5是看到一个视频可以检测街道上所有的行人&#xff0c;并实时框选出来。之后学习了CNN卷积神经网络&#xff0c;在完成一个项目需求时&#xff0c;发现卷积神经网络在切割图像方面仍然不太好用。于是我想到了之前看到的Yolov5&#xff0c;实战后不禁感慨一句&#xff…

50天50个前端小项目(纯html+css+js)第十八天(背景轮播图)

今天要做的是一个轮播图&#xff0c;不过是属于全屏类型的轮播图&#xff0c;先来看看效果&#xff1a; 点击左右按钮能切换背景&#xff0c;达到轮播图效果 来看代码实现部分&#xff0c;首先是html: <!DOCTYPE html> <html lang"en"><head>&…

四大含金量高的算法证书考试

证书考试推荐一、PAT 计算机程序设计能力测试二、CCF CSP认证三、团体程序设计天梯赛四、蓝桥杯大赛一、PAT 计算机程序设计能力测试 官网&#xff1a;PAT 计算机程序设计能力测试 PAT为浙江大学出的一款程序设计的测试网站&#xff0c;分为乙级、甲级、顶级三种&#xff0c;…

【MySQL 第十二天 事务的介绍|InnoDB使用事务】

【MySQL 第十二天 事务的介绍|InnoDB使用事务】【1】mysql事物的介绍【2】mysql事务处理的方法【3】mysql是u用InnoDB使用事务生命不息&#xff0c;学习不止 【1】mysql事物的介绍 atomicity 原子性&#xff1a;所有事情是统一的整体&#xff0c;必须一起执行&#xff0c;或者都…

2022 需求工程综合论述题【太原理工大学】

需求工程考题的最后一个模块 —— 综合论述题&#xff0c;只出一道题&#xff0c;30分&#xff0c;马上要考试了&#xff0c;临时抱佛脚其实还是非常管用的 hhh&#xff0c;简答、选择、填空及材料分析题前面博客已更&#xff0c;重点把下面这两个题看明白&#xff0c;仅供参考…

Real-Time Rendering——18.4 Optimization优化

Once a bottleneck has been located, we want to optimize that stage to boost the performance. In this section we present optimization techniques for the application,geometry, rasterization, and pixel processing stages. 一旦找到瓶颈&#xff0c;我们希望优化该…