为什么常量名称出现在已编译的 binaries/shared 库中?
Why do constant names appear in compiled binaries/shared libraries?
我正在 CMake 中构建一个库,它在私有 header 中有一些常量。当我在 Release
配置中编译时,例如输出中的 -O3 -DNDEBUG
和 运行 strings
,这些常量出现在输出中。这些常量的名称揭示了一些我想尽可能隐藏的实现细节。
这是一个演示问题的最小项目示例:
private.h
#pragma once
const int MY_CONSTANT = 42;
lib.c
#include "private.h"
extern int get_mask(void)
{
return MY_CONSTANT ^ 3;
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.5)
project(dummylib)
add_library(mylib SHARED lib.c)
构建并显示字符串输出:
$ mkdir build && cd build && cmake -DCMAKE_BUILD_TYPE=Release .. && cmake --build . --config Release -- VERBOSE=1 && strings libmylib.so | grep MY
MY_CONSTANT
我可以使用一些额外的开关来隐藏此信息吗?
我刚刚弄明白了。当您在常量前面添加 static
关键字时,您仍然可以从 lib.c
和关联的源文件中访问该值,但它的名称不再出现在二进制文件的 strings
转储中
private.h
#pragma once
const int MY_CONSTANT = 42;
结果:
$ strings libmylib.so | grep MY
MY_CONSTANT
MY_CONSTANT
使用static
关键字:
private.h
#pragma once
static const int MY_CONSTANT = 42;
结果:
$ strings libmylib.so | grep MY
在 gcc
中,您还可以使用 -g0
禁用调试符号
MY_CONSTANT
是一个需要在内存中占有一席之地的变量。 C 的编译 linking 过程涉及在 linking 到最终的 ELF executable 之前创建一个中间目标文件。需要跟踪变量并为其分配最终地址并在 link.
的最后阶段重新定位引用
作为此项目的产物,为目标文件创建了一个符号 table,该文件使用其名称引用 MY_CONSTANT
。默认情况下,linker 在创建最终 executable 时不会丢弃它。
您可以通过 运行 strip --strip-unneeded ./a.out
.
手动删除此符号 table
请注意,这与运行时用于 link 的 动态 符号 table 无关。应用程序仍然可以 link 反对和调用 get_mask(void)
我正在 CMake 中构建一个库,它在私有 header 中有一些常量。当我在 Release
配置中编译时,例如输出中的 -O3 -DNDEBUG
和 运行 strings
,这些常量出现在输出中。这些常量的名称揭示了一些我想尽可能隐藏的实现细节。
这是一个演示问题的最小项目示例:
private.h
#pragma once
const int MY_CONSTANT = 42;
lib.c
#include "private.h"
extern int get_mask(void)
{
return MY_CONSTANT ^ 3;
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.5)
project(dummylib)
add_library(mylib SHARED lib.c)
构建并显示字符串输出:
$ mkdir build && cd build && cmake -DCMAKE_BUILD_TYPE=Release .. && cmake --build . --config Release -- VERBOSE=1 && strings libmylib.so | grep MY
MY_CONSTANT
我可以使用一些额外的开关来隐藏此信息吗?
我刚刚弄明白了。当您在常量前面添加 static
关键字时,您仍然可以从 lib.c
和关联的源文件中访问该值,但它的名称不再出现在二进制文件的 strings
转储中
private.h
#pragma once
const int MY_CONSTANT = 42;
结果:
$ strings libmylib.so | grep MY
MY_CONSTANT
MY_CONSTANT
使用static
关键字:
private.h
#pragma once
static const int MY_CONSTANT = 42;
结果:
$ strings libmylib.so | grep MY
在 gcc
中,您还可以使用 -g0
MY_CONSTANT
是一个需要在内存中占有一席之地的变量。 C 的编译 linking 过程涉及在 linking 到最终的 ELF executable 之前创建一个中间目标文件。需要跟踪变量并为其分配最终地址并在 link.
作为此项目的产物,为目标文件创建了一个符号 table,该文件使用其名称引用 MY_CONSTANT
。默认情况下,linker 在创建最终 executable 时不会丢弃它。
您可以通过 运行 strip --strip-unneeded ./a.out
.
请注意,这与运行时用于 link 的 动态 符号 table 无关。应用程序仍然可以 link 反对和调用 get_mask(void)