上一篇ASM中打印出了被注入函数参数的传入值,
http://xkorey.iteye.com/admin/blogs/1667944
现在将要实现对参数传入值的拦截,不符合判断规则的传入值,将会被直接返回。
实现如下效果:
// 打印出参数传入值
start value:error
// 发现值等于 error 时直接返回
error,program will exit.
//属性值并未被更改
default
// 打印出传入值
start value:change
end value:change
// 属性值被更改
change
被拦截的方法是helloWorld中的sayHello
public class helloWorld {
public String va="default";
public void sayHello(String param){
va=param;
}
}
测试代码
asmAopGenerator aag = new asmAopGenerator();
helloWorld hw = (helloWorld) aag.proxy(helloWorld.class, "sayHello", "it's begin", "it's end");
// 传入值是error时直接返回 va的值没改变
hw.sayHello("error");
// 打印出default
System.out.println(hw.va);
// va的值被改变
hw.sayHello("change");
// 打印出 va的值为 change
System.out.println(hw.va);
注入到被拦截类的对象:
public class asmAopInvoker {
public static int methodEnd(String evtID){
System.out.println("end value:"+evtID);
return 0;
}
public static int methodStart(String evtID){
System.out.println("start value:"+evtID);
if(evtID.equals("error")){
System.out.println("error,program will exit.");
return 1;
}
return 0;
}
}
方法拦截对象就是上一篇中的asmAopMethodAdapter
具体修改为
public class asmAopMethodAdapter extends MethodAdapter implements Opcodes{
private final static int EXCEPTION_STACK = 2 + 1;//max_stack至少需要能够容纳2个常量地址(监控方法使用)和1个exception地址
private Label try_catch_start,try_catch_end;
private String startInfo,endInfo;
public asmAopMethodAdapter(MethodVisitor mv,String start,String end) {
super(mv);
try_catch_start = new Label();
try_catch_end = new Label();
startInfo = start;
endInfo = end;
}
public void visitCode() {
mv.visitCode();
mv.visitLabel(try_catch_start);
mv.visitVarInsn(ALOAD, 0);
mv.visitVarInsn(ALOAD, 1);
// 加入if标签
Label if_Lable = new Label();
// 获得函数 methodStart 的返回值
mv.visitVarInsn(ALOAD, 1);
// 调用 methodStart函数
// (Ljava/lang/String;)I 意为:接受一个类型为string参数
// 返回值为int的函数
mv.visitMethodInsn(INVOKESTATIC, "asmAop/asmAopInvoker",
"methodStart", "(Ljava/lang/String;)I");
// 访问if 标签
// 疑惑 asm4-guide 中说明 IFEQ的意思是:jump if i == 0。但我在asm 3.3.1中貌似IFEQ是 jump if i==1
mv.visitJumpInsn(IFEQ, if_Lable);
// 写入 return
mv.visitInsn(RETURN);
// 结束if标签
mv.visitLabel(if_Lable);
}
public void visitInsn(int opcode){
if(opcode >= IRETURN && opcode <= RETURN){
mv.visitCode();
mv.visitVarInsn(ALOAD, 0);
mv.visitVarInsn(ALOAD, 1);
mv.visitMethodInsn(INVOKESTATIC, "asmAop/asmAopInvoker",
"methodEnd", "(Ljava/lang/String;)I");
}
mv.visitInsn(opcode);
}
public void visitEnd() {
mv.visitLabel(try_catch_end);
mv.visitTryCatchBlock(try_catch_start, try_catch_end, try_catch_end, null);
mv.visitInsn(Opcodes.ATHROW);
mv.visitEnd();
}
public void visitMaxs(int maxStack,int maxLocals){
//保证max stack足够大
mv.visitMaxs(Math.max(EXCEPTION_STACK,maxStack), maxLocals);
}
}
所涉及类以打包。
代码运行环境 asm 3.3.1 jdk 1.6.
分享到:
相关推荐
NULL 博文链接:https://xkorey.iteye.com/blog/1667944
DLL函数动态调用工具1.0 使用Delphi + Asm编写,只要知道DLL中函数的名字和参数,就可以对任意Dll的函数进行调用。目前已经可以支持以下类型的参数和返回值:Boolean,Byte,Shortint,Word,Smallint,Longword,Integer,...
远程线程注入asm代码.hello world级别 xxxxxxxxxxx
Android 无痕埋点框架 使用ASM插桩实现
前面说过我们可以使用CALL的方式来实现跳转,这种方法的好处是可以为你的拦截函数提供一个或者多个参数。这里只要一个参数就足够了。带参数的函数调用的汇编代码是什么样子呢,前面也已经说了,类似与调用...
方便用于调试远程注入CALL的工具; 支持自行申请空间,进行参数写入; 支持代码搜索寻址;
asm算法的opencv实现,中含有三个工具,分别可以从图片,摄像机中获得人脸识别特征点描述
查看ASM实例和SCAN监听日志文件 查看本地监听日志文件 Database日志文件
1、六轴传感器ASM330LHH驱动函数 2、基于STM32F429 3、采用查询的方式读取数据
用泰勒公式实现余弦函数的计算,使用汇编的方法,里面用到了32位的运算方法,灵活应用了定点运算的思想。
代码注入器别名(ASM汇编CALL测试器)可测试游戏函数CALL,这个工具非常的好用,但是使用的时候请注入汇编书写和堆栈平衡否则游戏会崩溃。还有这个工具必须配合OD调试器使用,因为汇编代码是从OD里面分析出来 ,哈哈。
用asm实现汇编三级菜单;选择子程序+显示时间日期+退出
在 Visual C++ 中使用内联汇编 VC内联ASM汇编 混合使用C和汇编代码的程序(用__asm写c函数)
二进制文件可以直接使用可执行文件的代码空区通过修改代码来添加函数的。此方法是完全有效的如果不是有点费时,但在这里有一种替代方法,可以把要添加的函数代码放入一个单独的可以被目标应用程序加载调用的DLL文件中...
实现基于ASM9,动态生成entity、repository、service、serviceImpl、controller相关.class 可根据库表,一键生成新增、修改删除、查询等接口 实现部分基于mybatis-plus,动态代码生成(相关包,未包含) 数据库文件...
ASM HOOK API函数库
ASM算法实现对齐功能代码 经典算法asm,内部对齐部分代码,就是求解那个矩阵代码
ASM模拟坏块 ASM里实现修改指定的Block
利用汇编模块对C51模块进行无参数化调用,从根本上避开了传统汇编模块和C51模块之间调用时的繁琐接口编程问题,并以实例验证了该方法的优越性和有效性。