考虑这个(恕我直言)简单的例子:
public class DecompilerTest {
public static void main(String[] args) {
Object s1 = "The", s2 = "answer";
doPrint((Object) "You should know:");
for (int i = 0; i < 2; i++) {
doPrint(s1);
doPrint(s2);
s1 = "is";
s2 = new Integer(42);
}
System.out.println();
}
private static void doPrint(String s1) {
System.out.print("Wrong!");
}
private static void doPrint(Object s1) {
System.out.print(s1 + " ");
}
}
Run Code Online (Sandbox Code Playgroud)
在没有调试信息的情况下用源/目标级别1.1编译它(即不应存在局部变量信息)并尝试对其进行反编译.我尝试过Jad,JD-GUI和Fernflower,他们都至少有一个错误的调用(即程序打印"错误!"至少一次)
真的没有java反编译器可以推断出正确的强制转换,以便它不会调用错误的重载吗?
编辑:目标级别1.1,以便不存在特定于Java6的快速验证信息.这可能会给反编译器一个线索,即s1已被声明为Object而不是String.即使没有这些信息,反编译器也应该能够反编译代码(不一定得到原始变量类型,但显示相同的行为),特别是因为许多混淆器也将它剥离.
反编译器出了什么问题:
(Object)在第一次通话中错过了演员.s1要String …我试图在反编译代码中设置一个条件断点,但Eclipse不断给我错误:
条件断点有编译错误
原因:评估必须包含表达式或格式良好的语句块
我的情况非常简单,只是尝试与字符串值进行比较.我已经尝试了以下所有内容,但每个单独出错都会出错:
myObj.toString() == "abc123"
myObj.toString().equals("abc123")
if(myObj.toString() == "abc123"){ return true; }
true == true
Run Code Online (Sandbox Code Playgroud)
我也尝试过在行尾添加或不使用分号的每种组合,以及间距和换行符的每种组合以及包含或不包含{}的每种组合.基本上,我不知道为什么这不起作用......
我试图调试的代码是在一个用JD-Eclipse反编译的jar中.正常断点在此代码中正常工作.
有谁知道这里发生了什么?
我看到一些java反编译器可以将字节码反编译成可读的java源代码,我想知道来自java(不是其他JVM语言)的所有字节码是否可以再次反编译为java源代码?
更新
对不起,让我更清楚地提出问题.
刚谈谈JVM上的普通Java代码(没有Android,没有字节码增强,没有AOP,没有混淆),我实际上希望字节码可以被反编译.但是我不知道是否有编译成字节码的java代码形式,永远不能被反编译成可读的java源代码.
反编译Scala代码:为什么派生类中有两个重写方法?
class A
{
private var str: String = "A"
val x: A = this
override def toString(): String = str
def m1(other: AnyRef): AnyRef = {
println("This is A.m1(AnyRef)")
other
}
}
class B extends A {
private var str: String = "B"
var z: Int = 0
override val x: B = this
override def m1(other: AnyRef): B = {
println("This is B.m1(AnyRef)")
this
}
}
Run Code Online (Sandbox Code Playgroud)
上面代码的B类反编译为:
public class test$B extends test$A {
private java.lang.String str;
private int …Run Code Online (Sandbox Code Playgroud) 我的场景:我想在日志文件中写入发生异常的部分代码(例如,之前的5行和发生异常的5行之后 - 或者至少是该方法的所有代码).
我的想法是用C#代码反编译pdb文件,并从反编译的文件中找到一个在catch块中异常的方法.
Pbd文件存在,我的应用程序构建为调试版本.我知道有些工具允许通过它的GUI(例如Reflector)进行反编译,但我希望从我的代码中获得该功能.
怎么做?
我正在研究需要将.class文件反编译为源代码的java项目,我发现了很多方法,比如JAD反编译器和'javap -p'方法......但是我觉得这些方法都做不到以编程方式(请告诉是否可以),有没有办法以编程方式完成此操作,如果您向我展示任何库,将不胜感激.
我编写了一个实用程序来为java方法创建一个CFG(控制流图),该方法的节点是基本块而不是指令.
我不能认为异常抛出是CFG中的边缘.原因是:
静态代码分析器如何解决这个问题?
我被困在这一点上.如果我必须继续,我应该怎么做呢?
编辑:在我的情况下,我可以限制对那些可以指定抛出位置和异常的用例的支持.这解决了我的第二个问题.我仍然想知道通用静态代码分析器如何管理它.
我知道Java编译器用泛型替换泛型类型中的所有类型参数,或者Object在类型擦除过程中类型参数是否无界限.生成的机器字节码将反映被替换的边界或Object.
有没有办法获取生成的机器字节码并将其反编译回包含泛型类型中的原始类型参数的Java文件?是否存在可以实现此目的的反编译器?或者由于编译过程的性质,这个过程是不可逆转的?
我确实尝试了 uncompyle6、decompyl3 等,但它们都不适用于 3.10。现在是否有可能做到这一点?
肯定有一百万本关于构建编译器的理论和技术的书籍和论文。有没有资源可以做相反的事情?我对任何特定的硬件平台都不感兴趣。寻找深入研究该主题和困难的好书/研究论文。
decompiler ×10
java ×6
bytecode ×2
jad ×2
.net ×1
breakpoints ×1
c# ×1
class ×1
debugging ×1
eclipse ×1
generics ×1
inheritance ×1
logging ×1
pdb-files ×1
polymorphism ×1
pyc ×1
python ×1
python-3.10 ×1
scala ×1