Assembly 如何在启用控制流完整性的情况下从程序集和C文件构建可执行文件?
在启用了Clang的控制流完整性功能的情况下,是否可以从程序集和C文件构建可执行文件 使用以下命令生成文件Assembly 如何在启用控制流完整性的情况下从程序集和C文件构建可执行文件?,assembly,clang,sanitization,llvm-ir,Assembly,Clang,Sanitization,Llvm Ir,在启用了Clang的控制流完整性功能的情况下,是否可以从程序集和C文件构建可执行文件 使用以下命令生成文件funcs.s: gcc -S funcs.c 从funcs.c文件: int sum(int x, int y) { return x + y; } int dbl(int x) { return x + x; } void call_fn(int (*fn)(int)) { (*fn)(42); } void erase_type(void *fn) { call
funcs.s
:
gcc -S funcs.c
从funcs.c
文件:
int sum(int x, int y) {
return x + y;
}
int dbl(int x) {
return x + x;
}
void call_fn(int (*fn)(int)) {
(*fn)(42);
}
void erase_type(void *fn) {
call_fn(fn);
}
文件main.c
:
int main() {
erase_type(sum);
return 0;
}
为主机“x86”平台构建可执行文件,并启用“cfi”消毒剂功能:
./clang-8 \
-fsanitize=cfi \
-fvisibility=hidden \
-fno-sanitize-trap=all \
-fuse-ld=gold \
-flto \
funcs.s \
main.c \
-o \
main
测试功能:
./main
未检测到问题
注意:如果我使用原始的funcs.c
文件而不是funcs.S
文件,则所有文件都能正常工作:
$ ./main
funcs.c:10:3: runtime error: control flow integrity check for type 'int (int)' failed during indirect function call
(.../build_x86_cfi_lto_asm/main+0x42cb00): note: (unknown) defined here
常识表明答案是“否”(或者,至少不是以生成asm文件的方式)。消毒器功能应用于作为编译器/链接器输入提交的C代码,任何汇编语言文件都按原样使用。你可以做一个很好的实验——从“正确”的对象文件中获取汇编代码(通过使用objdump或开发环境中用于此目的的任何东西),并将结果与你从
gcc-S funcs.c
@tum_u中获得的汇编代码进行比较。我做了一个实验,是你提出的。是的,funcs.c.o和funcs.s.o非常不同。文件funcs.c.o是if LLVM IR格式(文件开头为“BC”)。文件funcs.s.o为ELF格式。无论如何,问题是一样的。是否可以为汇编文件启用CFI支持?好的,请尝试:/clang-8-S-fsanize=CFI funcs.c
@RossRidge他们说“sanitize=CFI”必须与“lto”一起使用。To OP:你错过了实验的要点——我建议看一下结果的程序集,而不是对象文件的内容。这将向您显示“cfi”选项添加了哪些额外代码,当您通过“gcc-S”生成asm时,这些额外代码显然丢失了。从问题标题来看,我认为这是关于手写asm,带有(或缺少)指令,如.cfi_def_cfa register、offset
,这些指令创建调用帧信息。eh_frame
元数据,用于堆栈展开。和。但在这两种情况下,答案都是:这是C编译器在查看原始C时可以生成的东西,而在组装任意asm时不能生成。常识表明答案是“否”(或者,至少不是以生成asm文件的方式)。消毒器功能应用于作为编译器/链接器输入提交的C代码,任何汇编语言文件都按原样使用。你可以做一个很好的实验——从“正确”的对象文件中获取汇编代码(通过使用objdump或开发环境中用于此目的的任何东西),并将结果与你从gcc-S funcs.c
@tum_u中获得的汇编代码进行比较。我做了一个实验,是你提出的。是的,funcs.c.o和funcs.s.o非常不同。文件funcs.c.o是if LLVM IR格式(文件开头为“BC”)。文件funcs.s.o为ELF格式。无论如何,问题是一样的。是否可以为汇编文件启用CFI支持?好的,请尝试:/clang-8-S-fsanize=CFI funcs.c
@RossRidge他们说“sanitize=CFI”必须与“lto”一起使用。To OP:你错过了实验的要点——我建议看一下结果的程序集,而不是对象文件的内容。这将向您显示“cfi”选项添加了哪些额外代码,当您通过“gcc-S”生成asm时,这些额外代码显然丢失了。从问题标题来看,我认为这是关于手写asm,带有(或缺少)指令,如.cfi_def_cfa register、offset
,这些指令创建调用帧信息。eh_frame
元数据,用于堆栈展开。和。但在这两种情况下,答案都是:这是C编译器在查看原始C时可以生成的东西,而在组装任意asm时不能生成。