国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
APIHOOK實(shí)例剖析

 APIHOOK實(shí)例剖析收藏

新一篇: 代碼書寫規(guī)范(Java) | 舊一篇: 我的Hook學(xué)習(xí)筆記

                           APIHOOK實(shí)例剖析

 關(guān)于APIHOOK的基礎(chǔ)知識(shí)有很多,如dll的相關(guān)知識(shí)、Hook的相關(guān)知識(shí)、系統(tǒng)進(jìn)程與線程之間的聯(lián)系等。具體可以看我的另兩篇文章:"我的Dll(動(dòng)態(tài)鏈接庫(kù))學(xué)習(xí)筆記" 和 "我的Hook學(xué)習(xí)筆記"。:)下面進(jìn)入這篇文章的重點(diǎn),根據(jù)APIHook源碼進(jìn)行APIHook的剖析。
 
一、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") //定義全局共享數(shù)據(jù)段

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

#pragma data_seg()

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

///////////////////////////////////// DllMain 函數(shù) /////////////////////////////////////////
//dll的入口點(diǎn)
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 函數(shù) /////////////////////////////////////////
//進(jìn)行IAT轉(zhuǎn)換的關(guān)鍵函數(shù),其參數(shù)含義:
//pszCalleeModuleName:需要hook的模塊名
//pfnOriginApiAddress:要替換的自己API函數(shù)的地址
//pfnDummyFuncAddress:需要hook的模塊名的地址
//hModCallerModule:我們要查找的模塊名稱,如果沒有被賦值,
//     將會(huì)被賦值為枚舉的程序所有調(diào)用的模塊

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

 //獲取指向PE文件中的Import中IMAGE_DIRECTORY_DESCRIPTOR數(shù)組的指針

 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;
 }

 //尋找我們想要的函數(shù)

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

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

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

//查找所掛鉤的進(jìn)程所應(yīng)用的dll模塊的

BOOL WINAPI HookAllAPI(LPCTSTR pszCalleeModuleName,PROC pfnOriginApiAddress,
        PROC pfnDummyFuncAddress,HMODULE hModCallerModule)
{
 if (pszCalleeModuleName == NULL)
 {
  return FALSE;
 }
 if (pfnOriginApiAddress == NULL)
 {
  return FALSE;
 }
 //如果沒傳進(jìn)來(lái)要掛鉤的模塊名稱,枚舉被掛鉤進(jìn)程的所有引用的模塊,
 //并對(duì)這些模塊進(jìn)行傳進(jìn)來(lái)的相應(yīng)函數(shù)名稱的查找
 
 if (hModCallerModule == NULL)
 {
  MEMORY_BASIC_INFORMATION mInfo;
  HMODULE hModHookDLL;
  HANDLE hSnapshot;
  MODULEENTRY32 me = {sizeof(MODULEENTRY32)};
  //MODULEENTRY32:描述了一個(gè)被指定進(jìn)程所應(yīng)用的模塊的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:指向當(dāng)前被掛鉤進(jìn)程的每一個(gè)模塊 
    HookOneAPI(pszCalleeModuleName,pfnOriginApiAddress,
     pfnDummyFuncAddress,hModCallerModule);
   }
   bOk = Module32Next(hSnapshot,&me);
  }
  return TRUE;  
 }
 //如果傳進(jìn)來(lái)了,進(jìn)行查找
 else
 {
  HookOneAPI(pszCalleeModuleName,pfnOriginApiAddress,
    pfnDummyFuncAddress,hModCallerModule);
  return TRUE;
 }
 return FALSE;
}

//////////////////////////////////// UnhookAllAPIHooks 函數(shù) /////////////////////////////////////
//通過使pfnDummyFuncAddress與pfnOriginApiAddress相等的方法,取消對(duì)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 函數(shù) ////////////////////////////////////////
//鉤子子程。與其它鉤子子程不大相同,沒做什么有意義的事情,繼續(xù)調(diào)用下一個(gè)鉤子子程,形成循環(huán)
LRESULT CALLBACK GetMsgProc(int code,WPARAM wParam,LPARAM lParam)
{
 return CallNextHookEx(hHook,code,wParam,lParam);
}

//////////////////////////////////// InstallHook 函數(shù) /////////////////////////////////////
//安裝或卸載鉤子,BOOL IsHook參數(shù)是標(biāo)志位
//對(duì)要鉤哪個(gè)API函數(shù)進(jìn)行初始化
//我們這里裝的鉤子類型是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"):取得要鉤的函數(shù)在所在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 函數(shù) ////////////////////////////////////
//卸載鉤子
BOOL WINAPI UnInstallHook()
{
 UnhookWindowsHookEx(hHook);
 return TRUE;
}

///////////////////////////////////// H_TextOutA 函數(shù) /////////////////////////////////////////
//我們的替換函數(shù),可以在里面實(shí)現(xiàn)我們所要做的功能
//這里我做的是顯示一個(gè)對(duì)話框,指明是替換了哪個(gè)函數(shù)
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);//返回原來(lái)的函數(shù),以顯示字符
 return TRUE;
}

///////////////////////////////////// H_TextOutW 函數(shù) /////////////////////////////////////////
//同上
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);//返回原來(lái)的函數(shù),以顯示字符
 return TRUE;
}

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

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

//dll頭文件,用于聲明函數(shù)

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 函數(shù) //////////////////////////////////////
//使用TextOut函數(shù)
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 函數(shù) ////////////////////////////////////
//開始掛鉤,這里我們掛的是自身這個(gè)APIHook_EXE這個(gè)程序
void CAPIHook_EXEDlg::OnButtonBegin()
{
 DWORD dwThreadId = GetWindowThreadProcessId(m_hWnd,NULL);//獲得自身進(jìn)程ID
 InstallHook(TRUE,dwThreadId);
}

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

三、APIHOOK之集成

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

四、一些說明

1、我這個(gè) HookAPI是使用了 Jeffrey Richter的改寫程序的 IAT來(lái)實(shí)現(xiàn)的,也可以用跳轉(zhuǎn)函數(shù)入口點(diǎn)的方法來(lái)實(shí)現(xiàn),這個(gè)我沒做研究。:)

2、我的一些心得:

 所謂 HookAPI,就是改寫程序的 IAT,再調(diào)用我自己寫的用于替換原API函數(shù)的函數(shù)。在我們自己寫的API函數(shù)中,我們可以進(jìn)行我們想要的工作。之后呢,可以把原來(lái)的函數(shù)傳回去,也可以不傳回去,只要你設(shè)計(jì)好了就行。

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

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

                                                                                rivershan 原創(chuàng)于 2002-9-23

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
【Hook技術(shù)】實(shí)現(xiàn)從"任務(wù)管理器"中保護(hù)進(jìn)程不被關(guān)閉 + 附帶源碼 + 進(jìn)程保護(hù)知識(shí)擴(kuò)展
API Hook 原理
C# 實(shí)現(xiàn)對(duì)硬件的控制
給msn messager裝個(gè)鉤子 - 笨笨歷險(xiǎn)記
C# 中調(diào)用C++ DLL (P/Invoke) - 博園雅客 - 求工作,求包養(yǎng) - 博...
VC實(shí)現(xiàn)Win2000下屏蔽Ctrl Alt Del鍵
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服