1. 程式人生 > >Java逆向基礎之常量入棧指令

Java逆向基礎之常量入棧指令

java入棧指令

本文參考:http://www.vuln.cn/7115

常量入棧指令有iconst、bipush、sipush、ldc、ldc2_w分別對應不同的使用場景

以下兩個表簡單總結了使用場景

八大基本類型場景表

常量類型

常量範圍

指令

×××int

-1~5

iconst_0~ iconst_5

iconst_m1

-128~127

bipush

-32768~32767

sipush

-2147483648~2147483647

#2 = Integer 12345678

0: ldc #2 // int 12345678

布爾型boolean

true

iconst_1

false

iconst_0

短整型short

-1~5

iconst_0~ iconst_5

iconst_m1

-128~127

bipush

-32768~32767

sipush

字符型char

\u0000~\u0005

iconst_0~ iconst_5

\u0000~\u00FF

bipush

\u0000~\uFFFF

sipush

字節型byte

-1~5

iconst_0~ iconst_5

iconst_m1

-128~127

bipush

長整型long

-2^63~2^63-1

#2 = Long 1234567890123456789l

ldc2_w #2 // long 1234567890123456789l

浮點型double

8字節

#2 = Double 123.456d

ldc2_w #2 // double 123.456d

浮點型float

4字節

#2 = Float 123.456f

ldc #2 // float 123.456f

指令場景表

指令

使用場景

iconst

int,short,byte,int(char a)數值在-1~5之間,boolean類型,註意不包括long

bipush

int,short,byte,int(char a)數值在-128~127之間,註意不包括long,範圍內的值在iconst之內的優先用iconst

sipush

int,short,int(char a)數值在-32768~32767之間,boolean類型,註意不包括long,範圍內的值在bipush之內的優先用bipush

ldc

int的數值-2147483648~2147483647之間(範圍內的值在sipush之內的優先用sipush),float類型

ldc2_w

long類型,double類型

以下是簡單的例子

×××常量0的例子iconst

public class ret
{
public static int main(String[] args)
{
return 0;
}
}

編譯

javac ret.java

Java標準反編譯

javap -c -verbose ret.class
...
major version: 52
...
public static int main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)I
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=1, locals=1, args_size=1
0: iconst_0
1: ireturn
LineNumberTable:
line 5: 0

註意其中的0: iconst_0即可


×××常量123的例子bipush

public class ret
{
public static int main(String[] args)
{
return 123;
}
}

反編譯

...
major version: 52
...
public static int main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)I
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=1, locals=1, args_size=1
0: bipush        123
2: ireturn
LineNumberTable:
line 5: 0

註意其中的0: bipush 123


×××常量1234的例子sipush

public class ret
{
public static int main(String[] args)
{
return 1234;
}
}

反編譯

...
major version: 52
...
public static int main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)I
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=1, locals=1, args_size=1
0: sipush        1234
3: ireturn
LineNumberTable:
line 5: 0

註意其中的 0: sipush 1234


×××常量12345678的例子ldc

public class ret
{
public static int main(String[] args)
{
return 12345678;
}
}

反編譯

...
major version: 52
...
#2 = Integer            12345678
...
public static int main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)I
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=1, locals=1, args_size=1
0: ldc           #2                  // int 12345678
2: ireturn
LineNumberTable:
line 5: 0


布爾型true例子iconst

public class ret
{
public static boolean main(String[] args)
{
return true;
}
}

反編譯

...
major version: 52
...
public static boolean main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)Z
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=1, locals=1, args_size=1
0: iconst_1
1: ireturn
LineNumberTable:
line 5: 0

註意0: iconst_1即ture用常量1表示


短整型short例子

public class ret
{
public static short main(String[] args)
{
return 1234;
}
}

反編譯

...
major version: 52
...
public static short main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)S
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=1, locals=1, args_size=1
0: sipush        1234
3: ireturn
LineNumberTable:
line 5: 0

註意0: sipush 1234


字符型A例子

public class ret
{
public static char main(String[] args)
{
return 'A';
}
}

反編譯

...
major version: 52
...
public static char main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)C
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=1, locals=1, args_size=1
0: bipush        65
2: ireturn
LineNumberTable:
line 5: 0

註意0: bipush 65


字符型中例子

public class ret
{
public static char main(String[] args)
{
return '中';
}
}

反編譯

...
major version: 52
...
public static char main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)C
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=1, locals=1, args_size=1
0: sipush        20013
3: ireturn
LineNumberTable:
line 5: 0

註意0: sipush 20013


byte類型123列子

public class ret
{
public static byte main(String[] args)
{
return 123;
}
}

反編譯

...
major version: 52
...
public static byte main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)B
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=1, locals=1, args_size=1
0: bipush        123
2: ireturn
LineNumberTable:
line 5: 0

註意 0: bipush 123


long類型1234567890123456789L例子

public class ret
{
public static long main(String[] args)
{
return 1234567890123456789l;
}
}

反編譯

...
major version: 52
...
#2 = Long               1234567890123456789l
...
public static long main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)J
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=1, args_size=1
0: ldc2_w        #2                  // long 1234567890123456789l
3: lreturn
LineNumberTable:
line 5: 0

註意0: ldc2_w #2 // long 1234567890123456789l


浮點類型123.456d的例子

public class ret
{
public static double main(String[] args)
{
return 123.456d;
}
}

反編譯

...
major version: 52
...
#2 = Double             123.456d
...
public static double main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)D
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=1, args_size=1
0: ldc2_w        #2                  // double 123.456d
3: dreturn
LineNumberTable:
line 5: 0

註意0: ldc2_w #2 // double 123.456d


浮點類型123.456f的例子

public class ret
{
public static float main(String[] args)
{
return 123.456f;
}
}

反編譯

...
major version: 52
...
#2 = Float              123.456f
...
public static float main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)F
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=1, locals=1, args_size=1
0: ldc           #2                  // float 123.456f
2: freturn
LineNumberTable:
line 5: 0

註意0: ldc #2 // float 123.456f



Java逆向基礎之常量入棧指令