ZjDroid原理分析

首先入口在這

com.android.reverse.mod.ReverseXposedModule

因爲github沒有跳轉看起來不方便,所以只是粗略分析一下

首先initModuleContext中,



hook了onCreate方法


往下翻可以看到其實是註冊了一個廣播,所以可以通過發送廣播的形式,進行命令傳遞。

而另一個方法 跟脫殼相關

public void start() throws Throwable {

        pathClassLoader = (PathClassLoader) ModuleContext.getInstance().getBaseClassLoader();

        Method openDexFileNativeMethod = RefInvoke.findMethodExact("dalvik.system.DexFile", ClassLoader.getSystemClassLoader(), "openDexFileNative",
                String.class, String.class, int.class);
        hookhelper.hookMethod(openDexFileNativeMethod, new MethodHookCallBack() {

            @Override
            public void beforeHookedMethod(HookParam param) {
                // TODO Auto-generated method stub

            }

            @Override
            public void afterHookedMethod(HookParam param) {
                // TODO Auto-generated method stub
                String dexPath = (String) param.args[0];
                int mCookie = (Integer) param.getResult();
                if (mCookie != 0) {
                    dynLoadedDexInfo.put(dexPath, new DexFileInfo(dexPath,mCookie));
                }
            }
        });
        
        Method defineClassNativeMethod = RefInvoke.findMethodExact("dalvik.system.DexFile", ClassLoader.getSystemClassLoader(), "defineClassNative",
                String.class, ClassLoader.class,int.class);
        hookhelper.hookMethod(defineClassNativeMethod, new MethodHookCallBack() {

            @Override
            public void beforeHookedMethod(HookParam param) {
                // TODO Auto-generated method stub

            }

            @Override
            public void afterHookedMethod(HookParam param) {
                // TODO Auto-generated method stub
               if(!param.hasThrowable()){
                   int mCookie = (Integer) param.args[2];
                   setDefineClassLoader(mCookie,(ClassLoader) param.args[1]);
               }
            }
        });
        
        Method findLibraryMethod = RefInvoke.findMethodExact("dalvik.system.BaseDexClassLoader", ClassLoader.getSystemClassLoader(), "findLibrary",
                String.class);
        hookhelper.hookMethod(findLibraryMethod, new MethodHookCallBack() {

            @Override
            public void beforeHookedMethod(HookParam param) {
                // TODO Auto-generated method stub

            }

            @Override
            public void afterHookedMethod(HookParam param) {
                Logger.log((String) param.args[0]);
                if (DVMLIB_LIB.equals(param.args[0]) && param.getResult() == null) {
                    param.setResult("/data/data/com.android.reverse/lib/libdvmnative.so");
                }
            }
        });
    }

可以看到都是hook了一些類,以及最後加載自己的so


第一個hook可以發現,獲取了dexpath以及返回值mcookie的指針

第二個方法可以看到hook 獲取了mcook的值以及對應的classloader

第三個方法可以看到如果加載的so 名字是自己的以及找不到的話,就把路徑換成自己的so路徑,其實就是一個路徑查找過程,如果系統找不到自己的so,就直接告訴系統我的so在哪裏。

接着看看脫殼過程


public void dumpDexFile(String filename, String dexPath) {
        File file = new File(filename);
        try {
            if (!file.exists())
                file.createNewFile();
            int mCookie = this.getCookie(dexPath);
            if (mCookie != 0) {
                FileOutputStream out = new FileOutputStream(file);
                ByteBuffer data = NativeFunction.dumpDexFileByCookie(mCookie, ModuleContext.getInstance().getApiLevel());
                data.order(ByteOrder.LITTLE_ENDIAN);
                byte[] buffer = new byte[8192];
                data.clear();
                while (data.hasRemaining()) {
                    int count = Math.min(buffer.length, data.remaining());
                    data.get(buffer, 0, count);
                    try {
                        out.write(buffer, 0, count);
                    } catch (IOException e1) {
                        // TODO Auto-generated catch block
                        e1.printStackTrace();
                    }
                }
            } else {
                Logger.log("the cookie is not right");
            }
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

可以看到拿到mcookie的值,然後用native層去讀數據,寫到文件中。

https://bbs.pediy.com/thread-252284.htm

而參考上面鏈接的說法的話,可以看出,裏面的指針指向的是dexfile,因爲native的操作無非就是拿到dexfile的base 和size 然後讀出來交給java層寫。

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