Java .class文件反編譯后的特殊代碼還原


java class反編譯后的代碼還原(一) 
        Java class 利用jad 反編譯之后,偶爾回碰到一些不正常的代碼,例如:label0 :_L1 MISSING_BLOCK_LABEL_30、JVM INSTR ret 7 、JVM INSTR tableswitch 1 3: default 269、 JVM INSTR monitorexit、JVM INSTR monitorenter,這些一般是由特殊的for循環、try catch finally語句塊、synchronized語句反編譯后產生的。下面,就簡單介紹一下,一些反編譯后的特殊代碼的還原規則。

   第一部分、for、while循環 

1、普通的循環,原始 

public void f1() {  
        boolean flag = false;  
        if (Boolean.getBoolean("sys")) {  
            System.out.println("sys");  
        } else {  
            for (int i = 0; i < 10; i++) {  
                flag = Boolean.getBoolean("sys");  
                if (flag) {  
                    System.exit(0);  
                }  
            }  
        }  
    }  

 
反編譯后的代碼 

public void f1()  

{  
      boolean flag = false;  
      if(Boolean.getBoolean("sys"))  
      {  
             System.out.println("sys");  
      } else  
       {  
             for(int i = 0; i < 10; i++)  
             {  
                 flag = Boolean.getBoolean("sys");  
                 if(flag)  
                     System.exit(0);  
             }    
         }  
     }  

      
2、反編譯后代碼變的很古怪,這是java原代碼 

public void f2() {  
        int[] list = new int[] { 1, 2, 3, 4 };  
        if (Boolean.getBoolean("sys")) {  
            System.out.println("sys");  
        } else {  
            check: while (true) {  
                for (int i = 0; i < list.length; i++) {  
                    if (list[i] == 2) {  
                        continue check;  
                    } else {  
                        break;  
                    }  
                }  
            }  
        }  
    }      

Java反編譯后的代碼,部分邏輯丟失。 

public void f2()  
     {  
         int list[] = {  
             1, 2, 3, 4  
         };  
         if(Boolean.getBoolean("sys"))  
             System.out.println("sys");  
         else  
             do  
             {  
                 int i = 0;  
                 if(i >= list.length || list[i] != 2);  
             } while(true);  
     }  

      
3、就是比f2()多了一行System.out.println("list[i]");,反編譯后也挺怪的。源碼如下: 

public void f3() {  
        int[] list = new int[] { 1, 2, 3, 4 };  
        if (Boolean.getBoolean("sys")) {  
            System.out.println("sys");  
        } else {  
            check: while (true) {  
                for (int i = 0; i < list.length; i++) {  
                    System.out.println("list[i]");  
                    if (list[i] == 2) {  
                        continue check;  
                    } else {  
                        break;  
                    }  
                }  
            }  
        }  
    }  

    
反編譯后的代碼: 

public void f3()  
     {  
         int list[] = {  
             1, 2, 3, 4  
         };  
         if(Boolean.getBoolean("sys"))  
             System.out.println("sys");  
         else  
             do  
             {  
                 int i;  
                 do  
                     i = 0;  
                 while(i >= list.length);  
                 System.out.println("list[i]");  
                 if(list[i] != 2);  
             } while(true);  
     }  

      
4、f2()中的break語言,移動了位置。源碼如下: 

public void f4() {  
        int[] list = new int[] { 1, 2, 3, 4 };  
        if (Boolean.getBoolean("sys")) {  
            System.out.println("sys");  
        } else {  
            check: while (true) {  
                for (int i = 0; i < list.length; i++) {  
                    if (list[i] == 2) {  
                        continue check;  
                    }  
                }  
                break;  
            }  
        }  
    }  

       
反編譯后代碼: 

public void f4()  
     {  
         int list[] = {  
             1, 2, 3, 4  
         };  
         int i;  
         if(Boolean.getBoolean("sys"))  
             System.out.println("sys");  
         else  
label0:  
             do  
             {  
                 for(i = 0; i < list.length; i++)  
                     if(list[i] == 2)  
                         continue label0;  
                 break;  
             } while(true);  
     }  

        
5、就是比f4()多了一行System.out.println("list[i]");,反編譯后相當怪的。源碼如下: 

public void f5() {  
        int[] list = new int[] { 1, 2, 3, 4 };  
        if (Boolean.getBoolean("sys")) {  
            System.out.println("sys");  
        } else {  
            check: while (true) {  
                for (int i = 0; i < list.length; i++) {  
                    System.out.println("list[i]");  
                    if (list[i] == 2) {  
                        continue check;  
                    }  
                }  
                break;  
            }  
        }  
    }  

       
反編譯后比較暈的代碼: 

