CN117215811A - 一种基于二进制重写的系统调用挂钩方法、设备及介质 - Google Patents
一种基于二进制重写的系统调用挂钩方法、设备及介质 Download PDFInfo
- Publication number
- CN117215811A CN117215811A CN202311481604.8A CN202311481604A CN117215811A CN 117215811 A CN117215811 A CN 117215811A CN 202311481604 A CN202311481604 A CN 202311481604A CN 117215811 A CN117215811 A CN 117215811A
- Authority
- CN
- China
- Prior art keywords
- function
- binary
- system call
- memory
- hook
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Pending
Links
- 238000000034 method Methods 0.000 title claims abstract description 82
- 230000006870 function Effects 0.000 claims description 117
- 230000008569 process Effects 0.000 claims description 20
- 230000007246 mechanism Effects 0.000 claims description 17
- 238000004590 computer program Methods 0.000 claims description 6
- 238000013507 mapping Methods 0.000 claims description 6
- 230000033772 system development Effects 0.000 abstract description 2
- 101100348848 Mus musculus Notch4 gene Proteins 0.000 description 13
- 230000011664 signaling Effects 0.000 description 12
- 230000015556 catabolic process Effects 0.000 description 5
- 238000006731 degradation reaction Methods 0.000 description 5
- 238000010586 diagram Methods 0.000 description 4
- 238000002474 experimental method Methods 0.000 description 4
- 238000013459 approach Methods 0.000 description 3
- 230000006399 behavior Effects 0.000 description 3
- 230000000694 effects Effects 0.000 description 3
- 238000005516 engineering process Methods 0.000 description 3
- 239000008186 active pharmaceutical agent Substances 0.000 description 2
- 238000011161 development Methods 0.000 description 2
- 230000018109 developmental process Effects 0.000 description 2
- 238000011156 evaluation Methods 0.000 description 2
- 230000002085 persistent effect Effects 0.000 description 2
- 238000012545 processing Methods 0.000 description 2
- 230000007958 sleep Effects 0.000 description 2
- 238000012360 testing method Methods 0.000 description 2
- 230000001960 triggered effect Effects 0.000 description 2
- 230000003213 activating effect Effects 0.000 description 1
- 230000009286 beneficial effect Effects 0.000 description 1
- PCHJSUWPFVWCPO-UHFFFAOYSA-N gold Chemical compound [Au] PCHJSUWPFVWCPO-UHFFFAOYSA-N 0.000 description 1
- 239000010931 gold Substances 0.000 description 1
- 229910052737 gold Inorganic materials 0.000 description 1
- 230000005055 memory storage Effects 0.000 description 1
- 238000012986 modification Methods 0.000 description 1
- 230000004048 modification Effects 0.000 description 1
- 238000011056 performance test Methods 0.000 description 1
- 239000000700 radioactive tracer Substances 0.000 description 1
- 230000003068 static effect Effects 0.000 description 1
- 238000006467 substitution reaction Methods 0.000 description 1
- 230000026676 system process Effects 0.000 description 1
- 238000012546 transfer Methods 0.000 description 1
Abstract
本申请属于计算机系统开发技术领域,具体涉及一种基于二进制重写的系统调用挂钩方法、设备及介质,该方法基于二进制重写技术,通过取代syscall和sysenter这两个用于触发系统调用的字节指令,来跳转到任意钩子函数地址。该方法解决了现有系统挂钩技术性能损耗高、无法彻底对系统调用挂钩、错误覆盖系统指令、可移植性差、普适性差的问题,实现了将用户空间操作系统子系统透明地应用于用户空间程序的要求,优势明显。
Description
技术领域
本申请属于计算机系统开发技术领域,具体涉及一种基于二进制重写的系统调用挂钩方法、设备及介质。
背景技术
现有的类Unix系统内核支持的钩子机制(例如,ptrace、Syscall User Dispatch(SUD)以及int3信令)所使用的传统二进制重写技术导致应用钩子的用户空间程序在性能上出现不可接受的降级。其他二进制重写机制(例如,指令双关语、E9Patch和XContainers中应用的技术)和函数调用替换(例如,LD_PRELOAD机制)无法彻底对系统调用进行挂钩。因此,它们不能用于对可靠性有要求的操作系统。
发明内容
为了解决现有技术的问题,本专利为x86-64CPU提出了一种新颖的系统调用挂钩操作方法,该方法基于二进制重写技术,它通过取代syscall和sysenter这两个用于触发系统调用的字节指令(汇编操作码分别为0x0f0x05和0x0f0x34),来跳转到任意钩子函数地址。该方法没有上面提到的所有缺点,解决了性能损耗高的问题,实现了将用户空间操作系统子系统透明地应用于用户空间程序的要求。其技术方案为:
一种基于二进制重写的系统调用挂钩方法,包括以下步骤:
S1.操作系统的环境配置:配置系统环境变量,将虚拟地址0设为可用;
S2.蹦床代码的设置:在虚拟地址0处分配内存,用nop指令序列和跳转代码填充分配的内存空间;
S3.二进制重写:获取内存映射信息,遍历内存上的指令,进行指令替换操作,完成二进制重写;
S4.加载钩子函数库:加载库文件,并为其指定新的命名空间;获取指向钩子函数核心实现的指针,挂载调用钩子函数。
优选的,操作系统环境配置还包括:
(1)设置操作系统环境变量:在Linux系统环境变量中,将LD_PRELOAD的值设置为专用共享库的路径;
(2)在Linux系统环境变量中增加自定义环境变量,并将其设置为钩子函数库的路径。
优选的,蹦床代码和二进制重写在专用共享库中实现,在用户空间程序的主函数启动之前执行设置过程;
专用共享库在通过LD_PRELOAD机制加载并在动态链接应用程序二进制文件时使用,LD_PRELOAD允许专用共享库在用户空间程序的主函数启动之前运行设置过程。
优选的,蹦床代码设置过程首先使用 mmap 系统调用在虚拟地址 0 处分配内存;然后,它用 nop 指令序列和跳转代码填充分配的内存区域。
优选的,二进制重写过程首先利用procfs文件系统获取内存映射信息;然后,遍历可执行内存区域上的中央处理器指令,并用指令替换 syscall/sysenter指令。
优选的,蹦床代码和用户空间程序的代码的存储区域在该设置阶段被配置为可写,并且在设置过程退出之前将它们恢复为不可写;设置完成后,用户空间程序的主函数照常启动,实现相应的挂钩操作。
优选的,通过利用dlmopen函数解决钩子函数在调用重写前原本就是要执行syscall/sysenter 的函数时会陷入无限循环的问题,因为替换的指令将执行流程带回到了钩子函数;为了使用 dlmopen 函数,假设用户将钩子函数构建为共享库,在设置阶段,专用共享库使用dlmopen函数在钩子函数专用的命名空间中加载该共享库文件,并使用dlsym函数获取指向钩子函数核心实现的指针,在专用命名空间中加载的共享库中实现的钩子函数可以通过获得的钩子函数核心实现的指针来调用,从而避免不必要的自动关联,进而避免陷入无限循环。
优选的,NULL指针访问终止如下:
终止NULL的读取和写入:为了终止NULL读写,将蹦床代码配置为仅可执行内存;尝试对配置为仅可执行的内存进行读/写访问的用户空间程序将因故障而被内核终止;
终止 NULL执行:为了捕获非故意的NULL执行动作,需要收集syscall/sysenter的虚拟地址,syscall/sysenter的虚拟地址在设置阶段被替换,并在钩子函数的入口点检查钩子函数的调用者是否是被替换的虚拟地址之一;如果不是,终止用户空间程序,如果是执行钩子函数。
优选的,为了维护替换的虚拟地址,同时实现低开销的NULL执行检查,使用覆盖x86-64CPU中常见的整个256TB虚拟地址范围的位图,位图允许通过一些位操作来执行NULL 执行检查。
一种电子设备,包括:处理器、存储器及存储在所述存储器上并可在所述处理器上运行的计算机程序,所述计算机程序被所述处理器执行时实现本申请所述的系统调用挂钩方法的步骤。
一种计算机可读存储介质,所述计算机可读存储介质上存储有计算机程序,所述计算机程序被处理器执行时实现本申请所述的系统调用挂钩方法的步骤。
与现有技术相比,本申请有益效果如下:
通过与现有钩子机制的比较来评估本专利提出的方法,特别是,量化了本专利提出方法的挂钩操作开销,以及由本专利提出的方法绑定的应用程序和用户空间操作系统子系统所经历的性能损失。
相较于基于ptrace、Syscall User Dispatch(SUD)以及int3信令等技术的系统调用钩子技术,本专利实现的基于二进制重写的x86-64架构系统调用低耗费挂钩方法具有一下优势:
(1)比基于ptrace的技术快100倍。
(2)可实现对系统调用的100%覆盖挂钩,即可以通过穷举所有的系统调用实现挂钩操作。
(3)不需要改动用户空间程序的源代码。
(4)无需更改操作系统内核,也无需内核模块。
附图说明
图1为本申请流程图。
图2为本申请具体实施方式图。
图3为钩子函数示意图。
图4为在HTTP服务器实验效果图。
图5为在Redis服务器实验效果图。
具体实施方式
下面将结合本申请实施例中的附图,对本申请实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例是本申请一部分实施例,而不是全部的实施例。基于本申请中的实施例,本领域普通技术人员在没有做出创造性劳动前提下所获得的所有其他实施例,都属于本申请保护的范围。
本专利实现的实际是一种挂钩方法,来实现对操作系统内核的所有函数的挂钩机制。
钩子函数这个称呼是很多开发语言中都会涉及到的一个东西,它是系统处理消息时预先设置好的一个函数,如图3所示。
钩子函数:
(1)是个函数,在系统消息触发时被系统调用;
(2)不是用户自己触发的;
(3)使用时直接编写函数体;
钩子函数的名称是确定的,当系统消息触发,自动会调用。
挂钩子(Hooking):
通过重写钩子函数或在目标软件(操作系统层的软件和用户软件)中设置触发条件,来激活钩子函数的过程,叫挂钩子(Hooking)。
也可以这么描述:通过拦截软件模块间的函数调用、消息传递、事件传递来修改或扩展操作系统、应用程序或其他软件组件的行为的各种技术,也叫做钩子编程(Hooking)。
处理被拦截的函数调用、事件、消息的代码,被称为钩子(hook),即钩子函数。
蹦床功能与蹦床代码:
挂钩子过程中,需要在不破坏被挂钩程序执行稳定性的前提下实现,即不能因为向被挂钩程序的内存中植入代码而引起被挂钩程序崩溃,这会造成挂钩失败,所以就需要对目标程序的内存存储情况进行研究,根据程序的内存布局进行修改调整,从而将被挂钩程序的执行流程安全、稳定地引导到钩子函数上,这个功能被形象化地成为“蹦床”功能;其中,在程序内存中修改的代码被称作蹦床代码。
蹦床只是生成的一段代码,它复制原始API的前几个字节的功能然后用定制的跳转功能覆盖它,并在覆盖的字节之后跳转到钩子函数的API。
一种基于二进制重写的系统调用挂钩方法,包括以下步骤:
S1.操作系统的环境配置:
(1)设置操作系统环境变量:在Linux系统环境变量中,将LD_PRELOAD的值设置为专用共享库的路径;
(2)在Linux系统环境变量中增加自定义环境变量,并将其设置为钩子函数库的路径。
(3)配置系统参数,将虚拟地址0设为可用;
S2.蹦床代码的设置:在虚拟地址0处分配内存,用nop指令序列和跳转代码填充分配的内存空间;
S3.二进制重写:获取内存映射信息,遍历内存上的指令,进行指令替换操作,完成二进制重写;
二进制重写在专用共享库中实现,在用户空间程序的主函数启动之前执行设置过程;
专用共享库在通过LD_PRELOAD机制加载并在动态链接应用程序二进制文件时使用,LD_PRELOAD允许专用共享库在用户空间程序的主函数启动之前运行设置过程。
蹦床代码设置过程首先使用 mmap 系统调用在虚拟地址 0 处分配内存。然后,它用 nop 指令序列和跳转代码填充分配的内存区域。
二进制重写过程首先利用procfs文件系统获取内存映射信息;然后,遍历可执行内存区域上的中央处理器指令,并用指令替换syscall/sysenter指令。
蹦床代码和用户空间程序的代码的存储区域在该设置阶段被配置为可写,并且在设置过程退出之前将它们恢复为不可写。设置完成后,用户空间程序的主函数照常启动,实现相应的挂钩操作。
S4.加载钩子函数库:加载库文件,并为其指定新的命名空间;获取指向钩子函数核心实现的指针,挂载调用钩子函数。
通过利用dlmopen函数解决钩子函数在调用重写前原本就是要执行 syscall/sysenter 的函数时会陷入无限循环的问题,因为替换的指令()将执行流程带回到了钩子函数。为了使用 dlmopen 函数,假设用户将钩子函数构建为共享库,在设置阶段,专用共享库使用dlmopen函数在钩子函数专用的命名空间中加载该共享库文件,并使用dlsym函数获取指向钩子函数核心实现的指针,在专用命名空间中加载的共享库中实现的钩子函数可以通过获得的钩子函数核心实现的指针来调用,从而避免不必要的自动关联,进而避免陷入无限循环。
NULL指针访问终止如下:
终止NULL的读取和写入:为了终止NULL读写,将蹦床代码配置为仅可执行内存;尝试对配置为仅可执行的内存进行读/写访问的用户空间程序将因故障而被内核终止;
终止NULL执行:为了捕获非故意的NULL执行动作,需要收集syscall/sysenter的虚拟地址,syscall/sysenter的虚拟地址在设置阶段被替换,并在钩子函数的入口点检查钩子函数的调用者是否是被替换的虚拟地址之一;如果不是,终止用户空间程序,如果是执行钩子函数。
为了维护替换的虚拟地址,同时实现低开销的NULL执行检查,使用覆盖x86-64CPU中常见的整个256TB虚拟地址范围的位图,位图允许通过一些位操作来执行 NULL执行检查。
一种电子设备,包括:处理器、存储器及存储在所述存储器上并可在所述处理器上运行的计算机程序,所述计算机程序被所述处理器执行时实现本申请的系统调用挂钩方法的步骤。
一种计算机可读存储介质,所述计算机可读存储介质上存储有计算机程序,所述计算机程序被处理器执行时实现本申请的系统调用挂钩方法的步骤。
本发明实现的方法如图2所示,其中阴影部分为蹦床代码部分。其中:
1)系统调用和调用约定方面:本专利实现的方法遵循系统调用的调用约定。在x86-64CPU上的类UNIX系统中,当用户空间程序执行syscall/sysenter时,上下文会切换到内核,然后调用预先配置的系统调用处理程序。为了请求内核执行特定的系统调用,用户空间程序在触发系统调用之前将系统调用号(例如,在x86-64CPU上的Linux中,0表示读取,1表示写入,2表示打开)设置到rax寄存器,而在内核中,系统调用处理程序根据rax寄存器的值执行其中一个系统调用。
2)二进制重写方面:为了挂钩系统调用,本专利实现的方法将syscall/sysenter指令替换为指令,在操作码中由两个字节0xFF 0xD0表示。由于syscall/sysenter和/>的指令大小是相同的两个字节,因此替换不会破坏临近的其他指令。/>的作用是将当前指令指针(调用者的地址)压入堆栈,并跳转到rax寄存器中存储的地址。根据调用约定,rax寄存器始终有一个系统调用号。因此,/>的结果是跳转到0到最大系统调用号(大约为500)之间的虚拟地址。
3)蹦床代码方面:为了将执行流程重定向到用户定义的钩子函数,本发明实现的方法在虚拟地址0处实例化设置了蹦床代码;在蹦床代码中,0到最大系统调用数之间的虚拟地址范围被单字节nop指令(0x90)填充,并且在最后一个nop指令的旁边,放置有一段跳转到特定钩子的代码函数。
4)执行流程方面:在蹦床代码实例化和二进制重写完成后,重写的部分()将跳转到蹦床代码中的nop序列之中,同时将调用者的地址压入堆栈。执行流程会向下滑动到后续的nop指令中;执行完最后一个nop后,跳转到钩子函数。此时,钩子函数将具有与内核空间系统调用处理程序相同的寄存器状态。钩子函数在返回时将跳转回压入栈中的调用者地址。
5)安全方面相关说明:与其他基于二进制重写的系统调用钩子机制一样,本专利实现的方法本身并不提供安全增强功能。如果用户希望提高应用系统的安全性,可以采用现有的机制。
实验测试
1.实验设置
为了进行评估实验,我们使用两台机器;每台都有两个主频为2.90GHz的16核Intel Xeon Gold 6326 CPU和128 GB DRAM。两台机器通过Mellanox ConnectX-5 100Gbps NIC 直接连接。我们使用两台计算机中的一台作为服务器计算机,另一台作为客户端计算机。两台机器都运行Linux5.15。
2.评估比较对象
我们将本专利提出的方法与基于ptrace的方法、基于int3信令的方法、基于SUD的方法和基于LD_PRELOAD的方法进行比较。以下是对几种技术机制的简要介绍:
(1)ptrace:
类 UNIX 操作系统提供ptrace系统调用,使跟踪器进程能够挂钩被跟踪进程的系统调用过程。由于ptrace是一个内核功能,因此可以借助它对系统调用进行细粒度的挂钩操作。然而,由于跟踪器和被跟踪者之间的上下文切换,该方法的挂钩开销是巨大的;跟踪器在被跟踪器运行时休眠,而被跟踪器在跟踪器运行其钩子函数期间休眠。因此,在每次系统调用被调用时,被跟踪者都会经历很长的延迟,其中包括跟踪器的唤醒时间、钩子函数的执行时间以及被跟踪者的唤醒时间。
此延迟会导致在被跟踪者上运行的用户空间程序的性能显着下降。
(2)int3信令:
int3信令是调用软件中断的单字节指令(0xcc)。在Linux上,内核处理它并向执行int3的用户空间进程发出SIGTRAP信号。int3信令技术利用这种行为来挂钩系统调用;它用int3信令替换syscall/sysenter并使用SIGTRAP的信号处理程序作为钩子函数。由于 int3信令是一个字节,因此它可以替换任意指令而不破坏临近的其他指令。这种技术传统上用于调试器中以实现断点。然而,信号处理会带来很大的开销,因为它涉及内核的上下文操作。
(3)系统调用用户调度(SUD):
Linux5.11中添加了系统调用用户调度方法(SUD),它提供了一种将系统调用重定向到任意用户空间代码的方法。对于SUD功能,内核在系统调用的入口点实现了一个钩子点。用户空间进程可以通过prctl函数接口激活 SUD。当SUD被激活时,挂钩点向用户空间进程发出SIGSYS信号。此机制允许用户空间程序利用SIGSYS信号处理程序作为系统调用挂钩。然而,与int3信令技术类似,由于信号处理的开销,SUD对用户空间程序造成了显着的性能损失。
(4)基于LD_PRELOAD的函数调用替换:
动态链接器/加载器(ld.so)提供 LD_PRELOAD功能,允许用户在程序的主要部分启动之前指定要加载的共享对象,并且它可用于有选择地覆盖在其他共享对象中实现的函数调用。用户可以利用此机制用任意函数调用替换通常在标准库中实现的系统调用包装函数。LD_PRELOAD 的性能损失非常小,因为钩子是通过函数指针替换来应用的。
函数调用挂钩不是系统调用挂钩。然而,准确地说,系统调用包装函数的函数调用替换并不是系统调用的挂钩;而是系统调用的钩子。首先,syscall和sysenter指令不与任何函数调用直接关联,并且LD_PRELOAD无法挂钩没有专用和导出包装函数的syscall/sysenter指令。
LD_PRELOAD挂钩子失败的情况。glibc是一个代表性示例,其中 LD_PRELOAD无法彻底应用系统调用挂钩。在很多情况下,glibc并不使用众所周知的系统调用包装函数来调用系统调用;相反,glibc直接将syscall/sysenter嵌入到其内部函数中,这些函数从glibc外部标记为不可见,并且LD_PRELOAD无法将钩子应用于由此类内部函数调用包装的syscall/sysenter指令。
尽管用户可以通过完全替换包含syscall/sysenter指令的库调用来使用LD_PRELOAD应用挂钩,但这种方法无法扩展,因为用户必须放弃使用原始库调用实现;换句话说,他们需要自己重新实现glibc等效的功能,但是重新实现大部分glibc是不现实的。此外,与glibc不同,如果共享库文件的源代码不可用,则无法应用此重新实现方法。
基于LD_PRELOAD方法的限制。简而言之,LD_PRELOAD 无法彻底挂钩系统调用,因此,不是将用户空间操作系统子系统应用于现有用户空间程序的适当选项;例如,如果系统调用未正确挂钩,则由用户空间操作系统子系统打开的文件描述符将被传递到内核空间操作系统子系统,并导致系统出现意外行为。
与二进制重写技术相似之处。我们注意到,在我们的评估实验中,其他二进制重写技术的情况由LD_PRELOAD情况代表表示,因为它们具有相同的特征:它们性能开销非常小,但他们无法彻底地实现系统调用的全面挂钩操作。
3.系统调用挂钩开销
我们通过测量挂钩getpid这一系统调用函数(最简单的系统调用之一)的时间来量化系统调用挂钩开销。我们在这里主要感兴趣的是挂钩操作开销本身;为了避免跨内核系统调用的开销,我们使用一个钩子函数来返回一个虚拟值,而不实际执行getpid系统调用。结果如表1所示。
表1 挂钩一个系统调用的开销
挂钩机制 | 时间(ns) |
Ptrace | 31201 |
int3信令 | 1342 |
SUD | 1156 |
本方法 | 41 |
LD_PRELOAD | 6 |
4.用户空间操作系统子系统性能
本节我们评估本专利提供的方法如何影响用户空间操作系统子系统支持的应用程序的性能;我们采用本专利提出的方法和前述内容中描述的现有钩子机制来透明地将由数据平面开发套件(DPDK)支持的可移植TCP/IP堆栈lwIP应用到简单的HTTP服务器和Redis上。通常,绕过内核的lwIP可以获得比Linux内核TCP/IP堆栈更高的网络性能;作为参考,我们使用Linux的内核TCP/IP堆栈运行相同的基准测试,并通过图4和图5中的水平线标示其性能。我们注意到,选择简单的HTTP服务器和Redis进行实验是因为LD_PRELOAD可以对它们应用钩子,并且前述内容所述,LD_PRELOAD可能无法挂钩其他系统中的系统调用。
简单的HTTP服务器。通常,当服务器程序的应用程序逻辑变得更轻时,它会更频繁地触发与网络相关的系统调用,因为它可以在短时间内处理大量请求。为了强调钩子机制与轻量级应用逻辑,我们制作了一个简单的HTTP服务器程序来回复静态的64字节内容;我们在服务器上运行它。作为基准测试客户端,我们在客户端机器上运行通用的性能测试工具wrk;它通过32个持久并发连接发送请求。结果如图4所示。首先,LD_PRELOAD结果代表最高吞吐量性能情况,它比Linux内核TCP/IP堆栈快5.2倍,其(Linux内核TCP/IP堆栈实现)吞吐量由图4中非虚线水平线显示。与LD_PRELOAD 情况的比较揭示了每个钩子机制的运行开销情况。与LD_PRELOAD相比,ptrace、int3信令和SUD的性能下降百分比分别为98.9%、85.3%和83.0%。而本专利实现的方法仅导致12.7%的性能下降。这些结果通过表1中所示的钩子开销进行解释。
Redis。我们评估实际应用场景中常用的Redis程序在本专利实现的方法上的执行情况。对于基准测试,我们使用Redis,这是一种广泛使用的键值存储程序;我们在服务器计算机上运行Redis服务器进程。作为基准测试客户端,我们在客户端计算机上使用redis-benchmark,它作为Redis源的一部分进行分发;我们运行GET100%工作负载,以便Redis服务器将大部分时间花在网络操作而不是磁盘操作上。请求通过32个持久并发连接发送。图5显示了与简单HTTP服务器实验类似的趋势,总体结果反映了表1所示的开销。与LD_PRELOAD相比,ptrace、int3信令和SUD的吞吐量结果分别出现98.8%、75.0%和72.3%的性能降低。相比之下,本专利实现的方法仅降低了5.2%的吞吐量。
以上所述,仅为本申请的具体实施方式,但本申请的保护范围并不局限于此,任何熟悉本技术领域的技术人员在本申请揭露的技术范围内,可轻易想到变化或替换,都应涵盖在本申请的保护范围之内。因此,本申请的保护范围应以权利要求的保护范围为准。
Claims (10)
1.一种基于二进制重写的系统调用挂钩方法,其特征在于,包括以下步骤:
S1.操作系统的环境配置:配置系统环境变量,将虚拟地址0设为可用;
S2.蹦床代码的设置:在虚拟地址0处分配内存,用nop指令序列和跳转代码填充分配的内存空间;
S3.二进制重写:获取内存映射信息,遍历内存上的指令,进行指令替换操作,完成二进制重写;
S4.加载钩子函数库:加载库文件,并为其指定新的命名空间;获取指向钩子函数核心实现的指针,挂载调用钩子函数。
2.根据权利要求1所述的一种基于二进制重写的系统调用挂钩方法,其特征在于,操作系统环境配置还包括:
(1)设置操作系统环境变量:在Linux系统环境变量中,将LD_PRELOAD的值设置为专用共享库的路径;
(2)在Linux系统环境变量中增加自定义环境变量,并将其设置为钩子函数库的路径。
3.根据权利要求2所述的一种基于二进制重写的系统调用挂钩方法,其特征在于,蹦床代码和二进制重写在专用共享库中实现,在用户空间程序的主函数启动之前执行设置过程;
专用共享库在通过LD_PRELOAD机制加载并在动态链接应用程序二进制文件时使用,LD_PRELOAD允许专用共享库在用户空间程序的主函数启动之前运行设置过程。
4.根据权利要求3所述的一种基于二进制重写的系统调用挂钩方法,其特征在于,蹦床代码设置过程首先使用 mmap 系统调用在虚拟地址 0 处分配内存;然后,它用 nop 指令序列和跳转代码填充分配的内存区域;
蹦床代码和用户空间程序的代码的存储区域在该设置阶段被配置为可写,并且在设置过程退出之前将它们恢复为不可写;设置完成后,用户空间程序的主函数照常启动,实现相应的挂钩操作。
5.根据权利要求3所述的一种基于二进制重写的系统调用挂钩方法,其特征在于,二进制重写过程首先利用procfs文件系统获取内存映射信息;然后,遍历可执行内存区域上的中央处理器指令,并用指令替换 syscall/sysenter指令。
6.根据权利要求1所述的一种基于二进制重写的系统调用挂钩方法,其特征在于,通过利用dlmopen函数解决钩子函数在调用重写前原本就是要执行 syscall/sysenter 的函数时会陷入无限循环的问题,因为替换的指令将执行流程带回到了钩子函数;为了使用 dlmopen 函数,假设用户将钩子函数构建为共享库,在设置阶段,专用共享库使用dlmopen函数在钩子函数专用的命名空间中加载该共享库文件,并使用dlsym函数获取指向钩子函数核心实现的指针,在专用命名空间中加载的共享库中实现的钩子函数可以通过获得的钩子函数核心实现的指针来调用,从而避免不必要的自动关联,进而避免陷入无限循环。
7.根据权利要求1所述的一种基于二进制重写的系统调用挂钩方法,其特征在于,NULL指针访问终止如下:
终止NULL的读取和写入:为了终止NULL读写,将蹦床代码配置为仅可执行内存;尝试对配置为仅可执行的内存进行读/写访问的用户空间程序将因故障而被内核终止;
终止 NULL执行:为了捕获非故意的NULL执行动作,需要收集syscall/sysenter的虚拟地址,syscall/sysenter的虚拟地址在设置阶段被替换,并在钩子函数的入口点检查钩子函数的调用者是否是被替换的虚拟地址之一;如果不是,终止用户空间程序,如果是执行钩子函数。
8.根据权利要求7所述的一种基于二进制重写的系统调用挂钩方法,其特征在于,为了维护替换的虚拟地址,同时实现低开销的NULL执行检查,使用覆盖x86-64CPU中整个256TB虚拟地址范围的位图,位图允许通过相关位操作来执行 NULL 执行检查。
9.一种电子设备,其特征在于,包括:处理器、存储器及存储在所述存储器上并可在所述处理器上运行的计算机程序,所述计算机程序被所述处理器执行时实现如权利要求1至7之中任一项所述的系统调用挂钩方法的步骤。
10.一种计算机可读存储介质,其特征在于,所述计算机可读存储介质上存储有计算机程序,所述计算机程序被处理器执行时实现如权利要求1至7之中任一项所述的系统调用挂钩方法的步骤。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202311481604.8A CN117215811A (zh) | 2023-11-09 | 2023-11-09 | 一种基于二进制重写的系统调用挂钩方法、设备及介质 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202311481604.8A CN117215811A (zh) | 2023-11-09 | 2023-11-09 | 一种基于二进制重写的系统调用挂钩方法、设备及介质 |
Publications (1)
Publication Number | Publication Date |
---|---|
CN117215811A true CN117215811A (zh) | 2023-12-12 |
Family
ID=89049659
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN202311481604.8A Pending CN117215811A (zh) | 2023-11-09 | 2023-11-09 | 一种基于二进制重写的系统调用挂钩方法、设备及介质 |
Country Status (1)
Country | Link |
---|---|
CN (1) | CN117215811A (zh) |
Citations (3)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN101278260A (zh) * | 2005-06-07 | 2008-10-01 | Vm软件股份有限公司 | 使软件程序免于弱点和攻击的约束注入系统 |
US9448788B1 (en) * | 2014-01-22 | 2016-09-20 | SecondWrite LLC | Binary rewriting system |
CN115795486A (zh) * | 2023-02-07 | 2023-03-14 | 山东大学 | 基于二进制重写的故障注入防护方法 |
-
2023
- 2023-11-09 CN CN202311481604.8A patent/CN117215811A/zh active Pending
Patent Citations (3)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN101278260A (zh) * | 2005-06-07 | 2008-10-01 | Vm软件股份有限公司 | 使软件程序免于弱点和攻击的约束注入系统 |
US9448788B1 (en) * | 2014-01-22 | 2016-09-20 | SecondWrite LLC | Binary rewriting system |
CN115795486A (zh) * | 2023-02-07 | 2023-03-14 | 山东大学 | 基于二进制重写的故障注入防护方法 |
Non-Patent Citations (2)
Title |
---|
YASUKATA, K: "zpoline: a system call hook mechanism based on binary rewriting", 《USENIX ANNUAL TECHNICAL CONFERENCE (USENIX ATC)》, pages 293 - 300 * |
马梦雨;陈李维;孟丹;: "内存数据污染攻击和防御综述", 信息安全学报, no. 04 * |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
US10489168B2 (en) | Ensuring determinism during programmatic replay in a virtual machine | |
US10585796B2 (en) | Ensuring determinism during programmatic replay in a virtual machine | |
US9514029B2 (en) | Partial recording of a computer program execution for replay | |
US10824716B2 (en) | Executing native-code applications in a browser | |
Saito | Jockey: a user-space library for record-replay debugging | |
US7661035B2 (en) | Method and system for instruction tracing with enhanced interrupt avoidance | |
US6779187B1 (en) | Method and system for dynamic interception of function calls to dynamic link libraries into a windowed operating system | |
Skaletsky et al. | Dynamic program analysis of microsoft windows applications | |
Chow et al. | Multi-stage replay with crosscut | |
US20050268290A1 (en) | Method and system for metering execution of interpreted programs | |
Maier et al. | Unicorefuzz: On the viability of emulation for kernelspace fuzzing | |
WO2010045317A1 (en) | Internal function debugger | |
US20060277371A1 (en) | System and method to instrument references to shared memory | |
US11366740B2 (en) | Debugging shared memory errors | |
Kang | Function call interception techniques | |
Ruan et al. | Analyzing android application in real-time at kernel level | |
CN117215811A (zh) | 一种基于二进制重写的系统调用挂钩方法、设备及介质 | |
US6738976B1 (en) | Method, system, and apparatus to minimize exception handling overhead from invoked functions | |
Harper‐Cyr et al. | Fast and flexible tracepoints in x86 | |
Ho et al. | On the design of a pervasive debugger | |
CN110119615B (zh) | 一种安卓日志防泄漏的控制方法、装置和计算机设备 | |
Oyama et al. | Forced continuation of malware execution beyond exceptions | |
CN117150487A (zh) | 一种动态链接库文件注入检测方法及装置 | |
CN118034915A (zh) | 一种在计算机程序中引入钩子的方法、装置、系统 | |
RU2390831C1 (ru) | Способ динамической инструментации |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
PB01 | Publication | ||
PB01 | Publication | ||
SE01 | Entry into force of request for substantive examination | ||
SE01 | Entry into force of request for substantive examination |