JAVA字节码修改异常分析

源class反编译后代码如下:

 public boolean isExpiring()
  {
    if ((this.timestamp == null) || (this.timestamp.length() <= 0)) {
      return true;
    }
    boolean isExpiring = false;
    try {
      SimpleDateFormat df = new SimpleDateFormat(
        SSOAuthConfig.getAuthDataDateFormart());
      Date date1 = df.parse(this.timestamp);
      long time1 = date1.getTime();
      long time2 = System.currentTimeMillis();
      long diffMilSecs = time2 - time1;
      Log.i(TAG, "diffMilSecs: " + String.valueOf(diffMilSecs));
      if (diffMilSecs > 0L)
        isExpiring = true;
    }
    catch (Exception e) {
      isExpiring = true;
      Log.e(TAG, "parse  Date Exception", e);
    }

    return isExpiring;
  }

现在要把

if (diffMilSecs > 0L)这一行改成
if (diffMilSecs > -100000L)在javaBite中修改之后文件异常,不能反编译。(按理来说只要常量池里添加一个常量,并在此处引用即可。改动非常小,不会有什么影响,而且之前class文件修改都是正常的,为什么这次不行了呢?)

对比正常class文件反编译和异常class文件使用ida反编译结果如下:修改过的文件,反编译时报错,但IDA能显示出异常的位置。再看一下异常的反编译:

我们可以看到.stack和.end stack之间的区域异常。单独的一个class文件,还没有运行,怎么会有stack信息呢?IDA这里的stack到底代表什么呢?我们的修改后的class文件反编译时异常和这些有什么联系么?

看下以下描述StackMapTable Attribute在J2SE 6中引入,记录了类型检查时需要用到的信息,如字节码的偏移量、局部变量的验证类型、操作栈中的验证类型,用于类型检查过程。在Code Attribute只能包含一项StackMapTable Attribute,记录所有当前Code Attribute中的验证信息。

参见Java字节码(.class文件)格式详解(二) 到底和这个有没有关系呢?对比.class文件格式里的
StackMapTable 这个段的字段定义,可以解析出ida所示的.stack和.end stack里的信息。具体就不写了,过程不复杂,但是手动解比较烦琐,对照结构体一项一项的比就好了(像IDA .stack里的cn/com/zte/android/securityauth/model/SSOAuthResultData这种信息,就是在class文件的常量池里的一个引用)。目前也没有找到什么有用的工具详细解析stackmaptable。

总结:j2se 6之后的编译器编译的class文件修改起来比较麻烦,要考虑StackMapTable的帧校验。如果能反出源码,最好反出源码修改,再编成class文件。如果不能,只能找工具帮忙了,至于手动写StackMapTable,还是不要考虑了吧。
时间: 2024-11-03 21:21:07

JAVA字节码修改异常分析的相关文章

一文让你明白Java字节码

也许你写了无数行的代码,也许你能非常溜的使用高级语言,但是你未必了解那些高级语言的执行过程.例如大行其道的Java. Java号称是一门"一次编译到处运行"的语言,但是我们对这句话的理解深度又有多少呢?从我们写的java文件到通过编译器编译成java字节码文件(也就是.class文件),这个过程是java编译过程:而我们的java虚拟机执行的就是字节码文件.不论该字节码文件来自何方,由哪种编译器编译,甚至是手写字节码文件,只要符合java虚拟机的规范,那么它就能够执行该字节码文件.那么

一文让你明白 Java 字节码

前言 也许你写了无数行的代码,也许你能非常溜的使用高级语言,但是你未必了解那些高级语言的执行过程.例如大行其道的Java. Java号称是一门"一次编译到处运行"的语言,但是我们对这句话的理解深度又有多少呢?从我们写的java文件到通过编译器编译成java字节码文件(也就是.class文件),这个过程是java编译过程:而我们的java虚拟机执行的就是字节码文件.不论该字节码文件来自何方,由哪种编译器编译,甚至是手写字节码文件,只要符合java虚拟机的规范,那么它就能够执行该字节码文件

