天天看點

SSDT 是什麼

SSDT的全稱是System Services Descriptor Table,系統服務描述符表。這個表就是一個把ring3的Win32 API和ring0的核心API聯系起來。SSDT并不僅僅隻包含一個龐大的位址索引表,它還包含着一些其它有用的資訊,諸如位址索引的基位址、服務函數個數等。

  通過修改此表的函數位址可以對常用windows函數及API進行hook,進而實作對一些關心的系統動作進行過濾、監控的目的。一些HIPS、防毒軟體、系統監控、系統資料庫監控軟體往往會采用此接口來實作自己的監控子產品,

  目前極個别病毒确實會采用這種方法來保護自己或者破壞防毒軟體,但在這種病毒進入系統前如果防毒軟體能夠識别并清除它将沒有機會發作.

  什麼是SSDT?較為正式一些的诠釋是System Service Descriptor Table(系統服務描述符表)

  那麼到底這個描述表是用來幹什麼的?他在記憶體中是如何組織的呢?

  首先,SSDT的結構:

  引用:

  typedef struct _SYSTEM_SERVICE_TABLE

  {

  PVOID ServiceTableBase; //這個指向系統服務函數位址表

  PULONG ServiceCounterTableBase;

  ULONG NumberOfService; //服務函數的個數

  ULONG ParamTableBase;

  }SYSTEM_SERVICE_TABLE,*PSYSTEM_SERVICE_TABLE;

  typedef struct _SERVICE_DESCRIPTOR_TABLE

  {

  SYSTEM_SERVICE_TABLE ntoskrnel; //ntoskrnl.exe的服務函數

  SYSTEM_SERVICE_TABLE win32k; //win32k.sys的服務函數,(gdi.dll/user.dll的核心支援)

  SYSTEM_SERVICE_TABLE NotUsed1;

  SYSTEM_SERVICE_TABLE NotUsed2;

  }SYSTEM_DESCRIPTOR_TABLE,*PSYSTEM_DESCRIPTOR_TABLE;

  實際上核心中存在兩個系統服務描述符表,一個是KeServiceDescriptorTable(由ntoskrnl.exe導出),一個是KeServieDescriptorTableShadow(沒有導出)。

  從上述結構中,我們可以看出,KeServieDescriptorTableShadow不但包含了ntoskrnel項,而且還包含了win32k項,而KeServiceDescriptorTable僅僅包含一個ntoskrnel項。

  我們用WinDbg看看,到底這個KeServiceDescriptorTable是什麼東西。

  引用:

  lkd> dd KeServiceDescriptorTable

  80553380 81f61008 00000000 0000013d 81e62358

  80553390 00000000 00000000 00000000 00000000

  805533a0 00000000 00000000 00000000 00000000

  805533b0 00000000 00000000 00000000 00000000

  805533c0 00002710 bf80c217 00000000 00000000

  805533d0 f8951a80 f80839e0 81f433a8 806e0f40

  805533e0 00000000 00000000 00000000 00000000

  805533f0 83740440 01c8eac3 00000000 00000000

  我們可以看出,函數表基位址為81f61008,存在0000013d個服務項

  我們繼續看看81f61008位址的記憶體塊内,到底放了些什麼。

  引用:

  lkd> dd 81f61008

  81f61008 80599746 805e6914 805ea15a 805e6946

  81f61018 805ea194 805e697c 805ea1d8 805ea21c

  81f61028 8060b880 8060c5d2 805e1cac 805e1904

  81f61038 805ca928 805ca8d8 8060bea6 805ab334

  81f61048 8060b4be 8059dbbc 805a5786 f8807de8

  81f61058 804ffed0 8060c5c4 8056be64 805353f2

  81f61068 80604b90 805b19c0 805ea694 80619a56

  81f61078 805eeb86 80599e34 80619caa 805996e6

  這裡面的資料到底表示什麼呢?實際上,這表示的是一個入口位址。我們對其中一個位址進行反彙編看看

  引用:

  lkd> u 80599746

  nt!NtConnectPort+0x60:

  80599746 689c000000 push 9Ch

  8059974b 6820a14d80 push offset nt!FsRtlLegalAnsiCharacterArray+0x1680 (804da120)

  80599750 e8abebf9ff call nt!wctomb+0x45 (80538300)

  80599755 64a124010000 mov eax,dword ptr fs:[00000124h]

  8059975b 8a8040010000 mov al,byte ptr [eax+140h]

繼續閱讀