`
cywhoyi
  • 浏览: 418616 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

原理跟踪脚本

    博客分类:
  • JAVA
 
阅读更多

 

写在前面的话:Btrace系列是我将平时里学习和使用Btrace的一些经验的总结,拿出来和大家一起交流一下,希望在这个过程中能找寻出自己理解或使用上的错误之处。

 

一、Btrace的简介:

    Btrace是由Kenai 开发的一个开源项目,是一种动态跟踪分析JAVA源代码的工具。它可以用来帮我们做运行时的JAVA程序分析,监控等等操作,当然,它也不是万能的,BTrace也有一些使用上的限制,如:不能在脚本中新建类等等,这些在官方网站上有很详细的介绍,大家有兴趣可以查看:http://kenai.com/projects/btrace/pages/UserGuide。

 

二、JDK6的几个新特性:

     Btrace是由:Attach API + BTrace脚本解析引擎 + ASM + JDK6 Instumentation组成,这里要注意最后一项是JDK6的Instumentation,为什么一定要是JDK6呢?我们就要来看一下JDK6为我们提供了什么:

1、虚拟机启动后的Instumentation:

        Instumentation早在JDK5的时候就已经提出了,但是它有个局限性,premain函数只能在main函数之前被运行(对于Instumentation不熟悉的请去Sun官网查看),而JDK6之后提供了一个叫做agentmain的函数,它可以在main函数运行后在运行,代码如下:

Java代码  收藏代码
  1. public static void agentmain(String args, Instrumentation inst)  
  2. public static void agentmain(String args)  

 这个函数的功能通premain函数一样,可以对类进行各种操作。同premain函数一样,在manifest 文件里面设置“Agent-Class”来指定包含 agentmain 函数的类。

2、Instumentation提供的新方法retransformClasses:

        这个新方法可以在agentmain函数中调用,它的功能和redefineClasses 一样,可以修改类的定义且是批量的。        

3、BootClassPath和SystemClassPath的动态指定:

       在JDK6之前,我们知道可以通过系统参数或者虚拟机启动参数,设置一个虚拟机运行时的boot class加载路径和system class加载路径,但是在启动后,这个路径是不可以修改的,并且,我们要在启动后再去加载一个*.jar文件是不可能的,但是在JDK6以后,这个规定被打破了,可以使用Instrumentation的appendToBootstrapClassLoaderSearch和appendToSystemClassLoaderSearch来修改路径或加载新的*.jar(注意:虽然实际的classpath被修改了,但是在property中的java.class.path却没有受任何影响)。

 

正因为以上的新特性,才缔造出了Btrace的想法以至于最后的实现。

 

三、Btrace的原理:

Btrace首先是通过Attach API中提供的VirtualMachine.attach(PID)方法来获得要监控的JVM,然后使用VirtualMachine.loadAgent("*.jar")方法来加载jar文件,这个jar文件中会包含Btrace的一个很重要的类com.sun.btrace.agent.Main,这个类里定义了如下的函数:

Java代码  收藏代码
  1. public static void premain(String args, Instrumentation inst) {  
  2.         main(args, inst);  
  3.  }  
  4.   
  5. public static void agentmain(String args, Instrumentation inst) {  
  6.        main(args, inst);  
  7. }  

 这里两个函数都调用了一个main方法,如下:

Java代码  收藏代码
  1. private static synchronized void main(final String args, final Instrumentation inst) {  
  2. ......  
  3. inst.appendToBootstrapClassLoaderSearch(new JarFile(new File(path)));  
  4. ......  
  5. inst.appendToSystemClassLoaderSearch(new JarFile(new File(path)));  
  6. ......  
  7. startServer();  
  8. }  

 这里省去了不必要的代码,主要三行代码,头两行不用解释,上面已经说过用途了,第三行解释一下,代码如下:

Java代码  收藏代码
  1. private static void startServer() {  
  2. ......  
  3. while (true) {  
  4.             try {  
  5. ......  
  6.                 handleNewClient(client);  
  7.             } catch (RuntimeException re) {  
  8.                 if (isDebug()) debugPrint(re);  
  9.             } catch (IOException ioexp) {  
  10.                 if (isDebug()) debugPrint(ioexp);  
  11.             }  
  12.         }  
  13. }  

 关键看一下handleNewClient(client)方法的调用,这个是修改类定义的地方,如下:

Java代码  收藏代码
  1. private static void handleNewClient(final Client client) {  
  2. ......  
  3. inst.addTransformer(client, true);  
  4. ......  
  5. inst.retransformClasses(classes);  
  6. }  

 这两句话就实现了对现有内存中的类定义的替换,当在一次调用new创建一个新对象时就会使用新的类定义,而老的已经生成的类对象是不会收到干扰的。

那又是谁取执行了对类定义的修改呢,这个是由BTrace脚本解析引擎 + ASM来实现的,脚本引擎负责解析我们所写的脚本,而ASM来对JAVA的字节码进行增强修改。你在Btrace的com.sun.btrace.agent.Client中可以看到ASM的影子,代码如下:

Java代码  收藏代码
  1. abstract class Client implements ClassFileTransformer, CommandListener {  
  2. static {  
  3.         ClassFilter.class.getClass();  
  4.         ClassReader.class.getClass();  
  5.         ClassWriter.class.getClass();  
  6. ......  
  7.     }  
  8.   
  9.  private byte[] instrument(Class clazz, String cname, byte[] target) {  
  10.         byte[] instrumentedCode;  
  11.         try {  
  12.             ClassWriter writer = InstrumentUtils.newClassWriter(target);  
  13.             ClassReader reader = new ClassReader(target);  
  14.             Instrumentor i = new Instrumentor(clazz, className,  btraceCode, onMethods, writer);  
  15. ......  
  16.     }  

 现在我们在回顾一下整个流程,用Attach API附加*.jar然后使用BTrace脚本解析引擎 + ASM来实现对类的修改,在使用Instumentation实现类的内存替换,完毕!perfect!BTrace原来也就这么回事,但是我们不得不佩服开发团队的思维和整合能力,向牛人致敬!

分享到:
评论

相关推荐

    模型预测控制实现轨迹跟踪matlab脚本程序,可直接运行

    在本MATLAB脚本程序中,MPC被应用于道路场景的轨迹跟踪任务,实现了车辆或机器人实时、精确地跟随预设轨迹行驶。这种技术广泛应用于自动驾驶汽车、无人机以及其他需要精确路径控制的领域。 首先,我们要理解MPC的...

    脱壳脚本OD使用,右键,脚本,打开某个脚本即可脱壳!!!.rar

    OllyDbg(简称OD)是一款16/32位Windows动态调试器,它允许用户跟踪程序执行,查看内存,修改指令,以及进行各种调试任务。OD的强大之处在于它的脚本功能,可以创建自定义的脚本来自动化复杂的逆向工程任务,如脱壳...

    linux下批量执行oracle脚本的shell脚本

    `说明.txt` 文件可能是对整个过程的详细说明,包括如何运行shell脚本,脚本的工作原理,以及可能遇到的问题和解决方案。阅读这份说明有助于理解脚本的使用方法和潜在问题。 执行Oracle SQL脚本的shell脚本通常包含...

    OD专用脱壳脚本

    脚本技术在OD中的应用主要体现在自定义插件和自动化脚本上,这些脚本可以扩展OD的功能,执行特定的任务,如自动跟踪、分析、解密等。OD脱壳脚本通常由熟练的逆向工程师编写,包含了一系列复杂的指令序列,用于识别并...

    OllyDBG脚本编辑器

    通过脚本,用户可以执行一系列复杂指令,例如自动跟踪特定函数,分析内存变化,或者在满足特定条件时触发动作,这对于逆向工程和恶意软件分析等任务非常有用。 OllyScript语法结构清晰,它结合了汇编语言的精度和...

    抓取systrace脚本.rar

    1. **设置脚本**:通常,一个Systrace脚本会包含一系列的命令行选项,指定要记录的跟踪类别、时间长度等参数。例如,`systrace.py -o output.html --time=5 -c gfx view`将记录5秒的GPU和视图系统相关的事件,并生成...

    2、Tamper脚本分析(支持所有类型数据库的Tamper脚本)-01

    在 Sqlmap 中,Tamper 脚本的分析是对 Tamper 脚本的执行过程的跟踪和分析,这种方式可以帮助我们更好地理解 Tamper 脚本的工作机理和实现原理。 Tamper 脚本的分析是 Sqlmap 中最重要的组件之一,它能够对各种类型...

    ollydbg-全脚本OD

    同时,学习和理解脚本的工作原理也是提升逆向工程技能的好方法。对于初学者来说,可以先从简单的脚本开始,逐步深入到更复杂的调试任务。而对经验丰富的使用者,这些脚本则提供了快速解决问题和提升工作效率的工具。...

    【批量下载】自动加域脚本等.zip

    在IT运维领域,批量操作是提高工作效率的关键。本压缩包"【批量下载】自动加域脚本等.zip"中包含的资源,显然专注于自动化管理和...理解并掌握这些脚本的使用方法和背后的原理,对于提升IT运维效率和管理水平至关重要。

    Unity3D中文脚本使用手册

    首先,手册简要介绍了Unity3D脚本的工作原理,包括脚本如何通过附加到游戏物体上来工作。在Unity3D中,脚本被附加到游戏物体上,形成一种组件化的结构。游戏中的行为通过脚本中的函数在特定的时机被调用,比如Update...

    京东自动抢茅台脚本!

    总的来说,这个京东自动抢茅台脚本项目涉及到网络编程、自动化、模拟用户行为和可能的反反爬虫策略,对于想要了解这一领域的用户,需要有一定的编程基础和对网络请求原理的理解。使用时,务必遵循京东的使用协议,并...

    Python-基于pywin32的游戏脚本

    首先,我们要理解游戏脚本的基本原理。通常,游戏脚本是通过模拟用户输入来自动化执行一系列操作,例如移动角色、点击按钮等。在这个特定的案例中,我们使用Python来抓取Windows游戏窗口的图像,然后通过图像处理...

    自录QTP9.0脚本

    QTP的录制功能使得测试人员可以轻松创建测试脚本,只需通过实际操作应用,QTP会自动跟踪并记录这些操作。在这个计算器脚本中,可能记录了点击按钮、输入数字等动作,并转化为可执行的代码。 **三、QTP对象库** QTP...

    Trend ManagerNT - MetaTrader 4脚本.zip

    此脚本通过分析市场价格行为,帮助交易者识别并跟踪当前市场趋势,从而制定更加精准的交易决策。它的工作原理是基于一定的技术分析算法,如移动平均线、趋势线或其他技术指标,以确定市场的上升、下降或横盘趋势。 ...

    AS脚本查看器

    "NEWS"文件可能记录了AS脚本查看器的更新历史,包括新功能、改进和修复的bug,对于跟踪软件的发展和变化非常有用。 "README"文件通常会介绍软件的用途、如何使用以及安装步骤等基本信息,是初次接触软件时的重要...

    外汇下单脚本

    本文将深入探讨这一脚本的工作原理、使用方法以及其在实际交易中的应用。 首先,"外汇下单脚本"主要由两个核心文件组成:doublePending_10_Orders_SL50_TP50_Script.ex4和doublePending_10_Orders_SL50_TP50_Script...

    Genesis2000脚本接口C#2010可调试

    在调试过程中,Visual Studio 2010的调试工具将非常有用,可以设置断点,查看变量值,跟踪代码执行流程,帮助定位和解决问题。 此外,为了确保代码的健壮性,你需要处理可能出现的异常情况,例如连接失败、权限不足...

    Shell脚本专家指南

    - **shell跟踪选项**:介绍了如何启用shell的跟踪功能,以便于调试脚本运行过程。 - **简单输出语句**:讲解了如何使用echo或printf命令输出信息。 - **根据调试层次控制输出**:通过设置不同的调试级别,控制输出的...

    LBR_Paint_Bars - MetaTrader 5脚本.zip

    本文将深入探讨这个脚本的工作原理、应用场景及使用方法。 一、LBR_Paint_Bars脚本概述 "LBR_Paint_Bars"脚本是由LBR团队开发的,旨在增强MT5图表的可视化效果。通过自定义颜色和样式来绘制蜡烛图,此脚本能够帮助...

    linux监控cpu脚本

    #### 三、脚本工作原理 此脚本通过调用`top`命令获取当前CPU使用情况,并利用正则表达式和`awk`工具提取出CPU使用百分比。接着根据CPU使用率的大小进行条件分支处理,当CPU使用率小于等于50%时,将相关信息写入文件...

Global site tag (gtag.js) - Google Analytics