《電子技術(shù)應(yīng)用》
您所在的位置:首頁(yè) > 通信與網(wǎng)絡(luò) > 業(yè)界動(dòng)態(tài) > 網(wǎng)絡(luò)安全編程:HOOK SSDT

網(wǎng)絡(luò)安全編程:HOOK SSDT

2021-07-31
來(lái)源:計(jì)算機(jī)與網(wǎng)絡(luò)安全
關(guān)鍵詞: HOOKSSDT

  SSDT把用戶(hù)層的Win32 API與內(nèi)核層的Native API做了一個(gè)關(guān)聯(lián),而整個(gè)Native API都保存在SSDT中的一個(gè)函數(shù)指針數(shù)組中,只要修改函數(shù)指針數(shù)組中的某一項(xiàng),就相當(dāng)于HOOK了某個(gè)Native API函數(shù)。比如,修改SSDT中函數(shù)指針數(shù)組中的最后一個(gè)函數(shù)指針,就相當(dāng)于HOOK了NtQueryPortInformationProcess()函數(shù)。

  下面HOOK一個(gè)比較熟悉的函數(shù),即創(chuàng)建進(jìn)程函數(shù)NtCreateProcessEx()。該函數(shù)在指針數(shù)組的第0x30項(xiàng)(該編號(hào)根據(jù)系統(tǒng)版本的不同而不同,是系統(tǒng)相關(guān)的)。通過(guò)編程獲取SSDT表,然后找到Native API的函數(shù)指針數(shù)組,再修改其中第0x30項(xiàng)的內(nèi)容為自己的函數(shù)地址。為了不影響進(jìn)程的正常創(chuàng)建,在函數(shù)中調(diào)用NtCreateProcessEx()函數(shù)。代碼如下:

  #include <ntddk.h>

  typedef struct _SERVICE_DESCRIPTOR_TABLE

  {

  PULONG ServiceTableBase;

  PULONG ServiceCounterTableBase;

  ULONG NumberOfServices;

  PUCHAR ParamTableBase;

  }SERVICE_DESCRIPTOR_TABLE, *PSERVICE_DESCRIPTOR_TABLE;

  extern PSERVICE_DESCRIPTOR_TABLE KeServiceDescriptorTable;

  typedef NTSTATUS (*NTCREATEPROCESSEX)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES,

  HANDLE, ULONG, HANDLE, HANDLE, HANDLE, ULONG);

  // 保存 NtCreateProcessEx 函數(shù)的地址

  NTCREATEPROCESSEX ulNtCreateProcessEx = 0;

  // 在指針數(shù)組中 NtCreateProcessEx 的地址

  ULONG ulNtCreateProcessExAddr = 0;

  VOID UN_PROTECT()

  {

  __asm

  {

  push eax

  mov eax, CR0

  and eax, 0FFFEFFFFh

  mov CR0, eax

  pop eax

  }

  }

  VOID RE_PROTECT()

  {

  __asm

  {

  push eax

  mov eax, CR0

  or eax, 0FFFEFFFFh

  mov CR0, eax

  pop eax

  }

  }

  VOID DriverUnload(PDRIVER_OBJECT pDriverObject)

  {

  UN_PROTECT();

  // 替換 NtCreateProcessEx 的地址為 MyNtCreateProcessEx

  *(PULONG)ulNtCreateProcessExAddr = (ULONG)ulNtCreateProcessEx;

  RE_PROTECT();

  }

  NTSTATUS

  MyNtCreateProcessEx(

  __out PHANDLE ProcessHandle,

  __in ACCESS_MASK DesiredAccess,

  __in_opt POBJECT_ATTRIBUTES ObjectAttributes,

  __in HANDLE ParentProcess,

  __in ULONG Flags,

  __in_opt HANDLE SectionHandle,

  __in_opt HANDLE DebugPort,

  __in_opt HANDLE ExceptionPort,

  __in ULONG JobMemberLevel

 ?。?/p>

  {

  NTSTATUS Status = STATUS_SUCCESS;

  KdPrint((“Enter MyNtCreateProcessEx! \r\n”));

  Status = ulNtCreateProcessEx(ProcessHandle,

  DesiredAccess,

  ObjectAttributes,

  ParentProcess,

  Flags,

  SectionHandle,

  DebugPort,

  ExceptionPort,

  JobMemberLevel);

  return Status;

  }

  VOID HookCreateProcess()

  {

  ULONG ulSsdt = 0;

  // 保存 NtCreateProcess 的地址

  // 獲取 SSDT

  ulSsdt = (ULONG)KeServiceDescriptorTable->ServiceTableBase;

  // 獲取 NtCreateProcessEx 地址的指針

  ulNtCreateProcessExAddr = ulSsdt + 0x30 * 4;

  // 備份 NtCreateProcessEx 的原始地址

  ulNtCreateProcessEx = (NTCREATEPROCESSEX) *(PULONG)ulNtCreateProcessExAddr;

  UN_PROTECT();

  // 替換 NtCreateProcessEx 的地址為 MyNtCreateProcessEx

  *(PULONG)ulNtCreateProcessExAddr = (ULONG)MyNtCreateProcessEx;

  RE_PROTECT();

  }

  NTSTATUS DriverEntry(

  PDRIVER_OBJECT pDriverObject,

  PUNICODE_STRING pRegistryPath

  )

  {

  NTSTATUS Status = STATUS_SUCCESS;

  pDriverObject->DriverUnload = DriverUnload;

  HookCreateProcess();

  return Status;

  }

  DriverEntry()中調(diào)用了HookCreateProcess()函數(shù),該函數(shù)的作用是將指針數(shù)組中NtCreateProcessEx()函數(shù)的地址替換為MyNtCreateProcessEx()函數(shù)的地址。而MyNtCreateProcessEx()函數(shù)是用來(lái)取代NtCreateProcessEx()函數(shù)的函數(shù),在這里的函數(shù)中調(diào)用了一條KdPrint()用于輸出代碼。整個(gè)HOOK的過(guò)程非常簡(jiǎn)單,只要找到指針數(shù)組的位置,保存原地址后修改為新的地址即可。代碼中出現(xiàn)了兩個(gè)函數(shù),分別是UN_PROTECT()和RE_PROTECT()。這兩個(gè)函數(shù)的作用是禁止和開(kāi)啟CPU向標(biāo)志為只讀的內(nèi)存頁(yè)進(jìn)行寫(xiě)入的操作。執(zhí)行UN_PROTECT后, CPU可以向標(biāo)志為只讀的內(nèi)存頁(yè)進(jìn)行寫(xiě)入操作。當(dāng)寫(xiě)入完成后,調(diào)用RE_PROTECT()函數(shù)恢復(fù)到原來(lái)的狀態(tài)。把它放到虛擬機(jī)中,打開(kāi)DebugView,然后加載該驅(qū)動(dòng),加載成功后隨便運(yùn)行一個(gè)可執(zhí)行程序??梢钥吹?,DebugView中顯示了在MyNtCreateProcessEx()中的輸出,如圖1所示,說(shuō)明HOOK成功了。

  圖1  MyNtCreateProcessEx()函數(shù)的輸出




電子技術(shù)圖片.png

本站內(nèi)容除特別聲明的原創(chuàng)文章之外,轉(zhuǎn)載內(nèi)容只為傳遞更多信息,并不代表本網(wǎng)站贊同其觀點(diǎn)。轉(zhuǎn)載的所有的文章、圖片、音/視頻文件等資料的版權(quán)歸版權(quán)所有權(quán)人所有。本站采用的非本站原創(chuàng)文章及圖片等內(nèi)容無(wú)法一一聯(lián)系確認(rèn)版權(quán)者。如涉及作品內(nèi)容、版權(quán)和其它問(wèn)題,請(qǐng)及時(shí)通過(guò)電子郵件或電話(huà)通知我們,以便迅速采取適當(dāng)措施,避免給雙方造成不必要的經(jīng)濟(jì)損失。聯(lián)系電話(huà):010-82306118;郵箱:aet@chinaaet.com。