Hook技術(鉤子技術)

HOOK(鉤子技術)

這里的hook我理解的意思就是通過攔截指令,將指令換成自己想要的指令,從而做道繞過原本的程序指令,要修改這個指令,要用匯編技術,從二進制入手。

擴展:

木馬病毒之所以會被攔截掉,是因為現在的安全軟件在內核中的HOOK了大量的關鍵位置,使得病毒木馬的進程、文件、網絡行為都將受到監控,一舉一動都難逃殺軟的眼睛,想要攔截易如反掌。

商業軟件通過逆向分析和lnline HOOK,可以篡改掉商業軟件的注冊校驗機制,讓校驗函數返回成功,繞開軟件的限制。

系統漏洞如何被補丁修復的:統一通過Inline HOOK,操作系統能夠修改原來有bug的代碼,轉而執行修復后的新版本,解決系統漏洞。

總結:

以上就是要介紹的全部HOOK技術了。當然有HOOK,就有反HOOK,很多安全軟件都會檢查關鍵的位置是否被篡改。不僅如此,因為流氓軟件隨意修改系統,Windows從Win7 x64開始加入了PatchGuard機制,針對操作系統核心數據結構都加入了定時檢測機制,一旦發現被篡改,立刻藍屏給你看,而且在隨著系統升級換代,這個檢查的粒度和強度變得越來越強。

Inline HOOK(內聯HOOK)

以下是我自己個人的理解:

這里也就是直接截取指令消息,從而實現自己的目的

Inline HOOK(內聯HOOK)的目標就是直接修改程序編譯后的指令,屬于最基礎也最常見的HOOK技術。

IAT掛鉤

以下是我自己個人的理解:

這里就要和dll劫持漏洞有點相似了,這里因為程序會調用很多dll進行操作,而為了方便調用這些dll,所以會有一個PE文件的導入表IAT存在,而我們要做的,則是修改IAT表中的參數地址,從而實現自己的操作,比如實現自己的dll文件運行。

一個程序的所有代碼一般不會全部都編譯到一個模塊中,分拆到不同的模塊既有利于合作開發,也有利于代碼管理,降低耦合。

動態鏈接庫就提供了這樣的能力,將不同的模塊編譯成一個個的動態庫文件,在使用時引入調用。

在Windows平臺上,動態鏈接庫一般以DLL文件的形式存在,主程序模塊一般是EXE文件形式存在。無論是EXE還是DLL,都是屬于PE文件。

一個模塊引用了哪些模塊的哪些函數,是被記錄在PE文件的導入表IAT中。這個表格位于PE文件的頭部,里面記錄了模塊的名字,函數的名字。

在模塊加載時,模塊加載器將解析對應函數的實際地址,填入到導入表中。

通過修改導入表IAT中函數的地址,這種HOOK叫IAT HOOK。

SEH 鉤子

以下是我自己個人的理解:

這里的意思就是在操作系統異常是,操作系統會向上報告錯誤,如果上級處理不了,就會報告給上上級,要是一直處理不了,則會彈出一個報錯對話框,而我們要修改的也正是這異常處理器中記錄的函數指針,當異常發生時就能獲得執行,從而劫持到執行流!因為這些異常處理器都位于線程的棧空間,修改起來并非難事。

SEH是Windows操作系統上結構化異常處理的縮寫,在代碼中通過try/except來捕獲異常時,操作系統將會在線程的棧空間里安置一個異常處理器(其實就是一個數據結構),里面定義了發生異常時該去執行哪里的代碼處理異常。

異常處理可以多級嵌套,那多個異常處理就構成了一個鏈表,存在于棧空間之上。

當發生異常時,操作系統系統就從最近的異常處理器進行尋求處理,如果能處理則罷了,不能處理就繼續尋求更上一級的異常處理器,直到找到能處理的異常處理器。如果都沒法處理,那對不起,只好彈出那個經典的報錯對話框,進程崩潰。

SEH HOOK針對的目標就是修改這些異常處理器中記錄的函數指針,當異常發生時就能獲得執行,從而劫持到執行流!因為這些異常處理器都位于線程的棧空間,修改起來并非難事。

