1. 程式人生 > >vc++HOOK API黑客外掛程式設計必知必會

vc++HOOK API黑客外掛程式設計必知必會

 
#include <windows.h>

// 定義API掛接項結構
typedef struct _HOOK_ITEM {
 DWORD dwAddr ;   // IAT項所在地址
 DWORD dwOldValue ;  // IAT項的原始函式地址
 DWORD dwNewValue ;  // IAT項的新函式地址
} HOOK_ITEM, *PHOOK_ITEM ;
HOOK_ITEM HookItem = {0} ; // 定義IAT項,用於儲存MessageBoxA的IAT項資訊

// 定義MessageBoxA函式原型
typedef int (WINAPI* PFNMessageBoxA)( HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType ) ;

// 定義重定向API的實現函式
BOOL WINAPI RedirectApi ( PCHAR pDllName, PCHAR pFunName, DWORD dwNewProc, PHOOK_ITEM pItem ) ;

// 自定義的MessageBoxA函式
// 實現對原始MessageBoxA的輸入、輸出引數的監控,甚至是取消呼叫
int WINAPI NEW_MessageBoxA( HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType )
{
 // 此處可以觀察/修改呼叫引數,甚至可以取消呼叫直接返回。
 // ……

 // 取得原函式地址
 PFNMessageBoxA pfnMessageBoxA = (PFNMessageBoxA)HookItem.dwOldValue ;

 // 輸出測試資訊,
 // 如果這裡直接呼叫MessageBoxA,就進入無限迴圈
 pfnMessageBoxA ( hWnd, "這是API重定向過程的訊息框", "測試", 0 ) ;

 // 呼叫原函式
 int ret = pfnMessageBoxA ( hWnd, lpText, lpCaption, uType ) ;

 // 此處可以檢視/修改呼叫原函式的返回值
 // ……

 return ret ;
}

int WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
 // 重定向API
 if ( !RedirectApi ( "USER32.dll", "MessageBoxA", (DWORD)NEW_MessageBoxA, &HookItem ) )
  OutputDebugStringA ( "RedirectApi failed!" ) ;
 else
  OutputDebugStringA ( "RedirectApi success!" ) ;
 
 MessageBoxA ( 0, "正常訊息框", "測試", 0 ) ;
 return 0 ;
}

// 實現重定向API
// 引數pDllName:目標API所在的DLL名稱
// 引數pFunName:目標API名稱
// 引數dwNewProc:自定義的函式地址
// 引數pItem:用於儲存IAT項資訊
BOOL WINAPI RedirectApi ( PCHAR pDllName, PCHAR pFunName, DWORD dwNewProc, PHOOK_ITEM pItem )
{
 // 檢查引數是否合法
 if ( pDllName == NULL || pFunName == NULL || !dwNewProc || !pItem )
  return FALSE ;

 // 檢測目標模組是否存在
 char szTempDllName[256] = {0} ;
 DWORD dwBaseImage = (DWORD)GetModuleHandle(NULL) ;
 if ( dwBaseImage == 0 )
  return FALSE ;

 // 取得PE檔案頭資訊指標
 PIMAGE_DOS_HEADER   pDosHeader = (PIMAGE_DOS_HEADER)dwBaseImage ;
 PIMAGE_NT_HEADERS   pNtHeader = (PIMAGE_NT_HEADERS)(dwBaseImage + (pDosHeader->e_lfanew)) ;
 PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = &(pNtHeader->OptionalHeader) ;
 PIMAGE_SECTION_HEADER  pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pNtHeader + 0x18 + pNtHeader->FileHeader.SizeOfOptionalHeader ) ;

 // 遍歷匯入表
 PIMAGE_THUNK_DATA pThunk, pIAT ;
 PIMAGE_IMPORT_DESCRIPTOR pIID = (PIMAGE_IMPORT_DESCRIPTOR)(dwBaseImage+pOptionalHeader->DataDirectory[1].VirtualAddress ) ;
 while ( pIID->FirstThunk )
 {
  // 檢測是否目標模組
  if ( strcmp ( (PCHAR)(dwBaseImage+pIID->Name), pDllName ) )
  {
   pIID++ ;
   continue ;
  }

  pIAT = (PIMAGE_THUNK_DATA)( dwBaseImage + pIID->FirstThunk ) ;
  if ( pIID->OriginalFirstThunk )
   pThunk = (PIMAGE_THUNK_DATA)( dwBaseImage + pIID->OriginalFirstThunk ) ;
  else
   pThunk = pIAT ;

  // 遍歷IAT
  DWORD dwThunkValue = 0 ;
  while ( ( dwThunkValue = *((DWORD*)pThunk) ) != 0 )
  {
   if ( ( dwThunkValue & IMAGE_ORDINAL_FLAG32 ) == 0 )
   {
    // 檢測是否目標函式
    if ( strcmp ( (PCHAR)(dwBaseImage+dwThunkValue+2), pFunName ) == 0 )
    {
     // 填充函式重定向資訊
     pItem->dwAddr  = (DWORD)pIAT ;
     pItem->dwOldValue = *((DWORD*)pIAT) ;
     pItem->dwNewValue = dwNewProc;

     // 修改IAT項
     DWORD dwOldProtect = 0 ;
     VirtualProtect ( pIAT, 4, PAGE_READWRITE, &dwOldProtect ) ;
     *((DWORD*)pIAT) = dwNewProc ;
     VirtualProtect ( pIAT, 4, PAGE_READWRITE, &dwOldProtect ) ;
     return TRUE ;
    }
   }

   pThunk ++ ;
   pIAT ++ ;
  }

  pIID ++ ;
 }

 return FALSE ;
}

相關推薦

vc++HOOK API黑客外掛程式設計

 #include <windows.h> // 定義API掛接項結構typedef struct _HOOK_ITEM { DWORD dwAddr ;   // IAT項所在地址 DWORD dwOldValue ;  // IAT項的原始函式地址 DWORD

Java開發人員的20種常用類庫和API

坐穩了沒?要開車了哦 一個有經驗的Java開發人員特徵之一就是善於使用已有的輪子來造車。《Effective Java》的作者Joshua Bloch曾經說過:“建議使用現有的API來開發,而不是重複造輪子”。在本文中,我將分享一些Java開發人員應該熟悉的最有用的和必

泥瓦匠聊併發程式設計:執行緒與多執行緒(基礎篇)

本文目錄 執行緒與多執行緒 執行緒的執行與建立 執行緒的狀態 1 執行緒與多執行緒 執行緒是什麼? 執行緒(Thread)是一個物件(Object)。用來幹什麼?Java 執行緒(也稱 JVM 執行緒)是 Java 程序內允許多個同時進行的任務。該程序內併發的任務成為執行緒(Thread)

Flutter 外掛使用

本文目的 介紹外掛的搜尋方式,三方庫評估的意義和基本思路 介紹如何給應用新增外掛,從原始碼角度看外掛是如何註冊生效的 介紹如何給外掛指定版本和解決版本衝突問題 介紹依賴源的種類,如何從pub/git/本地指定依賴庫 介紹依賴的2種分類方式:直接依賴和傳遞依賴;常規依賴和dev依賴

Flutter 外掛編寫

本文目的 介紹包和外掛的概念 介紹 flutter 呼叫平臺特定程式碼的機制:Platform Channels,和相關類的常用方法 介紹外掛開發流程和示例 介紹優化外掛的方法:新增文件,合理設定版本號,新增單元測試,新增持續整合 介紹釋出外掛的流程和常見問題 目錄結構

Java開發人員的常用類庫和API

一個有經驗的Java開發人員特徵之一就是善於使用已有的輪子來造車。《Effective Java》的作者Joshua Bloch曾經說過:“建議使用現有的API來開發,而不是重複造輪子”。在本文中,我將分享一些Java開發人員應該熟悉的最有用的和必要的庫和API。順便說一句,這裡不包括框架,如S

一個老師程序員說:這是學Java 的 20 種常用類庫和 API

