SSDT即System Service Dispath Table,它是一個表,這個表中有內核調用的函數地址。
KeServiceDescriptorTable:是由內核(Ntoskrnl.exe)導出的一個表

,這個表是訪問SSDT的關鍵,具體結構是
typedef struct ServiceDescriptorTable {
PVOID ServiceTableBase;
PVOID ServiceCounterTable(0);
unsigned int NumberOfServices;
PVOID ParamTableBase;
}

其中,
ServiceTableBase System Service Dispatch Table 的基地址。
NumberOfServices 由 ServiceTableBase 描述的服務的數目。
ServiceCounterTable 此域用於操作系統的 checked builds,包含著 SSDT 中每個服務被調用次數的計數器。這個計數器由 INT 2Eh 處理程序 (KiSystemService)更新。
ParamTableBase 包含每個系統服務參數字節數表的基地址。

CR0當中有一個寫保護位,是保護內存不可寫屬性的,為了能夠寫入內核,只能把它的保護給咔嚓掉了,不過……如果做完了手腳但不還原寫保護屬性的話,極有可能會BOSD.

代碼實例如下:

#include <NTDDK.h>

#pragma pack(1)
typedef struct ServiceDescriptorEntry {
unsigned int *ServiceTableBase;
unsigned int *ServiceCounterTableBase; //Used only in checked build
unsigned int NumberOfServices;
unsigned char *ParamTableBase;
} ServiceDescriptorTableEntry, *PServiceDescriptorTableEntry;
#pragma pack()

_declspec(dllimport) ServiceDescriptorTableEntry

KeServiceDescriptorTable;

NTSYSAPI NTSTATUS ZwOpenProcess(OUT PHANDLE ProcessHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN PCLIENT_ID ClientId);

typedef NTSTATUS (*ZWOPENPROCESS)(OUT PHANDLE ProcessHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN PCLIENT_ID ClientId);

#define SYSTEMSERVICE(_function)

KeServiceDescriptorTable.ServiceTableBase[*(PULONG)((PUCHAR)_function + 1)]

ZWOPENPROCESS OldZwOpenProcess;

NTSTATUS MyZwOpenProcess(PHANDLE ProcessHandle,
ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes,
PCLIENT_ID ClientId)
{
NTSTATUS ntStatus = STATUS_SUCCESS;

KdPrint(("MyZwOpenProcess\r\n"));

//調用原來的NtOpenProcess;
ntStatus = OldZwOpenProcess(ProcessHandle, DesiredAccess, ObjectAttributes, ClientId);

return ntStatus;
}

VOID DriverUnload(IN PDRIVER_OBJECT DriverObject)
{
__asm

{
cli
mov  eax,cr0
and  eax,not 10000h
mov  cr0,eax
}

(ZWOPENPROCESS)SYSTEMSERVICE(ZwOpenProcess) = OldZwOpenProcess;//恢復HOOK SSDT

__asm

{
mov  eax,cr0
or   eax,10000h
mov  cr0,eax
sti
}

KdPrint(("驅動卸載完畢!\r\n"));
}

NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING pRegistryPath)
{
NTSTATUS status = STATUS_SUCCESS;
KdPrint(("The driver begin loading.\r\n"));
DriverObject->DriverUnload = DriverUnload;
OldZwOpenProcess = (ZWOPENPROCESS)SYSTEMSERVICE(ZwOpenProcess);

__asm

{
cli
mov  eax,cr0
and  eax,not 10000h
mov  cr0,eax
}

(ZWOPENPROCESS)SYSTEMSERVICE(ZwOpenProcess) = MyZwOpenProcess;    

//HOOK SSDT

__asm

{
mov  eax,cr0
or   eax,10000h
mov  cr0,eax
sti
}


KdPrint(("The driver ends loading\r\n"));
return status;
}

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 殘月影 的頭像
    殘月影

    Rootkit --逆向工程技術--

    殘月影 發表在 痞客邦 留言(0) 人氣()