色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

安全開發之應用層Hook技術

蛇矛實驗室 ? 來源:蛇矛實驗室 ? 作者:蛇矛實驗室 ? 2022-10-31 14:32 ? 次閱讀

本環境是蛇矛實驗室基于"火天網演攻防演訓靶場"進行搭建,通過火天網演中的環境構建模塊,可以靈活的對目標網絡進行設計和配置,并且可以快速進行場景搭建和復現驗證工作。

前言

Hook中文譯為“鉤子”或“掛鉤”,這很容易聯想到釣東西,好比釣魚,但將其比作“網”更合適,在安全開發的過程中,Hook技術主要用于對程序的運行流程進行控制和攔截,對特定的消息或動作進行過濾。

Hook原理

在真正執行原始API之前,對程序流程進行攔截,使其先執行自定義的代碼后,再執行原始API調用流程。

e58f24f4-56c7-11ed-a3b6-dac502259ad0.png

Hook分類

Hook根據其作用的權限,可分為應用層(R3)鉤子和內核(R0)鉤子,本文主要講解應用層鉤子。

從代碼實現角度,可將R3 Hook分為以下幾類:

基于地址修改,比如IAT Hook。

基于代碼修改,比如Inline Hook。

基于異常或調試,比如VEH Hook。

由于篇幅有限,本文只包含部分Hook技術。

IAT Hook

IAT(import address table,導入地址表)是指PE文件格式中的一個表結構,說到IAT就離不開導入表,在實際的開發過程中,難免會使用到Windows API,這些API的代碼保存在Windows提供的不同的DLL(動態鏈接庫)文件中,DLL將這些API導出,在可執行程序中使用到其他DLL的代碼或數據時,編譯器會將這些導入的信息填充到可執行程序的導入表中。當可執行程序運行時,系統會將可執行程序和其依賴的DLL加載到內存中,其中windows加載器會定位所有導入函數的地址并將定位到的地址填充到IAT中供其使用,Windows加載器定位這些函數的地址需要依賴PE文件中的導入表,其中導入表存放了所使用到的DLL文件和導入的函數名稱和序號信息。

實現原理

通過替換IAT表中函數的原始地址從而實現Hook。

實現步驟

以Hook User32!MessageBoxA為例:

1. 定義基于User32!MessageBoxA的函數原型的函數指針;

2. 獲取User32!MessageBoxA的函數地址并保存;

3. 創建HookedMessageBoxA函數(函數原型同User32!MessageBoxA一樣),以攔截程序對User32!MessageBoxA的調用:

先執行自定義的代碼;
再執行原始User32!MessageBoxA函數。

4. 解析導入表,并在IAT中定位User32!MessageBoxA的位置;

5. 使用HookedMessageBoxA函數的地址替換IAT中User32!MessageBoxA的地址。

實現代碼

#include
#include
#include
#include
#pragmacomment (lib, "dbghelp.lib")

// 1. 定義基于User32!MessageBoxA的函數原型的函數指針
usingMessageBoxT = int(WINAPI*)(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType);

// 2. 獲取User32!MessageBoxA的函數地址并保存;
MessageBoxT OriginalMessageBox = MessageBoxA;

// 3. 創建HookedMessageBoxA函數(函數原型同User32!MessageBoxA一樣),以攔截程序對User32!MessageBoxA的調用:
intWINAPI HookedMessageBox(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType)
{
// 3.1 先執行自定義的代碼
MessageBoxW(0, L"HookedMessageBox() called", L"IAT Hook", 0);

// 3.2 再執行原始User32!MessageBoxA函數
returnOriginalMessageBox(hWnd, lpText, lpCaption, uType);
}

/*
4. 解析導入表,并在IAT中定位User32!MessageBoxA的位置;
5. 使用HookedMessageBoxA函數的地址替換IAT中User32!MessageBoxA的地址。
*/
boolSetHook(std::stringdllName, std::stringorigFunc, PROC hookingFunc)
{
ULONG size;
DWORD i;

LPCSTR importDllName = NULL;
HMODULE importDllImageBase = NULL;

// 獲取主模塊句柄
HMODULE imageBase = GetModuleHandle(NULL);

// 定位主模塊的導入表
PIMAGE_IMPORT_DESCRIPTOR importDescTab = (PIMAGE_IMPORT_DESCRIPTOR)ImageDirectoryEntryToDataEx(imageBase, TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &size, NULL);

// 尋找目標DLL
boolfound = false;
for(i = 0; i < size; i++)
??{
????importDllName = (LPCSTR)importDescTab[i].Name + (DWORD_PTR)imageBase; // 獲取導入DLL名稱
????if?(_stricmp(dllName.c_str(), importDllName) == 0)
????{
??????found = true;
??????break;
????}
??}

??// 沒找到目標DLL,返回
??if?(!found)
????return?false;

??// 找到目標dll
??importDllImageBase = GetModuleHandleA(importDllName);
??if?(!importDllImageBase) return?false;

??PIMAGE_THUNK_DATA originalFirstThunk = (PIMAGE_THUNK_DATA)((ULONG_PTR)imageBase + importDescTab[i].OriginalFirstThunk); // 定位導入名稱表INT
??PIMAGE_THUNK_DATA firstThunk = (PIMAGE_THUNK_DATA)((ULONG_PTR)imageBase + importDescTab[i].FirstThunk); // 定位導入地址表IAT

??// 尋找Hook的API
??while?(originalFirstThunk->u1.AddressOfData)
{
PIMAGE_IMPORT_BY_NAME functionName = (PIMAGE_IMPORT_BY_NAME)((ULONG_PTR)imageBase + originalFirstThunk->u1.AddressOfData);
if(_stricmp(origFunc.c_str(), functionName->Name) == 0)
{
// 確保內存可寫
DWORD oldProtect = 0;
VirtualProtect((LPVOID)(&firstThunk->u1.Function), 4096, PAGE_READWRITE, &oldProtect);

// 替換IAT中的函數地址
firstThunk->u1.Function = (ULONG_PTR)hookingFunc;

// 恢復內存屬性
VirtualProtect((LPVOID)(&firstThunk->u1.Function), 4096, oldProtect, &oldProtect);
}
++originalFirstThunk;
++firstThunk;
}

returntrue;
}

intmain()
{
// Hook前
MessageBoxA(0, "Before Hooking", "IAT HOOKS", 0);

// 進行IAT Hook
SetHook("user32.dll", "MessageBoxA", (PROC)HookedMessageBox);

// Hook后
MessageBoxA(0, "After Hooking", "IAT Hook", 0);

return0;
}

上述代碼第一次調用MessageBoxA時,正常彈出,為了之后在調用MessageBoxA時,先執行自定義的函數代碼(HookedMessageBox),首先在進程的IAT中定位到MessageBoxA的地址,這個過程是先通過進程的導入表找到MessageBoxA所在的DLL模塊(user32.dll),找到之后,通過INT(導入名稱表)得到MessageBoxA函數地址在IAT中的下標,此時使用自定義函數的地址替換掉IAT中MessageBoxA函數的地址,即可達到IAT Hook的效果,Hook之后在調用MessageBoxA時,程序會先執行HookedMessageBox函數,在執行原始的MessageBoxA函數(需要提前獲取MessageBoxA的地址)。

效果

e5a47dc2-56c7-11ed-a3b6-dac502259ad0.gif

Inline Hook

Inline Hook實際上是一種通過修改機器碼的方式來實現Hook的技術。

實現原理

通過直接修改API函數在內存中對應的二進制代碼,通過跳轉指令將其代碼的執行執行流程改變從而執行用戶編寫的代碼進而進行Inline Hook。

實現步驟

以Hook User32!MessageBoxA為例:

1. 在指定進程中內存中找到MessageBoxA函數地址,并保存函數頭部若干字節(用于后續unpatch);

2. 創建HookedMessageBoxA函數(函數原型同User32!MessageBoxA一樣),以攔截程序對User32!MessageBoxA的調用:

先執行自定義的代碼;
恢復先前保存的MessageBoxA原始字節;
執行原函數
再次對MessageBoxA進行Hook;

3. 構造跳轉指令,用于后續替換MessageBoxA函數代碼頭部字節;

4. 修改MessageBoxA函數首地址代碼為跳轉指令。

實現代碼

#include
#include

#ifdefined(_WIN64)
#defineORIG_BYTES_SIZE 14
#else
#defineORIG_BYTES_SIZE 7
#endif

BYTE OriginalBytes[ORIG_BYTES_SIZE]{}; // 用于保存MessageBoxA的部分原始代碼字節
BYTE PatchBytes[ORIG_BYTES_SIZE]{}; // 構造的跳轉指令

usingMessageBoxAT = int(WINAPI*)(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType);
MessageBoxAT OriginalMessageBox = nullptr;