public void f5()  
     {  
         int list[] = {  
             1, 2, 3, 4  
         };  
         if(!Boolean.getBoolean("sys")) goto _L2; else goto _L1  
_L1:  
         System.out.println("sys");  
           goto _L3  
_L2:  
         int i = 0;  
           goto _L4  
_L6:  
         System.out.println("list[i]");  
         if(list[i] != 2) goto _L5; else goto _L2  
_L5:  
         i++;  
_L4:  
         if(i < list.length) goto _L6; else goto _L3  
_L3:  
     }  

      
6、就是比f5()多了一行System.exit(0);代碼,但是差異確很大。源碼如下: 

public void f6() {  
        int[] list = new int[] { 1, 2, 3, 4 };  
        if (Boolean.getBoolean("sys")) {  
            System.out.println("sys");  
        } else {  
            check: while (true) {  
                for (int i = 0; i < list.length; i++) {  
                    System.out.println("list[i]");  
                    if (list[i] == 2) {  
                        continue check;  
                    }  
                }  
                System.exit(0);  
                break;  
            }  
        }  
    }  


編譯后代碼,比f5()差異太大了。 

public void f6()  
     {  
         int list[];  
         list = (new int[] {  
             1, 2, 3, 4  
         });  
         if(Boolean.getBoolean("sys"))  
         {  
             System.out.println("sys");  
             break MISSING_BLOCK_LABEL_75;  
         }  
_L2:  
         int i = 0;  
           goto _L1  
_L5:  
         System.out.println("list[i]");  
         if(list[i] != 2) goto _L3; else goto _L2  
_L3:  
         i++;  
_L1:  
         if(i < list.length) goto _L5; else goto _L4  
_L4:  
         System.exit(0);  
     }  

      
7、差異就是f6()中的System.exit(0);移動了位置,但是差異確很大。源碼如下: 

public void f7() {  
        int[] list = new int[] { 1, 2, 3, 4 };  
        if (Boolean.getBoolean("sys")) {  
            System.out.println("sys");  
        } else {  
            check: while (true) {  
                for (int i = 0; i < list.length; i++) {  
                    System.out.println("list[i]");  
                    if (list[i] == 2) {  
                        continue check;  
                    }  
                }  
                break;  
            }  
            System.exit(0);  
        }  
    }  

編譯后代碼,比f6()差異太大了。 

public void f7()  
     {  
         int list[];  
         list = (new int[] {  
             1, 2, 3, 4  
         });  
         if(Boolean.getBoolean("sys"))  
         {  
             System.out.println("sys");  
             break MISSING_BLOCK_LABEL_75;  
         }  
_L2:  
         int i = 0;  
           goto _L1  
_L5:  
         System.out.println("list[i]");  
         if(list[i] != 2) goto _L3; else goto _L2  
_L3:  
         i++;  
_L1:  
         if(i < list.length) goto _L5; else goto _L4  
_L4:  
         System.exit(0);  
     }  

      
8、邏輯和f7比沒有變,只是多了一些System.out.println()代碼。 

public void f8() {  
        int[] list = new int[] { 1, 2, 3, 4 };  
        if (Boolean.getBoolean("sys")) {  
            System.out.println("sys");  
        } else {  
            System.out.println(":check while");  
            check: while (true) {  
                System.out.println("for");  
                for (int i = 0; i < list.length; i++) {  
                    System.out.println("list[i]");  
                    if (list[i] == 2) {  
                        continue check;  
                    }  
                }  
                System.out.println("break");  
                break;  
            }  
            System.out.println("exit(0)");  
            System.exit(0);  
        }  
    }  

      
反編譯后的代碼:和f7()比較一下,基本就可以確定反編譯后的代碼對應關系了。 

public void f8()  
     {  
         int list[];  
         list = (new int[] {  
             1, 2, 3, 4  
         });  
         if(Boolean.getBoolean("sys"))  
         {  
             System.out.println("sys");  
             break MISSING_BLOCK_LABEL_107;  
         }  
         System.out.println(":check while");  
_L2:  
         int i;  
         System.out.println("for");  
         i = 0;  
           goto _L1  
_L5:  
         System.out.println("list[i]");  
         if(list[i] != 2) goto _L3; else goto _L2  
_L3:  
         i++;  
_L1:  
         if(i < list.length) goto _L5; else goto _L4  
_L4:  
         System.out.println("break");  
         System.out.println("exit(0)");  
         System.exit(0);  
     }  

      
9、邏輯和f8比沒有變,只是多了一行System.out.println()代碼,導致了反編譯后的。 

public void f9() {  
        int[] list = new int[] { 1, 2, 3, 4 };  
        if (Boolean.getBoolean("sys")) {  
            System.out.println("sys");  
        } else {  
            System.out.println(":check while");  
            check: while (true) {  
                System.out.println("for");  
                for (int i = 0; i < list.length; i++) {  
                    System.out.println("list[i]");  
                    if (list[i] == 2) {  
                        System.out.println("continue check");  
                        continue check;  
                    }  
                }  
                System.out.println("break");  
                break;  
            }  
            System.out.println("exit(0)");  
            System.exit(0);  
        }  
    }  
}  

       
反編譯后的代碼: 

public void f9()  
     {  
         int list[] = {  
             1, 2, 3, 4  
         };  
         if(!Boolean.getBoolean("sys")) goto _L2; else goto _L1  
_L1:  
         System.out.println("sys");  
           goto _L3  
_L2:  
         System.out.println(":check while");  
_L5:  
         System.out.println("for");  
         for(int i = 0; i < list.length; i++)  
         {  
             System.out.println("list[i]");  
             if(list[i] != 2)  
                 continue;  
             System.out.println("continue check");  
             continue;   
         }  
         System.out.println("break");  
         System.out.println("exit(0)");  
         System.exit(0);  
_L3:  
         return;  
         if(true) goto _L5; else goto _L4  
_L4:  
     }  
}     

java class反編譯后的代碼還原(二) 
       Java class 利用jad 反編譯之后,偶爾回碰到一些不正常的代碼,例如:label0 :_L1 MISSING_BLOCK_LABEL_30、JVM INSTR ret 7、JVM INSTR tableswitch 1 3: default 269、 JVM INSTR monitorexit、JVM INSTR monitorenter,這些一般是由特殊的for循環、try catch finally語句塊、synchronized語句反編譯后產生的。下面,就簡單介紹一下,一些反編譯后的特殊代碼的還原規則。本文在Jdk 1.4.2_08+jad 1.58f下測試。jad 1.5.8f可以到這里http://download.csdn.net/source/470540 下載。 

    第二部分、異常 

   下面的代碼前提是類中有如下屬性,  Calendar cal = Calendar.getInstance();。 

    1、Exceptioin的還原    反編譯后的代碼如下: 

public boolean f1()   
{  
    return cal.getTime().after(new Date());  
    Exception e;  
    e;  
    e.printStackTrace();  
    return false;  
}  

還原后的Java代碼 

public boolean f1()  
{  
    try  
    {  
        return cal.getTime().after(new Date());  
    }  
    catch (Exception e) 
    {  
        e.printStackTrace();  
        return false;  
    } 
}  

2、finally代碼的還原 反編譯后的Java代碼如下: 

public boolean f2()  
{  
    boolean flag = cal.getTime().after(new Date());  
    System.out.println("finally");  
    return flag;  
    Exception e;    
    e;  
    e.printStackTrace();  
    System.out.println("finally");  
    return false;  
    Exception exception;  
    exception;  
    System.out.println("finally");  
    throw exception;  

}  

還原后的代碼如下: 

public boolean f2()  
{  
    try  
    {  
        return cal.getTime().after(new Date());  
    }  
    catch (Exception e)  
    {  
        e.printStackTrace();  
        return false;  
    }  
    finally 
    {  
        System.out.println("finally");  
    }  
} 


3、MISSING_BLOCK_LABEL_的還原反編譯后的代碼 

public Object f22()  
{  
    Date date = cal.getTime();  
    System.out.println("finally");  
    return date; 
    Exception e;  
    e;  
    e.printStackTrace();  
    System.out.println("finally");  
    break MISSING_BLOCK_LABEL_45;  
    Exception exception; 
    exception; 
    System.out.println("finally");  
    throw exception;  
    return null;  
}  


還原后的Java代碼 

public Object f22()  
{  
    try  
    { 
        return cal.getTime(); 
    }  
    catch (Exception e)  
    {  
        e.printStackTrace();  
    }  
    finally 
    {  
        System.out.println("finally"); 
    }  
    return null;  
}  


4、異常中:label的還原反編譯后的代碼 

public String f4() 
    throws Exception  
{  
l0:  
    {  
        try  
        {  
            Integer i = new Integer(1);  
            if(i.intValue() > 0)  
            {  
                System.out.println(i);  
                break label0;  
            }  
            System.err.println(i);  
        }  
        catch(Exception dae)  
      {  
            System.err.println(dae);  
            throw new RuntimeException(dae);  
        }  
        return null;  
    }  
    return "Hello";  
}  


注意,這個代碼有點詭異,實際代碼如下: 

public String f4() throws Exception   
{  
    try  
    {  
        Integer i = new Integer(1);  
        if (i.intValue() > 0)  
        {  
            System.out.println(i);  
        }  
        else  
        {  
            System.err.println(i);  
            return null;  
        }  
        return "Hello";  
    }  
    catch (Exception dae)  
    {  
        System.err.println(dae);  
        throw new RuntimeException(dae);  
    }  
}  


