在逆向中,我们经常要跟踪某些类的成员变量的值,这里以获取ZKM9中的qs类的成员变量g为例进行说明
在StackOverFlow上有这么一篇提问:AspectJ: How to get accessed field's value in a get() pointcut
将其中内容改写为qs类的代码如下:
private pointcut qsfiledMethod() : get(* com.zelix.qs.*); after() returning(Object field) :qsfiledMethod(){ System.out.println(thisJoinPoint.toLongString()); System.out.println(" " + thisJoinPoint.getSignature().getName()); System.out.println(" " + field); }
但是这个方法有缺陷,只能获取公共变量,运行之后获取到的都是qs的成员变量j和k
运行结果如下
所以此路不通,那么就需要再找一条路:反射
qs类中的某个方法调用了jj.a方法,所以用call找出调用者,然后通过反射方式获取filed,talk is cheap,show you code?
private pointcut jjaMethod() : call(String com.zelix.jj.a(String, String, String, Object, int)); before() : jjaMethod() { System.out.println("> " + thisJoinPoint); if (thisJoinPoint.getThis() != null) { System.out.println("this "+thisJoinPoint.getThis().getClass().getName() + " " + thisJoinPoint.getSourceLocation()); Object obj = thisJoinPoint.getThis(); Class clazz = obj.getClass(); //遍历成员 Field[] fileds = clazz.getDeclaredFields(); for (Field field : fileds) { System.out.println(field); } try { //获取单个成员private final java.lang.String[] com.zelix.qs.g //并输出它的值 Field filed = clazz.getDeclaredField("g"); System.out.println(filed); filed.setAccessible(true); String[] g= (String[]) filed.get(obj); for (int i = 0; i < g.length; i++) { System.out.println("g["+i+"] ="+g[i]); } } catch (Exception e) { e.printStackTrace(); } }else if (thisJoinPoint.getTarget() != null) { System.out.println("target "+thisJoinPoint.getTarget().getClass().getName() + " " + thisJoinPoint.getSourceLocation()); } }
运行结果如下
before方法里的功能如下
1.打印出调用者的名称和位置
2.遍历打印qs类的所有成员名称
3.获取成员g的值,由于这个成员是数组类型,遍历这个数组打印值
原文地址:http://blog.51cto.com/7317859/2114892