好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

HookApi例子

HookApi例子

Windows 7 64位 HookApi例子

 

  本程序HOOK的API是DispatchMessageA和DispatchMessageW。在HOOK的方法内会还原ESP,调用user32.DispathMessage(A或W)之后再修改ESP,实现的功能是记录消息的详细日志,记录哪个窗口处理过哪些消息。

  1、新建一个win32 console项目,取名为DoInjection,新建一个DoInjectionMain.h,代码如下:

?

BOOL   SetPrivilege( LPCTSTR   lpszPrivilege, BOOL   bEnablePrivilege);

BOOL   IsVistaOrLater();

BOOL   InjectProcess();

BOOL   InjectCreateProcess();

void   HookGetMessage();

BOOL   InjectCreateThread( HANDLE   hProcess, LPTHREAD_START_ROUTINE pThreadProc, LPVOID   pRemoteBuf);

HANDLE   MsicCreateRemoteThread( HANDLE   hProcess,LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter);

 

typedef   void *(__stdcall*LPFN_KernelBaseGetGlobalData)( void );

typedef   DWORD   (WINAPI *PFNTCREATETHREADEX)

(

     PHANDLE                   ThreadHandle,  

     ACCESS_MASK             DesiredAccess, 

     LPVOID                    ObjectAttributes,  

     HANDLE                    ProcessHandle, 

     LPTHREAD_START_ROUTINE  lpStartAddress,

     LPVOID                    lpParameter,   

     BOOL                      CreateSuspended,   

     DWORD                     dwStackSize,   

     DWORD                     dw1,

     DWORD                     dw2,

     LPVOID                    Unknown

);

  2、新建一个DoInjectionMain.c( 不是CPP ),代码如下:

?

#include <windows.h>

#include <stdio.h>

#include <tlhelp32.h>

#include <tchar.h>

#include "DoInjection.h"

 

#pragma comment(lib,"th32.lib")

#pragma comment(lib,"Advapi32.lib")

 

//这个路径很有意思,这个路径是相对于目标进程的,而不是自身进程。

//所以要嘛写成绝对路径,要嘛写成相对于目标进程的相对路径。

//如果写成相对于自身的路径就要麻烦了,本程序就找不到DLL文件了。

const   char   *pcDllName= "MfcHookApi.dll" ;        //DLL文件的路径

HANDLE   hSnap=0,hThreadHandle=0,hRemoteProcess32=0,hTokenHandle=0;

PROCESSENTRY32 procEntry32;

BOOL   bNext=FALSE,bWrittenResult=FALSE;

TOKEN_PRIVILEGES tokenPower;

LUID luidPower;

LPVOID   pRemoteBuf=NULL;

FARPROC fnDllKernel32;

size_t   sizeWritten=0;

DWORD   dwThreadId=0;

 

char * pcProsessName= "DoWin32Test.exe" ;   //要注入的进程名(目标进程名)

 

int   main()

{

     IsVistaOrLater();

     SetPrivilege(SE_DEBUG_NAME,TRUE);

     //InjectProcess();

     InjectCreateProcess();

     getchar ();

     return   0;

}

 

BOOL   SetPrivilege( LPCTSTR   lpszPrivilege, BOOL   bEnablePrivilege)

{

     TOKEN_PRIVILEGES tp;

     HANDLE   hToken;

     LUID luid;

     if ( !OpenProcessToken(GetCurrentProcess(),

                           TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,

                           &hToken) )

     {

         _tprintf( "OpenProcessToken error: %u\r\n" , GetLastError());

         return   FALSE;

     }

     if ( !LookupPrivilegeValue(NULL,

                               lpszPrivilege,

                               &luid) )

     {

         _tprintf( "LookupPrivilegeValue error: %u\r\n" , GetLastError() );

         return   FALSE;

     }

     tp.PrivilegeCount = 1;

     tp.Privileges[0].Luid = luid;

     if ( bEnablePrivilege )

         tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

     else

         tp.Privileges[0].Attributes = 0;

     if ( !AdjustTokenPrivileges(hToken,

                                FALSE,

                                &tp,

                                sizeof (TOKEN_PRIVILEGES),

                                (PTOKEN_PRIVILEGES) NULL,

                                (PDWORD) NULL) )

     {

         _tprintf( "AdjustTokenPrivileges error: %u\r\n" , GetLastError() );

         return   FALSE;

     }

     if ( GetLastError() == ERROR_NOT_ALL_ASSIGNED )

     {

         _tprintf( "The token does not have the specified privilege. \r\n" );

         return   FALSE;

     }

     return   TRUE;

}

 

BOOL   IsVistaOrLater()

{

      

     OSVERSIONINFO osvi;

     ZeroMemory(&osvi, sizeof (OSVERSIONINFO));

     //OSVERSIONINFOEX osvix;

     //ZeroMemory(&osvix,sizeof(OSVERSIONINFOEX));

     osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);

     GetVersionEx(&osvi);

     printf ( "network terminal v%ld.%ld,%s,platform:%ld,build number:%ld\r\n" ,osvi.dwMajorVersion,osvi.dwMinorVersion,osvi.szCSDVersion,osvi.dwPlatformId,osvi.dwBuildNumber);

     if ( osvi.dwMajorVersion >= 6 )

         return   TRUE;

     return   FALSE;

}

 

BOOL   InjectProcess()

