C HOOK學習筆記

來源:互聯網
上載者:User

標籤:

參考 http://9200cs.blog.163.com/blog/static/134577369201041111656659/

 

環境:VS2008

 

一、建立一個dll程式add,程式非常簡單,其功能就是實現簡單的a+b。

1、建立一個項目名為add

選擇dll

 然後開啟dllmain.cpp,代碼:

// dllmain.cpp : 定義 DLL 應用程式的進入點。#include "stdafx.h"int WINAPI add(int a, int b){  return a + b;}BOOL APIENTRY DllMain(HANDLE hModule,  DWORD  ul_reason_for_call,  LPVOID lpReserved  ){  return TRUE;}

右鍵項目添加一個建立項名為add.def的檔案

開啟編寫代碼:

LIBRARY  AddDESCRIPTION "ADD LA"EXPORTS add  @1;

 

 編譯後我們就能在Debug目錄下擷取add.dll了。

二、編寫主程式,建立一個基於對話方塊的MFC應用程式One

在嚮導中選擇基於對話方塊

雙擊確定進入,代碼為

    HINSTANCE hAddDll = NULL;void COneDlg::OnBnClickedOk(){            typedef int (WINAPI*AddProc)(int a, int b);//函數原型定義      AddProc add;    if (hAddDll == NULL)    {      hAddDll = ::LoadLibrary(_T("add.dll"));//載入dll      }    add = (AddProc)::GetProcAddress(hAddDll, "add");//擷取函數add地址      int a = 1;    int b = 2;    int c = add(a, b);     CString tem;    tem.Format(_T("%d+%d=%d"), a, b, c);    AfxMessageBox(tem);}

編譯一下再將之前擷取到的add.dll拷貝到項目One下有exe檔案的Debug目錄下
運行結果出現

就說明我們的One已經成功調用了add.dll裡的add()方法了。

三、至此,我們的小程式已經完成了,接下來該到我們的主角HOOK登場了!

建立一個MFC DLL項目

Hook.cpp裡的代碼

// Hook.cpp : Defines the initialization routines for the DLL.#include "stdafx.h"#include "Hook.h"#ifdef _DEBUG#define new DEBUG_NEW#endif//變數定義  #pragma data_seg("SHARED") //不同Instance共用的該變數   static HHOOK  hhk = NULL; //滑鼠鉤子控制代碼  static HINSTANCE hinst = NULL; //本dll的執行個體控制代碼 (hook.dll)  #pragma data_seg()  #pragma comment(linker, "/section:SHARED,rws")  //以上的變數為共用  CString temp; //用於顯示錯誤的臨時變數  bool bHook = false; //是否Hook了函數  bool m_bInjected = false; //是否對API進行了Hook  BYTE OldCode[5]; //原程式API入口代碼  BYTE NewCode[5]; //新跳轉的API代碼 (jmp xxxx)  typedef int (WINAPI*AddProc)(int a, int b);//add.dll中的add函數定義  AddProc add; //add.dll中的add函數  HANDLE hProcess = NULL; //所處進程的控制代碼  FARPROC pfadd;  //指向add函數的遠指標  DWORD dwPid;  //所處進程ID  //end of 變數定義  // CHookAppBEGIN_MESSAGE_MAP(CHookApp, CWinApp)END_MESSAGE_MAP()//滑鼠鉤子過程,什麼事情也不做,目的是注入dll到程式中  LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam){    return CallNextHookEx(hhk, nCode, wParam, lParam);}//開啟鉤子的函數  void HookOn(){    ASSERT(hProcess != NULL);    DWORD dwTemp = 0;    DWORD dwOldProtect;    //將記憶體保護模式改為可寫,老模式儲存入dwOldProtect      VirtualProtectEx(hProcess, pfadd, 5, PAGE_READWRITE, &dwOldProtect);    //將所屬進程中add()的前5個位元組改為Jmp Myadd       WriteProcessMemory(hProcess, pfadd, NewCode, 5, 0);    //將記憶體保護模式改回為dwOldProtect      VirtualProtectEx(hProcess, pfadd, 5, dwOldProtect, &dwTemp);    bHook = true;}//關閉鉤子的函數  void HookOff()//將所屬進程中add()的入口代碼恢複  {    ASSERT(hProcess != NULL);    DWORD dwTemp = 0;    DWORD dwOldProtect;    VirtualProtectEx(hProcess, pfadd, 5, PAGE_READWRITE, &dwOldProtect);    WriteProcessMemory(hProcess, pfadd, OldCode, 5, 0);    VirtualProtectEx(hProcess, pfadd, 5, dwOldProtect, &dwTemp);    bHook = false;}//然後,寫我們自己的Myadd()函數  int WINAPI Myadd(int a, int b){    //截獲了對add()的調用,我們給a,b都加上一定的數    a = a + 1;    b = b + 1;    HookOff();//關掉Myadd()鉤子防止死迴圈      int ret;    ret = add(a, b);    HookOn();//開啟Myadd()鉤子      return ret;}//好,最重要的HOOK函數: void Inject(){    if (m_bInjected == false)    { //保證只調用1次          m_bInjected = true;        //擷取add.dll中的add()函數          HMODULE hmod = ::LoadLibrary(_T("add.dll"));        add = (AddProc)::GetProcAddress(hmod, "add");        pfadd = (FARPROC)add;        if (pfadd == NULL)        {            AfxMessageBox(L"cannot locate add()");        }        // 將add()中的入口代碼儲存入OldCode[]          _asm        {            lea edi, OldCode                mov esi, pfadd                cld                movsd                movsb        }        NewCode[0] = 0xe9;//實際上0xe9就相當於jmp指令          //擷取Myadd()的相對位址          _asm        {            lea eax, Myadd                mov ebx, pfadd                sub eax, ebx                sub eax, 5                mov dword ptr[NewCode + 1], eax        }        //填充完畢,現在NewCode[]裡的指令相當於Jmp Myadd          HookOn(); //可以開啟鉤子了      }}CHookApp::CHookApp(){}CHookApp theapp;//滑鼠鉤子安裝函數:  BOOL InstallHook(){    hhk = ::SetWindowsHookEx(WH_MOUSE, MouseProc, hinst, 0);    return true;}//卸載滑鼠鉤子函數  void UninstallHook(){    ::UnhookWindowsHookEx(hhk);}//在dll執行個體化中獲得一些參數  BOOL CHookApp::InitInstance(){    CWinApp::InitInstance();    //獲得dll 執行個體,進程控制代碼      hinst = ::AfxGetInstanceHandle();    DWORD dwPid = ::GetCurrentProcessId();    hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, dwPid);    //調用注射函數      Inject();    return TRUE;}

接著別忘了Hook.def下的配置

LIBRARY      "Hook"DESCRIPTION  ‘Hook Windows Dynamic Link Library‘EXPORTS    ; Explicit exports can go here InstallHook   MouseProc Myadd UninstallHook

 

 編譯一下,再將之前獲得的add.dll丟一份到Hook的Debug目錄下

這樣,我們的Hook完成了

四、接下來我們就可以修改前面的One的測試程式了

添加一個按鈕,雙擊進入相應事件 代碼:

HINSTANCE hinst;void COneDlg::OnBnClickedButton1(){    hinst=LoadLibrary(_T("hook.dll"));    if(hinst==NULL)    {        AfxMessageBox(_T("no hook.dll!"));        return;    }    typedef BOOL (CALLBACK *inshook)();     inshook insthook;    insthook=::GetProcAddress(hinst,"InstallHook");    if(insthook==NULL)    {        AfxMessageBox(_T("func not found!"));        return;    }    DWORD pid=::GetCurrentProcessId();    BOOL ret=insthook();}

別忘了退出時卸掉鉤子

再加個按鈕

void COneDlg::OnBnClickedButton2(){    // TODO: 在此添加控制項通知處理常式代碼s    typedef BOOL (CALLBACK *UnhookProc)();     UnhookProc UninstallHook;    UninstallHook=::GetProcAddress(hinst,"UninstallHook");    if(UninstallHook==NULL) UninstallHook();    if (hinst!=NULL)    {        ::FreeLibrary(hinst);    }    if (hAddDll!=NULL)    {        ::FreeLibrary(hAddDll);    }    CDialog::OnCancel();}

再將Hook目錄下的Hook.dll也丟到One的Debug目錄下

至此,整個HOOK的例子就結束了。

最後的效果:正常為1+2=3,點擊button1後再點擊確定,就變成1+1=5了

最後需要注意的是項目裡面有2個Debug目錄,要放在這個

 

 裡面有

 

 不要 放錯了哦,這個Debug目錄是需要編譯過後才產生的~~!

C HOOK學習筆記

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.