Reverse BASICS (13) JAVA (4)
54.15 for an exception, let's modify it a little. The example of monthly processing (in 54.13.4 on page 1)
Configuration 54.10: IncorrectMonthException. java
public class IncorrectMonthException extends Exception{ private int index; public IncorrectMonthException(int index) { this.index = index; } public int getIndex() { return index; }}
Configuration 54.11: Month2.java
class Month2{ public static String[] months = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; public static String get_month (int i) throws ⤦ Ç IncorrectMonthException { if (i<0 || i>11) throw new IncorrectMonthException(i); return months[i]; }; public static void main (String[] args) { try { System.out.println(get_month(100)); } catch(IncorrectMonthException e) { System.out.println("incorrect month ⤦ Ç index: "+ e.getIndex()); e.printStackTrace(); } };}
In essence, the incorrectmonth?tinclass class only performs Object Construction and accessors. Incorrectmonthequaltinclass is inherited from the Exception class. Therefore, before the IncorrectMonth class is constructed, the Exception of the parent class is constructed, and an integer is passed to the IncorrectMonthException class as the unique attribute value.
Public IncorrectMonthException (int); flags: ACC_PUBLICCode: stack = 2, locals = 2, args_size = 20: aload_01: invokespecial #1 // Method java/Ç lang/Exception. "<init>" :() V4: aload_05: iload_16: putfield #2 // Field index: I9: return
GetIndex () is just an accesser. It references the IncorrectMothnException class and is passed to the LVA 0 slot (this pointer). It is obtained using the aload_0 command and the getfield command to get the integer of the object, use the ireturn command to return the result.
Public int getIndex (); flags: ACC_PUBLICCode: stack = 1, locals = 1, args_size = 10: aload_01: getfield #2 // Field index: I4: ireturn
Now let's take a look at the get_month method of month. class.
Configuration 54.12: Month2.class
Public static java. lang. string get_month (int) throws Ç çincorrectmonthexception; flags: ACC_PUBLIC, ACC_STATICCode: stack = 3, locals = 1, args_size = 10: iload_01: iflt 104: iload_05: bipush 117: if_icmple 1910: new #2 // class ⤦ çincorrectmonthexception13: dup14: iload_015: invokespecial #3 // Method ⤦ çincorrectmonthexception. "<init>" :( I) V18: athrow19: getstatic #4 // Field months: [Ç çljava/lang/String; 22: iload_023: aaload24: areturn949
Iflt is at line offset 1. If it is less,
This is actually an invalid index. An object is created at the row offset of 10, and the object type is used as an instruction for the Operation book. (When this IncorrectMonthException is constructed, the subscript integer is passed through TOS. Line 15 offset) the time flow has shifted to line 18, and the object has been constructed. Now, the athrow command gets the reference of the new object, then, send a signal to the JVM to find a suitable exception handle.
The athrow command does not return back to the control flow. Other basic modules with the line 19 offset have nothing to do with exceptions. We can get the line 7 offset. How does the handle work? Main () in inmonth2.class
Configuration 54.13: Month2.class
Public static void main (java. lang. string []); flags: ACC_PUBLIC, ACC_STATICCode: stack = 3, locals = 2, args_size = 10: getstatic #5 // Field java/Ç lang/System. out: Ljava/io/PrintStream; 3: bipush 1005: invokestatic #6 // Method Ç get_month :( I) Ljava/lang/String; 8: invokevirtual #7 // Method java/io ⤦ ç/ PrintStream. println :( Ljava/lang/String;) V11: goto 4714: astore_115: getstatic #5 // Field java/Ç çlang/System. out: Ljava/io/PrintStream; 18: new #8 // class java/⤦ Ç lang/StringBuilder21: dup22: invokespecial #9 // Method java/⤦ Ç lang/StringBuilder. "<init>" :() V25: ldc #10 // String Ç çincorrect month index: 27: invokevirtual #11 // Method java/⤦ çlang/StringBuilder. append :( Ljava/lang/String;) Ljava/lang/Ç çstringbuilder; 30: aload_131: invokevirtual #12 // Method ⤦ çincorrectmonthexception. getIndex :() I34: invokevirtual #13 // Method java/Ç çlang/StringBuilder. append :( I) Ljava/lang/StringBuilder; 37: invokevirtual #14 // Method java/Ç çlang/StringBuilder. toString :() Ljava/lang/String; 40: invokevirtual #7 // Method java/io Ç/PrintStream. println :( Ljava/lang/String;) V43: aload_144: invokevirtual #15 // Method ⤦ çincorrectmonthexception. printStackTrace :() V47: returnException table: from to target type0 11 14 Class IncorrectMonthException
950 this is an exception table. An IncorrectinMonthException exception may occur in the row offset 0-11 (including). If the control flow reaches the offset of 14 rows, the main program ends at the offset of 11 rows, when the exception starts in row 14, the condition (condition/uncondition) setting in this region is unavailable. (PS: no exception capture settings, so no exception stream will be called for execution .)
However, the JVM will pass and overwrite this exception case. The first astore_1 (row offset 14) is obtained, and the reference of the incoming exception object is stored after Slot Parameter 1 of LVA. The getIndex () method (this exception object) is called at 31 line offset. Reference the current exception object before the offset of 30 rows. All the code resetting is a string operation code: the first integer uses the getIndex () method, and the toString () method is used for conversion to a string, it is linked to the text character of "correct month subscript" (as we have previously considered ). Println () and printStackTrace (1) will be called. After PrintStackTrace (1) is called, exceptions will be caught. We can handle normal functions in 47 line offsets, return ends the main () function. If no exception occurs, no code is executed.
Here is an example of how IDA displays the exception range:
Listing 54.14 I found the file random. class from my computer.
.catch java/io/FileNotFoundException from met001_335 to ⤦Ç met001_360\using met001_360.catch java/io/FileNotFoundException from met001_185 to ⤦Ç met001_214\using met001_214.catch java/io/FileNotFoundException from met001_181 to ⤦Ç met001_192\using met001_195951CHAPTER 54. JAVA 54.16. CLASSES.catch java/io/FileNotFoundException from met001_155 to ⤦Ç met001_176\using met001_176.catch java/io/FileNotFoundException from met001_83 to ⤦Ç met001_129 using \met001_129.catch java/io/FileNotFoundException from met001_42 to ⤦Ç met001_66 using \met001_69.catch java/io/FileNotFoundException from met001_begin to ⤦Ç met001_37\using met001_37
54.16 simple classes
Configuration 54.15: test. java
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; }}
The constructor only sets the two segments to 0.
Public test (); flags: ACC_PUBLICCode: stack = 1, locals = 1, args_size = 10: aload_01: invokespecial #1 // Method java/Ç lang/Object. "<init>" :() V4: iconst_05: putstatic #2 // Field a: I8: iconst_09: putstatic #3 // Field B: I12: return
A's Configurator
Public static void set_a (int); flags: ACC_PUBLIC, ACC_STATICCode: stack = 1, locals = 1, args_size = 10: iload_01: putstatic #2 // Field a: I4: return
A's iterator
Public static int get_a (); flags: ACC_PUBLIC, ACC_STATICCode: stack = 1, locals = 0, args_size = 00: getstatic #2 // Field a: I3: ireturn
B's Configurator
Public static void set_ B (int); flags: ACC_PUBLIC, ACC_STATICCode: stack = 1, locals = 1, args_size = 10: iload_01: putstatic #3 // Field B: I4: return
B's accessors
Public static int get_ B (); flags: ACC_PUBLIC, ACC_STATICCode: stack = 1, locals = 0, args_size = 00: getstatic #3 // Field B: I3: ireturn
There is no difference between the public and private field codes in the 953 class. However, the type information is expressed in the in. class file, and private variables are not accessible in any case.
Let's create an object and call the method: Listing 54.16: ex1.java
954 the new command creates an object, but does not call the constructor (it is called at four line offsets). The set_a () method is called at the 16 line offset and the getstatic command used for field access, the row offset is 21.
Listing54.16: ex1.java
public class ex1{ public static void main(String[] args) { test obj=new test(); obj.set_a (1234); System.out.println(obj.a); }}
public static void main(java.lang.String[]);flags: ACC_PUBLIC, ACC_STATICCode:stack=2, locals=2, args_size=10: new #2 // class test3: dup4: invokespecial #3 // Method test."<⤦Ç init>":()V7: astore_18: aload_19: pop10: sipush 123413: invokestatic #4 // Method test.⤦Ç set_a:(I)V16: getstatic #5 // Field java/⤦Ç lang/System.out:Ljava/io/PrintStream;19: aload_120: pop21: getstatic #6 // Field test.a:I24: invokevirtual #7 // Method java/io⤦Ç /PrintStream.println:(I)V27: return
54.17 simple patch.
54.17.1 first example
Let's take a simple example.
public class nag{ public static void nag_screen() { System.out.println("This program is not ⤦ Ç registered"); }; public static void main(String[] args) { System.out.println("Greetings from the mega-⤦ Ç software"); nag_screen(); }}
How can we remove the print output "This program is registered ".
The. class file is most loaded in IDA.
Configuration 54.1: IDA
We patch ourselves to the first function to 177 (return command operation code) Figure 54.2: IDA
This does not work in JDK1.7.
Exception in thread "main" java.lang.VerifyError: Expecting a ⤦Ç stack map frameException Details:Location:nag.nag_screen()V @1: nopReason:Error exists in the bytecodeBytecode:0000000: b100 0212 03b6 0004 b1at java.lang.Class.getDeclaredMethods0(Native Method)at java.lang.Class.privateGetDeclaredMethods(Class.java⤦Ç :2615)at java.lang.Class.getMethod0(Class.java:2856)at java.lang.Class.getMethod(Class.java:1668)at sun.launcher.LauncherHelper.getMainMethod(⤦Ç LauncherHelper.java:494)at sun.launcher.LauncherHelper.checkAndLoadMain(⤦Ç LauncherHelper.java:486)
956 maybe, JVM has some checks and is associated with Stack ing. Okay. To make the path different, we use remove call nag ()
List: 54.5 the ida nop operation code is 0: It is working now
54.17.2 second example
Here is another simple crackme example.
public class password{ public static void main(String[] args) { System.out.println("Please enter the password")⤦ Ç ; String input = System.console().readLine(); if (input.equals("secret")) System.out.println("password is correct⤦"); else System.out.println("password is not ⤦ Ç correct"); }}
Figure 54.4: IDA
We can see how the ifeq command works. Its name means that if it is equal. This is inappropriate. I prefer to name if (ifz if zero). if the top value of the stack is 0, it will jump. In our example, if the password is incorrect, it will jump. (The equal method returns 0.) The first idea is the patch command... iefq is the operation code and jump offset of two bytes. For this command to be customized, we must set byte3 3 byte (because 3 is added to the current address and always jumps to the same command) because the instruction length of ifeq is 3 bytes.
Figure 958 54.5IDA
This does not work in JDK1.7.
Exception in thread "main" java.lang.VerifyError: Expecting a ⤦Ç stackmap frame at branch target 24Exception Details:Location:password.main([Ljava/lang/String;)V @21: ifeqReason:Expected stackmap frame at this location.Bytecode:0000000: b200 0212 03b6 0004 b800 05b6 0006 4c2b0000010: 1207 b600 0899 0003 b200 0212 09b6 00040000020: a700 0bb2 0002 120a b600 04b1Stackmap Table:append_frame(@35,Object[#20])same_frame(@43)at java.lang.Class.getDeclaredMethods0(Native Method)at java.lang.Class.privateGetDeclaredMethods(Class.java⤦Ç :2615)at java.lang.Class.getMethod0(Class.java:2856)at java.lang.Class.getMethod(Class.java:1668)at sun.launcher.LauncherHelper.getMainMethod(⤦Ç LauncherHelper.java:494)959CHAPTER 54. JAVA 54.18. SUMMARYat sun.launcher.LauncherHelper.checkAndLoadMain(⤦Ç LauncherHelper.java:486)
Needless to say, it works in JRE1.6. Do I also try to replace all 3ifeq operations? bytes, using 0 bytes (NOP), it will still work, so there may be no more stack mappings checked out in JRE1.7.
Okay. I will replace the entire equal call method, and use the icore_1 command and NOPS contention patch.
11 is always at the top of the stack. When the ifeq command is not executed, ifeq will not be executed.
Work now.
54.18 conclusion
960 and C/C + are java missing? Struct: Use class union: Use a group class without additional data types. Let's say that there are some hard-coding encryption algorithms implemented in Java. Function pointer.