C++ 可觸發的 HOOK

以下是我自己個人的理解:

這里也就是修改用c++寫的程序中的虛函數表中的地址,從而實現自己的目的

C++是一門面向對象的編程語言,支持面向對象的三大特性:封裝性、繼承性、多態性。

其中的多態性,各個C++編譯器基本上都是通過一種叫虛函數表的機制來實現。

下面通過一個實際的例子來感受一下虛函數表在C++多態性上發揮的作用。

#include <iostream>

using namespace std;

class Animal {

public:

?virtual void breathe() {

? cout << "Animal breathe" << endl;

?}

?virtual void eat() {

? cout << "Animal eat" << endl;

?}

};

class Fish : public Animal {

public:

?virtual void breathe() {

? cout << "Fish breathe" << endl;

?}

?virtual void eat() {

? cout << "Fish eat" << endl;

?}

};

class Cat : public Animal {

public:

?virtual void breathe() {

? cout << "Cat breathe" << endl;

?}

?virtual void eat() {

? cout << "Cat eat" << endl;

?}

};

int main() {

?Animal* animal = nullptr;

?Fish* fish = new Fish();

?Cat* cat = new Cat();

?animal = fish;

?animal->breathe();

?animal->eat();

?cout << "--------------" << endl;

?cout << "sizeof(fish) = " << sizeof(fish) << endl;

?cout << "sizeof(cat) = " << sizeof(cat) << endl;

?cout << "--------------" << endl;

?animal = cat;

?animal->breathe();

?animal->eat();

?delete fish;

?delete cat;

?return 0;

}

輸出:

通過上面的輸出,可以看到,fish和cat對象都只占據4個字節。因為這兩個類都沒有成員變量,唯一需要存儲的就是一個虛函數表指針。

以cat對象為例,看一下它的地址,是0x005cfc30:

看一下這個地址起始的4個字節,是什么:

虛表指針是0x000d9b90(這里需要注意字節順序)。

通過這個地址,找到虛函數表,里面有兩個函數地址:

查看這兩個地址,都是指向了一個jmp指令,分別跳到了Cat類的兩個虛函數。

通過上面的實例,總結一下對象、虛函數表和虛函數代碼之間的關系如下圖所示:

每個包含虛函數的類對象,在內存中都有一個指針,位于對象頭部,指向的是一個虛函數表,表中的每一項都是虛函數地址。

類繼承后,如果重寫了父類的虛函數,子類對象指向的表格中對應函數的地址將會更新為子類的函數。

這樣,使用父類指針指向子類對象,通過指針調用虛函數時,就能調用到子類重寫的虛函數,從而實現多態性。

既然是記錄函數地址的表格,那就有存在被篡改的可能,這就是C++ virtable HOOK。

通過篡改對應虛函數的地址,實現對相應函數調用的攔截。

實施這種HOOK,需要逆向分析目標C++對象的結構,掌握虛函數表中各個函數的位置,才能精準打擊。

上面幾種HOOK,修改的都是應用層的函數指針,而操作系統內核中還有一些非常重要的表格,它們的表項中記錄了一些更加關鍵的函數,HOOK這些表格中的函數是非常高危的操作,操作不當將導致操作系統崩潰。當然,高風險高回報,HOOK這些函數,能實現一些非常強大的功能,是病毒、木馬、安全軟件非常愛干的事情。

SSDT 掛鉤

以下是我自己個人的理解:

因為操作系統會提供給程序API接口,來進行消息交互,而在操作系統中,會將所有的系統服務函數地址存放在一張表中,而這張表在windows中叫做SSDT,我們要修改的也正是這張表中的函數地址,從而實現自己的操作。

系統調用是操作系統提供給應用程序的編程接口API,應用程序通過這些API得以操作計算機的資源(如進程、網絡、文件等)。

執行系統調用的時候,CPU將從用戶模式切換到內核模式,進入內核后,將會根據系統調用的API編號,去找到對應的系統服務函數,實現對應API的功能。

操作系統將所有的系統服務函數地址,存放在了一個表格中,這個表格就是系統服務描述符表。在Linux上,這個表格的名字叫sys_call_table,在Windows上,它叫KeServiceDescriptorTable,簡稱SSDT。

