[求助] Java 对比字节码文件是不是由源码编译出来的 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
asanelder
V2EX    程序员

[求助] Java 对比字节码文件是不是由源码编译出来的

  •  
  •   asanelder 2020-12-07 10:07:12 +08:00 2927 次点击
    这是一个创建于 1851 天前的主题,其中的信息可能已经有所发展或是发生改变。

    俺现在有一个项目(别人的),有字节码文件和源码,但不知道这个字节码是不是源码编译出来的。现在俺想对比一下。

    俺当前能想出两个方向来。

    一. 将源码编译成字节码,然后对比

    这种方案的困难点是

    俺不知道当初字节码文件具体编译的环境是什么,如果编译出来的和现有的不同,也无法知道不同点在哪里。

    还有,对比这种字节码文件使用什么工具呢?


    二. 将字节码反编译成源码,然后对比

    俺找了一个文件试了一下,发现可以对比,只是反编译出来的源文件和现有的源文件中稍微的不同,比如变量名,比如语句顺序,这还需要俺人工的一个一个不同点进行检查。

    有没有铁子知道有什么反编译工具,可以反编译出和现有源代码一样的源码呢?这样就不需要俺人工一个一个不同点检查了。


    希望各位有类似经验的,给俺出出意见。

    22 条回复    2020-12-08 12:16:51 +08:00
    no1xsyzy
        1
    no1xsyzy  
       2020-12-07 10:21:27 +08:00
    不熟 Java,歪楼猜下场景。
    想到唯一的情况是带数字签名的字节码(比如 *.apk ),不然不管三七二十一直接编译一遍用自己编译的就行。
    TtTtTtT
        2
    TtTtTtT  
       2020-12-07 10:27:16 +08:00
    1. 这个方案最可行。不过如果使用了其他的编译器插件的话,就还要进一步猜。
    2. 这个方法不太可行,原理上可以反编译,但实际上有些糖化语法和常量内联没法找回最原始的代码。

    建议先编译源码,不行了再反编译。
    huruwo
        3
    huruwo  
       2020-12-07 10:28:42 +08:00
    1.源码编译一份
    2.两份编译后的代码全部拿去反向解密
    3.最后对比两个反向后的代码
    huruwo
        4
    huruwo  
       2020-12-07 10:30:37 +08:00
    @TtTtTtT 编译源码 在反编译 比较两个反编译结果就行。不用考虑是否完全还原,只要代码结构对的上就行
    asanelder
        5
    asanelder  
    OP
       2020-12-07 10:31:26 +08:00
    @TtTtTtT #2 俺能知道编译选项 source 和 target 是 1.8,但不知道当时使用的 jdk 是啥,铁子,不同的 jdk 会不会编译出来的字节码不同?

    还有一个问题,对比这种字节码使用什么工具呢?是不是一般的二进制对比工具就可以了? beyong compare 可以么?
    asanelder
        6
    asanelder  
    OP
       2020-12-07 10:34:21 +08:00
    @huruwo #4 铁子,感觉这个编译源码再反编译多此一举啊~~~。如果原来字节码的编译环境和俺的不一样,两个再反编译出来的也会不同吧(俺可以试试)

    你说的代码结构上对的上是啥?俺现在反编译的字节码就是在语法糖,变量名和语句顺序上不太一样,不过这些可以人工确定有没有问题。
    kanemochi
        7
    kanemochi  
       2020-12-07 10:35:00 +08:00
    编译成字节码本身就会丢失掉一些信息,例如排版方式与变量名,这样逆向无法推导的,就像 hash 碰撞一样,无法通过 hash 值反推出唯一的原文。
    TtTtTtT
        8
    TtTtTtT  
       2020-12-07 11:37:30 +08:00
    @asanelder jdk 就用 Oracle JDK 8 就行,我估计不太会有 IBM J9 这种诡异的版本。
    反编译的话,你可以试试 javap,或者 Bytecodeviewer,至于对比估计还是要手动对比一下。
    如果你有精力的话,用 ASM 自己写个程序对比一些就行了~
    TtTtTtT
        9
    TtTtTtT  
       2020-12-07 11:39:54 +08:00
    @huruwo 唔,这就有点复杂了不是,而且字节码并不是能够一定反编译回 Java 的,所以还是推荐在字节码级别上比较。
    chenshun00
        10
    chenshun00  
       2020-12-07 12:13:00 +08:00
    已经知道了字节码,使用 jd-gui 等反编译工具随机挑选 n 个文件进行对比.
    persona5
        11
    persona5  
       2020-12-07 13:44:48 +08:00
    你这么做的目的是什么?
    如果不放心 .class 文件,不是也有源码吗,code review 后自己编译一下?
    feitxue
        12
    feitxue  
       2020-12-07 13:51:57 +08:00
    外包项目验收代码嘛?是不是线上验收通过了,要验收源代码是不是 100%给交付了。
    asanelder
        13
    asanelder  
    OP
       2020-12-07 15:01:03 +08:00
    @kanemochi #7 嗯,是这样子的,所以俺只能人工比对一下

    @TtTtTtT #8 ASM 俺不会哈哈,这个需求并不常用,没办法的话,俺就人工比对一下,你说的这两个工具,俺试试

    @chenshun00 #10 不能随机啊,要对比所有文件的,抽查可不行

    @persona5 #11
    @feitxue #12

    就是别人给项目,有字节码和源码,但不知道该字节码是不是由源码编译出来的(给俺的人已经无法联系了),俺的后续需求是要继续迭代,所以得先确定项目的字节码和源码是否匹配
    mazyi
        14
    mazyi  
    PRO
       2020-12-07 15:17:58 +08:00 via iPhone
    那就直接用源码反编译的,不要用给的源码
    ColoThor
        15
    ColoThor  
       2020-12-07 15:31:58 +08:00
    有源码,不放心不是可以自己编译
    MaxLi77
        16
    MaxLi77  
       2020-12-07 15:45:15 +08:00
    没这种工具,不要想了。没有什么反编译工具可以 100%还原。
    icql
        17
    icql  
       2020-12-07 18:20:29 +08:00 via iPhone
    class 字节码文件里边有 java 版本信息啊,主版本次版本都有
    fengpan567
        18
    fengpan567  
       2020-12-07 19:21:16 +08:00
    先用源码编译,然后反编译两个文件对比是不是一样的内容
    asanelder
        19
    asanelder  
    OP
       2020-12-07 19:36:04 +08:00
    @fengpan567 #18
    @icql #17 ok,俺试试
    asanelder
        20
    asanelder  
    OP
       2020-12-07 19:56:05 +08:00
    @fengpan567 #18 铁子,好使!
    Jf35jxN3fwBXyeLh
        21
    Jf35jxN3fwBXyeLh  
       2020-12-08 12:14:32 +08:00
    楼主可以发一些样本看看吗,不知道你的字节码混淆没有,没有混淆的话,按文件名都能对应起来了,如果混淆了,可以看看字节码里有么有包含 sourcefile 信息
    Jf35jxN3fwBXyeLh
        22
    Jf35jxN3fwBXyeLh  
       2020-12-08 12:16:51 +08:00
    楼主可以发一些样本看看吗,不知道你的字节码混淆没有,没有混淆的话,按文件名都能对应起来了,如果混淆了,可以看看字节码里有么有包含 sourcefile 信息(把字节码反编译成可读文本 用 javap 命令)
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2298 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 28ms UTC 02:05 PVG 10:05 LAX 18:05 JFK 21:05
    Do have faith in what you're doing.
    ubao msn 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