Posted on 2012-04-15 16:27
zljpp 阅读(138)
评论(0) 编辑 收藏
上一节我们看了一个简单的例子,我们通过直接改变二进制的class文件,改变程序的行为,
这一节继续上面的例子看一些其他的情况,用前面的HelloWorld为例
先看java 文件:
public class HelloWorld{
public static void main(String [] arvgs){
System.out.println("hello world");
}
}
它的class文件
00000000h: CA FE BA BE 00 00 00 2E 00 1D 0A 00 06 00 0F 09 ; 漱壕............
00000010h: 00 10 00 11 08 00 12 0A 00 13 00 14 07 00 15 07 ; ................
00000020h: 00 16 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29 ; .....<init>...()
00000030h: 56 01 00 04 43 6F 64 65 01 00 0F 4C 69 6E 65 4E ; V...Code...LineN
00000040h: 75 6D 62 65 72 54 61 62 6C 65 01 00 04 6D 61 69 ; umberTable...mai
00000050h: 6E 01 00 16 28 5B 4C 6A 61 76 61 2F 6C 61 6E 67 ; n...([Ljava/lang
00000060h: 2F 53 74 72 69 6E 67 3B 29 56 01 00 0A 53 6F 75 ; /String;)V...Sou
00000070h: 72 63 65 46 69 6C 65 01 00 0F 48 65 6C 6C 6F 57 ; rceFile...HelloW
00000080h: 6F 72 6C 64 2E 6A 61 76 61 0C 00 07 00 08 07 00 ; orld.java.......
00000090h: 17 0C 00 18 00 19 01 00 0B 68 65 6C 6C 6F 20 77 ; .........hello w
000000a0h: 6F 72 6C 64 07 00 1A 0C 00 1B 00 1C 01 00 0A 48 ; orld...........H
000000b0h: 65 6C 6C 6F 57 6F 72 6C 64 01 00 10 6A 61 76 61 ; elloWorld...java
000000c0h: 2F 6C 61 6E 67 2F 4F 62 6A 65 63 74 01 00 10 6A ; /lang/Object...j
000000d0h: 61 76 61 2F 6C 61 6E 67 2F 53 79 73 74 65 6D 01 ; ava/lang/System.
000000e0h: 00 03 6F 75 74 01 00 15 4C 6A 61 76 61 2F 69 6F ; ..out...Ljava/io
000000f0h: 2F 50 72 69 6E 74 53 74 72 65 61 6D 3B 01 00 13 ; /PrintStream;...
00000100h: 6A 61 76 61 2F 69 6F 2F 50 72 69 6E 74 53 74 72 ; java/io/PrintStr
00000110h: 65 61 6D 01 00 07 70 72 69 6E 74 6C 6E 01 00 15 ; eam...println...
00000120h: 28 4C 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 ; (Ljava/lang/Stri
00000130h: 6E 67 3B 29 56 00 21 00 05 00 06 00 00 00 00 00 ; ng;)V.!.........
00000140h: 02 00 01 00 07 00 08 00 01 00 09 00 00 00 1D 00 ; ................
00000150h: 01 00 01 00 00 00 05 2A B7 00 01 B1 00 00 00 01 ; .......*?.?...
00000160h: 00 0A 00 00 00 06 00 01 00 00 00 01 00 09 00 0B ; ................
00000170h: 00 0C 00 01 00 09 00 00 00 25 00 02 00 01 00 00 ; .........%......
00000180h: 00 09 B2 00 02 12 03 B6 00 04 B1 00 00 00 01 00 ; ..?...?.?....
00000190h: 0A 00 00 00 0A 00 02 00 00 00 03 00 08 00 04 00 ; ................
000001a0h: 01 00 0D 00 00 00 02 00 0E ; .........
找到第18号常量池,它是一个constant_utf8类型,在第 000000a0h 行 bytes=0X 68 65 6C 6C 6F 20 77 6F 72 6C 64表示的正好是我们要输出的内容,“hello world”,其中0X6F 表示 0,现在我们在0X6F 之前增加4个字节的 0x6F ,如下:
00000000h: CA FE BA BE 00 00 00 2E 00 1D 0A 00 06 00 0F 09 ; 漱壕............
00000010h: 00 10 00 11 08 00 12 0A 00 13 00 14 07 00 15 07 ; ................
00000020h: 00 16 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29 ; .....<init>...()
00000030h: 56 01 00 04 43 6F 64 65 01 00 0F 4C 69 6E 65 4E ; V...Code...LineN
00000040h: 75 6D 62 65 72 54 61 62 6C 65 01 00 04 6D 61 69 ; umberTable...mai
00000050h: 6E 01 00 16 28 5B 4C 6A 61 76 61 2F 6C 61 6E 67 ; n...([Ljava/lang
00000060h: 2F 53 74 72 69 6E 67 3B 29 56 01 00 0A 53 6F 75 ; /String;)V...Sou
00000070h: 72 63 65 46 69 6C 65 01 00 0F 48 65 6C 6C 6F 57 ; rceFile...HelloW
00000080h: 6F 72 6C 64 2E 6A 61 76 61 0C 00 07 00 08 07 00 ; orld.java.......
00000090h: 17 0C 00 18 00 19 01 00 0B 68 65 6C 6C 6F 20 77 ; .........hello w
000000a0h: 6F 6F 6F 6F 6F 72 6C 64 07 00 1A 0C 00 1B 00 1C ; ooooorld........
000000b0h: 01 00 0A 48 65 6C 6C 6F 57 6F 72 6C 64 01 00 10 ; ...HelloWorld...
000000c0h: 6A 61 76 61 2F 6C 61 6E 67 2F 4F 62 6A 65 63 74 ; java/lang/Object
000000d0h: 01 00 10 6A 61 76 61 2F 6C 61 6E 67 2F 53 79 73 ; ...java/lang/Sys
000000e0h: 74 65 6D 01 00 03 6F 75 74 01 00 15 4C 6A 61 76 ; tem...out...Ljav
000000f0h: 61 2F 69 6F 2F 50 72 69 6E 74 53 74 72 65 61 6D ; a/io/PrintStream
00000100h: 3B 01 00 13 6A 61 76 61 2F 69 6F 2F 50 72 69 6E ; ;...java/io/Prin
00000110h: 74 53 74 72 65 61 6D 01 00 07 70 72 69 6E 74 6C ; tStream...printl
00000120h: 6E 01 00 15 28 4C 6A 61 76 61 2F 6C 61 6E 67 2F ; n...(Ljava/lang/
00000130h: 53 74 72 69 6E 67 3B 29 56 00 21 00 05 00 06 00 ; String;)V.!.....
00000140h: 00 00 00 00 02 00 01 00 07 00 08 00 01 00 09 00 ; ................
00000150h: 00 00 1D 00 01 00 01 00 00 00 05 2A B7 00 01 B1 ; ...........*?.?
00000160h: 00 00 00 01 00 0A 00 00 00 06 00 01 00 00 00 01 ; ................
00000170h: 00 09 00 0B 00 0C 00 01 00 09 00 00 00 25 00 02 ; .............%..
00000180h: 00 01 00 00 00 09 B2 00 02 12 03 B6 00 04 B1 00 ; ......?...?.?
00000190h: 00 00 01 00 0A 00 00 00 0A 00 02 00 00 00 03 00 ; ................
000001a0h: 08 00 04 00 01 00 0D 00 00 00 02 00 0E ; .............
其他不改变,运行如下:
可以看到错误提醒tag 111 非法,为什么呢,回顾前面的知识,看第18号常量池:
第18个常量:tag=0X 01,为一个constant_UTF8类型(utf8编码的字符串),根据它的定义后面的长度可变,length=0X00 0B表示后面有11个字节属于它的内容:bytes=0X 68 65 6C 6C 6F 20 77 6F 6f 6f 6f ,再往下为另外一个常量,tag=0X6F =111,而class 文件只定义了 tag=1,3,4...11,12.。11种类型(没有2),所以会找不到tag=111,那怎么样才能想程序中多输出字符呢,其实很简单,只是需要将第18号常量的长度增加4个,由0X0B ---》0X0F 。即如下:主要看 000000a0h 行 和 00000070h 行
00000000h: CA FE BA BE 00 00 00 2E 00 1D 0A 00 06 00 0F 09 ; 漱壕............
00000010h: 00 10 00 11 08 00 12 0A 00 13 00 14 07 00 15 07 ; ................
00000020h: 00 16 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29 ; .....<init>...()
00000030h: 56 01 00 04 43 6F 64 65 01 00 0F 4C 69 6E 65 4E ; V...Code...LineN
00000040h: 75 6D 62 65 72 54 61 62 6C 65 01 00 04 6D 61 69 ; umberTable...mai
00000050h: 6E 01 00 16 28 5B 4C 6A 61 76 61 2F 6C 61 6E 67 ; n...([Ljava/lang
00000060h: 2F 53 74 72 69 6E 67 3B 29 56 01 00 0A 53 6F 75 ; /String;)V...Sou
00000070h: 72 63 65 46 69 6C 65 01 00 0F 48 65 6C 6C 6F 57 ; rceFile...HelloW
00000080h: 6F 72 6C 64 2E 6A 61 76 61 0C 00 07 00 08 07 00 ; orld.java.......
00000090h: 17 0C 00 18 00 19 01 00 0F 68 65 6C 6C 6F 20 77 ; .........hello w
000000a0h: 6F 6F 6F 6F 6F 72 6C 64 07 00 1A 0C 00 1B 00 1C ; ooooorld........
000000b0h: 01 00 0A 48 65 6C 6C 6F 57 6F 72 6C 64 01 00 10 ; ...HelloWorld...
000000c0h: 6A 61 76 61 2F 6C 61 6E 67 2F 4F 62 6A 65 63 74 ; java/lang/Object
000000d0h: 01 00 10 6A 61 76 61 2F 6C 61 6E 67 2F 53 79 73 ; ...java/lang/Sys
000000e0h: 74 65 6D 01 00 03 6F 75 74 01 00 15 4C 6A 61 76 ; tem...out...Ljav
000000f0h: 61 2F 69 6F 2F 50 72 69 6E 74 53 74 72 65 61 6D ; a/io/PrintStream
00000100h: 3B 01 00 13 6A 61 76 61 2F 69 6F 2F 50 72 69 6E ; ;...java/io/Prin
00000110h: 74 53 74 72 65 61 6D 01 00 07 70 72 69 6E 74 6C ; tStream...printl
00000120h: 6E 01 00 15 28 4C 6A 61 76 61 2F 6C 61 6E 67 2F ; n...(Ljava/lang/
00000130h: 53 74 72 69 6E 67 3B 29 56 00 21 00 05 00 06 00 ; String;)V.!.....
00000140h: 00 00 00 00 02 00 01 00 07 00 08 00 01 00 09 00 ; ................
00000150h: 00 00 1D 00 01 00 01 00 00 00 05 2A B7 00 01 B1 ; ...........*?.?
00000160h: 00 00 00 01 00 0A 00 00 00 06 00 01 00 00 00 01 ; ................
00000170h: 00 09 00 0B 00 0C 00 01 00 09 00 00 00 25 00 02 ; .............%..
00000180h: 00 01 00 00 00 09 B2 00 02 12 03 B6 00 04 B1 00 ; ......?...?.?
00000190h: 00 00 01 00 0A 00 00 00 0A 00 02 00 00 00 03 00 ; ................
000001a0h: 08 00 04 00 01 00 0D 00 00 00 02 00 0E ; .............
再运行: