Android 逆向开发-apktool.yml的解析、修改、合并的java实现

Android 逆向开发-apktool.yml的解析、修改、合并的java实现,第1张

  • 在上一篇文章详细讲解了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

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/756690.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-30
下一篇 2022-04-30

发表评论

登录后才能评论

评论列表(0条)

保存