久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

標題: HOOK SSDT表的理解(1) [打印本頁]

作者: liuyuxi    時間: 2015-1-10 23:20
標題: HOOK SSDT表的理解(1)
**********************************************************************
剛開始時挺難理解SSDT 郁金香的視頻教程說的還是不夠詳細,后來自己實驗了,
多比較,多看就明白怎么回事了,現在寫下來方便以后自己查看。
**********************************************************************
SSDT 是一張表,里面存儲了所有Nt開頭的內核API內存地址。
每個內核API都有一個索引號。系統通過這個索引號得到相應的內核NtAPI的內存地址然后調用
可以把 SSDT 想象成一個LONG *SSDT 指針:
LONG *SSDT;
SSDT[0] 存儲著 NtAcceptConnectPort 所在的內存地址   0x805A565C
SSDT[1] 存儲著 NtAccessCheck 所在的內存地址         0x805F243E
...
SSDT[122] 存儲著 NtOpenProcess 所在的內存地址       0x805CC470  
其中數組元素
0 就是 NtAcceptConnectPort 索引號
1 就是 NtAccessCheck 索引號
122 就是 NtOpenProcess 索引號
如果要得到NtOpenProcess所在的內存地址 首先必須要知道 SSDT首地址 和 NtOpenProcess的索引號
【注意】不同的系統版本索引號也會不一樣 此處僅僅是為了解釋SSDT表。
現在根據實例來配合,現在要得到NtOpenProcess的內存地址
用 winDebug 得到 SSDT這個表的首地址是 0x80505480




進入這個地址看看里面的內容是什么



0: kd> dd poi[KeServiceDescriptorTable]
  地址       0        1        2        3  
80505480  805a565c 805f243e 805f5c74 805f2470
             4        5        6        7
80505490  805f5cae 805f24a6 805f5cf2 805f5d36
             8        9        10       11
805054a0  80616d1e 80617a60 805ed83c 805ed494
805054b0  805d5bae 805d5b5e 80617344 805b6fe2
805054c0  80616960 805a9ae6 805b15f6 805d7672
805054d0  8050289c 80617a52 80577b0a 80539c34
805054e0  8060ff2e 805bd55c 805f61ae 80624cf0
805054f0  805fa6c2 805a5d4a 80624f44 805a55fc

看到 0x80505480 這個地址存的第0個地址是 0x805A565C
Kerne Detective 這個工具看看這個是什么API




0個是NtAcceptConnectPort 這個API
可以看到 WinDebug 得到的數據 和 KD 一樣
用工具可以很容易找到SSDT的基地址 和 索引號以及NtAPI的內存地址
用編程實現  (精華):
要檢查 SSDT 指定的NtAPI有沒有被HOOK 就要先 獲取到現在的NtAPI地址、獲取原來的NtAPI的內存地址,然后將兩個地址相比較即可。
獲取現在NtAPI的內存地址的具體流程
首先應該得到SSDT的首地址 即 基址
然后將ServiceTableBase 的內存首地址+索引號*4 得到存儲著相應索引號內核NtAPI現在的內存地址的地址(ServiceTableBase的偏移地址)
讀取該地址得到現在的NtAPI內存地址
獲取原來的NtAPI的內存地址的具體流程
通過 MmGetSystemRoutineAddress 可以得到原來的NtAPI 地址
主要是 獲取現在的NtAPI比較費心思去理解,只要理解了這個流程,也就理解了SSDT表的結構了。
看看下面的代碼以及注釋就能理解SSDT表的結構了
左邊是用KD工具得到 NOtOpenProcess 內存地址 右邊是用WinDebug得到




下圖是通過編程得到 NtOpenProcess 內存地址:




代碼:
ypedef struct _ServiceDescriptorTable {
     PVOID ServiceTableBase; //System Service Dispatch Table 的基地址
     PVOID ServiceCounterTable;
     //包含著SSDT 中每個服務被調用次數的計數器。這個計數器一般由sysenter 更新。
     unsigned int NumberOfServices;//由ServiceTableBase 描述的服務的數目。
     PVOID ParamTableBase; //包含每個系統服務參數字節數表的基地址-系統服務參數表
}*PServiceDescriptorTable;  
extern PServiceDescriptorTable KeServiceDescriptorTable;
ULONG GetNt_CurAddr() //獲取當前SSDT_NtOpenProcess的現在地址
{
LONG *SSDT_Adr,SSDT_NtOpenProcess_Cur_Addr,t_addr;      
KdPrint(("驅動成功被加載中.............................\n\n"));
KdPrint(("********************** 計算現在的地址**********************\n\n"));
//讀取SSDT表中索引值為x7A的函數
//poi(poi(KeServiceDescriptorTable)+0x7a*4)
t_addr=(LONG)KeServiceDescriptorTable->ServiceTableBase;     // 得到ServiceTableBase 的地址
KdPrint(("[得到ServiceTableBase 的基址] \n當前ServiceTableBase地址為0x%X \n\n",t_addr));
// 將該地址里面的內容+ 索引號* 4  就能得到相應索引號內核NtAPI現在的內存地址0x7A為NtOpenProcess在SSDT的索引
SSDT_Adr=(PLONG)(t_addr+0x7A*4);
KdPrint(("[將ServiceTableBase 的內存首地址+索引號*4 \n得到存儲著相應索引號內核NtAPI現在的內存地址的地址(ServiceTableBase的偏移地址)]\n"));
KdPrint(("SSDT首地址0x%X + 0x7A * 4= 0x%X  這個地址0x%X 存儲著索引號為0x7A 的NtOpenProcess內存地址\n\n", t_addr, SSDT_Adr, SSDT_Adr));
SSDT_NtOpenProcess_Cur_Addr=*SSDT_Adr;                       
KdPrint(("[讀取0x%X 得到NtOpenProcess 函數現在的內存地址] 現在的NtOpenProcess 內存地址為0x%X \n\n",SSDT_Adr, SSDT_NtOpenProcess_Cur_Addr));
KdPrint(("********************** 計算完畢***************************\n\n"));
// 匯編
/*
__asm
{    int 3
push ebx
push eax
  mov ebx,KeServiceDescriptorTable
  mov ebx,[ebx] //表的基地址 取 KeServiceDescriptorTable 的地址  t_addr=(LONG)KeServiceDescriptorTable->ServiceTableBase;
  mov eax,0x7a
  shl eax,2//0x7A*4 //imul eax,eax,4//shl eax,2
  add ebx,eax//[KeServiceDescriptorTable]+0x7A*4
  mov ebx,[ebx] // SSDT_NtOpenProcess_Cur_Addr=*SSDT_Adr;    // 取出該地址中存儲的NtOpenProcess 函數的地址      
        mov SSDT_NtOpenProcess_Cur_Addr,ebx
pop  eax
pop  ebx
}
*/
return SSDT_NtOpenProcess_Cur_Addr;                              // 將獲得的地址返回
}
ULONG GetNt_OldAddr()
{
     UNICODE_STRING Old_NtOpenProcess;
    ULONG Old_Addr;
     KdPrint(("********************** 計算原來的地址**********************\n\n"));
     RtlInitUnicodeString(&Old_NtOpenProcess,L"NtOpenProcess");
     Old_Addr=(ULONG)MmGetSystemRoutineAddress(&Old_NtOpenProcess);//取得NtOpenProcess的地址
     KdPrint(("用MmGetSystemRoutineAddress 取得原來NtOpenProcess 的地址為0x%X\n\n",Old_Addr));
     KdPrint(("********************** 計算完畢****************************\n\n"));
     return Old_Addr;
}
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject,PUNICODE_STRING B) //TYPEDEF LONG NTSTATUS
{  
     ULONG cur,old;
     cur=GetNt_CurAddr();// 得到現在的NtAPI 地址
     old=GetNt_OldAddr();// 得到原來的NtAPI 地址
     if (cur!=old)
         KdPrint(("NtOpenProcess被HOOK了"));
     else
         KdPrint(("NtOpenProcess 沒有被HOOK"));







歡迎光臨 (http://m.zg4o1577.cn/bbs/) Powered by Discuz! X3.1
主站蜘蛛池模板: 久久精品一区二区三区不卡牛牛 | 久久国产一区二区三区 | 婷婷在线视频 | 蜜桃视频一区二区 | 麻豆精品一区 | 国产精品免费一区二区三区 | 日日干视频 | 老司机午夜影院 | 精品久久久久久久久久久久久久 | 69福利视频| 久久精品网 | 久久综合久久鬼 | 免费午夜视频 | 日本不卡在线视频 | 欧美日韩中文字幕 | 亚洲 欧美 激情 另类 校园 | 激情小说五月天 | 免费看片黄色 | 欧美a视频 | 欧美黄视频 | 在线免费观看av网站 | 艳妇乳肉亭妇荡乳av | 国产成人免费观看 | 久久99热这里只频精品6学生 | 欧美视频精品 | 亚洲国产免费 | 久久精品一区二区三区四区五区 | 国产福利在线视频 | av天天干| 久久精品一区二区国产 | 欧美啪啪网站 | 国产精品美女 | 欧洲av网站 | 欧美日韩啪啪 | 亚洲亚洲人成综合网络 | 欧美a级黄色片 | 99福利视频| 怡红院久久 | 在线视频一区二区三区 | 日韩精品在线一区二区 | 久久久久久久久国产 |