hook函數


在10M的源碼中查找內存泄露。

這個是網上隨便看的一個面試題,看到博主寫的解法,提到一個鈎子函數,我連什么是鈎子函數都不知道,人家都能想到用這個方法來解決,

感覺自己太齪了,如果面試中問到這種題,肯定掛了。下面先介紹下鈎子函數。

摘至網上:

鈎 子實際上是一個處理消息的程序段,通過系統調用,把它掛入系統。每當特定的消息發出,在沒有到達目的窗口前,鈎子程序就先捕獲該消息,亦即鈎子函數先得到 控制權。這時鈎子函數即可以加工處理(改變)該消息,也可以不作處理而繼續傳遞該消息,還可以強制結束消息的傳遞。對每種類型的鈎子由系統來維護一個鈎子 鏈,最近安裝的鈎子放在鏈的開始,而最先安裝的鈎子放在最后,也就是后加入的先獲得控制權。要實現Win32的系統鈎子,必須調用SDK中的API函數 SetWindowsHookEx來安裝這個鈎子函數,這個函數的原型是HHOOK   SetWindowsHookEx(int   idHook,HOOKPROC   lpfn,HINSTANCE   hMod,DWORD   dwThreadId);,其中,第一個參數是鈎子的類型;第二個參數是鈎子函數的地址;第三個參數是包含鈎子函數的模塊句柄;第四個參數指定監視的線 程。如果指定確定的線程,即為線程專用鈎子;如果指定為空,即為全局鈎子。其中,全局鈎子函數必須包含在DLL(動態鏈接庫)中,而線程專用鈎子還可以包 含在可執行文件中。得到控制權的鈎子函數在完成對消息的處理后,如果想要該消息繼續傳遞,那么它必須調用另外一個SDK中的API函數 CallNextHookEx來傳遞它。鈎子函數也可以通過直接返回TRUE來丟棄該消息,並阻止該消息的傳遞。

粗略看一下大概是說鈎子函數可以截獲一個消息並執行我們想要做的事情,一般用法是將鈎子函數作為一個函數參數,下面的例子

 

復制代碼
#include <iostream>
using namespace std;
//鈎子函數1
void fun1()
{
cout<<"hello fun1"<<endl;
}
//鈎子函數2
void fun2(int n)
{
cout<<"hello fun2 "<<n<<endl;
}
//作為參數傳遞
int caller1(void (*ptr)())
{
(*ptr)();
return 0;
}
int caller2(int i,void (*ptr)(int))
{
(*ptr)(i);
return 0;
}
int main()
{
caller1(fun1);
caller2(2,fun2);
return 0;
}
復制代碼


 那回到這個題目,有個簡單的方法是:

可以包裝malloc和free,假設為Malloc和Free。之后我們維護一個集合,如果是調用Malloc,則把地址放入到集合中,如果是調 用Free,則從集合中去掉該地址。之后把源代碼中的所有malloc和free替換成Malloc和Free,運行程序,那么當程序結束時,集合中剩余 的地址就是內存泄露的地址。

如果利用鈎子函數,大概變成這樣子:

比如malloc可能就變成Malloc(size,hook),size是大小,hook是鈎子,具體維護集合的代碼在hook里實現。

這么多不懂得知識,這么多需要學習的東西阿。。。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM