티스토리 뷰

반응형

원문 : https://woounnan.tistory.com/92

 

1.원리

 -SSDT 내에 존재하는 Native 함수는 ntoskrnl.exe 모듈 내에 존재.

 -SSDT를 검사하여, ntoskrnl.exe 외의 영역에 존재하는 함수주소가 존재할 경우

 후킹되었다고 판단.

 

2.필요 요소

 -ntoskrnl.exe 영역 주소 구하기

1)GetListOfModules:: ZwQuerySystemInformation의 2번째 인자를SystemModuleInformation로 주면 

 커널영역에 로드된 모든 모듈정보를 얻어올 수 있음.

2)DriverEntry:: 얻어진 모듈정보 중 모듈이름을 비교하여, ntoskrnl.exe 모듈을 찾음.

3)FindSSDTHook:: SSDT를 ntoskrnl.exe 영역과 비교.

 

3.주요 코드

void FindSSDTHook(void)
{
 unsigned int i;
 DbgPrint("start FindSSDTHook()\n");
 for (i = 0; i < KeServiceDescriptorTable.NumberOfServices; i++)
 {

  if ((KeServiceDescriptorTable.ServiceTableBase[i] < G_ntoskrnl.Base)
   || (KeServiceDescriptorTable.ServiceTableBase[i] > G_ntoskrnl.End))
  {
   DbgPrint("시스템 콜:[%d]이 [%x]로 후킹되었습니다. \n", i, KeServiceDescriptorTable.ServiceTableBase[i]);
  }
 }
}



PMODULE_LIST GetListOfModules(PNTSTATUS pns)
{
 ULONG moduleTotalSize;
 ULONG *ModuleListAddr = NULL;
 NTSTATUS ns;
 PMODULE_LIST pml = NULL;

 //모듈 정보 크기 구함.
 ZwQuerySystemInformation(SystemModuleInformation,
  &moduleTotalSize,
  0,
  &moduleTotalSize
 );



 //모듈 정보 담을 메모리 공간 할당.

 ModuleListAddr = (ULONG *)ExAllocatePool(PagedPool,
  moduleTotalSize);

 if (!ModuleListAddr) // ExAllocatePool 실패 
 {
  if (pns != NULL)
   *pns = STATUS_INSUFFICIENT_RESOURCES;
   
  return (PMODULE_LIST)ModuleListAddr;
 }



 ns = ZwQuerySystemInformation(
  SystemModuleInformation,
  ModuleListAddr,
  moduleTotalSize,
  0
 );


 if (ns != STATUS_SUCCESS)// ZwQuerySysternlnformation 실패
 {
  // 할당한 메모리 해제
  ExFreePool((PVOID)ModuleListAddr);
  if (pns != NULL)
   *pns = ns;
  return NULL;
 }

 pml = (PMODULE_LIST)ModuleListAddr;

 if (pns != NULL)
  *pns = ns;
 return pml;
}




NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{
 int count;
 G_PModuleList = NULL;
 G_ntoskrnl.Base = 0;
 G_ntoskrnl.End = 0;
 G_PModuleList = GetListOfModules(NULL);

 UNREFERENCED_PARAMETER(RegistryPath);

 DriverObject->DriverUnload = OnUnload;
 if (!G_PModuleList)
  return STATUS_UNSUCCESSFUL;

 for (count = 0; count < G_PModuleList->ModuleCount; count++)
 {
  //find ntoskrnl.exe
  if (_stricmp("ntoskrnl.exe", (char*)G_PModuleList->ModuleInfo[count].ModulePath + G_PModuleList->ModuleInfo[count].NameOffset) == 0)
  {
   DbgPrint("Wow, find ntoskrnl.exe!!\n");
   DbgPrint("ntoskrnl.exe\n");
   G_ntoskrnl.Base = (DWORD)G_PModuleList->ModuleInfo[count].Base;
   G_ntoskrnl.End = ((DWORD)G_PModuleList->ModuleInfo[count].Base + G_PModuleList->ModuleInfo[count].Size);
   DbgPrint("start Addr:%x\n", G_ntoskrnl.Base);
   DbgPrint("end Addr:%x\n", G_ntoskrnl.End);
  }
 }
 ExFreePool(G_PModuleList);

 if (G_ntoskrnl.Base != 0)
 {
  FindSSDTHook();
  return STATUS_SUCCESS;
 }
 else
 {
  DbgPrint("Sorry, not find ntoskrnl.exe!!\n");
  return STATUS_UNSUCCESSFUL;
 }

 

<관련글>

[Volatility] 커널 공간 후킹 탐지

반응형
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
글 보관함