最近修改了某个android的第三方jar包里的代码,在此记录一下心得

一开始想用jd-gui转成.java文件,修改后再重新编译回class,然后放进jar中覆盖掉原来的class文件。然而在编译回去时发现因为代码引用了部分android的类,用java命令等方式无法编译回class文件。于是我尝试通过直接修改class文件来实现修改代码。

  1. 找到jar包中对应的class文件的路径
  2. 建一个可以直接执行的java类
  3. 调用javassist.jar的API来写代码实现修改对应代码(示例代码在底下,关于javassist.jar的API请自行百度)
  4. 执行修改class文件的代码
  5. 生成的已修改class位于项目根目录下对应的class文件路径下(例:com.a.bb.A.class, 程序执行后class文件会生成在: 当前项目/com/a/bb/A.class
  6. 覆盖掉出来的class文件夹中原先的class文件
  7. 使用cmd命令:jar cvf test.jar命令重新打包
  8. 然后在项目中测试一下修改后的jar就大功告成了!

示例代码:

    public static void main(String[] args) {                ClassPool pool = ClassPool.getDefault();        try {            //取得需要反编译的jar文件,设定路径            pool.insertClassPath("G://abc//XXX.jar");                        //取得需要反编译修改的文件,注意是完整路径(注意:因为代码在内部类中,所以我读取的是WebViewActivity$2文件            CtClass cc1 = pool.get("com.xx.xxx.WebViewActivity$2");                        //取得需要修改的方法            CtMethod method = cc1.getDeclaredMethod("loadUrl");                        //插入修改项,我们让他直接返回(注意:根据方法的具体返回值返回,因为这个方法返回值是void,所以直接return;)            method.instrument(                    new ExprEditor() {                        public void edit(MethodCall m)                                throws CannotCompileException {                            System.out.println(m.getClassName() + ", " + m.getMethodName());                            // 在这里搜索class中符合条件的逻辑代码,并替换成我想改的                            if ( m.getClassName().equals("java.lang.String")                                    && m.getMethodName().equals("方法名")) {                                m.replace(                                        "$_ = $proceed(\"https\") ;");                            }                        }                    });            //写入保存            cc1.writeFile();        } catch (NotFoundException e) {            e.printStackTrace();        } catch (CannotCompileException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        }    }

PS:

  1. 如果发现修改不了对应的代码,那是因为对应的代码不是在那个A.class文件中。(没错,你没听错) 举例来说:我想修改匿名内部类中的代码,需要修改的class文件是
    A$.class系列,而不是A.class本身,因为编译成class文件后,内部类的代码实际上是放在A$.class文件中的
  2. 把class文件直接丢进jar包中有可能会导致用不了,这时候用命令重新打包试试
  3. 按住Shift+右键,在右键菜单中会出现“在此处打开命令窗口(W)”的选项

如果只是要修改某个字符串,可以使用JBE(Java Bytecode Editor)。 JBE是一个Java字节码编辑工具,可以查看和编辑该方法的字节码, 字节码化的代码虽然不容易看懂. 但是字符串内容不会变. 所以很适用于只需要修改某个字符串(比如正则)内容的需求. 找到对应方法的字节码,点击Code Editor找到对应字符串直接编辑完点保存就能拿到一个修改好的class文件.
JBE使用教程
JBE下载地址

更多相关文章

  1. 没有一行代码,「2020 新冠肺炎记忆」这个项目却登上了 GitHub 中
  2. 一款常用的 Squid 日志分析工具
  3. 分支和循环(二)(零基础学习C语言)
  4. GitHub 标星 8K+!一款开源替代 ls 的工具你值得拥有!
  5. RHEL 6 下 DHCP+TFTP+FTP+PXE+Kickstart 实现无人值守安装
  6. Linux 环境下实战 Rsync 备份工具及配置 rsync+inotify 实时同步
  7. android 示例源码
  8. 『ANDROID』App工程结构搭建:几种常见Android代码架构分析
  9. android如何实现文件打开方式可供选择功能

随机推荐

  1. flex容器与项目的认识和常用属性
  2. flex初体验之常用属性练习
  3. 2021.7.6表格作业,
  4. flex布局中容器及项目常用属性演示
  5. flex容器以及属性
  6. flex容器与项目中常用的属性
  7. AJAX的原理
  8. 无头浏览器Selenium的使用要点
  9. FROM表单实践以及心得
  10. 仿京东移动端首页的"部分"样式