⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 apihook.c

📁 多任务下的数据结构与算法的源码
💻 C
字号:
/*
 * Copyright (c) 2000-2008
 * Author: Weiming Zhou
 *
 * Permission to use, copy, modify, distribute and sell this software
 * and its documentation for any purpose is hereby granted without fee,
 * provided that the above copyright notice appear in all copies and
 * that both that copyright notice and this permission notice appear
 * in supporting documentation.  
 */

#include <windows.h>
#include "CapiGlobal.h"
#include "ApiHook.h"

typedef struct APIHOOKDATA_st {
	DWORD	dwSrcFuncAddr;   /* 源函数的地址 */
	DWORD	dwNewFuncAddr;   /* 钩子函数的地址 */
	BYTE	byHeaderCode[6]; /* 源函数起始6字节 */
	WORD	wFlag;           /* 用来表示是否设置了HOOK的标志 */
	char	*pszDllName;     
	char	*pszFuncName;    
} APIHOOKDATA;

typedef struct APIHOOK_st {
	APIHOOKDATA	*pHookData;
	UINT		uMaxFunctions;
} APIHOOK;


/**	ApiHook 模块初始化函数

	@param	INT nMaxHookFuncCounts - 最大可设置的钩子数量	
	@return	INT (by default) - NULL 表示失败
*/
HANDLE ApiHook_Init(UINT uMaxFunctions)
{
	APIHOOK	* pApiHook = (APIHOOK *)malloc(sizeof(APIHOOK));

	if ( pApiHook )
	{
		pApiHook->uMaxFunctions = uMaxFunctions;
		pApiHook->pHookData = (APIHOOKDATA *)malloc(sizeof(APIHOOKDATA) * uMaxFunctions);
		if ( NULL != pApiHook->pHookData)
		{
			memset( pApiHook->pHookData, 0, sizeof(APIHOOKDATA) * uMaxFunctions );
			return (HANDLE)pApiHook;
		}
		free(pApiHook);
	}

	return NULL;
}


/**	通过地址来设置某个函数的钩子函数

	@param	HANDLE hApiHook - 由ApiHook_Init()函数生成的句柄	
	@param	DWORD dwSrcFuncAddr - 源函数地址	
	@param	DWORD dwNewFuncAddr - 钩子函数地址	
	@return	INT (by default) - -1表示失败,>=0表示在hook数组中的序号	
*/
INT ApiHook_SetByAddr(HANDLE hApiHook, DWORD dwSrcFuncAddr, DWORD dwNewFuncAddr)
{
	DWORD	dwOldProtect;
	DWORD	dwNewProtect;
	DWORD   lpSrcFunc;
    DWORD   lppNewFunc;
    UINT     i;
	INT		nAlreadyFlag = 0;

	APIHOOK		*pApiHook = (APIHOOK *)hApiHook;
	if ( NULL == hApiHook )
	{
		return -1;
	}

	lpSrcFunc = dwSrcFuncAddr;
    /* 查找是否已被设置了钩子 */
	for ( i = 0; i < pApiHook->uMaxFunctions; i++ )
	{
		if ( pApiHook->pHookData[i].dwSrcFuncAddr == lpSrcFunc )
		{
			/* 如果已经被设置了钩子,仅仅改变. */
			nAlreadyFlag = 1;
			break;
		}

	}
	/* 如果没有设置源函数的钩子函数,在表中找出一个可供记录的位置. */
	if ( i == pApiHook->uMaxFunctions )
	{
		for ( i = 0; i < pApiHook->uMaxFunctions; i++ )
		{
			if (pApiHook->pHookData[i].wFlag == 0 )
			{
				break;
			}
		}		
		if ( i == pApiHook->uMaxFunctions )
		{
			return -1;
		}
	}

    /* 将新的钩子函数地址记录到表中 */
	pApiHook->pHookData[i].dwNewFuncAddr = dwNewFuncAddr;
	
	/* 以下这段代码将源函数头部6个字节保存到表中 */
	lppNewFunc = (DWORD)(&(pApiHook->pHookData[i].dwNewFuncAddr) );

	if ( !nAlreadyFlag )
	{
		/* 将源函数起始处6个字节保存到 byHeaderCode.中 */
        memcpy( pApiHook->pHookData[i].byHeaderCode, (const void *)lpSrcFunc, 6);
	}

    /* 以下这段代码将源函数首部6个字节改成为一条跳转到新函数地址的指令 */
    if ( VirtualProtect( (LPVOID)lpSrcFunc,
                         6,
                         PAGE_EXECUTE_READWRITE,
                         &dwOldProtect ) == 0 ) 
    {
        /* 
         * Failure.
         */
        return -1;
    }
	
    *(unsigned char *)lpSrcFunc = (unsigned char)0xff;
    *(((unsigned char *)lpSrcFunc)+1) = (unsigned char)0x25;

    memcpy( (void *)(lpSrcFunc+2), 
            (const void *)&lppNewFunc, 
            4 );                            /* address  */ 

    if ( VirtualProtect( (LPVOID)lpSrcFunc,
                         6,
                         dwOldProtect,
						 &dwNewProtect) == 0 ) {
        /* 
         * Failure.
         */
        return -1;
    };

	pApiHook->pHookData[i].wFlag = 1;
	pApiHook->pHookData[i].dwSrcFuncAddr = lpSrcFunc; 

	return (INT)i;
}


INT ApiHook_SetByName(HANDLE hApiHook,
			   char *pszDllName, 
			   char *pszFuncName, 
			   DWORD dwNewFuncAddr)
{
    DWORD dwFuncAddr; 
    APIHOOK *pApiHook;
    INT i;

    HMODULE hModule = GetModuleHandle( pszDllName );
    if ( !hModule ) {
        /* 
         * Winsock 1.1 not loaded (would happen for non-Winsock apps, and
         * apps that exclusively use Winsock 2.
         */
        return -1;
    }

    /*
     * Step 2:
     *  Find the address of the function.
     */
    dwFuncAddr = (DWORD)GetProcAddress( hModule, pszFuncName );
    if ( !dwFuncAddr ) {
        /*
         * This should never happen.
         */
        return -1;
    }

    i = ApiHook_SetByAddr(hApiHook, dwFuncAddr, dwNewFuncAddr);
    pApiHook = (APIHOOK *)hApiHook;
    if ( pApiHook->pHookData[i].pszDllName )
    {
        free(pApiHook->pHookData[i].pszDllName);
        pApiHook->pHookData[i].pszDllName = NULL;
    }
    if ( pApiHook->pHookData[i].pszFuncName )
    {
        free( pApiHook->pHookData[i].pszFuncName );
        pApiHook->pHookData[i].pszFuncName = NULL;
    }
    pApiHook->pHookData[i].pszDllName = strdup(pszDllName);
    pApiHook->pHookData[i].pszFuncName = strdup(pszFuncName);

    return i;
}


/**	取消某个函数的钩子函数设置

	@param	HANDLE hApiHook - 由ApiHook_Init()函数生成的句柄	
	@param	DWORD dwSrcFuncAddr - 源函数地址	
	@return	INT (by default) - -1表示失败,>=0表示在hook数组中的序号	
*/
INT	ApiHook_UnSetByAddr(HANDLE hApiHook, DWORD dwSrcFuncAddr )
{
	UINT i;
	DWORD	dwOldProtect;
	DWORD	dwNewProtect;
    DWORD lpSrcFunc;
    
	APIHOOK	*pApiHook = (APIHOOK *)hApiHook;

	if ( NULL == hApiHook )
	{
		return -1;
	}
	for ( i = 0; i < pApiHook->uMaxFunctions; i++ )
	{
		if ( pApiHook->pHookData[i].dwSrcFuncAddr == dwSrcFuncAddr )
		{
			break;
		}
	}

	if ( i == pApiHook->uMaxFunctions )
	{
		return -1;
	}
	
	lpSrcFunc = pApiHook->pHookData[i].dwSrcFuncAddr;
     
    /* 修改lpSrcFunc指向的内存属性为可以读写的 */
    if ( VirtualProtect( (LPVOID)lpSrcFunc, 6, PAGE_EXECUTE_READWRITE, &dwOldProtect ) == 0 ) 
    {
        return -1;
    }

    memcpy( (void *)lpSrcFunc, pApiHook->pHookData[i].byHeaderCode, 6 );

    /* 恢复lpSrcFunc指向的内存属性 */
    if ( VirtualProtect( (LPVOID)lpSrcFunc, 6, dwOldProtect, &dwNewProtect ) == 0 ) 
    {
        return -1;
    }

    pApiHook->pHookData[i].wFlag = 0;
    if ( pApiHook->pHookData[i].pszDllName )
    {
        free(pApiHook->pHookData[i].pszDllName);
        pApiHook->pHookData[i].pszDllName = NULL;
    }
    if ( pApiHook->pHookData[i].pszFuncName )
    {
        free( pApiHook->pHookData[i].pszFuncName );
        pApiHook->pHookData[i].pszFuncName = NULL;
    }
    return (INT)i;
}