{

     procEntry32.dwSize = sizeof (PROCESSENTRY32);

     hSnap=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

     bNext=Process32First(hSnap, &procEntry32);

     while (bNext)

     {

         if (!stricmp(procEntry32.szExeFile,pcProsessName))        //--->>

         {

             hRemoteProcess32=OpenProcess(PROCESS_CREATE_THREAD|PROCESS_VM_WRITE|PROCESS_VM_OPERATION,1,procEntry32.th32ProcessID);

             break ;

         }

         bNext=Process32Next(hSnap, &procEntry32);

     }

     CloseHandle(hSnap);

     pRemoteBuf=VirtualAllocEx(hRemoteProcess32,NULL, strlen (pcDllName),MEM_COMMIT,PAGE_READWRITE);

     bWrittenResult=WriteProcessMemory(hRemoteProcess32,pRemoteBuf,pcDllName, strlen (pcDllName),( ULONG *)&sizeWritten);

     if   (bWrittenResult)

     {

         printf ( "InjectCreate()-->WriteProcessMemory() Success,written size:%ld,buffer address:%16X\r\n" ,sizeWritten,pRemoteBuf);

     }

     else

     {

         printf ( "InjectCreate()-->WriteProcessMemory() Error:%ld\r\n" ,GetLastError());

     }

     fnDllKernel32=GetProcAddress(GetModuleHandle( "kernel32.dll" ), "LoadLibraryA" );

 

     //hThreadHandle=CreateRemoteThread(hRemoteProcess32,NULL,0,(LPTHREAD_START_ROUTINE)fnDllKernel32,pAllocMemory,0,&dwThreadId);

     //if (hThreadHandle&&dwThreadId)

     //{

     //  printf("CreateRemoteThread Success,Handle:%ld,Thread Id:%ld\r\n",hThreadHandle,dwThreadId);

     //}

     //else

     //{

     //  printf("CreateRemoteThread Error:%ld\r\n",GetLastError());

     //}

     InjectCreateThread(hRemoteProcess32, (LPTHREAD_START_ROUTINE)fnDllKernel32, pRemoteBuf);

     //MsicCreateRemoteThread(hRemoteProcess32,(LPTHREAD_START_ROUTINE)fnDllKernel32,pRemoteBuf);

     VirtualFreeEx(hRemoteProcess32, pRemoteBuf, 0, MEM_RELEASE);;

     CloseHandle(hRemoteProcess32);

     return   TRUE;

}

 

BOOL   InjectCreateProcess()

{

     PROCESS_INFORMATION pi;

     STARTUPINFO si;

     procEntry32.dwSize = sizeof (PROCESSENTRY32);

     ZeroMemory(&pi, sizeof (PROCESS_INFORMATION));

     ZeroMemory(&si, sizeof (STARTUPINFO));

     si.cb= sizeof (STARTUPINFO);

 

     CreateProcess(NULL,pcProsessName,NULL,NULL, false ,0,NULL,NULL,&si,&pi);

     hRemoteProcess32=pi.hProcess;

     printf ( "waiting for 30 seconds please.\r\n" );

     for   ( int   i=0;i<30;i++)

     {

         Sleep(1000);

         printf ( "." );

     }

     printf ( "\r\n" );

     pRemoteBuf=VirtualAllocEx(hRemoteProcess32,NULL, strlen (pcDllName),MEM_COMMIT,PAGE_READWRITE);

     bWrittenResult=WriteProcessMemory(hRemoteProcess32,pRemoteBuf,pcDllName, strlen (pcDllName),( ULONG *)&sizeWritten);

     if   (bWrittenResult)

     {

         printf ( "InjectCreate()-->WriteProcessMemory() Success,written size:%ld,buffer address:%16X\r\n" ,sizeWritten,pRemoteBuf);

     }

     else

     {

         printf ( "InjectCreate()-->WriteProcessMemory() Error:%ld\r\n" ,GetLastError());

     }

     fnDllKernel32=GetProcAddress(GetModuleHandle( "kernel32.dll" ), "LoadLibraryA" );

 

     //hThreadHandle=CreateRemoteThread(hRemoteProcess32,NULL,0,(LPTHREAD_START_ROUTINE)fnDllKernel32,pAllocMemory,0,&dwThreadId);

     //if (hThreadHandle&&dwThreadId)

     //{

     //  printf("CreateRemoteThread Success,Handle:%ld,Thread Id:%ld\r\n",hThreadHandle,dwThreadId);

     //}

     //else

     //{

     //  printf("CreateRemoteThread Error:%ld\r\n",GetLastError());

     //}

     //InjectCreateThread(hRemoteProcess32, (LPTHREAD_START_ROUTINE)fnDllKernel32, pRemoteBuf);

     MsicCreateRemoteThread(hRemoteProcess32,(LPTHREAD_START_ROUTINE)fnDllKernel32,pRemoteBuf);

     //VirtualFreeEx(hRemoteProcess32, pRemoteBuf, 0, MEM_RELEASE);;

     //CloseHandle(hRemoteProcess32);

     return   TRUE;

}

 

BOOL   InjectCreateThread( HANDLE   hProcess, LPTHREAD_START_ROUTINE pThreadProc, LPVOID   pRemoteBuf)

{

     HANDLE        hThread = NULL;

     FARPROC     pFunc = NULL;

     if ( IsVistaOrLater() )    // Vista, 7, Server2008

     {

         pFunc = GetProcAddress(GetModuleHandle( "ntdll.dll" ), "NtCreateThreadEx" );

         if ( pFunc == NULL )

         {

             printf ( "InjectCreateThread()-->GetProcAddress(\"NtCreateThreadEx\") Error %d\r\n" ,GetLastError());

             return   FALSE;

         }

         ((PFNTCREATETHREADEX)pFunc)(&hThread,

                                     0x1FFFFF,

                                     NULL,

                                     hProcess,

                                     pThreadProc,

                                     pRemoteBuf,

                                     FALSE,

                                     NULL,

                                     NULL,

                                     NULL,

                                     NULL);

         if ( hThread == NULL )

         {

             printf ( "InjectCreateThread()-->NtCreateThreadEx() Error: %d\r\n" , GetLastError());

             return   FALSE;

         }

         else

         {

             printf ( "InjectCreateThread()-->NtCreateThreadEx() Success,Thread Id:%ld\r\n" ,hThread);

         }

     }

     else                      // 2000, XP, Server2003

     {

         hThread = CreateRemoteThread(hProcess,

                                      NULL,

                                      0,

                                      pThreadProc,

                                      pRemoteBuf,

                                      0,

                                      NULL);

         if ( hThread == NULL )

         {

             printf ( "InjectCreateThread()-->CreateRemoteThread() Error: %d\r\n" , GetLastError());

             return   FALSE;

         }

         else

         {

             printf ( "InjectCreateThread()-->CreateRemoteThread() Success,Thread Id:%ld\r\n" ,hThread);

         }

     }

     if ( WAIT_FAILED == WaitForSingleObject(hThread, INFINITE) )

     {

         printf ( "InjectCreateThread() : WaitForSingleObject() Error: %d\r\n" , GetLastError());

         return   FALSE;

     }

     return   TRUE;

}

 