intWINAPI HookedMessageBox(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType)
{
// 執行自定義的代碼
SIZE_T bytesOut = 0;

MessageBoxW(0, L"HookedMessageBox() called", L"Inline Hook", 0);

// unpatch MessageBoxA
WriteProcessMemory(GetCurrentProcess(), (LPVOID)OriginalMessageBox, OriginalBytes, sizeof(OriginalBytes), &bytesOut);

// 調用原來的MessageBoxA
intresult = MessageBoxA(NULL, lpText, lpCaption, uType);

// 再次patch MessageBoxA
WriteProcessMemory(GetCurrentProcess(), OriginalMessageBox, PatchBytes, sizeof(PatchBytes), &bytesOut);

returnresult;
}

boolSetHook(std::stringdllName, std::stringorigFunc, FARPROC hookingFunc)
{
SIZE_T bytesIn = 0;
SIZE_T bytesOut = 0;

// 保存MessageBoxA原始地址
OriginalMessageBox = (MessageBoxAT)GetProcAddress(GetModuleHandleA(dllName.c_str()), origFunc.c_str());

// 保存MessageBoxA的部分原始代碼字節
ReadProcessMemory(GetCurrentProcess(), OriginalMessageBox, OriginalBytes, ORIG_BYTES_SIZE, &bytesIn);

memset(PatchBytes, 0, sizeof(PatchBytes));
#ifdefined(_WIN64)
/*
JMP [RIP+0];
xFFx25x00x00x00x00
x00x11x22x33x44x55x66x77
*/
memcpy(PatchBytes, "xFFx25", 2);
memcpy(PatchBytes + 6, &hookingFunc, 8);
#else
/*
mov eax, &hookingFunc
jmp eax
*/
memcpy(PatchBytes, "xB8", 1);
memcpy(PatchBytes + 1, &hookingFunc, sizeof(ULONG_PTR));
memcpy(PatchBytes + 5, "xFFxE0", 2);
#endif

// patch the MessageBoxA
WriteProcessMemory(GetCurrentProcess(), OriginalMessageBox, PatchBytes, sizeof(PatchBytes), &bytesOut);

returntrue;
}

intmain()
{
// Hook前
MessageBoxA(0, "Before Hooking", "Inline Hook", 0);

// 進行Inline Hook
SetHook("user32.dll", "MessageBoxA", (FARPROC)HookedMessageBox);

// Hook后
MessageBoxA(0, "After Hooking", "Inline Hook", 0);

return0;
}

程序中調用了2次MessageBoxA,第一次調用時未被掛鉤,之后Inline Hook方式使用對MessageBoxA進行掛鉤,當之后再次調用MessageBoxA時,程序會首先進入自寫函數(HookedMessageBox)中,在該函數中,自定義的代碼部分使用MessageBoxW彈出內容,隨后修復MessageBoxA被修改的字節代碼后,開始執行原始MessageBoxA代碼。

效果

e5d414ba-56c7-11ed-a3b6-dac502259ad0.gif

VEH Hook

VEH Hook是一種基于異常處理的Hook手段,通過主動觸發異常從在獲取程序控制權來達到Hook的手段。其中VEH(Vectored Exception Handler,向量化異常處理)是Windows中處理異常的一種方式。

實現原理

