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

用 c 手撸一个 Java 的 decompiler

  •  
  •   neocanabe
    neocanable 2024-07-07 00:38:56 +08:00 2093 次点击
    这是一个创建于 461 天前的主题,其中的信息可能已经有所发展或是发生改变。

    失业在家重新学习 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; } } 
    6 条回复
    KMpAn8Obw1QhPoEP
        1
    KMpAn8Obw1QhPoEP  
       2024-07-07 01:34:27 +08:00 via Android   2
    秀啊 屠龙技不懂 试试这个?
    https://www.craftinginterpreters.com/
    lisongeee
        2
    lisongeee  
       2024-07-07 02:27:11 +08:00
    感觉 java 的 decompiler 挺常见的,有考虑手撸 flutter/dart 的 decompiler 吗?
    neocanable
        3
    neocanable  
    OP
       2024-07-07 14:56:17 +08:00
    @enchilada2020 这本书太棒了
    neocanable
        4
    neocanable  
    OP
       2024-07-07 17:49:18 +08:00
    @lisongeee 不一样的东西吧,flutter 是包了一层 api 的 app
    piapia
        5
    piapia  
       100 天前 via iPhone
    请问 lz ,哪块的实现需要参考 nginx 的代码呀
    neocanable
        6
    neocanable  
    OP
       100 天前   1
    @piapia memory pool, 命名风格
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5558 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 30ms UTC 08:55 PVG 16:55 LAX 01:55 JFK 04:55
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86