Java 用调试信息反编译C代码?
Java和Python字节码比C/C++编译器生成的已编译机器码更容易反编译 对于-g选项中的信息不足以反编译,但足以进行调试的原因,我无法找到令人信服的答案?Java 用调试信息反编译C代码?,java,c++,c,reverse-engineering,decompiling,Java,C++,C,Reverse Engineering,Decompiling,Java和Python字节码比C/C++编译器生成的已编译机器码更容易反编译 对于-g选项中的信息不足以反编译,但足以进行调试的原因,我无法找到令人信服的答案? Python/Java字节码中包含哪些额外的东西使反编译变得容易?以下是一些原因: Java和Python字节码相对简单且高级,而某些CPU(比如x86)的指令集极其复杂 字节码紧密地模仿了为其设计的语言的结构 在生成字节码时,Java和Python执行的优化很少。这导致字节码与原始源代码的结构紧密对应。一个好的优化C或C++编译器能够
Python/Java字节码中包含哪些额外的东西使反编译变得容易?以下是一些原因:
有些处理器,如x86处理器,具有可变长度的指令。如果将控件传递到指令的中间(=第一个字节后的任何位置),则该指令也可以是有效的指令(或多条指令)。这使得很难明确地反汇编机器代码。C/C++代码可以利用此功能 在某些处理器和操作系统上,可以像执行代码一样执行数据,也可以像使用数据一样使用代码。这使得很难明确区分两者。同样,这也是C/C++程序通常可以轻松完成的 在某些处理器和操作系统上,很容易动态生成代码并执行它,并且可以在运行时修改现有代码。这也导致了反编译代码中的歧义。C/C++程序通常也能做到这一点 编辑:此外,一些CPU对同一条指令有多个不同的编码。例如,x86 CPU有两条指令
mov-reg,reg/mem
和mov-reg/mem,reg
。这使您可以在寄存器和内存位置(任意方向)之间以及两个寄存器之间移动数据。这两条指令都可用于在两个寄存器之间传输数据,但它们的编码不同。如果程序以某种方式依赖于特定的编码(例如,为了通过校验和验证其完整性),那么从反汇编(如mov eax,ebx
)中,您将无法分辨它最初是两条mov
指令中的哪一条,因此如果您尝试重新组装反汇编,你可能会破坏程序
您可以使用调试器调试带有或不带有调试/符号信息的程序。由于许多(但不一定全部)例程和变量可以使用它们的名称和类型识别和显示,而不仅仅是原始地址和原始无类型数据,因此这些信息只会使人类更容易导航代码和数据
我猜各种字节码都不那么模棱两可,而且在它们的功能上更受限制,这使得反编译这些字节码更容易
对于-g选项中的信息不足以反编译,但足以进行调试的原因,我无法找到令人信服的答案
调试信息基本上只包含生成代码中的地址和源文件行号之间的映射。调试器不需要反编译代码-它只显示原始源代码。如果源文件丢失,调试器将不会神奇地显示它们
也就是说,调试信息的存在确实使反编译更容易。如果调试信息包括所用类型和函数原型的布局,反编译器可以使用它并提供更精确的反编译。然而,在许多情况下,它仍可能与原始来源不同
例如,下面是一个使用Hex-Rays反编译器反编译的函数,而不使用调试信息:
int __stdcall sub_4050A0(int a1)
{
int result; // eax@1
result = a1;
if ( *(_BYTE *)(a1 + 12) )
{
result = sub_404600(*(_DWORD *)a1);
*(_BYTE *)(a1 + 12) = 0;
}
return result;
}
由于它不知道a1
的类型,因此对其字段的访问表示为添加和强制转换
加载符号文件后,这里有相同的函数:
void __thiscall mytree::write_page(mytree *this, PAGE *src)
{
if ( src->isChanged )
{
cache::set_changed(this->cache, src->baseAddr);
src->isChanged = 0;
}
}
你可以看到它已经改进了很多
至于为什么字节码反编译通常更容易,除了NPE的答案检查之外。这个答案最适合堆栈交换的area51反向工程networks@Koushik:该网站已经有五天的历史了,似乎正在进行私人测试。@NPE哦,完全忘记了。。希望公共测试从soonHi NPE开始,谢谢你的回答:)这些观点完全有道理。但是,你知道有哪种C/C++反编译器能够令人满意地反编译-O0-g编译代码吗?我要补充的是-g只提供标签名,而没有它,二进制文件只包含绝对地址和偏移量。这有助于阅读反编译的程序集,但不会让您回到C.@C.fogelklou:“反编译”程序集是什么?那不是C吗?我是说一个转换成文本的二进制文件。。。反编译可能不是正确的词,但最终结果是以文本可读格式包含的程序集代码。@Saswattpadhi“decompiled”程序集不必是c。它可以是c++/D/B/fortran等。也就是说,它取决于。Hi Alexey,