typedef   void *(__stdcall*LPFN_KernelBaseGetGlobalData)( void );

HANDLE   MsicCreateRemoteThread( HANDLE   hProcess,LPTHREAD_START_ROUTINE lpStartAddress, LPVOID   lpParameter)

{

     OSVERSIONINFOEX stOSVersionInfoEx= {0};

     FARPROC pCreateRemoteThreadEx=NULL;

     LPFN_KernelBaseGetGlobalData pKernelBaseGetGlobalData=NULL;

     UCHAR   *pCreateRemoteThread=NULL;

     UCHAR   *pGlobalData=NULL;

     UCHAR   *pMisc=NULL;

     HMODULE   hKernelBase=NULL;

     HMODULE   hKernel32=NULL;

     HANDLE   hNewThread=NULL;

     ULONG   ulIndex=0;

     WORD   wCode=0;

     do

     {

         stOSVersionInfoEx.dwOSVersionInfoSize= sizeof (OSVERSIONINFOEX);

         if (!GetVersionEx((OSVERSIONINFO*)&stOSVersionInfoEx))

         {

             break ;

         }

//vista以前的系统不存在这个问题

         if ((stOSVersionInfoEx.dwMajorVersion<6)||(GetCurrentProcess()==hProcess))

         {

             hNewThread=CreateRemoteThread(hProcess,NULL,0,lpStartAddress,lpParameter,0,&dwThreadId);

             if   (dwThreadId)

             {

                 printf ( "MsicCreateRemoteThread()-->CreateRemoteThread() Success,Thread Id:%08X\r\n" ,dwThreadId);

             }

             else

             {

                 printf ( "MsicCreateRemoteThread()-->CreateRemoteThread() Error:%ld\r\n" ,GetLastError());

             }

              

             break ;

         }

         if ((stOSVersionInfoEx.dwMajorVersion==6)&&(0==stOSVersionInfoEx.dwMinorVersion))

         {

//vista

             hKernel32=LoadLibraryA( "Kernel32.dll" );

             pCreateRemoteThread=( UCHAR *)GetProcAddress(hKernel32, "CreateRemoteThread" );

             for (ulIndex=0; ulIndex<0x300; ulIndex+=1)

             {

                 wCode=*(( USHORT *)(pCreateRemoteThread+ulIndex));

#ifdef _WIN64

                 if (0x3D80==wCode)

                 {

                     pMisc=(*(( ULONG *)(pCreateRemoteThread+ulIndex+2)))+(pCreateRemoteThread+ulIndex+7);

                     break ;

                 }

#else

                 if (0x1D38==wCode)

                 {

                     pMisc=( UCHAR *)(*(( ULONG *)(pCreateRemoteThread+ulIndex+2)));

                     break ;

                 }

#endif

             }

         }

         else   if ((stOSVersionInfoEx.dwMajorVersion==6)&&(1==stOSVersionInfoEx.dwMinorVersion))

         {

//win7

             hKernelBase=LoadLibraryW(L "KernelBase.dll" );

             if (NULL==hKernelBase)

             {

                 break ;

             }

             pKernelBaseGetGlobalData=(LPFN_KernelBaseGetGlobalData)GetProcAddress(hKernelBase, "KernelBaseGetGlobalData" );

             printf ( "MsicCreateRemoteThread()-->KernelBaseGetGlobalData:%08X\r\n" ,pKernelBaseGetGlobalData);

             if (NULL==pKernelBaseGetGlobalData)

             {

                 break ;

             }

             pGlobalData=( UCHAR *)pKernelBaseGetGlobalData();

             if (NULL==pGlobalData)

             {

                 break ;

             }

#ifdef _WIN64

             pMisc=pGlobalData+0x5C;

#else

             pMisc=pGlobalData+0x30;

#endif

         }

         else

         {

//手上的win8 Build 8250 没有session 隔离

         }

//////////////////////////////////////////////////////////////////////////

         if (NULL==pMisc)

         {

             break ;

         }

         printf ( "MsicCreateRemoteThread()-->pMisc: %08X\r\n" ,pMisc);

//Patch

         *pMisc=1;

//xx

         hNewThread=CreateRemoteThread(hProcess,NULL,0,lpStartAddress,lpParameter,0,&dwThreadId);

         if   (dwThreadId)

         {

             printf ( "MsicCreateRemoteThread()-->CreateRemoteThread() Success,Thread Id:%08X\r\n" ,dwThreadId);

         }

         else

         {

             printf ( "MsicCreateRemoteThread()-->CreateRemoteThread() Error:%ld\r\n" ,GetLastError());

         }

//UnPatch

         *pMisc=0;

     }

     while (FALSE);

     if (NULL!=hKernelBase)

     {

         printf ( "MsicCreateRemoteThread()-->hKernelBase:%08X\r\n" ,hKernelBase);

         FreeLibrary(hKernelBase);

         hKernelBase=NULL;

     }

     return   hNewThread;

}

 

void   HookGetMessage()

{

     HOOKPROC hp;

     //SetWindowsHookEx(WH_GETMESSAGE,hp,)

}

  3、新建一个mfc的DLL项目,命名为 MfcHookApi.dll,MfcHookApi.h的代码如下:

?

// MfcHookApi.h : main header file for the MFCHOOKAPI DLL

//

 

#if !defined(AFX_MFCHOOKAPI_H__6A8FC5E5_0E77_4B74_8344_CB9CA22141E5__INCLUDED_)

#define AFX_MFCHOOKAPI_H__6A8FC5E5_0E77_4B74_8344_CB9CA22141E5__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

#ifndef __AFXWIN_H__

     #error include 'stdafx.h' before including this file for PCH

#endif

 

#include "resource.h"       // main symbols

 

/////////////////////////////////////////////////////////////////////////////

// CMfcHookApiApp

// See MfcHookApi.cpp for the implementation of this class

//

 

class   CMfcHookApiApp : public   CWinApp

{

public :

     CMfcHookApiApp();

 

// Overrides

     // ClassWizard generated virtual function overrides

     //{{AFX_VIRTUAL(CMfcHookApiApp)

     public :

     virtual   BOOL   InitInstance();

     //}}AFX_VIRTUAL

 

     //{{AFX_MSG(CMfcHookApiApp)

         // NOTE - the ClassWizard will add and remove member functions here.

         //    DO NOT EDIT what you see in these blocks of generated code !

     //}}AFX_MSG

     DECLARE_MESSAGE_MAP()

};

 

extern   "C"   __declspec ( dllexport ) void   ActiveHook();

extern   "C"   __declspec ( dllexport ) void   InstallHook4Api( HWND   hwnd);

 

int * addrMsgBoxA=( int *)MessageBoxA;

int * addrMsgBoxW=( int *)MessageBoxW;

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

int   WINAPI HookMessageBoxW( HWND   hWnd, LPCWSTR   lpText, LPCWSTR   lpCaption, UINT   uType);

void   SetHookMessageBox( HMODULE   hModule);

 

typedef   int (WINAPI* PfnMessageBox)( HWND , LPCSTR , LPCSTR , UINT );

 

int * addrDispatchA=( int *)DispatchMessageA;

int * addrDispatchW=( int *)DispatchMessageW;

LRESULT   WINAPI HookDispatchMessageA(MSG* msg);

LRESULT   WINAPI HookDispatchMessageW(MSG* msg);

void   SetHookDispatchMessage( HMODULE   hModule);

 

typedef   LRESULT   (WINAPI* DLLDISPATCHMESSAGE)(MSG* msg);

/////////////////////////////////////////////////////////////////////////////

 

//{{AFX_INSERT_LOCATION}}

// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

 

#endif // !defined(AFX_MFCHOOKAPI_H__6A8FC5E5_0E77_4B74_8344_CB9CA22141E5__INCLUDED_)

  5、MfcHookApi.cpp代码如下:

?

// MfcHookApi.cpp : Defines the initialization routines for the DLL.

//

 

#include "stdafx.h"

#include "MfcHookApi.h"

#include <TlHelp32.h>

#include <stdio.h>

#include <Shlwapi.h>

 

#pragma comment(lib,"shlwapi.lib")

#pragma comment(lib,"th32.lib")

 

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static   char   THIS_FILE[]=__FILE__;

#endif

 

//

//  Note!

//

//      If this DLL is dynamically linked against the MFC

//      DLLs,any functions exported from this DLL which

//      call into MFC must have the AFX_MANAGE_STATE macro

//      added at the very beginning of the function.

//

//      For example:

//

//      extern "C" BOOL PASCAL EXPORT ExportedFunction()

//      {

//          AFX_MANAGE_STATE(AfxGetStaticModuleState());

//          // normal function body here

//      }

//

//      It is very important that this macro appear in each

//      function,prior to any calls into MFC.  This means that

//      it must appear as the first statement within the

//      function,even before any object variable declarations

//      as their constructors may generate calls into the MFC

//      DLL.

//

//      Please see MFC Technical Notes 33 and 58 for additional

//      details.

//

 

/////////////////////////////////////////////////////////////////////////////

// CMfcHookApiApp

 

BEGIN_MESSAGE_MAP(CMfcHookApiApp,CWinApp)

     //{{AFX_MSG_MAP(CMfcHookApiApp)

         // NOTE - the ClassWizard will add and remove mapping macros here.

         //    DO NOT EDIT what you see in these blocks of generated code!

     //}}AFX_MSG_MAP

END_MESSAGE_MAP()

 

/////////////////////////////////////////////////////////////////////////////

// CMfcHookApiApp construction

 

CMfcHookApiApp::CMfcHookApiApp()

{

     // TODO: add construction code here,

     // Place all significant initialization in InitInstance

}

 

/////////////////////////////////////////////////////////////////////////////

// The one and only CMfcHookApiApp object

 

CMfcHookApiApp theApp;

 

HHOOK   hHook=0;

HINSTANCE   hinstDll=0;

DWORD   dwCurrentPid=0;

DWORD   TargetPid=0;

BOOL   bApiHook= false ;   

FARPROC fpApiAddrA=NULL,fpApiAddrW=NULL;

BYTE   btOldCodeA[5]={0,0,0,0,0};

BYTE   btNewCodeA[5]={0,0,0,0,0};

BYTE   btOldCodeW[5]={0,0,0,0,0};

BYTE   btNewCodeW[5]={0,0,0,0,0};

DWORD   dwProtect=0;

HANDLE   hRemoteProcess32=0,hSnap=0;

//#pragma data_seg()

//#pragma comment(linker,"/SECTION:YuKai,rws")

int   nHookCount=0;

 

char * pcProsessName= "DoWin32Test.exe" ;

 

//---------------------------------------------------------------------------

// 空的钩子函数

LRESULT   WINAPI HookProc( int   nCode, WPARAM   wParam, LPARAM   lParam)

{

     return   CallNextHookEx(hHook,nCode,wParam,lParam);

}

 

extern   "C"   __declspec ( dllexport ) void   ActiveHook()

