Java逆向基础之字符串
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java逆向基础之字符串相关的知识,希望对你有一定的参考价值。
本文参考:《Reverse Engineering for Beginners》Dennis Yurichev著
字符串
字符串也是对象,和其他对象的构造方式相同。(包括数组)
第一个例子
public class stringhello { public static void main(String[] args) { System.out.println("What is your name?"); String input = System.console().readLine(); System.out.println("Hello, " + input); } }
编译
javac stringhello.java
反编译
javap -c -verbose stringhello.class
public static void main(java.lang.String[]); descriptor: ([Ljava/lang/String;)V flags: ACC_PUBLIC, ACC_STATIC Code: stack=3, locals=2, args_size=1 0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream; 3: ldc #3 // String What is your name? 5: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 8: invokestatic #5 // Method java/lang/System.console:()Ljava/io/Console; 11: invokevirtual #6 // Method java/io/Console.readLine:()Ljava/lang/String; 14: astore_1 15: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream; 18: new #7 // class java/lang/StringBuilder 21: dup 22: invokespecial #8 // Method java/lang/StringBuilder."<init>":()V 25: ldc #9 // String Hello, 27: invokevirtual #10 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 30: aload_1 31: invokevirtual #10 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 34: invokevirtual #11 // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 37: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 40: return
部分指令解释
11: invokevirtual #6 // Method java/io/Console.readLine:()Ljava/lang/String; //调用了readline()方法,字符串引用(由用户提供)被存储在栈顶
14: astore_1 //将字符串引用从操作数栈中弹出,保存在索引为1的局部变量中(即input)
25: ldc #9 // String Hello, //将字符串String Hello,压入栈
27: invokevirtual #10 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; //使用StringBuilder.append方法,返回一个StringBuilder对象的引用压入栈顶,需要从栈顶弹出两个值,一个是StringBuilder的引用,一个是字符串String Hello,
30: aload_1 //将索引为1的局部变量(即input)压入操作数栈
31: invokevirtual #10 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; //使用StringBuilder.append方法,返回一个StringBuilder对象的引用压入栈顶,需要从栈顶弹出两个值,一个是StringBuilder的引用,一个是字符串input变量值
34: invokevirtual #11 // Method java/lang/StringBuilder.toString:()Ljava/lang/String; //使用StringBuilder.toString方法,返回一个String对象的引用压入栈顶,需要从栈顶弹出一个值,是StringBuilder的引用
37: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V //使用PrintStream.println方法,需要从栈顶弹出一个值,是System.out的引用
可以看到字符串的链接由StringBuilder完成
另外一个例子
public class strings { public static char test(String a) { return a.charAt(3); }; public static String concat(String a, String b) { return a + b; } }
反编译
test方法
public static char test(java.lang.String); descriptor: (Ljava/lang/String;)C flags: ACC_PUBLIC, ACC_STATIC Code: stack=2, locals=1, args_size=1 0: aload_0 1: iconst_3 2: invokevirtual #2 // Method java/lang/String.charAt:(I)C 5: ireturn
concat方法
public static java.lang.String concat(java.lang.String, java.lang.String); descriptor: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; flags: ACC_PUBLIC, ACC_STATIC Code: stack=2, locals=2, args_size=2 0: new #3 // class java/lang/StringBuilder 3: dup 4: invokespecial #4 // Method java/lang/StringBuilder."<init>":()V 7: aload_0 8: invokevirtual #5 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 11: aload_1 12: invokevirtual #5 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 15: invokevirtual #6 // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 18: areturn
这里的字符串的连接也使用StringBuilder类完成
部分指令解释
0: new #3 // class java/lang/StringBuilder //创建StringBuilder的引用并压入栈顶
3: dup //复制栈顶值,即StringBuilder的引用
4: invokespecial #4 // Method java/lang/StringBuilder."<init>":()V //弹出1个栈顶值,调用<init>方法初始化
另外一个例子
public class stringhellotwo { public static void main(String[] args) { String s = "Hello!"; int n = 123; System.out.println("s=" + s + " n=" + n); } }
反编译
public static void main(java.lang.String[]); descriptor: ([Ljava/lang/String;)V flags: ACC_PUBLIC, ACC_STATIC Code: stack=3, locals=3, args_size=1 0: ldc #2 // String Hello! 2: astore_1 3: bipush 123 5: istore_2 6: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream; 9: new #4 // class java/lang/StringBuilder 12: dup 13: invokespecial #5 // Method java/lang/StringBuilder."<init>":()V 16: ldc #6 // String s= 18: invokevirtual #7 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 21: aload_1 22: invokevirtual #7 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 25: ldc #8 // String n= 27: invokevirtual #7 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 30: iload_2 31: invokevirtual #9 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder; 34: invokevirtual #10 // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 37: invokevirtual #11 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 40: return
这里的字符串的连接也使用StringBuilder类进行拼接
以上是关于Java逆向基础之字符串的主要内容,如果未能解决你的问题,请参考以下文章