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");  
    }   
} 
原文地址:https://www.cnblogs.com/vijay/p/3543363.html