Win64編程
32位系統逐漸淘汰,轉到64位編程相當重要. 但苦於64位驅動編程網上的資料比較雜亂
這里打算寫寫關於64位驅動編程的內容,當然大部分內容都是從網上搜集過來的,然后匯集到一起好用來學習.
- 准備
雙機調試, 加載驅動工具,debgview工具, win10重啟后禁用驅動簽名. 重啟后加載驅動
雙機調試:
在win7虛擬機關機狀態添加一個基於命名管道的串口,然后設置另一端時應用程序,然后
執行下面命令
64系統開始有個驅動簽名機制,沒有通過微軟簽名的驅動無法加載, 我們調試時需要禁用它.
開機按f8后有個禁用驅動簽名啟動選項, 選擇它啟動即可.
bcdedit /dbgsettings serial baudrate:115200 debugport:1 (最后的1表示虛擬機中設置的com1)
bcdedit /copy {current} /d debug (記住這里返回的id號,下面用到)
bcdedit /displayorder {current} {ID} 這里的ID設置為第2條命令返回的id
bcdedit /debug {ID} ON 這里的ID設置為第2條命令返回的id
重啟即可.
2.代碼
對於ULONG 在64編譯時自動轉為ULONG64
如果是ULONG_PTR 則編譯器自動幫我們轉換
無類型指針使用PVOID64.
通過KdPrint打印時, %x不用而用%p .
從xp到windows7 64位 像EPROCESS等結構體也有變化,通過windbg可以查看比較.
對於驅動代碼來說, 因為那些數據類型都有2個版本:以32結尾和以64結尾,它通過在不同環境編譯時自動轉到目標類型
3.Patchguard
說白了,就是微軟為了讓系統更安全, 不能隨隨便便就能hook和inline,不能隨隨便便就能通過修改EPROCESS來隱藏進程.
這家伙每隔一段時間對系統關鍵文件,內存區域進行CRC校驗,發現不對立刻進行0x109藍屏.
而且它自己藏在內存中不好通過解決它來繞過patchguard.
上面的網站有列出的被其保護的內容.
4. 64位ssdt表的查找
在32位系統中我們可以通過已導出的結構體名直接操作, 或者搜素函數KeAddSystemServiceTable, 或者通過windbg查看.
但是在64位系統中並沒有導出這個結構. 所以需要通過其他方式找到他.
思路1 (這個思路參考黑客防線2011合訂本下半年第7頁)
通過讀取C0000082寄存器 獲得KiSystemCall64函數的地址, 因為這個函數沒有導出,故通過這種方式.. (相當佩服作者底層知識功底)
在往下搜索0x500個字節左右就能得到KeServiceDescriptorTable地址
在windbg中查看:

而且KeServiceDescriptorTable的特征碼是4c8d15
KeServiceDescriptorTableShadow的特征碼是4c8d1d
查找思路是, 將ntoskrnl.exe拖到ida,隨便找到一個內核函數,比如ZwCreateFile:



所以在KiSystemServiceRepeat 里面就能看到 在加載好符號的windbg中 反匯編即可:

編寫代碼如下 :
ULONGLONG GetKeSeviceDescriptorTable64()
{
PUCHAR startSearchAddress = (PUCHAR)__readmsr(0xC0000082);
PUCHAR endSearchAddress = startSearchAddress + 0x500;
PUCHAR i = 0;
UCHAR b1 = 0, b2 = 0, b3 = 0;
ULONG temp = 0;
ULONGLONG addr = 0;
for ( i = startSearchAddress; i < endSearchAddress; i++)
{
if (MmIsAddressValid(i) && MmIsAddressValid(i + 1) && MmIsAddressValid(i + 2))
{
b1 = *i;
b2 = *(i + 1);
b3 = *(i + 2);
if (b1 == 0x4c && b2 == 0x8d && b3 == 0x15)
{
memcpy(&temp, i + 3, 4);
addr = (ULONGLONG)temp + (ULONGLONG)i + 7;//加上指令長度
KdPrint(("find ssdt is %p\n", addr));
return addr;
}
}
}
KdPrint(("find ssdt error\n"));
return 0;
}
測試結果:

