Windows 7 64位 HookApi例子

来源:互联网 发布:360全景效果图软件 编辑:程序博客网 时间:2024/06/13 12:07
转载请注明来源: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_MSGDECLARE_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_FILEstatic 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.///////////////////////////////////////////////////////////////////////////////// CMfcHookApiAppBEGIN_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_MAPEND_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////// CMfcHookApiApp constructionCMfcHookApiApp::CMfcHookApiApp(){// TODO: add construction code here,// Place all significant initialization in InitInstance}/////////////////////////////////////////////////////////////////////////////// The one and only CMfcHookApiApp objectCMfcHookApiApp 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并保存原始ESPhModuleUser32=LoadLibrary("user32.dll");fpApiAddrA=GetProcAddress(hModuleUser32,"MessageBoxA");if(fpApiAddrA==NULL) return;/*MessageBoxA原前5字节存至OldCode[5]*/_asm{pushadlea edi,btOldCodeAmov esi,fpApiAddrAcldmovsdmovsbpopad}/*MessageBoxA新前5字节存至 NewCode[5]*/btNewCodeA[0]=0xe9;_asm{lea eax,HookMessageBoxAmov ebx,fpApiAddrAsub eax,ebxsub eax,5mov 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并保存原始ESPfpApiAddrW=GetProcAddress(hModuleUser32,"MessageBoxW");if(fpApiAddrW==NULL) return;/*MessageBoxA原前5字节存至OldCode[5]*/_asm{pushadlea edi,btOldCodeWmov esi,fpApiAddrWcldmovsdmovsbpopad}/*MessageBoxW新前5字节存至 NewCode[5]*/btNewCodeW[0]=0xe9;_asm{lea eax,HookMessageBoxWmov ebx,fpApiAddrWsub eax,ebxsub eax,5mov dword ptr [btNewCodeW+1],eax}/*改写MessageBoxA()的前5个字节*///修改ESPVirtualProtectEx(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进来的dllif(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并保存原始ESPhModuleUser32=LoadLibrary("user32.dll");fpApiAddrA=GetProcAddress(hModuleUser32,"DispatchMessageA");if(fpApiAddrA==NULL) return;/*MessageBoxA原前5字节存至OldCode[5]*/_asm{pushadlea edi,btOldCodeAmov esi,fpApiAddrAcldmovsdmovsbpopad}/*MessageBoxA新前5字节存至 NewCode[5]*/btNewCodeA[0]=0xe9;_asm{lea eax,HookDispatchMessageAmov ebx,fpApiAddrAsub eax,ebxsub eax,5mov 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并保存原始ESPfpApiAddrW=GetProcAddress(hModuleUser32,"DispatchMessageW");if(fpApiAddrA==NULL) return;/*MessageBoxA原前5字节存至OldCode[5]*/_asm{pushadlea edi,btOldCodeWmov esi,fpApiAddrWcldmovsdmovsbpopad}/*MessageBoxW新前5字节存至 NewCode[5]*/btNewCodeW[0]=0xe9;_asm{lea eax,HookDispatchMessageWmov ebx,fpApiAddrWsub eax,ebxsub eax,5mov dword ptr [btNewCodeW+1],eax}/*改写MessageBoxA()的前5个字节*///修改ESPVirtualProtectEx(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进来的dllif(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);//}//}//恢复HOOKVirtualProtectEx(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 classSetHookDispatchMessage(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 instanceTCHAR szTitle[MAX_LOADSTRING];// The title bar textTCHAR szWindowClass[MAX_LOADSTRING];// The title bar text// Foward declarations of functions included in this code module:ATOMMyRegisterClass(HINSTANCE hInstance);BOOLInitInstance(HINSTANCE, int);LRESULT CALLBACKWndProc(HWND, UINT, WPARAM, LPARAM);LRESULT CALLBACKAbout(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 stringsLoadString(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;}

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

2 0
原创粉丝点击