windows內核下的回調鉤子整理
一丶鉤子
1.1 重新初始化鉤子
void IoRegisterDriverReinitialization(
[in] PDRIVER_OBJECT DriverObject,
[in] PDRIVER_REINITIALIZE DriverReinitializationRoutine,
[in, optional] PVOID Context
);
函數作用 可以在DriverEntry執行完畢之後,重新執行一次初始化的. 全驅動有且只能註冊一個. 且 在DriverEntry 返回 STATUS_SUCCESS
之後纔會被執行.
1.2 進程鉤子
可以攔截進程,監控進程等等.
NTSTATUS PsSetCreateProcessNotifyRoutine(
[in] PCREATE_PROCESS_NOTIFY_ROUTINE NotifyRoutine,
[in] BOOLEAN Remove
);
NTSTATUS PsSetCreateProcessNotifyRoutineEx(
[in] PCREATE_PROCESS_NOTIFY_ROUTINE_EX NotifyRoutine,
[in] BOOLEAN Remove
);
NTSTATUS PsSetCreateProcessNotifyRoutineEx2(
[in] PSCREATEPROCESSNOTIFYTYPE NotifyType,
[in] PVOID NotifyInformation,
[in] BOOLEAN Remove
);
PsSetCreateProcessNotifyRoutine
在 Windows 2000
開始提供 可以達到監視
進程的目的
PsSetCreateProcessNotifyRoutineEx
在 Windows Vista with SP1 and Windows Server 2008.
開始提供(Vista大於win7 也就是win7的前身,現在win7用的都不是很多了.所以後面可以使用此函數的.不用使用第一個了)
此函數可以達到 監視
進程的目的 監控只能看,監視可以修改,比如拒絕進程啓動.
PsSetCreateProcessNotifyRoutineEx2
比較新,在 Windows 10, version 1703
開始提供. 唯一區別有一個類型,作用和 Ex
函數相似
原理:
上述API 其實本質都是將我們設置的函數設置到一個 數組中
而操作系統是通過 數組中
中記錄的類型來識別 當前數組中的函數地址是哪個函數創建的. 類型分別是 2 4 6
如果是2 那麼代表就是 PsSetCreateProcessNotifyRoutine
創建的, 那麼操作系統調用我們的回調的時候就會按照回調函數的參數來進行傳參.
2 4 6
是通過逆向得出的. 如果有興趣做 鉤子識別操作.那麼就會使用到. 不保證後是否會改變.
1.3 線程鉤子
使用方式跟進程鉤子相似, 一個是監控,一個是監視.
NTSTATUS PsSetCreateThreadNotifyRoutine(
[in] PCREATE_THREAD_NOTIFY_ROUTINE NotifyRoutine
);
NTSTATUS PsSetCreateThreadNotifyRoutineEx(
[in] PSCREATETHREADNOTIFYTYPE NotifyType,
[in] PVOID NotifyInformation
);
1.4 模塊回調監控
跟 進程 線程相似
NTSTATUS PsSetLoadImageNotifyRoutine(
[in] PLOAD_IMAGE_NOTIFY_ROUTINE NotifyRoutine
);
NTSTATUS PsSetLoadImageNotifyRoutineEx(
[in] PLOAD_IMAGE_NOTIFY_ROUTINE NotifyRoutine,
[in] ULONG_PTR Flags
);
1.5 註冊表的回調
註冊回調
NTSTATUS CmRegisterCallback(
[in] PEX_CALLBACK_FUNCTION Function,
[in, optional] PVOID Context,
[out] PLARGE_INTEGER Cookie
);
NTSTATUS CmRegisterCallbackEx(
[in] PEX_CALLBACK_FUNCTION Function,
[in] PCUNICODE_STRING Altitude,
[in] PVOID Driver,
[in, optional] PVOID Context,
[out] PLARGE_INTEGER Cookie,
PVOID Reserved
);
取消註冊:
NTSTATUS CmUnRegisterCallback(
[in] LARGE_INTEGER Cookie
);
基本沒用過的(瞭解)
PVOID ExRegisterCallback(
[in, out] PCALLBACK_OBJECT CallbackObject,
[in] PCALLBACK_FUNCTION CallbackFunction,
[in, optional] PVOID CallbackContext
);
1.6 進程保護
進程保護要註冊保護回調. 然後裏面可以控制進程的權限. 或者抹除權限.
註冊:
NTSTATUS ObRegisterCallbacks(
[in] POB_CALLBACK_REGISTRATION CallbackRegistration,
[out] PVOID *RegistrationHandle
);
取消註冊:
void ObUnRegisterCallbacks(
[in] PVOID RegistrationHandle
);
1.7 關機回調
可以監控關鍵回調.在關機的時候做一些處理.
註冊:
NTSTATUS IoRegisterShutdownNotification(
[in] PDEVICE_OBJECT DeviceObject
);
取消註冊:
void IoUnregisterShutdownNotification(
[in] PDEVICE_OBJECT DeviceObject
);
另一個註冊回調(下面說區別)
NTSTATUS IoRegisterLastChanceShutdownNotification(
[in] PDEVICE_OBJECT DeviceObject
);
用法:
註冊好關機回調之後, 我們需要 在派遣函數中指定 IRP_MJ_SHUTDOWN
的回調函數,操作系統檢測到關機的時候則會調用這個派遣函數
IoRegisterLastChanceShutdownNotification
和 IoRegisterShutdownNotification
的區別是 時機問題,前者會在文件系統刷新關閉之後調用,
後者則不是. 後者接受的通知比前者強. 關於文件系統刷新無法正確解釋.舉個例子自己體會. 後者關機回調裏面可以設置註冊表(註冊表也可以說是文件,沒刷新) 可以讀寫註冊表的值. 而前者因爲 文件系統刷新(可能處理了文件) 在回調裏面操作註冊表則不可以操作了. 包括打開 Key setvalue都會失敗.
二丶未完待續
如果遇到新的回調則繼續整理.目前已知是這些.