zoukankan      html  css  js  c++  java
  • 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");  
        }   
    } 
  • 相关阅读:
    java中的死锁现象
    Maven 创建动态web 3.0项目
    查询数据库主外键关系
    函数指针的应用学习Demo
    WCF宿主Window Service Demo
    一段小程序理解getchar和putchar
    Flash在线签名小程序,可回放,动态导出gif图片
    uninstall gitlab
    使用SCP在命令行传输文件
    Linux下网卡eth编号配置文件路径
  • 原文地址:https://www.cnblogs.com/vijay/p/3543363.html
Copyright © 2011-2022 走看看