Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 如何在启用控制流完整性的情况下从程序集和C文件构建可执行文件?_Assembly_Clang_Sanitization_Llvm Ir - Fatal编程技术网

Assembly 如何在启用控制流完整性的情况下从程序集和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

在启用了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_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时不能生成。