{

     AFX_MANAGE_STATE(AfxGetStaticModuleState());

}

 

//---------------------------------------------------------------------------

//本函数一定要用WINAPI(即__stdcall),表示本函数自己平衡堆栈(和win32 API一致)

int   WINAPI HookMessageBoxA( HWND   hWnd, LPCTSTR   lpText, LPCTSTR   lpCaption, UINT   uType)

{

     nHookCount++;

     printf ( "HookMessageBoxA hook Success......%d\r\n" ,nHookCount);

     return   1;

     //return ((PfnMessageBox)(addrMsgBoxA))(NULL,"HOOK成功","HOOK成功",MB_ICONINFORMATION);

}

 

//---------------------------------------------------------------------------

//本函数一定要用WINAPI(即__stdcall),表示本函数自己平衡堆栈(和win32 API一致)

int   WINAPI HookMessageBoxW( HWND   hWnd, LPCWSTR   lpText, LPCWSTR   lpCaption, UINT   uType)

{

      

     nHookCount++;

     printf ( "HookMessageBoxW hook Success......%d\r\n" ,nHookCount);

     return   1;

     //return ((PfnMessageBox)(addrMsgBoxW))(NULL,"HOOK成功","HOOK成功",MB_ICONINFORMATION);

}

 

 

//---------------------------------------------------------------------------

// 安装卸载空钩子(ProcessID=NULL:卸载)

extern   "C"   __declspec ( dllexport ) void   InstallHook4Api( HWND   hwnd)

{

     AFX_MANAGE_STATE(AfxGetStaticModuleState());

     //GetWindowThreadProcessId(hwnd,&TargetPid);

     //只hook窗口句柄为hwnd的线程

     if (hwnd)

         hHook=SetWindowsHookEx(WH_GETMESSAGE,(HOOKPROC)HookProc,hinstDll,GetWindowThreadProcessId(hwnd,&TargetPid));

     else

     {

         if (hHook)

             UnhookWindowsHookEx(hHook);

     }

}

 

void   SetHookMessageBox( HMODULE   hModule)

{

     HMODULE   hModuleUser32=0;

     char   cArrDllName[256];

     hinstDll=( HINSTANCE )hModule;

     BOOL   bNext=FALSE;

     PROCESSENTRY32 procEntry32;

     //获取目标进程句柄。

     procEntry32.dwSize= sizeof (PROCESSENTRY32);

     hSnap=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);

     bNext=Process32First(hSnap,&procEntry32);

     while (bNext)

     {

         if (!stricmp(procEntry32.szExeFile,pcProsessName))        //--->>

         {

             hRemoteProcess32=OpenProcess(PROCESS_CREATE_THREAD|PROCESS_VM_WRITE|PROCESS_VM_OPERATION,1,procEntry32.th32ProcessID);

             break ;

         }

         bNext=Process32Next(hSnap,&procEntry32);

     }

     CloseHandle(hSnap);

     dwCurrentPid=procEntry32.th32ProcessID;

     //载入需要HOOK的DLL并保存原始ESP

     hModuleUser32=LoadLibrary( "user32.dll" );

     fpApiAddrA=GetProcAddress(hModuleUser32, "MessageBoxA" );

     if (fpApiAddrA==NULL)

         return ;    

     /*MessageBoxA原前5字节存至OldCode[5]*/

     _asm

     {

         pushad

         lea edi,btOldCodeA

         mov esi,fpApiAddrA

         cld

         movsd

         movsb

         popad

     }

     /*MessageBoxA新前5字节存至 NewCode[5]*/

     btNewCodeA[0]=0xe9;

     _asm

     {

         lea eax,HookMessageBoxA

         mov ebx,fpApiAddrA

         sub eax,ebx

         sub eax,5

         mov dword ptr [btNewCodeA+1],eax

     }

     //修改ESP

     /*改写MessageBoxA()的前5个字节*/

     VirtualProtectEx(hRemoteProcess32,fpApiAddrA,5,PAGE_READWRITE,&dwProtect);

     WriteProcessMemory(hRemoteProcess32,fpApiAddrA,btNewCodeA,5,0);

     VirtualProtectEx(hRemoteProcess32,fpApiAddrA,5,dwProtect,&dwProtect);

     //载入需要HOOK的DLL并保存原始ESP

     fpApiAddrW=GetProcAddress(hModuleUser32, "MessageBoxW" );

     if (fpApiAddrW==NULL)

         return ;    

     /*MessageBoxA原前5字节存至OldCode[5]*/

     _asm

     {

         pushad

         lea edi,btOldCodeW

         mov esi,fpApiAddrW

         cld

         movsd

         movsb

         popad

     }

     /*MessageBoxW新前5字节存至 NewCode[5]*/

     btNewCodeW[0]=0xe9;

     _asm

     {

         lea eax,HookMessageBoxW

         mov ebx,fpApiAddrW

         sub eax,ebx

         sub eax,5

         mov dword ptr [btNewCodeW+1],eax

     }

     /*改写MessageBoxA()的前5个字节*/

     //修改ESP

     VirtualProtectEx(hRemoteProcess32,fpApiAddrW,5,PAGE_READWRITE,&dwProtect);

     WriteProcessMemory(hRemoteProcess32,fpApiAddrW,btNewCodeW,5,0);

     VirtualProtectEx(hRemoteProcess32,fpApiAddrW,5,dwProtect,&dwProtect);

 

     bApiHook= true ;

     //增加引用次数后立即卸钩(目的:卸钩后保留该dll存在于目标进程中)

     GetModuleFileName(( HINSTANCE )hModule,cArrDllName,256);

     LoadLibrary(cArrDllName);

     //只能由目标程序卸钩,否则目标程序有可能来不及加载Hook进来的dll

     if (hHook && (dwCurrentPid==TargetPid))

         UnhookWindowsHookEx(hHook);

      

}

 

void   SetHookDispatchMessage( HMODULE   hModule)

