Win7 64位的SSDTHOOK(2)---64位SSDT hook的實現
上篇文章知道了尋找SSDT表的方法,這篇記錄一下如何實現SSDT表的Hook。
下面以Hook NtOpenProcess為例,之前我查SSDT表發現NtOpenProcess函式的標號為35,用XT等工具也能檢視。
廢話不多說,上程式碼。
首先感謝老大(Tesla.Angela)對我的幫助 //相關宣告 __int64 __readmsr(int register); unsigned __int64 __readcr0(void); void __writecr0( unsigned __int64 Data ); void _disable(void); void _enable(void); //_SYSTEM_SERVICE_TABLE結構宣告 typedef struct _SYSTEM_SERVICE_TABLE{ PVOID ServiceTableBase; PVOID ServiceCounterTableBase; ULONGLONG NumberOfServices; PVOID ParamTableBase; } SYSTEM_SERVICE_TABLE, *PSYSTEM_SERVICE_TABLE; //_SERVICE_DESCRIPTOR_TABLE結構宣告 typedef struct _SERVICE_DESCRIPTOR_TABLE{ SYSTEM_SERVICE_TABLE ntoskrnl; // ntoskrnl.exe (native api) SYSTEM_SERVICE_TABLE win32k; // win32k.sys (gdi/user) SYSTEM_SERVICE_TABLE Table3; // not used SYSTEM_SERVICE_TABLE Table4; // not used }SERVICE_DESCRIPTOR_TABLE,*PSERVICE_DESCRIPTOR_TABLE; //宣告要尋找程序名用的函式 NTKERNELAPI UCHAR * PsGetProcessImageFileName(PEPROCESS Process); //定義NTOPENPROCESS typedef NTSTATUS (__stdcall *NTOPENPROCESS)(OUT PHANDLE ProcessHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN OPTIONAL PCLIENT_ID ClientId); NTOPENPROCESS OldOpenProcess = NULL; ULONG OldTpVal; //定義自己的NtOpenProcess NTSTATUS __stdcall Fake_NtOpenProcess(OUT PHANDLE ProcessHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN OPTIONAL PCLIENT_ID ClientId) { PEPROCESS process = NULL; NTSTATUS st = ObReferenceObjectByHandle(<span style="font-family: Arial, Helvetica, sans-serif;">ClientId->processid</span> ,0,*PsProcessType,KernelMode,&process,NULL); DbgPrint("進入HOOK函式.\n"); if (NT_SUCCESS(st)) { if (!_stricmp((char*)PsGetProcessImageFileName(process),"CrackMe3.exe")) { return STATUS_ACCESS_DENIED; } else { return OldOpenProcess(ProcessHandle,DesiredAccess,ObjectAttributes,ClientId); } } else { return STATUS_ACCESS_DENIED; } } //關閉頁面保護 KIRQL WPOFFx64() { KIRQL irql=KeRaiseIrqlToDpcLevel(); UINT64 cr0=__readcr0(); cr0 &= 0xfffffffffffeffff; __writecr0(cr0); _disable(); return irql; } //開啟頁面保護 void WPONx64(KIRQL irql) { UINT64 cr0=__readcr0(); cr0 |= 0x10000; _enable(); __writecr0(cr0); KeLowerIrql(irql); } //老外定位KeServiceDescriptorTable的方法 ULONGLONG GetKeServiceDescriptorTable64() { char KiSystemServiceStart_pattern[] = "\x8B\xF8\xC1\xEF\x07\x83\xE7\x20\x25\xFF\x0F\x00\x00"; //特徵碼 ULONGLONG CodeScanStart = (ULONGLONG)&_strnicmp; ULONGLONG CodeScanEnd = (ULONGLONG)&KdDebuggerNotPresent; UNICODE_STRING Symbol; ULONGLONG i, tbl_address, b; for (i = 0; i < CodeScanEnd - CodeScanStart; i++) { if (!memcmp((char*)(ULONGLONG)CodeScanStart +i, (char*)KiSystemServiceStart_pattern,13)) { for (b = 0; b < 50; b++) { tbl_address = ((ULONGLONG)CodeScanStart+i+b); if (*(USHORT*) ((ULONGLONG)tbl_address ) == (USHORT)0x8d4c) return ((LONGLONG)tbl_address +7) + *(LONG*)(tbl_address +3); } } } return 0; } //根據KeServiceDescriptorTable找到SSDT基址 PULONG GetSSDTBaseAddress() { PULONG addr = NULL; PSYSTEM_SERVICE_TABLE ssdt = (PSYSTEM_SERVICE_TABLE)GetKeServiceDescriptorTable64(); addr = (PULONG)(ssdt->ServiceTableBase); return addr; } //根據標號找到SSDT表中函式的地址 ULONGLONG GetFuncAddr(ULONG id) { LONG dwtmp = 0; ULONGLONG addr = 0; PULONG stb = NULL; stb = GetSSDTBaseAddress(); dwtmp = stb[id]; dwtmp = dwtmp >> 4; addr = (LONGLONG)dwtmp + (ULONGLONG)stb; DbgPrint("SSDT TABLE BASEADDRESS:%llx",addr); return addr; } //設定函式的偏移地址,注意其中引數的處理。低四位放了引數個數減4個引數。如果引數小於等於4的時候為0 #define SETBIT(x,y) x|=(1<<y) //將X的第Y位置1 #define CLRBIT(x,y) x&=~(1<<y) //將X的第Y位清0 #define GETBIT(x,y) (x & (1 << y)) //取X的第Y位,返回0或非0 ULONG GetOffsetAddress(ULONGLONG FuncAddr, CHAR paramCount) { LONG dwtmp = 0,i; CHAR b = 0, bits[4] = {0}; PULONG stb = NULL; stb = GetSSDTBaseAddress(); dwtmp = (LONG)(FuncAddr - (ULONGLONG)stb); dwtmp = dwtmp << 4; if (paramCount>4) { paramCount = paramCount - 4; } else { paramCount = 0; } memcpy(&b,&dwtmp,1); for (i=0;i<4;i++) { bits[i] = GETBIT(paramCount,i); if (bits[i]) { SETBIT(b,i); } else { CLRBIT(b,i); } } memcpy(&dwtmp,&b,1); return dwtmp; } //核心中用不到的方法,二次跳轉用(自己的NtOpenProcess跳到KeBugCheckEx函式,然後再KeBugCheckEx函式跳到要Hook的NtOpenProcess) VOID FuckKeBugCheckEx() { KIRQL irql; ULONGLONG myfun; UCHAR jmp_code[]="\xFF\x25\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"; myfun=(ULONGLONG)Fake_NtOpenProcess; memcpy(jmp_code+6,&myfun,8); irql=WPOFFx64(); memset(KeBugCheckEx,0x90,15); memcpy(KeBugCheckEx,jmp_code,14); WPONx64(irql); } //Hook ssdt VOID HookSSDT() { KIRQL irql; LONG dwtmp = 0; PULONG stb = NULL; //1.get old address OldOpenProcess = (NTOPENPROCESS)GetFuncAddr(35); DbgPrint("Old_NtOpenProcess:%llx",(ULONGLONG)OldOpenProcess); //2.show new address stb = GetSSDTBaseAddress(); //3.get offset value dwtmp = GetOffsetAddress((ULONGLONG)KeBugCheckEx,4); //set kebugcheckex FuckKeBugCheckEx(); //4.record old offset value OldTpVal = stb[35]; irql = WPOFFx64(); stb[35] = GetOffsetAddress((ULONGLONG)KeBugCheckEx,2); WPONx64(irql); DbgPrint("KeBugCheckEx:%llx",(ULONGLONG)KeBugCheckEx); DbgPrint("New_NtOpenProcess:%llx",GetFuncAddr(35)); } //UN hook VOID UnhookSSDT() { KIRQL irql; PULONG stb=NULL; stb = GetSSDTBaseAddress(); //老函式的地址複製回來 irql=WPOFFx64(); stb[35]=OldTpVal; WPONx64(irql); }
相關解釋:
1.為什麼要二次跳轉?
WIN64核心裡的每個驅動都不在同一個4GB裡,4位元組的整數只能表示4GB的範圍,所以不管怎麼修改這個4位元組都不會跳到你的代理函式,因為你的驅動不可能跟NTOSKRNL在同一個4GB裡面。
2.引數的處理:
函式地址的低四位存放了函式引數個數減4的數字,如果引數為5,那麼低四位的數字為1,如果引數個數小於等於4個,低四位的數位0,可以再WINDBG裡面檢視到。
相關推薦
Win7 64位的SSDTHOOK(2)---64位SSDT hook的實現
上篇文章知道了尋找SSDT表的方法,這篇記錄一下如何實現SSDT表的Hook。 下面以Hook NtOpenProcess為例,之前我查SSDT表發現NtOpenProcess函式的標號為35,用XT等工具也能檢視。 廢話不多說,上程式碼。 首先感謝老大(Tesla.A
MySQL基礎環境_安裝配置教程(Windows7 64或Centos7.2 64、MySQL5.7)
secure https http cti -s entos 重啟 init data MySQL基礎環境_安裝配置教程(Windows7 64或Centos7.2 64、MySQL5.7) 安裝包版本 1) VMawre-workstation版本包 地址:
Oracle欄位保留2兩位小數點number型別
*問題背景*:昨天調阿里發票平臺的申請發票介面時發生了一個異常,原因是發票金額至少保留兩位小數,我查了下記錄,確實表中的記錄為600,所以查出來的資料不會帶小數點。 由於用的oracle,我查了下欄位是否能像mysql一樣設定保留小數點呢。查了網上很多
win7 64位TensorFlow1.2.1的安裝
遇到的兩個主要問題: (1)超時報錯Readtimedout。解決方法:pip --default-timeout=100 install -U pip (2)pip版本問題。解決方法:python
Win10 64位 Apache 2.4+MySQL 5.7+PHP 7環境搭建
ble read def 文本編輯 x64 得到 c11 next gin 軟件版本及獲取 Apache 2.4.25 win64 | MySQL Server 5.7.17 win64 | PHP 7.0 x64 Thread Safe Apache 2.4.25 wi
WIN7 環境下搭建 PHP7(64 位)操作步驟
再次 丟失 word srv sql ram 安裝目錄 only mys WIN7 環境下搭建 PHP7(64 位)操作步驟 一、安裝與配置 Apache 1、下載 Apache下載地址:https://www.apachelounge.com/download/ 2、
新版火狐瀏覽器(61.0.2 (64 位))如何進行元素定位
com 恢復 分享 http bubuko 一個 src 開始 選擇 ---恢復內容開始--- 我們在寫自動化腳本進行web測試時,經常會用到元素定位,之前我們用的都是Firebug+Firepath,但瀏覽器總要更新的,所以就有了這篇筆記,新版的火狐瀏覽器整合掉了這兩個小
騰訊雲CentOS 7.2 64位安裝Mongodb
如果 .com () epo 查看 bsp logs 無法連接 inline 一、安裝步驟:1、配置MongoDB的yum源:創建yum源文件:vim /etc/yum.repos.d/mongodb-org-3.4.repo 2、mongodb-org-3.4.repo
阿里雲伺服器安裝PHP執行環境(CentOS6.8 64位|Vsftpd2.2.2)的 錯誤
1. ERROR: unable to bind listening socket for address '127.0.0.1:9000': Address already in use (98) [16-Nov-2018 18:48:17] ERROR: FPM initialization
Linux_CentOS 7.2 64位之安裝apache-activemq-5.15.6步驟
下載檔案: 1. 解壓: tar -xvf apache-activemq-5.15.6-bin.tar.gz 2. 找到檔案解壓位置: [[email protected]_0_13_centos apache-activemq-5.15.6]# pwd /w
linux_CentOS 7.2 64位 騰訊雲 80埠未啟用解決方法
描述:在購買的騰訊雲伺服器,自己選擇的安裝映象CentOS 7.2 64位,然後自己搭建好環境後,發現有限埠沒有啟動 尤其是預設的網路訪問埠:80沒有自己啟用。一開始以為是防火牆的問題。這裡面遇到了一些小坑 1 CentOS 7.2 64位 之後的防火牆沒有直接使用se
winrar 4.2 64位註冊碼
在winrar的安裝目錄下 新建一個RarReg.key的檔案,複製下面的程式碼進去即可 RAR registration data Federal Agency for Education 1000000 PC usage license UID=b621cca9a8
VC 32位(或64位)win7作業系統的登錄檔操作
1、登錄檔位置 Windows7 64bit系統的登錄檔分32 位登錄檔項和64位登錄檔項兩部分。 在64bit系統下,通過regedit中檢視到指定路徑下的登錄檔項均為64位登錄檔項,而32位登錄檔項被重定位到: HKEY_LOCAL_MACHINE\Software\WOW6432Node。 應用
64位CentOS6.2安裝erlang及rabbitmqServer
CentOS 6.2 64bit 安裝erlang及RabbitMQ Server 1、作業系統環境(CentOS 6.2 64bit) 01.[root@leekwen ~]# cat /etc/issue 02.CentOS release 6.2 (Fin
linux-Centos-7-64位:2、 安裝Tomcat並配置
將下載好的tomcat放到/mnt/share下 建立 /data 下資料夾tomcat, 並在資源目錄share下複製一份tomcat壓縮包 mkdir /data/tomcat cp /mnt/share/apache-tomcat-9.0.0.M4.ta
CentOS7.2 64位yum安裝與配置MySQL
CentOS7.2 64位yum安裝與配置MySQL 1、配置YUM源 在MySQL官網中下載YUM源rpm安裝包:https://dev.mysql.com/downloads/repo/yum/ 下載mysql源安裝包 shell> wget http://dev.my
【Linux\雲伺服器】CentOS 7.2 64位 視覺化桌面的安裝與解除安裝
CentOS 7.2 視覺化桌面的安裝和解除安裝 終於開始寫第一篇CSDN部落格了,心情有點兒小激動,前兩天,小D在阿里雲出購買了一臺學生優惠的ECS雲伺服器,購買之前並沒有學習過任何有關Linux的知識,於是乎,那會兒就有了想安裝一個視
JDK or JRE是32位還是64位的2種檢視方法
1、java -version 2、執行java程式 public class Test{ public static void main(String[] args){ String arch = System.getProperty("sun.arch
win7硬碟安裝Ubuntu12.04 64位時顯示Error 15: File not found.
安裝Ubuntu12.04 -64位時,用EasyBCD建好引導檔案重啟電腦後出現如下錯誤: Error 15: File not found 原因一個是安裝檔案所在碟符不對,另一個是檔名。Ubuntu12.04 32位的ISO包解壓後casper資料夾下核心檔案為v
centos7.2 64位--ruby的安裝與解除安裝---想安裝什麼版本就安裝什麼版本
先吐槽 , 網上這麼多教程,沒一個好使 。。。 渣渣。。。。。 先安裝(一定要裝): yum install gcc-c++ 看正文: 先教你們怎麼下載(網址在這裡不用謝我) : https://ca