做逆向(当然了,不一定是好事,关键是看用的人)的时候,经常发现别人为了防止你修改这个修改那个而各种加密加密再加密,加到最后自己都蒙了,如果顺着杆子网上摸索,太过于麻烦,何不换一个思路,在他最后的那个方法中做修改,输出其传入的参数,也就是直接修改他的.class文件呢?
package com.wei.tian;
import org.objectweb.asm.ClassAdapter;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor;
public class AddLogClassAdapter extends ClassAdapter{
    public AddLogClassAdapter(ClassVisitor arg0) {
        super(arg0);
    }
     public MethodVisitor visitMethod(final int access, final String name, 
                final String desc, final String signature, final String[] exceptions) { 
                MethodVisitor mv = cv.visitMethod(access, name, desc, signature,exceptions);
                if (mv != null) { 
                    if (name.equals("sendMessage")) { 
                        return new MyAdviceAdapter(mv,access,name,desc); 
                    } 
                } 
                return mv; 
            } 
}
package com.wei.tian;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.AdviceAdapter;
public class MyAdviceAdapter extends AdviceAdapter{
protected MyAdviceAdapter(MethodVisitor mv, int access, String name, String desc) {
        super(mv,access,name,desc);
    }
    @Override
        protected void onMethodEnter() {
            super.onMethodEnter();
            visitFieldInsn(GETSTATIC,"java/lang/System","out","Ljava/io/PrintStream;");
             loadArg(0);
             visitMethodInsn(INVOKEVIRTUAL,"java/io/PrintStream","println",
                "(Ljava/lang/String;)V");
        }
}然后写一个可执行程序Test.java,main里面有以下代码即可 
try{
                     ClassReader cr = new ClassReader(ABC.class.getName());
                     ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); 
                     ClassAdapter classAdapter = new AddLogClassAdapter(cw); 
                     cr.accept(classAdapter, ClassReader.SKIP_DEBUG); 
                     byte[] data = cw.toByteArray(); 
                     File file = new File("ABC.class"); 
                     FileOutputStream fout = new FileOutputStream(file); 
                     fout.write(data); 
                     fout.close(); 
                    }catch(Exception e){
                        e.printStackTrace();
                    }
private void sendMessage(String msg){
  以前的逻辑
}修改之后的ABC.class中的sendMessage代码相当于 
private void sendMessage(String msg){
  System.out.println(msg);
  以前的逻辑
}最后一步,怎么用这个ABC.class呢?很简单,将realSDK.jar解压,找到其中的ABC.class然后删掉,用我们刚生成的ABC.class替换掉,然后(假定这个realSDK解压后第一个目录是com)用命令 jar cvf newSDK.jar com/* 生成心的newSDK.jar文件,将这个newSDK.jar文件导入到一个新建的Android工程中,就能够在调用这个sendMessage的时候,输出我们需要看到的内容了。
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
-------------------------