具体实施方式
为使本发明实施例的目的、技术方案和优点更加清楚,下面将结合本发明实施例中的附图,对本发明实施例中的技术方案进行清楚地描述,显然,所描述的实施例是本发明一部分实施例,而不是全部的实施例。基于本发明中的实施例,本领域普通技术人员在没有做出创造性劳动前提下所获得的所有其他实施例,都属于本发明保护的范围。
图1为本发明实施例提供的监控进程方法的流程图,如图1所示,该方法包括:S1,获知当前运行的所有进程中存在客户端程序的进程;S2,获取所述客户端程序的进程模块信息,并接收所述客户端程序传输的配置信息;S3,将所述进程模块信息与所述配置信息进行校验;S4,若校验结果不一致,则终止所述客户端程序运行;或者若校验结果一致,则允许所述客户端程序继续运行。
其中,客户端也可称为用户端,是指与服务器相对应,为客户提供本地服务的程序。除了一些只在本地运行的应用程序之外,一般安装在普通的客户机上,需要与服务端互相配合运行。因特网发展以后,较常用的用户端包括了如万维网使用的网页浏览器、收寄电子邮件时的电子邮件客户端、观看直播时的直播软件客户端、以及即时通讯的客户端软件等。对于这一类应用程序,需要网络中有相应的服务器和服务程序来提供相应的服务,如数据库服务,电子邮件服务等等,这样在客户机和服务器端,需要建立特定的通信连接,来保证应用程序的正常运行。
其中,进程是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。程序是指令、数据及其组织形式的描述,进程是程序的实体。
具体地,在监控客户端程序的进程之前,先建立一个独立的服务程序,并在服务器端对客户端程序需要校验的模块及代码进行配置。当服务程序获知当前运行的所有进程中存在客户端程序的进程时,也就是说客户端程序正在启动或者运行,此时服务程序会去获取客户端程序的进程模块信息,例如,进程模块信息为该客户端程序进程所有加载的动态链接库(Dynamic LinkLibrary,DLL)信息,并且此时服务程序会接收到客户端程序传输的配置信息。然后服务程序将DLL信息与配置信息进行校验,若校验结果不一致,说明模块被修改,此时服务程序将终止该客户端程序运行;若校验结果一致,说明模块处于正常状态,此时服务程序将允许该客户端程序继续运行。
本发明实施例与现有技术相比,通过一个独立的服务程序监控客户端程序的进程,当获知客户端程序正在启动或运行时,服务程序对该客户端程序的进程模块信息与配置信息进行校验,若校验结果不一致,则关闭该客户端程序的进程,阻止该客户端程序继续运行,从而达到监控客户端程序是否被修改的目的。并且这种监控进程的方法,其校验与被校验是两个不同的进程,能够对服务程序自身起到比较好的隐藏保护作用,同时在客户端程序被校验时,也不会影响到客户端程序自身的运行。
其中,在服务程序建立好之后,会随着客户端程序一起打包到安装程序中,当第一次启动客户端程序时,则会调用系统命令来注册一个服务程序。注册服务程序可以使用命令行:
sc create svnserve binpath=“服务程序的全路径”
然后调用命令行:
sc start服务名
来启动服务程序,其中服务名则是编写的服务程序注册的服务的名称,这样就实现了服务程序的打包及启动。通过将服务程序与客户端程序打包到一个安装包中,可以让用户在下载一次安装包的情况下,既可以下载客户端程序的安装包,又可以下载校验该客户端程序的服务程序的安装包,为用户的安装提供方便。服务程序的建立步骤如下:
1、定义一个服务转发表结构
SERVICE_TABLE_ENTRY ServiceTable;
ServiceTable[0].lpServiceName=_T(SERVICE_NAME);
ServiceTable[0].lpServiceProc=(LPSERVICE_MAIN_FUNCTION)service_main;
其中转发表的结构是SERVICE_TABLE_ENTRY,定义的变量是ServiceTable。而转发表中有2个属性,一个是注册的服务的名称,一个是服务的回调函数。其中服务的名称指创建的服务程序的名称,而回调函数则指明服务程序启动后会去执行的函数。
2、注册服务入口函数
通过调用系统API函数StartServiceCtrlDispatcher来注册服务的入口函数。其中参数则填入步骤1创建的服务转发表,从而在系统中创建了服务名称和入口函数的对应关系。当服务程序启动时则会调用对应的入口函数逻辑。
3、编写服务停止的回调函数
当服务程序被停止时,则需要进行一些服务的清理工作,包括释放资源等等。即在服务程序启动时会创建一个线程来监控客户端程序软件进程的启动,那么在服务程序被停止时,则需要停止这个线程的执行,并释放线程。
此函数的原型如下:
voidWINAPI ServiceHandler(DWORD fdwControl)
其中参数DWORD fdwControl标示服务控制事件类型。
那么当收到类型为SERVICE_CONTROL_STOP、SERVICE_CONTROL_SHUTDOWN则标示服务被停止,那么此时则需要停止线程的执行。具体为调用Windows的函数TerminateThread来停止线程,其中传入创建的线程句柄。
4、编写服务的入口函数
当服务程序启动后会调用这个入口函数,所以服务程序的所有逻辑都编写在这个入口函数中。其函数原型如下:
voidWINAPI service_main(int argc,char**argv)
在此函数中需要编写创建服务停止的回调函数注册,同时需要创建一个线程来执行后续的监控客户端程序软件进程的启动功能。其中Windows函数RegisterServiceCtrlHandler则是用来注册一个服务的回调函数,其函数原型如下:
SERVICE_STATUS_HANDLE WINAPI RegisterServiceCtrlHandler(LPCTSTRlpServiceName,
LPHANDLER_FUNCTION lpHandlerProc
);
其中参数LPCTSTR lpServiceName,标示服务的名称。
其中参数LPHANDLER_FUNCTION lpHandlerProc标示服务的回调函数。
此回调函数则对应于步骤3编写的服务停止的回调函数,当服务停止时则会调用步骤3编写的函数。同时在服务程序的入口函数中还要创建一个线程来监控客户端程序软件进程的启动。
调用Windows函数CreateThread来创建线程,实现如下:
HANDLE task_handle=CreateThread(NULL,NULL,check_thread,NULL,NULL,NULL);
其中最重要的是线程的回调执行函数check_thread函数,此函数执行线程的整个逻辑功能。
至此,服务程序的建立过程已经完成,然后将服务程序与客户端程序一起打包到安装程序中,方便用户下载安装。
在上述实施例的基础上,所述S1进一步包括:每隔预设时间枚举当前运行的所有进程,并判断所述所有进程中是否存在所述客户端程序的进程。
服务程序获知当前运行的所有进程中存在客户端程序的进程进一步包括:服务程序会每隔预设时间枚举系统当前运行的所有进程,例如,预设时间为30秒或者15秒等任意时间值,在本发明实施例中预设时间以30秒为例,但并不用于限制本发明的保护范围。则服务程序会每隔30秒去枚举系统当前运行的所有进程,然后在当前运行的所有进程中判断是否存在该客户端程序的进程,如果存在该客户端程序的进程,说明该客户端程序正在启动或者运行。此时服务程序会去获取该客户端程序的进程模块信息,并对该进程模块信息进行校验,若校验结果不一致,说明模块被修改,服务程序将阻止该客户端程序继续运行。
在本发明实施例中,通过服务程序每隔预设时间去枚举当前运行的所有进程,并在当前运行的所有进程中判断是否存在该客户端程序的进程,达到实时监控客户端程序的进程的目的,从而能够实时校验客户端程序是否被修改的目的,提高安全性。
在上述实施例的基础上,所述S2进一步包括:客户端程序每次登录时,服务器将所述配置信息发送至所述客户端程序,所述客户端程序再将所述配置信息通过进程间通信的方式传输至所述服务器。
其中,进程间通信(Interprocess communication,IPC)是一组编程接口,让程序员能够协调不同的进程,使之能在一个操作系统里同时运行,并相互传递和交换信息。这使得一个程序能够在同一时间里处理许多用户的要求。因为即使只有一个用户发出要求,也可能导致一个操作系统中多个进程的运行,进程之间必须互相通话,IPC接口就提供了这种可能性。IPC包括管道(PIPE)、消息排队、旗语、共用内存以及套接字(Socket)。
在本发明实施例中,进程间通信的方式以命名管道的方式为例进行说明,但不用于限制本发明的保护范围。其中,“命名管道”又名“命名管线”(Named Pipes),是一种简单的进程间通信(IPC)机制,MicrosoftWindows大都提供了对它的支持(但不包括WindowsCE)。命名管道可在同一台计算机的不同进程之间或在跨越一个网络的不同计算机的不同进程之间,支持可靠的、单向或双向的数据通信。采用命名管道作为进程通信方案的一项重要原因是因为它们可以充分利用Windows内建的安全特性(ACL等)。
具体地,在客户端程序登录时便会与服务器建立连接关系,此时服务器将事先配置需要校验的配置信息发送至该客户端程序,并且当在服务器端对该客户端程序的配置进行更新时,客户端程序也可以通过服务器发送的配置信息进行更新,从而达到不断更新客户端程序的目的。然后客户端程序再将该配置信息通过命名管道的方式传输至服务器,例如,服务器为服务程序,也就是说,客户端程序每开启一次都会与服务程序建立一次命名管道通信,通过该命名管道通信的方式将客户端程序接收到的配置信息传输至服务程序。在客户端程序有更新的情况下,服务程序接收到的配置信息也随着客户端程序的更新而更新,使得服务程序对不断更新的客户端程序同样能起到监控作用。然后服务程序将该配置信息与其获取的客户端程序的进程模块信息进行校验,达到监控客户端程序是否被修改的目的。
在本发明实施例中,服务器在客户端程序每次登陆时将所述配置信息发送至所述客户端程序,所述客户端程序再将所述配置信息通过进程间通信的方式传输至服务器,达到不断更新配置信息和客户端程序的目的,并且服务器也可以根据更新的配置信息对不断更新的客户端程序进行校验。
在上述实施例的基础上,所述S2中的配置信息包括:所述客户端程序中的模块名称、模块基址、模块代码段起始地址、模块代码长度和校验值。
具体地,在服务器端配置客户端程序需要被校验的配置信息时,该配置信息包括:客户端程序中的模块名称、模块基址、模块代码段起始地址、模块代码长度和校验值。服务器可以使用正确的模块计算得到正确的校验值。在客户端程序启动时,服务器将配置好的配置信息发送至客户端程序,客户端程序再通过进程间通信的方式传输至服务程序。
在上述实施例的基础上,所述S1进一步包括:通过调用函数CreateThread来创建线程函数,所述线程函数用于每隔预设时间枚举当前运行的所有进程,并判断所述所有进程中是否存在所述客户端程序的进程。
其中,函数CreateThread是WindowsAPI函数。该函数在主线程的基础上创建一个新线程。
具体地,通过启动服务程序则会调用函数CreateThread来创建一个线程函数,该线程函数用于监控客户端程序的启动。即线程函数每隔预设时间(例如,预设时间为30秒)去枚举系统当前运行的所有进程,然后判断当前进程中是否有客户端程序的进程,如果有则调用对客户端程序进程模块的检测功能,如果没有则继续等待下次预设时间来枚举。
调用Windows函数CreateThread来创建线程函数,具体如下:
HANDLE task_handle=CreateThread(NULL,NULL,check_thread,NULL,NULL,NULL);
其中最重要的是线程的回调执行函数check_thread函数,此函数执行线程的整个逻辑功能。
线程函数枚举系统当前运行的所有进程,并判断当前进程中是否有客户端程序进程的步骤具体如下:
1、获取系统进程名列表的快照
hSnapshot=CreateToolhelp32Snapshot(TH32CS_SNAPALL,0)
通过调用系统API函数CreateToolhelp32Snapshot来获取系统进程名的快照,其中传入参数1TH32CS_SNAPPROCESS,标示获取的是进程的快照,第二个参数为0标示获取当前系统的进程列表。
2、获取第一个进程的名字
Process32First(hSnapshot,&procEntry32)
通过调用系统API函数Process32First来获取系统的第一个进程的信息。其中第一个参数hSnapshot是步骤1获取进程列表快照的句柄,第二个参数则用于返回获取的进程的信息,其中procEntry32有一个属性szExeFile是进程的名字,所以procEntry32.szExeFile是进程的名字。
3、获取系统剩下所有进程的名字
while(bMore){
bMore=Process32Next(hProcessSnap,&procEntry32);}
通过一个while循环来调用函数Process32Next不断的获取下一个进程的名字,直到所有进程都获取完毕。每调用一次Process32Next则从procEntry32.szExeFile中获取到一个进程的名字。通过上述步骤可以获取到系统当前运行的所有进程名称列表。
4、从所有进程名称列表中判断是否存在客户端程序的进程
获取到系统当前运行的所有进程名列表后,可以从所有进程列表中判断是否存在客户端程序的进程。如果存在该客户端程序的进程,则后续会获取客户端进程中的模块信息,然后对每个模块进行校验。
在本发明实施例中,服务程序通过调用函数CreateThread来创建一个线程函数,然后通过该线程函数监控客户端程序的启动,当客户端程序启动或者运行时,服务程序就会对其进行校验,从而达到实时校验客户端程序是否被修改的目的,提高安全性。
在上述实施例的基础上,所述S2中获取所述客户端程序的进程模块信息进一步包括:通过调用函数CreateToolhelp32Snapshot来获取所述客户端程序的进程模块信息。
其中,CreateToolhelp32Snapshot可以通过获取进程信息为指定的进程、进程使用的堆[HEAP]、模块[MODULE]、线程建立一个快照。
具体地,当服务程序的线程函数监控到客户端程序在启动或者运行后,则会调用函数CreateToolhelp32Snapshot去获取客户端程序的所有加载模块信息,然后对每个模块进行校验。具体实现如下:
通过调用WindowsAPI函数CreateToolhelp32Snapshot来获取加载的所有模块列表的快照。
CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,ProcessID);
其中参数TH32CS_SNAPMODULE标示获取客户端程序进程模块的快照。
其中参数ProcessID则是客户端程序进程的ID。
bModule=Module32First(hModule,&mem32);
然后调用WindowsAPI函数Module32First来获取第一个模块的名称。其中mem32结构中szExePath则是模块的名称。
while(bModule)
{bModule=Module32Next(hModule,&mem32);}
然后通过一个while循环不断的调用函数Module32Next来获取下一个模块的名称。其中mem32结构中szExePath则是模块的名称,其中mem32结构中modBaseAddr则是模块加载的内存基址。通过上述步骤则获取到客户端程序进程加载的所有模块的名称列表。
在本发明实施例中,当服务程序监控到客户端程序启动或者运行后,则通过调用函数CreateToolhelp32Snapshot来获取所述客户端程序的进程模块信息,然后对进程模块信息进行校验,达到只要客户端程序启动或者运行,则对其进行校验的目的,提高安全性。
在上述实施例的基础上,所述S3中的所述进程模块信息与所述配置信息进行校验为进行HASH校验。
其中,HASH一般翻译为“散列”,也可直接音译为“哈希”,就是把任意长度的输入(又叫做预映射,pre-image),通过散列算法,变换成固定长度的输出,该输出就是散列值。简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。
具体地,在服务程序已经获取到客户端程序的进程模块信息后,例如,进程模块信息为客户端程序所有加载的模块名称、模块基址、模块代码段起始地址和模块代码长度。从而可以从服务器下发到客户端程序,然后客户端程序再传输至服务程序的配置信息中来对客户端程序中的每个模块的代码进行HASH校验。由于每个模块在内存中加载的起始地址不一样,所以先需要对校验的模块代码进行安装、服务器下发的地址进行重定位,重定位后再来计算模块的内存HASH值。HASH计算后再校验结果是否一致,如果校验结果一致表明该模块是正常的没有被修改,此时服务程序将允许客户端程序继续运行,如果校验结果不一样则说明模块被修改,此时服务程序将终止客户端程序的运行。
图2为本发明实施例提供的监控进程装置的结构框图,如图2所示,该装置包括获知模块201、处理模块202、校验模块203和执行模块204。获知模块201用于获知当前运行的所有进程中存在客户端程序的进程。处理模块202用于获取客户端程序的进程模块信息,并接收所述客户端程序传输的配置信息。校验模块203用于将所述进程模块信息与所述配置信息进行校验。执行模块204用于若校验结果不一致,则终止所述客户端程序运行;或者若校验结果一致,则允许所述客户端程序继续运行。
具体地,在监控客户端程序的进程之前,在服务器端对客户端程序需要校验的模块及代码进行配置。当获知模块201获知系统当前运行的所有进程中存在客户端程序的进程,也就是说客户端程序正在启动或者运行,此时处理模块202会去获取客户端程序的进程模块信息,此时处理模块202还会接收到客户端程序传输的配置信息。然后校验模块203将进程模块信息与配置信息进行校验,执行模块204根据校验结果来确定是否允许客户端程序继续运行,若校验结果不一致,说明模块被修改,此时执行模块204将终止该客户端程序运行;或者若校验结果一致,说明模块处于正常状态,此时执行模块204将允许该客户端程序继续运行。
本发明实施例与现有技术相比,通过判断模块监控客户端程序的进程,当获知客户端程序正在启动或者运行时,处理模块会去获取客户端程序的进程模块信息,然后校验模块对该进程模块信息进行校验,最后执行模块根据校验结果来确定是否允许客户端程序继续运行,从而达到监控客户端程序是否被修改的目的。并且这种监控进程的方法,其校验和被校验是两个不同的进程,能够对服务程序自身起到比较好的隐藏保护作用,同时在对客户端程序被校验时,也不会影响到客户端程序自身的运行。
在上述图2所示实施例的基础上,所述获知模块201进一步用于每隔预设时间枚举当前运行的所有进程,并判断所述所有进程中是否存在所述客户端程序的进程。
获知模块201获知当前运行的所有进程中存在客户端程序的进程具体为:获知模块201会每隔预设时间枚举系统当前运行的所有进程,例如,预设时间为30秒或者15秒等任意时间值,在本发明实施例中预设时间以20秒为例,但并不用于限制本发明的保护范围。则获知模块201会每隔20秒去枚举系统当前运行的所有进程,然后在所有进程中判断是否存在该客户端程序的进程,如果存在该客户端程序的进程,说明该客户端程序正在启动或者运行。此时处理模块202会去获取该客户端程序的进程模块信息,然后校验模块203对该进程模块信息进行校验,执行模块204再根据校验结果确定是否允许客户端程序继续运行,若校验结果不一致,说明模块被修改,则阻止该客户端程序继续运行。
在本发明实施例中,通过获知模块每隔预设时间去枚举系统当前运行的所有进程,并在所有进程中判断是否存在该客户端程序的进程,达到实时监控客户端程序的进程的目的,并能够实时校验客户端程序是否被修改的目的。
在上述各实施例提供的监控客户端程序的方法及装置,通过注册一个服务程序,然后通过服务程序每隔预设时间去枚举系统当前运行的所有进程,如果获知当前运行的所有进程中存在该应用程的进程,则服务程序同时会去获取该客户端程序进程所有加载的DLL信息,并对该DLL中的代码进行校验,若校验结果不一致,则关闭该客户端程序进程,阻止该客户端程序继续使用,从而达到实时监控客户端程序是否被黑客修改的目的。并且这种监控客户端程序的方法,其校验与被校验是两个不同的进程,能够对服务程序自身起到比较好的隐藏保护作用,同时在本方法中只要该客户端程序进程存在,服务程序会一直对该进程的所有模块进行校验,提高安全性。
最后应说明的是:以上实施例仅用以说明本发明的技术方案,而非对其限制;尽管参照前述实施例对本发明进行了详细的说明,本领域的普通技术人员应当理解:其依然可以对前述各实施例所记载的技术方案进行修改,或者对其中部分技术特征进行等同替换;而这些修改或者替换,并不使相应技术方案的本质脱离本发明各实施例技术方案的精神和范围。