如何截获API函数

曹梦晗

曹梦晗

2016-02-19 15:18

下面请跟着图老师小编一起来了解下如何截获API函数,精心挑选的内容希望大家喜欢,不要忘记点个赞哦!

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

(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/bianchengyuyan/)

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

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

(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/bianchengyuyan/)

  

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] == '')
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.

展开更多 50%)
分享

猜你喜欢

如何截获API函数

编程语言 网络编程
如何截获API函数

API之绘图函数

编程语言 网络编程
API之绘图函数

s8lol主宰符文怎么配

英雄联盟 网络游戏
s8lol主宰符文怎么配

API之消息函数

编程语言 网络编程
API之消息函数

API之打印函数

编程语言 网络编程
API之打印函数

lol偷钱流符文搭配推荐

英雄联盟 网络游戏
lol偷钱流符文搭配推荐

API之网络函数

编程语言 网络编程
API之网络函数

API之文件处理函数

编程语言 网络编程
API之文件处理函数

lolAD刺客新符文搭配推荐

英雄联盟
lolAD刺客新符文搭配推荐

JavaScript中new运算符

JavaScript中new运算符

JavaScript中减法赋值运算符

JavaScript中减法赋值运算符
下拉加载更多内容 ↓