【发布时间】:2012-12-27 19:58:39
【问题描述】:
我正在努力寻找确凿的事实,以帮助我的管理层了解对已编译的 C 代码进行逆向工程的难易程度。
以前曾在本网站上提出过类似的问题(例如,参见 Is it possible to “decompile” a Windows .exe? Or at least view the Assembly? 或 Possible to decompile DLL written in C?),但这些问题的要点是反编译已编译的 C 代码“很难,但并非完全不可能”。
为了便于提供基于事实的答案,我将包含一个神秘函数的编译代码,并且我建议对这个问题的答案通过它们是否可以确定该函数的作用来衡量所提出技术的成功或失败.这对于 SO 来说可能是不寻常的,但我认为这是对这个工程问题获得“良好的主观”或事实答案的最佳方式。因此,您对这个函数在做什么以及如何做的最佳猜测是什么?
这是编译后的代码,在 Mac OSX 上使用 gcc 编译:
_mystery:
Leh_func_begin1:
pushq %rbp
Ltmp0:
movq %rsp, %rbp
Ltmp1:
movsd LCPI1_0(%rip), %xmm1
subsd %xmm0, %xmm1
pxor %xmm2, %xmm2
ucomisd %xmm1, %xmm2
jbe LBB1_2
xorpd LCPI1_1(%rip), %xmm1
LBB1_2:
ucomisd LCPI1_2(%rip), %xmm1
jb LBB1_8
movsd LCPI1_0(%rip), %xmm1
movsd LCPI1_3(%rip), %xmm2
pxor %xmm3, %xmm3
movsd LCPI1_1(%rip), %xmm4
jmp LBB1_4
.align 4, 0x90
LBB1_5:
ucomisd LCPI1_2(%rip), %xmm1
jb LBB1_9
movapd %xmm5, %xmm1
LBB1_4:
movapd %xmm0, %xmm5
divsd %xmm1, %xmm5
addsd %xmm1, %xmm5
mulsd %xmm2, %xmm5
movapd %xmm5, %xmm1
mulsd %xmm1, %xmm1
subsd %xmm0, %xmm1
ucomisd %xmm1, %xmm3
jbe LBB1_5
xorpd %xmm4, %xmm1
jmp LBB1_5
LBB1_8:
movsd LCPI1_0(%rip), %xmm5
LBB1_9:
movapd %xmm5, %xmm0
popq %rbp
ret
Leh_func_end1:
更新
@Igor Skochinsky 是第一个找到正确答案的人:它确实是 Heron 计算平方根算法的幼稚实现。原始源代码在这里:
#include <stdio.h>
#define EPS 1e-7
double mystery(double x){
double y=1.;
double diff;
diff=y*y-x;
diff=diff<0?-diff:diff;
while(diff>=EPS){
y=(y+x/y)/2.;
diff=y*y-x;
diff=diff<0?-diff:diff;
}
return y;
}
int main() {
printf("The square root of 2 is %g\n", mystery(2.));
}
【问题讨论】:
-
您拥有 7k+ 的声誉并称呼“网站版主”??你没有弄清楚这个网站是如何运作的吗?
-
@djechlin:“猜猜我的汇编器做了什么?”曾经是一个有效的问题吗? (或者那是讽刺?)
-
@lindelof - 我会给你另一个例子here,其中 10 行内联函数和 C++ 模板被编译成 4-5 条机器指令。任何人都可以复制原始源代码的几率是多少?
-
一般情况下是不可能的,原始源是绝对不可能的,在极少数情况下没有使用优化器并且代码是如此琐碎以至于您无需费心回到C,然后您可以重构功能相同的东西。
-
将此视为将 wav 文件转换为 mp3,(将图像转换为 jpg,将电影转换为 mpeg 等)一种有损压缩。您无法取回原始信号。同样的事情发生在编译器中,正在编译的源代码中的信息丢失,在输出中不可见,您无法返回原始代码。功能相似的 C 代码在可能的情况下并不比汇编语言更具可读性或可维护性,如果您必须在 asm 中进行修改或通过对 asm 的分析手动编写 C 代码,则最好。
标签: c assembly x86 reverse-engineering decompiling