API hook 原理與Windows hook 應用

來源:互聯網
上載者:User

// IatApiHook.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "windows.h"

BOOL TestFunctionInIAT( HMODULE hModule, ULONG FunctionAddress )
{
    BOOL bReturn = FALSE;
    unsigned char *pBaseAddr = reinterpret_cast<unsigned char *>(hModule);

    // 擷取DOS header 的位置
    PIMAGE_DOS_HEADER pDosHeader = reinterpret_cast<PIMAGE_DOS_HEADER>(pBaseAddr);

    // 擷取NTImage header 的位置
    PIMAGE_NT_HEADERS pNtHeader = reinterpret_cast<PIMAGE_NT_HEADERS>(
        pBaseAddr + pDosHeader->e_lfanew );

    // 擷取 PE option header的位置
    PIMAGE_OPTIONAL_HEADER pPEOptionHeader = &pNtHeader->OptionalHeader;

    // 擷取匯入表的目錄結構
    PIMAGE_DATA_DIRECTORY pIATDataDirectory = &(pPEOptionHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]);

    // 擷取匯入表 descriptor
    PIMAGE_IMPORT_DESCRIPTOR pImportDescriptor = reinterpret_cast<PIMAGE_IMPORT_DESCRIPTOR>(
        pBaseAddr + pIATDataDirectory->VirtualAddress );

    // 從pImportDescriptor 開始是一堆匯入表,一張接著一張,直到
    // 匯入表的名字為空白為止,其實就是對應Windows 的一個dll,有幾張表,就表示
    // 該模組依賴幾個dll 的匯出函數, Name 欄位是dll的名稱的相對虛擬位址
    while ( pImportDescriptor->Name != 0 )
    {
        // thunk data 就是表示匯入dll 中函數描述
        PIMAGE_THUNK_DATA pThunkData = reinterpret_cast<PIMAGE_THUNK_DATA>(
            pBaseAddr + pImportDescriptor->FirstThunk);
        while( pThunkData->u1.Function != 0 )
        {
            ULONG *ppfn = ( ULONG *)&pThunkData->u1.Function;
            if ( *ppfn == FunctionAddress )
            {

                bReturn = TRUE;
                break;
            }
            ++pThunkData;
        }
        ++pImportDescriptor;
    }

    return bReturn;
}

PROC g_CreateFunc = NULL;

typedef BOOL (WINAPI *PCreateProcessW)(
    __in_opt    LPCWSTR lpApplicationName,
    __inout_opt LPWSTR lpCommandLine,
    __in_opt    LPSECURITY_ATTRIBUTES lpProcessAttributes,
    __in_opt    LPSECURITY_ATTRIBUTES lpThreadAttributes,
    __in        BOOL bInheritHandles,
    __in        DWORD dwCreationFlags,
    __in_opt    LPVOID lpEnvironment,
    __in_opt    LPCWSTR lpCurrentDirectory,
    __in        LPSTARTUPINFOW lpStartupInfo,
    __out       LPPROCESS_INFORMATION lpProcessInformation);

BOOL WINAPI MyCreateProcessW(
    __in_opt    LPCWSTR lpApplicationName,
    __inout_opt LPWSTR lpCommandLine,
    __in_opt    LPSECURITY_ATTRIBUTES lpProcessAttributes,
    __in_opt    LPSECURITY_ATTRIBUTES lpThreadAttributes,
    __in        BOOL bInheritHandles,
    __in        DWORD dwCreationFlags,
    __in_opt    LPVOID lpEnvironment,
    __in_opt    LPCWSTR lpCurrentDirectory,
    __in        LPSTARTUPINFOW lpStartupInfo,
    __out       LPPROCESS_INFORMATION lpProcessInformation)
{

    MessageBoxW(NULL, lpCommandLine, L"CreateProcessW", MB_OK);

    return ((PCreateProcessW)g_CreateFunc)(
        lpApplicationName,
        lpCommandLine,
        lpProcessAttributes,
        lpThreadAttributes,
        bInheritHandles,
        dwCreationFlags,
        lpEnvironment,
        lpCurrentDirectory,
        lpStartupInfo,
        lpProcessInformation);
}

PROC install_api_hook(
    HMODULE hHookModule,
    const char * szDllName,
    PROC pfnHookFunAddr,
    PROC pfnNewFundAddr
    )
{
    PROC pOrigFunc = NULL;

    unsigned char *pBaseAddr =
        reinterpret_cast<unsigned char *>(hHookModule);

    PIMAGE_DOS_HEADER pDosHeader =
        reinterpret_cast<PIMAGE_DOS_HEADER>(pBaseAddr);

    PIMAGE_NT_HEADERS pNtHeader =
        reinterpret_cast<PIMAGE_NT_HEADERS>(
        pBaseAddr + pDosHeader->e_lfanew );

    PIMAGE_OPTIONAL_HEADER pPEOptionHeader =
        &pNtHeader->OptionalHeader;

    PIMAGE_DATA_DIRECTORY pIATDataDirectory =
        &(pPEOptionHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]);

    PIMAGE_IMPORT_DESCRIPTOR pImportDescriptor =
        reinterpret_cast<PIMAGE_IMPORT_DESCRIPTOR>(
        pBaseAddr + pIATDataDirectory->VirtualAddress );

    for ( ; pImportDescriptor->Name; pImportDescriptor++ )  
    {  
        const char* pszModName =
            reinterpret_cast<const char*>(
            pBaseAddr + pImportDescriptor->Name);  
        if ( 0 == lstrcmpiA( pszModName, szDllName ) )  
        {
            break;  
        }
    }  

    if ( 0 == pImportDescriptor->Name )
    {
        return pOrigFunc;
    }

    PIMAGE_THUNK_DATA pThunkData =
        reinterpret_cast<PIMAGE_THUNK_DATA>(
        pBaseAddr + pImportDescriptor->FirstThunk);
    while( pThunkData->u1.Function != 0 )
    {
        PROC *ppFunc = reinterpret_cast<PROC*>(
            &pThunkData->u1.Function);
        if ( *ppFunc == pfnHookFunAddr )
        {
            DWORD dwOldProtect = 0;  
            VirtualProtect( ppFunc, sizeof(PROC), PAGE_READWRITE, &dwOldProtect );  

            pOrigFunc = *ppFunc;
            CopyMemory(ppFunc, &pfnNewFundAddr, sizeof(PROC));
            //            SIZE_T stMemorySize = 0;
            //             WriteProcessMemory(
            //                 GetCurrentProcess(),
            //                 ppFunc,
            //                 &uNewFundAddr,
            //                 sizeof(*ppFunc),
            //                 &stMemorySize);
            VirtualProtect( ppFunc, sizeof(PROC), dwOldProtect, 0 );  
            break;
        }
        pThunkData++;
    }

    return pOrigFunc;    
}

int _tmain(int argc, _TCHAR* argv[])
{
    HMODULE hModule = NULL;
    GetModuleHandleEx(
        GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
        (LPCTSTR)TestFunctionInIAT,
        &hModule);
    BOOL bReturn = TestFunctionInIAT( hModule , (ULONG_PTR)CreateProcessW );
    if ( bReturn )
    {
        printf("Found address CreateProcessW!\n");
    }
    else
    {
        printf("found failed!\n");
    }

    g_CreateFunc = install_api_hook(hModule, "kernel32.dll", (PROC)CreateProcessW, (PROC)MyCreateProcessW);

    wchar_t szProcessName[] = L"notepad.exe";
    STARTUPINFO si = {sizeof(si)};
    PROCESS_INFORMATION pi;
    CreateProcessW(NULL,
        szProcessName,
        NULL,
        NULL,
        FALSE,
        0,
        NULL,
        NULL,
        &si,
        &pi);

    return 0;
}

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.