我将一些 [相对复杂的] Java 代码编译成一个 .class 文件,然后使用 jad 将其反编译回 java。当然,代码被混淆了,这是意料之中的。但是,鉴于我拥有原始代码,我认为我可以相当轻松地查看反编译代码。但是,我注意到代码中的差异,例如某些变量的定义位置(包括范围的差异)。
这有什么主要原因吗?我想这是在反编译代码时发生的事情之一,但我更好奇是什么因素导致了变化(例如代码的复杂性,是否引用了其他文件等)。
有人可以就哪些因素导致前后代码差异向我提供一个很好的解释吗?
编辑
从技术上讲,.class 文件是从 jar 中提取的。我提取了内容并在其中使用了 .class 文件。
至于我使用的混淆器,我使用了带有以下选项的 Retroguard 混淆器(我目前只是在探索混淆并找出每件事对最终结果的影响):
.option Application
.option Applet
.option Repackage
.option Annotations
.option MapClassString
.attribute LineNumberTable
.attribute EnclosingMethod
.attribute Deprecated
该脚本的文档可以在他们的站点上找到。它有点无组织,但你应该能够在那里找到足够的解释。同样值得注意的是,我剥离了泛型和局部变量表。
我现在还设置了一种方法(受 Minecraft Coder Pack 的创建者启发)使用来自文件(或多个文件)的数据重命名源,该文件被传递到包、类、方法和字段的列表字典.
# snippet from the MCP version (mine's slightly different) (all in Python):
srg_types = {'PK:': ['obf_name', 'deobf_name'],
'CL:': ['obf_name', 'deobf_name'],
'FD:': ['obf_name', 'deobf_name'],
'MD:': ['obf_name', 'obf_desc', 'deobf_name', 'deobf_desc']}
parsed_dict = {'PK': [],
'CL': [],
'FD': [],
'MD': []}
然后从文件中解析出一行,并将其传递到 中parsed_dict
,然后用于重命名所有内容(来回)。编译后实现而不是第一次反编译(在我注意到差异之后)。