[0142] 举例来说,若目标隐藏驱动信息哈希名称长度为10 byte,长度较短,为了增加其最终结果的隐蔽性,那么需要利用较为复杂的调用策略进行哈希运算。这时可以调用不同等级的哈希算法进行运算。比如,调用策略中的运算次数为3次,那么第一次哈希运算可以利用第一等级的哈希算法组中的哈希算法进行运算,第二次哈希运算可以利用第二等级的哈希算法组中的哈希算法进行运算,第三次哈希运算可以利用第三等级的哈希算法组中的哈希算法进行运算。
[0143] 若目标隐藏驱动信息哈希名称长度为80 byte,可以利用普通的调用策略进行哈希运算。这时可以调用同一等级的哈希算法进行运算。比如,调用策略中的运算次数为2次,那么第一次哈希运算可以利用第一等级的哈希算法组中第一编号的哈希算法进行运算,第二次哈希运算可以利用第一等级的哈希算法组中第二编号的哈希算法进行运算。
[0144] 这里,第二次哈希运算的运算参数是第一次的哈希结果值,第三次哈希运算的运算参数是第二次的哈希结果值。
[0145] 举例来说,若目标隐藏驱动信息哈希名称长度为80 byte,第一编号的哈希算法为MD5哈希算法,第二编号的哈希算法为SHA哈希算法,那么链式指针为HashBase* phash,调用Stl::string result = pHash->Hash();来实现运算过程:
[0146] HashBase* phashMd5 = new Md5HASH();第一编号的哈希算法的运算[0147] HashBase* phashSha = new ShaHASH(phashMd5 );第二编号的哈希算法的运算[0148] 可以看出,在进行SHA的哈希算法的运算时,运算参数是phashMd5,即Md5的哈希运算的结果值。
[0149] 即使后续有新的哈希算法NewHASH,也可以通过同样的方式进行叠加运算:
[0150] HashBase* phashNew = new NewHASH();
[0151] HashBase* phashMd5 = new Md5HASH(phashNew );
[0152] HashBase* phashSha = new ShaHASH(phashMd5 );
[0153] 这样的调用方式即使增加新的哈希算法,也无需更改底层框架代码。
[0154] 而在实际运算中,每次待调用的哈希算法的编号是可以根据公式(1)预先确定的:
[0155] F= MD5(initial + time) (1)
[0156] 在公式(1)中,F为待调用的哈希算法的编号,所述initial为预设的初始值,所述initial的值根据待计算的目标隐藏驱动信息的哈希名称长度确定,所述time为预设的时间戳。
[0157] 比如,在实际运算中F值为246,若调用策略为同一等级哈希算法的调用时,那么在同一等级的哈希算法组中,第一次调用的是编号为2的哈希算法,第二次调用的是编号为4的哈希算法,第三次调用的是编号为6的哈希算法,逐次进行哈希运算。
[0158] 若调用策略为不同等级哈希算法的调用时,第一次调用的是第一等级哈希算法组中编号为2的哈希算法,第二次调用的是第二等级哈希算法组中编号为 4的哈希算法,第三次调用的是第三等级哈希算法组中编号为6的哈希算法,逐次进行哈希运算。
[0159] 需要说明的是,每次在进行当前次的哈希运算时,可以将预设的时间戳与当前次的上一次的哈希结果值共同作为运算参数,来进行当前次的哈希运算,这样可以根据时间戳追溯到每次的哈希运算结果。
[0160] 这样,在不影响驱动信息模块的原始代码功能的基础上,可以进行多次哈希运算,提高了最终的目标哈希值的隐蔽性,避免被非正常用户篡改。
[0161] 目标哈希值计算出之后,上报至服务器,以使得服务器利用所述目标哈希值标记所述目标隐藏驱动信息所在的设备。
[0162] 具体地,服务器接收到目标哈希值后,可以利用目标哈希值标记目标隐藏驱动信息所在的设备,可以提高设备标记的隐蔽性,避免被非正常用户篡改,进而确保可以正常追踪到设备中的所需的数据;并且,本申请利用链式指针调用对应的哈希算法类进行哈希计算,计算过程复杂多变,得出的哈希值复杂度高,进而提高破解难度。
[0163] 进一步地,因设备标记是根据隐藏驱动信息确定的,那么服务器还可以根据标记来确定该设备中是否存在非正常驱动信息,若存在非正常驱动信息,且用户在该台设备上利用目标隐藏驱动信息对应的驱动程序继续操作时,驱动程序必然需要向服务器请求数据,那么服务器可以确定出该用户为非正常用户,进而可以对该用户进行相应的处理,以确保平台收益及系统运行安全。
[0164] 比如,当某个用户利用当前设备进行游戏,服务器根据该设备的标记确定该台设备中装有目标隐藏驱动信息,那么即使非正常用户更换了账号,只要该用户使用了目标隐藏驱动信息对应的驱动程序,服务器依然可以确定当前用户为非正常用户,会根据预设的处理策略对非正常用户进行相应处理。
[0165] 进一步地,确定出非正常用户后,因服务器会接收到很多设备上报的隐藏驱动信息的哈希值,那么服务器还可以对其他用户进行检测,具体为:
[0166] 遍历接收到的所有隐藏驱动信息的哈希值,基于非正常用户对应的目标哈希值对所有哈希值进行一一比较;
[0167] 若确定存在与非正常用户对应的目标哈希值相同的当前哈希值,则确定当前哈希值对应的用户为疑似非正常用户。
[0168] 这样,服务器还可预测出疑似非正常用户,进而对这些疑似非正常用户进行重点监测。
[0169] 基于同样的发明构思,本申请还提供一种标记设备的装置,详见实施例二。
[0170] 实施例二
[0171] 本实施例提供一种标记设备的装置,如图2所示,装置包括:创建单元21、传入单元22、加载单元23、调用单元24;其中,
[0172] 本申请中的抽象基类用于提供调用哈希算法的方法及接口,创建单元21需要预先创建哈希算法类的抽象基类。抽象基类中还提供了各个接口的接口规范。
[0173] 抽象基类创建好之后,传入单元22将链式指针传入所述抽象基类中,以使得所述抽象基类基于所述链式指针对驱动信息的哈希名称进行链式哈希运算。
[0174] 创建单元21还需创建哈希算法类,为了使得哈希算法类可以通过所述抽象接口继承所述抽象基类,进而可以实现真正的哈希算法运算,抽象基类创建好之后,需要在抽象基类中创建抽象接口。
[0175] 这里,创建单元21创建抽象基类、在抽象基类中创建抽象接口,传入单元22将链式指针传入所述抽象基类的程序实现如下:
[0176] Class HashBase{ HashBase
[0177] Public:
[0178] HashBase(HashBase* hash):m_hash(hash)传入链式指针
[0179] Virtual Std::string imp_Hash(BYTE* pData, int nDataLen) = 0;创建抽象接口Virutal void Hash_Event(string *devpath) = 0;创建回调接口
[0180] Std::string Hash(BYTE* pData, int nDataLen);创建调用接口[0181] Return imp_Hash(pData, nDataLen);封装调用接口
[0182] protected:
[0183] HashBase*m_hash;存储链式指针
[0184] }
[0185] 其中,HashBase为抽象基类的名称,调用接口用于调用对应的哈希算法进行哈希计算,调用接口中包含:数据指针、数据长度及结果返回值string,数据指针用于获取对应哈希算法类的哈希算法,结果返回值为计算出的目标哈希值。这里,因哈希算法可能包括多个,因此可以利用数据指针用于方便获取对应的哈希算法。
[0186] 这里,调用接口创建之后,可以对调用接口进行封装。对调用接口进行封装是为了便于后续的功能扩展和组合,比如:若需要对多个哈希算法的计算日志进行日志打印时,可以将多个哈希算法计算过程的日志打印统一封装到调用接口中,同时打印,无需单独对每个哈希算法的计算日志进行一一打印。
[0187] 若获取到目标哈希值后,为了方便应用层可以获取到底层数据并对其进行处理,在抽象基类中还创建有回调接口,回调接口用于调用相应的底层数据(比如驱动信息的名称或路径),并将底层数据发送至应用层。
[0188] 进一步地,因哈希算法包括多种,创建单元21在创建哈希算法类时,需要为不同的哈希算法分别建立对应的哈希算法类,每个哈希算法类均继承抽象基类。具体实现如下:
[0189] 首先创建用于调用抽象基类的构造函数;
[0190] 利用抽象接口获取驱动信息的哈希名称;
[0191] 调用对应的哈希算法计算驱动信息哈希名称的哈希值;
[0192] 将哈希值赋值给预先定义的结果变量。
[0193] 由于本申请可以采用链式调用的方式,所以将哈希值赋值给预先定义的结果变量后,判断当前的链式指针是否存在,若存在,则根据链式指针调用对应的哈希算法对哈希值进行再次哈希运算,再返回运算的结果。
[0194] 返回运算的结果后,可以触发回调接口调用该驱动信息的驱动路径或驱动名称,将该驱动信息的驱动路径或驱动名称发送至应用层,应用层可以打印驱动日志,在软件开发中显示驱动日志,方便开发过程中的错误定位。
[0195] 比如:哈希算法为Md5哈希算法时,创建Md5哈希算法对应的哈希算法类程序实现如下:
[0196] class Md5HASH : public HashBase{
[0197] Md5HASH (HashBase* hash):HashBase(hash);用于调用抽象基类的构造函数[0198] Std::string imp_Hash(BYTE* pData1, int nDataLen){
[0199] Std::string result; 定义计算结果变量
[0200] Result = MD5.Create(pData1, nDataLen);利用MD5哈希算法来计算HASH值[0201] If (m_hash){
[0202] Return m_hash(pData1 + result.data(), nDataLe + result.length());如果存在链式指针,则将原始数据和hash结果进行叠加的链式计算
[0203] }
[0204] return result;返回链式计算的结果
[0205] }
[0206] void Hash_Event(string *devpath) {
[0207] }
[0208] }
[0209] 其中,Std::string imp_Hash(BYTE* pData1, int nDataLen)为调用MD5哈希算法类中的哈希算法,pData1为MD5哈希算法类的指针。void Hash_Event(string *devpath)为利用回调接口调用驱动路径。
[0210] 其他类型的哈希算法对应的哈希算法类的程序实现与Md5哈希算法对应的哈希算法类程序实现相同,唯一不同的是,在计算哈希值时,是利用对应类型的哈希算法进行计算的,故而不再赘述。
[0211] 上述抽象基类及哈希算法类创建好之后,当需要获取目标隐藏驱动信息时,加载单元23预先利用系统提供的文档确定目标隐藏驱动信息对应的目标API函数,加载系统的内核文件ntdll.dll及动态链接库文件kernel32.dll,获得至少一个目标API函数。其中,隐藏驱动信息可以理解为系统中非正常的驱动信息,每个API函数可以获取一个目标隐藏驱动信息,因目标隐藏驱动信息可能包括一个或多个,因此需要获取少一个目标API函数。
[0212] 这里,加载系统的内核文件ntdll.dll及动态链接库文件kernel32.dll的程序实现如下:
[0213] HMODULE hNtDll = ::LoadLibrary(“ntdll.dll”);
[0214] HMODULE hKernel32 = ::LoadLibrary(“kernel32.dll”);
[0215] 获取到至少一个目标API函数后,调用单元24需要获取至少一个目标API函数对应的API接口,以能利用所述API接口调用对应的目标API函数,获得至少一个目标隐藏驱动信息。
[0216] 其中,获取至少一个目标API函数对应的API接口的程序实现如下:
[0217] pfnZwQuerySystemInformation =
[0218] GetProcAddress(hNtDll, “ZwQuerySystemInformation”)
[0219] 获取到目标隐藏驱动信息后,调用单元24将所述至少一个目标隐藏驱动信息的实例句柄传入所述抽象基类中,基于所述抽象基类中的链式指针调用对应哈希算法类中的哈希算法,利用各所述哈希算法计算所述至少一个目标隐藏驱动信息的目标哈希值。其中,将实例句柄传入抽象基类中计算驱动信息的哈希值不会改变驱动模块本身的代码功能,并且可以利用链式指针可以对不同的哈希算法进行叠加、组合,使得计算出的哈希结果值更具有隐蔽性。
[0220] 这里,在获取驱动信息时,需要为驱动信息分配足够的内存空间,但是因系统并未提前告知需要分配多大的内存空间,而当内存空间不足时会导致调用失败,内存空间太大又会造成资源浪费。因此,作为一种可选的实施例,获取所述至少一个目标API函数对应的API接口,利用所述API接口调用对应的目标API函数,获得至少一个目标隐藏驱动信息时,方法还包括:
[0221] 获取系统分配的内存空间对应的空间变量;
[0222] 判断所述空间变量是否为空,若所述空间变量不为空,说明当前分配的内存空间不够,则释放所述内存空间,并将所述内存空间的指针赋值为空;
[0223] 按照预设的空间内存增量递增所述内存空间,每次增大所述内存空间后,利用递增后的内存空间调用所述目标API函数;内存增量可以为1024字节;
[0224] 在 每 次 增 大 所 述 内 存 空 间 后 ,均 要 调 用 系 统 的 判 断 函 数pfnZwQuerySystemInformation判断所述目标API函数是否被调用成功,若所述目标API函数被调用成功,则确定增大后的所述内存空间足够。
[0225] 这里,内存增量可以为1024字节时正好是一个内存页面的大小,方便系统的内存管理。
[0226] 相应地,上述内存空间的分配对应的程序实现如下:
[0227] do{ if (pbyDriverListBuf){首先判断分配的空间变量是否不为空[0228] Free(pbyDriverListBuf); 如果不为空则释放掉之前分配的空间[0229] pbyDriverListBuf = NULL;}释放后将指针赋值为空
[0230] ulLen += 0x1024; 每一次我们将分配的空间增加1024个字节[0231] pbyDriverListBuf = (BYTE*)Malloc(ulLen); 然后重新分配内存空间[0232] }
[0233] 内存空间分配完成后,利用判断函数pfnZwQuerySystemInformation判断所述目标API函数是否被调用成功的程序实现如下:
[0234] while(pfnZwQuerySystemInformation(SystemModuleInformation, pbyDriverListBuf, ulLen, &ulLen) == STATUS_INFO_LENGTH_MISMATCH);
[0235] 确定出内存空间,获得至少一个目标隐藏驱动信息后,将获取到的至少一个隐藏驱动信息存储至内存空间中的变量pbyDriverListBuf中,程序实现如下:
[0236] pfnZwQuerySystemInformation(SystemModuleInformation, pbyDriverListBuf, ulLen, &ulLen);
[0237] 其中,变量pbyDriverListBuf中存储有已获取到的目标隐藏驱动信息的总数量,那么可以利用Int DriverNum = *(DWORD*)pbyDriverListBuf;来获取到变量中所有隐藏驱动信息的数量Int DriverNum。
[0238] 获取到所有隐藏驱动信息的数量后,作为一种可选的实施例,遍历所述存储变量,获取所述至少一个目标隐藏驱动信息的占用内存及所述至少一个目标隐藏驱动信息的名称。遍历存储变量的程序实现如下:
[0239] for (Index = 0; Index < DriverNum ; Index++){从0开始遍历[0240] pstSysModuleInfo->Modules[Index].ImageSize;获取驱动信息的占用内存[0241] char*pszDriverName=(char*)(pstSysModuleInfo->Modules[Index].FullPathName + pstSysModuleInfo->Modules[Index].OffsetToFileName);
[0242] }
[0243] 获取第一个驱动信息的名称,其中pszDriverName是驱动信息的名称。
[0244] 并且,由于本申请中在获取到驱动信息的名称或路径后,为了使得驱动层得知该驱动信息,做出相应的处理,方法还包括:
[0245] 利用所述回调接口调用至少一个目标隐藏驱动信息的名称或路径,将所述至少一个目标隐藏驱动信息的名称或路径发送至应用层。
[0246] 应用层获取到目标隐藏驱动信息的名称或路径后,可以打印驱动日志,也可以判断该驱动信息是否对系统存在安全隐患等相应的处理。
[0247] 获取到目标隐藏驱动信息后,作为一种可选的实施例,所述基于所述抽象基类中的链式指针调用对应哈希算法类中的哈希算法,利用各所述哈希算法计算所述至少一个目标隐藏驱动信息的目标哈希值,包括:
[0248] 预先确定各哈希算法的等级,获得不同等级的哈希算法组;每个等级的哈希算法组中至少包括一个对应等级的哈希算法,每个所述哈希算法组中的哈希算法具有预设的编号,所述哈希算法的等级与所述哈希算法的复杂度为正比;
[0249] 比如,第一等级哈希算法组中包括:编号1哈希算法、编号2哈希算法等;第二等级哈希算法组中包括编号1哈希算法、编号2哈希算法等;但第一等级哈希算法组中包括的编号1哈希算法与第二等级哈希算法组中包括的编号1哈希算法是不同的哈希算法。
[0250] 确定所述抽象基类中链式指针的调用策略,基于所述链式指针的调用策略顺序调用对应等级哈希算法组的哈希算法;
[0251] 根据所述对应等级哈希算法组的当前哈希算法确定出当前哈希值,并将所述当前哈希值作为当前哈希算法的下一哈希算法的运算参数;
[0252] 利用所述下一哈希算法对所述运算参数进行哈希运算,获取所述至少一个目标隐藏驱动信息的目标哈希值。
[0253] 这里,哈希算法有很多种,每种哈希算法本身的复杂度是不一样的,因此本申请可以根据哈希算法本身的复杂度确定相应的等级,比如哈希算法包括A F,A和B的复杂度为一~般,C和D的复杂度为较复杂,E和F的复杂度为非常复杂;那么哈希算法A和B可以为第一等级的哈希算法组,哈希算法C和D可以为第二等级的哈希算法组,哈希算法E和F可以为第三等级的哈希算法组。
[0254] 而所述确定所述抽象基类中链式指针的调用策略,包括:
[0255] 获取所述目标隐藏驱动信息哈希名称的长度;
[0256] 若所述目标隐藏驱动信息哈希名称的长度小于A,则确定所述链式指针的调用策略为调用不同等级的哈希算法;