android中的jar包反编译修改心得

最近修改了某个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下载地址

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,886评论 18 139
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 173,124评论 25 708
  • 催眠师-程伟 来访者是个高中的在校学生。 咨询方式:通过微信视频远程催眠 咨询问题:寒假放假回家,觉得学习动力下降...
    b43ac3a3eee7阅读 1,605评论 0 0
  • 由于外婆临时有事需回乡下几天,家里的这个两岁多的小豆这下突然令我们犯愁了,怎么办?请人,不太实际,放朋友家也不太可...
    佳鹏一鸣阅读 441评论 0 4
  • 《书都不会读,你还想成功》是韩国作家二志成和郑会一合著,冯适宜翻译的一本关于培养读书兴趣、介绍读书方法及其改变自身...
    fishstar阅读 436评论 0 3