多读书多实践,勤思考善领悟

java逆向基础之九.简单类

本文于1997天之前发表,文中内容可能已经过时。

简单类

1. 例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class test {
public static int a;
private static int b;

public test() {
a = 0;
b = 0;
}

public static void set_a(int input) {
a = input;
}

public static int get_a() {
return a;
}

public static void set_b(int input) {
b = input;
}

public static int get_b() {
return b;
}
}

编译

1
javac test.java

反编译

1
javap -c -verbose test.class

构造方法,把所有的静态成员变量设置成0

1
2
3
4
5
6
7
8
9
10
11
12
public test();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: iconst_0
5: putstatic #2 // Field a:I
8: iconst_0
9: putstatic #3 // Field b:I
12: return

a的setter方法

1
2
3
4
5
6
7
8
public static void set_a(int);
descriptor: (I)V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=1, locals=1, args_size=1
0: iload_0
1: putstatic #2 // Field a:I
4: return

a的getter方法

1
2
3
4
5
6
7
public static int get_a();
descriptor: ()I
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=1, locals=0, args_size=0
0: getstatic #2 // Field a:I
3: ireturn

b的setter方法

1
2
3
4
5
6
7
8
public static void set_b(int);
descriptor: (I)V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=1, locals=1, args_size=1
0: iload_0
1: putstatic #3 // Field b:I
4: return

b的getter方法

1
2
3
4
5
6
7
public static int get_b();
descriptor: ()I
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=1, locals=0, args_size=0
0: getstatic #3 // Field b:I
3: ireturn

无论这个类的成员变量是公有还是私有,代码执行起来没有区别,但是成员变量的类型信息会显示再class文件中,在其他任何文件中都不能直接访问到类的私有成员变量。

2. 接下来我们创建一个对象去调用其中的方法

//ex1.java

1
2
3
4
5
6
7
public class ex1 {
public static void main(String[] args) {
test obj = new test();
obj.set_a(1234);
System.out.println(obj.a);
}
}

反编译

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=2, args_size=1
0: new #2 // class test
3: dup
4: invokespecial #3 // Method test."<init>":()V
7: astore_1
8: aload_1
9: pop
10: sipush 1234
13: invokestatic #4 // Method test.set_a:(I)V
16: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream;
19: aload_1
20: pop
21: getstatic #6 // Field test.a:I
24: invokevirtual #7 // Method java/io/PrintStream.println:(I)V
27: return

new指令创建了一个对象,但是没有调用其中的构造方法(构造方法在偏移块4中调用了)

偏移块14调用了set_a()方法

偏移块21访问了test类中的成员变量a


参考资料
http://www.vuln.cn/7115
《Reverse Engineering for Beginners》Dennis Yurichev著