逆向基础（十三） JAVA (二) – 糖果

• A+

54.7 线性同余伪随机数生成器

``````#!java
public class LCG
{
public static int rand_state;
public void my_srand (int init)
{
rand_state=init;
}
public static int RNG_a=1664525;
public static int RNG_c=1013904223;

public int my_rand ()
{
rand_state=rand_state*RNG_a;
rand_state=rand_state+RNG_c;
return rand_state & 0x7fff;
}
}
``````

``````static {};
flags: ACC_STATIC
Code:
stack=1, locals=0, args_size=0
0: ldc #5 // int 1664525
2: putstatic #3 // Field RNG_a:I
5: ldc #6 // int 1013904223
7: putstatic #4 // Field RNG_c:I
10: return
``````

``````public void my_srand(int);
flags: ACC_PUBLIC
Code:
stack=1, locals=2, args_size=2
1: putstatic #2 // Field ⤦
Ç rand_state:I
4: return
``````

``````public int my_rand();
flags: ACC_PUBLIC
Code:
stack=2, locals=1, args_size=1
0: getstatic #2 // Field ⤦
Ç rand_state:I
3: getstatic #3 // Field RNG_a:I
6: imul
7: putstatic #2 // Field ⤦
Ç rand_state:I
10: getstatic #2 // Field ⤦
Ç rand_state:I
13: getstatic #4 // Field RNG_c:I
17: putstatic #2 // Field ⤦
Ç rand_state:I
20: getstatic #2 // Field ⤦
Ç rand_state:I
23: sipush 32767
26: iand
27: ireturn
``````

54.8 条件跳转

``````#!java
public class abs
{
public static int abs(int a)
{
if (a<0)
return -a;
return a;
}
}
``````

``````public static int abs(int);
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=1, locals=1, args_size=1
1: ifge 7
5: ineg
6: ireturn
8: ireturn
``````

``````#!java
public static int min (int a, int b)
{
if (a>b)
return b;
return a;
}
``````

``````public static int min(int, int);
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=2, args_size=2
2: if_icmple 7
6: ireturn
8: ireturn
``````

if_icmple会从栈中弹出两个值进行比较，如果第二个小于或者等于第一个，那么跳转到偏移位7.

``````#!java
public static int max (int a, int b)
{
if (a>b)
return a;
return b;
}
``````

``````public static int max(int, int);
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=2, args_size=2
2: if_icmple 7
6: ireturn
8: ireturn
``````

``````#!java
public class cond
{
public static void f(int i)
{
if (i<100)
System.out.print("<100");
if (i==100)
System.out.print("==100");
if (i>100)
System.out.print(">100");
if (i==0)
System.out.print("==0");
}
}
``````

``````public static void f(int);
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=1, args_size=1
1: bipush 100
3: if_icmpge 14
6: getstatic #2 // Field java/⤦
Ç lang/System.out:Ljava/io/PrintStream;
9: ldc #3 // String <100
11: invokevirtual #4 // Method java/io⤦
Ç /PrintStream.print:(Ljava/lang/String;)V
15: bipush 100
17: if_icmpne 28
20: getstatic #2 // Field java/⤦
Ç lang/System.out:Ljava/io/PrintStream;
23: ldc #5 // String ==100
25: invokevirtual #4 // Method java/io⤦
Ç /PrintStream.print:(Ljava/lang/String;)V
29: bipush 100
31: if_icmple 42
34: getstatic #2 // Field java/⤦
Ç lang/System.out:Ljava/io/PrintStream;
37: ldc #6 // String >100
39: invokevirtual #4 // Method java/io⤦
Ç /PrintStream.print:(Ljava/lang/String;)V
43: ifne 54
46: getstatic #2 // Field java/⤦
Ç lang/System.out:Ljava/io/PrintStream;
49: ldc #7 // String ==0
51: invokevirtual #4 // Method java/io⤦
Ç /PrintStream.print:(Ljava/lang/String;)V
54: return
``````