{

     HMODULE   hModuleUser32=0;

     char   cArrDllName[256];

     hinstDll=( HINSTANCE )hModule;

     BOOL   bNext=FALSE;

     PROCESSENTRY32 procEntry32;

     //获取目标进程句柄。

     procEntry32.dwSize= sizeof (PROCESSENTRY32);

     hSnap=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);

     bNext=Process32First(hSnap,&procEntry32);

     while (bNext)

     {

         if (!stricmp(procEntry32.szExeFile,pcProsessName))

         {

             hRemoteProcess32=OpenProcess(PROCESS_CREATE_THREAD|PROCESS_VM_WRITE|PROCESS_VM_OPERATION,1,procEntry32.th32ProcessID);

             break ;

         }

         bNext=Process32Next(hSnap,&procEntry32);

     }

     CloseHandle(hSnap);

     dwCurrentPid=procEntry32.th32ProcessID;

     //载入需要HOOK的DLL并保存原始ESP

     hModuleUser32=LoadLibrary( "user32.dll" );

     fpApiAddrA=GetProcAddress(hModuleUser32, "DispatchMessageA" );

     if (fpApiAddrA==NULL)

         return ;    

     /*MessageBoxA原前5字节存至OldCode[5]*/

     _asm

     {

         pushad

         lea edi,btOldCodeA

         mov esi,fpApiAddrA

         cld

         movsd

         movsb

         popad

     }

     /*MessageBoxA新前5字节存至 NewCode[5]*/

     btNewCodeA[0]=0xe9;

     _asm

     {

         lea eax,HookDispatchMessageA

         mov ebx,fpApiAddrA

         sub eax,ebx

         sub eax,5

         mov dword ptr [btNewCodeA+1],eax

     }

     //修改ESP

     /*改写MessageBoxA()的前5个字节*/

     VirtualProtectEx(hRemoteProcess32,fpApiAddrA,5,PAGE_READWRITE,&dwProtect);

     WriteProcessMemory(hRemoteProcess32,fpApiAddrA,btNewCodeA,5,0);

     VirtualProtectEx(hRemoteProcess32,fpApiAddrA,5,dwProtect,&dwProtect);

 

     //载入需要HOOK的DLL并保存原始ESP

     fpApiAddrW=GetProcAddress(hModuleUser32, "DispatchMessageW" );

     if (fpApiAddrA==NULL)

         return ;    

     /*MessageBoxA原前5字节存至OldCode[5]*/

     _asm

     {

         pushad

         lea edi,btOldCodeW

         mov esi,fpApiAddrW

         cld

         movsd

         movsb

         popad

     }

     /*MessageBoxW新前5字节存至 NewCode[5]*/

     btNewCodeW[0]=0xe9;

     _asm

     {

         lea eax,HookDispatchMessageW

         mov ebx,fpApiAddrW

         sub eax,ebx

         sub eax,5

         mov dword ptr [btNewCodeW+1],eax

     }

     /*改写MessageBoxA()的前5个字节*/

     //修改ESP

     VirtualProtectEx(hRemoteProcess32,fpApiAddrW,5,PAGE_READWRITE,&dwProtect);

     WriteProcessMemory(hRemoteProcess32,fpApiAddrW,btNewCodeW,5,0);

     VirtualProtectEx(hRemoteProcess32,fpApiAddrW,5,dwProtect,&dwProtect);

 

     bApiHook= true ;

     //增加引用次数后立即卸钩(目的:卸钩后保留该dll存在于目标进程中)

     GetModuleFileName(( HINSTANCE )hModule,cArrDllName,256);

     LoadLibrary(cArrDllName);

     //只能由目标程序卸钩,否则目标程序有可能来不及加载Hook进来的dll

     if (hHook && (dwCurrentPid==TargetPid))

         UnhookWindowsHookEx(hHook);

      

}

 

LRESULT   WINAPI HookDispatchMessageA(MSG* msg)

{

     CString szFormat= "" ;

     CString szLog= "" ;

     CTime time ;

     CString szFileName= "" ;

     DWORD   dwFlag=0;

 

     RECT rc;

     TCHAR   szCaption[128];

     //HMODULE hDll=0;

     //DLLDISPATCHMESSAGE dispatch;

     LRESULT   lr=0;

     //hDll=LoadLibrary("user32.dll");

     //if (hDll)

     //{

     //  dispatch=(DLLDISPATCHMESSAGE)GetProcAddress(hDll,"DispatchMessageA");

     //  if (dispatch)

     //  {

     //      lr=(dispatch)(msg);

     //  }

     //}

     VirtualProtectEx(hRemoteProcess32,fpApiAddrA,5,PAGE_READWRITE,&dwProtect);

     WriteProcessMemory(hRemoteProcess32,fpApiAddrA,btOldCodeA,5,0);

     VirtualProtectEx(hRemoteProcess32,fpApiAddrA,5,dwProtect,&dwProtect);

     lr=DispatchMessageA(msg);

 

     //写日志

     szFormat= "%-16X%-16X%-16X%-16X%-16d%-16d%-16X%-16d%-16d%-128s\r\n" ;

     memset (szCaption,0,128);

     if   (IsWindow(msg->hwnd))

     {

         GetWindowRect(msg->hwnd,&rc);

         GetWindowText(msg->hwnd,szCaption,128);

         szLog.Format(szFormat,msg->hwnd,msg->message,msg->wParam,msg->wParam,msg->pt.x,msg->pt.y,msg-> time ,rc.right,rc.bottom,szCaption);

     }

     else

     {

         szLog.Format(szFormat,msg->hwnd,msg->message,msg->wParam,msg->wParam,msg->pt.x,msg->pt.y,msg-> time ,-1,-1,szCaption);

     }

 

     time =CTime::GetCurrentTime();

     szFileName= time .Format( "%Y%m%d%H" );

     szFileName.Insert(0, "C:\\DM" );

     szFileName+= ".log" ;

     dwFlag=CFile::modeReadWrite|CFile::shareDenyRead;

     if   (!PathFileExists(szFileName))

     {

         dwFlag|=CFile::modeCreate;

     }

     CFile fileLog(szFileName,dwFlag);

     fileLog.SeekToEnd();

     fileLog.Write(szLog,szLog.GetLength());

     fileLog.Flush();

     fileLog.Close();

 

     //重新HOOK以便写日志

     VirtualProtectEx(hRemoteProcess32,fpApiAddrA,5,PAGE_READWRITE,&dwProtect); 

     WriteProcessMemory(hRemoteProcess32,fpApiAddrA,btNewCodeA, 5, 0);

     VirtualProtectEx(hRemoteProcess32,fpApiAddrA,5,dwProtect,&dwProtect);

     return   lr;

}

 