Windows上的SSDT向來是兵家必爭之地,安全軟件為了監控應用程序的行為,通常都會替換SSDT表格中的系統服務函數地址為它們的函數。當系統調用觸發時,安全軟件將會及時知曉,并通過應用程序的參數來判定是否“放行”這次調用。

IDT 掛鉤

以下是我自己個人的理解:

這里是在CPU異常的情況下,會根據知道好的函數跳轉道哪里去的操作,而該轉向哪里去處理這些情況的函數地址,而這些地址會存放道一張表中,讓CPU進行查閱,而這里有所不同的是,CPU異常后可能跳轉的次數有點多,所有會有多種表存放了跳轉的函數地址,所以我們要進行修改的話必須知道每張表中的函數地址,這樣我們才可以進行函數地址的修改,從而實現自己的操作。

內核中除了記錄系統服務的SSDT,還有一個非常重要的表格:中斷描述符表IDT。

IDT用于記錄CPU執行過程中遇到中斷、異常等情況時,該轉向哪里去處理這些情況的函數地址。

HOOK IDT有一個注意事項,不同于SSDT是全局唯一的,IDT是與CPU核心緊密相關的,對于多核處理器,會對應多個IDT表。如果想通過HOOK IDT中的函數來搞事情的話,可能需要同時處理多個表。

除了直接修改函數指令和修改函數指針之外,還有一類特殊的HOOK,它們通過系統提供的機制攔截某些消息、通知,從而有機會介入監聽、攔截。

IRP HOOK

以下是我自己個人的理解:

這個hook技術就是去截獲驅動程序發送出去的消息并進行篡改,從而實現自己想要的操作

在Windows系統上,用戶程序和內核驅動之間的交互是通過一種稱為IRP的數據結構實現的,你可以簡單將其理解為應用程序發送了一個消息下去,這個消息就是一個IRP。

而接收消息的目標,是驅動程序創建的設備Device。注意,這個設備不一定是物理設備,也可能完全不存在的虛擬設備,驅動程序可以任意創建一個不存在的設備。

Windows內核中提供了驅動設備的掛載操作,允許別的驅動程序對指定設備進行掛載,從而可以截獲發送給該設備的“消息”,這種HOOK方式被稱為IRP HOOK。

國內一些安全軟件為了互相攻擊,經常用這種方式攔截對方驅動程序的消息,從而可以保護自己不被對方干掉。

TDI HOOK && NDIS HOOK

以下是我自己個人的理解:

這里就是在windows內核中的網絡結構層次中進行截獲消息,之所以能夠截獲消息,是因為TDI和NDIS這兩個標準的接口,因為這兩個接口可以用來被理解成事用來分別向各層傳遞消息用的,而windows為了擴展支持,允許類似防火墻之類的軟件通過這些接口接入,從而能夠截獲到網絡通信流量,進行安全審計,而我們也正是裝了這個空子,從而截獲指令消息

這兩種HOOK方式與Windows內核中的網絡子系統密切相關。

Windows內核中的網絡結構是分層式設計。從最上層的API socket層、到TCP/IP協議棧層、再到底層的網卡驅動程序,分了很多個層次。

而層與層之間的交互,是通過一系列標準接口來實現的,其中最重要的兩個接口標準就是TDI和NDIS。TDI封裝了不同協議棧的差異(Windows不止支持TCP/IP協議棧)提供給上層統一的調用接口。NDIS則封裝了底層不同網卡的驅動程序接口差異,提供給上層統一的收發數據包接口。

Windows為了擴展性支持,允許類似防火墻之類的軟件通過這些接口接入,從而能夠截獲到網絡通信流量,進行安全審計。

既然開了這些接口,一些流氓軟件和木馬病毒也就盯上了它們,通過這些接口就能輕松監聽、篡改網絡數據,達到邪惡的目的。

Windows Message HOOK

以下是我自己個人的理解:

這個就是應用與程序中的,我們日常應用程序時,程序和系統之間會有交互的,而windows通過開啟API接口和這些程序進行交互消息,而也正是因為API接口的開啟,使得我們可以截獲指令消息從而篡改

