看了两天PE结构
照两年前看的<advance windows> 抄的 加了点注释
没有写成dll,HOOK自己的ExitProcess(),永远不退出
------------------------------------------
// MyApiHook.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
#include <Dbghelp.h>
#pragma comment(lib,"Dbghelp.lib")
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// TODO: Place code here.
PROC pfnOrig = GetProcAddress(GetModuleHandle("Kernel32"), "ExitProcess");
HMODULE hModCaller = GetModuleHandle("MyApiHook.exe");
void ReplaceIATEntryInOneMod(PCTSTR pszCalleeModName, PROC pfnCurrent, PROC pfnNew, HMODULE hModCaller);
int CALLBACK MyExitProcess();
ReplaceIATEntryInOneMod(
"Kernel32.dll",
pfnOrig,
MyExitProcess,
hModCaller);
return 0;
}
int CALLBACK MyExitProcess()
{
MessageBox(NULL,"HOOK Success!","",MB_OK);
ExitProcess(0);
return 1;
}
//这里PROC定义为无参数,返回值为int的函数指针 typedef int (*PROC)()
//使用的时候要hook只需要给函数名赋值就可以了
void ReplaceIATEntryInOneMod(PCTSTR pszCalleeModName, PROC pfnCurrent, PROC pfnNew, HMODULE hModCaller)
{
ULONG ulSize;
//dump IAT,失败则返回
PIMAGE_IMPORT_DESCRIPTOR pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)ImageDirectoryEntryToData(
hModCaller,
TRUE,
IMAGE_DIRECTORY_ENTRY_IMPORT,
&ulSize);
if(NULL == pImportDesc)
{
return;
}
//遍历导入地址表中有那些模块名称,并与要求操作的模块名称比较,若找到,则提前退出循环
for (;pImportDesc->Name;pImportDesc++)
{
PSTR pszModName = (PSTR)((PBYTE)hModCaller + pImportDesc->Name);
if(0 == lstrcmpiA(pszModName,pszCalleeModName))
break;
}
//该模块并没有导入其他模块
if(0 == pImportDesc->Name)
return;
//取得导入表在内存中的实际映射地址数组
PIMAGE_THUNK_DATA pThunk = (PIMAGE_THUNK_DATA)((PBYTE)hModCaller + pImportDesc->FirstThunk);
//遍历导入表
for (;pThunk->u1.Function;pThunk++)
{
//取得当前导入函数地址
PROC* ppfn = (PROC*) &pThunk->u1.Function;
//判断这个函数是不是我们要hook的对象
BOOL bfFound = (*ppfn == pfnCurrent);
//HOOK掉原来的API地址 把跳转地址改写为我们要执行的函数地址
if (bfFound)
{
WriteProcessMemory(GetCurrentProcess(), ppfn, &pfnNew, sizeof(pfnNew), NULL);
return;
}
}
}