本人最近在学习HOOK技术,想利用HOOK技术捕获文件打开操作同时用自己写的函数替换原函数主要是CreateFileA和CreateFileW。主要参考的是王艳平编写的《windows程序设计》第九章和第十章的代码分别是09HookTermProLib代码09HookTermProApp还有10IPPackLib主要参考第十章的IPPackLib类方式进行函数地址替换和第九章的方式挂载全局钩子但是我在运行代码的时候发现在运行过程中会导致explorer崩溃。
ULHookLib项目文件包括ULHook.h、ConFile.h、ULHook.cpp、ConFile.cpp ConFile.def
//////////////////////////////////////////////////////////
// ULHook.h#ifndef __ULHOOK_H__
#define __ULHOOK_H__#include <windows.h>class CULHook
{
public:
CULHook(LPSTR pszModName, LPSTR pszFuncName, PROC pfnHook);
~CULHook();
// 取消挂钩
void Unhook();
// 重新挂钩
void Rehook();
protected:
PROC m_pfnOrig; // 目标API函数的地址
BYTE m_btNewBytes[8];  // 新构建的8个字节
BYTE m_btOldBytes[8];  // 原来8个字节
HMODULE m_hModule;
};#endif // __ULHOOK_H__
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// ULHook.cpp文件
#include "ULHook.h"
CULHook::CULHook(LPSTR pszModName, LPSTR pszFuncName, PROC pfnHook)
{// jmp eax == 0xFF, 0xE0
// 生成新的执行代码
BYTE btNewBytes[8] = { 0xB8, 0x00, 0x00, 0x40, 0x00, 0xFF, 0xE0, 0x00 };  
memcpy(m_btNewBytes, btNewBytes, 8);
*(DWORD *)(m_btNewBytes + 1) = (DWORD)pfnHook;  // 加载指定模块,取得API函数地址
m_hModule = ::LoadLibrary(pszModName);
if(m_hModule == NULL)
{
m_pfnOrig = NULL;
return;
}
m_pfnOrig = ::GetProcAddress(m_hModule, pszFuncName);
// 修改原API函数执行代码的前8个字节,使它跳向我们的函数
if(m_pfnOrig != NULL)
{
DWORD dwOldProtect;
MEMORY_BASIC_INFORMATION mbi;
::VirtualQuery( m_pfnOrig, &mbi, sizeof(mbi) );
::VirtualProtect(m_pfnOrig, 8, PAGE_READWRITE, &dwOldProtect);// 保存原来的执行代码
memcpy(m_btOldBytes, m_pfnOrig, 8);
// 写入新的执行代码
::WriteProcessMemory(::GetCurrentProcess(), (void *)m_pfnOrig,  
m_btNewBytes, sizeof(DWORD)*2, NULL);  ::VirtualProtect(m_pfnOrig, 8, mbi.Protect, 0);
}
}CULHook::~CULHook()
{
Unhook();
if(m_hModule != NULL)
::FreeLibrary(m_hModule);
}void CULHook::Unhook()
{
if(m_pfnOrig != NULL)
{
DWORD dwOldProtect;
MEMORY_BASIC_INFORMATION mbi;
::VirtualQuery(m_pfnOrig, &mbi, sizeof(mbi));
::VirtualProtect(m_pfnOrig, 8, PAGE_READWRITE, &dwOldProtect);// 写入原来的执行代码
::WriteProcessMemory(::GetCurrentProcess(), (void *)m_pfnOrig,  
m_btOldBytes, sizeof(DWORD)*2, NULL);  ::VirtualProtect(m_pfnOrig, 8, mbi.Protect, 0);
}
}void CULHook::Rehook()
{
// 修改原API函数执行代码的前8个字节,使它跳向我们的函数
if(m_pfnOrig != NULL)
{
DWORD dwOldProtect;
MEMORY_BASIC_INFORMATION mbi;
::VirtualQuery( m_pfnOrig, &mbi, sizeof(mbi) );
::VirtualProtect(m_pfnOrig, 8, PAGE_READWRITE, &dwOldProtect);// 写入新的执行代码
::WriteProcessMemory(::GetCurrentProcess(), (void *)m_pfnOrig,  
m_btNewBytes, sizeof(DWORD)*2, NULL);  ::VirtualProtect(m_pfnOrig, 8, mbi.Protect, 0);
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
ConFile.h
///////////////////
#ifndef _CONFILE_H__
#define _CONFILE_H__#endif
/////////////////////////////////////////
ConFile.cpp
////////////////////////////////////////////////////////////////////////////////////
#include "ULHook.h"
#include "ConFile.h"
#include<windows.h>
#pragma comment(lib,"Kernel32")#pragma data_seg("YCIShared")
HHOOK g_hHook=NULL;
#pragma data_seg()//extern CULHook g_OpenFile;
extern CULHook g_CreateFileA;
extern CULHook g_CreateFileW;HANDLE WINAPI Hook_CreateFileA(
  LPCTSTR lpFileName,  // pointer to name of the file
  DWORD dwDesiredAccess,  // access (read-write) mode
  DWORD dwShareMode,  // share mode
  LPSECURITY_ATTRIBUTES lpSecurityAttributes,  // pointer to security attributes
  DWORD dwCreationDisposition,  // how to create
  DWORD dwFlagsAndAttributes,  // file attributes
  HANDLE hTemplateFile  // handle to file with attributes to  
  )
{
//typedef HANDLE (WINAPI *PFNCREATEFILEA)(LPCTSTR,DWORD,DWORD,LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE);
// ::MessageBox(NULL,lpFileName,"1",MB_OK);
g_CreateFileA.Unhook();
HANDLE hand=CreateFileA(lpFileName,dwDesiredAccess,dwShareMode,lpSecurityAttributes,dwCreationDisposition,dwFlagsAndAttributes,hTemplateFile);
g_CreateFileA.Rehook();
return hand;}HANDLE WINAPI Hook_CreateFileW(
  LPCWSTR lpFileName,  // pointer to name of the file
  DWORD dwDesiredAccess,  // access (read-write) mode
  DWORD dwShareMode,  // share mode
  LPSECURITY_ATTRIBUTES lpSecurityAttributes,  // pointer to security attributes
  DWORD dwCreationDisposition,  // how to create
  DWORD dwFlagsAndAttributes,  // file attributes
  HANDLE hTemplateFile  // handle to file with attributes to  
  // copy
)
 {
//typedef HANDLE (WINAPI *PFNCREATEFILEW)(LPCWSTR,DWORD,DWORD,LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE);
// ::MessageBoxW(NULL,lpFileName,L"1",MB_OK);
g_CreateFileW.Unhook();
HANDLE hand=CreateFileW(lpFileName,dwDesiredAccess,dwShareMode,lpSecurityAttributes,dwCreationDisposition,dwFlagsAndAttributes,hTemplateFile);
g_CreateFileW.Rehook();
return hand;
//return ((PFNCREATEFILEW)(PROC)g_CreateFileW)(lpFileName,dwDesiredAccess,dwShareMode,lpSecurityAttributes,dwCreationDisposition,dwFlagsAndAttributes,hTemplateFile); }
CULHook g_CreateFileA("kernel32.dll","CreateFileA",(PROC)Hook_CreateFileA);
CULHook g_CreateFileW("kernel32.dll","CreateFileW",(PROC)Hook_CreateFileW);/*static HFILE (WINAPI *OrgOpenFile)
(LPCSTR lpFileName,
  LPOFSTRUCT lpReOpenBuff,
  UINT uStyle
 )=OpenFile;
HFILE WINAPI Hook_OpenFile(
  LPCSTR lpFileName,
  LPOFSTRUCT lpReOpenBuff,
  UINT uStyle
)
{
::MessageBox(NULL,lpFileName,"1",MB_OK);
g_OpenFile.Unhook();HFILE file=OrgOpenFile(lpFileName,lpReOpenBuff,uStyle);
g_OpenFile.Rehook();
return file;
}
CULHook g_OpenFile("kernel32","OpenFile",(PROC)Hook_OpenFile);*/
static HMODULE ModuleFromAddress(PVOID pv)  
{
MEMORY_BASIC_INFORMATION mbi;
if(::VirtualQuery(pv, &mbi, sizeof(mbi)) != 0)
{
return (HMODULE)mbi.AllocationBase;
}
else
{
return NULL;
}
}static LRESULT WINAPI GetMsgProc(int code, WPARAM wParam, LPARAM lParam)  
{
return ::CallNextHookEx(g_hHook, code, wParam, lParam);
}BOOL WINAPI SetSysHook(BOOL bInstall, DWORD dwThreadId)
{
BOOL bOk;
if(bInstall)  
{
g_hHook = ::SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc,  
ModuleFromAddress(GetMsgProc), dwThreadId);
bOk = (g_hHook != NULL);
}  
else  
{
bOk = ::UnhookWindowsHookEx(g_hHook);
g_hHook = NULL;
}
return bOk;
}
/////////////////////////////////////////////////////////////////////////////////////