Windows操作系統的UI交互是以消息來驅動的,用戶的鍵盤輸入、鼠標操作都會被操作系統以消息的形式發送到各個應用程序處理。

Windows提供了API接口,可以被程序用于捕獲這些消息,從而實現一些特定的功能。

這種機制叫做Windows消息鉤子,最常見的就要數鍵盤鉤子了,在十多年前流氓軟件和木馬病毒大行其道的時候,這些惡意軟件經常喜歡通過這種方式來監聽用戶的鍵盤輸入,從而來盜取QQ密碼(當然,現在肯定是不行的了)。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/164693.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/164693.shtml
英文地址,請注明出處:http://en.pswp.cn/news/164693.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

git clone慢的解決辦法

在網站 https://www.ipaddress.com/ 分別搜索&#xff1a; github.global.ssl.fastly.net github.com 得到ip&#xff1a; 打開hosts文件 sudo vim /etc/hosts 在hosts文件末尾添加 140.82.114.3 github.com 151.101.1.194 github.global-ssl.fastly.net 151.101.65.194 g…

外部網關協議_邊界網關協議BGP

一.邊界網關協議BGP的基本概念 邊界網關協議(Border Gateway Protocol&#xff0c;BGP&#xff09;屬于外部網關協議EGP這個類別&#xff0c;用于自治系統AS之間的路由選擇協議。由于在不同AS內度量路由的“代價”(距離、帶寬、費用等&#xff09;可能不同&#xff0c;因此對于…

elasticsearch 7安裝

問題提前報 max virtual memory areas error max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144] 如果您的環境是Linux&#xff0c;注意要做以下操作&#xff0c;否則es可能會啟動失敗 1 用編輯工具打開文件/etc/sysctl.conf 2 …

qml渲染引擎介紹

qml項目啟動入口 Qt Quick項目qml腳本在C++代碼里啟動,main.cpp如下: #include <QGuiApplication> #include <QQmlApplicationEngine>int main(int argc, char *argv[]) {

VUE excel表格導出

js代碼 //下載模板 downloadExl() { // 標題 const tHeader [‘xxx’,xxx,xx名稱,電槍xx,協議xx,snxx]; // key const filterVal [agentName, stationName, equName, channelNumber, manufacturer, sn, ]; // 值 const datas [ { agentName: 你好, stationName: 我們, e…

激光雷達與慣導標定 | Lidar_IMU_Init : 編譯

激光雷達與慣導標定&#xff1a;Lidar_IMU_Init 編譯 功能包安裝安裝ceres-solver-2.0.0 &#xff08;注意安裝2.2.0不行&#xff0c;必須要安裝2.0.0&#xff09; LI-Init是一種魯棒、實時的激光雷達慣性系統初始化方法。該方法可校準激光雷達與IMU之間的時間偏移量和外部參數…

unity shaderGraph實例-可交互瀑布

不要問我水在哪里&#xff0c;你自己相像這是一個瀑布&#xff0c;瀑布的效果我還不會做 效果展示 整體結構 這里片元著色器最后輸出的baseColor應該是黑色&#xff0c;白色為錯誤。 各區域內容 區域1 計算球到瀑布的距離&#xff0c;然后減去一個值&#xff0c;實現黑色區域…

UNETR:用于三維醫學圖像分割的Transformer

論文鏈接&#xff1a;https://arxiv.org/abs/2103.10504 代碼鏈接&#xff1a; https://monai.io/research/unetr 機構&#xff1a;Vanderbilt University, NVIDIA 最近琢磨不出來怎么把3d體數據和文本在cnn中融合&#xff0c;因為確實存在在2d里面用的transformer用在3d里面…

wpf使用CefSharp.OffScreen模擬網頁登錄,并獲取身份cookie,C#后臺執行js

目錄 框架信息&#xff1a;MainWindow.xamlMainWindow.xaml.cs爬取邏輯模擬登錄攔截請求Cookie獲取 CookieVisitorHandle 框架信息&#xff1a; CefSharp.OffScreen.NETCore 119.1.20 MainWindow.xaml <Window x:Class"Wpf_CHZC_Img_Identy_ApiDataGet.MainWindow&qu…