就是 到你 今天 減少 web應用 ttpClient 程序員 effective 放棄 一個有經驗的Java開發人員特征之一就是善於使用已有的輪子來造車。《Effective Java》的作者Joshua Bloch曾經說過:“建議使用現有的API來開發,而不是重復造輪子

Pytest自動化測試 - 的一些外掛

Pytest擁有豐富的外掛架構,超過800個以上的外部外掛和活躍的社群,在PyPI專案中以“ pytest- *”為標識。 本篇將列舉github標星超過兩百的一些外掛進行實戰演示。 外掛庫地址:http://plugincompat.herokuapp.com/   1、pytest-html

【MySQL】第6章 過濾數據

sea 錯誤 arch order by ice where 大量數據 子句 否則 1、使用WHERE子句   數據庫一般包含大量數據,所以一般不會檢索所有行。只檢索所需數據需要指定搜索條件(search criteria),搜索條件也稱為過濾條件(filter condi

《MYSQL

聚集函數 結構 則表達式 拼接 建議 支持 類型 習慣 功能 1、 同一個數據庫中不允許出現同名表;不同的數據庫中可以出現同名表2、 每一行記錄都用有一個key(一列或一組列作為key)3、 作為key的列不允許值為空(NULL)4、 多個列作為key時,多個列的組

《MYSQL2

pri upd delet rate 服務器 cal delete 生效 單獨 60、NULL是沒有值,空串是一個有效值61、主鍵只能使用不允許未NULL值的列62、每個表只允許一個auto_increment列63、不允許使用函數作為默認值,只支持常量64、InnoDB

SQL -------- 通配符、計算字段、函數

提取 mar 第8章 column round vendor 方法 多少 頁面 1.LIKE操作符 1.1百分號(%)通配符 SELECT prod_id, prod_name FROM Products WHERE prod_name LIKE ‘Fish%‘

【MySQL】第十章 創建計算字段

客戶機 cat 第十章 去掉 quantity 字段 cme 引用 field 1、字段(field):一般與列(同義),經常互換使用,不過數據庫列一般稱之為列,字段通常用在計算字段的連接上。 2、拼接:將值連接到一起構成單個值。   註:多數DBMS使用+或||來實現拼接

【MySQL】第十三章 分組數據

num mysql 統計 where子句 rom 過濾 group by 大於 映射 1、創建分組   輸入:   SELECT vend_id , COUNT(*) AS num_prods   FROM products   GROUP BY vend_id;   輸出

【MySQL】第十六章 創建高級聯結

類型 where子句 contact items order by 其他 mysq custom 必知必會 1、使用表別名   好處:   a、縮短SQL語句。   b、允許在單條SELECT語句中多次使用相同的表。   輸入:   SELECT  cust_name,cu

SQL摘要

用法 row 第一個 table class err num 方向 返回 數據檢索 2.2 檢索單個列 SELECT prod_name FROM Products; SQL語句不區分大小寫 2.3 檢索多個列 SELECT prod_name,pr

《領導梯隊》:4星。企業中六個層級的領導的和必須不能做的事情。

進行 方案 更多 思路 和平 要花 能力 事情 專註 書不錯,根據許多企業的情況總結出來的,作者們有企業家的顧問經驗。 總體內容是每一次晉級都是思路的轉換,每一層領導都需要轉換思路才能做好,每一層領導都容易犯的錯誤是事必躬親。 作者列出六個層級的領導:經理、總監、事

JSON學習總結(一)

tor lint 沒有 script app 對數 數據交換格式 object 什麽 七月第一周,從學校畢業回來上班的第一周。離開一段時候後,再次回來重新工作,有了很多新的認識,不再是實習時那麽混混沌沌了。每天我自己該做什麽,怎麽做,做到什麽程度更清晰了。除了要去完成我負責

《MySQL學習筆記》:子查詢

簡單的 後繼 復雜 pos clas tty append 靈活 values 子查詢 在開始了解子查詢之前,首先做下準備工作,建立3個表, 一個是customers表,當中包含:客戶名字、客戶ID、客戶Tel等。 一個是orders

MySQL-表的關系

mysql必知必會-表的關系MySQL必知必會-表的關系