如何使gcc为-fpatchable函数项发出多字节NOP?
gcc确实能够使用多字节NOP来对齐循环和函数。然而,当我尝试这个方法时,它总是发出单字节NOP 您可以看到,gcc将函数与如何使gcc为-fpatchable函数项发出多字节NOP?,gcc,assembly,x86,x86-64,Gcc,Assembly,X86,X86 64,gcc确实能够使用多字节NOP来对齐循环和函数。然而,当我尝试这个方法时,它总是发出单字节NOP 您可以看到,gcc将函数与nop DWORD PTR[rax+rax*1+0x0]和nop WORD PTR cs:[rax+rax*1+0x0]对齐,但当我指定-fpatchable function entry=8,3 我在文件中看到了这一点 -fpatchable function entry=N[,M] 在每个函数的开头生成N个NOP,函数入口点在第m个NOP之前。如果省略M,则默认为0,
nop DWORD PTR[rax+rax*1+0x0]
和nop WORD PTR cs:[rax+rax*1+0x0]
对齐,但当我指定-fpatchable function entry=8,3
我在文件中看到了这一点
-fpatchable function entry=N[,M]
- 在每个函数的开头生成N个NOP,函数入口点在第m个NOP之前。如果省略M,则默认为0,因此函数入口仅指向第一个NOP处的地址。如果代码段是可写的,NOP指令将保留额外的空间,可用于在运行时修补任何所需的检测。通过NOP的数量间接控制空间量;使用的NOP指令对应于内部GCC后端接口发出的指令
。此行为是特定于目标的,也可能取决于体系结构变量和/或其他编译选项gen_NOP
那么gcc为什么要这样做呢?我们能让它生成多字节NOP吗?两个0x90 NOP是否比Microsoft的
mov edi、edi
?好?多字节NOP可能是由汇编程序通过其对齐指令生成的。请注意,严格地说,该选项按照文档和预期工作,参数是插入的NOP指令数,而不是NOP指令的字节数。更改此行为使其按您认为的方式工作将是不兼容的更改,并且可能会破坏使用此选项的现有应用程序。您可能需要查看ms\u hook\u prologue
函数属性,看看它是否符合您的要求,否则我认为您需要自己实现它;每个都在uop缓存中获取一个条目,以及前端问题带宽的单独插槽。与大型函数开始时的推送
和其他简短指令一起,在一个函数的前32字节机器代码中可能会有太多的UOP,无法在Sandybridge-family上容纳3行最多6个UOP。似乎当前的最佳选择是。此外,从这个角度来看,这似乎是一个“懒惰”的设计选择。