• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            S.l.e!ep.¢%

            像打了激速一樣,以四倍的速度運轉,開心的工作
            簡單、開放、平等的公司文化;尊重個性、自由與個人價值;
            posts - 1098, comments - 335, trackbacks - 0, articles - 1
              C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

            APIHOOK實例剖析

            Posted on 2010-01-31 22:20 S.l.e!ep.¢% 閱讀(501) 評論(0)  編輯 收藏 引用 所屬分類: RootKit
            APIHOOK實例剖析

            ?關于APIHOOK的基礎知識有很多,如dll的相關知識、Hook的相關知識、系統進程與線程之間的聯系等。具體可以看我的另兩篇文章:"?
            一、APIHOOK之dll部分
            ?
            //////////////////////////////// APIHook_Dll.cpp ////////////////////////////////////////
            //???????????????????????????? rivershan寫于2002.9.23????????????????????????????????? //
            /////////////////////////////////////////////////////////////////////////////////////////

            #include "stdafx.h"
            #include "APIHook_Dll.h"

            #include <ImageHlp.h>
            #include <tlhelp32.h>

            #pragma comment(lib,"ImageHlp") //定義全局共享數據段

            #pragma data_seg("Shared")
            HMODULE hmodDll=NULL;
            HHOOK hHook=NULL;

            #pragma data_seg()

            #pragma comment(linker,"/Section:Shared,rws") //設置全局共享數據段的屬性

            ///////////////////////////////////// DllMain 函數 /////////////////////////////////////////
            //dll的入口點
            BOOL APIENTRY DllMain( HMODULE hModule,?
            ?????????????????????? DWORD? ul_reason_for_call,?
            ?????????????????????? LPVOID lpReserved
            ????? )
            {
            ?switch(ul_reason_for_call)
            ?{
            ?case DLL_PROCESS_ATTACH:
            ??//if(sHook)??
            ??
            ?case DLL_PROCESS_DETACH:
            ??UnInstallHook();
            ??break;
            ?}
            ?hmodDll=hModule;
            ??? return TRUE;
            }

            ///////////////////////////////////// HookOneAPI 函數 /////////////////////////////////////////
            //進行IAT轉換的關鍵函數,其參數含義:
            //pszCalleeModuleName:需要hook的模塊名
            //pfnOriginApiAddress:要替換的自己API函數的地址
            //pfnDummyFuncAddress:需要hook的模塊名的地址
            //hModCallerModule:我們要查找的模塊名稱,如果沒有被賦值,
            //?????將會被賦值為枚舉的程序所有調用的模塊

            void WINAPI HookOneAPI(LPCTSTR pszCalleeModuleName,PROC pfnOriginApiAddress,?
            ??????? PROC pfnDummyFuncAddress,HMODULE hModCallerModule)
            {
            ?ULONG size;

            ?//獲取指向PE文件中的Import中IMAGE_DIRECTORY_DESCRIPTOR數組的指針

            ?PIMAGE_IMPORT_DESCRIPTOR pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)
            ??ImageDirectoryEntryToData(hModCallerModule,TRUE,IMAGE_DIRECTORY_ENTRY_IMPORT,&size);

            ?if (pImportDesc == NULL)
            ??return;

            ?//查找記錄,看看有沒有我們想要的DLL

            ?for (;pImportDesc->Name;pImportDesc++)
            ?{
            ??LPSTR pszDllName = (LPSTR)((PBYTE)hModCallerModule+pImportDesc->Name);
            ??if (lstrcmpiA(pszDllName,pszCalleeModuleName) == 0)
            ???break;
            ?}

            ?if (pImportDesc->Name == NULL)
            ?{
            ??return;
            ?}

            ?//尋找我們想要的函數

            ?PIMAGE_THUNK_DATA pThunk =?
            ??(PIMAGE_THUNK_DATA)((PBYTE)hModCallerModule+pImportDesc->FirstThunk);//IAT
            ?for (;pThunk->u1.Function;pThunk++)
            ?{
            ??//ppfn記錄了與IAT表項相應的函數的地址

            ??PROC * ppfn= (PROC *)&pThunk->u1.Function;??
            ??if (*ppfn == pfnOriginApiAddress)?
            ??{
            ???//如果地址相同,也就是找到了我們想要的函數,進行改寫,將其指向我們所定義的函數

            ???WriteProcessMemory(GetCurrentProcess(),ppfn,&(pfnDummyFuncAddress),
            ????sizeof(pfnDummyFuncAddress),NULL);
            ???return;
            ??}
            ?}
            }

            //查找所掛鉤的進程所應用的dll模塊的

            BOOL WINAPI HookAllAPI(LPCTSTR pszCalleeModuleName,PROC pfnOriginApiAddress,
            ??????? PROC pfnDummyFuncAddress,HMODULE hModCallerModule)
            {
            ?if (pszCalleeModuleName == NULL)
            ?{
            ??return FALSE;
            ?}
            ?if (pfnOriginApiAddress == NULL)
            ?{
            ??return FALSE;
            ?}
            ?//如果沒傳進來要掛鉤的模塊名稱,枚舉被掛鉤進程的所有引用的模塊,
            ?//并對這些模塊進行傳進來的相應函數名稱的查找
            ?
            ?if (hModCallerModule == NULL)
            ?{
            ??MEMORY_BASIC_INFORMATION mInfo;
            ??HMODULE hModHookDLL;
            ??HANDLE hSnapshot;
            ??MODULEENTRY32 me = {sizeof(MODULEENTRY32)};
            ??//MODULEENTRY32:描述了一個被指定進程所應用的模塊的struct

            ??VirtualQuery(HookOneAPI,&mInfo,sizeof(mInfo));
            ??hModHookDLL=(HMODULE)mInfo.AllocationBase;
            ??
            ??hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,0);
            ??BOOL bOk = Module32First(hSnapshot,&me);
            ??while (bOk)
            ??{
            ???if (me.hModule != hModHookDLL)
            ???{
            ????hModCallerModule = me.hModule;//賦值
            ????//me.hModule:指向當前被掛鉤進程的每一個模塊?
            ????HookOneAPI(pszCalleeModuleName,pfnOriginApiAddress,
            ?????pfnDummyFuncAddress,hModCallerModule);
            ???}
            ???bOk = Module32Next(hSnapshot,&me);
            ??}
            ??return TRUE;??
            ?}
            ?//如果傳進來了,進行查找
            ?else
            ?{
            ??HookOneAPI(pszCalleeModuleName,pfnOriginApiAddress,
            ????pfnDummyFuncAddress,hModCallerModule);
            ??return TRUE;
            ?}
            ?return FALSE;
            }

            //////////////////////////////////// UnhookAllAPIHooks 函數 /////////////////////////////////////
            //通過使pfnDummyFuncAddress與pfnOriginApiAddress相等的方法,取消對IAT的修改
            BOOL WINAPI UnhookAllAPIHooks(LPCTSTR pszCalleeModuleName,PROC pfnOriginApiAddress,
            ???????? PROC pfnDummyFuncAddress,HMODULE hModCallerModule)
            {
            ?PROC temp;
            ?temp = pfnOriginApiAddress;
            ?pfnOriginApiAddress = pfnDummyFuncAddress;
            ?pfnDummyFuncAddress = temp;
            ?return HookAllAPI(pszCalleeModuleName,pfnOriginApiAddress,
            ??pfnDummyFuncAddress,hModCallerModule);
            }

            ////////////////////////////////// GetMsgProc 函數 ////////////////////////////////////////
            //鉤子子程。與其它鉤子子程不大相同,沒做什么有意義的事情,繼續調用下一個鉤子子程,形成循環
            LRESULT CALLBACK GetMsgProc(int code,WPARAM wParam,LPARAM lParam)
            {
            ?return CallNextHookEx(hHook,code,wParam,lParam);
            }

            //////////////////////////////////// InstallHook 函數 /////////////////////////////////////
            //安裝或卸載鉤子,BOOL IsHook參數是標志位
            //對要鉤哪個API函數進行初始化
            //我們這里裝的鉤子類型是WH_GETMESSAGE
            void __declspec(dllexport) WINAPI InstallHook(BOOL IsHook,DWORD dwThreadId)
            {
            ?if(IsHook)
            ?{
            ?hHook=SetWindowsHookEx(WH_GETMESSAGE,(HOOKPROC)GetMsgProc,hmodDll,dwThreadId);
            ?
            ?//GetProcAddress(GetModuleHandle("GDI32.dll"),"ExtTextOutA"):取得要鉤的函數在所在dll中的地址
            ?
            ?HookAllAPI("GDI32.dll",GetProcAddress(GetModuleHandle("GDI32.dll"),
            ??"TextOutW"),(PROC)&H_TextOutW,NULL);
            ?HookAllAPI("GDI32.dll",GetProcAddress(GetModuleHandle("GDI32.dll"),
            ??"TextOutA"),(PROC)&H_TextOutA,NULL);
            ?}
            ?else
            ?{
            ??UnInstallHook();
            ??UnhookAllAPIHooks("GDI32.dll",GetProcAddress(GetModuleHandle("GDI32.dll"),
            ???"TextOutW"),(PROC)&H_TextOutW,NULL);
            ??UnhookAllAPIHooks("GDI32.dll",GetProcAddress(GetModuleHandle("GDI32.dll"),
            ???"TextOutA"),(PROC)&H_TextOutA,NULL);
            ?}
            }

            ///////////////////////////////////// UnInstallHook 函數 ////////////////////////////////////
            //卸載鉤子
            BOOL WINAPI UnInstallHook()
            {
            ?UnhookWindowsHookEx(hHook);
            ?return TRUE;
            }

            ///////////////////////////////////// H_TextOutA 函數 /////////////////////////////////////////
            //我們的替換函數,可以在里面實現我們所要做的功能
            //這里我做的是顯示一個對話框,指明是替換了哪個函數
            BOOL WINAPI H_TextOutA(HDC hdc,int nXStart,int nYStart,LPCSTR lpString,int cbString)
            {
            ?MessageBox(NULL,"TextOutA","APIHook_Dll ---rivershan",MB_OK);
            ?TextOutA(hdc,nXStart,nYStart,lpString,cbString);//返回原來的函數,以顯示字符
            ?return TRUE;
            }

            ///////////////////////////////////// H_TextOutW 函數 /////////////////////////////////////////
            //同上
            BOOL WINAPI H_TextOutW(HDC hdc,int nXStart,int nYStart,LPCWSTR lpString,int cbString)
            {
            ?MessageBox(NULL,"TextOutW","APIHook_Dll ---rivershan",MB_OK);
            ?TextOutW(hdc,nXStart,nYStart,lpString,cbString);//返回原來的函數,以顯示字符
            ?return TRUE;
            }

            **********************************************************************************************
            **********************************************************************************************

            //////////////////////////////// APIHook_Dll.h ////////////////////////////////////////
            //???????????????????????????? rivershan寫于2002.9.23????????????????????????????????? //
            /////////////////////////////////////////////////////////////////////////////////////////

            //dll頭文件,用于聲明函數

            void __declspec(dllexport) WINAPI InstallHook(BOOL,DWORD);
            BOOL WINAPI UnInstallHook();
            LRESULT CALLBACK GetMsgProC(int code,WPARAM wParam,LPARAM lParam);

            void WINAPI HookOneAPI(LPCTSTR pszCalleeModuleName,PROC pfnOriginApiAddress,
            ??????? PROC pfnDummyFuncAddress,HMODULE hModCallerModule);
            BOOL WINAPI HookAllAPI(LPCTSTR pszCalleeModuleName,PROC pfnOriginApiAddress,
            ??????? PROC pfnDummyFuncAddress,HMODULE hModCallerModule);
            BOOL WINAPI UnhookAllAPIHooks(LPCTSTR pszCalleeModuleName,PROC pfnOriginApiAddress,
            ???????? PROC pfnDummyFuncAddress,HMODULE hModCallerModule);

            BOOL WINAPI H_TextOutA(HDC, int, int, LPCSTR, int);
            BOOL WINAPI H_TextOutW(HDC, int, int, LPCWSTR, int);
            BOOL WINAPI H_ExtTextOutA(HDC, int, int, UINT, CONST RECT *,LPCSTR, UINT, CONST INT *);
            BOOL WINAPI H_ExtTextOutW(HDC, int, int, UINT, CONST RECT *,LPCWSTR, UINT, CONST INT *);

            **********************************************************************************************
            **********************************************************************************************

            ;APIHook_Dll之def文件
            LIBRARY APIHook_Dll.dll
            EXPORT
            ?InstallHook
            ?
            二、APIHOOK之exe部分

            //////////////////////////// APIHook_EXEDlg.cpp /////////////////////////////////////////
            //???????????????????????????? rivershan寫于2002.9.23????????????????????????????????? //
            /////////////////////////////////////////////////////////////////////////////////////////


            #include "stdafx.h"
            #include "APIHook_EXE.h"
            #include "APIHook_EXEDlg.h"
            #include "APIHook_Dll.h"

            #ifdef _DEBUG
            #define new DEBUG_NEW
            #undef THIS_FILE
            static char THIS_FILE[] = __FILE__;
            #endif

            /////////////////////////////////////////////////////////////////////////////
            // CAPIHook_EXEDlg dialog

            CAPIHook_EXEDlg::CAPIHook_EXEDlg(CWnd* pParent /*=NULL*/)
            : CDialog(CAPIHook_EXEDlg::IDD, pParent)
            {
            ?//{{AFX_DATA_INIT(CAPIHook_EXEDlg)
            ?// NOTE: the ClassWizard will add member initialization here
            ?//}}AFX_DATA_INIT
            ?// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
            ?m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
            }

            void CAPIHook_EXEDlg::DoDataExchange(CDataExchange* pDX)
            {
            ?CDialog::DoDataExchange(pDX);
            ?//{{AFX_DATA_MAP(CAPIHook_EXEDlg)
            ?//?DDX_Control(pDX, IDC_EDIT1, m_Edit);
            ?//}}AFX_DATA_MAP
            }

            BEGIN_MESSAGE_MAP(CAPIHook_EXEDlg, CDialog)
            //{{AFX_MSG_MAP(CAPIHook_EXEDlg)
            ON_WM_PAINT()
            ON_WM_QUERYDRAGICON()
            ?ON_BN_CLICKED(IDC_BUTTON_OUT, OnButtonOut)
            ?ON_BN_CLICKED(IDC_BUTTON_BEGIN, OnButtonBegin)
            ?ON_BN_CLICKED(IDC_BUTTON_STOP, OnButtonStop)
            ?//}}AFX_MSG_MAP
            END_MESSAGE_MAP()

            /////////////////////////////////////////////////////////////////////////////
            // CAPIHook_EXEDlg message handlers

            BOOL CAPIHook_EXEDlg::OnInitDialog()
            {
            ?CDialog::OnInitDialog();
            ?
            ?// Set the icon for this dialog.? The framework does this automatically
            ?// when the application's main window is not a dialog
            ?SetIcon(m_hIcon, TRUE);???// Set big icon
            ?SetIcon(m_hIcon, FALSE);??// Set small icon
            ?
            ?// TODO: Add extra initialization here
            ?
            ?return TRUE;? // return TRUE? unless you set the focus to a control
            }

            // If you add a minimize button to your dialog, you will need the code below
            //? to draw the icon.? For MFC applications using the document/view model,
            //? this is automatically done for you by the framework.

            void CAPIHook_EXEDlg::OnPaint()?
            {
            ?if (IsIconic())
            ?{
            ??CPaintDC dc(this); // device context for painting
            ??
            ??SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
            ??
            ??// Center icon in client rectangle
            ??int cxIcon = GetSystemMetrics(SM_CXICON);
            ??int cyIcon = GetSystemMetrics(SM_CYICON);
            ??CRect rect;
            ??GetClientRect(&rect);
            ??int x = (rect.Width() - cxIcon + 1) / 2;
            ??int y = (rect.Height() - cyIcon + 1) / 2;
            ??
            ??// Draw the icon
            ??dc.DrawIcon(x, y, m_hIcon);
            ?}
            ?else
            ?{
            ??CDialog::OnPaint();
            ?}
            }

            // The system calls this to obtain the cursor to display while the user drags
            //? the minimized window.
            HCURSOR CAPIHook_EXEDlg::OnQueryDragIcon()
            {
            ?return (HCURSOR) m_hIcon;
            }
            ///////////////////////////////////// OnButtonOut 函數 //////////////////////////////////////
            //使用TextOut函數
            void CAPIHook_EXEDlg::OnButtonOut()?
            {
            ?// TODO: Add your control notification handler code here
            ?HDC hdc = ::GetDC(GetSafeHwnd());
            ?::TextOutA(hdc,0,0,"APIHOOK_EXE ---rivershan",30);
            ?UpdateWindow();
            }

            ///////////////////////////////////// OnButtonBegin 函數 ////////////////////////////////////
            //開始掛鉤,這里我們掛的是自身這個APIHook_EXE這個程序
            void CAPIHook_EXEDlg::OnButtonBegin()
            {
            ?DWORD dwThreadId = GetWindowThreadProcessId(m_hWnd,NULL);//獲得自身進程ID
            ?InstallHook(TRUE,dwThreadId);
            }

            ///////////////////////////////////// OnButtonStop 函數 ////////////////////////////////////
            //取消掛鉤
            void CAPIHook_EXEDlg::OnButtonStop()
            {
            ?InstallHook(FALSE,0);
            }

            三、APIHOOK之集成

            1. 用 VC++新建一個 Win32 Dynamic-Link Library 程序,命名為 APIHook_Dll。接下來選擇第二項 A Simple DLL Project;
            2. 新建一頭文件,命名為 APIHook_Dll.h。刪除工程中 APIHook_Dll.cpp文件中原來的內容,然后把上面的 APIHook_Dll.cpp 和 APIHook_Dll.h文件的內容全部復制到新建的這個工程的 .cpp及 .h文件中來;
            3. 新建一 Text文件,命名為 APIHook_Dll.def。復制上面的def文件內容。
            4. 編譯;
            5. 新建一 MFC APPWizard(exe)程序,命名為 APIHook_EXE。接著選擇第三項,基于對話框的程序,其它默認;
            6. 刪除原來對話框上的控件,然后新建三個按鈕ID分別為:IDC_BUTTON_BEGIN、IDC_BUTTON_STOP、IDC_BUTTON_OUT,Caption分別為:Bigin Hook、Stop Hook、Text Out。不要讓這三個按鈕出于對話框客戶區的最上面就行;
            7. 拷貝 APIHook_Dll.h文件到 APIHook_EXE程序目錄下,然后加到 APIHook_EXE的頭文件夾中。
            8. 刪除工程中 APIHook_EXEDlg.cpp文件中原來的內容,然后把上面的 APIHook_EXEDlg.cpp文件的內容全部復制到新建的這個工程的 .cpp文件中來;
            9. 打開 Project->Setting菜單,選擇第四項link,在 Object/library moduls里添加我們的dll的lib文件的路徑:..\APIHook_Dll\Debug\APIHook_Dll.lib;
            10. 編譯;
            11. 把 APIHook_Dll.dll文件放在 APIHook_Dll.exe程序的同一個文件夾內;
            12. 運行程序,點擊 Bigin Hook按鈕,開始掛鉤。再點擊 Text Out按鈕會跳出對話框并且會在程序中顯示所要顯示的字。點擊 Stop Hook然后在點擊 Text Out按鈕就沒有對話框出現了。

            四、一些說明

            1、我這個 HookAPI是使用了 Jeffrey Richter的改寫程序的 IAT來實現的,也可以用跳轉函數入口點的方法來實現,這個我沒做研究。:)

            2、我的一些心得:

            ?所謂 HookAPI,就是改寫程序的 IAT,再調用我自己寫的用于替換原API函數的函數。在我們自己寫的API函數中,我們可以進行我們想要的工作。之后呢,可以把原來的函數傳回去,也可以不傳回去,只要你設計好了就行。

            ?而所謂調用自己的函數,就是把原函數參數都傳給我的替換函數。我們就可以利用這些參數去干我們想做的事。而系統呢,我想由于微軟設置的這個鉤子的目的(我這么認為的),所以不會去檢查替換函數是否就是原函數,只要參數、返回值符合條件就行,要不會出錯。替換函數的返回值最好是原函數,否則有可能會出錯

            ?HookAPI時,exe程序起到的作用就是進行Hook,把dll注入到要Hook的程序,并且傳回要掛接的進程的ID或者全局鉤子,以便查詢所要掛接的模塊的IAT。如果不注入進去,系統不會讓你去查詢IAT的。DLL做的事情是確定要掛接哪個函數和這個函數在哪個DLL中等。

            ?????????????????????????????????????????????????????????????????????????????? ?rivershan 原創于 2002-9-23

            2021国产精品久久精品| 久久久久人妻一区二区三区vr| 国产精品久久波多野结衣| 精品蜜臀久久久久99网站| 亚洲成人精品久久| 欧美激情精品久久久久久久九九九 | 亚洲精品第一综合99久久| 午夜精品久久久久久影视777 | 韩国三级大全久久网站| 久久精品国产亚洲麻豆| 久久久这里有精品中文字幕| 色综合久久中文字幕无码| 久久久91人妻无码精品蜜桃HD| 日韩乱码人妻无码中文字幕久久| 精品国产青草久久久久福利| 午夜精品久久久久久久久| 日本久久久久久久久久| 99久久www免费人成精品| 亚洲va久久久噜噜噜久久男同| 久久精品国产黑森林| 91精品国产综合久久精品| 少妇内射兰兰久久| 色婷婷久久综合中文久久一本| 2021久久国自产拍精品| 新狼窝色AV性久久久久久| 久久婷婷五月综合成人D啪| 久久这里有精品视频| 久久激情亚洲精品无码?V| 久久青青草原综合伊人| 99久久成人国产精品免费| 久久精品国产99久久无毒不卡| 久久久久免费精品国产| 99久久综合国产精品免费| 99久久免费国产精品特黄| 久久亚洲国产最新网站| 伊人久久成人成综合网222| 久久无码中文字幕东京热| 久久亚洲AV无码精品色午夜| 婷婷国产天堂久久综合五月| 中文字幕无码久久精品青草| 久久婷婷五月综合97色直播|