一种未导出的函数地址和数据结构偏移的获取方法及装置转让专利

申请号 : CN201510881945.3

文献号 : CN105550575B

文献日 :

基本信息:

PDF:

法律信息:

相似专利:

发明人 : 刘业欣刘海霞

申请人 : 北京神州绿盟信息安全科技股份有限公司北京神州绿盟科技有限公司

摘要 :

本发明公开了一种未导出的函数地址和数据结构偏移的获取方法及装置,用以实现未导出的函数地址和数据结构偏移的自动获取,以解决现有技术中靠人工获取未导出的函数地址和数据结构偏移所造成的人力浪费问题,同时提高系统的支持效率。其中,所述方法包括:当待监控系统的内核执行到断点时,调用控制函数,通过所述控制函数找出与所述指定函数存在访问关系的所述未导出的函数地址和/或数据结构偏移的函数,获取所述未导出的函数地址和/或数据结构偏移的函数的数据属性;其中所述数据属性是所述未导出的函数地址和/或数据结构偏移的属性信息;所述内核根据所述数据属性,确定所述未导出的函数地址和/或数据结构偏移。

权利要求 :

1.一种未导出的函数地址和数据结构偏移的获取方法,其特征在于,所述方法包括:在从待监控系统的内核文件直接获取到的地址中选择合适的地址作为固定点;所述合适的地址为所述内核文件中的入口地址、导出的函数或数据地址或中断表中的地址;

从待监控系统的内核文件中找出与所述未导出的函数地址和/或数据结构偏移的函数存在访问关系的指定函数,并在所述固定点处将所述指定函数的地址设置为断点;

当待监控系统的内核执行到所述断点时,调用控制函数,通过所述控制函数找出与所述指定函数存在访问关系的所述未导出的函数地址和/或数据结构偏移的函数,获取所述未导出的函数地址和/或数据结构偏移的函数的数据属性;其中所述数据属性是所述未导出的函数地址和/或数据结构偏移的属性信息;

所述内核根据所述数据属性,确定所述未导出的函数地址和/或数据结构偏移。

2.如权利要求1所述的方法,其特征在于,所述并在所述固定点处将所述指定函数的地址设置为断点,包括:在所述固定点处将所述指定函数地址设置为代码执行断点和/或数据读写断点。

3.如权利要求2所述的方法,其特征在于,所述数据读写断点为从所述断点位置开始到预设长度结束的内存区域中的区域性断点。

4.如权利要求2所述的方法,其特征在于,所述方法具体包括:

在从待监控系统的内核文件直接获取到的地址中选择合适的地址作为固定点;所述合适的地址为所述内核文件中的入口地址、导出的函数或数据地址或中断表中的地址;

从待监控系统的内核文件中找出与所述未导出的函数地址的函数存在访问关系的指定函数,并在所述固定点处将所述指定函数的地址设置为代码执行断点和/或数据读写断点;

当待监控系统的内核执行到所述代码执行断点和/或数据读写断点时,调用所述控制函数,通过所述控制函数找出与所述指定函数存在访问关系的所述未导出的函数地址的函数,获取所述未导出的函数地址的函数的数据属性;

所述内核根据所述未导出的函数地址的函数的数据属性,确定所述未导出的函数地址;

从待监控系统的内核文件中找出与所述未导出的数据偏移结构的函数存在访问关系的指定函数,并在新的固定点上将该指定函数的地址设置为代码执行断点和/或数据读写断点;

当待监控系统的内核执行到所述代码执行断点和/或数据读写断点时,调用所述控制函数,通过所述控制函数找出与所述指定函数存在访问关系的所述未导出的数据结构偏移的函数,获取所述未导出的数据结构偏移的函数的数据属性;

所述内核根据所述未导出的数据结构偏移的函数的数据属性,确定所述未导出的数据结构偏移。

5.如权利要求4所述的方法,其特征在于,在新的固定点上设置代码执行断点和/或数据读写断点之前,所述方法还包括:将找出的所述未导出的函数地址作为新的固定点。

6.如权利要求2~5任一权项所述的方法,其特征在于,所述方法还包括:采用传统断点调试技术或虚拟机技术实现代码执行断点和数据读写断点。

7.一种未导出的函数地址和数据结构偏移的获取装置,其特征在于,所述装置包括:设置模块,用于在从待监控系统的内核文件直接获取到的地址中选择合适的地址作为固定点;以及,从待监控系统的内核文件中找出与所述未导出的函数地址和/或数据结构偏移的函数存在访问关系的指定函数,并在所述固定点处将所述指定函数的地址设置为断点;所述合适的地址为所述内核文件中的入口地址、导出的函数或数据地址或中断表中的地址;

触发模块,用于当待监控系统的内核执行到所述断点时,调用控制函数,通过所述控制函数找出与所述指定函数存在访问关系的所述未导出的函数地址和/或数据结构偏移的函数,获取所述未导出的函数地址和/或数据结构偏移的函数的数据属性;其中所述数据属性是所述未导出的函数地址和/或数据结构偏移的属性信息;

获取模块,用于根据所述数据属性,确定所述未导出的函数地址和/或数据结构偏移。

8.如权利要求7所述的装置,其特征在于,所述断点包括代码执行断点和/或数据读写断点;

其中所述数据读写断点是从设置数据读写断点初始位置起始到预设长度结束的内存区域中的区域性断点。

9.如权利要求8所述的装置,其特征在于,

所述触发模块,具体用于当待监控系统的内核执行到所述代码执行断点和/或数据读写断点时,调用所述控制函数,通过所述控制函数找出与所述指定函数存在访问关系的所述未导出的函数地址的函数,获取所述未导出的函数地址的函数的数据属性;以及,当待监控系统的内核执行到所述代码执行断点和/或数据读写断点时,调用所述控制函数,通过所述控制函数找出与所述指定函数存在访问关系的所述未导出的数据结构偏移的函数,获取所述未导出的数据结构偏移的函数的数据属性;

所述获取模块,具体用于根据所述未导出的函数地址的函数的数据属性,确定所述未导出的函数地址;以及,根据所述未导出的数据结构偏移的函数的数据属性,确定所述未导出的数据结构偏移。

10.如权利要求9所述的装置,其特征在于,所述设置模块还用于:将找出的所述未导出的函数地址作为新的固定点。

说明书 :

一种未导出的函数地址和数据结构偏移的获取方法及装置

技术领域

[0001] 本发明涉及网络安全技术,特别涉及一种未导出的函数地址和数据结构偏移的获取方法及装置。

背景技术

[0002] 基于虚拟机的软件监控技术是利用虚拟机技术,以实现在最底层对操作系统中的进程、线程、模块、文件、网络等行为进行监控。利用该技术,我们就可以针对各种对操作系统产生的危害可以进行分析处理了。但基于虚拟机的软件监控技术基本上要依赖于特定的操作系统,如特定的操作种类(Windows,Linux),特定的版本(Windows XP/7,Debian 7/8),特定的内核编译选项等等约束。
[0003] 目前,基于虚拟机的软件监控技术一般有如下几种方式:纯用户态的软件监控技术、基于驱动程序的软件监控技术、基于代理程序和虚拟机结合的软件监控技术和纯虚拟机的软件监控技术。其中,纯虚拟机的软件监控技术对监控的目标程序完全透明,目标程序无法知道监控机制的存在,而且还可以做全系统监控,从用户态到内核态,所有进程、线程、指令等都能实现监控;而且,此技术完全在虚拟机层面来实现对内部的操作系统进行监控,不需要借助操作系统的任何代理程序即可完成监控而成为主要的监控方式,基于上述各种优点,使得纯虚拟机的软件监控技术成为目前监控的主要方式。但是,该利用纯虚拟机的软件监控技术进行监控时,必须要知道被监控操作系统的内部关键函数的位置和关键数据结构的定义,否则无法从操作系统外层来区分哪些数据是描述进程对象的,哪些数据是描述文件对象的。因此要实现这种监控技术,首先要明确被监控的操作系统的种类,版本等各种信息,通过操作系统的关键文件(例如内核文件),自动或者人工的分析出关键的函数位置和关键的数据结构定义。比如Windows系统,可以通过内核文件的PDB文件,来获取关键函数和关键数据结构。这个可以使用程序自动化完成。如果是Linux系统,一般情况下,Linux系统的内核文件内部有一段符号信息。虽然这些符号信息可以定位某些关键函数(但并非所有),但符号信息中不包含数据结构的信息。Linux数据结构信息虽然在源代码里都有,但不同的版本很多都是有差异的,即便是同一个版本,不同的编译选项,也会造成数据结构的差异,对于这些差异,现有技术基本上只能是支持已知版本,已知编译选项的Linux系统的监控。对于未知版本,未知编译选项,只能靠人工逆向的方式来确定,这样很浪费人力和时间。

发明内容

[0004] 本发明实施例提供了一种未导出的函数地址的获取方法及装置,用以实现未导出的函数地址的自动获取,以解决现有技术中靠人工获取未导出的函数地址所造成的人力浪费问题,同时提高系统支持效率。
[0005] 本发明实施例提供了一种未导出的函数地址和数据结构偏移的获取方法,所述方法包括:
[0006] 在从待监控系统的内核文件直接获取到的地址中选择合适的地址作为固定点;
[0007] 从待监控系统的内核文件中找出与所述未导出的函数地址和/或数据结构偏移的函数存在访问关系的指定函数,并在所述固定点处将所述指定函数的地址设置为断点;
[0008] 当待监控系统的内核执行到所述断点时,调用控制函数,通过所述控制函数找出与所述指定函数存在访问关系的所述未导出的函数地址和/或数据结构偏移的函数,获取所述未导出的函数地址和/或数据结构偏移的函数的数据属性;其中所述数据属性是所述未导出的函数地址和/或数据结构偏移的属性信息;
[0009] 所述内核根据所述数据属性,确定所述未导出的函数地址和/或数据结构偏移。
[0010] 本发明实施例提供的方法中,通过选择固定点,并在所述固定点上设置断点,当所述待监控系统的内核执行到所述断点时,调用控制函数,通过所述控制函数找出与所述指定函数存在访问关系的所述未导出的函数地址和/或数据结构偏移的函数,获取所述未导出的函数地址和/或数据结构偏移的函数的数据属性;其中所述数据属性是所述未导出的函数地址和/或数据结构偏移的属性信息;所述内核根据所述数据属性,确定所述未导出的函数地址和/或数据结构偏移。这样,不需要知道系统的版本和编译选项,也能够实现未导出的函数地址的自动获取,解决了现有技术中靠人工获取未导出的函数地址所造成的人力浪费问题。并且,通过该方法还可以大大提高实际运行的操作系统的支持效率,节省人力成本和时间。
[0011] 较佳的,所述并在所述固定点处将所述指定函数的地址设置为断点,包括:
[0012] 在所述固定点处将所述指定函数地址设置为代码执行断点和/或数据读写断点。
[0013] 较佳的,所述数据读写断点为从所述断点位置开始到预设长度结束的内存区域中的区域性断点。
[0014] 较佳的,所述方法具体包括:
[0015] 在从待监控系统的内核文件直接获取到的地址中选择合适的地址作为固定点;
[0016] 从待监控系统的内核文件中找出与所述未导出的函数地址的函数存在访问关系的指定函数,并在所述固定点处将所述指定函数的地址设置为码执行断点和/或数据读写断点;
[0017] 当待监控系统的内核执行到所述码执行断点和/或数据读写断点时,调用所述控制函数,通过所述控制函数找出与所述指定函数存在访问关系的所述未导出的函数地址的函数,获取所述未导出的函数地址的函数的数据属性;
[0018] 所述内核根据所述未导出的函数地址的函数的数据属性,确定所述未导出的函数地址;
[0019] 从待监控系统的内核文件中找出与所述未导出的数据偏移结构的函数存在访问关系的指定函数,并在新的固定点上将该指定函数的地址设置为代码执行断点和/或数据读写断点;
[0020] 当待监控系统的内核执行到所述代码执行断点和/或数据读写断点时,调用所述控制函数,通过所述控制函数找出与所述指定函数存在访问关系的所述未导出的数据结构偏移的函数,获取所述未导出的数据结构偏移的函数的数据属性;
[0021] 所述内核根据所述未导出的数据结构偏移的函数的数据属性,确定所述未导出的数据结构偏移。
[0022] 较佳的,在所述在新的固定点上设置代码执行断点和/或数据读写断点之前,所述方法还包括:将所述找出的未导出的函数地址作为新的固定点。
[0023] 较佳的,所述方法还包括:采用传统断点调试技术或虚拟机技术实现代码执行断点和数据读写断点。
[0024] 基于同一发明构思,本发明实施例还提供了一种未导出的函数地址和数据结构偏移的获取装置,所述装置包括:
[0025] 设置模块,用于在从待监控系统的内核文件直接获取到的地址中选择合适的地址作为固定点;以及,从待监控系统的内核文件中找出与所述未导出的函数地址和/或数据结构偏移的函数存在访问关系的指定函数,并在所述固定点处将所述指定函数的地址设置为断点;
[0026] 触发模块,用于当待监控系统的内核执行到所述断点时,调用控制函数,通过所述控制函数找出与所述指定函数存在访问关系的所述未导出的函数地址和/或数据结构偏移的函数,获取所述未导出的函数地址和/或数据结构偏移的函数的数据属性;其中所述数据属性是所述未导出的函数地址和/或数据结构偏移的属性信息;
[0027] 获取模块,用于根据所述数据属性,确定所述未导出的函数地址和/或数据结构偏移。
[0028] 本发明实施例中,通过置模块在系统中选择固定点,并在所述固定点上设置断点,当所述系统内核执行到所述断点时,调用控制函数,通过所述控制函数找出与所述指定函数存在访问关系的所述未导出的函数地址和/或数据结构偏移的函数,获取所述未导出的函数地址和/或数据结构偏移的函数的数据属性;其中所述数据属性是所述未导出的函数地址和/或数据结构偏移的属性信息;所述内核根据所述数据属性,确定所述未导出的函数地址和/或数据结构偏移。这样,不需要知道系统的版本和编译选项,也能够实现未导出的函数地址的自动获取,解决了现有技术中靠人工获取未导出的函数地址所造成的人力浪费问题。并且,通过该方法还可以大大提高实际运行的操作系统的支持效率,节省人力成本和时间。
[0029] 较佳的,所述断点包括代码执行断点和/或数据读写断点;
[0030] 其中所述数据读写断点是从设置数据读写断点初始位置起始到预设长度结束的内存区域中的区域性断点。
[0031] 较佳的,所述触发模块,具体用于当待监控系统的内核执行到所述代码执行断点和/或数据读写断点时,调用所述控制函数,通过所述控制函数找出与所述指定函数存在访问关系的所述未导出的函数地址的函数,获取所述未导出的函数地址的函数的数据属性;以及,当待监控系统的内核执行到所述码执行断点和/或数据读写断点时,调用所述控制函数,通过所述控制函数找出与所述指定函数存在访问关系的所述未导出的数据结构偏移的函数,获取所述未导出的数据结构偏移的函数的数据属性;
[0032] 所述获取模块,具体用于根据所述未导出的函数地址的函数的数据属性,确定所述未导出的函数地址;以及,根据所述未导出的数据结构偏移的函数的数据属性,确定所述未导出的数据结构偏移。
[0033] 较佳的,所述设置模块还用于:将所述找出的未导出的函数地址作为新的固定点。

附图说明

[0034] 图1为本申请实施例提供的一种未导出的函数地址和/或数据结构偏移的获取方法流程示意图;
[0035] 图2为本申请实施例提供的另一种未导出的函数地址和/或数据结构偏移的获取方法流程示意图;
[0036] 图3为本申请实施例提供的利用静态匹配特征找出未导出的函数地址和/或数据结构偏移的方法流程示意图;
[0037] 图4为本申请实施例提供的一种未导出的函数地址的获取装置的功能结构示意图。

具体实施方式

[0038] 本发明实施例提供了一种未导出的函数地址的获取方法及装置,用以实现未导出的函数地址的自动获取,以解决现有技术中靠人工获取未导出的函数地址所造成的人力浪费问题,同时提高系统支持效率。
[0039] 本发明实施例中,为了解决目前因版本不同、或同一版本而编译项不同所导致的只能靠人工确定关键函数以及函数地址的问题,设计了一种能够不依赖于版本和编译项的自动获取未导出的函数地址的方法,参见图1,所述方法包括:
[0040] 步骤101,在从待监控系统的内核文件直接获取到的地址中选择合适的地址作为固定点;;
[0041] 步骤102,从待监控系统的内核文件中找出与所述未导出的函数地址和/或数据结构偏移的函数存在访问关系的指定函数,并在所述固定点处将所述指定函数的地址设置为断点;
[0042] 步骤103,当待监控系统的内核执行到所述断点时,调用控制函数,通过所述控制函数找出与所述指定函数存在访问关系的所述未导出的函数地址和/或数据结构偏移的函数,获取所述未导出的函数地址和/或数据结构偏移的函数的数据属性;其中所述数据属性是所述未导出的函数地址和/或数据结构偏移的属性信息;
[0043] 步骤104,所述内核根据所述数据属性,确定所述未导出的函数地址和/或数据结构偏移。
[0044] 进一步的,所述并在所述固定点处将所述指定函数的地址设置为断点,包括:
[0045] 在所述固定点处将所述指定函数地址设置为代码执行断点和/或数据读写断点。
[0046] 所述系统内核文件中,可直接获取地址的文件包括包括导出函数表、终端表以及入口地址等文件。一般的,可将系统内核文件的入口地址设置为固定点,在所述固定点上查找预先人工选定的作为断点的函数及其函数地址设置,并将该函数地址设置为代码执行断点和/或数据读写断点。
[0047] 进一步的,所述数据读写断点为从所述断点位置开始到预设长度结束的内存区域中的区域性断点。
[0048] 进一步的,所述方法具体包括:
[0049] 在从待监控系统的内核文件直接获取到的地址中选择合适的地址作为固定点;
[0050] 从待监控系统的内核文件中找出与所述未导出的函数地址的函数存在访问关系的指定函数,并在所述固定点处将所述指定函数的地址设置为码执行断点和/或数据读写断点;
[0051] 当待监控系统的内核执行到所述码执行断点和/或数据读写断点时,调用所述控制函数,通过所述控制函数找出与所述指定函数存在访问关系的所述未导出的函数地址的函数,获取所述未导出的函数地址的函数的数据属性;
[0052] 所述内核根据所述未导出的函数地址的函数的数据属性,确定所述未导出的函数地址;
[0053] 从待监控系统的内核文件中找出与所述未导出的数据偏移结构的函数存在访问关系的指定函数,并在新的固定点上将该指定函数的地址设置为代码执行断点和/或数据读写断点;
[0054] 当待监控系统的内核执行到所述代码执行断点和/或数据读写断点时,调用所述控制函数,通过所述控制函数找出与所述指定函数存在访问关系的所述未导出的数据结构偏移的函数,获取所述未导出的数据结构偏移的函数的数据属性;
[0055] 所述内核根据所述未导出的数据结构偏移的函数的数据属性,确定所述未导出的数据结构偏移。
[0056] 较佳的,在所述在新的固定点上设置代码执行断点和/或数据读写断点之前,所述方法还包括:将找出的所述未导出的函数地址作为新的固定点。
[0057] 通过将找出的未导出的函数地址作为新的固定点,进一步获取更多的未导出的函数地址和数据结构偏移。
[0058] 进一步的,所述方法还包括:采用传统断点调试技术或虚拟机技术实现代码执行断点和数据读写断点。
[0059] 本发明实施例提供的方法中,通过选择固定点,并在所述固定点上设置断点,当所述内核执行到所述断点时,调用控制函数,通过所述控制函数找出与所述指定函数存在访问关系的所述未导出的函数地址和/或数据结构偏移的函数,获取所述未导出的函数地址和/或数据结构偏移的函数的数据属性;其中所述数据属性是所述未导出的函数地址和/或数据结构偏移的属性信息;所述内核根据所述数据属性,确定所述未导出的函数地址和/或数据结构偏移。这样,不需要知道系统的版本和编译选项,也能够实现未导出的函数地址的自动获取,解决了现有技术中靠人工获取未导出的函数地址所造成的人力浪费问题。并且,通过该方法还可以大大提高实际运行的操作系统的支持效率,节省人力成本和时间。
[0060] 下面结合附图对本发明优选的实施方式进行详细说明。
[0061] 本发明实施例一提供了一种自动获取未导出的函数地址方法,下面以从Linux系统的3.10版本的task_struct数据结构(该数据结构为现有技术,具体内容本申请中不再赘述)中找出task_struct.flags、task_struct.tasks、task_struct.mm、task_struct.active_mm、task_struct.pid、task_struct.real_parent、task_struct.group_leader、task_struct.thread_group、task_struct.comm、task_struct.fs、task_struct.files等成员变量为例,具体阐述本发明技术方案,参阅图2所示,具体步骤如下:
[0062] 步骤201,从Linux系统内核中获取内核文件中入口地址作为固定点。
[0063] 所述固定点可以是内核文件中的入口地址,也可以是导出的函数或数据地址、以及中断表中的地址等内核文件中的相对不变的地址。固定点的选择要根据要获取的未导出函数的需求来人工确定。
[0064] 步骤202,当内核执行到Linux内核的入口处时,搜索内核符号表的位置,然后解压缩得到原始的内核符号表。所述内核符号表中包含有多个函数和函数地址、以及变量与变量地址之间的映射关系。
[0065] 步骤203,根据所述内核符号表中的映射关系,获取指定函数copy_process的地址偏移,然后将指定函数copy_process的函数地址设置代码执行断点。
[0066] 根据源码中的定义,只有函数task_struct.flags的结构内偏移是固定的,为0x0C。其他的都是与版本和条件编译有关的。为定位其他的成员变量,我们需要找到一个在内核符号表里到处的符号,经过人工分析,我们找到了copy_process这个指定函数,这个指定函数是Linux内核fork子进程的核心函数,如果在这个指定函数入口设置执行断点,我们就可以监控到所有Linux进程的创建,这个指定函数也可以帮助我们来解决定位task_struct里面需要的成员变量的结构内偏移。
[0067] 这个步骤可以利用传统的调试断点技术来实现,也可以利用虚拟机技术来实现这些断点功能。传统的调试断点技术包括x86下可以插入“int3”指令、利用页保护属性、利用CPU提供的硬件断点技术。利用虚拟机技术,可以实现无限制的硬件断点功能[0068] 步骤204,当Linux内核第一次执行到指定函数copy_process时,就进入了断点的控制函数,此时通过控制函数获取当前进程的task_struct指针(这个指针可以从线程栈里获取)。此时当前进程就是最初是的进程,也就是init_task位置。
[0069] 步骤205,此时的task_struct结构中的real_parent指向的就是自己的task_struct基址,因此只要控制函数利用当前进程的task_struct指针搜索,第一个匹配上的就是成员变量real_parent,然后获取real_parent的数据属性;这样根据函数real_paren的数据属性也就知道了函数real_parent在task_struct的结构内偏移;第二个匹配上的是成员变量parent;第三个匹配上的就是成员变量group_leader。
[0070] 步骤206,继续搜索“swapper”,就能找到成员变量comm的位置。
[0071] 步骤207,继续搜索大于内核基址的地址,就能找出变量fs和files的位置。
[0072] 利用类似与步骤201~207中的方法,可以找到其他的成员变量的位置。此处不再赘述。
[0073] 通过上述过程,即可在task_struct数据结构中找出未导出的函数地址,从而根据所述函数地址实现对操作系统内部的关键函数和关键数据结构实现全面的监控。
[0074] 但是,有一些成员变量没有明显的静态匹配特征,比如task_struct.pid,单纯的代码执行断点可能对于获取一些未导出的数据结构偏移的难度很大,而结合数据读写断点就可以大大提高获取未导出的函数地址和数据结构偏移的效率。因此,本发明实施例二提供了利用代码执行断点和数据执行断点相结合以获取未导出的函数地址的方法。下面,再次从Linux系统的3.10版本的task_struct数据结构中找出未导出的函数地址为例,具体阐述本发明技术方案,参阅图3所示,具体步骤如下:
[0075] 步骤301,从Linux系统内核中获取内核文件中入口地址作为固定点。
[0076] 所述固定点可以是内核文件中的入口地址,也可以是导出的函数或数据地址、以及中断表中的地址等内核文件中的相对不变的地址。固定点的选择要根据要获取的未导出函数的需求来人工确定。
[0077] 步骤302,当内核执行到Linux内核的入口处时,搜索内核符号表的位置,然后解压缩得到原始的内核符号表。所述内核符号表中包含有多个函数和函数地址、以及变量与变量地址之间的映射关系。
[0078] 步骤303,根据所述内核符号表中的映射关系,获取指定函数copy_process的地址偏移,然后将指定函数copy_process地址设置代码执行断点。
[0079] 根据源码中的定义,只有函数task_struct.flags的结构内偏移是固定的,为0x0C。其他的都是与版本和条件编译有关的。为定位其他的成员变量,我们需要找到一个在内核符号表里到处的符号,经过人工分析,我们找到了copy_process这个指定函数,这个指定函数是Linux内核fork子进程的核心函数,如果在这个指定函数入口设置执行断点,我们就可以监控到所有Linux进程的创建,这个指定函数也可以帮助我们来解决定位task_struct里面需要的成员变量的结构内偏移。
[0080] 步骤304,当Linux内核第一次执行到指定函数copy_process时,就进入了断点的控制函数,此时通过控制函数获取当前进程的task_struct指针(这个指针可以从线程栈里获取,还可以从中获取其它的与未导出的函数地址或数据结构偏移相关的数据信息,根据所述其它的与未导出的函数地址或数据结构偏移相关的数据信息找到未导出的函数地址或数据结构偏移相关的函数)。此时当前进程就是最初始的进程,也就是init_task位置。
[0081] 步骤305,此时的task_struct结构中的real_parent指向的就是自己的task_struct基址,因此只要控制函数用当前进程的task_struct指针搜索,第一个匹配上的就是成员变量real_parent,这样根据函数real_paren的数据属性也就知道了函数real_parent在task_struct的结构内偏移;第二个匹配上的是成员变量parent;第三个匹配上的就是成员变量group_leader。
[0082] 步骤306,继续搜索“swapper”,就能找到成员变量comm的位置。
[0083] 步骤307,继续搜索大于内核基址的地址,就能找到找出变量fs和files的位置。利用类似与步骤301~307中的方法,可以找到其他的成员变量的位置。此处不再赘述。
[0084] 步骤308,从步骤307中找到的函数地址中选择一合适的地址,并将该地址设置为新的固定点。
[0085] 步骤309,从符号表中获取指定函数do_exit的函数地址,并在所述新的固定点上将指定函数do_exit的函数地址设置为新的数据读写断点。所述数据读写断点为从所述断点位置开始到预设长度结束的内存区域中的区域性断点。
[0086] 经过人工分析在do_exit这个函数里,有对没有明显的静态匹配特征的函数task_struct.pid的访问,这个函数也可以帮助我们来解决定位task_struct里面没有明显的静态匹配特征的函数的结构内偏移。
[0087] 步骤310,当系统内核执行到指定函数do_exit函数的入口时,获取当前的task_struct指针。
[0088] 步骤311,当指定函数do_exit中的代码访问到task_struct.pid时,就会触发数据读写断点,此时通过控制函数获取的触发数据读写断点的数据地址就是task_struct.pid的函数地址,所述task_struct.pid的函数地址减去基址就是成员变量task_struct.pid的结构内偏移。依次类推,还可以通过该方法得到其它不具有明显的静态匹配特征的函数。
[0089] 从上面的过程,可以看出,本发明实施例二是通过动态运行的方式,结合执行断点和数据断点以及静态的数据匹配特征,因此本发明可以做到与操作系统的硬件平台(CPU指令级)无关。虽然在例子中,固定点的选取来自与符号信息中的某些函数,但实际上也可以不依赖于任何符号信息,可以借助许多外部事件的入口,如中断向量、某些控制寄存器等等的一些数据和代码来获取以上信息。因此本发明提供的获取函数地址的方法通用性更强,对于不带符号信息的Linux内核仍然可以支持监控。
[0090] 需要指出的是,利用所述动态执行方式运行一次也有可能不会得到全部的未导出的函数地址,在有需要的情况下,可以通过设置自动运行多次的方式渐进的把所有未导出的函数地址都获取到。
[0091] 基于同一发明构思,本发明实施例提供了一种未导出的函数地址,参见图4;所述装置包括:
[0092] 设置模块401,用于在从待监控系统的内核文件直接获取到的地址中选择合适的地址作为固定点;以及,从待监控系统的内核文件中找出与所述未导出的函数地址和/或数据结构偏移的函数存在访问关系的指定函数,并在所述固定点处将所述指定函数的地址设置为断点;
[0093] 触发模块402,用于当待监控系统的内核执行到所述断点时,调用控制函数,通过所述控制函数找出与所述指定函数存在访问关系的所述未导出的函数地址和/或数据结构偏移的函数,获取所述未导出的函数地址和/或数据结构偏移的函数的数据属性;其中所述数据属性是所述未导出的函数地址和/或数据结构偏移的属性信息;
[0094] 获取模块403,用于根据所述数据属性,确定所述未导出的函数地址和/或数据结构偏移。
[0095] 为了便于描述,下面依然以从Linux系统的3.10版本的task_struct数据结构中找出task_struct.flags、task_struct.tasks、task_struct.mm、task_struct.active_mm、task_struct.pid、task_struct.real_parent、task_struct.group_leader、task_struct.thread_group、task_struct.comm、task_struct.fs、task_struct.files等成员变量为例,具体阐述所述装置的工作原理。
[0096] 具体的,所述固定点可以是内核文件中的入口地址,也可以是导出的函数或数据地址、以及中断表中的地址等内核文件中的相对不变的地址。固定点的选择要根据要获取的未导出函数的需求来人工确定。
[0097] 进一步的,所述断点包括代码执行断点和/或数据读写断点;其中所述数据读写断点是从设置数据读写断点初始位置起始到预设长度结束的内存区域中的区域性断点。
[0098] 根据源码中的定义,只有函数task_struct.flags的结构内偏移是固定的,为0x0C。其他的都是与版本和条件编译有关的。为定位其他的成员变量,我们需要找到一个在内核符号表里到处的符号,经过人工分析,我们找到了copy_process这个函数,这个函数是Linux内核fork子进程的核心函数,如果在这个函数入口设置执行断点,我们就可以监控到所有Linux进程的创建,这个函数也可以帮助我们来解决定位task_struct里面需要的成员变量的结构内偏移。
[0099] 设置代码执行断点的步骤可以利用传统的调试断点技术来实现,也可以利用虚拟机技术来实现这些断点功能。传统的调试断点技术包括x86下可以插入“int3”指令、利用页保护属性、利用CPU提供的硬件断点技术。利用虚拟机技术,可以实现无限制的硬件断点功能。
[0100] 所述触发模块402,具体用于当系统执行到所述代码执行断点和/或数据读写断点时,调用所述控制函数,通过所述控制函数找出与所述指定函数存在访问关系的所述未导出的函数地址的函数,获取所述未导出的函数地址的函数的数据属性;以及,当待监控系统的内核执行到所述码执行断点和/或数据读写断点时,调用所述控制函数,通过所述控制函数找出与所述指定函数存在访问关系的所述未导出的数据结构偏移的函数,获取所述未导出的数据结构偏移的函数的数据属性;
[0101] 所述获取模块403,具体用于根据所述未导出的函数地址的函数的数据属性,确定所述未导出的函数地址;以及,根据所述未导出的数据结构偏移的函数的数据属性,确定所述未导出的数据结构偏移。
[0102] 实施过程中,当系统执行到所述代码执行断点时,触发模块42调用控制函数并获取当前进程的指针;实施过程中,当Linux内核第一次执行到指定函数copy_process时,所述触发模块触发所述代码执行断点,内核调用控制函数,此时控制函数获取当前进程的task_struct指针(这个指针可以从线程栈里获取)。此时当前进程就是最初是的进程,也就是init_task位置。通过控制函数利用所述当前进程的指针,搜索并找出未导出的函数地址的函数,获取所述未导出的函数地址的函数的数据属性,并将当前进程的基址赋予第一个被找出的未导出函数;获取模块43根据所述数据属性获取未导出函数的函数地址。实施过程中,task_struct结构中的real_parent指向的就是自己的task_struct基址,因此只要利用当前进程的task_struct指针搜索,第一个匹配上的就是成员变量real_parent,这样也就知道了real_parent在task_struct的结构内偏移;第二个匹配上的是成员变量parent;第三个匹配上的就是成员变量group_leader。继续搜索“swapper”,就能找到成员变量comm的位置。然后,再搜索大于内核基址的地址,就能找到找出变量fs和files的位置。利用类似的方法,就可以找到其他的成员变量的位置。此处不再赘述。。
[0103] 通过上述过程,即可在task_struct数据结构中找出未导出的函数地址,从而根据所述函数地址实现对操作系统内部的关键函数和关键数据结构实现全面的监控。
[0104] 但是,有一些成员变量没有明显的静态匹配特征,比如task_struct.pid,单纯的代码执行断点可能对于获取一些未导出的数据结构偏移的难度很大,而结合数据读写断点就可以大大提高获取未导出的函数地址和数据结构偏移的效率。
[0105] 因此,所述设置模块401,还具体用于将所述找出的未导出的函数地址作为新的固定点,在所述新的固定点上将与所述未导出的函数地址和/或数据结构偏移的函数存在访问关系的指定函数的地址设置为新的数据读写断点。
[0106] 所述触发模块402,还具体用于当系统执行到与新的数据读写断点时,调用控制函数;通过控制函数利用静态特征匹配的方式继续搜索,当利用控制函数在所述新的执行断点处获取的指针访问到未导出函数时,触发数据读写断点,获取所述未导出的函数地址和/或数据结构偏移的函数的数据属性。
[0107] 实施过程中,所述设置模块从符号表中获取指定函数do_exit的函数地址,并在固定点处将指定函数do_exit的函数地址设置为代码执行断点。因为经过人工分析在do_exit这个函数里,有对函数task_struct.pid的访问,这个函数也可以帮助我们来解决定位task_struct里面没有明显的静态匹配特征的函数的结构内偏移。接下来,当系统执行到指定函数do_exit的入口时,触发模块获取当前的task_struct指针,并在从这个指针开始到预定长度结束的一片内存区域内设置数据读写断点;最后,当指定函数do_exit中的代码访问到task_struct.pid时,就会触发数据断点,此时就触发数据断点的数据地址就是task_struct.pid的函数地址,通过所述task_struct.pid的函数地址减去task_struct基址就是成员变量task_struct.pid的结构内偏移。
[0108] 综上,本发明实施例提供了实施例中,通过选择固定点,并在所述固定点上设置断点,当所述系统执行到与所述断点匹配的函数时,进入与所述断点对应的控制函数,并获取当前进程的指针;利用所述当前进程的指针,搜索并找出未导出的函数及其函数地址,即通过动态运行的方式,结合执行断点和数据断点以及静态的数据匹配特征,不需要知道系统的版本和编译选项,也能够实现未导出的函数地址的自动获取,解决了现有技术中靠人工获取未导出的函数地址所造成的人力浪费问题。并且,通过该方法还可以大大提高实际运行的操作系统的支持效率,节省人力成本和时间。
[0109] 本发明是参照根据本发明实施例的方法、设备(系统)、和计算机程序产品的流程图和/或方框图来描述的。应理解可由计算机程序指令实现流程图和/或方框图中的每一流程和/或方框、以及流程图和/或方框图中的流程和/或方框的结合。可提供这些计算机程序指令到通用计算机、专用计算机、嵌入式处理机或其他可编程数据处理设备的处理器以产生一个机器,使得通过计算机或其他可编程数据处理设备的处理器执行的指令产生用于实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能的装置。
[0110] 这些计算机程序指令也可存储在能引导计算机或其他可编程数据处理设备以特定方式工作的计算机可读存储器中,使得存储在该计算机可读存储器中的指令产生包括指令装置的制造品,该指令装置实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能。
[0111] 这些计算机程序指令也可装载到计算机或其他可编程数据处理设备上,使得在计算机或其他可编程设备上执行一系列操作步骤以产生计算机实现的处理,从而在计算机或其他可编程设备上执行的指令提供用于实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能的步骤。
[0112] 尽管已描述了本发明的优选实施例,但本领域内的技术人员一旦得知了基本创造性概念,则可对这些实施例作出另外的变更和修改。所以,所附权利要求意欲解释为包括优选实施例以及落入本发明范围的所有变更和修改。
[0113] 显然,本领域的技术人员可以对本发明实施例进行各种改动和变型而不脱离本发明实施例的精神和范围。这样,倘若本发明实施例的这些修改和变型属于本发明权利要求及其等同技术的范围之内,则本发明也意图包含这些改动和变型在内。