Java注入學習總結


最近看到Android手機上金山毒霸實現了一個過濾廣告的功能(也不確認是不是最早的),在注入過程中還包括JAR和dex注入,這讓我產生了興趣。

有關金山的注入在看雪論壇上有簡要的分析:

http://bbs.pediy.com/showthread.php?t=166151

 

這里主要是被JAR注入吸引到了,不知道JAVA原來也能玩注入。不過替換的本質我卻產生了個誤解:難道JAVA的方法能夠被動態替換?當然后來問了達人,得到一個結論,C#和JAVA初始化的過程不是一樣的,方法的動態替換。據說C#可以,但是JAVA不行

 

首先在網上搜索了一些有關JAVA注入的資料,有2套資料比較有幫助:

1、xantorohara:http://xantorohara.blogspot.tw/2007/09/java-code-injection-via-winapis.html

2、vmattach:http://www.blogjava.net/javacap/default.html?page=5

 

一、在資料1中,按照作者提供的代碼,(最好是XP環境下)編譯完成之后,在我運行Notepad.jar之后,再注入JAR運行得到了如下圖所示結果:

 

這的確實現了在對方的JAR(或者說java.exe)中運行了注入的JAR代碼(Insider.java實現):

public class Insider implements Runnable {
    static {
        Thread t = new Thread(new Insider());
        t.setPriority(Thread.MIN_PRIORITY);
        t.setDaemon(true);
        t.start();
    }

    public void run() {
        int i = 0;
        while (true) {
            System.out.println(i++);
            try {
                Thread.sleep(300);
            } catch (InterruptedException e) {
                break;
            }
        }
    }
}

Xantorohara在實現過程中包含了一共5個重要的代碼文件:

Injector.java —— 用於實現注入的JAVA代碼,PID值由用戶輸入

Injector.cpp —— 用於實現注入的JNI代碼,就是利用了Win32下的CreateRemoteThread函數,在遠程進程中實現了LoadLibraryA("Insider.dll"),用於加載Insider.dll

Insider.java —— 構造了一個Insider類創建線程不斷的輸出數字,就是圖示的情況

Insider.cpp —— Insider.dll的代碼,它利用了Bin2H.java將Insider.java生成了class字節碼存入Insider.h的jbyte clazz[]數組,在Insider.cpp中利用DefineClass創建新類,並且激活了這個類的代碼:

C語言中的env->FindClass(className)類比JAVA下的Class.forName(className)

Bin2H.java —— 主要用於將javac Insider.java得到的Insider.class的字節碼存入Insider.h的jbyte clazz[]數組

 

這里我們可以看得出來,要實現一個JAVA的注入,我們至少需要2個DLL:一個是用於主要負責原生工作的注入代碼(主要調用CreateRemoteThread);另外一個DLL主要是在注入遠程進程調用LoadLibraryA后啟動,用於加載或者初始化類從而完成JAR的工作。

 

二、資料2中,作者沒有提供相對完整的原生部分代碼,但是展現的代碼更為注入的意義

作者的VMAttach包中包含了2個DLL,VMAttach.dll和VMattach.jar配合主要是實現在JAVA(VMAttach.jar)下調用JNI(VMAttach.dll),像遠程的JAVA進程注入了worker.dll,而worker.dll中通過IDA分析其通過JNI下實現的類似於如下JAVA代碼:

loader = new URLClassLoader(new URL ("jar:file:/C:/AttachDemo.jar!/AttachDemo"))

 

來加載了AttchDemo.jar(入口為AttachDemo)並且調用FindClass、CallStaticVoidMethod函數運行了AttachDemo.jar中的main方法。

在main方法中,遠程進程通過反射的方式,獲得了UseSingletonApp中 private   volatile   int  stateNum; 的當前值,測試效果如下所示:

 

后記:

最后,我google了很久也沒找到一個關於JAVA動態時候替換方法的辦法,有一些比如說熱替換的思路,但是是在特殊構造的代碼情況下能夠實現;除此之外就是利用開源的ASM類修改字節碼實現,不過這不屬於“運行時替換”吧。雖然能夠注入JAVA代碼,但是如果想實現類似API HOOK的方式,必須找到一種替換其方法的辦法,只是可惜最后沒有找到,僅僅只是實現了一個可用於部分訪問成員的代碼注入而已。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM