SmaliInjector (對重度混淆過的apk處理得比dex2jar更好)

 

說明:
===================================================================
1). dex 轉 jar 用的 enjarify,比目前常用的 dex2jar(d2j) 要穩定可靠得多,尤其是在處理重度混淆過的apk時

2). 用於對apk進行代碼修改,掃描目標apk中函數,並在指定函數的開頭部分 添加 調用自定義靜態函數的代碼

3). 省略 jar 轉 smali 再回轉的步驟,轉而使用 objectweb.asm(ow2) 直接對 jar 文件進行 smali 注入

4). dex2jar 的步驟使用的是 google 自家的 enjarify 工具,沒使用老掉牙的、對部分混淆apk處理極不準確極不穩定的 dex2jar(d2j)

5). jar2dex 使用的是 android studio 自帶的 dx.bat 工具,貌似 dex2jar(d2j) 在做jar迴轉的時候也是調用dx.jar

6). 手機無需 root

 

下載地址:

http://download.csdn.net/detail/jizhitp/9904209

public static int processJarFile(String fnOldjar, String fnNewjar) {
		int nFunctionProcess = 0;
        try {
            JarFile Oldjar = new JarFile(new File(fnOldjar));
            File Newjar = new File(fnNewjar);
 
            try (final JarOutputStream output = new JarOutputStream(new FileOutputStream(Newjar))) {
                Enumeration<JarEntry> enumeration = Oldjar.entries();
                while (enumeration.hasMoreElements()) {
 
                    //<editor-fold defaultstate="collapsed" desc="遍歷jar文件中的所有.class文件">
                    JarEntry next = enumeration.nextElement();
                    if (next.getName().endsWith(".class")) {
 
                        ClassNode cn = new ClassNode(ASM5);
                        ClassReader cr = new ClassReader(Oldjar.getInputStream(next));
                        cr.accept(cn, 0);
 
                        //<editor-fold defaultstate="collapsed" desc="根據類名來判斷當前類是否爲需要注入smali的類">
                        if (cn.name.equals("com/test/u/t")) {
                            for (Object methodNodeObj : cn.methods) {
                                MethodNode methodNode = (MethodNode) methodNodeObj;
 
                                //<editor-fold defaultstate="collapsed" desc="根據函數名判斷該函數是否需要注入">
                                if (methodNode.name.equals("a")) {
                                    //new MethodHelper(methodNode.access, cn.name, methodNode.name, methodNode.desc, (MethodVisitor) methodNode);
                                    String tmpInject_ClassName = SmaliInjector.pc.Injector.Inject_ClassName.replace(".", "/");
                                    String tmpInjectMethodName = SmaliInjector.pc.Injector.InjectMethodName;
 
                                    //<editor-fold defaultstate="collapsed" desc="根據函數的參數列表來判斷是否爲需要注入的函數">
                                    if (methodNode.desc.equals("([B[BLcom/test/pointers/PInt;Lcom/test/protocal/c/asb;)[B")) {
                                        System.out.println("\tfound: "+cn.name+"."+methodNode.name+methodNode.desc);
										nFunctionProcess++;
 
                                        InsnList injectCode = new InsnList();
                                        injectCode.add(new VarInsnNode(Opcodes.ALOAD, 1));
                                        injectCode.add(new MethodInsnNode(Opcodes.INVOKESTATIC, tmpInject_ClassName, tmpInjectMethodName, "([B)V", false));
 
                                        AbstractInsnNode firstIns = methodNode.instructions.get(0);//.getFirst();//
                                        methodNode.instructions.insertBefore(firstIns, injectCode);
 
                                    } else if (methodNode.desc.equals("(I[B[B)Z")) {
                                        System.out.println("\tfound: "+cn.name+"."+methodNode.name+methodNode.desc);
										nFunctionProcess++;
 
                                        InsnList injectCode = new InsnList();
                                        injectCode.add(new VarInsnNode(Opcodes.ALOAD, 3));
                                        injectCode.add(new MethodInsnNode(Opcodes.INVOKESTATIC, tmpInject_ClassName, tmpInjectMethodName, "([B)V", false));
 
                                        AbstractInsnNode firstIns = methodNode.instructions.get(0);//.getFirst();//
                                        methodNode.instructions.insertBefore(firstIns, injectCode);
                                    }
                                    //</editor-fold>
 
                                }
                                //</editor-fold>
 
                            } // end of methods loop
 
                        } // end of java class name filter
                        //</editor-fold>
 
                        ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
                        cn.accept(cw);
 
                        output.putNextEntry(new JarEntry(cn.name.replaceAll("\\.", "/") + ".class"));
                        output.write(cw.toByteArray());
                        output.closeEntry();
 
                    } // end of if jarEntry == .class
                    //</editor-fold>
 
                } // end of .class loop
            }
 
            Oldjar.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
		
		return nFunctionProcess;
    }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章