V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
neocanable
V2EX  ›  分享创造

用 c 手撸一个 Java 的 decompiler

  •  
  •   neocanable · 169 天前 · 1566 次点击
    这是一个创建于 169 天前的主题,其中的信息可能已经有所发展或是发生改变。

    失业在家重新学习 c 语言,本来想写一个 arm 的 hook 框架,结果心血来潮,手撸一个 java 的 decompiler

    已经支持

    • lambda 表达式
    • 三元表达式
    • 赋值链
    • while/do while 循环
    • 数据类型推断
    • LocalVariableTable signature 还原
    • class annotation
    • filed annotation
    • method annotation
    • method 参数 annotation

    还在开发

    • android dex 支持
    • for 循环
    • for in 循环
    • java code label 支持
    • 优化掉 goto 语句
    • StringConcatFactory
    • varargs 方法支持
    • code attribute annotation
    • 。。。。。

    没有支持的还有一大堆,大体的框子已经写完了,剩下的大部分是体力活了。

    收获

    • 更恨 c++了
    • c 语言不完全掌握,三级指针不敢用,二级指针用的哆哆嗦嗦
    • jvm 的运行逻辑算是了解了一知半解
    • android dex
    • 能写一堆超级复杂的,没有注释谁也看不懂的宏
    • 参考了好多 nginx 的代码,写的真好啊!

    希望大佬帮忙

    哪位大佬有类似编译原理或者编译器开发的交流群或者社区,需要理论指导的时候,十分抓狂。 龙书/虎书/鲸书理论看起来太枯燥。

    成果

    源码

    import java.nio.channels.NotYetBoundException;
    import java.util.HashMap;
    import java.util.concurrent.ExecutionException;
    
    public class TryCatchNestedInCatch {
    
        public static void demo(String name, String ye) {
            try {
                int mmm = 1000;
            } catch (Exception e) {
                // String e3 = "Exception";
                try {
                    int mmm1 = 1000;
                    //demo2();
                } catch (NotYetBoundException e100) {
                    String e1 = "NotYetBoundException";
                    // System.out.println(e1);
                } catch(Exception e1) {
                    String e2 = "Exception";
                    // System.out.println(e2);
                } finally {
                    int mmm2 = 2000;
                    // System.out.println(mmm2);
                }
                // System.out.println(e3);
            } finally {
                int ccc = 2000;
                // System.out.println(ccc);
            }
    
        }
    }
    

    反编译结果:

    import java.nio.channels.NotYetBoundException;
    import java.util.HashMap;
    import java.util.concurrent.ExecutionException;
    
    public class TryCatchNestedInCatch  {
    
    	public static void demo(String var_0_0, String var_1_1) {
    		exception { // block_id: 1  range: 0 - 35  parent_id: 0
    			try { // block_id: 2  range: 0 - 4  parent_id: 1
    				int var_2_2(1) = 1000;
    				goto 74;
    			}
    			catch { // block_id: 3  range: 5 - 30  parent_id: 1
    				exception { // block_id: 5  range: 6 - 27  parent_id: 3
    					try { // block_id: 6  range: 6 - 10  parent_id: 5
    						int var_3_4(1) = 1000;
    						goto 57;
    					}
    					catch { // block_id: 7  range: 11 - 16  parent_id: 5
    						String var_4_9(1) = "NotYetBoundException";
    						goto 57;
    					}
    					catch { // block_id: 8  range: 17 - 22  parent_id: 5
    						String var_4_12(1) = "Exception";
    						goto 57;
    					}
    					finally { // block_id: 9  range: 23 - 27  parent_id: 5
    						int var_6_15(1) = 2000;
    						athrow(var_5_14);
    					}
    				}
    				goto 74;
    			}
    			finally { // block_id: 4  range: 31 - 35  parent_id: 1
    				int var_8_7(1) = 2000;
    			}
    		}
    	}
    
    }
    

    源码:

    import java.util.Random;
    
    public class Or {
        public static int a1;
        public static int a2;
        public static int a3;
    
        public int b1;
        public int b2;
        public int b3;
        public static void main(String[] args)
        {
            Random r = new Random();
            boolean q = 100 < r.nextInt() || 20 > r.nextInt() && r.nextInt() > 0; 
            int m = 200000;
            boolean s = r.nextInt() > 20 && r.nextInt() < 100;
        }
    
        public static void st()
        {
            Random r = new Random();
    
            boolean q = 100 < r.nextInt() || (Or.a1 = Or.a2 = Or.a3 = 20) > r.nextInt() && r.nextInt() > 0;
        }
    
        public void field()
        {
            Random r = new Random();
             int[] d = {0, 0, 2, 3};
            boolean q = 100 < r.nextInt() || (this.b1 = this.b2 = this.b3 = 20) > r.nextInt() && r.nextInt() > 0;
    
            boolean cd = 100 < r.nextInt() || (d[0] = d[2] = this.b3 = 20) > r.nextInt() && r.nextInt() > 0;
        }
    
    
       public boolean define_or()
       {
           int m = 0;
           int k = 0;
           int n = 0;
           int z = 0;
           Random r = new Random();
    
          boolean dddd =
               (m = 20) > 100 || (
                       30 > ((r.nextInt() > 100 && r.nextInt() != 1000) ? (100 & r.nextInt()) : 20) ?
                       (Or.a1 = this.b1 = m = k = n = 100 > r.nextInt() ? r.nextInt() : 0) :
                       // (100 > r.nextInt() ? r.nextInt() : 0) :
                       (r.nextInt() > 2000 ? 100 : 20)
                       ) <
               (z = r.nextInt() > 1000 ? 0 : 1);
    
    
          System.out.println(m);
          System.out.println(k);
          System.out.println(n);
    
          return true;
    
       }
    
    
    
    
    }
    

    反编译结果:

    import java.util.Random;
    import java.io.PrintStream;
    
    public class Or  {
    
      public static int a1;
    
      public static int a2;
    
      public static int a3;
    
      public int b1;
    
      public int b2;
    
      public int b3;
    
    
      public static void main(String[] var_0_0) {
        Random var_1_1(1) = new Random();
        int var_2_6(1) = 100 < var_1_1.nextInt() || 20 > var_1_1.nextInt() && var_1_1.nextInt() > 0 ? 0 : 1;
        int var_3_3(1) = 200000;
        int var_4_5(1) = var_1_1.nextInt() > 20 && var_1_1.nextInt() < 100 ? 0 : 1;
      }
    
      public static void st() {
        Random var_0_0(1) = new Random();
        int var_1_2(1) = 100 < var_0_0.nextInt() || Or.a1 = Or.a2 = Or.a3 = 20 > var_0_0.nextInt() && var_0_0.nextInt() > 0 ? 0 : 1;
      }
    
      public void field() {
        Random var_1_1(1) = new Random();
        int[] var_2_2(1) = new int[4]{0, 0, 2, 3};
        int var_3_6(1) = 100 < var_1_1.nextInt() || this.b1 = this.b2 = this.b3 = 20 > var_1_1.nextInt() && var_1_1.nextInt() > 0 ? 0 : 1;
        int var_4_5(1) = 100 < var_1_1.nextInt() || var_2_2[0] = var_2_2[2] = this.b3 = 20 > var_1_1.nextInt() && var_1_1.nextInt() > 0 ? 0 : 1;
      }
    
      public boolean define_or() {
        int var_1_1(1) = 0;
        int var_2_2(1) = 0;
        int var_3_3(1) = 0;
        int var_4_4(1) = 0;
        Random var_5_5(1) = new Random();
        int var_6_7(1) = var_1_1 = 20 > 100 || 30 > var_5_5.nextInt() > 100 && var_5_5.nextInt() != 1000 ? 20 : 100 & var_5_5.nextInt() ? var_5_5.nextInt() > 2000 ? 20 : 100 : 100 > var_5_5.nextInt() ? Or.a1 = this.b1 = var_1_1 = var_2_2 = var_3_3 = 0 : Or.a1 = this.b1 = var_1_1 = var_2_2 = var_3_3 = var_5_5.nextInt() < var_5_5.nextInt() > 1000 ? var_4_4 = 1 : var_4_4 = 0 ? 0 : 1;
        System.out.println(var_1_1);
        System.out.println(var_2_2);
        System.out.println(var_3_3);
        return true;
      }
    
    }
    
    4 条回复
    enchilada2020
        1
    enchilada2020  
       168 天前 via Android   ❤️ 2
    秀啊 屠龙技不懂 试试这个?
    https://www.craftinginterpreters.com/
    lisongeee
        2
    lisongeee  
       168 天前
    感觉 java 的 decompiler 挺常见的,有考虑手撸 flutter/dart 的 decompiler 吗?
    neocanable
        3
    neocanable  
    OP
       168 天前
    @enchilada2020 这本书太棒了
    neocanable
        4
    neocanable  
    OP
       168 天前
    @lisongeee 不一样的东西吧,flutter 是包了一层 api 的 app
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1291 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 17:22 · PVG 01:22 · LAX 09:22 · JFK 12:22
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.