类文件结构解析
程序员文章站
2022-06-06 11:16:34
...
就很好奇反编译出来自己写的代码,这里主要使用了五个工具,idea intellij、010edit、jgui、bytecode viewer、eclipse。
HelloWorld
package com.google; import java.util.ArrayList; import java.util.List; public class HelloWorld { public String hi(String val) { String p = val; System.out.println("val" + p); List<Integer> list = new ArrayList<Integer>(); list.add(1); for (Integer i : list) { int value = say(i); int ck3 = 9; if (value > ck3) { System.out.println(i); } } return p; } public int say(int p) { if (p > 1) { return p; } else { return 0; } } }
jdgui 反编译出来:
package com.google; import java.io.PrintStream; import java.util.ArrayList; import java.util.List; public class HelloWorld { public String hi(String val) { String p = val; System.out.println("val" + p); List<Integer> list = new ArrayList(); list.add(Integer.valueOf(1)); for (Integer i : list) { int value = say(i.intValue()); int ck3 = 9; if (value > ck3) { System.out.println(i); } } return p; } public int say(int p) { if (p > 1) { return p; } return 0; } }
- 如果没有混淆,几乎是一模一样的代码, 只要编译环境一样,修改下全量替换,运行环境就能够很顺利的运行一样。
- 加了混淆,其实也一样,并不会修改主逻辑,只是把变量修改为IIIIIIIIIIIIIIIII这类没有字面意义的意思,但是不影响逻辑
- 自定义Classloader+混淆,但是没有加密,其实效果一样,因为Classloader能够反编译出来破解
- 自定义Classloader+加密+混淆,达到基础效果,但是秘钥如果被拿到其实本质一样
- 自定义Classloader+多重加密+混淆,可以放心了吗?
接下来我就是要告诉大家如何破解哪些(自定义Classloader+多重加密+混淆),其实这个工作主要是帮助国外的朋友,所以不能讲得太细!
用bytecode viewer工具展示出来效果,say方法:
aload_1 astore_2 getstatic java/lang/System/out Ljava/io/PrintStream; new java/lang/StringBuilder dup invokespecial java/lang/StringBuilder/<init>()V ldc "val" invokevirtual java/lang/StringBuilder/append(Ljava/lang/String;)Ljava/lang/StringBuilder; aload_2 invokevirtual java/lang/StringBuilder/append(Ljava/lang/String;)Ljava/lang/StringBuilder; invokevirtual java/lang/StringBuilder/toString()Ljava/lang/String; invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V new java/util/ArrayList dup invokespecial java/util/ArrayList/<init>()V astore_3 aload_3 iconst_1 invokestatic java/lang/Integer/valueOf(I)Ljava/lang/Integer; invokeinterface java/util/List/add(Ljava/lang/Object;)Z 2 pop aload_3 invokeinterface java/util/List/iterator()Ljava/util/Iterator; 1 astore 4 aload 4 invokeinterface java/util/Iterator/hasNext()Z 1 ifeq 46 aload 4 invokeinterface java/util/Iterator/next()Ljava/lang/Object; 1 checkcast java/lang/Integer astore 5 aload_0 aload 5 invokevirtual java/lang/Integer/intValue()I invokevirtual com/google/HelloWorld/say(I)I istore 6 bipush 9 istore 7 iload 6 iload 7 if_icmple 45 getstatic java/lang/System/out Ljava/io/PrintStream; aload 5 invokevirtual java/io/PrintStream/println(Ljava/lang/Object;)V goto 25 aload_2 areturn
这里简单讲述下Class类结构
ClassFile { u4 magic; //魔数,固定值0xCAFEBABE u2 minor_version; //次版本号 u2 major_version; //主版本号 u2 constant_pool_count; //常量的个数 cp_info constant_pool[constant_pool_count-1]; //具体的常量池内容 u2 access_flags; //访问标识 u2 this_class; //当前类索引 u2 super_class; //父类索引 u2 interfaces_count; //接口的个数 u2 interfaces[interfaces_count]; //具体的接口内容 u2 fields_count; //字段的个数 field_info fields[fields_count]; //具体的字段内容 u2 methods_count; //方法的个数 method_info methods[methods_count]; //具体的方法内容 u2 attributes_count; //属性的个数 attribute_info attributes[attributes_count]; //具体的属性内容 }
具体的说明请参照http://blog.jamesdbloom.com/JavaCodeToByteCode_PartOne.html
使用010Editor:
第一个箭头就是magic
第二个箭头就是major version
需要修改的constants pool,method info
假设需要加入如下的java代码
public int say(int p) { p = 123; if (p > 1) { return p; } else { return 0; } }
可以看到加入了p=123;
bipush 123 istore_1 iload_1 iconst_1 if_icmple 8 iload_1 ireturn iconst_0 ireturn
查看指令表bipush 0x10
通过计算得到123,对应的字节码为7B
通过010editor分析,很快定位到say方法,以及很快找到数值
接下来你要干的事情就很容易了,使用010Editor改完保存,再使用jdgui查看下,当然如果值超出length,就需要修改attribute info表的信息
下一篇: 乖孙儿
推荐阅读
-
实例解析iOS应用多线程开发中NSthread类的用法
-
Android编程解析XML文件的方法详解【基于XmlPullParser】
-
html转换成word文档(分享文件转换工具类)
-
收藏的asp.net文件上传类源码
-
java解析出url请求的路径和参数键值对类(解析出url请求的路径,包括页面)
-
Android studio怎么创建文件? Android studio新建Java类文件的方法
-
解析Android资源文件及他们的读取方法详解
-
基于android中读取assets目录下a.txt文件并进行解析的深入分析
-
摘自织梦CMS的HTTP文件下载类
-
Python中使用装饰器和元编程实现结构体类实例