INT ApiHook_UnSetByName(HANDLE hApiHook,
			   char *pszDllName, 
			   char *pszFuncName )
{
	INT		ret;
    HMODULE hModule;
    DWORD dwSrcFuncAddr;

    ret = -1;
    hModule = GetModuleHandle( pszDllName );
    if ( !hModule ) {
        /* 
         * Winsock 1.1 not loaded (would happen for non-Winsock apps, and
         * apps that exclusively use Winsock 2.
         */
        return -1;
    }

    /*
     * Step 2:
     *  Find the address of the function.
     */
    dwSrcFuncAddr = (DWORD)GetProcAddress( hModule, pszFuncName );
    if ( !dwSrcFuncAddr ) {
        /*
         * This should never happen.
         */
        return -1;
    }

    ret = ApiHook_UnSetByAddr(hApiHook, dwSrcFuncAddr);

    return ret;
}


UINT ApiHook_GetMaxHooks(HANDLE hApiHook)
{
    UINT uCount;
    UINT	i;
	APIHOOK	*pApiHook;
    
    pApiHook= (APIHOOK *)hApiHook;
    uCount = 0;

	if ( !hApiHook )
	{
		return 0;
	}
	for ( i = 0; i < pApiHook->uMaxFunctions; i++ )
	{
		if ( pApiHook->pHookData[i].wFlag == 1 )
		{
			uCount += 1;
		}
	}
	return uCount;
}


/**	ApiHook模块关闭函数

	@param	HANDLE - 由ApiHook_Init()函数生成的句柄		
	@return	INT (by default) - 失败返回-1, 成功返回0。	
*/
INT ApiHook_Close(HANDLE hApiHook)
{
	if ( NULL != hApiHook )
	{
        UINT i;
		APIHOOK *p = (APIHOOK *)hApiHook; 
		for ( i = 0; i < p->uMaxFunctions; i++ )
		{
			if ( p->pHookData[i].wFlag )
			{
				DWORD	dwOldProtect;
				DWORD	dwNewProtect;

				DWORD lpSrcFunc = p->pHookData[i].dwSrcFuncAddr;
				/* 
				 * Rewrite the bytes for future calls.
				 */
				if ( VirtualProtect( (LPVOID)lpSrcFunc,
									 6,
									 PAGE_EXECUTE_READWRITE,
									 &dwOldProtect ) == 0 ) {
					/* 
					 * Failure.
					 */
					return -1;
				}

				memcpy( (void *)lpSrcFunc, 
						(const void *)p->pHookData[i].byHeaderCode, 
						6 );

				if ( VirtualProtect( (LPVOID)lpSrcFunc,
									 6,
									 dwOldProtect,
									 &dwNewProtect ) == 0 ) {
					/* 
					 * Failure.
					 */
					return -1;
				}
			}
			if ( p->pHookData[i].pszDllName )
			{
				free( p->pHookData[i].pszDllName );
			}
			if ( p->pHookData[i].pszFuncName )
			{
				free( p->pHookData[i].pszFuncName );
			}
		}
		free(p->pHookData);
		free(p);
	}
	return 0;
}
        

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -