Java逆向基础之AspectJ的Around方法修改方法体

在逆向中,我们往往通过修改某个方法达到目的,在javaassist中有insertBefore,insertAfter,setBody,在AspectJ中也可以通过Around实现类似的功能。

看一个简单的例子

java文件Main.java

//Main.java
package 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));
	}
}

aj文件Tracing.aj

//Tracing.aj
public aspect Tracing {
	private pointcut mainMethod():
            execution(public static void main(String[]));

	before(): mainMethod() {
		System.out.println("> " + thisJoinPoint);
	}

	after(): mainMethod() {
		System.out.println("< " + thisJoinPoint);
	}

	pointcut addMethodOne() : call (public int add(int,int));

	int around() : addMethodOne() {
		System.out.println("> " + thisJoinPoint);
		Object[] args = thisJoinPoint.getArgs();
		for (int i = 0; i < args.length; i++) { //输出参数
			if( args[i]!=null) {
				System.out.println("args[" + i + "]: " + args[i].toString());
			}
		}
		int result = proceed();//这里执行原有方法体
		System.out.println("original return value: " + result);//输出原有返回值
		return 777; //指定新值返回
	}

	pointcut addMethodTwo(int a, int b, int c) : call (public int add(int,int,int)) && args (a, b, c);

	int around(int a, int b, int c) : addMethodTwo (a, b, c){
		System.out.println("> " + thisJoinPoint);
		System.out.println("1st passed value: " + a);
		System.out.println("2nd passed value: " + b);
		System.out.println("3rd passed value: " + c);
		a = 6;
		b = 6;
		c = 6;
		int result = proceed(a, b, c);//修改传入的参数值
		return result;
	}

}

运行后的结果如下

proceed用于执行原有方法体,return方法用于改变返回值

在第一个修改中我们输出了其中的参数,执行了原有方法之后,直接指定了一个返回值777

在第二个修改中,我们通过&& args 指定了参数,修改其参数之后执行原有方法体并返回。

原文地址:http://blog.51cto.com/7317859/2115501

时间: 2024-11-09 05:44:17

Java逆向基础之AspectJ的Around方法修改方法体的相关文章

Java逆向基础之AspectJ的ajc与aj5命令

acj命令是用于编译java文件和aj文件的编译器,相当于eclipse的编译器(ECJ)+aspectj运行时扩展 aj5命令在jdk1.5上使用-javaagent:pathto/aspectjweaver.jar加载aspectj程序,达到修改字节码的目的 这两个命令可以用java命令和javac来替代,我们以上文的命令为例 Load-time weaving (LTW) 加载时编织 编译 ajc -outjar myjar.jar HelloWorld.java ajc -outjar 

Java逆向基础之AspectJ的Eclipse插件AJDT

AJDT即Eclipse AspectJ Development Tools.是一个Eclipse插件,可以编写AspectJ项目 安装 help-->Install New Software 填写在线安装地址:http://download.eclipse.org/tools/ajdt/47_aj9/dev/update 安装完成之后,新建Aspectj项目 项目结构如下 把前面博文的aj文件和java文件内容复制过来 其中aj文件的新建方法 File-->New-->Project选

Java逆向基础之动态生成类

为什么有这个东西,一方面时AOP框架的需要,另一方面是增加软件逆向的难度 动态生成类的技术目前大体上分为两类,一类是通过操作字节码框架如cglib/Javassist去实现,另一类就是JNI方式,调用dll/so库,内存中动态还原.这两种方式都能实现隐藏类 看一个Javassist动态生成类的例子 package com.vvvtimes; import java.lang.reflect.Modifier; import javassist.ClassPool; import javassis

Java逆向基础之初识javaagent

首先说一下javaagent是什么 javaagent是一种能够在不影响正常编译的情况下,修改字节码. 在逆向中javaagent可以完成对类的拦截和增强. 看一个例子 在Eclipse新建如下MyAgent结构的项目 MyAgent.java文件内容 package com.vvvtimes.demo.agent; import java.lang.instrument.Instrumentation; public class MyAgent {     public static void

Java逆向基础之导出内存中的类一

为什么需要这个,因为在之前的博文中提到,为了增加逆向的难度,部分软件会对部分关键方法和类进行隐藏,所以我们需要把这个类从内存中拿出来. 本文介绍使用javaagent的方法,下一篇介绍dumpclass,两种方法各有利弊. 本文需要用到第三方jar为:javassist-3.20.0-GA.jar,不过我们需要的是它的源码javassist-3.20.0-GA-sources.jar 新建名为DumpClassAgent的项目,项目结构如下 将下载到的源码复制到src目录下 DumpClassA

Java逆向基础之JDB动态调试

本文参考:https://docs.oracle.com/javase/8/docs/technotes/tools/windows/jdb.html JDB在有源代码的时候可以实现调试远程机器上的java程序,但是在逆向中源码很难分析出来,不过还是能够调试得到一部分信息的 本文主要获取两个信息 1.动态调用混淆类中的方法,因为实践过程中我们去手动补全相关代码比较难 2.打印调用栈 以下例子以调试ZKM.jar为例 JDB无源代码调试调用方法 启动Xdebug调试 java -Xdebug -X

Java逆向基础之操作数栈

本文参考:http://www.vuln.cn/7115 本地变量和操作数栈 本地变量数组(Local Variable Array) 本地变量的数组包括方法执行所需要的所有变量,包括 this 的引用,所有方法参数和其他本地定义的变量.对于那些方法(静态方法 static method)参数是以零开始的,对于实例方法,零为 this 保留. 所有的类型都在本地变量数组中占一个槽(entry),而 long 和 double 会占两个连续的槽,因为它们有双倍宽度(64-bit 而不是 32-bi

Java逆向基础之函数

本文参考http://www.vuln.cn/7115 本文提到的函数(function)和方法(method)为同一个意思 例子1,方法名的定义 public class HalfRandom { public static double f() { return Math.random()/2; } } 编译 javac HalfRandom.java 反编译 javap -c -verbose HalfRandom.class ... major version: 52 ... #2 = 

Java逆向基础之数组

本文参考:http://www.vuln.cn/7116 本文参考:<Reverse Engineering for Beginners>Dennis Yurichev著 数组 简单的例子 创建一个长度是10的整型的数组,对其初始化 public class ArrayInit { public static void main(String[] args) { int a[] = new int[10]; for (int i = 0; i < 10; i++) a[i] = i; d