SSVM目录
0x1 前言
本文主要简单介绍SSVM常用类的获取方法
0x2 InstanceJavaClass
- 如何获取InstanceJavaClass的实例?
我们使用System类来作例子
例子1:
InstanceJavaClass systemClazz = vm.getSymbols().java_lang_System();
例子2:
InstanceJavaClass systemClazz = (InstanceJavaClass) vm.findBootstrapClass("java/lang/System");
0x3 JavaMethod 与 JavaField
// JavaMethod
JavaMethod printlnMethod = runtime.getMethod("println","(Ljava/lang/String;)V");
// JavaField
JavaField outField = system.getStaticField("out","Ljava/io/PrintStream;");
0x04 VMInterface
类似注册事件,管理调用
主要的函数
- setInvoker
- registerMethodEnter
- registerMethodExit
- registerInstructionInterceptor 能处理字节码
例子:
vmi.setInvoker(printlnMethod,ctx -> {
// instance
System.out.println("this "+ ctx.getLocals().load(0));
// method first param is load(1)
System.out.println("text "+ vm.getHelper().readUtf8(ctx.getLocals().load(1)));
return Result.ABORT;
});
0x05 简单的HelloWorld
public static void main(String[] args2) throws Exception {
VirtualMachine vm = new VirtualMachine();
//虚拟机启动
vm.bootstrap();
try {
// 获取Runtime & System的实例
InstanceJavaClass system = vm.getSymbols().java_lang_System();
InstanceJavaClass runtime = (InstanceJavaClass) vm.findBootstrapClass("java/io/PrintStream");
// 读取out获取Runtime返回的实例
// 用于执行println
Value outInstance = vm.getOperations().getStaticField(system,"out","Ljava/io/PrintStream;");
JavaMethod printlnMethod = runtime.getMethod("println","(Ljava/lang/String;)V");
//创建Locals
Locals locals = vm.getThreadStorage().newLocals(printlnMethod);
// 实例
locals.set(0,outInstance);
// 这是第一个参数.
locals.set(1,vm.getHelper().newUtf8("Hello World1"));
//用于调节 配置 虚拟机使用的
VMInterface vmi = vm.getInterface();
// 注册调用钩子
vmi.setInvoker(printlnMethod,ctx -> {
// instance
System.out.println("this "+ ctx.getLocals().load(0));
// method first param is load(1)
System.out.println("text "+ vm.getHelper().readUtf8(ctx.getLocals().load(1)));
// 中止调用进行
return Result.ABORT /*Result.CONTINUE*/;
});
// 调用函数
vm.getHelper().invoke(printlnMethod,locals);
}catch (VMException e)
{
// 处理内部虚拟机的产生的异常
throw new Exception(vm.getHelper().toJavaException(e.getOop()));
}
}
运行结果:
0x06 总结
用法上和java自带反射类似。
此外本文章进行监控的为个人编写的代码调用,实则上还可以通过URLClassPath中addURL函数加载计算机内的jar文件,使用vm.getHelper().invoke调用程序入口并注册特定函数的事件,进行监控/修改参数内容,以及追踪调用轨迹。