还是没弄会,,连日记也没心情写,,看了pe的文章,,<<箴言>>里的程序都没注释,,梁这不是打自己嘴巴子么?也不替我们这样的新手考虑考虑,,写书干嘛呀,,难道就让我知道这些你早逗会了?? 哎,,发啥牢骚啊,,毕竟自己从梁大哥那里学了不少 :) 今天hook还是没成功,,已经是第2中方法了,,把他的程序给做了遍注释,,程序倒是理解了,,可不成功的原因没找到,,,估计自己还算不上理解 :(
#include "stdio.h"
#include "windows.h"
#include "imagehlp.h"
#include "tlhelp32.h"
#pragma comment(lib,"imagehlp.lib")
#pragma comment(lib,"kernel32.lib")
typedef struct _APIHOOK32_ENTRY
{
LPCTSTR pszAPINAme;
LPCTSTR pszCAllerModuleNAme;
PROC pfnOriginApiAddress;
PROC pfnDummyFuncAddress;
HMODULE hModCAllerModule;
}APIHOOK32_ENTRY,*PAPIHOOK32_ENTRY;
BOOL _SetApiHookUp(PAPIHOOK32_ENTRY phk)
{
PIMAGE_THUNK_DATA pThunk;
ULONG size;
//每个IMAGE_IMPORT_DESCRIPTOR代表一个DLL,这里的 pImportDesc 为NULL是表示遍历了所有的引入的DLL
PIMAGE_IMPORT_DESCRIPTOR pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)ImageDirectoryEntryToData(
phk->hModCAllerModule ,
TRUE,
IMAGE_DIRECTORY_ENTRY_IMPORT,
&size);
if (pImportDesc == NULL){
return FALSE;
}
//遍历DLL,,第一层循环
for(;pImportDesc->Name ;pImportDesc++){
//这里不理解,,为什么要把pImportDesc->NAme和phk->hModCAllerModule加起来
//IMAGE_DESCRIPTOR中的NAme是一个RVA指向一个ASCII字符串,是dll的名字,,那下面这句就更不理解了
PSTR pszDllNAme = (LPSTR)((PBYTE)phk->hModCAllerModule + pImportDesc->Name );////哈哈,,单步时这里果然和我想的一样,,加上基址后变为虚拟地址,,然后,,比如这次把 其值就是 0x77ebcd79 "NTDLL.DLL"
//这样比较肯定不相等了啊
//找到相等的后 :(
if (strcmp(pszDllNAme,phk->pszCAllerModuleNAme )==0) break;
}
//看是否真的找到了
if (pImportDesc->Name == NULL){
return FALSE;
}
//IMAGE_IMPORT_DESCRIPTOR结构里的FirstThunk指向一个DWORD数组,每个DWORD都是一个RVA,是输入函数的入口地址,这个数组可以叫输入地址表
//现在关键是弄清楚phk->hModCAllerModule到底是个什么???????????????????????????
//大概是这样吧,,phk->hModCAllerModule是个HMODULE类型,,也许是通过它把RVA变成真实的虚拟地址吧,,它起了个加载基址的作用,,
//哎 不知道对不对,,看看它的值才知道
pThunk = (PIMAGE_THUNK_DATA)((PBYTE)phk->hModCAllerModule + pImportDesc->FirstThunk );//IAT
//现在开始是第2层循环 IMAGE_THUNK_DATA 结构如下
//* typedef struct _IMAGE_THUNK_DATA32 {
//* union {
//* PBYTE ForwarderString;
//* PDWORD Function;
//* DWORD Ordinal;
//* PIMAGE_IMPORT_BY_NAME AddressOfData;
//* } u1;
//* } IMAGE_THUNK_DATA32;
//*typedef IMAGE_THUNK_DATA32 * PIMAGE_THUNK_DATA32;
//这里不懂,,PThunk指向一个DWORD数组,在遍历时应该用pThunk++吗?好象也可以,,但自己不清楚,,
//因为pThunk里面就一个u1,pThunk->u1.Function++等于pThunk++吗??????????
for (;pThunk->u1 .Function ;pThunk++){
PROC* ppfn = (PROC*)&pThunk->u1 .Function ;
//做比较,,看是否是要找的函数,,如果是,,就把地址改写
if(*ppfn == phk->pfnOriginApiAddress ){
WriteProcessMemory(GetCurrentProcess(),
ppfn,
&(phk->pfnDummyFuncAddress),
sizeof(phk->pfnDummyFuncAddress ),
NULL);
return TRUE;
}
}
return TRUE;
}
//------------------------------------------------------------------------------
BOOL SetWindowsAPIHook(PAPIHOOK32_ENTRY phk)
{
//The MEMORY_BASIC_INFORMATION structure contains information about a range of pages
//in the virtual address space of a process. The VirtualQuery and VirtualQueryEx
// functions use this structure :)
//*typedef struct _MEMORY_BASIC_INFORMATION { // mbi
//* PVOID BaseAddress; // base address of region
//* PVOID AllocationBase; // allocation base address
//* DWORD AllocationProtect; // initial access protection
//* DWORD RegionSize; // size, in bytes, of region
//* DWORD State; // committed, reserved, free
//* DWORD Protect; // current access protection
//* DWORD Type; // type of pages
//*} MEMORY_BASIC_INFORMATION;
//*typedef MEMORY_BASIC_INFORMATION *PMEMORY_BASIC_INFORMATION;
MEMORY_BASIC_INFORMATION mInfo;
HMODULE hModHookDll;
HANDLE hSnApShot;
BOOL bOk;
//Describes an entry from a list that enumerates the modules used by a specified process.
//*typedef struct tagMODULEENTRY32 {
//* DWORD dwSize;
//* DWORD th32ModuleID;
//* DWORD th32ProcessID;
//* DWORD GlblcntUsage;
//* DWORD ProccntUsage;
//* BYTE * modBaseAddr;
//* DWORD modBaseSize;
//* HMODULE hModule;
//* char szModule[MAX_MODULE_NAME32 + 1];
//* char szExePath[MAX_PATH];
//*} MODULEENTRY32;
//*typedef MODULEENTRY32 * PMODULEENTRY32;
//*typedef MODULEENTRY32 * LPMODULEENTRY32;
MODULEENTRY32 me = {sizeof(MODULEENTRY32)};
if (phk->pszAPINAme == NULL||phk->pszCAllerModuleNAme == NULL
||phk->pfnOriginApiAddress == NULL){
return FALSE;
}
//如果phk->hModCAllerModule 是 NULL 的话,,表示hook自己??还得往下看才知道 :)
if (phk->hModCAllerModule == NULL){
//取得从_SetApiHookUp地址开始的一个页面的信息
VirtualQuery(_SetApiHookUp,&mInfo,sizeof(mInfo));
//得到函数_SetApiHookUp的地址
hModHookDll = (HMODULE)mInfo.AllocationBase ;///我靠! 没错,,逗是基址 单步的时候看到这里是0x00400000
//快照,,以前在pslist里用过的 :)
//TH32CS_SNAPMODULE Includes the module list of the specified process in the snapshot.
//还好,,:) 是在指定进程内的
hSnApShot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,0);
//找到一个了 :)
//这个循环看上去很疯狂啊
//只要不是自己所在的MODULE,全都给_SetApiHookUp一遍,,但全是本进程的
//me.hModule是Handle to the module in the context of the owning process.
//那它是不是地址呢???????如果不是的话,,那上边的那个问题怎么解决???
//(pThunk = (PIMAGE_THUNK_DATA)((PBYTE)phk->hModCAllerModule + pImportDesc->FirstThunk );)
bOk = Module32First(hSnApShot,&me);////单步时,,me.hModule是0x00400000 恩,,基址,,没错
while(bOk){
if (me.hModule != hModHookDll){ ////单步时 第一次me.hModule和hModHookDll都是0x00400000可能这时是同一个Module,第2次就不一样了,,开始是本进程中的其他Module了 :)
phk->hModCAllerModule = me.hModule ;
_SetApiHookUp(phk);
}
bOk = Module32Next(hSnApShot,&me);
}
phk->hModCAllerModule = NULL;
return FALSE;
}else{
//如果指定了phk->hModCAllerModule的话,,就不会随便_SetApiHookUp
return _SetApiHookUp(phk);
}
return FALSE;
}
//------------------------------------------------------------------------------
BOOL UnhookWindowsAPIHooks(PAPIHOOK32_ENTRY lpHk)
{
//整个一个逆过程 :) pfnOriginApiAddress 和 pfnDummyFuncAddress调个个儿
PROC temp;
temp = lpHk->pfnOriginApiAddress ;
lpHk->pfnOriginApiAddress = lpHk->pfnDummyFuncAddress ;
lpHk->pfnDummyFuncAddress = temp;
return SetWindowsAPIHook(lpHk);
}
//------------------------------------------------------------------------------
//保存原地址
PROC lpAdder = MessageBoxA;
int WINAPI MyMessAgeBoxA(HWND hWnd,LPCTSTR lpText,LPCTSTR lpCAption,UINT uType)
{
return lpAdder(NULL,"new","new",MB_OK);
}
//------------------------------------------------------------------------------
int main(void)
{
//哈哈 终于开始啦
APIHOOK32_ENTRY pe;
pe.pszAPINAme = "MessageBoxA";
pe.pszCAllerModuleNAme = "USER32.DLL";//区分大小写
pe.pfnOriginApiAddress = MessageBoxA;
pe.pfnDummyFuncAddress = MyMessAgeBoxA;
pe.hModCAllerModule = NULL;
//lpAdder = MessageBoxA;
SetWindowsAPIHook(&pe);
MessageBox(NULL,"old","old",MB_OK);
UnhookWindowsAPIHooks(&pe);
MessageBox(NULL,"old","old",MB_OK);
}
//------------------------------------------------------------------------------
博客围绕Windows API Hook展开,作者尝试Hook未成功,对相关程序进行注释并分析。介绍了APIHOOK32_ENTRY结构体,详细阐述了_SetApiHookUp、SetWindowsAPIHook、UnhookWindowsAPIHooks等函数的实现,还给出了示例代码,包含对MessageBoxA函数的Hook和取消Hook操作。
2326

被折叠的 条评论
为什么被折叠?



