Then according to your line of thought the following should work:
Code: Select alltypedef NTSTATUS (__stdcall *QUERY_SYS_INFO)(
__in SYSTEM_INFORMATION_CLASS SystemInformationClass,
__inout PVOID SystemInformation,
__in ULONG SystemInformationLength,
__out_opt PULONG ReturnLength
);
QUERY_SYS_INFO ZwQuerySystemInformation = NULL;
QUERY_SYS_INFO myNtQuerySystemInformation = NULL;
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{
//some code ommited
RtlInitUnicodeString(&FuncName, L"ZwQuerySystemInformation");
ZwQuerySystemInformation = (QUERY_SYS_INFO)MmGetSystemRoutineAddress(&FuncName);
myNtQuerySystemInformation = (QUERY_SYS_INFO)getRealFuncAddress((BYTE *)ZwQuerySystemInformation, KeServiceDescriptorTable.KiServiceTable);
myNtQuerySystemInformation = (QUERY_SYS_INFO) ((PBYTE)myNtQuerySystemInformation + 2);
if( NT_SUCCESS(inlineHookInstall()) ) {
DbgPrint("Successfully patched the function\n");
}
//code ommited for brevity
}
Code: Select allNTSTATUS inlineHookInstall() {
NTSTATUS status;
UNICODE_STRING FuncName = {0};
DWORD dwOldCR0 = 0;
BYTE *funcPointer = NULL;
//get the address we want to start overwriting
funcPointer = getRealFuncAddress((BYTE *)ZwQuerySystemInformation, KeServiceDescriptorTable.KiServiceTable);
if(!funcPointer) {
DbgPrint("Error getting the real address of NtQuerySYsteminformation\n");
return STATUS_UNSUCCESSFUL;
}
DbgPrint("Address of NTQUERYSYSINFO IS %p", funcPointer);
dwOldCR0=__readcr0();
__writecr0(dwOldCR0&~(1<<16));
writeBytesToMemSafe(funcPointer);
__writecr0(dwOldCR0);
return STATUS_SUCCESS;
}
Code: Select allvoid writeBytesToMemSafe(PVOID Addr) {
BYTE shortJMP[] = "\xEB\xF9";
BYTE longJMP[] = "\xE9\xDE\xAD\xBE\xEF";
//now instead of 0XDEADBEEF we have the address of our routine.
FixJMPAddress(longJMP, (BYTE *) myZwQuerySystemInformation, (BYTE *) Addr);
//overwrite the nopsled
RtlCopyMemory((PBYTE)Addr - 5 , longJMP, 5);
//copy the short jump instead of mov edi, edi
RtlCopyMemory((PBYTE) Addr, shortJMP, 2);
DbgPrint("Jump fixed address: %p\n", Prolog_NtQuerySys);
}
Code: Select allNTSTATUS myZwQuerySystemInformation(SYSTEM_INFORMATION_CLASS SystemInformationClass, PVOID SystemInformation, ULONG SystemInformationLength, PULONG ReturnLength)
{
NTSTATUS ntStatus;
PSYSTEM_PROCESS_INFORMATION currentProcInfo;
PSYSTEM_PROCESS_INFORMATION previousProcInfo;
BYTE *tempMath;
ntStatus = myNtQuerySystemInformation(SystemInformationClass, SystemInformation, SystemInformationLength, ReturnLength);
if(!NT_SUCCESS(ntStatus))
return ntStatus;
//code ommitted for brevity
Basically I take the address of the NT routine from the Index of the ZwQuerySystemInfo and use that in my hook function but unfortunately this doesn't work. My code goes into some section which consists of just int 3 and nothing happens. The correct overwrites are performed but then when the code jumps to my hook function everything goes south....
Here is how my assembly looks like:
Code: Select allnt!NtQuerySystemInformation:
0x8288A416 jmp nt!CmpDereferenceKeyControlBlockWithLock+0xb1 (8288a411)
0x8288A418 push ebp
0x8288A419 mov ebp,esp
0x8288A41B mov edx,dword ptr [ebp+8]
0x8288A41E cmp edx,53h
Code: Select all0x8288A411 jmp SSDThook!SSDThookDefaultHandler+0x3b (9469e2cb)
Code: Select all0x9469E2CC int 3
0x9469E2CD int 3
0x9469E2CE int 3
0x9469E2CF int 3
--- e:\drivers\development\ssdthook\ssdthook\ssdthook.cpp ----------------------
{
0x9469E2D0 mov edi,edi
0x9469E2D2 push ebp
0x9469E2D3 mov ebp,esp
0x9469E2D5 sub esp,20h
0x9469E2D8 push esi
0x9469E2D9 push edi
and at some point my code just keep looping at the INT3 Region o_O