• Windows 7 64位 HookApi例子


    转载请注明来源:http://www.cnblogs.com/xuesongshu/

      本程序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;
    }
    

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

  • 相关阅读:
    关于Tomcat的那些事儿(一)
    关于Spring的问题(一)
    关于Spring的@RequestBody的使用
    关于Eclipse切换所有分支
    关于使用BetterIntelliJ激活IntelliJ IDEA
    关于Elasticsearch的问题(一)
    关于Elasticsearch那些事
    关于LRU算法及Java实现
    自定义滚动条
    创建型模式之建造者模式
  • 原文地址:https://www.cnblogs.com/xuesongshu/p/hookapi.html
Copyright © 2020-2023  润新知