標籤:java 逆向 aspectj
AspectJ是一個面向切面編程的架構,它擴充了Java語言。AspectJ定義了AOP文法所以它有一個專門的編譯器用來產生遵守Java位元組編碼規範的Class檔案。
AspectJ目前支援以下三種編織的方式
編譯時間編織:把aspect類(aop的切面)和目標類(被aop的類)放在一起用ajc編譯。
後編譯時間編織:目標類可能已經被打成了一個jar包,這時候也可以用ajc命令將jar再編織一次
載入時編織Load-time weaving (LTW):在jvm載入類的時候,做位元組碼修改或替換
逆向工程中可以用到後兩個:後編譯時間編織和載入時編織。
1.安裝AspectJ
:http://www.eclipse.org/aspectj/downloads.php
選擇裡面的1.9版本下載,下載完成之後是個jar包
安裝命令
java -jar aspectj-1.9.1.jar
根據提示設定好java主目錄和aspectj的安裝目錄,這裡採用預設的C:\aspectj1.9
安裝完成後,設定如下環境變數
設定ASPECTJ_HOME
ASPECTJ_HOME = C:\aspectj1.9
添加/修改CLASSPATH,把aspectjrt.jar添加進去
CLASSPATH = .;%JAVA_HOME%\lib;%JAVA_HOME%\lib\tools.jar;%JAVA_HOME%\lib\dt.jar;%ASPECTJ_HOME%\lib\aspectjrt.jar
PATH變數新增值
%ASPECTJ_HOME%\bin
環境變數設定完成之後,驗證命令
ajc -version
出現如下結果說明環境變數配置成功
2.看兩個簡單的例子
第一個項目helloworld
Java檔案HelloWorld.java
//HelloWorld.javapublic class HelloWorld {public void sayHello() {System.out.println("Hello, world!");}public static void main(String[] argv) {HelloWorld hw = new HelloWorld();hw.sayHello();}}
Aspectj檔案MyAspect.aj
//MyAspect.ajpublic aspect MyAspect {pointcut say():call(void HelloWorld.sayHello());before():say() {System.out.println("before say hello....");}after():say() {System.out.println("after say hello....");}}
Load-time weaving (LTW) 載入時編織命令
編譯
ajc -outjar myjar.jar HelloWorld.javaajc -outjar MyAspect.jar -outxml MyAspect.aj -classpath "myjar.jar;%CLASSPATH%"
運行
aj5 -classpath "MyAspect.jar;myjar.jar;%CLASSPATH%" HelloWorld
運行結果
可以看到在helloworld字串上有上下兩行文字
第二個項目,輸出參數和傳回值
java檔案Main.java
//Main.javapackage com.vvvtimes;public class Main {public int add(int x, int y) {return x + y;}public int add(int x, int y, int z) {return x + y + z;}public static void main(String[] args) {Main m = new Main();System.out.println(m.add(1, 2));System.out.println(m.add(1, 2, 3));}}
Aspectj檔案Tracing.aj
//Tracing.ajpublic aspect Tracing {private pointcut mainMethod(): execution(public static void main(String[]));before(): mainMethod() {System.out.println("> " + thisJoinPoint);}after(): mainMethod() {System.out.println("< " + thisJoinPoint);}private pointcut addMethod(): execution(public int add(..));before(): addMethod() {System.out.println("> " + thisJoinPoint);Object[] args = thisJoinPoint.getArgs();for (int i = 0; i < args.length; i++) {System.out.println("args[" + i + "]: " + thisJoinPoint.getArgs()[i].toString());}}after(): addMethod() {System.out.println("< " + thisJoinPoint);}after() returning(Object o) :addMethod(){System.out.println("Return value: " + o.toString());}}
編譯
ajc -outjar myjar.jar com/vvvtimes/Main.javaajc -outjar Tracing.jar -outxml Tracing.aj -classpath "myjar.jar;%CLASSPATH%"
運行
aj5 -classpath "Tracing.jar;myjar.jar;%CLASSPATH%" com.vvvtimes.Main
運行結果
可以看到,add方法的參數和傳回值都列印出來了
順便說一下三個編織期的區別,從命令列角度比較如下:
Compile-time weaving 編譯時間編織
ajc -outjar mytarget.jar HelloWorld.java MyAspect.aj
運行
aj5 -classpath "mytarget.jar;%CLASSPATH%" HelloWorld
Post-compile weaving 後編譯時間編織
ajc -outjar myjar.jar HelloWorld.javaajc -inpath myjar.jar MyAspect.aj -outjar mytarget.jar
運行
aj5 -classpath "mytarget.jar;%CLASSPATH%" HelloWorld
Load-time weaving (LTW) 載入時編織
編譯
ajc -outjar myjar.jar HelloWorld.javaajc -outjar MyAspect.jar -outxml MyAspect.aj -classpath "myjar.jar;%CLASSPATH%"
運行
aj5 -classpath "MyAspect.jar;myjar.jar;%CLASSPATH%" HelloWorld
Java逆向基礎之初識AspectJ