V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
zhwguest
V2EX  ›  Java

一个关于 Java 反编译的问题

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

    对一个 jar 进行反编译,发现有些代码并没有生成 java 代码,而是这样的结果:

            /* JADX WARNING: Code restructure failed: missing block: B:4:0x0007, code lost:
                r2 = Companion.getClipDataUris$activity_release(r3);
             */
            /* Code decompiled incorrectly, please refer to instructions dump. */
            public final java.util.List<android.net.Uri> parseResult(int r2, android.content.Intent r3) {
                /*
                    r1 = this;
                    r0 = -1
                    if (r2 != r0) goto L_0x0004
                    goto L_0x0005
                L_0x0004:
                    r3 = 0
                L_0x0005:
                    if (r3 == 0) goto L_0x0010
                    androidx.activity.result.contract.ActivityResultContracts$GetMultipleContents$Companion r2 = Companion
                    java.util.List r2 = r2.getClipDataUris$activity_release(r3)
                    if (r2 == 0) goto L_0x0010
                    goto L_0x0014
                L_0x0010:
                    java.util.List r2 = kotlin.collections.CollectionsKt.emptyList()
                L_0x0014:
                    return r2
                */
                throw new UnsupportedOperationException("Method not decompiled: androidx.activity.result.contract.ActivityResultContracts.GetMultipleContents.parseResult(int, android.content.Intent):java.util.List");
            }
    

    两个问题:

    1. 什么情况下会出现这种问题,比如注释中写明了 Code restructure failed: misseing block ,那是不是我们估计构造这样的代码可以增加反编译难度;
    2. 经常发现代码反编译不成功的额时候,会用一段注释将其描述出来,这段描述也不是标准的字节码,那重新对这个 java 文件直接进行编译能够得到原来的 class 文件么?
    3. 有没有办法指定给反编译器,当反编译为 java 不成功的时候,直接使用字节码反编译,方便后续再次编译为 class ? 感谢
    10 条回复    2024-03-25 23:21:51 +08:00
    virusdefender
        1
    virusdefender  
       233 天前
    https://www.benf.org/other/cfr/ 试试这个,有些反编译器冷门的一些用法处理的不太好
    secondwtq
        2
    secondwtq  
       233 天前
    这个看起来是 JVM 支持 goto ,但是 Java 不支持,然后你这个 bytecode 可能是 Kotlin 编译器生成的不是 Java 编译器生成的。你直接用 Java 构造可能会比较困难,但是对已有的 bytecode 做后处理达到这样的效果倒是有可能。
    secondwtq
        3
    secondwtq  
       233 天前
    C/C++ 反编译里面这种情况非常常见,比如你用 Hex Rays 或者 GHIDRA 反编译稍微复杂一点的函数很容易出现一堆 label+goto 的结果,虽然源代码 90% 不是这么写的。其实就是 C/C++ 编译器优化得多
    32uKHwVJ179qCmPj
        4
    32uKHwVJ179qCmPj  
       233 天前
    多试几个反编译器
    flyqie
        5
    flyqie  
       233 天前 via Android
    jadx-gui 逆向效果已经算不错的了吧。。

    有这个问题。。可能只能手动看 bytecode 修了。。
    naythefirst01
        6
    naythefirst01  
       233 天前
    一般用到了比较少见的写法会解析错误,不排除使用了一些保护手段,jadx 和其他的反编译工具都有 smali code 的窗口吧,就是为了还原 Java code 不顺利时使用的,smali 比较直观 可以人肉翻译 或者直接丢给 GPT 让它给你翻译成 Java 代码
    zhwguest
        7
    zhwguest  
    OP
       233 天前
    谢谢各位的热心指导。
    反编译失败的原因一直没有搞太明白。今天明白了 goto 可能导致反编译失败原因之一,不知道还有没有其他方法。
    Aresxue
        8
    Aresxue  
       232 天前   ❤️ 1
    多试几个好了。Cfr 、Procyon 、jadx ,一般 Java 的代码很少加混淆也没那个价值
    zerofancy
        9
    zerofancy  
       232 天前
    多用点 Kotlin 协程,jadx 反编译后都是这种代码
    secondwtq
        10
    secondwtq  
       232 天前   ❤️ 1
    @zhwguest 不是说"goto 导致反编译失败",所有 control flow 到字节码里面都是 goto ,只是反编译器能不能从 goto 里面还原出原来的 control flow 来。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3575 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 19ms · UTC 00:09 · PVG 08:09 · LAX 16:09 · JFK 19:09
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.