由于VEH的異常處理發生在之前,所以通過`主動拋出異常,使程序觸發異常,進而使控制權交給異常處理例程的這一系列操作來實現Hook。

實現步驟

以Hook User32!MessageBoxA為例:

1. 獲取MessageBoxA地址,并保存;

2. 安裝VEH異常處理程序,編寫VEHHandler(VEH的異常處理函數);

3. 設置鉤子:人為在Hook點構造異常(比如修改目標函數第一個字節位0xCC等),并保存觸發異常的地址等信息;

4. 在VEHHandler函數內部修改目標函數原始流程,并在執行完畢后主動修復異常。

實現代碼

#include
#include

// 獲取目標函數的地址
ULONG_PTR OriginalMessageBox = NULL;

structEXCEPTION_HOOK
{
ULONG_PTR address; // 用來記錄異常產生的地址,后面將用來確保是我們人為構造的異常
BYTE originalBytes; // 用來記錄原始目標函數的第一個字節
};
EXCEPTION_HOOK HookInfo;

// 異常處理函數
// 用來修改目標函數原始流程,并在執行完我們功能后修復異常
LONG NTAPI VEHHandler(EXCEPTION_POINTERS* ExceptionInfo)
{
if(ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_BREAKPOINT && // 異常類型為斷點異常
(ULONG_PTR)ExceptionInfo->ExceptionRecord->ExceptionAddress == HookInfo.address) // 發生異常的地址為我們主動構造的異常地址
{
// 在這里編寫自定義的代碼,或者修改Hook API的相關參數
MessageBoxW(0, L"VEHHandler() called", L"VEH Hook", 0);

// 解除鉤子
DWORD oldProtect = 0;
VirtualProtect((LPVOID)HookInfo.address, 1, PAGE_EXECUTE_READWRITE, &oldProtect);
*(BYTE*)HookInfo.address = HookInfo.originalBytes;
VirtualProtect((LPVOID)HookInfo.address, 1, oldProtect, &oldProtect);

returnEXCEPTION_CONTINUE_EXECUTION; // 回到異常發生的地方,由于已經修復了異常問題,所以之后能夠正確執行
}
returnEXCEPTION_CONTINUE_SEARCH; // 向上繼續尋找異常處理程序
}

voidSetHook(ULONG_PTR address)
{
AddVectoredExceptionHandler(1, VEHHandler); // 添加VEH的異常處理函數

HookInfo.address = address; // 保存目標函數發生異常的地址
HookInfo.originalBytes = *(BYTE*)address; // 保存目標函數原始的第一個字節

DWORD oldProtect = 0;
VirtualProtect((LPVOID)address, 1, PAGE_EXECUTE_READWRITE, &oldProtect);
*(UCHAR*)address = 0xCC; // 人為構造異常,將目標函數代碼處的第一個字節改為0xCC
VirtualProtect((LPVOID)address, 1, oldProtect, &oldProtect);
}

intmain()
{
// 保存MessageBoxA原始地址
OriginalMessageBox = (ULONG_PTR)GetProcAddress(GetModuleHandleA("user32.dll"), "MessageBoxA");

MessageBoxA(0, "Before Hooking", "VEH Hook", 0);

SetHook(OriginalMessageBox);// 安裝鉤子用以觸發異常
MessageBoxA(0, "After Hooking", "VEH Hook", 0);

return0;
}

在上述代碼中,先保存了MessageBoxA函數在當前進程中的地址,之后第一次調用MessageBoxA,此時該函數還沒有被Hook,隨后為了人為構造異常,將MessageBoxA函數代碼的第一個字節修改為0xCC,當之后再次調用MessageBoxA后,程序將會觸發0xCC異常,由于程序中添加了VEH異常處理,那么程序將跳轉到VEHHandler(自寫的異常處理函數中),在該函數代碼中,首先過濾得到主動觸發的異常,滿足的條件下,開始執行自定義的代碼,這里為了說明,使用MessageBoxW彈出對話框,由于異常被程序接管,所以在異常處理函數中,執行完自定義的代碼后,需要修復異常,進而返回原始觸發異常的位置繼續執行。

效果

e5f6a836-56c7-11ed-a3b6-dac502259ad0.gif

PS:通常來說,我們將Hook的功能代碼編寫進一個DLL文件中,在將該DLL文件通過進程注入的方式注入到需要改變程序流程的進程中來達到目的。

丈八網安蛇矛實驗室成立于2020年,致力于安全研究、攻防解決方案、靶場對標場景仿真復現及技戰法設計與輸出等相關方向。團隊核心成員均由從事安全行業10余年經驗的安全專家組成,團隊目前成員涉及紅藍對抗、滲透測試、逆向破解、病毒分析、工控安全以及免殺等相關領域。

審核編輯:湯梓紅

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • API
    API
    +關注

    關注

    2

    文章

    1502

    瀏覽量

    62092
  • 應用層
    +關注

    關注

    0

    文章

    46

    瀏覽量

    11511
  • HOOK
    +關注

    關注

    0

    文章

    15

    瀏覽量

    8393

原文標題:安全開發之應用層Hook技術

文章出處:【微信號:蛇矛實驗室,微信公眾號:蛇矛實驗室】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    Android安全開發WebView中的地雷

    `Android安全開發WebView中的地雷0X01 About WebView在Android開發中,經常會使用WebView來實現WEB頁面的展示,在Activiry中啟動自己的瀏覽器,或者
    發表于 09-09 19:35

    應用層通信安全

    `歡迎工程師的我們!電子發燒友E2E技術沙龍-北京站,本期討論主題是關于“應用層通信安全”E2E活動北京站活動鏈接~~http://url.elecfans.com/u/e524cb1b33
    發表于 03-18 17:55

    學習嵌入式Linux應用層開發

    1 應用層與驅動要想學習嵌入式Linux應用層開發,首先要區分好應用層和驅動之間的關系。我
    發表于 11-02 10:20

    嵌入式應用層開發通常有哪些問題

    嵌入式應用層開發通常有哪些問題?
    發表于 12-24 06:54

    【學習打卡】OpenHarmony的應用層說明

    以增加額外的網絡安全;3.確保存在必要的通信接口,例如發送方計算機中是否有以太網或Wi-Fi接口;4.確保雙方就錯誤恢復程序、數據完整性和隱私達成一致;5.在應用層確定協議和數據語法規則;6.將接收
    發表于 07-14 08:44

    講講Hook技術的攻防對抗思路

    1、論Hook技術的攻防對抗  首先,簡單認識下Hook 技術。  Hook技術是一門廣泛用于計
    發表于 09-28 11:12

    嵌入式開發系列課程五:Windows CE安全開發

    嵌入式開發系列課程五:Windows CE安全開發與配置
    發表于 03-25 08:58 ?22次下載

    應用層和后臺分析便攜式電子產品的節能技術

    應用層和后臺分析便攜式電子產品的節能技術  便攜式電子產品的節能技術基本上可以按照其執行方式分為應用層技術及后臺
    發表于 11-30 10:03 ?615次閱讀
    從<b class='flag-5'>應用層</b>和后臺分析便攜式電子產品的節能<b class='flag-5'>技術</b>

    SIP應用層網關技術

    本文提出了“SIP應用層網關”技術,并將其應用于網絡通信中來建立相對合理、完善的SIP網絡,以解決SIP私網遠程控制中穿越NAT/FireWall的難題
    發表于 04-20 11:37 ?5758次閱讀

    Zigbee應用層規范

    本內容介紹了Zigbee應用層規范
    發表于 05-24 11:37 ?85次下載
    Zigbee<b class='flag-5'>應用層</b>規范

    電子功能安全開發及汽車EPS電機控制設計

    實現認證并開始你的功能安全開發
    的頭像 發表于 08-14 00:15 ?4929次閱讀

    認知無線電MAC應用層仿真軟件

    認知無線電MAC應用層仿真軟件(澳萊特電源技術有限公司)-該文檔為認知無線電MAC應用層仿真軟件總結文檔,是一份很不錯的參考資料,具
    發表于 09-15 11:40 ?11次下載
    認知無線電MAC<b class='flag-5'>層</b>與<b class='flag-5'>應用層</b>仿真軟件

    嵌入式Linux應用層開發教程(一)基本概念

    1 應用層與驅動要想學習嵌入式Linux應用層開發,首先要區分好應用層和驅動之間的關系。我
    發表于 11-01 17:59 ?14次下載
    嵌入式Linux<b class='flag-5'>應用層</b><b class='flag-5'>開發</b>教程(一)基本概念

    什么是SEooC?SEooC和正常功能安全開發有什么不同?

    在功能安全開發過程中,很多時候我們會遇到獨立于環境的安全要素開發(Safety Element out of Context, SEooC)
    的頭像 發表于 04-27 16:52 ?9393次閱讀
    什么是SEooC?SEooC和正常功能<b class='flag-5'>安全開發</b>有什么不同?

    物聯網的技術架構及應用層是什么?

    物聯網的技術架構包括感知、網絡、平臺應用層應用層是物聯網的頂層,它的主要功能是將感知
    的頭像 發表于 07-15 08:56 ?3765次閱讀
    主站蜘蛛池模板: 亚洲、国产综合视频| 91桃色污无限免费看| 福利啪啪吧| 手机在线观看毛片| 国产亚洲福利在线视频| 亚洲欧美日韩国产精品26u| 久久婷婷久久一区二区三区| 97午夜精品| 特级毛片全部免费播放免下载| 国产亚洲精品久久久无码狼牙套| 亚洲无AV在线中文字幕| 男女爽爽无遮挡午夜视频在线观看| 阿娇和冠希13分钟在线观看| 午夜国产在线观看| 久久久伊人影院| 大伊人青草狠狠久久| 亚洲人成www在线播放| 欧美 国产 日产 韩国 在线| 国产精品三级在线观看| 18video性欧美19sex高清| 日韩熟女精品一区二区三区| 娇小亚裔被两个黑人| 草莓视频在线免费观看| 亚洲午夜AV久久久精品影院色戒 | 忘忧草高清| 久久看片网| 国产精品999| 97国产视频| 亚洲精品嫩草研究院久久| 免费女人光着全身网站| 国内精品蜜汁乔依琳视频| 不卡一区二区高清观看视频| 一本道中文无码亚洲| 帅哥操美女| 男人j进女人j一进一出| 精品国产露脸久久AV麻豆| 俄罗斯大肥BBXX| 99精品小视频| 在线一本码道高清| 亚洲精品欧美精品中文字幕| 三级黄色片免费观看|