API自動化測試:如何構建高效的測試流程

一、引言 在當前的軟件開發環境中&#xff0c;API&#xff08;Application Programming Interface&#xff09;扮演了極為重要的角色&#xff0c;連接著應用的各個部分。對API進行自動化測試能夠提高測試效率&#xff0c;降低錯誤&#xff0c;確保軟件產品的質量。本文將通過實…

SpringMVC(三)

十、攔截器 1、攔截器的配置 SpringMVC中的攔截器用于攔截控制器方法的執行 SpringMVC中的攔截器需要實現HandlerInterceptor SpringMVC的攔截器必須在SpringMVC的配置文件中進行配置&#xff1a; <bean class"com.atguigu.interceptor.FirstInterceptor">…

constexpt

constexpt constexpt是C11引入的新的關鍵字&#xff0c;它用于在編譯時而非運行時計算函數或變量的值。這個特性對于提高程序效率和優化代非常有用。 編譯時常量和運行時常量 編譯時常量&#xff08;Compile-time Constants&#xff09;和運行時常量&#xff08;Runtime Con…

8年經驗之談 —— 如何使用自動化工具編寫測試用例?

以下為作者觀點&#xff0c;僅供參考&#xff1a; 在快速變化的軟件開發領域&#xff0c;保證應用程序的可靠性和質量至關重要。隨著應用程序復雜性和規模的不斷增加&#xff0c;僅手動測試無法滿足行業需求。 這就是測試自動化發揮作用的地方&#xff0c;它使軟件測試人員能…

leetcode做題筆記1410. HTML 實體解析器

「HTML 實體解析器」 是一種特殊的解析器&#xff0c;它將 HTML 代碼作為輸入&#xff0c;并用字符本身替換掉所有這些特殊的字符實體。 HTML 里這些特殊字符和它們對應的字符實體包括&#xff1a; 雙引號&#xff1a;字符實體為 &quot; &#xff0c;對應的字符是 "…

python appium 官網下載

找了半天吐了 https://github.com/appium/appium-desktop/releases/tag/v1.22.3-4

Hibernate批量處理數據

概念&#xff1a; 批量處理數據是指在一個事務場景中處理大量數據。 在應用程序中難以避免進行批量操作&#xff0c;Hibernate提供了以下方式進行批量處理數據&#xff1a; (1)使用HQL進行批量操作 數據庫層面 executeUpdate() (2)使用JDBC API進行批量操作 數據庫層面 …

Vue學習筆記-Object.defineproperty函數

文章目錄 前文提要Object.defineProperty作用Object.defineProperty參數使用例圖getter&#xff0c;也就是get函數setter&#xff0c;也就是set函數 前文提要 本人僅做個人學習記錄&#xff0c;如有錯誤&#xff0c;請多包涵 Object.defineProperty作用 當在js中聲明了一個變…

王道p150 20.將給定的表達式樹轉化為等價的中綴表達式(通過括號反應操作符的計算次序)

本題代碼如下 void btreetoexp(tree t, char deep) {if (t NULL)return;else if (t->lchild NULL && t->rchild NULL)printf("%c", t->data);//輸出操作數&#xff0c;不加括號else {if (deep > 1)printf("(");btreetoexp(t->l…

Rust語言入門教程(二) - 變量與作用域

變量與作用域 變量的聲明與初始化 Rust的基本語法格式如下&#xff1a; fn main(){let bunnies 2; }語句以分號結尾&#xff0c;用花括號包含語句塊。 Rust的語法其實借鑒了很多其他的語言&#xff0c;比如C語言和Python&#xff0c; 所以變量定義的格式看起來也跟很多我們…

shell 腳本的函數和數組

函數 —— 封裝的一個公式&#xff1a;sin、cos、tan —— 函數為腳本的別名 —— 函數就是一個功能模塊&#xff0c;在函數中寫執行的命令即可&#xff1b;使用函數可以避免代碼重復&#xff0c;增加可讀性&#xff0c;簡化腳本&#xff0c;使用函數可以將大的工程分割為若…