C++ C++;程序从“导入文件”;。a「;文件,但您可以';“t反向”;。a「;你自己归档?
如果包含打包为“.a”的文件,则可以导入其中的文件并调用其方法。但是,据我所知,您无法从“.a”文件检索源代码。程序怎么可能知道并可以使用源代码,但没有程序以人类可读的形式生成源代码?编译器将源代码转换为二进制文件,称为对象文件,可直接链接或存储在存档(.a、.lib等)中. 链接器将对象文件(可以是实际文件或存档内容)组合到可执行文件中。档案文件中没有魔法;链接器不会将二进制文件转换回源代码C++ C++;程序从“导入文件”;。a「;文件,但您可以';“t反向”;。a「;你自己归档?,c++,C++,如果包含打包为“.a”的文件,则可以导入其中的文件并调用其方法。但是,据我所知,您无法从“.a”文件检索源代码。程序怎么可能知道并可以使用源代码,但没有程序以人类可读的形式生成源代码?编译器将源代码转换为二进制文件,称为对象文件,可直接链接或存储在存档(.a、.lib等)中. 链接器将对象文件(可以是实际文件或存档内容)组合到可执行文件中。档案文件中没有魔法;链接器不会将二进制文件转换回源代码 至于将目标文件转换回源文件,有一些工具可以做到这一点;它们被称为反编译器,但它们工作得不太好,因为根本
至于将目标文件转换回源文件,有一些工具可以做到这一点;它们被称为反编译器,但它们工作得不太好,因为根本没有足够的信息来重构源代码。制作香肠后,你无法回到猪的身边。编译器将源代码转换为二进制文件,称为对象文件,可以直接链接或存储在存档(.a、.lib等)中。链接器将对象文件(可以是实际文件或存档内容)组合到可执行文件中。档案文件中没有魔法;链接器不会将二进制文件转换回源代码
至于将目标文件转换回源文件,有一些工具可以做到这一点;它们被称为反编译器,但它们工作得不太好,因为根本没有足够的信息来重构源代码。在你做了香肠之后,你不能回到猪的身边。好吧,即使有关于链接器的所有解释,你仍然感到困惑 简单地说,CPU理解并执行的代码不是您在
C++
中编写的代码。它做同样的事情,但它不一样
汇编是介于C++
(和其他高级语言)和机器代码(CPU执行的代码)之间的一种语言,人眼仍然可以理解,因此我将在这里使用汇编。让我们看两个C++
函数,并查看它们的程序集(通过启用优化的叮当声生成):
第一个功能:
第二条:
使用它生成的程序集:
foo(int, int, int): # @foo(int, int, int)
cmpl %edx, %edi
cmovlel %edi, %edx
cmpl %esi, %edi
cmovll %esi, %edx
movl %edx, %eax
retq
clamp(int, int, int): # @clamp(int, int, int)
cmpl %edi, %edx
cmovlel %edx, %edi
cmpl %esi, %edi
cmovll %esi, %edi
movl %edi, %eax
retq
我们可以观察到:
- 这两个
函数的作用完全相同c++
- 组件丢失了很多信息:
- 参数的原始名称
- 即使是函数中有多少变量的信息也会丢失
- 函数具有什么样的指令流
代码有什么指令C++
- 第二个函数实际上调用了其他函数
- 除非明确指定(
),否则即使函数名也会在最终的对象文件中丢失-g
- 等等等等
<> L>强的>非常不同的< /强>(在实现中)C++函数生成<强>相同的<强> >(几乎,取“五月”字,它只是不同的测试顺序)
因此,您可以看到,没有可靠的方法可以从程序集中获取原始的
C++
代码(从对象文件中更是如此)。好的,即使对链接器进行了所有说明,您仍然感到困惑
简单地说,CPU理解并执行的代码不是您在C++
中编写的代码。它做同样的事情,但它不一样
汇编是介于C++
(和其他高级语言)和机器代码(CPU执行的代码)之间的一种语言,人眼仍然可以理解,因此我将在这里使用汇编。让我们看两个C++
函数,并查看它们的程序集(通过启用优化的叮当声生成):
第一个功能:
第二条:
使用它生成的程序集:
foo(int, int, int): # @foo(int, int, int)
cmpl %edx, %edi
cmovlel %edi, %edx
cmpl %esi, %edi
cmovll %esi, %edx
movl %edx, %eax
retq
clamp(int, int, int): # @clamp(int, int, int)
cmpl %edi, %edx
cmovlel %edx, %edi
cmpl %esi, %edi
cmovll %esi, %edi
movl %edi, %eax
retq
我们可以观察到:
- 这两个
函数的作用完全相同c++
- 组件丢失了很多信息:
- 参数的原始名称
- 即使是函数中有多少变量的信息也会丢失
- 函数具有什么样的指令流
代码有什么指令C++
- 第二个函数实际上调用了其他函数
- 除非明确指定(
),否则即使函数名也会在最终的对象文件中丢失-g
- 等等等等
<> L>强的>非常不同的< /强>(在实现中)C++函数生成<强>相同的<强> >(几乎,取“五月”字,它只是不同的测试顺序)
C++
代码(从对象文件中更是如此)。负责组合多个文件的“程序”。一个文件称为链接器。它无法访问.a中的源代码(并且.a甚至不包含源代码)。它只知道函数的机器代码,以及其中一些函数的入口点,以便其他链接代码可以调用它们
to.a文件的示例:
- file1.a在某个地方调用了一个函数foo(),该函数未在文件中定义。编译器当时知道调用此函数的方法将在以后定义,他让调用“挂起”在.a中
- file2.a具有函数foo()的编译机器代码和一个包含调用foo所需信息的符号表