if_icmpge出栈两个值，并且比较两个数值，如果第的二个值大于第一个，跳转到偏移位14，if_icmpne和if_icmple做的工作类似，但是使用不同的判断条件。

JVM没有无符号数据类型，所以，只能通过符号整数值进行比较指令操作。

54.9 传递参数值

``````#!java
public class minmax
{
public static int min (int a, int b)
{
if (a>b)
return b;
return a;
}
public static int max (int a, int b)
{
if (a>b)
return a;
return b;
}
public static void main(String[] args)
{
int a=123, b=456;
int max_value=max(a, b);
int min_value=min(a, b);
System.out.println(min_value);
System.out.println(max_value);
}
}
``````

``````public static void main(java.lang.String[]);
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=5, args_size=1
0: bipush 123
2: istore_1
3: sipush 456
6: istore_2
9: invokestatic #2 // Method max:(II⤦
Ç )I
12: istore_3
15: invokestatic #3 // Method min:(II⤦
Ç )I
18: istore 4
20: getstatic #4 // Field java/⤦
Ç lang/System.out:Ljava/io/PrintStream;
25: invokevirtual #5 // Method java/io⤦
Ç /PrintStream.println:(I)V
28: getstatic #4 // Field java/⤦
Ç lang/System.out:Ljava/io/PrintStream;
32: invokevirtual #5 // Method java/io⤦
Ç /PrintStream.println:(I)V
35: return
``````

54.10位。

java中的位操作其实与其他的一些ISA（指令集架构）类似：

``````#!java
public static int set (int a, int b)
{
return a | 1<<b;
}

public static int clear (int a, int b)
{
return a & (~(1<<b));
}
``````

``````public static int set(int, int);
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=3, locals=2, args_size=2
1: iconst_1
3: ishl
4: ior
5: ireturn

public static int clear(int, int);
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=3, locals=2, args_size=2
1: iconst_1
3: ishl
4: iconst_m1
5: ixor
6: iand
7: ireturn
``````

iconst_m1加载-1入栈，这数其实就是16进制的0xFFFFFFFF，将0xFFFFFFFF作为XOR-ing指令执行的操作数。起到的效果就是把所有bits位反向，（A.6.2在1406页）

``````#!java
public static long lset (long a, int b)
{
return a | 1<<b;
}
public static long lclear (long a, int b)
{
return a & (~(1<<b));
}
``````

``````public static long lset(long, int);
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=4, locals=3, args_size=2
1: iconst_1
3: ishl
4: i2l
5: lor
6: lreturn
public static long lclear(long, int);
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=4, locals=3, args_size=2
1: iconst_1
3: ishl
4: iconst_m1
5: ixor
6: i2l
7: land
8: lreturn
``````

54.11循环

``````#!java
public class Loop
{
public static void main(String[] args)
{
for (int i = 1; i <= 10; i++)
{
System.out.println(i);
}
}
}
``````

``````public static void main(java.lang.String[]);
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=2, args_size=1
0: iconst_1
1: istore_1
3: bipush 10
5: if_icmpgt 21
8: getstatic #2 // Field java/⤦
Ç lang/System.out:Ljava/io/PrintStream;
12: invokevirtual #3 // Method java/io⤦
Ç /PrintStream.println:(I)V
15: iinc 1, 1
18: goto 2
21: return
``````

icont_1将1推入栈顶，istore_1将其存入到局部数组变量的储存位1。

goto指令就是跳转，它跳转偏移2，就是循环体的开始地址.

``````#!java
public class Fibonacci
{
public static void main(String[] args)
{
int limit = 20, f = 0, g = 1;
for (int i = 1; i <= limit; i++)
{
f = f + g;
g = f - g;
System.out.println(f);
}
}
}
``````

``````#!bash
￼public static void main(java.lang.String[]);
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=5, args_size=1
0: bipush        20
2: istore_1
3: iconst_0
4: istore_2
5: iconst_1
6: istore_3
7: iconst_1
8: istore        4
13: if_icmpgt     37