主题:<windows核心编程>上ApiHook.cpp 问题
/***********************************************************************
Module: APIHook.cpp
Notices: Copyright (c) 2000 Jeffrey Richter
***********************************************************************/
#include "..\CmnHdr.h"
#include <ImageHlp.h >
#pragma comment(lib, "ImageHlp")
#include "APIHook.h"
#include "..\04-ProcessInfo\Toolhelp.h"
///////////////////////////////////////////////////////////////////////
// When an application runs on Windows 98 under a debugger, the debugger
// makes the module 's import section point to a stub that calls the
desired 看不太明白,98下到底怎么了?
// function. To account for this, the code in this module must do some
crazy
// stuff. These variables are needed to help with the crazy stuff.
// The highest private memory address (used for Windows 98 only)
PVOID CAPIHook::sm_pvMaxAppAddr = NULL;
const BYTE cPushOpCode = 0x68; // The PUSH opcode on x86 platforms
////////////////////////////////////////////////////////////////////////
// The head of the linked-list of CAPIHook objects
CAPIHook* CAPIHook::sm_pHead = NULL;
////////////////////////////////////////////////////////////////////////
CAPIHook::CAPIHook(PSTR pszCalleeModName, PSTR pszFuncName, PROC pfnHook,
BOOL fExcludeAPIHookMod) {
if (sm_pvMaxAppAddr == NULL) {
// Functions with address above lpMaximumApplicationAddress require
// special processing (Windows 98 only)
SYSTEM_INFO si;
GetSystemInfo(&si);
sm_pvMaxAppAddr = si.lpMaximumApplicationAddress;
}
m_pNext = sm_pHead; // The next node was at the head
sm_pHead = this; // This node is now at the head
// Save information about this hooked function
m_pszCalleeModName = pszCalleeModName;
m_pszFuncName = pszFuncName;
m_pfnHook = pfnHook;
m_fExcludeAPIHookMod = fExcludeAPIHookMod;
m_pfnOrig = GetProcAddressRaw(
GetModuleHandleA(pszCalleeModName), m_pszFuncName);
chASSERT(m_pfnOrig != NULL); // Function doesn 't exist
if (m_pfnOrig > sm_pvMaxAppAddr) {
// The address is in a shared DLL; the address needs fixing up
//我知道98下的DLL共享, fixing up 具体是怎么回事?
PBYTE pb = (PBYTE) m_pfnOrig;
if (pb[0] == cPushOpCode) {
// Skip over the PUSH op code and grab the real address
上面注释的操作原理是什么?
PVOID pv = * (PVOID*) &pb[1];
m_pfnOrig = (PROC) pv;
}
}
// Hook this function in all currently loaded modules
ReplaceIATEntryInAllMods(m_pszCalleeModName, m_pfnOrig, m_pfnHook,
m_fExcludeAPIHookMod);
}
注:GetProcAddressRaw其实就是GetProcAddress
比如我们要HOOK的API是fApi,它的地址是AddApi. 我们的替换函数地址是AddHook .
(98下)调试器首先修改了IAT , 将AddApi改为AddDebugger .
看书上代码, 在IAT中并不是按函数名fApi来进行搜索, 而是用GetProcAddress(fApi)
获取fApi的地址AddApi, 再从IAT中寻找这个地址值(AddApi) , 找到了将该值后将其修改为AddHook.
现在, 由于AddApi已被调试器改成了AddDebugger ,而我们执行GetProcAddress(fApi)
获得的仍然是AddApi . 怎么办呢 ? 只能是设法知道AddDebugger是多少.
书上获取AddDebugger的方法我实在是想不明白其原理 :
查看AddApi处的第一条指令是不是push, 如是, 则push内容即为AddDebugger ...
欢迎大家讨论,指教!
Module: APIHook.cpp
Notices: Copyright (c) 2000 Jeffrey Richter
***********************************************************************/
#include "..\CmnHdr.h"
#include <ImageHlp.h >
#pragma comment(lib, "ImageHlp")
#include "APIHook.h"
#include "..\04-ProcessInfo\Toolhelp.h"
///////////////////////////////////////////////////////////////////////
// When an application runs on Windows 98 under a debugger, the debugger
// makes the module 's import section point to a stub that calls the
desired 看不太明白,98下到底怎么了?
// function. To account for this, the code in this module must do some
crazy
// stuff. These variables are needed to help with the crazy stuff.
// The highest private memory address (used for Windows 98 only)
PVOID CAPIHook::sm_pvMaxAppAddr = NULL;
const BYTE cPushOpCode = 0x68; // The PUSH opcode on x86 platforms
////////////////////////////////////////////////////////////////////////
// The head of the linked-list of CAPIHook objects
CAPIHook* CAPIHook::sm_pHead = NULL;
////////////////////////////////////////////////////////////////////////
CAPIHook::CAPIHook(PSTR pszCalleeModName, PSTR pszFuncName, PROC pfnHook,
BOOL fExcludeAPIHookMod) {
if (sm_pvMaxAppAddr == NULL) {
// Functions with address above lpMaximumApplicationAddress require
// special processing (Windows 98 only)
SYSTEM_INFO si;
GetSystemInfo(&si);
sm_pvMaxAppAddr = si.lpMaximumApplicationAddress;
}
m_pNext = sm_pHead; // The next node was at the head
sm_pHead = this; // This node is now at the head
// Save information about this hooked function
m_pszCalleeModName = pszCalleeModName;
m_pszFuncName = pszFuncName;
m_pfnHook = pfnHook;
m_fExcludeAPIHookMod = fExcludeAPIHookMod;
m_pfnOrig = GetProcAddressRaw(
GetModuleHandleA(pszCalleeModName), m_pszFuncName);
chASSERT(m_pfnOrig != NULL); // Function doesn 't exist
if (m_pfnOrig > sm_pvMaxAppAddr) {
// The address is in a shared DLL; the address needs fixing up
//我知道98下的DLL共享, fixing up 具体是怎么回事?
PBYTE pb = (PBYTE) m_pfnOrig;
if (pb[0] == cPushOpCode) {
// Skip over the PUSH op code and grab the real address
上面注释的操作原理是什么?
PVOID pv = * (PVOID*) &pb[1];
m_pfnOrig = (PROC) pv;
}
}
// Hook this function in all currently loaded modules
ReplaceIATEntryInAllMods(m_pszCalleeModName, m_pfnOrig, m_pfnHook,
m_fExcludeAPIHookMod);
}
注:GetProcAddressRaw其实就是GetProcAddress
比如我们要HOOK的API是fApi,它的地址是AddApi. 我们的替换函数地址是AddHook .
(98下)调试器首先修改了IAT , 将AddApi改为AddDebugger .
看书上代码, 在IAT中并不是按函数名fApi来进行搜索, 而是用GetProcAddress(fApi)
获取fApi的地址AddApi, 再从IAT中寻找这个地址值(AddApi) , 找到了将该值后将其修改为AddHook.
现在, 由于AddApi已被调试器改成了AddDebugger ,而我们执行GetProcAddress(fApi)
获得的仍然是AddApi . 怎么办呢 ? 只能是设法知道AddDebugger是多少.
书上获取AddDebugger的方法我实在是想不明白其原理 :
查看AddApi处的第一条指令是不是push, 如是, 则push内容即为AddDebugger ...
欢迎大家讨论,指教!