LRESULT   WINAPI HookDispatchMessageW(MSG* msg)

{

     CString szFormat= "" ;

     CString szLog= "" ;

     CTime time ;

     CString szFileName= "" ;

     DWORD   dwFlag=0;

 

     RECT rc;

     DWORD   dwThreadId=0;

     TCHAR   szCaption[128];

     //HMODULE hDll=0;

     //DLLDISPATCHMESSAGE dispatch;

     LRESULT   lr=0;

     //hDll=LoadLibrary("user32.dll");

     //if (hDll)

     //{

     //  dispatch=(DLLDISPATCHMESSAGE)GetProcAddress(hDll,"DispatchMessageW");

     //  if (dispatch)

     //  {

     //      lr=(dispatch)(msg);

     //  }

     //}

     //恢复HOOK

     VirtualProtectEx(hRemoteProcess32,fpApiAddrW,5,PAGE_READWRITE,&dwProtect);

     WriteProcessMemory(hRemoteProcess32,fpApiAddrW,btOldCodeW,5,0);

     VirtualProtectEx(hRemoteProcess32,fpApiAddrW,5,dwProtect,&dwProtect);

     lr=DispatchMessageW(msg);

 

     szFormat= "%-16X%-16X%-16X%-16X%-16d%-16d%-16X%-16d%-16d%-16d%-128s\r\n" ;

     memset (szCaption,0,128);

     dwThreadId=GetCurrentThreadId();

     if   (IsWindow(msg->hwnd))

     {

         GetWindowRect(msg->hwnd,&rc);

         GetWindowText(msg->hwnd,szCaption,128);

         szLog.Format(szFormat,msg->hwnd,msg->message,msg->wParam,msg->wParam,msg->pt.x,msg->pt.y,msg-> time ,rc.right,rc.bottom,dwThreadId,szCaption);

     }

     else

     {

         szLog.Format(szFormat,msg->hwnd,msg->message,msg->wParam,msg->wParam,msg->pt.x,msg->pt.y,msg-> time ,-1,-1,dwThreadId,szCaption);

     }

 

     time =CTime::GetCurrentTime();

     szFileName= time .Format( "%Y%m%d%H" );

     szFileName.Insert(0, "C:\\DM" );

     szFileName+= ".log" ;

     dwFlag=CFile::modeReadWrite|CFile::shareDenyRead;

     if   (!PathFileExists(szFileName))

     {

         dwFlag|=CFile::modeCreate;

     }

     CFile fileLog(szFileName,dwFlag);

     fileLog.SeekToEnd();

     fileLog.Write(szLog,szLog.GetLength());

     fileLog.Flush();

     fileLog.Close();

 

     //重新HOOK以便写日志

     VirtualProtectEx(hRemoteProcess32,fpApiAddrW,5,PAGE_READWRITE,&dwProtect); 

     WriteProcessMemory(hRemoteProcess32,fpApiAddrW,btNewCodeW, 5, 0);

     VirtualProtectEx(hRemoteProcess32,fpApiAddrW,5,dwProtect,&dwProtect);

     return   lr;

}

 

BOOL   CMfcHookApiApp::InitInstance()

{

     // TODO: Add your specialized code here and/or call the base class

     SetHookDispatchMessage(GetModuleHandle(NULL));

     //SetHookMessageBox(GetModuleHandle(NULL));

 

     CString szFormat= "" ;

     CString szLog= "" ;

     CTime time ;

     CString szFileName= "" ;

     DWORD   dwFlag=0;

 

     szFormat= "%-16s%-16s%-16s%-16s%-16s%-16s%-16s%-16s%-16s%-16s%-128s\r\n" ;

     szLog.Format(szFormat, "hwnd" , "message" , "wparam" , "lparam" , "mouse.x" , "mouse.y" , "message.time" , "client.width" , "client.height" , "thread id" , "window.caption" );

     time =CTime::GetCurrentTime();

     szFileName= time .Format( "%Y%m%d%H" );

     szFileName.Insert(0, "C:\\DM" );

     szFileName+= ".log" ;

     dwFlag=CFile::modeReadWrite|CFile::shareDenyRead;

     if   (!PathFileExists(szFileName))

     {

         dwFlag|=CFile::modeCreate;

     }

     CFile fileLog(szFileName,dwFlag);

     fileLog.SeekToEnd();

     fileLog.Write(szLog,szLog.GetLength());

     fileLog.Flush();

     fileLog.Close();

 

     return   CWinApp::InitInstance();

}

  5、新建一个测试程序:WIN32项目,取名为:DoWin32Test,代码如下:

?

// DoWin32Test.cpp : Defines the entry point for the application.

//

 

#include "stdafx.h"

#include "resource.h"

 

#define MAX_LOADSTRING 100

 

// Global Variables:

HINSTANCE   hInst;                                // current instance

TCHAR   szTitle[MAX_LOADSTRING];                              // The title bar text

TCHAR   szWindowClass[MAX_LOADSTRING];                                // The title bar text

 

// Foward declarations of functions included in this code module:

ATOM                  MyRegisterClass( HINSTANCE   hInstance);

BOOL                  InitInstance( HINSTANCE , int );

LRESULT   CALLBACK    WndProc( HWND , UINT , WPARAM , LPARAM );

LRESULT   CALLBACK    About( HWND , UINT , WPARAM , LPARAM );

 

int   APIENTRY WinMain( HINSTANCE   hInstance,

                      HINSTANCE   hPrevInstance,

                      LPSTR       lpCmdLine,

                      int         nCmdShow)

{

     // TODO: Place code here.

     MSG msg;

     HACCEL   hAccelTable;

 

     // Initialize global strings

     LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);

     LoadString(hInstance, IDC_DOWIN32TEST, szWindowClass, MAX_LOADSTRING);

     MyRegisterClass(hInstance);

 

     // Perform application initialization:

     if   (!InitInstance (hInstance, nCmdShow))

     {

         return   FALSE;

     }

 

     hAccelTable = LoadAccelerators(hInstance, ( LPCTSTR )IDC_DOWIN32TEST);

 

     // Main message loop:

     while   (GetMessage(&msg, NULL, 0, 0))

     {

         if   (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))

         {

             TranslateMessage(&msg);

             DispatchMessage(&msg);

         }

     }

 

     return   msg.wParam;

}

 

 

 

//

//  FUNCTION: MyRegisterClass()

//

//  PURPOSE: Registers the window class.

//

//  COMMENTS:

//

//    This function and its usage is only necessary if you want this code

//    to be compatible with Win32 systems prior to the 'RegisterClassEx'

//    function that was added to Windows 95. It is important to call this function

//    so that the application will get 'well formed' small icons associated

//    with it.

//

ATOM   MyRegisterClass( HINSTANCE   hInstance)

{

     WNDCLASSEX wcex;

 

     wcex.cbSize = sizeof (WNDCLASSEX);

 

     wcex.style          = CS_HREDRAW | CS_VREDRAW;

     wcex.lpfnWndProc    = (WNDPROC)WndProc;

     wcex.cbClsExtra     = 0;

     wcex.cbWndExtra     = 0;

     wcex.hInstance      = hInstance;

     wcex.hIcon          = LoadIcon(hInstance, ( LPCTSTR )IDI_DOWIN32TEST);

     wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);

     wcex.hbrBackground  = ( HBRUSH )(COLOR_WINDOW+1);

     wcex.lpszMenuName   = ( LPCSTR )IDC_DOWIN32TEST;

     wcex.lpszClassName  = szWindowClass;

     wcex.hIconSm        = LoadIcon(wcex.hInstance, ( LPCTSTR )IDI_SMALL);

 

     return   RegisterClassEx(&wcex);

}

 

//

//   FUNCTION: InitInstance(HANDLE, int)

//

//   PURPOSE: Saves instance handle and creates main window

//

//   COMMENTS:

//

//        In this function, we save the instance handle in a global variable and

//        create and display the main program window.

//

BOOL   InitInstance( HINSTANCE   hInstance, int   nCmdShow)

{

    HWND   hWnd;

 

    hInst = hInstance; // Store instance handle in our global variable

 

    hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,

       CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

 

    if   (!hWnd)

    {

       return   FALSE;

    }

 

    ShowWindow(hWnd, nCmdShow);

    UpdateWindow(hWnd);

 

    return   TRUE;

}

 

//

//  FUNCTION: WndProc(HWND, unsigned, WORD, LONG)

//

//  PURPOSE:  Processes messages for the main window.

//

//  WM_COMMAND  - process the application menu

//  WM_PAINT    - Paint the main window

//  WM_DESTROY  - post a quit message and return

//

//

LRESULT   CALLBACK WndProc( HWND   hWnd, UINT   message, WPARAM   wParam, LPARAM   lParam)

{

     int   wmId, wmEvent;

     PAINTSTRUCT ps;

     HDC   hdc;

     TCHAR   szHello[MAX_LOADSTRING];

     LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);

 

     switch   (message)

     {

         case   WM_COMMAND:

             wmId    = LOWORD(wParam);

             wmEvent = HIWORD(wParam);

             // Parse the menu selections:

             switch   (wmId)

             {

                 case   IDM_ABOUT:

                    DialogBox(hInst, ( LPCTSTR )IDD_ABOUTBOX, hWnd, (DLGPROC)About);

                    break ;

                 case   IDM_EXIT:

                    DestroyWindow(hWnd);

                    break ;

                 default :

                    return   DefWindowProc(hWnd, message, wParam, lParam);

             }

             break ;

         case   WM_PAINT:

             hdc = BeginPaint(hWnd, &ps);

             // TODO: Add any drawing code here...

             RECT rt;

             GetClientRect(hWnd, &rt);

             DrawText(hdc, szHello, strlen (szHello), &rt, DT_CENTER);

             EndPaint(hWnd, &ps);

             break ;

         case   WM_DESTROY:

             PostQuitMessage(0);

             break ;

         default :

             return   DefWindowProc(hWnd, message, wParam, lParam);

    }

    return   0;

}

 

// Mesage handler for about box.

LRESULT   CALLBACK About( HWND   hDlg, UINT   message, WPARAM   wParam, LPARAM   lParam)

{

     switch   (message)

     {

         case   WM_INITDIALOG:

                 return   TRUE;

 

         case   WM_COMMAND:

             if   (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)

             {

                 EndDialog(hDlg, LOWORD(wParam));

                 return   TRUE;

             }

             break ;

     }

     return   FALSE;

}

  最后,记得修改所有项目的生成目录,令所有项目生成到一个目录。我设置的方法是直接在默认生成目录前加“..\”。祝你成功。

 

 

分类:  Windows SDK/MFC

标签:  HookApi ,  SetWindowsHookEx ,  DispatchMessage

作者: Leo_wl

    

出处: http://www.cnblogs.com/Leo_wl/

    

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权信息

查看更多关于HookApi例子的详细内容...

  阅读:41次