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

下面我们来说下解析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<String, String> sdkInfo;
        public PackageInfo packageInfo;
        public VersionInfo versionInfo;
        public boolean compressionType;
        public boolean sharedLibrary;
        public boolean sparseResources;
        public Map<String, String> unknownFiles;
        public List<String> doNotCompress;
    
        public Map<String, String> getUnknownFiles() {
            return unknownFiles;
        }
    
        public void putUnknownFiles(Map<String, String> data) {
            if (data == null) return;
    
            if (unknownFiles == null) {
                unknownFiles = new HashMap<>();
            }
    
            unknownFiles.putAll(data);
        }
    
        public void addDoNotCompress(List<String> 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<Integer> 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
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值