C++辅导:如何截获API函数

C++辅导:如何截获API函数,第1张

C++辅导:如何截获API函数,第2张

这个程序基于HOOK原理,主要是把自己的函数放在目标进程的地址空里。在这里,它是通过使用钩子来实现的。先构建一个鼠标的钩子程序,然后在全局鼠标钩子的DLL中做拦截,可以在PROCESS_ATTACH期间做,也可以在鼠标的钩子链函数中做。

设置全局钩子我就不说了,网上很多地方都可以看到。主要是拦截动作。我通过PE格式调用时改变API函数的地址(使用IMAGE)。DLL部分引用了以下代码:
static int winapi mymessageboxw(hwnd hwnd,lpcwstr lptext,Lpstr lpcaption,uintype)//own MessageBoxW函数
{return messagebox (hwnd," TNT"/* lptext */," TNT"/* lpcaption */,utype);
}
我定义了一个结构
typedef struct tag _ hook API
{
LPC str SZ func;//要挂钩的API函数名
PROC pNewProc;//新的函数指针
PROC pold PROC;//旧函数指针
}HOOKAPI,* LPHOOKAPI

extern " C " _ _ declspec(dll export)PIMAGE _ IMPORT _ DESCRIPTOR GetNamedImportDescriptor(HMODULE HMODULE,Lptr sziportmod)
{
/首先,DOS header
PIMAGE _ DOS _ header PDO header =(PIMAGE _ DOS _ header)HMODULE;
if(PDO header-> e _ magic!= IMAGE_DOS_SIGNATURE)返回NULL
PIMAGE _ NT _ HEADERS pnthe header =(PIMAGE _ NT _ HEADERS)((DWORD)PDO header+(DWORD)(PDO header-> e _ LFA new));
if(pNTHeader->Signature!= IMAGE_NT_SIGNATURE)返回NULL
//如果没有导入部分,则返回失败
if (pntheader->可选header . data directory[image _ directory _ entry _ Import]。virtualaddress = = 0)
返回null
//取导入部分
pimage _ Import _ descriptor pimportdesc =(pimage _ Import _ descriptor)
((dword)PDO header+(dword)(pnthe header-> optional header。
数据目录[图像目录条目导入]。virtual address));
//查找与szImportMod
匹配的部分while(Pimportdesc-> name)
{
pstr szCurrMod =(pstr)((dword)PDO header+(dword)(Pimportdesc-> name
if(stri CMP(szCurrMod,szImportMod)= = 0)
break;//Find
pimportdesc++;
}
if(pImportDesc--> Name = = NULL)返回NULL;
return pImportDesc;
}

extern " c " _ _ declspec(dll export)HOOK API by name(hmodule hmodule/*是HOOK的目标进程模块指定的函数名*/,LPCSTR sziportmod/*如gdi32.dll */,lphook API phookapi/*,如" messagebox w " */)
{
Pimage _ import _ descriptor Pimportdesc =
GetNameImportDescriptor(hmodule,sziportmod);
if(pImportDesc = = NULL)
返回FALSE//要更改的API无法得到正确的描述Pimage _ thunk _ data Porigthunk =(Pimage _ thunk _ data)((dword)hm odule+(dword)(Pimportdesc-> original first thunk));
PIMAGE _ THUNK _ DATA preal THUNK =
(PIMAGE _ THUNK _ DATA)((DWORD)hm odule+(DWORD)(pImportDesc-> first THUNK));
while(pOrigThunk->u1。function)
{
if((pOrigThunk-> u1。序数& IMAGE_ORDINAL_FLAG)!= IMAGE _ ORDINAL _ FLAG)
{
PIMAGE _ IMPORT _ BY _ NAME pby NAME =(PIMAGE _ IMPORT _ BY _ NAME)((DWORD)hm odule+(DWORD)(pOrigThunk-> u1。address of data));
if(pByName-> Name[0]= = ' \ 0 ')
返回FALSE//Failed
if(str cmpi(phookapi-> SZ func,(char *)pbyname-> name)= = 0)
{
/Change thunk保护属性
MEMORY _ BASIC _ INFORMATION mbi _ thunk
virtual query(preal thunk,&mbi_thunk,sizeof(MEMORY _ BASIC _ INFORMATION));
VirtualProtect(mbi_thunk。基址,mbi_thunk。RegionSize,PAGE_READWRITE,&mbi_thunk。保护);
//保存原API函数指针
if(phookapi-> pold proc = = null)
phookapi-> pold proc =(proc)preal thunk-> u1 . function;
//更改API函数指针
preal thunk-> u1 . function =(PD word)phookapi-> pnewproc;
//将thunk保护属性改回
dword dwold project;
VirtualProtect(mbi_thunk。基址,mbi_thunk。RegionSize,
mbi_thunk。Protect,& dwOldProtect);
}
}
porigthunk++;
prealthunk++;
}
SetLastError(ERROR _ SUCCESS);
返回TRUE
}
EXE部分很简单。加载DLL并启动鼠标挂钩。

位律师回复
DABAN RP主题是一个优秀的主题,极致后台体验,无插件,集成会员系统
白度搜_经验知识百科全书 » C++辅导:如何截获API函数

0条评论

发表评论

提供最优质的资源集合

立即查看 了解详情