首先Hook Api 有两种方法
1) 可以修改指向系统API的地址来达到目的,比如像"user32.dll" "kernel32.dll" 等,这些都是系统已经加载好的dll,如果可以把指向这些dll里API的地址改了就可以达到目的,其实系统的dll空间该不能更改,因为WriteProcessMemory这个函数的前提是不管该内存是否可读都可以进行更改.
2)就是修改模块的入口表,其实就是模块的函数入口表,以此来达到目的.这个也就不多说了,只要知道模块名,还有模块是要调用哪些API就可以了.
下面来看看实例吧[以下引用(Windows核心编程):
首先要确定准备Hook API的原型,这样才可以用自己的方法来代替原来的方法,这不说也该知道的吧.[下面就以Hook GetActiveWindow 为例吧 暂时就先自己Hook 自己吧
(1)先定义与GetActiveWindow相同的方法: typedef HWND (WINAPI * GETACTIVEWINDOW)();
(2)自己建一个dll 建一个MFC Regular Dll是很简单的 还有,一定要在该dll里包含有GetActiveWindow的调用 要不就查找不到了,找不到可怎么Hook 呀 ,有方法的调用,还要用个自己的方法,是准备接手当调用GetActiveWindow时先跑到我这来,至于你是否要再调用GetActiveWindow把返回值给调用者就不管了。 自己的方法就用:myGetActiveWindow吧
(3)在dll里挂个勾子,什么时候挂呢,那就是你想什么时候用你的方法来代替原来的方法就什么时候挂吧 下面是实现勾子的回调方法 怎么建立勾子就不用说了吧
LRESULT CALLBACK GetMsgProc(int code,WPARAM wParam,LPARAM lParam)
{
if(!theApp.isInit) // 因为Hook只需进行一次操作就可以了
{
theApp.isInit=TRUE;
//下面这个theApp.oldProc 这是用来保存旧地址的,要是改了不改回来那程序可就坏了
theApp.oldProc=(GETACTIVEWINDOW)GetProcAddress (GetModuleHandleA("user32"),"GetActiveWindow");
//这个就是新地址了
theApp.newProc=(GETACTIVEWINDOW)GetProcAddress(theApp.m_hInstance,"myGetActiveWindow");//这个函数就是前面提到的 用来代替原GetActiveWindow函数的
//这个就是进行相应改内存地址的操作
theApp.ReplaceIATEntryInMod("user32.dll",theApp.m_hInstance,(PROC)theApp.oldProc,(PROC)theApp.newProc);
}
return CallNextHookEx(theApp.msgHook, code, wParam, lParam);
}
下面是ReplaceIATEntryInMod这个是引用(Windows核心编程)里的:
void dll名字::ReplaceIATEntryInMod(PCSTR pModName,HMODULE hmod,PROC oldProc,PROC newProc)
{
ULONG ulSize;
PIMAGE_IMPORT_DESCRIPTOR pImportDesc=(PIMAGE_IMPORT_DESCRIPTOR)ImageDirectoryEntryToData(hmod,TRUE,IMAGE_DIRECTORY_ENTRY_IMPORT,&ulSize);
if(pImportDesc==NULL)
return;
PSTR pszModName=NULL;
for(;pImportDesc->Name;pImportDesc++)
{
pszModName=(PSTR)((PBYTE)hmod+pImportDesc->Name);
if(lstrcmpiA(pszModName,pModName)==0)
break;
}
if(pImportDesc->Name==0)
return;
PIMAGE_THUNK_DATA pThunk=(PIMAGE_THUNK_DATA)((PBYTE)hmod+pImportDesc->FirstThunk);
for(;pThunk->u1.Function;pThunk++)
{
PROC* ppfn=(PROC*)&pThunk->u1.Function;
BOOL fFound=(*ppfn==oldProc);
if(fFound)
{
if(!WriteProcessMemory(GetCurrentProcess(),ppfn,&newProc,sizeof(newProc),NULL))
{
AfxMessageBox(_T("修改失败"));
}
return;
}
}
}
做完这几步就是加载dll,并启动勾子就行了,还有myGetActiveWindow里怎么写就是自己的事了.
其实为什么要用dll呢,就像这个只针对一个模块的Hook当然不用也行-_-;;;
只是为了以后的Hook系统API做准备吧,因为其它进程要用到你为他准备的函数就只能是共享空间了,而全局勾子就可以做到这一点,全局勾子好像是要做成dll的吧.
唉,说多了...有时间下次再继续吧!!