一种函数调用时间的监控方法及装置转让专利

申请号 : CN201710651465.7

文献号 : CN107480029B

文献日 :

基本信息:

PDF:

法律信息:

相似专利:

发明人 : 孙吉平尹永政

申请人 : 北京深思数盾科技股份有限公司

摘要 :

本发明公开了一种函数调用时间的监控方法及装置,涉及计算机安全技术领域,主要目的是能够实现函数调用时间的监控,从而更好了解函数是否需要加保护。所述方法包括:通过挂起的方式创建监控进程,所述监控进程中包含有预设容量的动态内存;将用于监控函数调用时间的预设分析代码载入所述动态内存中;启动所述监控进程,根据所述预设分析代码加载需要注入至所述监控进程的动态链接库;根据所述动态链接库中的监控函数块监控所述调用函数被调用的起始时间和结束时间,得到调用函数的调用时间。本发明主要用于函数的调用时间的分析。

权利要求 :

1.一种函数调用时间的监控方法,其特征在于,包括:通过挂起的方式创建监控进程,所述监控进程中包含有预设容量的动态内存;

将用于监控函数调用时间的预设分析代码载入所述动态内存中;

启动所述监控进程,根据所述预设分析代码加载需要注入至所述监控进程的动态链接库;

根据所述动态链接库中的监控函数块监控所述调用函数被调用的起始时间和结束时间,得到调用函数的调用时间;

所述根据所述动态链接库中的监控函数- 块 监控所述调用函数被调用的起始时间和结束时间包括:启动所述动态链接库中的函数hook被保护程序的函数块作为监控函数块;

根据所述函数hook被保护程序的函数块监控所述调用函数被调用的起始时间和结束时间,得到所述调用函数的调用时间;

所述根据所述函数hook被保护程序的函数块监控所述调用函数被调用的起始时间和结束时间,得到所述调用函数的调用时间包括:当调用函数被调用时,通过所述函数hook被保护程序的函数块获取所述调用函数的起始地址;

从堆栈中读取指定存储空间中的地址取值,所述指定存储空间是用于存储函数返回地址的;

查找所述地址取值所指向指令的上一条指令所指向的地址;

判断所述上一条指令所指向的地址是否与所述调用函数的起始地址相同,如果相同,则监控所述调用函数被调用的起始时间和结束时间,得到调用函数的调用时间。

2.根据权利要求1所述的方法,其特征在于,在所述启动所述监控进程之前,所述方法还包括:创建内存映射文件以及时间统计结果事件,所述内存映射文件中存储有调用函数的函数信息;

传递所述监控进程的标识信息,根据所述标识信息加载所述内存映射文件以及时间统计结果事件;

根据所述内存映射文件将程序执行的起始地址添加至所述预设分析代码中,当启动所述监控进程时跳转至程序执行的起始地址。

3.根据权利要求1所述的方法,其特征在于,在所述启动所述动态链接库中的函数hook被保护程序的函数块作为监控函数块之前,所述方法还包括:根据所述调用函数的函数信息获取所述调用函数的函数类型;

当所述调用函数的函数类型为可直接执行函数时,通过模块句柄载入动态链接库;

当所述调用函数的函数类型为不可直接执行函数时,通过加载模块载入动态链接库。

4.一种函数调用时间的监控装置,其特征在于,包括:第一创建单元,用于通过挂起的方式创建监控进程,所述监控进程中包含有预设容量的动态内存;

载入单元,用于将用于监控函数调用时间的预设分析代码载入所述动态内存中;

启动单元,用于启动所述监控进程,根据所述预设分析代码加载需要注入至所述监控进程的动态链接库;

监控单元,用于根据所述动态链接库中的监控函数块监控所述调用函数被调用的起始时间和结束时间,得到调用函数的调用时间;

所述监控单元包括:

启动模块,用于启动所述动态链接库中的函数hook被保护程序的函数块作为监控函数块;

监控模块,用于根据所述函数hook被保护程序的函数块监控所述调用函数被调用的起始时间和结束时间,得到所述调用函数的调用时间;

所述监控模块,还用于当调用函数被调用时,通过所述函数hook被保护程序的函数块获取所述调用函数的起始地址;从堆栈中读取指定存储空间中的地址取值,所述指定存储空间是用于存储函数返回地址的;查找所述地址取值所指向指令的上一条指令所指向的地址;判断所述上一条指令所指向的地址是否与所述调用函数的起始地址相同,如果相同,则监控所述调用函数被调用的起始时间和结束时间,得到调用函数的调用时间。

5.根据权利要求4所述的装置,其特征在于,所述装置还包括:第二创建单元,用于创建内存映射文件以及时间统计结果事件,所述内存映射文件中存储有调用函数的函数信息;

加载单元,用于传递所述监控进程的标识信息,根据所述标识信息加载所述内存映射文件以及时间统计结果事件;

添加单元,用于根据所述内存映射文件将程序执行的起始地址添加至所述预设分析代码中,当启动所述监控进程时跳转至程序执行的起始地址。

6.根据权利要求4所述的装置,其特征在于,

所述启动模块,还用于在所述启动所述动态链接库中的函数hook被保护程序的函数块作为监控函数块之前,根据所述调用函数的函数信息获取所述调用函数的函数类型;当所述调用函数的函数类型为可直接执行函数时,通过模块句柄载入动态链接库;当所述调用函数的函数类型为不可直接执行函数时,通过加载模块载入动态链接库。

说明书 :

一种函数调用时间的监控方法及装置

技术领域

[0001] 本发明涉及计算机安全领域,尤其是一种函数调用时间的监控方法及装置。

背景技术

[0002] 在函数保护中,如果对函数的调用时间没有清楚的认识,盲目地对函数进行加壳保护,如代码碎片化、代码虚拟化、代码移植或者代码混淆,对于加保护后的函数,如果调用时间在保护前与保护后的差距较大,则说明加保护极大影响了函数的运行时间,应该取消对函数的保护,如果调用时间在保护前与保护后的差距不大,则说明加保护没有对函数产生很大影响,无需取消对函数的保护,因此,在对函数的调用时间不了解的情况下,很容易无意中对系统函数或者操作中不希望加保护的调用的函数进行了保护,这样不仅影响了加壳后程序的体积,同时还会降低加壳后程序的运行效率。
[0003] 如果开发人员在程序运行过程中保护了过多的不希望加保护的函数,会使得保护后的可执行程序的体积加大,同时会降低保护后的可执行程序的运行效率。

发明内容

[0004] 鉴于上述问题,提出了本发明以便提供一种克服上述问题或者至少部分地解决上述问题的一种函数调用时间的监控方法及装置,能够实现函数调用时间的监控,从而更好了解函数是否需要加保护。
[0005] 本发明实施例的一方面,本发明提供了一种函数调用时间的监控方法,包括:
[0006] 通过挂起的方式创建监控进程,所述监控进程中包含有预设容量的动态内存;
[0007] 将用于监控函数调用时间的预设分析代码载入所述动态内存中;
[0008] 启动所述监控进程,根据所述预设分析代码加载需要注入至所述监控进程的动态链接库;
[0009] 根据所述动态链接库中的监控函数块监控所述调用函数被调用的起始时间和结束时间,得到调用函数的调用时间。
[0010] 进一步地,在所述启动所述监控进程之前,所述方法还包括:
[0011] 创建内存映射文件以及时间统计结果事件,所述内存映射文件中存储有调用函数的函数信息;
[0012] 传递所述监控进程的标识信息,根据所述标识信息加载所述内存映射文件以及时间统计结果事件;
[0013] 根据所述内存映射文件将程序执行的起始地址添加至所述预设分析代码中,当启动所述监控进程时跳转至程序执行的起始地址。
[0014] 进一步地,所述根据所述动态链接库中的监控函数块监控所述调用函数被调用的起始时间和结束时间,得到调用函数的调用时间包括:
[0015] 启动所述动态链接库中的函数hook被保护程序的函数块作为监控函数块;
[0016] 根据所述函数hook被保护程序的函数块监控所述调用函数被调用的起始时间和结束时间,得到所述调用函数的调用时间。
[0017] 进一步地,在所述启动所述动态链接库中的函数hook被保护程序的函数块作为监控函数块之前,所述方法还包括:
[0018] 根据所述调用函数的函数信息获取所述调用函数的函数类型;
[0019] 当所述调用函数的函数类型为可直接执行函数时,通过模块句柄载入动态链接库;
[0020] 当所述调用函数的函数类型为不可直接执行函数时,通过加载模块载入动态链接库。
[0021] 进一步地,所述根据所述函数hook被保护程序的函数块监控所述调用函数被调用的起始时间和结束时间,得到所述调用函数的调用时间包括:
[0022] 当调用函数被调用时,通过所述函数hook被保护程序的函数块获取所述调用函数的起始地址;
[0023] 从堆栈中读取指定存储空间中的地址取值,所述指定存储空间是用于存储函数返回地址的;
[0024] 查找所述地址取值所指向指令的上一条指令所指向的地址;
[0025] 判断所述上一条指令所指向的地址是否与所述调用函数的起始地址相同,如果相同,则监控所述调用函数被调用的起始时间和结束时间,得到调用函数的调用时间。
[0026] 依据本发明实施例的另一方面,本发明实施例提供了一种函数调用时间的监控装置,包括:
[0027] 第一创建单元,用于通过挂起的方式创建监控进程,所述监控进程中包含有预设容量的动态内存;
[0028] 载入单元,用于将用于监控函数调用时间的预设分析代码载入所述动态内存中;
[0029] 启动单元,用于启动所述监控进程,根据所述预设分析代码加载需要注入至所述监控进程的动态链接库;
[0030] 监控单元,用于根据所述动态链接库中的监控函数块监控所述调用函数被调用的起始时间和结束时间,得到调用函数的调用时间。
[0031] 进一步地,所述装置还包括:
[0032] 第二创建单元,用于创建内存映射文件以及时间统计结果事件,所述内存映射文件中存储有调用函数的函数信息;
[0033] 加载单元,用于传递所述监控进程的标识信息,根据所述标识信息加载所述内存映射文件以及时间统计结果事件;
[0034] 添加单元,用于根据所述内存映射文件将程序执行的起始地址添加至所述预设分析代码中,当启动所述监控进程时跳转至程序执行的起始地址。
[0035] 进一步地,所述监控单元包括:
[0036] 启动模块,用于启动所述动态链接库中的函数hook被保护程序的函数块作为监控函数块;
[0037] 监控模块,用于根据所述函数hook被保护程序的函数块监控所述调用函数被调用的起始时间和结束时间,得到所述调用函数的调用时间。
[0038] 进一步地,所述启动模块,还用于在所述启动所述动态链接库中的函数hook被保护程序的函数块作为监控函数块之前,根据所述调用函数的函数信息获取所述调用函数的函数类型;当所述调用函数的函数类型为可直接执行函数时,通过模块句柄载入动态链接库;当所述调用函数的函数类型为不可直接执行函数时,通过加载模块载入动态链接库。
[0039] 进一步地,所述监控模块,还用于当调用函数被调用时,通过所述函数hook被保护程序的函数块获取所述调用函数的起始地址;从堆栈中读取指定存储空间中的地址取值,所述指定存储空间是用于存储函数返回地址的;查找所述地址取值所指向指令的上一条指令所指向的地址;判断所述上一条指令所指向的地址是否与所述调用函数的起始地址相同,如果相同,则监控所述调用函数被调用的起始时间和结束时间,得到调用函数的调用时间。
[0040] 借由上述技术方案,本发明提供的一种函数调用时间的监控方法及装置,通过将用于监控函数调用时间的预设分析代码载入监控进程中,以便于在程序执行到该调用函数时,根据动态链接库中的监控函数块监控调用函数被调用的起始时间和结束时间,能够实时监控调用函数的调用时间。与现有技术的函数调用时间的监控方法相比,本发明实施例通过在程序运行过程中对调用函数的调用时间进行监控,能够得到程序执行过程中函数的调用时间,进而可以通过函数的调用时间了解函数保护之前和保护之后调用时间的差距,进而更好了解函数是否需要加保护,提高用户体验,另外,根据函数的调用时间可以实时对程序的函数模块进行优化,提高可执行程序的运行效率,极大地节省了技术人员的时间。
[0041] 上述说明仅是本发明技术方案的概述,为了能够更清楚了解本发明的技术手段,而可依照说明书的内容予以实施,并且为了让本发明的上述和其它目的、特征和优点能够更明显易懂,以下特举本发明的具体实施方式。

附图说明

[0042] 通过阅读下文优选实施方式的详细描述,各种其他的优点和益处对于本领域普通技术人员将变得清楚明了。附图仅用于示出优选实施方式的目的,而并不认为是对本发明的限制。而且在整个附图中,用相同的参考符号表示相同的部件。在附图中:
[0043] 图1示出了本发明实施例提供的一种函数调用时间的监控方法流程示意图;
[0044] 图2示出了本发明实施例提供的另一种函数调用时间的监控方法流程示意图;
[0045] 图3示出了本发明实施例提供的一种函数调用时间的监控装置结构示意图;
[0046] 图4示出了本发明实施例提供的另一种函数调用时间的监控装置结构示意图。

具体实施方式

[0047] 下面将参照附图更详细地描述本公开的示例性实施例。虽然附图中显示了本公开的示例性实施例,然而应当理解,可以以各种形式实现本公开而不应被这里阐述的实施例所限制。相反,提供这些实施例是为了能够更透彻地理解本公开,并且能够将本公开的范围完整的传达给本领域的技术人员。
[0048] 本发明实施例提供了一种函数调用时间的监控方法,如图1所示,该方法主要通过预设代码对调用函数的调用时间进行监控,具体步骤包括:
[0049] 101、通过挂起的方式创建监控进程。
[0050] 其中,监控进程用于监控程序执行中函数的调用时间,另外,由于执行程序都需要一定的内存,为了方便进程的使用,在监控进程中申请预设容量的动态内存,可以用来存放预设分析代码或者其他程序运行数据,如代码段或数据段,本发明实施例对申请动态内存的容量大小不进行限定,可根据应用运行实际需要的内存大小进行申请。
[0051] 需要说明的是,这里为了方便用户观察和分析监控进程,通过挂起的方式创建监控进程,此时该监控进程处于静止状态,从而方便用户对程序进行修改或者其他操作。
[0052] 102、将用于监控函数调用时间的预设分析代码载入所述动态内存中。
[0053] 这里的预设分析代码主要用于对调用函数的调用时间进行分析,具体可以包括进程标识传递模块、程序起始地址添加模块、动态链接库的注入模块、信息保存模块等多个模块,各个模块之间可以互通消息,并且相互之间不会影响,其中,进程标识传递模块用于传递监控进程的标识信息,从而程序根据该标识信息加载内存映射文件以及时间统计结果事件,这里的内存映射文件中存储有调用函数的函数信息,如函数的名称,函数的相对虚拟地址RVA,函数的相对虚拟地址RVA的个数以及程序执行的起始地址等信息,程序起始地址添加模块用于将内存映射文件中程序执行的起始地址添加至预设分析代码中,以便当调用函数被调用时跳转至预设分析代码执行的起始地址,动态链接库的注入模块用于加载监控进程的动态链接库,根据动态链接库中的存储的分析函数块对调用函数的函数信息进行监控,得到调用函数的调用时间,这里使用动态链接库可以更为容易地将程序应用于各个模块,并且不影响该程序的其他部分,这样也方便对监控进程进行修改,如需要对函数调用时间中的内容进行更新,可以通过对动态链接库进行修改即可,从而方便程序的更新,信息保存模块用于根据时间统计结果事件将调用信息保存至内存映射文件中,以便后续对函数调用时间的分析,还可以显示在显示界面,从而更直观的展示给用户。
[0054] 具体地,当程序执行至调用函数时,通过预设分析代码中的各个模块对调用函数进行分析,首先通过进程标识传递模块传递监控进程的标识信息,根据该标识信息加载内存映射文件以及时间统计结果事件,然后通过程序起始地址添加模块将内存映射文件中程序执行的起始地址添加至预设分析代码中,进一步通过动态链接库加载动态链接库中的监控函数块对调用函数进行监控,得到函数的调用时间,最后通过信息保存模块将函数的调用时间实时保存至内存映射文件中。
[0055] 103、启动所述监控进程,根据所述预设分析代码加载需要注入至所述监控进程的动态链接库。
[0056] 具体地,启动监控进程后,当监控到程序执行至调用函数时,通过预设分析代码中的各个模块对调用函数进行分析,首先通过进程标识传递模块传递监控进程的标识信息,根据该标识信息加载内存映射文件以及时间统计结果事件,然后通过程序起始地址添加模块将内存映射文件中程序执行的起始地址添加至预设分析代码中,进一步通过动态链接库加载动态链接库中的监控函数块,进一步实现对调用函数的监控。
[0057] 104、根据所述动态链接库中的监控函数块监控所述调用函数被调用的起始时间和结束时间,得到调用函数的调用时间。
[0058] 其中,动态链接库中存储有用于监控函数调用时间的分析函数块,进一步可以根据内存映射文件获取调用函数的函数信息,然后通过启动动态链接库中函数hook被保护程序的函数块作为监控函数块,对调用函数进行监控,监控调用函数被调用的起始时间和结束时间,通过将结束时间减去起始时间得到调用函数的调用时间,进一步可以通过信息保存模块将函数的调用时间实时保存至内存映射文件中。
[0059] 需要说明的是,这里得到的函数的调用时间可以根据用户实际需求进行显示,如用户可以设置界面显示某函数最近一次被调用的调用时间,还可以设置界面显示所有调用函数每次被调用的调用时间等,当然还可以显示函数被调用的起始时间和结束时间,本发明实施例对分析结果的在界面上显示的内容不进行限定。
[0060] 结合上述的实现方式可以看出,本发明实施例提供的一种函数调用时间的监控方法,通过将用于监控函数调用时间的预设分析代码载入监控进程中,以便于在程序执行到该调用函数时,根据动态链接库中的监控函数块监控调用函数被调用的起始时间和结束时间,能够实时监控调用函数的调用时间。与现有技术的函数调用时间的监控方法相比,本发明实施例通过在程序运行过程中对调用函数的调用时间进行监控,能够得到程序执行过程中函数的调用时间,进而可以通过函数的调用时间了解函数保护之前和保护之后调用时间的差距,进而更好了解函数是否需要加保护,提高用户体验,另外,根据函数的调用时间可以实时对程序的函数模块进行优化,提高可执行程序的运行效率,极大地节省了技术人员的时间。
[0061] 以下为了更加详细地说明本发明提出的一种函数调用时间的监控方法,特别是在根据动态链接库中的监控函数块监控调用函数被调用的起始时间和结束时间,得到调用函数的调用时间的步骤,本发明实施例还提供了另一种函数调用时间的监控方法,如图2所示,该方法的具体步骤包括:
[0062] 201、通过挂起的方式创建监控进程。
[0063] 其中,监控进程用于监控程序执行中函数的调用时间,另外,由于执行程序都需要一定的内存,为了方便进程的使用,在监控进程中申请预设容量的动态内存,可以用来存放预设分析代码或者其他程序运行数据,如代码段或数据段,本发明实施例对申请动态内存的容量大小不进行限定,可根据应用运行实际需要的内存大小进行申请。
[0064] 对于本发明实施例,通过创建的监控进程对程序执行中调用函数的调用时间进行监控,以便了解函数在不同情况下被调用的时间,从而更好地对程序进行保护,通常情况下,对于加保护后的函数,如果调用时间在保护前与保护后的差距较大,则说明加保护极大影响了函数的运行时间,应该取消对函数的保护,如果调用时间在保护前与保护后的差距不大,则说明加保护没有对函数产生很大影响,无需取消对函数的保护,本发明实施例可以通过监控调用函数的调用时间可以更好了解函数是否需要加保护,进而对需要保护的函数进行保护。
[0065] 需要说明的是,在创建监控进程之前可以通过分析器对进程中的各个子线程进行性能分析,这里的性能分析主要是通过统计内存使用状况检测可能存在的内存泄露问题以及确定优化内存使用的方向,以防止界面卡死。
[0066] 202、将用于监控函数调用时间的预设分析代码载入所述动态内存中。
[0067] 这里预设分析代码用于监控调用函数的调用时间,具体可以包括进程标识传递模块、程序起始地址添加模块、动态链接库的注入模块、信息保存模块等多个模块,各个模块之间可以互通消息,并且相互之间不会影响。
[0068] 需要说明的是,这里的预设分析代码可以通过组装shellcode的方式来存储各个模块,然后将shellcode写入到申请的动态内存中,本发明实施例对预设分析代码的编译模式不进行限定。
[0069] 203、创建内存映射文件以及时间统计结果事件。
[0070] 其中,内存映射文件中存储有调用函数的函数信息,例如,调用函数的名称、调用函数的相对虚拟地址RVA、调用函数的相对虚拟地址RVA的个数以及程序执行的起始地址等信息,该时间统计结果事件用于统计调用函数的调用信息。
[0071] 对于本发明实施例,通过创建内存映射文件,可以方便同时启动多个性能分析模块,并且实现模块之间的数据通信,通过创建时间统计结果事件,进一步方便模块之间进行消息传递。
[0072] 204、传递所述监控进程的标识信息,根据所述标识信息加载所述内存映射文件以及时间统计结果事件。
[0073] 其中,监控进程的标识信息为操作系统的内核用于唯一标识进程的一个数值,这里的标识信息可以作为许多函数调用的参数,用以调整进程的优先级、控制进程行为等。
[0074] 为了进一步获取调用函数的函数信息以及调用信息,根据传递的监控进程的标识信息加载内存映射文件以及时间统计结果事件,通过打开内存映射文件获取调用函数的函数信息,通过时间统计结果事件统计调用函数的调用时间。
[0075] 205、根据所述内存映射文件将程序执行的起始地址添加至所述预设分析代码中,当启动所述监控进程时跳转至程序执行的起始地址。
[0076] 需要说明的是,这里在预设分析代码中添加程序执行的起始地址的目的是保证当开启监控进程时跳转至程序执行的起始地址,从而对程序中的调用函数进行监控。
[0077] 206、启动所述动态链接库中的函数hook被保护程序的函数块作为监控函数块。
[0078] 其中,动态链接库中存储有用于监控函数调用时间的分析函数块,进一步可以根据内存映射文件获取调用函数的函数信息,然后通过启动动态链接库中函数hook被保护程序的函数块作为监控函数块,对调用函数进行监控。
[0079] 需要说明的是,在通过动态链接库中的函数hook被保护函数块作为监控函数块对调用函数进行监控之前,可以根据调用函数的函数类型的不同采用不同的方式加载动态链接库,具体可以包括但不局限于下述方式,首先根据调用函数的函数信息获取调用函数的函数类型,如该调用函数的函数类型为dll类型或者exe类型,当调用函数的函数类型为exe可直接执行函数时,则说明模块肯定已经被加载过,进一步通过GetModuleHandle获取到模块句柄,通过模块句柄载入动态链接库;当调用函数的函数类型为dll不可直接执行函数时,则说明模块可能已经被加载过可能没被加载过,进一步通过loadlibrary加载模块载入动态链接库。
[0080] 对于本发明实施例,通过在程序执行过程中加载动态链接库,通过动态链接库取得调用函数的地址进行函数调用,无需在程序运行之初加载所有代码,只有在程序需要用某个调用函数时才从动态链接库中取出调用函数,减少了程序的体积。
[0081] 207、根据所述函数hook被保护程序的函数块监控所述调用函数被调用的起始时间和结束时间,得到所述调用函数的调用时间。
[0082] 对于本发明实施例,根据动态链接库中存储的函数hook被保护程序的函数块监控调用函数被调用的起始时间和结束时间的过程具体可以包括但不局限于下述实现方式,当调用函数被调用时,通过函数hook被保护的函数块获取调用函数的起始地址,这里调用函数的起始地址为存储在内存映射文件中调用函数的相对虚拟地址,然后从堆栈中读取指定存储空间中的地址取值,这里的指定存储空间是在程序执行过程中临时保存的用于存储函数返回地址的,对于存在返回地址的调用函数,从堆栈中可以查找到调用函数的起始地址,对于不存在返回地址的调用函数,从堆栈中无法查找到调用函数的起始地址,进一步查找地址取值所指向指令的上一条指令所指向的地址,判断上一条指令所指向的地址是否与调用函数的起始地址相同,如果相同,则说明调用函数存在返回地址,这里指定存储空间中的地址取值是调用函数的返回地址ret,则记录该调用函数被调用的起始时间和结束时间,计算调用函数被调用的结束时间与起始时间的差值,得到调用函数的调用时间,例如当前调用函数被调用的起始时间为A,结束时间为B,则调用时间相应为B-A,这里只有当执行调用函数时才能记录调用函数的起始时间,当调用结束时才能记录调用函数的结束时间,并将调用时间保存至内存映射文件中。
[0083] 需要说明的是,对于不存在返回值的调用函数说明该调用函数可能为递归函数,该调用函数在被调用时可能会跳转到其他调用函数中,并且从堆栈中找到的该指定存储空间中的地址取值不是调用函数的返回地址,则无法准确计算出该调用函数的调用时间,因此,本发明实施例对于不存在返回值的调用函数的调用时间不进行计算。
[0084] 需要说明的是,本发明实施例还可通过创建一个缓冲区来存储函数的调用时间,进一步根据时间统计结果事件将函数的调用时间保存至缓冲区内,本发明实施例对函数的调用时间的存储位置不进行限定。
[0085] 由于在程序运行过程中,不同函数的调用时间有所不同,在函数保护的过程中,如果加保护后的函数对应的调用时间与未加保护的函数对应的调用时间相差较大,会导致程序运行效率低下,同时也使得保护后的可执行程序体积过大,本发明实施例通过对函数调用时间的监控,能够兼顾安全的情况下达到程序体积和效率的平衡,在检查应用程序时候,通过对调用函数的调用时间进行分析,能够进一步确定该函数是否需要加保护,如果调用时间相比加保护之前增加过多,则说明该函数不需要加保护,这样能够帮助软件开发人员后续优化编写的应用程序,同时在分析应用程序的过程中找到需要加保护的函数,从而对函数进行加壳保护。
[0086] 本发明实施例的具体应用场景可以包括但不限制于下述实现方式:当程序执行之前,首先创建内存映射文件以及时间统计结果事件,内存映射文件用于存储调用函数的函数信息,时间统计结果事件用于统计调用函数的调用信息然后通过挂起的方式,然后创建监控进程,并且在监控进程中申请预设容量的动态内存,并将用于分析调用函数的预设分析代码载入动态内存中,进一步启动监控进程,传递监控进程的标识信息,根据监控进程的标识信息加载内存映射文件以及时间统计结果事件,当程序执行到调用函数时,跳转至程序执行的起始地址,对程序执行过程中的调用函数进行分析,进一步加载需要注入监控进程的动态链接库,根据动态链接库中函数hook被保护的函数块对调用函数进行监控,若当前执行程序需要调用v412_open函数,进一步通过hook函数块获取v412_open函数的地址,从堆栈中读取指定存储空间中的地址取值,查找所述地址取值所指向指令的上一条指令所指向的地址;判断所述上一条指令所指向的地址是否与所述调用函数的起始地址相同,如果相同,则监控所述调用函数被调用的起始时间和结束时间,如果返回地址说明该函数不是递归函数,则计算v412_open函数被调用的结束时间与起始时间的差值,,得到v412_open函数的调用时间,最后将v412_open函数的调用时间保存至内存映射文件中。
[0087] 为了进一步分析函数是否需要加保护以及加保护对函数的影响,本发明实施例提供的另一种函数调用时间的监控方法,通过对调用函数的调用时间进行监控,从而根据函数的调用时间来判定函数是否需要加保护,对于需要加保护的函数,对该函数进行加壳保护,对于不需要加保护的函数,取消对该函数的保护,进而提高程序的运行效率。
[0088] 进一步地,作为图1所示方法的具体实现,本发明实施例提供一种函数调用时间的监控装置,该装置实施例与前述方法实施例对应,为便于阅读,本装置不在对前述方法实施例中的细节内容进行逐一赘述,但应当明确,本实施例中的装置能够对应实现前述方法实施例中的全部内容,如图3所示,所述装置包括:
[0089] 第一创建单元31,可以用于通过挂起的方式创建监控进程,所述监控进程中包含有预设容量的动态内存;
[0090] 载入单元32,可以用于将用于监控函数调用时间的预设分析代码载入所述动态内存中;
[0091] 启动单元33,可以用于启动所述监控进程,根据所述预设分析代码加载需要注入至所述监控进程的动态链接库;
[0092] 监控单元34,可以用于根据所述动态链接库中的监控函数块监控所述调用函数被调用的起始时间和结束时间,得到调用函数的调用时间。
[0093] 本发明实施例提供的一种函数调用时间的监控装置,通过将用于监控函数调用时间的预设分析代码载入监控进程中,以便于在程序执行到该调用函数时,根据动态链接库中的监控函数块监控调用函数被调用的起始时间和结束时间,能够实时监控调用函数的调用时间。与现有技术的函数调用时间的监控方法相比,本发明实施例通过在程序运行过程中对调用函数的调用时间进行监控,能够得到程序执行过程中函数的调用时间,进而可以通过函数的调用时间了解函数保护之前和保护之后调用时间的差距,进而更好了解函数是否需要加保护,提高用户体验,另外,根据函数的调用时间可以实时对程序的函数模块进行优化,提高可执行程序的运行效率,极大地节省了技术人员的时间。
[0094] 进一步地,作为图2所示方法的具体实现,本发明实施例提供了另一种函数调用时间的监控装置,该装置实施例与前述方法实施例对应,为便于阅读,本装置不在对前述方法实施例中的细节内容进行逐一赘述,但应当明确,本实施例中的装置能够对应实现前述方法实施例中的全部内容,如图4所示,所述装置包括:
[0095] 第一创建单元41,可以用于通过挂起的方式创建监控进程,所述监控进程中包含有预设容量的动态内存;
[0096] 载入单元42,可以用于将用于监控函数调用时间的预设分析代码载入所述动态内存中;
[0097] 第二创建单元43,可以用于创建内存映射文件以及时间统计结果事件,所述内存映射文件中存储有调用函数的函数信息;
[0098] 加载单元44,可以用于传递所述监控进程的标识信息,根据所述标识信息加载所述内存映射文件以及时间统计结果事件;
[0099] 添加单元45,用于根据所述内存映射文件将程序执行的起始地址添加至所述预设分析代码中,当启动所述监控进程时跳转至程序执行的起始地址。
[0100] 启动单元46,用于启动所述监控进程,根据所述预设分析代码加载需要注入至所述监控进程的动态链接库;
[0101] 监控单元47,用于根据所述动态链接库中的监控函数块监控所述调用函数被调用的起始时间和结束时间,得到调用函数的调用时间。
[0102] 进一步地,所述监控单元47包括:
[0103] 启动模块471,可以用于启动所述动态链接库中的函数hook被保护程序的函数块作为监控函数块;
[0104] 监控模块472,可以用于根据所述函数hook被保护程序的函数块监控所述调用函数被调用的起始时间和结束时间,得到所述调用函数的调用时间。
[0105] 进一步地,所述启动模块471,还可以用于在所述启动所述动态链接库中的函数hook被保护程序的函数块作为监控函数块之前,根据所述调用函数的函数信息获取所述调用函数的函数类型;当所述调用函数的函数类型为可直接执行函数时,通过模块句柄载入动态链接库;当所述调用函数的函数类型为不可直接执行函数时,通过加载模块载入动态链接库。
[0106] 进一步地,所述监控模块472,还可以用于当调用函数被调用时,通过所述函数hook被保护程序的函数块获取所述调用函数的起始地址;从堆栈中读取指定存储空间中的地址取值,所述指定存储空间是用于存储函数返回地址的;查找所述地址取值所指向指令的上一条指令所指向的地址;判断所述上一条指令所指向的地址是否与所述调用函数的起始地址相同,如果相同,则监控所述调用函数被调用的起始时间和结束时间,得到调用函数的调用时间。
[0107] 由于在程序运行过程中,不同函数的调用时间有所不同,在函数保护的过程中,如果加保护后的函数对应的调用时间与未加保护的函数对应的调用时间相差较大,会导致程序运行效率低下,同时也使得保护后的可执行程序体积过大,本发明实施例通过对函数调用时间的监控,能够兼顾安全的情况下达到程序体积和效率的平衡,在检查应用程序时候,通过对调用函数的调用时间进行分析,能够进一步确定该函数是否需要加保护,如果调用时间相比加保护之前增加过多,则说明该函数不需要加保护,这样能够帮助软件开发人员后续优化编写的应用程序,同时在分析应用程序的过程中找到需要加保护的函数,从而对函数进行加壳保护。
[0108] 本发明实施例提供的另一种函数调用时间的监控装置,通过对调用函数的调用时间进行监控,从而根据函数的调用时间来判定函数是否需要加保护,对于需要加保护的函数,对该函数进行加壳保护,对于不需要加保护的函数,取消对该函数的保护,进而提高程序的运行效率。
[0109] 所述函数调用时间的监控装置包括处理器和存储器,上述第一创建单元31、载入单元32、启动单元33和监控单元34等均作为程序单元存储在存储器中,由处理器执行存储在存储器中的上述程序单元来实现相应的功能。
[0110] 处理器中包含内核,由内核去存储器中调取相应的程序单元。内核可以设置一个或以上,通过调整内核参数来节省人力,能够实现函数调用时间的监控,从而更好了解函数是否需要加保护。
[0111] 存储器可能包括计算机可读介质中的非永久性存储器,随机存取存储器(RAM)和/或非易失性内存等形式,如只读存储器(ROM)或闪存(flash RAM),存储器包括至少一个存储芯片。
[0112] 本申请还提供了一种计算机程序产品,当在数据处理设备上执行时,适于执行初始化有如下方法步骤的程序代码:通过挂起的方式创建监控进程,所述监控进程中包含有预设容量的动态内存;将用于监控函数调用时间的预设分析代码载入所述动态内存中;启动所述监控进程,根据所述预设分析代码加载需要注入至所述监控进程的动态链接库;根据所述动态链接库中的监控函数块监控所述调用函数被调用的起始时间和结束时间,得到调用函数的调用时间。
[0113] 本领域内的技术人员应明白,本申请的实施例可提供为方法、系统、或计算机程序产品。因此,本申请可采用完全硬件实施例、完全软件实施例、或结合软件和硬件方面的实施例的形式。而且,本申请可采用在一个或多个其中包含有计算机可用程序代码的计算机可用存储介质(包括但不限于磁盘存储器、CD-ROM、光学存储器等)上实施的计算机程序产品的形式。
[0114] 本申请是参照根据本申请实施例的方法、设备(系统)、和计算机程序产品的流程图和/或方框图来描述的。应理解可由计算机程序指令实现流程图和/或方框图中的每一流程和/或方框、以及流程图和/或方框图中的流程和/或方框的结合。可提供这些计算机程序指令到通用计算机、专用计算机、嵌入式处理机或其他可编程数据处理设备的处理器以产生一个机器,使得通过计算机或其他可编程数据处理设备的处理器执行的指令产生用于实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能的装置。
[0115] 这些计算机程序指令也可存储在能引导计算机或其他可编程数据处理设备以特定方式工作的计算机可读存储器中,使得存储在该计算机可读存储器中的指令产生包括指令装置的制造品,该指令装置实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能。
[0116] 这些计算机程序指令也可装载到计算机或其他可编程数据处理设备上,使得在计算机或其他可编程设备上执行一系列操作步骤以产生计算机实现的处理,从而在计算机或其他可编程设备上执行的指令提供用于实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能的步骤。
[0117] 在一个典型的配置中,计算设备包括一个或多个处理器(CPU)、输入/输出接口、网络接口和内存。
[0118] 存储器可能包括计算机可读介质中的非永久性存储器,随机存取存储器(RAM)和/或非易失性内存等形式,如只读存储器(ROM)或闪存(flash RAM)。存储器是计算机可读介质的示例。
[0119] 计算机可读介质包括永久性和非永久性、可移动和非可移动媒体可以由任何方法或技术来实现信息存储。信息可以是计算机可读指令、数据结构、程序的模块或其他数据。计算机的存储介质的例子包括,但不限于相变内存(PRAM)、静态随机存取存储器(SRAM)、动态随机存取存储器(DRAM)、其他类型的随机存取存储器(RAM)、只读存储器(ROM)、电可擦除可编程只读存储器(EEPROM)、快闪记忆体或其他内存技术、只读光盘只读存储器(CD-ROM)、数字多功能光盘(DVD)或其他光学存储、磁盒式磁带,磁带磁磁盘存储或其他磁性存储设备或任何其他非传输介质,可用于存储可以被计算设备访问的信息。按照本文中的界定,计算机可读介质不包括暂存电脑可读媒体(transitory media),如调制的数据信号和载波。
[0120] 以上仅为本申请的实施例而已,并不用于限制本申请。对于本领域技术人员来说,本申请可以有各种更改和变化。凡在本申请的精神和原理之内所作的任何修改、等同替换、改进等,均应包含在本申请的权利要求范围之内。