关于java字节码框架ASM的学习

一.什么是ASM ASM是一个java字节码操纵框架,它能被用来动态生成类或者增强既有类的功能.ASM 可以直接产生二进制 class 文件,也可以在类被加载入 Java 虚拟机之前动态改变类行为.Java class 被存储在严格格式定义的 .class文件里,这些类文件拥有足够的元数据来解析类中的所有元素:类名称.方法.属性以及 Java 字节码(指令).ASM从类文件中读入信息后,能够改变类行为,分析类信息,甚至能够根据用户要求生成新类.asm字节码增强技术主要是用来反射的时候提升性能的,

Java字节码操作开源框架简介

avassist  Javassist是一个开源的分析.编辑和创建Java字节码的类库.是由东京技术学院的数学和计算机科学系的 Shigeru Chiba 所创建的.它已加入了开放源代码JBoss 应用服务器项目,通过使用Javassist对字节码操作为JBoss实现动态AOP框架. BCEL  Byte Code Engineering Library (BCEL),这是Apache Software Foundation 的Jakarta 项目的一部分.BCEL是 Java classwor

第五篇 java字节码操作

java动态性的两种常见的实现方式: ①字节码操作 ②反射 运行时操作字节码可以让我们实现如下功能: ①动态生成新的类 ②动态改变某个类的结构(添加.删除.修改  新的属性或方法) 优点: 比反射的开销小,性能高 Javassist性能高于反射,低于ASM BCEL(Byte Code Engineering Library): 是java classworking 广泛使用的一种框架,它可以让你深入JVM汇编语言进行类操作的细节.BCEL与Javassist有不同的处理字节码的方法,BCEL在

JVM(四):深入分析Java字节码-下

JVM(四):深入分析Java字节码-下 在上文中,我们讲解了 Class 文件中的文件标识,常量池等内容.在本文中,我们就详细说一下剩下的指令集内容,阐述其分别代表了什么含义,以及 JVM 团队这样设计的意义. 简介 JVM 指令设计为仅有一个字节长度,由操作码和紧随其后的零至多个操作数来构成. 这里说到 JVM 的指令仅有一个字节,这意味着 JVM 在操作超过一个字节长度的数据时,需要在运行时重建出多字节数据类型的具体数据结构,例如 Long 等.这会导致这个操作不是原子操作,在高并发的情况

这一次,彻底弄懂「Java字节码文件」

提前祝福各位读者??圣诞快乐!这个圣诞节请在学习中度过! 不啰嗦,直接从最最简单的一段Java源代码开启Java整体字节码分析之旅. 1.Java 源码文件 package com.dskj.jvm.bytecode; public class MyTest1 { private int a = 1; public int getA() { return a; } public void setA(int a) { this.a = a; } } 2.Java字节码文件 IDEA工具编译代码后,

Java字节码 小结

Reference javap 基本使用方法 深入理解java字节码 从Java代码到字节码 Java字节码.class文件案例分析 字节码 核心概念 Class文件是8位字节流,按字节对齐.之所以称为字节码,是由于每条指令都仅仅占领一个字节.全部的操作码和操作数都是按字节对齐的. 数据结构 Java虚拟机规范中规定.Class文件格式採用一种相似C语言结构体的伪结构来存储,它仅仅有两种数据类型 无符号数(基本数据类型) 主要用于描写叙述数字.索引引用.数量值.或UTF-8编码构成的字符串: u

Java字节码基础[转]

原文链接:http://it.deepinmind.com/jvm/2014/05/24/mastering-java-bytecode.html Java是一门设计为运行于虚拟机之上的编程语言,因此它需要一次编译,处处运行(当然也是一次编写,处处测试).因此,安装到你系统上的JVM是原生的程序,而运行在它之上的代码是平台无关的.Java字节码就是你写的源代码的中间表现形式,也就是你的代码编译后的产物.你的class文件就是字节码. 简单点说,字节码就是JVM使用的代码集,它在运行时可能会被JI