发明内容
本发明实施例提供了一种应用程序dump文件获取方法、装置及电子设备,以解决目前抓取dump文件不具有普适性,无法适用于任意的应用程序,开发人员无法有效分析的问题。
第一方面,本申请提供了一种应用程序dump文件获取方法,应用于电子设备中,该方法包括:
建立获取dump文件的模块;
在所述模块中编写生成dump文件的功能函数;
在所述模块中编写捕获异常的异常处理函数;
在所述电子设备系统中注册所述异常处理函数;
屏蔽所述电子设备系统中其它异常处理模块注册异常处理函数;
将所述模块注入需要获取dump文件的第三方目标应用程序中,以在所述目标应用程序发生异常时,通过所述模块生成dump文件。
进一步的,在所述模块中编写生成dump文件的功能函数,包括:
在所述模块中编写调用系统提供的功能函数CreateFile的模块,以创建一个dump文件;
在所述模块中编写调用系统函数MiniDumpWriteDump的模块,以将生成的dump信息写入到dump文件。
进一步的,在所述模块中编写异常处理函数,包括:
在所述模块中定义一个异常处理函数,所述异常处理函数中定义了处理的异常类型信息,以及在捕获异常时调用所述生成dump文件的功能函数。
进一步的,所述屏蔽所述电子设备系统中其它异常处理模块注册异常处理函数,包括:
获取所述电子设备系统中异常注册函数的内存地址;
修改所述异常注册函数的内存属性,将所述异常注册函数的内存属性由可读修改为可读写;
获取当前进程的句柄;
构造需要修改的内存代码;
根据所述修改的内存代码修改所述异常注册函数的内存代码,以使得所述电子设备系统中其它异常处理模块注册异常处理函数时无法注册成功。
进一步的,所述屏蔽所述电子设备系统中其它异常处理模块注册异常处理函数,还包括:
恢复所述异常注册函数的内存属性为原始属性。
进一步的,所述将该获取dump文件的模块注入需要获取dump文件的第三方目标应用程序中,包括:
通过WindowsAPI函数VirtualAllocEx函数在目标进程的内存空间中分配内存,其中,所述目标进程为所述目标应用程序的进程。
通过WindowsAPI函数WriteProcessMemory将所述获取dump文件的模块的磁盘路径写入到已经分配的内存中;
调用WindowsAPI函数CreateRemoteThread函数在所述目标进程中创建一个线程,所述线程的执行逻辑就是调用WindowsAPI函数LoadLibrary来加载所述获取dump文件的模块的磁盘路径。
第二方面,本申请提供一种应用程序dump文件获取装置,该装置包括:
建立模块,用于建立获取dump文件的模块;
第一编写模块,用于在所述模块中编写生成dump文件的功能函数;
第二编写模块,用于在所述模块中编写捕获异常的异常处理函数;
注册模块,用于在所述电子设备系统中注册所述异常处理函数;
屏蔽模块,用于屏蔽所述电子设备系统中其它异常处理模块注册异常处理函数;
注入模块,用于将所述模块注入需要获取dump文件的第三方目标应用程序中,以在所述目标应用程序发生异常时,通过所述模块生成dump文件。
进一步的,所述第一编写模块具体用于:
在所述模块中编写调用系统提供的功能函数CreateFile的模块,以创建一个dump文件;
在所述模块中编写调用系统函数MiniDumpWriteDump的模块,以将生成的dump信息写入到dump文件。
进一步的,所述第二编写模块具体用于:
在所述模块中定义一个异常处理函数,所述异常处理函数中定义了处理的异常类型信息,以及在捕获异常时调用所述生成dump文件的功能函数。
进一步的,所述屏蔽模块具体用于:
获取所述电子设备系统中异常注册函数的内存地址;
修改所述异常注册函数的内存属性,将所述异常注册函数的内存属性由可读修改为可读写;
获取当前进程的句柄;
构造需要修改的内存代码;
根据所述修改的内存代码修改所述异常注册函数的内存代码,以使得所述电子设备系统中其它异常处理模块注册异常处理函数时无法注册成功。
进一步的,所述屏蔽模块具体还用于:
恢复所述异常注册函数的内存属性为原始属性。
第三方面,本发明还提供一种电子设备,包括:存储器,处理器及存储在所述存储器上并可在所述处理器上运行的计算机程序,其中,所述处理器执行所述计算机程序时可以实现第一方面中任一所述的方法。
第四方面,本发明还提供一种计算机可读存储介质,其上存储有计算机程序,该程序被处理器执行时实现第一方面中任一所述的方法。
本发明实施例通过建立获取dump文件的模块;在该模块中编写生成dump文件的功能函数;在模块中编写异常处理函数;在电子设备系统中注册异常处理函数;屏蔽电子设备系统中其它异常处理模块注册异常处理函数;将模块注入需要获取dump文件的第三方目标应用程序中,以在所述目标应用程序发生异常时,通过该模块生成dump文件。本发明实施例中编写一个独立的抓取dump功能的模块,然后将此模块注入到需要抓取dump文件的任意第三方目标应用程序中。当第三方目标应用程序产生异常错误时,被注入的模块则会捕获到此异常,从而生成dump文件,可以方便开发人员或者应用程序使用者快速定位崩溃的原因。
具体实施方式
为了使本技术领域的人员更好地理解本发明方案,下面将结合本发明实施例中的附图,对本发明实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例仅仅是本发明一部分的实施例,而不是全部的实施例。基于本发明中的实施例,本领域普通技术人员在没有做出创造性劳动前提下所获得的所有其他实施例,都应当属于本发明保护的范围。
本发明的说明书和权利要求书及上述附图中的术语“第一”、“第二”等(如果存在)是用于区别类似的对象,而不必用于描述特定的顺序或先后次序。应该理解这样使用的数据在适当情况下可以互换,以便这里描述的实施例能够以除了在这里图示或描述的内容以外的顺序实施。此外,术语“包括”和“具有”以及他们的任何变形,意图在于覆盖不排他的包含,例如,包含了一系列步骤或单元的过程、方法、系统、产品或设备不必限于清楚地列出的那些步骤或单元,而是可包括没有清楚地列出的或对于这些过程、方法、产品或设备固有的其它步骤或单元。
本发明实施例中应用程序dump文件获取方法应用于应用程序dump文件获取装置,该装置位于电子设备中,本实施例中该电子设备系统为Windows系统,该电子设备可以是手机、平板电脑或者个人电脑等Windows系统电子设备,也可以是未来新出现的Windows系统的电子设备等。
请参阅图1,本发明实施例中应用程序dump文件获取方法的一个实施例包括:
S101、建立获取dump文件的模块;
其中,该获取dump文件的模块即为一个独立的模块,后续进行获取dump文件的模块的功能编写。
S102、在该获取dump文件的模块中编写生成dump文件的功能函数;
具体的,在独立的模块中编写一个生成dump文件的功能,从而在异常产生时能够生成一个dump文件。
S103、在该获取dump文件的模块中编写捕获异常的异常处理函数;
本实施例中,异常(Exception)是应用程序在运行时可能出现的会导致程序运行终止的错误。在编写生成dump文件的功能函数的同时,还需要在该获取dump文件的模块中编写捕获异常的功能,用于处理产生异常时来调用上述步骤S102中编写的产生dump文件的功能。
S104、在电子设备系统中注册异常处理函数;
具体的,由于Windows系统中的应用程序均需要注册后才能正常使用,因此本实施例中,还需要注册上述编写的异常处理函数,当产生异常时,编写的异常处理函数的对应逻辑才会被执行。
S105、屏蔽电子设备系统中其它异常处理模块注册异常处理函数;
由于电子设备系统中或电子设备系统中的其他程序中可能也会存在异常处理模块,为了避免冲突及资源浪费,保障本实施例中编写的该获取dump文件的模块肯定能够捕获异常,所以本实施例在注册完成异常捕获函数后,还需要屏蔽掉后续其他模块或者功能注册的异常捕获函数。
S106、将该获取dump文件的模块注入需要获取dump文件的第三方目标应用程序中,以在目标应用程序发生异常时,通过该获取dump文件的模块生成dump文件。
本实施例中,经过上述步骤S101~S105,上述获取dump文件的模块已经具备了注册异常的功能,屏蔽掉后续的注册异常的功能,异常产生时捕获异常,并生成dump文件的功能。那么本步骤中则需要将此独立模块注入到需要去抓取dump的目标应用程序中,以在任何需要分析异常的目标应用程序中实现抓取dump文件的功能。
需要说明的是,本发明实施例中应用程序可以是移动终端(如手机、平板灯)上的应用程序(APP)或终端(如个人电脑)上的计算机程序。
本发明实施例通过建立获取dump文件的模块,在该模块中编写生成dump文件的功能函数;在模块中编写异常处理函数;在电子设备系统中注册异常处理函数;屏蔽电子设备系统中其它异常处理模块注册异常处理函数;将模块注入需要获取dump文件的第三方目标应用程序中,以在所述目标应用程序发生异常时,通过该模块生成dump文件。本发明实施例中编写一个独立的抓取dump功能的模块,然后将此模块注入到需要抓取dump文件的任意第三方目标应用程序中。当第三方目标应用程序产生异常错误时,被注入的模块则会捕获到此异常,从而生成dump文件,可以方便开发人员或者应用程序使用者快速定位崩溃的原因。
如图2所示,在本发明一些实施例中,上述步骤S102可以进一步的包括:
S1021、在该获取dump文件的模块中编写调用系统提供的功能函数CreateFile的模块,以创建一个dump文件;
该具体实现方式如下:
首先编写一个接口用于生成dump文件,接口具体如下:
void CreateMiniDump(PEXCEPTION_POINTERS pep,LPCTSTR strFileName)
由于dump是一个文件,所以本实施例中还需要创建一个dump文件,以供写入生成的dump信息。具体则调用系统提供的功能函数CreateFile来创建一个文件,具体实现如下:
HANDLE hFile=CreateFile(strFileName,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_WRITE,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
其中,参数strFileName则标示创建的文件的名称。
S1022、在该dump文件的模块中编写调用系统函数MiniDumpWriteDump的模块,以将生成的dump信息写入到dump文件。
本实施例中,通过调用系统函数MiniDumpWriteDump来将生成的dump信息写入到dump文件中,具体实现方式如下:
MiniDumpWriteDump(GetCurrentProcess(),GetCurrentProcessId(),hFile,MiniDumpNormal,NULL,NULL,NULL);
其中,系统函数MiniDumpWriteDump则可以生成当前的dump信息;参数1则是当前进程的句柄,通过调用系统函数GetCurrentProcess来获取;参数2则是当前的进程的ID,则是通过调用系统函数GetCurrentProcessId来获取;参数3hFile则是需要写入文件的句柄,则是之前预先创建的文件句柄;参数4则是传入需要生成的是MiniDumpNormal,而不是全量dump。
最后再关闭文件句柄CloseHandle(hFile),调用系统函数CloseHandle,从而dump文件即生成了。
通过本实施例中步骤即实现了在获取dump文件的模块中编写了一个生成dump文件的功能函数。
在本发明一些实施例中,上述步骤S103进一步的可以包括:在该获取dump文件的模块中定义一个异常处理函数,该异常处理函数中定义了处理的异常类型信息,以及在捕获异常时调用上述生成dump文件的功能函数。具体实现方式如下:
LONG__stdcall MyUnhandledExceptionFilter(PEXCEPTION_POINTERSpExceptionInfo){
{
CreateMiniDump(pExceptionInfo,"core.dmp");
return EXCEPTION_CONTINUE_EXECUTION;
}
其中,定义一个异常处理函数,函数名称是MyUnhandledExceptionFilter,参数pExceptionInfo则会传递一些异常相关的信息,包括此时是什么异常,如除0异常、无效句柄异常、内存访问异常等。另外,CreateMiniDump是上述步骤中编写的产生dump文件的功能函数;参数pExceptionInfo是系统的产生异常时的环境信息;参数"core.dmp"则是需要生成的dump文件的名称,其中,.dmp为dump文件的格式。
通过本实施例步骤即实现了在该获取dump文件的模块中编写了一个捕获异常并生成dump文件的功能。
由于Windows系统中提供了相应的API函数来注册异常处理函数,因此可以根据该提供的API函数来注册异常处理函数,上述步骤S105中在电子设备系统中注册异常处理函数具体实现方式可以如下:
SetUnhandledExceptionFilter(MyUnhandledExceptionFilter);
其中,系统API函数SetUnhandledExceptionFilter则是用来注册一个异常处理函数;参数MyUnhandledExceptionFilter则是上述步骤中编写的异常处理函数。因此只有在系统中注册异常处理函数,当应用程序执行时,产生了异常,则系统会去执行注册的异常处理函数MyUnhandledExceptionFilter。在此函数中则会对异常进行处理。通过这个步骤就实现了在该获取dump文件的模块中注册异常处理函数。
如图3所示,在本发明一些实施例中,上述步骤S105进一步的可以具体包括:
S1051、获取电子设备系统中异常注册函数的内存地址;
由于在Windows系统中注册异常捕获函数,必须是调用系统的SetUnhandledExceptionFilter函数来注册,那么本实施例中则可以通过获取进程中的此异常注册函数的内存地址,根据该内存地址从而可以得到异常注册函数在内存中的汇编代码。
由于Windows系统中异常注册函数SetUnhandledExceptionFilter是属于系统的kernel32.dll模块的函数,所以首先需要获取kernel32.dll模块的句柄,然后通过该句柄获取SetUnhandledExceptionFilter函数的内存地址。具体的,步骤S1051的具体实现方式如下:
通过调用系统函数来获取系统模块kernel32.dll模块的句柄。
HMODULE WINAPI LoadLibrary(LPCTSTR lpFileName);
hModule=LoadLibrary(“LoadLibrary”);
其中,参数则是填入模块的名称,返回值则是获取的模块句柄。
由于异常注册函数SetUnhandledExceptionFilter是模块kernel32.dll的导出函数,所以可以直接获取异常注册函数的内存地址。
通过调用系统函数GetProcAddress实现获取异常注册函数的内存地址,其原型如下:
FARPROC GetProcAddress(
HMODULE hModule,//DLL模块句柄
LPCSTR lpProcName//函数名
);
其中,参数1是需要传入的DLL模块句柄,参数2则是获取的导出函数的名称。
具体实现方式如下:
void*Address=(void*)GetProcAddress(hModule,
"SetUnhandledExceptionFilter");
从而得到异常注册函数SetUnhandledExceptionFilter在内存的地址,内存的地址则是异常注册函数SetUnhandledExceptionFilter的代码地址。
S1052、修改异常注册函数的内存属性,将异常注册函数的内存属性由可读修改为可读写;
由于代码在内存中是以只读可执行的属性,如果要进行修改,则需要修改内存属性,通过调用系统函数VirtualProtect可以修改系统的内存属性,以异常注册函数的内存属性,具体实现方式如下:
其中,参数1LPVOID lpAddress则是需要修改系统内存的起始地址;参数SIZE_TdwSize则是需要修改系统内存的大小;参数DWORD flNewProtect则是需要修改的内存属性;参数PDWORD lpflOldProtect是用于返回修改前的属性。
具体调用如下:
VirtualProtect(Address,5,PAGE_EXECUTE_READWRITE,&dwOld);
其中,参数1填入步骤1获取的内存地址;参数2则只需要修改5个字节的内存代码;参数3则是修改内存属性为可读写可执行。接下来则修改异常注册函数的内存代码。
S1053、获取当前进程的句柄;
具体实现方式如下:
HANDLE GetCurrentProcess(void);
通过调用系统函数GetCurrentProcess则可以获取当前进程的句柄,返回值则是当前进程的句柄值。该当前进程可以是异常注册函数的进程。
S1054、构造需要修改的内存代码;
由于Windows系统中函数代码在内存中存在的是X86的汇编代码,所以需要编写汇编代码,并且在此异常注册函数中是通过寄存器EAX来返回结果数据。所以本实施例中构造需要修改的内存代码如下:
需要将原有的代码修改成:
XOR EAX,EAX
RETN 4
其中,第一段代码指令表示将寄存器EAX的值置位为0,标示注册异常识别。由于异常注册函数有一个参数,所以需要平衡堆栈,因此需要填写4,用于平衡堆栈,第二段代码指令直接编写retn 4表示程序直接返回,不执行后续程序,从而不会执行系统的注册异常,从而异常注册处理函数不成功。
由于上述编写的是汇编代码的助记符,用于人方便记忆和编写,实际机器执行的则是16进制数据,对应的XOR EAX,EAX指令对应的16进制数据则是0x33C0,对应的RETN 4指令对应的16进制数据则是0xC2 0400,所以需要将系统中异常注册函数SetUnhandledExceptionFilter的内存代码修改成0x33c0c2 04 00。
本发明实施例中还可以进一步的定义一个存储区域来存储异常注册函数SetUnhandledExceptionFilter修改后的内存代码,具体方式如下:
定义一个char codeBuff[]={0x33,0xc0,0xc2,0x04,0x00}。
S1055、根据修改的内存代码修改异常注册函数的内存代码,以使得电子设备系统中其它异常处理模块注册异常处理函数时无法注册成功。
具体的Windows系统中提供了一个函数WriteProcessMemory来修改系统进程的代码,具体如下:
其中,参数1hProcess则是填入需要修改的进程句柄;参数2lpBaseAddress则是需要修改的内存地址;参数3lpBuffer则是需要修改成的代码数据;参数4则是实际修改了多少字节。
本实施例中实现步骤S1055具体调用如下:
WriteProcessMemory(GetCurrentProcess(),Address,codeBuff,5,NULL);
其中参数1则填入获取当前进程的句柄;参数2则填入需要修改的内存地址,则是步骤S1051获取的内存地址;参数3则是填入需要修改成的代码数据,则是上述步骤S1054中构造的codeBuff;参数5则是填入,需要修改5个字节;参数6则填入NULL,不关心此数据。
如图4所示,在本发明另一些实施例中,上述步骤S105还可以进一步包括:
S1056、恢复异常注册函数的内存属性为原始属性。
由于本实施例步骤S1052中修改函数代码将内存属性修改成可以写的属性,先已经修改完成后,则需要将内存属性恢复为原始属性,具体的则是修改成不可以写的属性,具体实现方式如下:
VirtualProtect(Address,5,dwOld,&deOldOld);
其中,属性填入之前调用此函数返回的dwOld属性。
通过本实施例中步骤就实现了对系统异常处理函数代码进行修改,使得其后续的异常处理函数注册失败。
由于经过上述步骤,本实施例中获取dump文件的模块已经具备了注册异常的功能、屏蔽掉后续的注册异常的功能、异常产生时捕获异常,并生成dump文件的功能。那么本实施例中则需要编写功能来将此获取dump文件的模块注入到需要去抓取dump的应用程序中。具体的,本发明实施例可以使用创建远程线程的方式来注入,例如,本发明实施例中通过调用Windows系统提供的API函数来将一个模块注入到另一个应用程序进程中。基本思路是通过Windows系统API函数CreateRemoteThread来在目标进程中创建一个远程线程(之所以称为远程线程是因为这个线程是工具软件进程在目标进程中创建的一个线程),通过创建的远程线程去调用系统函数LoadLibrary来加载需要注入到第三方应用程序进程的模块。即本发明实施例中上述步骤S106具体实现方式可以如下:
(1)通过WindowsAPI函数VirtualAllocEx函数在目标进程的内存空间中分配内存,其中,该目标进程为该目标应用程序的进程。
(2)通过WindowsAPI函数WriteProcessMemory来将编写的需要注入的模块(即获取dump文件的模块)的磁盘路径写入到已经分配的内存中(步骤(1)中分配的目标进程的内存空间)。
(3)调用WindowsAPI函数CreateRemoteThread函数来在目标进程中创建一个线程,该线程的执行逻辑就是调用WindowsAPI函数LoadLibrary来加载需要注入的模块(即获取dump文件的模块)的的磁盘路径。这样就实现了在目标进程开启一个线程,通过线程来加载一个模块,实现了对目标进程注入该获取dump文件的模块的功能。
在获取dump文件的模块注入到目标进程后,则会注册异常处理函数,并屏蔽其他异常处理函数,当目标进程产生异常后,则可以捕获到并生成dump文件。因此通过这个步骤就实现了将本发明实施例中编写的获取dump文件的模块注入到目标进程(目标应用程序)中的功能。
如图5所示,本发明实施例中还提供一种应用程序dump文件获取装置,该装置包括:
建立模块501,用于建立获取dump文件的模块;
第一编写模块502,用于在所述模块中编写生成dump文件的功能函数;
第二编写模块503,用于在所述模块中编写捕获异常的异常处理函数;
注册模块504,用于在所述电子设备系统中注册所述异常处理函数;
屏蔽模块505,用于屏蔽所述电子设备系统中其它异常处理模块注册异常处理函数;
注入模块506,用于将所述模块注入需要获取dump文件的第三方目标应用程序中,以在所述目标应用程序发生异常时,通过所述模块生成dump文件。
进一步的,所述第一编写模块502具体用于:
在所述模块中编写调用系统提供的功能函数CreateFile的模块,以创建一个dump文件;
在所述模块中编写调用系统函数MiniDumpWriteDump的模块,以将生成的dump信息写入到dump文件。
进一步的,所述第二编写模块503具体用于:
在所述模块中定义一个异常处理函数,所述异常处理函数中定义了处理的异常类型信息,以及在捕获异常时调用所述生成dump文件的功能函数。
进一步的,所述屏蔽模块505具体用于:
获取所述电子设备系统中异常注册函数的内存地址;
修改所述异常注册函数的内存属性,将所述异常注册函数的内存属性由可读修改为可读写;
获取当前进程的句柄;
构造需要修改的内存代码;
根据所述修改的内存代码修改所述异常注册函数的内存代码,以使得所述电子设备系统中其它异常处理模块注册异常处理函数时无法注册成功。
进一步的,所述屏蔽模块505具体还用于:
恢复所述异常注册函数的内存属性为原始属性。
进一步的,所述注入模块具体用于:
通过WindowsAPI函数VirtualAllocEx函数在目标进程的内存空间中分配内存,其中,所述目标进程为所述目标应用程序的进程。
通过WindowsAPI函数WriteProcessMemory将所述获取dump文件的模块的磁盘路径写入到已经分配的内存中;
调用WindowsAPI函数CreateRemoteThread函数在所述目标进程中创建一个线程,所述线程的执行逻辑就是调用WindowsAPI函数LoadLibrary来加载所述获取dump文件的模块的磁盘路径。
本发明实施例中还提供一种电子设备,请参见图6,所述电子设备包括:
存储器601,处理器602及存储在所述存储器上并可在所述处理器上运行的计算机程序603,其中,所述处理器602执行所述计算机程序603时可以实现上述应用程序dump文件获取方法。
为了便于说明,仅示出了与本发明实施例相关的部分,具体技术细节未揭示的,请参照本发明实施例方法部分。存储器601可用于存储计算机程序603,上述计算机程序包括软件程序、模块和数据,处理器602通过运行执行存储在存储器601的计算机程序603,从而执行电子设备的各种功能应用以及数据处理。
在具体的实施过程中,存储器601可用于存储软件程序以及模块,处理器602通过运行存储在存储器601的软件程序以及模块,从而执行电子设备的各种功能应用以及数据处理。存储器601可主要包括存储程序区和存储数据区,其中,存储程序区可存储操作系统、至少一个功能所需的应用程序(例如游戏类应用程序、聊天类应用程序)等;存储数据区可存储根据电子设备的使用所创建的数据(游戏配置数据、音频数据)等。此外,存储器601可以包括高速随机存取存储器,还可以包括非易失性存储器,例如至少一个磁盘存储器件、闪存器件、或其他易失性固态存储器件。处理器602是电子设备的控制中心,利用各种接口和线路连接整个电子设备的各个部分,通过运行或执行存储在存储器601内的软件程序和/或模块,以及调用存储在存储器601内的数据,执行电子设备的各种功能和处理数据,从而对电子设备进行整体监控。可选的,处理器602可包括一个或多个处理单元;优选的,处理器602可集成应用处理器,其中,应用处理器主要处理操作系统、用户界面和应用程序等。
本发明实施例还提供一种计算机可读存储介质,其中,该计算机可读存储介质可存储有程序,该程序执行时包括上述方法实施例中记载的应用程序dump文件获取方法的部分或全部步骤。
所属领域的技术人员可以清楚地了解到,为描述的方便和简洁,上述描述的系统,装置和单元的具体工作过程,可以参考前述方法实施例中的对应过程,在此不再赘述。
在本申请所提供的几个实施例中,应该理解到,所揭露的系统,装置和方法,可以通过其它的方式实现。例如,以上所描述的装置实施例仅仅是示意性的,例如,所述单元的划分,仅仅为一种逻辑功能划分,实际实现时可以有另外的划分方式,例如多个单元或组件可以结合或者可以集成到另一个系统,或一些特征可以忽略,或不执行。另一点,所显示或讨论的相互之间的耦合或直接耦合或通信连接可以是通过一些接口,装置或单元的间接耦合或通信连接,可以是电性,机械或其它的形式。
所述作为分离部件说明的单元可以是或者也可以不是物理上分开的,作为单元显示的部件可以是或者也可以不是物理单元,即可以位于一个地方,或者也可以分布到多个网络单元上。可以根据实际的需要选择其中的部分或者全部单元来实现本实施例方案的目的。
另外,在本发明各个实施例中的各功能单元可以集成在一个处理单元中,也可以是各个单元单独物理存在,也可以两个或两个以上单元集成在一个单元中。上述集成的单元既可以采用硬件的形式实现,也可以采用软件功能单元的形式实现。
所述集成的单元如果以软件功能单元的形式实现并作为独立的产品销售或使用时,可以存储在一个计算机可读取存储介质中。基于这样的理解,本发明的技术方案本质上或者说对现有技术做出贡献的部分或者该技术方案的全部或部分可以以软件产品的形式体现出来,该计算机软件产品存储在一个存储介质中,包括若干指令用以使得一台计算机设备(可以是个人计算机,服务器,或者网络设备等)执行本发明各个实施例所述方法的全部或部分步骤。而前述的存储介质包括:U盘、移动硬盘、只读存储器(ROM,Read-OnlyMemory)、随机存取存储器(RAM,Random Access Memory)、磁碟或者光盘等各种可以存储程序代码的介质。
以上所述,以上实施例仅用以说明本发明的技术方案,而非对其限制;尽管参照前述实施例对本发明进行了详细的说明,本领域的普通技术人员应当理解:其依然可以对前述各实施例所记载的技术方案进行修改,或者对其中部分技术特征进行等同替换;而这些修改或者替换,并不使相应技术方案的本质脱离本发明各实施例技术方案的精神和范围。