gpt4 book ai didi

linux - 是否有与 Linux 内核的 alternative() 宏等效的用户空间?

转载 作者:太空狗 更新时间:2023-10-29 11:07:13 31 4
gpt4 key购买 nike

Linux 内核有一个alternative() macro它允许开发人员为一系列代码指定多个实现,并在运行时选择要使用的特定替代方案(在启动过程的早期,对于内核 alternative() 宏)。

是否有合理的方法来为用户模式应用程序实现类似的功能?特别是替代位置的记录和运行时补丁代码。

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

最佳答案

如果您在 Linux 上使用英特尔的 icc 编译器,您可以使用 __notify_intrinsic 特性来允许附加补丁。也就是说,它是一种允许您安全地 Hook 现有函数并添加额外行为的方法 - 这与侧重于在两个序列之间进行选择的 alternative() 有所不同。

__notify_intrinsic 确保在您放置内在代码的位置有一个探测就绪指令序列。这允许您以安全的方式在该点注入(inject)“探测”(实际上可以是任意代码),即使代码正在执行也是如此。

原则上,这可能有零开销:一个探测就绪序列只是一个由 6 个指令字节组成的序列1,您可以安全地将其重新定位到其他地方:意思是大部分这 6 个字节在指令边界上均匀对齐,没有位置相关代码2,并且没有任何跳转到范围内。

这个想法是,您可以使用这个探测就绪序列在运行时修改行为,方法是将字节复制到其他地方,然后是您的新代码,然后用 jmp 指令修补探测序列到您的离线“探针”(但探针可以是任何东西,真的)。

实际上,icc 版本 13 到 17 似乎只是插入一个 6 字节的 NOP 而不是实际尝试使用现有指令。作为example ,以下 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 指令组成一个六字节长的 nop 指令。

编译器在ELF二进制文件中的一个特殊的.itt_not_tab部分记录了每个__notify_intrinsic的位置和其他信息,比如注解的值,你可以查看在运行时。

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


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

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

关于linux - 是否有与 Linux 内核的 alternative() 宏等效的用户空间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45970156/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com