有没有一个相当于Linux内核的alternative()macros的用户空间?

Linux内核有一个alternative() macros ,它允许开发人员为一系列代码指定多个实现,在运行时使用特定的替代alternative()在内核的alternative()macros的情况下,在启动过程的早期 )。

有没有一种合理的方式来实现类似的用户模式应用程序? 特别是logging备选位置和运行时修补代码。

对于半静态检测可能是有用的:可以在运行时启用或禁用的检测,但仍仅“编译”到特定位置。

    如果您使用的是Linux的Intel icc编译器,则可以使用__notify_intrinsic功能来允许添加补丁。 也就是说,这是一种方法,可以让您安全地挂钩现有函数并添加其他行为 – 这与重点在于在两个序列之间进行选择的alternative()稍有不同。

    __notify_intrinsic确保在放置内在代码的位置有一个准备好探针的指令序列。 这样,即使代码正在执行,您也可以以安全的方式注入“探针”(实际上可以是任意代码)。

    原则上,这可能没有任何开销: 准备探测的序列只是一个6个指令字节的序列,您可以安全地重定位到其他地方:主要意思是这6个字节在指令边界上均匀对齐,没有位置相关的代码2 ,并没有任何跳跃的范围。

    这个想法是,您可以使用这个准备好探测的序列来修改运行时的行为,方法是复制别处的字节,然后是新的代码,然后使用jmp指令将探针序列修补到您的外联“探针” (但是探针可以是任何东西,真的)。

    实际上, icc版本13到17只是插入了一个6字节的NOP,而不是实际上试图使用现有的指令。 作为一个例子 ,下面的C代码:

     int add(int a, int b) { if (a < b) { __notify_intrinsic("a lt b", 0); a *= b; return a * b; } else { __notify_intrinsic("a gt b", 0); return a << b; } } 

    生成这个程序集:

     add: cmp edi, esi #2.11 jge ..B1.4 # Prob 50% #2.11 xor edx, edx #3.5 .byte 102 # .byte 15 # .byte 31 # .byte 68 # .byte 0 # .byte 0 # imul edi, esi #4.5 imul esi, edi #5.16 mov eax, esi #5.16 ret #5.16 ..B1.4: # Preds ..B1.1 xor edx, edx #7.5 .byte 102 # .byte 15 # .byte 31 # .byte 68 # .byte 0 # .byte 0 # mov ecx, esi #8.17 shl edi, cl #8.17 mov eax, edi #8.17 ret 

    这个6 .byte指令序列产生一个6字节的.bytenop指令。

    编译器__notify_intrinsic每个__notify_intrinsic的位置以及其他信息(如注释的值) .itt_not_tab在ELF二进制文件的特殊.itt_not_tab节中,您可以在运行时检查该节。

    您可以在文档中找到有关此方法的更多详细信息,但不幸的是,目前似乎仅限于英特尔专有的icc编译器。


    1在32位x86上有5个字节。

    2例如,相对跳转或翻转相对寻址。