如何截获API函数

2016-02-19 15:18 42 1 收藏

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

【 tulaoshi.com - 编程语言 】

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

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

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

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

(本文来源于图老师网站,更多请访问https://www.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.

来源:https://www.tulaoshi.com/n/20160219/1609356.html

延伸阅读
CancelWaitableTimer这个函数用于取消一个可以等待下去的计时器操作CallNamedPipe这个函数由一个希望通过管道通信的一个客户进程调用ConnectNamedPipe指示一台服务器等待下去,直至客户机同一个命名管道连接CreateEvent创建一个事件对象CreateMailslot创建一个邮路。返回的句柄由邮路服务器使用(收件人)CreateMutex创建一个互斥体(MUTEX)Cre...
AddFontResource在Windows系统中添加一种字体资源CreateFont用指定的属性创建一种逻辑字体CreateFontIndirect用指定的属性创建一种逻辑字体CreateScalableFontResource为一种TureType字体创建一个资源文件,以便能用API函数AddFontResource将其加入Windows系统DrawText将文本描绘到指定的矩形中DrawTextEx与DrawText相似,只是加入了更多的功能E...
以往的DOS系统是通过DOS中断和BIOS中断向用户提供串行接口的通讯能力。在Windows环境下,C++的开发工具既没有提供象DOS和BIOS中那样专门的串行通讯控制方法,也不答应用户直接控制串口的中断。 为了保证资源共享,Windows系统完全接管了各种硬件资源,使用中断来控制端口将破坏系统的多任务性,使系统的稳定性受到影响。但Windows...
标签: ASP
       any       有些消息的参数声明为any.这表示该参数是一种可变的类型(你可以以整型,字符串,用户自定义或其他的类型来传递).      这有一个这样的例子:      public declare function sendmessage lib "user32" alias "sendmessagea...