• api hook(二)


    #include <windows.h>

     

    // 定义API挂接项结构

    typedef struct _HOOK_ITEM {

     DWORD dwAddr ;   // IAT项所在地址

     DWORD dwOldValue ;  // IAT项的原始函数地址

     DWORD dwNewValue ;  // IAT项的新函数地址

    } HOOK_ITEM, *PHOOK_ITEM ;

    HOOK_ITEM HookItem = {0} ; // 定义IAT项,用于保存MessageBoxAIAT项信息

     

    // 定义MessageBoxA函数原型

    typedef int (WINAPI* PFNMessageBoxA)( HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType ) ;

     

    // 定义重定向API的实现函数

    BOOL WINAPI RedirectApi ( PCHAR pDllName, PCHAR pFunName, DWORD dwNewProc, PHOOK_ITEM pItem ) ;

     

    // 自定义的MessageBoxA函数

    // 实现对原始MessageBoxA的输入、输出参数的监控,甚至是取消调用

    int WINAPI NEW_MessageBoxA( HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType )

    {

     // 此处可以观察/修改调用参数,甚至可以取消调用直接返回。

     // ……

     

     // 取得原函数地址

     PFNMessageBoxA pfnMessageBoxA = (PFNMessageBoxA)HookItem.dwOldValue ;

     

     // 输出测试信息,

     // 如果这里直接调用MessageBoxA,就进入无限循环

     pfnMessageBoxA ( hWnd, "这是API重定向过程的消息框", "测试", 0 ) ;

     

     // 调用原函数

     int ret = pfnMessageBoxA ( hWnd, lpText, lpCaption, uType ) ;

     

     // 此处可以查看/修改调用原函数的返回值

     // ……

     

     return ret ;

    }

     

    int WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )

    {

     // 重定向API

     if ( !RedirectApi ( "USER32.dll", "MessageBoxA", (DWORD)NEW_MessageBoxA, &HookItem ) )

      OutputDebugStringA ( "RedirectApi failed!" ) ;

     else

      OutputDebugStringA ( "RedirectApi success!" ) ;

     

     MessageBoxA ( 0, "正常消息框", "测试", 0 ) ;

     return 0 ;

    }

     

    // 实现重定向API

    // 参数pDllName:目标API所在的DLL名称

    // 参数pFunName:目标API名称

    // 参数dwNewProc:自定义的函数地址

    // 参数pItem:用于保存IAT项信息

    BOOL WINAPI RedirectApi ( PCHAR pDllName, PCHAR pFunName, DWORD dwNewProc, PHOOK_ITEM pItem )

    {

     // 检查参数是否合法

     if ( pDllName == NULL || pFunName == NULL || !dwNewProc || !pItem )

      return FALSE ;

     

     // 检测目标模块是否存在

     char szTempDllName[256] = {0} ;

     DWORD dwBaseImage = (DWORD)GetModuleHandle(NULL) ;

     if ( dwBaseImage == 0 )

      return FALSE ;

     

     // 取得PE文件头信息指针

     PIMAGE_DOS_HEADER   pDosHeader = (PIMAGE_DOS_HEADER)dwBaseImage ;

     PIMAGE_NT_HEADERS   pNtHeader = (PIMAGE_NT_HEADERS)(dwBaseImage + (pDosHeader->e_lfanew)) ;

     PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = &(pNtHeader->OptionalHeader) ;

     PIMAGE_SECTION_HEADER  pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pNtHeader + 0x18 + pNtHeader->FileHeader.SizeOfOptionalHeader ) ;

     

     // 遍历导入表

     PIMAGE_THUNK_DATA pThunk, pIAT ;

     PIMAGE_IMPORT_DESCRIPTOR pIID = (PIMAGE_IMPORT_DESCRIPTOR)(dwBaseImage+pOptionalHeader->DataDirectory[1].VirtualAddress ) ;

     while ( pIID->FirstThunk )

     {

      // 检测是否目标模块

      if ( strcmp ( (PCHAR)(dwBaseImage+pIID->Name), pDllName ) )

      {

       pIID++ ;

       continue ;

      }

     

      pIAT = (PIMAGE_THUNK_DATA)( dwBaseImage + pIID->FirstThunk ) ;

      if ( pIID->OriginalFirstThunk )

       pThunk = (PIMAGE_THUNK_DATA)( dwBaseImage + pIID->OriginalFirstThunk ) ;

      else

       pThunk = pIAT ;

     

      // 遍历IAT

      DWORD dwThunkValue = 0 ;

      while ( ( dwThunkValue = *((DWORD*)pThunk) ) != 0 )

      {

       if ( ( dwThunkValue & IMAGE_ORDINAL_FLAG32 ) == 0 )

       {

        // 检测是否目标函数

        if ( strcmp ( (PCHAR)(dwBaseImage+dwThunkValue+2), pFunName ) == 0 )

        {

         // 填充函数重定向信息

         pItem->dwAddr  = (DWORD)pIAT ;

         pItem->dwOldValue = *((DWORD*)pIAT) ;

         pItem->dwNewValue = dwNewProc;

     

         // 修改IAT

         DWORD dwOldProtect = 0 ;

         VirtualProtect ( pIAT, 4, PAGE_READWRITE, &dwOldProtect ) ;

         *((DWORD*)pIAT) = dwNewProc ;

         VirtualProtect ( pIAT, 4, PAGE_READWRITE, &dwOldProtect ) ;

         return TRUE ;

        }

       }

     

       pThunk ++ ;

       pIAT ++ ;

      }

     

      pIID ++ ;

     }

     

     return FALSE ;

    }


  • 相关阅读:
    poj2421 Constructing Roads *
    poj1789 Truck History *
    关于最小生成树的一些理解
    资源收集【更新】
    poj2313 Sequence ***
    poj1258 AgriNet **
    最大流的算法小结 Algorithm for Maximum Flow
    算法导论18.32 BTREEDELETE的伪代码
    poj2325 Persistent Numbers ****
    23天的单车旅行,从广州到四川,篇首语
  • 原文地址:https://www.cnblogs.com/longle/p/2072874.html
Copyright © 2020-2023  润新知