- 在上一篇文章详细讲解了apktool.yml的作用,以及里面字段的具体含义,有哪些用处、需要修改的场景等,可参考Android逆向开发apktool.yml详解,常用的doNotCompress、sdkInfo、unknownFiles、versionInfo修改需求说明_林慈桥的博客-CSDN博客
下面我们来说下解析apktool.yml的解析、修改、合并java实现
- apktool.yml是一个yml文件,解析的工具可以使用snakeyaml-x.x.x.jar工具,如果您需要这个工具的话可以去这里下载解析yml、yaml的工具类库文件-Java文档类资源-CSDN下载
- 首先我们打开一个apktool.yml文件,将里面的所有key、value映射成一个java类
- ApktoolYml.java:
package com.lcq.apktoolyml; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class ApktoolYml { public String version; public String apkFileName; public boolean isFrameworkApk; public UsesFramework usesFramework; public Map
sdkInfo; public PackageInfo packageInfo; public VersionInfo versionInfo; public boolean compressionType; public boolean sharedLibrary; public boolean sparseResources; public Map unknownFiles; public List doNotCompress; public Map getUnknownFiles() { return unknownFiles; } public void putUnknownFiles(Map data) { if (data == null) return; if (unknownFiles == null) { unknownFiles = new HashMap<>(); } unknownFiles.putAll(data); } public void addDoNotCompress(List data) { if (data == null) return; if (doNotCompress == null) { doNotCompress = new ArrayList<>(); } doNotCompress.addAll(data); } } - PackageIfo.java
package com.lcq.apktoolyml; public class PackageInfo { public String forcedPackageId; public String renameManifestPackage; }
- UsesFramework.java
package com.lcq.apktoolyml; import java.util.List; public class UsesFramework { public List
ids; public String tag; } - VersionInfo.java
package com.lcq.apktoolyml; public class VersionInfo { public String versionCode; public String versionName; }
- apktool.yml对应的实体类写好后,就可以开始使用snakeyaml-x.x.x.jar工具提供的Yaml类进行解析了,我封装了一个YmlUtil类,如下
package com.lcq.apktoolyml; import org.yaml.snakeyaml.DumperOptions; import org.yaml.snakeyaml.Yaml; import java.io.*; import java.nio.charset.StandardCharsets; public class YmlUtil { /** * 加载apktool.yml 到ApktoolYml类中 * * @param ymlPath apktool.yml文件路径 * @return */ public static ApktoolYml loadYml(String ymlPath) { FileInputStream fis = null; try { fis = new FileInputStream(new File(ymlPath)); return new Yaml().loadAs(fis, ApktoolYml.class); } catch (Exception e) { e.printStackTrace(); } finally { if (fis != null) { try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } } return null; } /** * 将ApktoolYml 实例写入apktool.yml文件 * * @param data ApktoolYml 实例 * @param ymlPath apktool.yml文件路径 */ public static void write(ApktoolYml data, String ymlPath) { FileOutputStream fos = null; OutputStreamWriter outputStreamWriter = null; Writer writer = null; try { fos = new FileOutputStream(new File(ymlPath)); outputStreamWriter = new OutputStreamWriter(fos, StandardCharsets.UTF_8); writer = new BufferedWriter(outputStreamWriter); DumperOptions options = new DumperOptions(); options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); new Yaml().dump(data, writer); } catch (Exception e) { e.printStackTrace(); } finally { if (fos != null) { try { fos.close(); } catch (IOException ioException) { ioException.printStackTrace(); } } if (outputStreamWriter != null) { try { outputStreamWriter.close(); } catch (IOException ioException) { ioException.printStackTrace(); } } if (writer != null) { try { writer.close(); } catch (IOException ioException) { ioException.printStackTrace(); } } } } /** * @param srcYmlPath 需要合并的apktool.yml文件 * @param targetYmlPath 合并到的目标apktool.yml文件 */ public void merge(String srcYmlPath, String targetYmlPath) { ApktoolYml mergeYml = loadYml(srcYmlPath); ApktoolYml targetYml = loadYml(targetYmlPath); targetYml.addDoNotCompress(mergeYml.doNotCompress); targetYml.putUnknownFiles(mergeYml.unknownFiles); write(targetYml, targetYmlPath); } }
- 调用loadYml()可以得到一个ApktoolYml实例,我们可以任意的修改里面的内容,然后再调用write()方法,将修改后的ApktoolYml实例写入到指定的apktool.yml文件文件中,这样我们在使用apktool进行回编译的时候,这些设置将会生效
- 下面来写个修改versionCode和versionName的示例吧
package com.lcq.apktoolyml; public class Main { public static void main(String[] args) { String path = "./apktool.yml"; ApktoolYml apktoolYml = YmlUtil.loadYml(path); apktoolYml.versionInfo.versionCode = "110"; apktoolYml.versionInfo.versionName = "1.1.1"; YmlUtil.write(apktoolYml, path); System.out.println(apktoolYml.apkFileName); } }
- 查看下apktool.yml文件,已经修改生效了,其他的也可以进行修改,如果您有兴趣的话,可以自己试试哦,这个代码的demo示例可以到这里查看:ApktoolYml: apktool.yml解析Demo
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)