HOOK虚函数
文章目錄
- 聲明
- 過程
- 過程綜述
- 代碼講解
- 正常代碼:
- Hook后:
聲明
首先呢,這里會牽扯到虛函數,建議先看看以下博客(前三章就行),
c++類成員函數指針
詳解虛函數的實現過程之初探虛表(1)
詳解虛函數的實現過程之單繼承(2)
詳解虛函數的實現過程之多重繼承(3)
詳解虛函數的實現過程之虛基類(4)
詳解虛函數的實現過程之菱形繼承(5)
看了之后大家會了解到:虛函數的地址存放在虛表里面,虛表地址放在對象里面,虛表地址都是放在對象的前四個字節。
所以我們可以進行把存放在 虛表里面這個函數地址值給替換(這也就是Hook手法之一)了,當進行調用虛函數時,是不是就可以改變程序的走向,和原來不同。
過程
class Base { public:virtual void Print() {printf("這是一個虛函數");} }; void Myprint() {printf("這是一個普通函數");}過程綜述
Base類里面有個虛函數,虛表地址存放在對象的前四個字節里面,然后虛函數地址存放在虛表的前四個字節里面,
用Myprint函數地址,把虛表里面前四個字節的地址值給替換了,這樣就Hook成功。
代碼講解
或者這樣也行
Base* Pb = new Base();首先,把這個指針的范圍放在四個字節,因為虛表地址就四個字節,所以有了(DWORD *),然后出內容,加個*號,即*(DWORD *),取出內容后,內容也就是虛表的地址值,此時這個指針也就指向了這個地址值,范圍是整個虛表,然后還要強轉一下范圍(DWORD*)(因為函數的地址值是前4個字節),所以就有了(DWORD*)*(DWORD*)Pb
正常代碼:
#include <iostream> #include<Windows.h> class Base { public:virtual void Print() {printf("這是一個虛函數");} };void Myprint() {printf("這是一個普通函數");} int main() {Base* Pb = new Base();Pb->Print();delete Pb;return 0; }Hook后:
#include <iostream> #include<Windows.h> class Base { public:virtual void Print() {printf("這是一個虛函數");}};void Myprint() {printf("這是一個普通函數");} int main() {Base* Pb = new Base();DWORD* pVtAddr = (DWORD*)*(DWORD*)Pb;DWORD dwOldProtect = 0;VirtualProtect(pVtAddr, 4, PAGE_READWRITE, &dwOldProtect);*pVtAddr = (DWORD)Myprint;Pb->Print();delete Pb;return 0;}總結
- 上一篇: 内核和用户模式下进程与线程创建
- 下一篇: 一次讲清UNICODE