钩子函数

**鉤子編程**（hooking），也稱作「掛鈎」，是電腦程式設計術語，指通過攔截軟體模塊間的函數調用、消息傳遞、事件傳遞來修改或擴展作業系統、應用程式或其他軟體組件的行為的各種技術。處理被攔截的函數調用、事件、消息的代碼，被稱為**鉤子**（hook）。

鉤子編程有多種用途，如調試、擴展功能。例如在鍵盤或滑鼠事件到達應用程式之前攔截這些事件；攔截應用程式或其他模塊的作業系統調用以監督行為、修改功能。也廣泛用於 benchmarking 程序，如度量 3D 遊戲的幀率。

鉤子編程也被用於惡意代碼，如 rootkit 是各種通過假扮系統 API 調用輸出來隱藏自身進程的可見性的工具與技術；遊戲外掛是另一類例子。

## 方法

### 物理修改

在應用程式執行之前，物理修改可執行程序，這典型通過找到函數調用入口點，修改入口點使之在函數被執行前先執行其他的代碼。另一種掛鈎的方法是修改可執行程序的輸入表（import table）。還有一種掛鈎方法是採用包裝庫，使得應用程式不需修改即可調用該包裝庫完成其功能，而在包裝庫中插入鉤子然後再調用原有的庫。

### 運行時修改

作業系統與軟體可提供方法，在運行時插入事件鉤子。Microsoft Windows 允許插入鉤子以處理或修改對話框、滾動條、菜單等的系統事件、應用程式事件；插入、刪除、處理或修改鍵盤滑鼠事件。Linux 允許類似的鉤子通過 NetFilter 以處理網絡事件。

如果沒有上述機制或權限，也可攔截進程的庫函數調用，在函數調用開始處注入代碼。這可通過修改內存中的進程的中斷向量表或輸入表（import table）實現。

## 示例代碼

### 虛函數表掛鈎

C++ 使用虛函數，因此可在運行時直接修改虛函數表的內容來掛鈎。 Window 上很多軟體庫以 COM 方式提供的（如 DirectX）， 所以有需求攔截 COM 調用的 COM Hook。COM 里的接口是 C++ 虛表的形式提供的，所以 COM 的 Hook 其實就是虛表（vtable）的 Hook。ATL 就是用接口替代的方式來調試和記錄 COM 接口引用計數的次數

### C# 鍵盤事件鉤子

### 使用跳轉指令的 API / 函數鉤子攔截

下述例子使用 JMP 指令，修改 windows API 中的 MessageBoxW 函數的前 6 個字節執行其他代碼。這段代碼編譯為 DLL 文件，採用 DLL 注入技術讓應用程式使用。微軟提供了封裝好的 Detours 庫用於此目的。

### Netfilter 鉤子

使用 Netfilter 鉤子修改 Linux 內核的網絡交通。

### 內部 IAT 鉤子

下例展示通過修改可執行程序的輸入地址表（IAT），把鉤子函數替代原函數。

### Windows API 提供的掛鈎函數

* SetWinEventHook：基本沒有權限問題，也就是說這個 API 可以 Hook 到高權限程序的事件，同時支持進程內 (WINEVENT\_INCONTEXT) 和進程外 (WINEVENT\_OUTOFCONTEXT) 2 種 Hook 方式，可以進程外的方式 Hook 到 64 位程序的事件。
* SetWindowsHookEx：64 位編程情形，32 位 DLL 沒法直接注入到 64 位的應用程式裡面， 因為地址空間完全不一樣。UAC 打開的情況下低權限程序沒法 Hook 高權限程序。對於 64 位問題，解決方法是提供 2 個 DLL，分別可以 Hook32 和 64 位程序。對於權限問題，通過註冊系統服務，由服務進程創建工作進程。因為 Windows Vista 開始有了 Session 隔離機制，服務進程運行在 Session 0，用戶程序運行在 Session 1, Session 2 等，如果直接在服務程序里幹活，我們就只能在 Session 0 里工作。通過創建進程，可以在 DuplicateTokenEx 後將 Token 的 SessionID 設置成目標 Session，並且在 CreateProcessAsUser 時指定目標 WinStation 和 Desktop， 這樣就獲得了 System 權限，並且也可以和當前桌面進程交互。

## 參見

* 回調函數
* 委託 (編程)
* 終止並駐留
* User exit
* WinAPIOverride32

## 參考文獻

## 外部連結

### Windows

* Information on Import Address Table function hooking. （頁面存檔備份，存於網際網路檔案館）
* Information from Microsoft on hooking （頁面存檔備份，存於網際網路檔案館）
* Information and various techniques regarding x86 hooking. （頁面存檔備份，存於網際網路檔案館）
* APISpy32 （頁面存檔備份，存於網際網路檔案館） is an application used to hook win32 API.
* Detours （頁面存檔備份，存於網際網路檔案館） is a general purpose function hooking library created by Microsoft Research which works in C / C++.
* winspy （頁面存檔備份，存於網際網路檔案館） Three ways to inject code into another process.
* HookTool SDK (ACF SDK) （頁面存檔備份，存於網際網路檔案館） Provides a comprehensive overview on API hooking and code injection. A commercial product available too.
* madCodeHook （頁面存檔備份，存於網際網路檔案館） is a commercial x86 and x64 API hooking and DLL injection library for C++ and Delphi.
* EasyHook （頁面存檔備份，存於網際網路檔案館） is an open source hooking engine supporting x86 and x64 in Windows in both user and kernel land.
* SpyStudio Application Trace （頁面存檔備份，存於網際網路檔案館） SpyStudio is an Application tracer which hook calls, displaying the results in a structured way.
* rohitab.com API Monitor （頁面存檔備份，存於網際網路檔案館） is a freeware application that can hook and display 10,000+ Windows APIs and COM Interfaces in 32-bit and 64-bit applications and services.
* Deviare API Hook （頁面存檔備份，存於網際網路檔案館） Deviare is a freeware inter-process hook framework that can be used to intercept other processes' API calls and show full-parameter information or create API monitors.
* WinAPIOverride （頁面存檔備份，存於網際網路檔案館） WinAPIOverride is a freeware for non commercial use. It can hook win32 API, COM, OLE, ActiveX, .NET in 32-bit and 64-bit processes. It includes monitoring post analysis tools.
* urmem （頁面存檔備份，存於網際網路檔案館） C++11 cross-platform library (x86) for working with memory (hooks, patches, pointer's wrapper, signature scanner etc.)

### Linux

* [1] A student research project that utilizes hooking.
* [2] Functionality that allows a piece of software to observe and control the execution of another process.
* [3] （頁面存檔備份，存於網際網路檔案館） Use of LD\_PRELOAD to hook shared library calls.

### Emacs

* Emacs Hooks （頁面存檔備份，存於網際網路檔案館） Hooks are an important mechanism for customization of Emacs. A hook is a Lisp variable which holds a list of functions, to be called on some well-defined occasion. (This is called running the hook.)

### OS X 與 iOS

* Cydia Substrate （頁面存檔備份，存於網際網路檔案館） is a framework for jailbroken iOS devices allowing developers to hook into any other framework or application.
* harpoon （頁面存檔備份，存於網際網路檔案館） is an OS X library for runtime function hooking.

### Depth API Hooking

* x86 API Hooking Demystified （頁面存檔備份，存於網際網路檔案館） Article on various API Hooking methods, for the x86 architecture.