安全放心的免费绿色软件下载网站!

64位Windows 7 系统 HookApi编程实例

时间:2022-09-16 14:39:33

本程序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 ", GetLastError());
return FALSE;
}
if( !LookupPrivilegeValue(NULL,
lpszPrivilege,
&luid) )
{
_tprintf("LookupPrivilegeValue error: %u ", 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 ", GetLastError() );
return FALSE;
}
if( GetLastError() == ERROR_NOT_ALL_ASSIGNED )
{
_tprintf("The token does not have the specified privilege. ");
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 ",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 ",sizeWritten,pRemoteBuf);
}
else
{
printf("InjectCreate()-->WriteProcessMemory() Error:%ld ",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 ",hThreadHandle,dwThreadId);
//}
//else
//{
// printf("CreateRemoteThread Error:%ld ",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. ");
for (int i=0;i<30;i++)
{
Sleep(1000);
printf(".");
}
printf(" ");
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 ",sizeWritten,pRemoteBuf);
}
else
{
printf("InjectCreate()-->WriteProcessMemory() Error:%ld ",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 ",hThreadHandle,dwThreadId);
//}
//else
//{
// printf("CreateRemoteThread Error:%ld ",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 ",GetLastError());
return FALSE;
}
((PFNTCREATETHREADEX)pFunc)(&hThread,
0x1FFFFF,
NULL,
hProcess,
pThreadProc,
pRemoteBuf,
FALSE,
NULL,
NULL,
NULL,
NULL);
if( hThread == NULL )
{
printf("InjectCreateThread()-->NtCreateThreadEx() Error: %d ", GetLastError());
return FALSE;
}
else
{
printf("InjectCreateThread()-->NtCreateThreadEx() Success,Thread Id:%ld ",hThread);
}
}
else // 2000, XP, Server2003
{
hThread = CreateRemoteThread(hProcess,
NULL,
0,
pThreadProc,
pRemoteBuf,
0,
NULL);
if( hThread == NULL )
{
printf("InjectCreateThread()-->CreateRemoteThread() Error: %d ", GetLastError());
return FALSE;
}
else
{
printf("InjectCreateThread()-->CreateRemoteThread() Success,Thread Id:%ld ",hThread);
}
}
if( WAIT_FAILED == WaitForSingleObject(hThread, INFINITE) )
{
printf("InjectCreateThread() : WaitForSingleObject() Error: %d ", 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 ",dwThreadId);
}
else
{
printf("MsicCreateRemoteThread()-->CreateRemoteThread() Error:%ld ",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 ",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 ",pMisc);
//Patch
*pMisc=1;
//xx
hNewThread=CreateRemoteThread(hProcess,NULL,0,lpStartAddress,lpParameter,0,&dwThreadId);
if (dwThreadId)
{
printf("MsicCreateRemoteThread()-->CreateRemoteThread() Success,Thread Id:%08X ",dwThreadId);
}
else
{
printf("MsicCreateRemoteThread()-->CreateRemoteThread() Error:%ld ",GetLastError());
}
//UnPatch
*pMisc=0;
}
while(FALSE);
if(NULL!=hKernelBase)
{
printf("MsicCreateRemoteThread()-->hKernelBase:%08X ",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_)

4、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 ",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 ",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 ";
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 ";
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 ";
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;
}
最后,记得修改所有项目的生成目录,令所有项目生成到一个目录。我设置的方法是直接在默认生成目录前加“..”。祝你成功。

相关文章
蚂蚁庄园今日答案奥运会 奥运会选手住宿的地方叫什么
蚂蚁庄园今日答案奥运会 奥运会选手住宿的地方叫什么

蚂蚁庄园今日答案奥运会?这是支付宝中蚂蚁庄园玩法8月2日小课堂的问题,答对即可获得一份180g小鸡宝宝饲料作为奖励。那么接下来就让我们一起了解一下8月2日蚂蚁庄园的正确答案吧!

电脑老是自动重启是什么原因?电脑老是自动重启怎么解决?
电脑老是自动重启是什么原因?电脑老是自动重启怎么解决?

电脑老是自动重启怎么办?这个问题想必不少小伙伴们都遇到过,特别是在我们工作的时候,很多重要的文件都没有保存,自动重启之后很多重要文件丢失,还是很苦恼的,那么这是什么原

手机系统重装步骤教程
手机系统重装步骤教程

有时候手机很卡,使用起来非常不方便怎么办。这个时候一般可以通过手机系统重装解决。下面小编来跟大家说说手机系统重装该怎么操作。 工具/原料: 品牌型号:华为 软件版本:刷机

阴阳师cdk在哪兑换 2019阴阳师在哪儿兑换CDKEY礼包
阴阳师cdk在哪兑换 2019阴阳师在哪儿兑换CDKEY礼包

阴阳师的cdk礼包,要在庭院左侧的许愿架处,点击灯笼,出现兑换码框,接着便可以输入自己的兑换码,就可以得到相应的礼包。cdk礼包目前只有安卓版才能领取,ios暂不支持许愿架兑换码。

无人深空赚钱攻略介绍 无人深空赚钱攻略2022最容易方法介绍
无人深空赚钱攻略介绍 无人深空赚钱攻略2022最容易方法介绍

无人深空是一款太空科幻类型游戏,在游戏中玩家将会体验到深空中的寂寥,探索不断生成的星球,体验更多有趣的宇宙变化,对于喜欢科幻太空作品的玩家们来说本作十分的符合口味。这

心遇app聊天真的能赚钱吗?心遇交友是正规平台吗?
心遇app聊天真的能赚钱吗?心遇交友是正规平台吗?

心遇app作为交友软件,不仅可以和周围的好友交流,多种交流方式,而且还可以聊天赚钱,那这个心遇交友是正规平台吗?真的可以赚钱吗?下面就和小编一起来看看吧。 心遇app聊天真的

相关软件
京东茅台抢购神器v1.5 免费版
京东茅台抢购神器v1.5 免费版
大小:2.2M 时间:2021-09-24
下载

京东茅台抢购神器是为喜欢茅台的用户准备的京东下单工具,能够帮助用户在京东上自动下单购买原价飞天茅台,能够在出货的一瞬间就锁定订单,帮助你进行抢购,有需要的用户不要错过

离开手机v1.0
离开手机v1.0
大小:4.9MB 时间:2020-09-04
下载

  离开手机软件是一款专门来防止用户沉迷手机的工具,用户可以在上面详细的看到手机里面每个应用的实用时间,还应用多种提醒效果,离开手机app专门提醒用户放下手机,做一些有意义的事情。需要的朋友快下载离开手机体验吧

华新链智v1.0.3
华新链智v1.0.3
大小:24.5M 时间:2023-05-30
下载

华新链智app是一款能为大家 提供智能学习服务的教育软件,华新链智app上汇集了海量写学习课程,可以让你快速学到自己想学的知识,让自己不断地进步,华新链智软件帮助你找到适合自

企胜力v2.0.8
企胜力v2.0.8
大小:63.3MB 时间:2020-10-17
下载

企胜力是一款十分功能强大的公司培训软件,这款手机app合适公司和组织客户来应用,课程丰富多彩,线上与线下都能够学习培训,能够查询全新的学习任务,能够学知识文本文档和参加课程直播间! 手机软件详细介绍 世华科技产品研发的一款根据云计算技术和互联网大数据的saa

爱奇艺漫画v1.7.5
爱奇艺漫画v1.7.5
大小:44.1M 时间:2020-11-13
下载

爱奇艺漫画安装免费版是一款绿色又安全的正版漫画阅读软件。爱奇艺漫画为大家呈现了来自国内国外多个国家的各种类型的漫画资源,通过爱奇艺漫画可以让大家一饱眼福! 软件介绍 爱

射击幽灵v1.0
射击幽灵v1.0
大小:60.0M 时间:2022-11-07
下载

射击幽灵下载,射击幽灵游戏是一款由深圳市指点天下科技有限公司开发的生存生存类型手游,射击幽灵游戏中你化身为一个普通参赛者,其中有50个和你一样的普通玩家,参与游戏中努力过关才能活到最后。