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

2020-12-07 10:07:12 +08:00
 asanelder

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

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

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

这种方案的困难点是

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

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


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

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

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


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

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

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

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

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

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

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

@persona5 #11
@feitxue #12

就是别人给项目,有字节码和源码,但不知道该字节码是不是由源码编译出来的(给俺的人已经无法联系了),俺的后续需求是要继续迭代,所以得先确定项目的字节码和源码是否匹配
mazyi
2020-12-07 15:17:58 +08:00
那就直接用源码反编译的,不要用给的源码
ColoThor
2020-12-07 15:31:58 +08:00
有源码,不放心不是可以自己编译
MaxLi77
2020-12-07 15:45:15 +08:00
没这种工具,不要想了。没有什么反编译工具可以 100%还原。
icql
2020-12-07 18:20:29 +08:00
class 字节码文件里边有 java 版本信息啊,主版本次版本都有
fengpan567
2020-12-07 19:21:16 +08:00
先用源码编译,然后反编译两个文件对比是不是一样的内容
asanelder
2020-12-07 19:36:04 +08:00
@fengpan567 #18
@icql #17 ok,俺试试
asanelder
2020-12-07 19:56:05 +08:00
@fengpan567 #18 铁子,好使!

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/732792

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX