Windows核心新手上路1——掛鈎SSDT

來源:互聯網
上載者:User

Windows核心新手上路1——掛鈎SSDT

        這個系列記錄學習我學習windows核心的點點滴滴,高手請直接無視。

        文章核心內容:掛鈎SSDT中函數列NtOpenProcess,NtDuplicateObject,NtCreateThread,NtOpenThread,NtWriteVirtualMemory,過濾進程操作來保護目標進程空間。

 

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

SSDT管的是與系統相關的函數(kernel32.dll、ntdll.dll)。通過修改此表的函數地址可以對常用windows函數及API進行hook,從而實現對一些關心的系統動作進行過濾、監控的目的。一些HIPS、防毒軟體、系統監控、註冊表監視軟體往往會採用此介面來實現自己的監控模組。

SSDT在Win32子系統的核心實現是NTOSKRNL.EXE,匯出表名是 KeServiceDescriptorTable,對應系統進程一般有System

SSDT結構:

typedef struct tagSSDT {

PULONG pSSDTBase;                                  //SSDT在記憶體中的基址

PVOID    pServiceCounterTable;

ULONG  uNumberOfServices;                 //SSDT項個數

PUCHAR         pParamTableBase;

} SSDT, *PSSDT; //SSDT

1    如何掛鈎SSDT

首先關閉CR0防寫保護(通過改變CR0寄存器的WP位),然後用新的函數地址替換原來SSDT中的函數地址,最後恢複CR0防寫保護。

掛鈎SSDT中函數列NtOpenProcess,NtDuplicateObject,NtCreateThread,NtOpenThread,NtWriteVirtualMemory,過濾進程操作來保護目標進程空間。

1.1NtOpenProcess

在Windows作業系統中,kernel32!OpenProcess通過調用ntdll!NtOpenProcess最終轉到核心態的nt!NtOpenProcess,通過掛鈎NtOpenProcess,可以過濾和攔截進程開啟其他進程的操作。

在自訂的NtOpenProcess函數中,首先擷取要開啟的進程PID,判斷該PID是否是被保護的進程,如果是被保護的進程,則去掉開啟許可權中的相應許可權,如果是開啟本系統R3進程,還要去掉結束進程的許可權,最終,再調用真實的NtOpenProcess函數,最後返回給R3的進程控制代碼就無法讀寫操作受保護的進程,惡意程式也無法結束目標進程。

通過進程控制代碼擷取PID

判斷是否受保護的PID

如果是

        做一些許可權的處理….

        調用真實NtOpenProcess

如果否

        調用真實的NtCreateThread

代碼1.1 MyNtOpenProcess

1.2NtDuplicateObject

Windows系統提供了一個函數DuplicateHandle,用於從其他進程複製一個控制代碼到當前進程,而且csrss.exe進程會儲存所有進程的控制代碼,通過調用DuplicateHandle從csrss中複製控制代碼,可以間接的達到調用OpenProcess擷取目標進程控制代碼的目的。

在定義的NtDuplcateObject函數中,首先調用真實的NtDuplicateObject,如果調用成功,判斷最後返回的控制代碼是不是受保護進程的控制代碼,如果是受保護的進程控制代碼,則關閉之。通過這樣的過濾,惡意程式無法通過調用DuplicateHandle來開啟受保護的進程。

1.3NtCreateThread

R3中在進程中和其他進程中建立線程(分別調用CreateThread和CreateRemoteThread)最終通過ntdll!NtCreateThread轉到核心態的nt!CreateThread,通過過濾nt!CreateThread可以防止惡意程式在受保護的進程中建立遠程線程(即調用CreateRemoteThread)。實現的MyNtCreateThread處理流程如代碼1.2所示:

通過進程控制代碼擷取PID

判斷是否受保護的PID

如果是

        返回STATUS_ACCESS_DENIED

如果否

        調用真實的NtCreateThread

代碼1.2 MyNtCreateThread

1.4NtOpenThread

在windows作業系統中,通過調用OpenThread可以擷取目標線程的控制代碼,進一步通過此控制代碼操作目標線程。防密碼竊取系統掛鈎了NtOpenThread來防止惡意程式操作受保護進程的線程。

在自訂的NtOpenThread函數中,首先擷取線程所在進程的PID,然後判斷該PID是否被保護,如果是被保護的PID,則直接返回STATUS_ACCESS_DENIED,否則調用真實的NtOpenThread。

1.5NtWriteVirtualMemory

在windows作業系統中,進程可以調用kernel32!WriteProcessMemory來寫其他進程記憶體,kernel32!WriteProcessMemory通過ntdll!NtWriteVirtualMemory轉到核心態的nt!NtWriteVirtualMemory。通過掛鈎nt!NtWriteVirtualMemory來防目惡意程式寫受保護的進程記憶體。虛擬碼如代碼1.3所示。

通過進程控制代碼擷取PID

判斷是否受保護的PID

如果是

        返回STATUS_ACCESS_DENIED

如果否

        調用真實的NtWriteVirtualMemory

代碼1.3 MyNtWriteVirtualMemory

Windows核心新手上路1——掛鈎SSDT

        這個系列記錄學習我學習windows核心的點點滴滴,高手請直接無視。

        文章核心內容:掛鈎SSDT中函數列NtOpenProcess,NtDuplicateObject,NtCreateThread,NtOpenThread,NtWriteVirtualMemory,過濾進程操作來保護目標進程空間。

 

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

SSDT管的是與系統相關的函數(kernel32.dll、ntdll.dll)。通過修改此表的函數地址可以對常用windows函數及API進行hook,從而實現對一些關心的系統動作進行過濾、監控的目的。一些HIPS、防毒軟體、系統監控、註冊表監視軟體往往會採用此介面來實現自己的監控模組。

SSDT在Win32子系統的核心實現是NTOSKRNL.EXE,匯出表名是 KeServiceDescriptorTable,對應系統進程一般有System

SSDT結構:

typedef struct tagSSDT {

PULONG pSSDTBase;                                  //SSDT在記憶體中的基址

PVOID    pServiceCounterTable;

ULONG  uNumberOfServices;                 //SSDT項個數

PUCHAR         pParamTableBase;

} SSDT, *PSSDT; //SSDT

1    如何掛鈎SSDT

首先關閉CR0防寫保護(通過改變CR0寄存器的WP位),然後用新的函數地址替換原來SSDT中的函數地址,最後恢複CR0防寫保護。

掛鈎SSDT中函數列NtOpenProcess,NtDuplicateObject,NtCreateThread,NtOpenThread,NtWriteVirtualMemory,過濾進程操作來保護目標進程空間。

1.1NtOpenProcess

在Windows作業系統中,kernel32!OpenProcess通過調用ntdll!NtOpenProcess最終轉到核心態的nt!NtOpenProcess,通過掛鈎NtOpenProcess,可以過濾和攔截進程開啟其他進程的操作。

在自訂的NtOpenProcess函數中,首先擷取要開啟的進程PID,判斷該PID是否是被保護的進程,如果是被保護的進程,則去掉開啟許可權中的相應許可權,如果是開啟本系統R3進程,還要去掉結束進程的許可權,最終,再調用真實的NtOpenProcess函數,最後返回給R3的進程控制代碼就無法讀寫操作受保護的進程,惡意程式也無法結束目標進程。

通過進程控制代碼擷取PID

判斷是否受保護的PID

如果是

        做一些許可權的處理….

        調用真實NtOpenProcess

如果否

        調用真實的NtCreateThread

代碼1.1 MyNtOpenProcess

1.2NtDuplicateObject

Windows系統提供了一個函數DuplicateHandle,用於從其他進程複製一個控制代碼到當前進程,而且csrss.exe進程會儲存所有進程的控制代碼,通過調用DuplicateHandle從csrss中複製控制代碼,可以間接的達到調用OpenProcess擷取目標進程控制代碼的目的。

在定義的NtDuplcateObject函數中,首先調用真實的NtDuplicateObject,如果調用成功,判斷最後返回的控制代碼是不是受保護進程的控制代碼,如果是受保護的進程控制代碼,則關閉之。通過這樣的過濾,惡意程式無法通過調用DuplicateHandle來開啟受保護的進程。

1.3NtCreateThread

R3中在進程中和其他進程中建立線程(分別調用CreateThread和CreateRemoteThread)最終通過ntdll!NtCreateThread轉到核心態的nt!CreateThread,通過過濾nt!CreateThread可以防止惡意程式在受保護的進程中建立遠程線程(即調用CreateRemoteThread)。實現的MyNtCreateThread處理流程如代碼1.2所示:

通過進程控制代碼擷取PID

判斷是否受保護的PID

如果是

        返回STATUS_ACCESS_DENIED

如果否

        調用真實的NtCreateThread

代碼1.2 MyNtCreateThread

1.4NtOpenThread

在windows作業系統中,通過調用OpenThread可以擷取目標線程的控制代碼,進一步通過此控制代碼操作目標線程。防密碼竊取系統掛鈎了NtOpenThread來防止惡意程式操作受保護進程的線程。

在自訂的NtOpenThread函數中,首先擷取線程所在進程的PID,然後判斷該PID是否被保護,如果是被保護的PID,則直接返回STATUS_ACCESS_DENIED,否則調用真實的NtOpenThread。

1.5NtWriteVirtualMemory

在windows作業系統中,進程可以調用kernel32!WriteProcessMemory來寫其他進程記憶體,kernel32!WriteProcessMemory通過ntdll!NtWriteVirtualMemory轉到核心態的nt!NtWriteVirtualMemory。通過掛鈎nt!NtWriteVirtualMemory來防目惡意程式寫受保護的進程記憶體。虛擬碼如代碼1.3所示。

通過進程控制代碼擷取PID

判斷是否受保護的PID

如果是

        返回STATUS_ACCESS_DENIED

如果否

        調用真實的NtWriteVirtualMemory

代碼1.3 MyNtWriteVirtualMemory

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.