如何看懂c语言的api函数,如何截获API函数

本文介绍了如何通过HOOK技术实现对MessageBoxW函数的动态截获,通过PE格式修改API函数地址,展示了在DLL中创建全局鼠标HOOK并实现指定函数替换的过程。适合对Windows API Hook和程序动态修改感兴趣的开发者。
摘要由CSDN通过智能技术生成

我曾经写过一个截获MessageBoxW的程序,可以看看,或许对你有一些帮助.

该程序是基于HOOK原理,主要是将自己的函数放到目标PROCESS的地址空间,这里是使用HOOK实现.首先建立一个MOUSE的HOOK程序,然后在全局鼠标HOOK的DLL中做截获动作,可以在PROCESS_ATTACH时做,也可以在鼠标的HOOK链函数中做.

建立全局HOOK我就不说了,可以在网上很多地方看到.主要是截获动作.我是通过PE格式(使用IMAGE)改变API函数在调用时的地址.DLL部分参考如下代码:

static int WINAPI MyMessageBoxW(HWND hWnd , LPCWSTR lpText, LPCWSTR lpCaption, UINT uType)//自己的MessageBoxW函数

{return MessageBox(hWnd, “TNT”/*lpText*/, “TNT”/*lpCaption*/, uType);

}

我定义了一个结构

typedef struct tag_HOOKAPI

{

LPCSTR szFunc;//待HOOK的API函数名

PROC pNewProc;//新的函数指针

PROC pOldProc;//老的函数指针

}HOOKAPI, *LPHOOKAPI;

extern “C” __declspec(dllexport)PIMAGE_IMPORT_DESCRIPTOR GetNamedImportDescriptor(HMODULE hModule, LPCSTR szImportMod)

{

//首先是DOS头

PIMAGE_DOS_HEADER pDOSHeader = (PIMAGE_DOS_HEADER) hModule;

if(pDOSHeader->e_magic != IMAGE_DOS_SIGNATURE) return NULL;

PIMAGE_NT_HEADERS pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDOSHeader + (DWORD)(pDOSHeader->e_lfanew));

if(pNTHeader->Signature != IMAGE_NT_SIGNATURE) return NULL;

//如果没有Import部分,返回失败

if(pNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress == 0)

return NULL;

//取Import部分

PIMAGE_IMPORT_DESCRIPTOR pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)

((DWORD)pDOSHeader + (DWORD)(pNTHeader->OptionalHeader.

DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress));

//寻找与szImportMod相配部分

while (pImportDesc->Name)

{

PSTR szCurrMod = (PSTR)((DWORD)pDOSHeader + (DWORD)(pImportDesc->Name));

if (stricmp(szCurrMod, szImportMod) == 0)

break; //找到

pImportDesc++;

}

if(pImportDesc->Name == NULL) return NULL;

return pImportDesc;

}

extern “C” __declspec(dllexport) HookAPIByName(HMODULE hModule/*被HOOK的目标进程MODULE*/, LPCSTR szImportMod/*如GDI32.DLL*/,LPHOOKAPI pHookApi/*指定函数名,如”MessageBoxW”*/)

{

PIMAGE_IMPORT_DESCRIPTOR pImportDesc =

GetNamedImportDescriptor(hModule, szImportMod);

if (pImportDesc == NULL)

return FALSE; //需要改换的API不能取到正确描PIMAGE_THUNK_DATA pOrigThunk = (PIMAGE_THUNK_DATA)((DWORD)hModule + (DWORD)(pImportDesc->OriginalFirstThunk));

PIMAGE_THUNK_DATA pRealThunk =

(PIMAGE_THUNK_DATA)((DWORD)hModule + (DWORD)(pImportDesc->FirstThunk));

while(pOrigThunk->u1.Function)

{

if((pOrigThunk->u1.Ordinal & IMAGE_ORDINAL_FLAG) != IMAGE_ORDINAL_FLAG)

{

PIMAGE_IMPORT_BY_NAME pByName = (PIMAGE_IMPORT_BY_NAME)((DWORD)hModule + (DWORD)(pOrigThunk->u1.AddressOfData));

if(pByName->Name[0] == ‘\0′)

return FALSE; //失败

if(strcmpi(pHookApi->szFunc, (char*)pByName->Name) == 0)

{

//改变thunk保护属性

MEMORY_BASIC_INFORMATION mbi_thunk;

VirtualQuery(pRealThunk, &mbi_thunk, sizeof(MEMORY_BASIC_INFORMATION));

VirtualProtect(mbi_thunk.BaseAddress,mbi_thunk.RegionSize, PAGE_READWRITE, &mbi_thunk.Protect);

//保存原来的API函数指针

if(pHookApi->pOldProc == NULL)

pHookApi->pOldProc = (PROC)pRealThunk->u1.Function;

//改变API函数指针

pRealThunk->u1.Function = (PDWORD)pHookApi->pNewProc;

//将thunk保护属性改回来

DWORD dwOldProtect;

VirtualProtect(mbi_thunk.BaseAddress, mbi_thunk.RegionSize,

mbi_thunk.Protect, &dwOldProtect);

}

}

pOrigThunk++;

pRealThunk++;

}

SetLastError(ERROR_SUCCESS);

return TRUE;

}

EXE部分很简单,将该DLL载入,开启鼠标HOOK.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值