A forum for reverse engineering, OS internals and malware analysis 

Forum for discussion about kernel-mode development.
 #13746  by m5home
 Wed Jun 06, 2012 1:44 am
Hook SSDT in Win7x64 is easy.
But I don't think it is useful.
Because you need to disable PatchGuard(use fyyre's DISABLE_PG_DS_V3).
This is the main code:
Code: Select all
//Author: Tesla.Angela [www.m5home.com/bbs]
#include <ntddk.h>

PSYSTEM_SERVICE_TABLE KeServiceDescriptorTable;
NTTERMINATEPROCESS NtTerminateProcess=NULL;
ULONG OldTpVal;

NTSTATUS __fastcall Fake_NtTerminateProcess(IN HANDLE ProcessHandle, IN NTSTATUS ExitStatus)
{
        PEPROCESS Process;
        NTSTATUS st = ObReferenceObjectByHandle (ProcessHandle, 0, *PsProcessType, KernelMode, &Process, NULL);
        DbgPrint("Fake_NtTerminateProcess called!");
        if(NT_SUCCESS(st))
        {
                if(!_stricmp(PsGetProcessImageFileName(Process),"loaddrv.exe")||!_stricmp(PsGetProcessImageFileName(Process),"calc.exe"))
                        return STATUS_ACCESS_DENIED;
                else
                        return NtTerminateProcess(ProcessHandle,ExitStatus);
        }
        else
                return STATUS_ACCESS_DENIED;
}

ULONGLONG GetKeServiceDescriptorTable64() //written by a foreigner
{
        char KiSystemServiceStart_pattern[13] = "\x8B\xF8\xC1\xEF\x07\x83\xE7\x20\x25\xFF\x0F\x00\x00"; 
        ULONGLONG CodeScanStart = (ULONGLONG)&_strnicmp;
        ULONGLONG CodeScanEnd = (ULONGLONG)&KdDebuggerNotPresent;
        UNICODE_STRING Symbol;
        ULONGLONG i, tbl_address, b;
        for (i = 0; i < CodeScanEnd - CodeScanStart; i++)
        {
                if (!memcmp((char*)(ULONGLONG)CodeScanStart +i, (char*)KiSystemServiceStart_pattern,13))
                { 
                        for (b = 0; b < 50; b++)
                        {
                                tbl_address = ((ULONGLONG)CodeScanStart+i+b);
                                if (*(USHORT*) ((ULONGLONG)tbl_address ) == (USHORT)0x8d4c)
                                        return ((LONGLONG)tbl_address +7) + *(LONG*)(tbl_address +3);
                        }
                }
        }
        return 0;
}

ULONGLONG GetSSDTFuncCurAddr(ULONG id)
{
        LONG dwtmp=0;
        PULONG ServiceTableBase=NULL;
        ServiceTableBase=(PULONG)KeServiceDescriptorTable->ServiceTableBase;
        dwtmp=ServiceTableBase[id];
        dwtmp=dwtmp>>4;
        return (LONGLONG)dwtmp + (ULONGLONG)ServiceTableBase;
}

ULONG GetOffsetAddress(ULONGLONG FuncAddr)
{
        ULONG dwtmp=0;
        PULONG ServiceTableBase=NULL;
        ServiceTableBase=(PULONG)KeServiceDescriptorTable->ServiceTableBase;
        dwtmp=(ULONG)(FuncAddr-(ULONGLONG)ServiceTableBase);
        return dwtmp<<4;
}

VOID FuckKeBugCheckEx()
{
        KIRQL irql;
        ULONGLONG myfun;
        UCHAR jmp_code[]="\x48\xB8\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xE0";
        myfun=(ULONGLONG)Fake_NtTerminateProcess;
        memcpy(jmp_code+2,&myfun,8);
        irql=WPOFFx64();
        memset(KeBugCheckEx,0x90,15);
        memcpy(KeBugCheckEx,jmp_code,12);
        WPONx64(irql);
}

/*
填写KeBugCheckEx的地址
在KeBugCheckEx填写jmp,跳到Fake_NtTerminateProcess
不能直接填写Fake_NtTerminateProcess的地址,因为它们不再同一个4GB
*/
VOID HookSSDT()
{
        KIRQL irql;
        ULONGLONG dwtmp=0;
        PULONG ServiceTableBase=NULL;
        //get old address
        NtTerminateProcess=(NTTERMINATEPROCESS)GetSSDTFuncCurAddr(41);
        dprintf("Old_NtTerminateProcess: %llx",(ULONGLONG)NtTerminateProcess);
        //set kebugcheckex
        FuckKeBugCheckEx();
        //show new address
        ServiceTableBase=(PULONG)KeServiceDescriptorTable->ServiceTableBase;
        OldTpVal=ServiceTableBase[41];        //record old offset value
        irql=WPOFFx64();
        ServiceTableBase[41]=GetOffsetAddress((ULONGLONG)KeBugCheckEx);
        WPONx64(irql);
        dprintf("KeBugCheckEx: %llx",(ULONGLONG)KeBugCheckEx);
        dprintf("New_NtTerminateProcess: %llx",GetSSDTFuncCurAddr(41));
}

VOID UnhookSSDT()
{
        KIRQL irql;
        PULONG ServiceTableBase=NULL;
        ServiceTableBase=(PULONG)KeServiceDescriptorTable->ServiceTableBase;
        //set value
        irql=WPOFFx64();
        ServiceTableBase[41]=GetOffsetAddress((ULONGLONG)NtTerminateProcess);        //OldTpVal;        //直接填写这个旧值也行
        WPONx64(irql);
        //没必要恢复KeBugCheckEx的内容了,反正执行到KeBugCheckEx时已经完蛋了。
        dprintf("NtTerminateProcess: %llx",GetSSDTFuncCurAddr(41));
}
hookssdt.jpg
hookssdt.jpg (258.14 KiB) Viewed 1010 times
Attachments
This is the bin
(470.2 KiB) Downloaded 85 times
 #13820  by m5home
 Fri Jun 08, 2012 10:31 pm
Vrtule wrote:Yes, ObRegisterCallbacks does the job much much better and the defense is less vulnerable. Personally, I do not see much interesting in this kind of hooking on 64bit systems.
I know, kernel hook is not a good way in WIN64.

But kernel hook(include SSDT HOOK and INLINE HOOK) can do many things.

ObRegisterCallbacks can monitor process/thread handle only, it means that this function can protect process/thread only.

My rule: Try to use standard method, if standard method cannot realize my need, I will use hook to realize it.
 #13912  by Dmitry Varshavsky
 Mon Jun 11, 2012 9:35 pm
m5home wrote:
Vrtule wrote:Yes, ObRegisterCallbacks does the job much much better and the defense is less vulnerable. Personally, I do not see much interesting in this kind of hooking on 64bit systems.
I know, kernel hook is not a good way in WIN64.

But kernel hook(include SSDT HOOK and INLINE HOOK) can do many things.

ObRegisterCallbacks can monitor process/thread handle only, it means that this function can protect process/thread only.

My rule: Try to use standard method, if standard method cannot realize my need, I will use hook to realize it.
ObRegisterCallbacks is much more flexible and useful than hooking of single NtTerminateProcess routine. It can restrict suspend/resume, vm operations, setting of context and many other things. You would require a bunch of hooked functions to achieve the whole functionality ObRegisterCallbacks provide you. Especially when we talk about x64 systems..
Think about it.
 #13921  by m5home
 Tue Jun 12, 2012 11:20 am
Dmitry Varshavsky wrote:
m5home wrote:
Vrtule wrote:Yes, ObRegisterCallbacks does the job much much better and the defense is less vulnerable. Personally, I do not see much interesting in this kind of hooking on 64bit systems.
I know, kernel hook is not a good way in WIN64.

But kernel hook(include SSDT HOOK and INLINE HOOK) can do many things.

ObRegisterCallbacks can monitor process/thread handle only, it means that this function can protect process/thread only.

My rule: Try to use standard method, if standard method cannot realize my need, I will use hook to realize it.
ObRegisterCallbacks is much more flexible and useful than hooking of single NtTerminateProcess routine. It can restrict suspend/resume, vm operations, setting of context and many other things. You would require a bunch of hooked functions to achieve the whole functionality ObRegisterCallbacks provide you. Especially when we talk about x64 systems..
Think about it.
This topic is just a demo code of "HOOK SSDT IN WIN64".
I NEVER SAID "HOOK SSDT TO PROTECT PROCESS IS BETTER THEN USE ObRegisterCallbacks".
 #13923  by m5home
 Tue Jun 12, 2012 11:24 am
EP_X0FF wrote:Capslock off please.

OK, next time, I will.
 #17464  by m5home
 Tue Jan 01, 2013 4:50 pm
Something about kernel hook on X64:
1.Hook SSDT is illegal on WIN7 and WIN8.
2.Hook SHADOW SSDT is illegal on WIN8 but is legal on WIN7.
3.Hook Kernel Object Routine Function is illegal on WIN8 but is legal on WIN7.
4.Hook FSD dispatch function is legal on WIN7(Is it legal on WIN8? I don't know).
 #17956  by gloryo
 Fri Feb 01, 2013 5:34 am
m5home wrote:Something about kernel hook on X64:
1.Hook SSDT is illegal on WIN7 and WIN8.
2.Hook SHADOW SSDT is illegal on WIN8 but is legal on WIN7.
3.Hook Kernel Object Routine Function is illegal on WIN8 but is legal on WIN7.
4.Hook FSD dispatch function is legal on WIN7(Is it legal on WIN8? I don't know).

i'd like to know about no 3.

u mean hook object_type_initializer function of any kernel object type is illegal on windows 8?