Java逆向基础之二十二.Byteman
本文于2369天之前发表,文中内容可能已经过时。
Byteman的是由Jboss发明主要是为了支持多线程和多JVM测试的自动化。
Byteman规则语言提供了一组标准的内置操作,这些操作支持特定的上述类别中的任务
为了简化测试自动化,Byteman已经与两种流行的测试框架JUnit和TestNG集成
在逆向中,我们也可以利用Byteman来帮助我们分析方法的调用
1. 安装
Byteman下载地址:http://byteman.jboss.org/downloads.html
环境变量配置
1 | BYTEMAN_HOME = C:\byteman-download-4.0.2 |
PATH添加%BYTEMAN_HOME%\bin
安装验证
1 | bmcheck |
2. 看一个例子
HelloWorld.java
1 | //HelloWorld.java |
规则文件appmain.btm
1 | #appmain.btm |
编译
1 | javac HelloWorld.java |
运行
1 | java HelloWorld |
规则检查
1 | bmcheck -cp . -v appmain.btm |
Byteman运行
1 | java -javaagent:%BYTEMAN_HOME%\lib\byteman.jar=script:appmain.btm HelloWorld |
运行结果
规则文件定义
1 | # 规则骨架 |
在脚本中我们使用了traceln语句,那么这个调用的其实是Byteman的org.jboss.byteman.rule.helper.Helper类的方法,这些方法都是已经内置的,可以直接在脚本中调用。我们也可以扩展Helper类进行调用。
从上面我们可以看出Byteman的使用方法:1.写规则文件,2.写Helper类的扩展方法(可选),3.指定脚本文件调用
3. 再看一个例子
输出参数和返回值
Main.java
1 | package com.vvvtimes; |
规则文件appmain.btm
1 | RULE trace arg1 |
编译
1 | javac com/vvvtimes/Main.java |
运行
1 | java com.vvvtimes.Main |
规则检查
1 | bmcheck -cp . -v scripts/appmain.btm |
byteman运行
1 | java -javaagent:%BYTEMAN_HOME%\lib\byteman.jar=script:scripts/appmain.btm com.vvvtimes.Main |
运行结果
这里的$0指的是当前对象。$1指的是当前方法的第一个参数,如果有多个参数,数字依次增长。$!指返回值,AT与AFTER同义
需要注意的是,RULE的语法规则中的CLASS METHOD都不支持通配符模式,逆向中如果用这个规则去写会很麻烦,官方建议用批量脚本去生成。。。
所以如果同名方法很多,还是用前面的AspectJ去找吧
更多内容可参考docs/byteman-programmers-guide.pdf
网上有个追踪局部变量的没啥用。需要-g编译,逆向中用不了
4. 扩展Helper类
看一个例子
新建目标项目和扩展Helper类项目,结构如下
其中目标项目使用上一篇博客的第二个例子的代码
扩展Helper类项目需要用到第三方jar,在C:\byteman-download-4.0.2\lib找到byteman.jar复制过来
TraceHelper.java代码如下
1 | package com.vvvtimes; |
将这个项目导出为BytemanHelperDemo.jar
目标项目里的规则文件tracing.btm内容如下,其中HELPER项指定自定义了Helper类名
1 | RULE trace return value1 |
编译
1 | javac com/vvvtimes/Main.java |
运行
1 | java com.vvvtimes.Main |
加helper类的规则文件检查,注意多了个-cp BytemanHelperDemo.jar
1 | bmcheck -cp . -cp BytemanHelperDemo.jar -v scripts/tracing.btm |
byteman运行
1 | java -cp ".;BytemanHelperDemo.jar;%CLASSPATH%" -javaagent:%BYTEMAN_HOME%\lib\byteman.jar=script:scripts/tracing.btm com.vvvtimes.Main |
运行结果如下
如果我们将上面的目标项目打包成jar,则命令可以改成如下形式
目标项目打包成的jar名为BytemanDemo2.jar
运行
1 | java -cp "BytemanDemo2.jar;%CLASSPATH%" com.vvvtimes.Main |
加helper类的规则文件检查
1 | bmcheck -cp BytemanDemo2.jar -cp BytemanHelperDemo.jar -v scripts/tracing.btm |
byteman运行
1 | java -cp "BytemanDemo2.jar;BytemanHelperDemo.jar;%CLASSPATH%" -javaagent:%BYTEMAN_HOME%\lib\byteman.jar=script:scripts/tracing.btm com.vvvtimes.Main |
运行结果如图
5. 运行后注入
Byteman可以在目标程序运行后进行注入,命令如下
运行后注入
- 查看java进程,找到目标进程的pid
1 | jps |
- 安装pid
1 | bminstall <pid> |
- 装载规则脚本
1 | bmsubmit -l tracing.btm |
//指定监听端口默认是9091
//bmsubmit -p
- 卸载规则脚本
1 | bmsubmit -u tracing.btm |
//指定监听端口
//bmsubmit -p
规则文件如果用到了自定义的扩展Helper类,需要先加载扩展类的jar包
- 装载jar包
1 | bmsubmit -s helpers.jar |
- 装载规则脚本
1 | bmsubmit -l tracing.btm |
看一个例子
Main.java
1 | //Main.java |
tracing.btm
1 | RULE trace arg1 |
编译
1 | javac com/vvvtimes/Main.java |
运行
1 | java com.vvvtimes.Main |
新开窗口查看注入到Main进程
查看进程
1 | jps |
安装pid
1 | bminstall 6852 |
规则检查
1 | bmcheck -cp . -v scripts/tracing.btm |
装载规则脚本
1 | bmsubmit -l scripts/tracing.btm |
之后回到Main窗口输入参数
运行结果如下