5、典型數據庫操作代碼還原 反編譯后代碼 

public HashMap f5()  
{  
    Connection conn = null;  
    HashMap hashmap;  
    HashMap map = new HashMap();  
    Class.forName("");  
    conn = DriverManager.getConnection("jdbc:odbc:");  
    PreparedStatement pstmt = conn.prepareStatement("select * from table");  
    pstmt.setString(1, "param");  
    String columnVallue;  
    for(ResultSet rs = pstmt.executeQuery(); rs.next(); map.put(columnVallue, ""))  
    columnVallue = rs.getString("column");  
    hashmap = map;  
    if(conn != null)  
        try  
        {  
            conn.close();  
        }  
        catch(SQLException sqlce)  
        {  
            sqlce.printStackTrace();  
        }  
    return hashmap;  
    ClassNotFoundException cnfe;  
    cnfe;  
    cnfe.printStackTrace();  
    if(conn != null)  
        try  
        {  
            conn.close();  
        } 
        catch(SQLException sqlce)  
        {  
            sqlce.printStackTrace();  
        }  
    break MISSING_BLOCK_LABEL_188;  
    SQLException sqle;  
    sqle;  
    sqle.printStackTrace();  
    if(conn != null)  
        try  
        {  
            conn.close();  
        }  
        catch(SQLException sqlce)  
        {  
            sqlce.printStackTrace();  
        }  
    break MISSING_BLOCK_LABEL_188;  
    Exception exception;  
    exception;  
    if(conn != null)  
        try  
        {  
            conn.close();  
        }  
        catch(SQLException sqlce)  
        {  
            sqlce.printStackTrace();  
        }  
    throw exception;  
    return null;  
}  


實際代碼如下: 

public HashMap f5() 
{  
    Connection conn = null;  
    try  
    {  
        HashMap map = new HashMap();  
        Class.forName("");  
        conn = DriverManager.getConnection("jdbc:odbc:");  
        PreparedStatement pstmt = conn.prepareStatement("select * from table");  
        pstmt.setString(1, "param");  
        ResultSet rs = pstmt.executeQuery();  
        while (rs.next())  
        {  
            String columnVallue = rs.getString("column");  
            map.put(columnVallue, "");  
        }  
        return map;  
    }  
    catch (ClassNotFoundException cnfe) 
    {  
        cnfe.printStackTrace();  
    }  
    catch (SQLException sqle)  
    {  
        sqle.printStackTrace(); 
    }  
    finally 
    {  
        if (conn != null)  
        {  
            try  
            {  
                conn.close();  
            } 
            catch (SQLException sqlce)  
            {  
                sqlce.printStackTrace();  
            }  
        } 
    } 
    return null;   
}  


6、兩層異常嵌套代碼還原 反編譯后的代碼 

public int f6()   
{  
    int i = cal.getTime().compareTo(new Date());  
    System.out.println("finally");  
    return i;  
    Exception e1;  
    e1;  
    e1.printStackTrace();  
    System.out.println("finally");  
    return -1; 
    Exception e2;  
    e2; 
    e2.printStackTrace();  
    System.out.println("finally");  
    return -2;  
    Exception exception;  
    exception;  
    System.out.println("finally");  
    throw exception;  
}  

實際代碼 

public int f6() 
{ 
    try 
    {  
        try 
        {  
            return cal.getTime().compareTo(new Date());  
        }  
        catch (Exception e1)  
        {  
            e1.printStackTrace();  
            return -1;  
        }  
    }  
    catch (Exception e2)  
    {  
        e2.printStackTrace();  
        return -2;  
    }  
    finally  
    {  
        System.out.println("finally"); 
    } 
}  


7、非常詭異的代碼 反編譯后的代碼 
  

  public int f7()  
    {  
        int i = cal.getTime().compareTo(new Date());  
        System.out.println("finally");  
        return i;  
        Exception e1;  
        e1;  
        e1.printStackTrace();  
_L2:  
        System.out.println("finally"); 
        return -1;  
        Exception e2;  
        e2;  
        e2.printStackTrace();  
        if(true) goto _L2; else goto _L1  
_L1:  
        Exception exception;  
        exception;  
        System.out.println("finally");  
        throw exception;  
    }  

原始代碼 

public int f7()  
{  
    try  
    {  
     try 
        { 
            return cal.getTime().compareTo(new Date()); 
        } 
        catch (Exception e1) 
        {  
            e1.printStackTrace(); 
            return -1;  
        }  
    }    
    catch (Exception e2)   
    {  
        e2.printStackTrace();  
        return -1;  
    }   
    finally   
    {  
        System.out.println("finally");  
    }   
} 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM