一种程序保护方法及相关装置与流程

文档序号:18106446发布日期:2019-07-06 11:41阅读:144来源:国知局
一种程序保护方法及相关装置与流程

本申请涉及软件开发领域,尤其涉及一种程序保护方法及相关装置。



背景技术:

当今应用程序已经深入到生活的方方面面,在人们的饮食、出行、交通等领域均扮演着越来越重要的角色,因此对于一些有安全考虑的应用程序或者有核心算法需要保护的程序来说,通常的都需要对其算法进行保护,防止黑客通过逆向分析调试的方法来分析清楚其中的逻辑,从而盗取了其核心功能的算法。

然而,在现有技术中,为了防止破解者对软件进行破解,通常采用反调试的方式进行保护,但是破解者可以根据反调试应用程序编程接口(applicationprogramminginterface,api)名称找到反调试保护软件的位置,进而修改跳转指令从而达到绕过反调试函数、最终去除反调试保护的效果。因此在程序中需要更加好的检测当前程序是否有被逆向调试的方法,同时还需要能够比较可靠和正常的退出程序阻止黑客进行进一步的调试核心代码。



技术实现要素:

本申请实施例提供了一种程序保护方法及相关装置,用于提高检测程序逆向调试的效率。

本申请实施例的第一方面提供了一种程序保护方法,包括:确定程序中的核心函数,所述核心函数为运行所述程序时必须执行的函数;获取开始执行所述核心函数的第一时间和结束执行所述核心函数的第二时间;判断所述第二时间与所述第一时间的时间差是否大于预设值;若所述第二时间与所述第一时间的时间差大于所述预设值,则确定所述程序被非法调试,并退出所述程序。

在一种可能的实施例中,所述获取开始执行所述核心函数的第一时间和结束执行所述核心函数的第二时间包括:在时间函数组中选择目标函数,所述时间函数组中的函数用于获取当前时间;在所述核心函数的起始位置和所述核心函数的结束位置分别加入所述目标函数;当开始执行所述核心函数时,通过调用所述目标函数获取所述第一时间;当所述核心函数执行结束时,通过调用所述目标函数获取所述第二时间。

在一种可能的实施例中,所述在时间函数组中选择目标函数包括:

当所述时间函数组包括各函数和与所述各函数对应的编号,且所述编号为区间[0,n-1]中的整数时,通过调用函数rand()获取随机数据,所述n用于表示所述时间函数组中函数的总个数;根据以下求余公式确定所述目标函数:m=nrand%n;其中,所述m用于表示所述目标函数在所述时间函数组中的编号,所述nrand用于表示所述随机数据。

在一种可能的实施例中,所述方法还包括:接收服务器发送的远程调试消息,所述远程调试消息用于指示检测指定函数是否被调试,所述远程调试消息包括用于索引所述指定函数的位置信息,和时间阈值;响应于所述远程调试消息,根据所述位置信息确定所述指定函数,并在所述指定函数的起始位置和所述指定函数的结束位置分别加入所述目标函数;根据所述目标函数确定执行所述指定函数时的第三时间和结束执行所述指定函数时的第四时间;若所述第四时间与所述第三时间的时间差大于所述时间阈值,则确定所述指定函数被调试;若所述第四时间与所述第三时间的时间差小于所述时间阈值,则确定所述指定函数未被调试。

在一种可能的实施例中,所述位置信息包括所述指定函数所在模块的名称、所述指定函数的偏移量和所述指定函数的长度,所述根据所述位置信息确定所述指定函数包括:通过调用函数getmodulehandle()获取所述模块在内存中的起始地址,所述函数getmodulehandle()的输入参数为所述模块的名称;按照如下方式确定所述指定函数:dwstart=module+offset;dwend=module+offset+length;其中,所述dwstart用于表示所述指定函数的起始位置,所述dwend用于表示所述指定函数的结尾位置,所述module用于表示所述模块在内存中的起始地址,所述offset用于表示所述指定函数的偏移量,所述length用于表示所述指定代码的长度。

在一种可能的实施例中,所述退出所述程序包括:通过调用循环函数创建多个线程;当所述程序被调试时,通过所述各线程调用退出函数,以退出所述程序,所述退出函数包括函数pthread_exit或者函数abort;或者,删除或者修改所述程序中的内存代码,以使得所述程序崩溃并退出。

在一种可能的实施例中,所述核心函数为用于接收数据的接收函数、用于发送数据的发送函数或者用于准备关键数据的函数。

本申请实施例的第二方面提供了一种客户端,包括:确定函数,用于确定程序中的核心函数,所述核心函数为运行所述程序时必须执行的函数;获取函数,用于获取开始执行所述核心函数的第一时间和结束执行所述核心函数的第二时间;判断函数,用于判断所述第二时间与所述第一时间的时间差是否大于预设值;退出函数,用于若所述第二时间与所述第一时间的时间差大于所述预设值,则确定所述程序被非法调试,并退出所述程序。

本申请第三方面提供了一种电子设备,包括存储器、处理器,其特征在于,所述处理器用于执行存储器中存储的计算机管理类程序时实现如上述任意一项所述的方法的步骤。

本申请第四方面提供了一种计算机可读存储介质,其上存储有计算机管理类程序,其特征在于:所述计算机管理类程序被处理器执行时实现如上述任意一项所述的方法的步骤。

从以上技术方案可以看出,本申请实施例具有以下优点:确定程序中的核心函数,所述核心函数为运行所述程序时必须执行的函数;获取开始执行所述核心函数的第一时间和结束执行所述核心函数的第二时间;判断所述第二时间与所述第一时间的时间差是否大于预设值;若所述第二时间与所述第一时间的时间差大于所述预设值,则确定所述程序被非法调试,并退出所述程序。本申请实施例中,由于不需要对程序中的所有函数进行检测,而是通过选择的核心函数来进行检测,并提供了多种检测核心函数是否被逆向调试的方式,以及提供了多种程序退出的方式,提高检测程序逆向调试的效率。

附图说明

图1为本申请实施例提供的一种可能的程序保护方法的流程图;

图2为本申请实施例提供的一种可能的客户端的结构示意图;

图3为本申请实施例提供的一种可能的电子设备的硬件结构示意图;

图4为本申请实施例提供的一种可能的计算机可读存储介质的硬件结构示意图。

具体实施方式

本申请实施例提供了一种程序保护方法及相关装置,用于提高检测程序逆向调试的效率。

下面将结合本申请实施例中的附图,对本申请实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例仅仅是本申请一部分实施例,而不是全部的实施例。基于本申请中的实施例,本领域技术人员在没有做出创造性劳动前提下所获得的所有其他实施例,都属于本申请保护的范围。

本申请的说明书和权利要求书及上述附图中的术语“第一”、“第二”、“第三”、“第四”等(如果存在)是用于区别类似的对象,而不必用于描述特定的顺序或先后次序。应该理解这样使用的数据在适当情况下可以互换,以便这里描述的实施例能够以除了在这里图示或描述的内容以外的顺序实施。此外,术语“包括”和“具有”以及他们的任何变形,意图在于覆盖不排他的包含,例如,包含了一系列步骤或单元的过程、方法、系统、产品或设备不必限于清楚地列出的那些步骤或单元,而是可包括没有清楚地列出的或对于这些过程、方法、产品或设备固有的其它步骤或单元。

本申请提供了一种程序保护方法,请参阅图1,为本申请实施例提供的一种程序保护方法的流程图,具体包括:

101、确定程序中的核心函数;

本申请实施例中,需要对代码进行检测以确定程序是否被黑客非法调试,为提高检测效率,不需要对程序中的所有代码都进行检测,而是在程序中挑选核心的代码逻辑即核心函数进行调试检测,该核心函数可以理解为程序正常运行时必须执行的函数。因此,通过对核心函数进行调试检测,不仅可以提高程序的效率也可以起到程序的保护效果。具体地,核心函数可以为用于接收数据的接收函数、用于发送数据的发送函数或者用于准备关键数据的函数,例如当该核心函数为用于准备关键数据的函数时,假设实际应用中,需要对关键数据计算其签名的sign值,那么如何计算sign值则是安全关键代码逻辑,如果黑客通过逆向调试分析清楚该安全关键代码逻辑的实现,则可以实现去伪造这样的sign值。可以理解的是,在计算sign值时肯定会先准备好数据再计算签名。可选的,可通过函数papredata()准备计算sign值所需要的数据,具体实现函数如下:

stringpapredata(){

stringdata=time+did+uid+url+info;

returndata;

}

其中,data为返回的数据,即需要进行计算签名的信息,其中time表示时间参数,did表示设备的唯一id,uid表示用户的唯一id,url表示参与计算的网络地址信息,info表示其他参与计算的参数,故通过函数papredata()返回了一个需要计算签名的字符串信息。

在通过papredata()准备好数据即data后,将data作为函数getsign()的输入参数,以得到data的签名信息sign值,具体函数实现包括:stringgetsign(stringdata)。因此在该例子中,进行计算签名之前一定会首先调用函数papredata()来准备数据,故可以将此函数papredata()挑选为核心函数后续来加入调试检测逻辑。可以理解的是,由于函数getsign()也是肯定会执行的函数,因此也可以将函数getsign()作为核心函数,在该函数getsign()中也加入调试检测逻辑。

102、获取开始执行核心函数的第一时间和结束执行核心函数的第二时间;

需要说明的是,由于逆向调试都是通过调试器来附加到程序中对代码执行进行调试,那么其附加后是由人为手动的调试每一行汇编代码,那么调试会非常的消耗时间,而正常的若是由中央处理器(centralprocessingunit,cpu)来执行,其速度是非常的快。因此通过两者的对比差异则可以发现程序是否在被调试。有鉴于此,在选择了核心函数后,可以在执行核心函数的函数头获取当前时间,在执行核心函数的函数尾再次的获取当前时间,通过时间的差值则可以发现核心函数是否被黑客所在调试。需要说明的是,获取的两个检测时间可以放到程序的任意位置,例如放到核心函数的函数头和函数尾,也可以放到一段代码执行逻辑中,具体此处不做限定。

故本申请实施例中,需要在核心函数的起始位置即函数头部以及核心函数的结束位置即函数尾部均加入获取当前时间的逻辑函数,以获取开始执行核心函数的第一时间和结束执行核心函数的第二时间。为便于理解,假设核心函数为函数papredata(),且通过函数gettickcount()获取当前时间,则具体实现函数可能如下:

stringpapredata(){

uint64_ttimestart=gettickcount();

stringdata=time+did+uid+url+info;

uint64_ttimeend=gettickcount();

则在函数papredata()开始执行时,获取当前时间即第一时间timestart,在函数papredata()执行结束时,再获取当前时间即第二时间timeend。

需要说明的是,实际应用中,获取当前时间的函数有多种,除了函数gettickcount()外,还包括函数timegettime(),函数getsystemtime或者函数queryperformancecounter()等,具体此处不做限定。为了防止获取当前时间的函数被黑客所hook来阻止获取时间的准确性,本申请实施例中,可以在时间函数组中选择获取当前时间的函数,为便于描述,将该获取当前时间的函数称为目标函数,其中,该时间函数组中包括多个函数,且该多个函数均可用于获取当前时间。具体地,从时间函数组中选择目标函数的方式可以包括:若时间函数组包括各函数和与各函数对应的编号,且编号为区间[0,n-1]中的整数时,通过调用函数rand()获取随机数据,其中n用于表示时间函数组中函数的总个数;根据以下求余公式确定目标函数:m=nrand%n;其中,m用于表示目标函数在时间函数组中的编号,nrand用于表示随机数据。为便于理解,假设时间函数组中包括4个函数,即n=4,则具体实现函数可能如下:

uint64_tgetcurrenttime(){

intnrand=rand();

if(nrand%4==0){

returngettickcount();

}elseif(nrand%4==1){

returntimegettime();

}elseif(nrand%4==2){

returngetsystemtime();

}elseif(nrand%4==3){

returnqueryperformancecounter();

}

即通过函数rand()获得随机数据nrand,将随机数据nrand%4得到余数m,若m为0,则返回函数gettickcount()作为目标函数;若m为1,则返回函数timegettime()作为目标函数;若m为2,则返回函数getsystemtime()作为目标函数;若m为3,则返回函数queryperformancecounter()作为目标函数。

可选的,除了上述方式外,本申请实施例中,还可在时间函数组中随机选择一个函数作为目标函数,或者当核心函数有多个时,不同的核心函数采用不同的目标函数,具体此处不做限定。

因此,在确定了目标函数后,在核心函数的起始位置和核心函数的结束位置分别加入目标函数。当开始执行核心函数时,通过调用目标函数获取第一时间;当核心函数执行结束时,通过调用目标函数获取第二时间。

103、判断第二时间与第一时间的时间差是否大于预设值;

104、若第二时间与第一时间的时间差大于预设值,则确定程序被非法调试;

在通过目标函数获得第一时间与第二时间后,获取第二时间与第一时间的时间差,具体实现函数如下:

uint64_telapse=timeend-timestart;

其中,elapse用于表示第二时间与第一时间的时间差,timeend用于表示第二时间,timestart用于表示第一时间。

将该时间差与预设值进行比较,判断第二时间与第一时间的时间差是否大于预设值,若大于,则执行步骤104。需要说明的是,实际应用中,在程序未被调试的时候,此函数的执行时间可能是多少毫秒,基本绝大多数都不会超过1秒钟,大多数情况下,正常运行的函数在cpu执行情况下都会非常的快速,故实际应用中,可将该预设值设为1分钟。可以理解的是,部分函数的执行时间会超过1分钟,对于超过1分钟的函数,预设值可以设置的更大一些。为便于理解,本申请实施例中,假设预设值为1分钟,则判断第二时间与第一时间的时间差是否大于预设值的具体实现函数如下:

其中,第二时间与第一时间的时间差elapse的单位为毫秒,若elapse大于预设值,即60*1000,则确定该程序被非法调试,反之,说明程序未被非法调试,则返回签名后的数据。

需要说明的是,本申请实施例中,步骤101至步骤104是在实现挑选好核心函数后,对核心函数进行检测是否被黑客非法调试。而实际应用中,若程序已经发布到外围用户设备中,当后续发现有些函数也比较重要需要检测是否被调试时,为便于描述,将另外需要检测的函数称为指定函数,则只能通过在新版本中增加核心函数的调试检测后重新发布版本。

有鉴于此,本申请实施例还提供了一种方式,可以实现通过服务器远程来控制对指定函数增加反调试的检测,从而可以在不发布新的版本基础上来对指定函数增加反调试的检测。具体地,包括以下步骤:步骤1、接收服务器发送的远程调试消息,该远程调试消息用于指示检测指定函数是否被调试,远程调试消息包括用于索引指定函数的位置信息,和时间阈值;步骤2、响应于远程调试消息,根据位置信息确定指定函数,并在指定函数的起始位置和指定函数的结束位置分别加入目标函数;步骤3、再根据目标函数确定执行指定函数时的第三时间和执行指定函数时的第四时间;步骤4、若第四时间与第三时间的时间差大于时间阈值,则确定指定函数被调试;若第四时间与第三时间的时间差小于时间阈值,则确定指定函数未被调试。可以理解的是,该指定函数可以包括多个函数,则服务器下发的远程调试消息包括多个用于索引指定函数的位置信息,和对应的多个时间阈值。

为便于理解本方案,下面将结合具体的例子对步骤1至步骤4进行详细说明。

例如,当步骤1中接收到的远程调试消息中的位置信息包括指定函数所在模块的名称、指定函数的偏移量和指定函数的长度,则步骤2中根据位置信息确定指定函数具体包括:

通过调用函数getmodulehandle()获取模块在内存中的起始地址,其中该函数getmodulehandle()的输入参数为模块的名称,具体函数实现如下:

dwordmodule=getmodulehandle(“模块的名称”);

dwstart=module+offset;

dwend=module+offset+length;

其中,dwstart用于表示指定函数的起始位置,dwend用于表示指定函数的结尾位置,module用于表示模块在内存中的起始地址,offset用于表示指定函数的偏移量,length用于表示指定代码的长度。

在确定指定函数的起始位置和指定函数的结尾位置即确定指定函数后,可以通过微软提供的开源的detours库来对上述2处代码进行hook,从而通过目标函数得到两处代码的执行时间,实现上述步骤3。具体实现函数如下:

detourhook(dwstart,funcstart);

其中,detourhook是hook的接口,其中参数dwstart为指定函数的起始位置,是需要hook的内存地址,funcstart是编写的需要执行的额外逻辑,该额外逻辑则是通过调用目标函数获取指定函数执行的起始时间即第三时间,具体实现函数如下:

voidfuncstart(){

uint64_ttimestart=getcurrenttime();}

其中,timestart用于表示指定函数执行的起始时间即第三时间,函数getcurrenttime()为目标函数;类似的,再对指定函数的结尾位置进行hook,具体函数实现如下:

detourhook(dwend,funcend);

其中detourhook是hook的接口,参数dwend为指定函数的结尾位置,是需要hook的内存地址。funcend是编写的需要执行的额外逻辑,该额外逻辑则是通过调用目标函数获取指定函数执行的结束时间即第四时间,具体实现函数如下:

voidfuncend(){

uint64_ttimeend=getcurrenttime();

其中,timeend用于表示指定函数执行的结束时间即第四时间,函数getcurrenttime()为目标函数。再得到第三时间和第四时间后,判断第四时间和第三时间的时间差是否大于时间阈值,进而确定该指定函数是否被调试,即实现上述步骤4。具体实现函数如下:

uint64_telapse1=timeend-timestart;

if(elapse1>servertime){

}else{}}

其中,elapse1用于表示第四时间与第三时间的时间差,servertime用于表示时间阈值,若elapse1>servertime,则确定该指定函数被黑客非法调试;否则,则确定该指定函数未被调试。

105、退出程序。

若第二时间与第一时间的时间差大于预设值,或者第四时间与第三时间的时间差大于预设值,则确定程序被非法调试。当检查到程序被调试时,首先可以通过网络消息告知给服务器,从而服务器可以端开当前用户的网络连接,并且对该用户的账号信息进行封禁。进一步的需要阻止黑客进一步的调试程序,从而将程序终止执行或者将程序故意绕到虚假程序,消耗黑客的精力。如何更安全的退出,是本步骤编写的核心点。本申请实施例中,提供了多种程序退出的方式,提高黑客破解程序退出的难度。具体多种程序退出的方式包括:

方式1、多线程退出。

当检测到程序正在被非法调试时,通过多线程的方式产生多条退出机制,从而使得程序尽快的退出程序。由于各个线程都可以进行退出,并且每个线程都是独立的,都可以起到退出的功能,并且多线程更难调试和阻止,黑客必须阻止所有线程才能够阻止程序退出,对黑客来说,实现难度较大。具体实现多线程退出的方式如下:首先编写线程函数pthread(),该线程函数主要是杀掉当前程序,从而退出程序,黑客则无法继续进行逆向分析和调试,其中,退出程序可以通过调用函数pthread_exit来退出当前进程,或者调用函数abort来退出当前进程。具体实现函数如下:

staticvoid*pthread(void*arg){

exit(1);

abort();};

在编写了用于退出当前程序的线程函数pthread后,再通过线程创建函数pthread_create()创建线程,本实施例中可以通过编写一个for循环来创建多个线程,具体实现函数如下:

for(inti=0;i<m;i++){

pthread_create(&tidp,null,pthread,(void*)b))};

其中m为创建线程的个数,由于每个线程都会调用函数pthread(),故每个线程都会去执行退出逻辑,以退出程序。

方式2、通过删除内存代码或者修改内存代码来实现程序退出。

当检测到程序在被非法调试时,可以通过对程序中现有内存的代码进行删除或者修改,从而程序执行到被删除或者被修改的代码时,则会由于其不是原来的代码而导致程序崩溃,从而实现了程序退出功能。具体地,首先获取模块在内存中代码的起始地址,再获取模块的大小,实现函数可能如下:

dwordmodule=getmodulehandle(“模块的名称”);

dworddwsize=getmodulesize(“模块的名称”);

其中,module用于表示模块在内存中代码的起始地址,dwsize用于表示模块的大小。由于内存中的代码是只读可执行的内存属性,因此可将内存属性修改为可以写入属性。具体函数实现可能如下:

virtualprotect(module,dwsize,page_readwrite,&dwoldprotect);

其中,函数virtualprotect()用于对模块的内存属性进行修改,以修改成可以写入的属性,参数module则表示模块在内存中代码的起始地址;参数dwsize则表示模块的大小;参数page_readwrite表示修改内存属性为可以读写;参数dwoldprotect表示保存原有属性。接下来再通过函数memeset()将该段内存进行清0写操作,具体函数实现可能如下:

memset(module,dwsize,0);

其中,函数memeset()将上述模块的整个代码写成0,从而使得其不再是代码。当程序执行到此时则会产生程序崩溃,以实现程序退出的目的。

3、修改关键参数。

当检测到程序被调试时,还可以修改关键参数,使得程序计算不正常从而退出。该关键参数可以为多种,例如客户端与服务器的网络通信协议是加密的,客户端会存储密钥信息,那么当发现客户端被调试时,修改客户端的密钥,故客户端解密服务器的所有网络数据都不正常,导致程序无法继续执行,从而退出程序。具体地,假设客户端与服务器约定采用非对称加密方式来加密客户端与服务器之间的传输数据,其中,客户端侧用服务器下发的私钥解密传输数据,设该公私钥对为a-b,将客户端的私钥修改为c,则当客户端接收到服务器通过公钥a加密发送的数据时,客户端通过c并不能进行数据解密,导致程序无法继续执行,从而退出程序。

可选的,也可以修改客户端的加密密钥,从而发送到服务器的数据,服务器都无法解密,从而断开与客户端的连接。可选的,还可以修改客户端自身信息,如客户端的token数据,从而后续客户端无法与服务器进行数据传输。因此,选择修改的关键参数具体此处不做限定。

方式4、消耗黑客时间。

本文还提出了一种策略,通过不断的消耗黑客的调试时间使得黑客放弃分析。例如本申请实施例中可以在一些代码逻辑中增加循环次数。由于正常的情况下,程序只会执行一次,当发现黑客在调试时,则可以将循环次数设置的非常大。例如,在创建线程时,正常情况下只需要编写一个线程,当发现程序被黑客调试时,可以编写一个for循环来创建多个线程,具体实现函数如下:

for(inti=0;i<m;i++){

pthread_create()};

其中,函数pthread_create()用于创建编程,则可将该m设置为无穷大,这样调试时间足够长,使得黑客主动放弃分析。

综上,本申请实施例中,退出程序的方式有多种,具体此处不做限定。

本申请实施例中,采用了多种检测核心代码是否被调试的手段和退出程序机制,从而使得程序一旦检测到被调试则会退出程序阻止黑客进一步的逆向调试。提高了程序的逆向调试的效率,并保护了程序的安全性。

上面从程序保护方法的角度对本申请实施例进行了描述,下面从客户端的角度对本申请实施例进行描述。

请参阅图2,图2为本申请实施例提供的一种可能的客户端的实施例示意图,其中,该客户端具体包括:

确定函数201,用于确定程序中的核心函数,所述核心函数为运行所述程序时必须执行的函数;

获取函数202,用于获取开始执行所述核心函数的第一时间和结束执行所述核心函数的第二时间;

判断函数203,用于判断所述第二时间与所述第一时间的时间差是否大于预设值;

退出函数204,用于若所述第二时间与所述第一时间的时间差大于所述预设值,则确定所述程序被非法调试,并退出所述程序。

请参阅图3,图3为本申请实施例提供的电子设备的实施例示意图。

如图3所示,本申请实施例提供了一种电子设备,包括存储器310、处理器320及存储在存储器320上并可在处理器320上运行的计算机程序311,处理器320执行计算机程序311时实现以下步骤:确定程序中的核心函数,所述核心函数为运行所述程序时必须执行的函数;获取开始执行所述核心函数的第一时间和结束执行所述核心函数的第二时间;判断所述第二时间与所述第一时间的时间差是否大于预设值;若所述第二时间与所述第一时间的时间差大于所述预设值,则确定所述程序被非法调试,并退出所述程序。

可选的,在一种可能的实施例中,所述处理器320具体用于:在时间函数组中选择目标函数,所述时间函数组中的函数用于获取当前时间;在所述核心函数的起始位置和所述核心函数的结束位置分别加入所述目标函数;当开始执行所述核心函数时,通过调用所述目标函数获取所述第一时间;当所述核心函数执行结束时,通过调用所述目标函数获取所述第二时间。

可选的,在一种可能的实施例中,所述处理器320具体用于:当所述时间函数组包括各函数和与所述各函数对应的编号,且所述编号为区间[0,n-1]中的整数时,通过调用函数rand()获取随机数据,所述n用于表示所述时间函数组中函数的总个数;根据以下求余公式确定所述目标函数:m=nrand%n;其中,所述m用于表示所述目标函数在所述时间函数组中的编号,所述nrand用于表示所述随机数据。

可选的,在一种可能的实施例中,所述处理器320具体用于:接收服务器发送的远程调试消息,所述远程调试消息用于指示检测指定函数是否被调试,所述远程调试消息包括用于索引所述指定函数的位置信息,和时间阈值;响应于所述远程调试消息,根据所述位置信息确定所述指定函数,并在所述指定函数的起始位置和所述指定函数的结束位置分别加入所述目标函数;根据所述目标函数确定执行所述指定函数时的第三时间和结束执行所述指定函数时的第四时间;若所述第四时间与所述第三时间的时间差大于所述时间阈值,则确定所述指定函数被调试;若所述第四时间与所述第三时间的时间差小于所述时间阈值,则确定所述指定函数未被调试。

可选的,在一种可能的实施例中,所述处理器320具体用于:所述位置信息包括所述指定函数所在模块的名称、所述指定函数的偏移量和所述指定函数的长度,通过调用函数getmodulehandle()获取所述模块在内存中的起始地址,所述函数getmodulehandle()的输入参数为所述模块的名称;按照如下方式确定所述指定函数:dwstart=module+offset;dwend=module+offset+length;其中,所述dwstart用于表示所述指定函数的起始位置,所述dwend用于表示所述指定函数的结尾位置,所述module用于表示所述模块在内存中的起始地址,所述offset用于表示所述指定函数的偏移量,所述length用于表示所述指定代码的长度。

可选的,在一种可能的实施例中,所述处理器320具体用于:通过调用循环函数创建多个线程;当所述程序被调试时,通过所述各线程调用退出函数,以退出所述程序,所述退出函数包括函数pthread_exit或者函数abort;或者,删除或者修改所述程序中的内存代码,以使得所述程序崩溃并退出。

由于本实施例所介绍的电子设备为实施本申请实施例中一种注册装置所采用的设备,故而基于本申请实施例中所介绍的方法,本领域所属技术人员能够了解本实施例的电子设备的具体实施方式以及其各种变化形式,所以在此对于该电子设备如何实现本申请实施例中的方法不再详细介绍,只要本领域所属技术人员实施本申请实施例中的方法所采用的设备,都属于本申请所欲保护的范围。

请参阅图4,图4为本申请实施例提供的一种计算机可读存储介质的实施例示意图。

如图4所示,本实施例提供了一种计算机可读存储介质400,其上存储有计算机程序411,该计算机程序411被处理器执行时实现如下步骤:确定程序中的核心函数,所述核心函数为运行所述程序时必须执行的函数;获取开始执行所述核心函数的第一时间和结束执行所述核心函数的第二时间;判断所述第二时间与所述第一时间的时间差是否大于预设值;若所述第二时间与所述第一时间的时间差大于所述预设值,则确定所述程序被非法调试,并退出所述程序。

可选的,在一种可能的实施例中,该计算机程序411被处理器执行时具体用于实现如下步骤:在时间函数组中选择目标函数,所述时间函数组中的函数用于获取当前时间;在所述核心函数的起始位置和所述核心函数的结束位置分别加入所述目标函数;当开始执行所述核心函数时,通过调用所述目标函数获取所述第一时间;当所述核心函数执行结束时,通过调用所述目标函数获取所述第二时间

可选的,在一种可能的实施例中,该计算机程序411被处理器执行时具体用于实现如下步骤:当所述时间函数组包括各函数和与所述各函数对应的编号,且所述编号为区间[0,n-1]中的整数时,通过调用函数rand()获取随机数据,所述n用于表示所述时间函数组中函数的总个数;根据以下求余公式确定所述目标函数:m=nrand%n;其中,所述m用于表示所述目标函数在所述时间函数组中的编号,所述nrand用于表示所述随机数据。

可选的,在一种可能的实施例中,该计算机程序411被处理器执行时具体用于实现如下步骤:接收服务器发送的远程调试消息,所述远程调试消息用于指示检测指定函数是否被调试,所述远程调试消息包括用于索引所述指定函数的位置信息,和时间阈值;响应于所述远程调试消息,根据所述位置信息确定所述指定函数,并在所述指定函数的起始位置和所述指定函数的结束位置分别加入所述目标函数;根据所述目标函数确定执行所述指定函数时的第三时间和结束执行所述指定函数时的第四时间;若所述第四时间与所述第三时间的时间差大于所述时间阈值,则确定所述指定函数被调试;若所述第四时间与所述第三时间的时间差小于所述时间阈值,则确定所述指定函数未被调试。

可选的,在一种可能的实施例中,该计算机程序411被处理器执行时具体用于实现如下步骤:通过调用函数getmodulehandle()获取所述模块在内存中的起始地址,所述函数getmodulehandle()的输入参数为所述模块的名称;按照如下方式确定所述指定函数:dwstart=module+offset;dwend=module+offset+length;其中,所述dwstart用于表示所述指定函数的起始位置,所述dwend用于表示所述指定函数的结尾位置,所述module用于表示所述模块在内存中的起始地址,所述offset用于表示所述指定函数的偏移量,所述length用于表示所述指定代码的长度。

可选的,在一种可能的实施例中,该计算机程序411被处理器执行时还用于实现如下步骤:通过调用循环函数创建多个线程;当所述程序被调试时,通过所述各线程调用退出函数,以退出所述程序,所述退出函数包括函数pthread_exit或者函数abort;或者,删除或者修改所述程序中的内存代码,以使得所述程序崩溃并退出。

需要说明的是,在上述实施例中,对各个实施例的描述都各有侧重,某个实施例中没有详细描述的部分,可以参见其它实施例的相关描述。

本领域内的技术人员应明白,本申请的实施例可提供为方法、系统、或计算机程序产品。因此,本申请可采用完全硬件实施例、完全软件实施例、或结合软件和硬件方面的实施例的形式。而且,本申请可采用在一个或多个其中包含有计算机可用程序代码的计算机可用存储介质(包括但不限于磁盘存储器、cd-rom、光学存储器等)上实施的计算机程序产品的形式。

本申请是参照根据本申请实施例的方法、设备(系统)、和计算机程序产品的流程图和/或方框图来描述。应理解可由计算机程序指令实现流程图和/或方框图中的每一流程和/或方框、以及流程图和/或方框图中的流程和/或方框的结合。可提供这些计算机程序指令到通用计算机、专用计算机、嵌入式计算机或者其他可编程数据处理设备的处理器以产生一个机器,使得通过计算机或其他可编程数据处理设备的处理器执行的指令产生用于实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能的装置。

这些计算机程序指令也可存储在能引导计算机或其他可编程数据处理设备以特定方式工作的计算机可读存储器中,使得存储在该计算机可读存储器中的指令产生包括指令装置的制造品,该指令装置实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能。

这些计算机程序指令也可装载到计算机或其他可编程数据处理设备上,使得在计算机或其他可编程设备上执行一系列操作步骤以产生计算机实现的处理,从而在计算机或其他可编程设备上执行的指令提供用于实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能的步骤。

尽管已描述了本申请的优选实施例,但本领域内的技术人员一旦得知了基本创造概念,则可对这些实施例作出另外的变更和修改。所以,所附权利要求意欲解释为包括优选实施例以及落入本申请范围的所有变更和修改。

显然,本领域的技术人员可以对本申请进行各种改动和变型而不脱离本申请的精神和范围。这样,倘若本申请的这些修改和变型属于本申请权利要求及其等同技术的范围之内,则本申请也意图包括这些改动和变型在内。

当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1