64位Windows 7 系统 HookApi编程实例
本程序HOOK的API是DispatchMessageA和DispatchMessageW。在HOOK的方法内会还原ESP,调用user32.DispathMessage(A或W)之后再修改ESP,实现的功能是记录消息的详细日志,记录哪个窗口处理过哪些消息。 1、新
本程序钩的应用程序接口是调度消息a和DispatchMessageW。在钩的方法内会还原ESP,调用用户32。DispathMessage(A或w)之后再修改ESP,实现的功能是记录消息的详细日志,记录哪个窗口处理过哪些消息。1、新建一个win32 console项目,取名为注射毒品,新建一个DoInjectionMain.h,代码如下:
BOOL set特权(LPCTSTR lpsz特权,BOOL benable特权);
BOOL isvisatorlater();
BOOL注入过程();
BOOL InjectCreateProcess();
void hook getmessage();
BOOL InjectCreateThread(HANDLE h process,LPTHREAD _ START _ ROUTINE pThreadProc,LPVOID pRemoteBuf);
HANDLE MsicCreateRemoteThread(HANDLE h进程,LPTHREAD _ START _ ROUTINE lpStartAddress,LPVOID LP参数);
typedef void *(_ _ stdcall * LPFN _ KernelBaseGetGlobalData)(void);
typedef DWORD(WINAPI * PFNTCREATETHREADEX)
(
PHANDLE ThreadHandle,
ACCESS_MASK DesiredAccess,
LPVOID对象属性,
句柄进程句柄,
LP线程_开始_例程LP开始地址,
LPVOID lpParameter,
布尔创造了暂停,
DWORD dwStackSize,
DWORD dw1,
DWORD dw2,
LPVOID未知
);
2、新建一个DoInjectionMain.c(不是CPP),代码如下:
#包含windows.h
#包含标准视频
#包含tlhelp32.h
#包含查尔. h
# include ' DoInjection.h '
#杂注注释(lib,' th32.lib ')
#杂注注释(lib,' Advapi32.lib ')
//这个路径很有意思,这个路径是相对于目标进程的,而不是自身进程。
//所以要嘛写成绝对路径,要嘛写成相对于目标进程的相对路径。
//如果写成相对于自身的路径就要麻烦了,本程序就找不到动态链接库文件了。
const char * pcDllName=' mfchookapi。dll ';//DLL文件的路径
HANDLE hSnap=0,hThreadHandle=0,hRemoteProcess32=0,hTokenHandle=0;
程序输入32程序输入32;
BOOL bNext=FALSE,bWrittenResult=FALSE
令牌_特权令牌权;
标识符路德鲍尔;
LPVOID pRemoteBuf=NULL
FARPROC fnDllKernel32
size _ t size写入=0;
DWORD dwThreadId=0;
char * pcproessname=' dowin 32测试。exe ';//要注入的进程名(目标进程名)
int main()
{
is visator la ter();
SetPrivilege(SE_DEBUG_NAME,TRUE);
//注入进程();
InjectCreateProcess();
getchar();
返回0;
}
BOOL set特权(LPCTSTR lpsz特权,BOOL benable特权)
{
令牌_特权tp
处理托肯
标识符流体;
如果(!OpenProcessToken(GetCurrentProcess(),
令牌_调整_权限|令牌_查询,
hToken))
{
_tprintf('OpenProcessToken错误: %u
,GetLastError());
返回错误的
}
如果(!LookupPrivilegeValue(NULL,
lpszPrivilege,
luid))
{
_ tprintf(' LookupPrivilegeValue错误:% u
,GetLastError());
返回错误的
}
tp .PrivilegeCount=1;
tp .权限[0]。流体=流体
if( bEnablePrivilege)
tp .权限[0]。属性=SE _特权_已启用
其他
tp .权限[0]。属性=0;
如果(!AdjustTokenPrivileges(hToken,
假的,
tp,
sizeof(令牌特权),
(PTOKEN_PRIVILEGES) NULL,
(PDWORD) NULL))
{
_ tprintf(' AdjustTokenPrivileges错误: %u
,GetLastError());
返回错误的
}
if(GetLastError()==ERROR _ NOT _ ALL _ ASSIGNED)
{
_tprintf('该令牌没有指定的权限。
');
返回错误的
}
返回真实的
}
BOOL IsVistaOrLater()
{
OSVERSIONINFO osvi
ZeroMemory(osvi,sizeof(OS版本信息));
//OSVERSIONINFOEX OS VIX;
//ZeroMemory(osvix,sizeof(OS版本infoex));
奥斯威。dwosversioninfosize=sizeof(OSVERSIONINFO);
GetVersionEx(osvi);
printf('网络终端v%ld .%ld,%s,平台:%ld,内部版本号:%ld
、osvi.dwMajorVersion、osvi.dwMinorVersion、osvi.szCSDVersion、osvi.dwPlatformId、osvi。dwbuildnumber);
if( osvi.dwMajorVersion=6)
返回真实的
返回错误的
}
布尔注入过程()
{
处理32号入口。dwsize=sizeof(进程条目32);
hs nap=createtoolhelp 32 snapshot(th 32 cs _ snap process,0);
bNext=Process32First(hSnap,proce entry 32);
while(bNext)
{
如果(!stricmp(procEntry32.szExeFile,pcproessname))//-
{
hremoteprocess 32=open PROCESS(PROCESS _ CREATE _ THREAD | PROCESS _ VM _ WRITE | PROCESS _ VM _ OPERATION,1,procentry 32。th 32 processid);
打破;
}
bNext=Process32Next(hSnap,proce entry 32);
}
关闭手柄(hs nap);
pRemoteBuf=virtualallocx(hremoteprocess 32,NULL,strlen(pcDllName),MEM _提交,页面_读写);
bWrittenResult=WriteProcessMemory(hRemoteProcess32,pRemoteBuf,pcDllName,strlen(pcDllName),(ULONG *)大小写入);
if (bWrittenResult)
{
printf(' inject create()-writeprocessmemory()成功,写入大小:%ld,缓冲区address:X
,sizeWritten,pRemoteBuf);
}
其他
{
printf(' inject create()-WriteProcessMemory()错误:%ld
,GetLastError());
}
fndllkernel 32=GetProcAddress(GetModuleHandle(' kernel 32。dll ')、' loadlibrary a ');
//hThreadHandle=CreateRemoteThread(hremote process 32,NULL,0,(LPTHREAD _ START _ ROUTINE)fndllkernel 32,pAllocMemory,0,dwThreadId);
//if (hThreadHandledwThreadId)
//{
//printf('CreateRemoteThread成功,句柄:%ld,线程Id:%ld
、hThreadHandle、dwThreadId);
//}
//否则
//{
//printf('CreateRemoteThread错误:%ld
,GetLastError());
//}
InjectCreateThread(hremote process 32,(LPTHREAD _ START _ ROUTINE)fndllkernel 32,pRemoteBuf);
//MsicCreateRemoteThread(hremote process 32,(LPTHREAD _ START _ ROUTINE)fndllkernel 32,pRemoteBuf);
VirtualFreeEx(hRemoteProcess32,pRemoteBuf,0,MEM _ RELEASE);
关闭句柄(hremoteprocess 32);
返回真实的
}
BOOL InjectCreateProcess()
{
过程_信息pi;
一些必备参数设置
处理32号入口。dwsize=sizeof(进程条目32);
ZeroMemory(pi,sizeof(PROCESS _ INFORMATION));
ZeroMemory(si,sizeof(启动信息));
是的。CB=sizeof(启动信息);
CreateProcess(NULL,pcProsessName,NULL,NULL,false,0,NULL,NULL,si,pi);
hRemoteProcess32=pi.hProcess
请等待30秒。
');
for(int I=0;i30我)
{
睡眠(1000);
printf(' . ');
}
printf('
');
pRemoteBuf=virtualallocx(hremoteprocess 32,NULL,strlen(pcDllName),MEM _提交,页面_读写);
bWrittenResult=WriteProcessMemory(hRemoteProcess32,pRemoteBuf,pcDllName,strlen(pcDllName),(ULONG *)大小写入);
if (bWrittenResult)
{
printf(' inject create()-writeprocessmemory()成功,写入大小:%ld,缓冲区address:X
,sizeWritten,pRemoteBuf);
}
其他
{
printf(' inject create()-WriteProcessMemory()错误:%ld
,GetLastError());
}
fndllkernel 32=GetProcAddress(GetModuleHandle(' kernel 32。dll ')、' loadlibrary a ');
//hThreadHandle=CreateRemoteThread(hremote process 32,NULL,0,(LPTHREAD _ START _ ROUTINE)fndllkernel 32,pAllocMemory,0,dwThreadId);
//if (hThreadHandledwThreadId)
//{
//printf('CreateRemoteThread成功,句柄:%ld,线程Id:%ld
、hThreadHandle、dwThreadId);
//}
//否则
//{
//printf('CreateRemoteThread错误:%ld
,GetLastError());
//}
//InjectCreateThread(hremote process 32,(LPTHREAD _ START _ ROUTINE)fndllkernel 32,pRemoteBuf);
MsicCreateRemoteThread(hremote process 32,(LPTHREAD _ START _ ROUTINE)fndllkernel 32,pRemoteBuf);
//VirtualFreeEx(hremoteprocess 32,pRemoteBuf,0,MEM _ RELEASE);
//关闭句柄(hremoteprocess 32);
返回真实的
}
BOOL InjectCreateThread(HANDLE h process,LPTHREAD _ START _ ROUTINE pThreadProc,LPVOID pRemoteBuf)
{
句柄hThread=NULL
FARPROC pFunc=NULL
if(isvisator later())//Vista,7,Server2008
{
pf unc=GetProcAddress(GetModuleHandle(' ntdll。dll ')、' NtCreateThreadEx ');
if( pFunc==NULL)
{
printf(' InjectCreateThread()-GetProcAddress(' NtCreateThreadEx ')错误%d
,GetLastError());
返回错误的
}
((PFNTCREATETHREADEX)pFunc)(hThread,
0x1FFFFF,
空,
hProcess,
pThreadProc,
前蟾蜍,
假的,
空,
空,
空,
NULL);
if( hThread==NULL)
{
printf(' InjectCreateThread()-NtCreateThreadEx()错误: %d
,GetLastError());
返回错误的
}
其他
{
printf(' InjectCreateThread()-NtCreateThreadEx()成功,线程Id:%ld
,hThread);
}
}
else //2000,XP,Server2003
{
hThread=CreateRemoteThread(hProcess,
空,
0,
pThreadProc,
前蟾蜍,
0,
NULL);
if( hThread==NULL)
{
printf(' InjectCreateThread()-createremotethead()错误: %d
,GetLastError());
返回错误的
}
其他
{
printf(' InjectCreateThread()-createremotethead()成功,线程Id:%ld
,hThread);
}
}
if(WAIT _ FAILED==WaitForSingleObject(hThread,INFINITE))
{
printf(' InjectCreateThread(): WaitForSingleObject()错误: %d
,GetLastError());
返回错误的
}
返回真实的
}
typedef void *(_ _ stdcall * LPFN _ KernelBaseGetGlobalData)(void);
HANDLE MsicCreateRemoteThread(HANDLE h process,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;
字wCode=0;
做
{
stosversioninfoex。dwosversioninfosize=sizeof(OSVERSIONINFOEX);
如果(!GetVersionEx((操作系统版本信息*)stOSVersionInfoEx))
{
打破;
}
//vista以前的系统不存在这个问题
if((stosversioninfoex。dw major version 6)| |(GetCurrentProcess()==h process))
{
hNewThread=CreateRemoteThread(h process,NULL,0,lpStartAddress,lpParameter,0,dwThreadId);
if (dwThreadId)
{
printf(' msiccreateremotethread()-createremotethread()成功,线程Id:X
,dwThreadId);
}
其他
{
printf(' MsicCreateRemoteThread()-CreateRemoteThread()错误:%ld
,GetLastError());
}
打破;
}
if((stosversioninfoex。dw主版本==6)(0==stosversioninfoex。dwminorversion))
{
//vista
hkernel 32=loadlibrary a(' kernel 32。dll’);
pCreateRemoteThread=(UCHAR *)GetProcAddress(hkernel 32,' CreateRemoteThread ');
for(ulIndex=0;ulIndex0x300ulIndex=1)
{
wCode=*((USHORT *)(pcreateremotethadeluindex));
#ifdef _WIN64
if(0x3D80==wCode)
{
pMisc=(*((ULONG *)(pcreateremotethadeluindex 2))(pcreateremotethadeluindex 7);
打破;
}
#否则
if(0x1D38==wCode)
{
pMisc=(UCHAR *)(*((ULONG *)(pcreateremotethadeluindex 2)));
打破;
}
#endif
}
}
else if((stosversioninfoex。dw主版本==6)(1==stosversioninfoex。dwminorversion))
{
//win7
hKernelBase=loadlibrary w(L '内核基。dll’);
if(NULL==hKernelBase)
{
打破;
}
pKernelBaseGetGlobalData=(LPFN _ KernelBaseGetGlobalData)GetProcAddress(hKernelBase,' KernelBaseGetGlobalData ');
printf(' msiccreateremotethread()-kernelbasegetglobaldata:x
,pKernelBaseGetGlobalData);
if(NULL==pKernelBaseGetGlobalData)
{
打破;
}
pGlobalData=(UCHAR *)pKernelBaseGetGlobalData();
if(NULL==pGlobalData)
{
打破;
}
#ifdef _WIN64
pMisc=pGlobalData0x5C
#否则
pMisc=pGlobalData0x30
#endif
}
其他
{
//手上的win8内部版本8250没有会议隔离
}
//////////////////////////////////////////////////////////////////////////
if(NULL==pMisc)
{
打破;
}
printf(' msiccreateremotethread()-pmisc : x
,pMisc);
//补丁
* pMisc=1;
//xx
hNewThread=CreateRemoteThread(h process,NULL,0,lpStartAddress,lpParameter,0,dwThreadId);
if (dwThreadId)
{
printf(' msiccreateremotethread()-createremotethread()成功,线程Id:X
,dwThreadId);
}
其他
{
printf(' MsicCreateRemoteThread()-CreateRemoteThread()错误:%ld
,GetLastError());
}
//取消匹配
* pMisc=0;
}
而(假);
if(NULL!=hKernelBase)
{
printf(' msiccreateremotethread()-hkernelbase:x
,hKernelBase);
免费图书馆(hKernelBase);
hKernelBase=NULL
}
返回hNewThread
}
void HookGetMessage()
{
HOOKPROC hp
//SetWindowsHookEx(WH _获取消息,惠普,)
}3、新建一个mfc的DLL项目,命名为 MfcHookApi.dll,MfcHookApi.h的代码如下:
//MFCHOOKAPI。h : MFCHOOKAPI DLL的主头文件
//
#如果!已定义(AFX _ MFCHOOKAPI _ H _ _ 6a 8f C5 e 5 _ 0e 77 _ 4b 74 _ 8344 _ cb9ca 22141 E5 _ _ INCLUDED _)
# define AFX _ MFCHOOKAPI _ H _ _ 6a 8f C5 e 5 _ 0e 77 _ 4b 74 _ 8344 _ cb9ca 22141 E5 _ _ INCLUDED _
# VER国际机场1000
#杂注一次
#endif //_MSC_VER 1000
#ifndef __AFXWIN_H__
#错误:在包含预编译头文件的此文件之前包含" stdafx.h "
#endif
#include 'resource.h' //主符号
/////////////////////////////////////////////////////////////////////////////
//CMfcHookApiApp
//如需这个类别的实作,请参阅MfcHookApi.cpp
//
CMfcHookApiApp :类公共对象
{
公共:
CMfcHookApiApp();
//覆盖
//类向导生成的虚函数重写
//{{AFX_VIRTUAL(CMfcHookApiApp)
公共:
虚拟BOOL InitInstance();
//}}AFX_VIRTUAL
//{{AFX_MSG(CMfcHookApiApp)
//注意类别向导将在这里添加和移除成员函数。
//不要编辑您在这些生成代码块中看到的内容!
//}}AFX_MSG
声明消息映射()
};
extern ' C ' _ _ declspec(dll导出)void active hook();
extern ' C ' _ _ declspec(dll导出)void安装挂钩4 API(HWND HWND);
int * addrMsgBoxA=(int *)messagebox a;
int * addrMsgBoxW=(int *)MessageBoxW;
int WINAPI hook messagebox a(HWND HWND,LPCSTR lpText,LPCSTR lpCaption,UINT uType);
int WINAPI hook messageboxw(HWND HWND,LPCWSTR lpText,LPCWSTR lpCaption,UINT uType);
void set hook messagebox(HMODULE HMODULE);
typedef int(WINAPI * PfnMessageBox)(HWND,LPCSTR,LPCSTR,UINT);
int * addrDispatchA=(int *)调度消息a;
int * addrDispatchW=(int *)调度消息w;
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 #将在前一行之前插入附加声明。
#endif //!已定义(AFX _ MFCHOOKAPI _ H _ _ 6a 8f C5 e 5 _ 0e 77 _ 4b 74 _ 8344 _ cb9ca 22141 E5 _ _ INCLUDED _)
4、MfcHookApi.cpp代码如下:
//MfcHookApi.cpp :定义动态链接库的初始化例程。
//
#include 'stdafx.h '
#包含" MfcHookApi.h "
#包含TlHelp32.h
#包含标准视频
#包含Shlwapi.h
#杂注注释(lib,' shlwapi.lib ')
#杂注注释(lib,' th32.lib ')
#ifdef _DEBUG
#定义新的调试_新
#undef THIS_FILE
static char THIS _ FILE[]=_ _ FILE _ _;
#endif
//
//注意!
//
//如果此动态链接库是针对MS-VisualC++的类库(Microsoft Foundation Class的缩写)动态链接的
//DLL,从此动态链接库导出的任何函数
//对MS-VisualC++的类库(Microsoft Foundation Class的缩写)的调用必须有AFX _管理_状态宏
//添加在函数的最开始。
//
//例如:
//
//extern ' C ' BOOL PASCAL EXPORT导出函数()
//{
//AFX _ MANAGE _ STATE(AfxGetStaticModuleState());
////这里是普通的函数体
//}
//
//这个宏出现在每个
//函数,在对MS-VisualC++的类库(Microsoft Foundation Class的缩写)的任何调用之前。这意味着
//它必须作为中的第一条语句出现
//函数,甚至在任何对象变量声明之前
//因为它们的构造函数可能会生成对MS-VisualC++的类库(Microsoft Foundation Class的缩写)的调用
//DLL .
//
//有关更多信息,请参见MS-VisualC++的类库(Microsoft Foundation Class的缩写)技术说明33和58
//详情。
//
/////////////////////////////////////////////////////////////////////////////
//CMfcHookApiApp
BEGIN _ MESSAGE _ MAP(CMfcHookApiApp,CWinApp)
//{{AFX_MSG_MAP(CMfcHookApiApp)
//注意类别向导将在这里添加和移除映射宏。
//不要编辑您在这些生成代码块中看到的内容!
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
//CMfcHookApiApp构造
cmfchookapiapp : cmfchookapiapp()
{
//TODO:此处添加构造代码,
//将所有重要的初始化放在初始实例中
}
/////////////////////////////////////////////////////////////////////////////
//唯一的CMfcHookApiApp对象
CMfcHookApiApp theApp
HHOOK HHOOK=0;
h实例hinst dll=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 dw protect=0;
HANDLE hRemoteProcess32=0,hs nap=0;
//#杂注data_seg()
//#杂注注释(链接器,'/SECTION:YuKai,rws ')
int nHookCount=0;
char * pcproessname=' dowin 32测试。exe ';
//-
//空的钩子函数
LRESULT WINAPI HookProc(int nCode,WPARAM wParam,LPARAM lParam)
{
返回CallNextHookEx(hHook,nCode,wParam,lParam);
}
extern ' C ' _ _ declspec(dll导出)void活动挂钩()
{
AFX _ MANAGE _ STATE(AfxGetStaticModuleState());
}
//-
//本函数一定要用WINAPI(即__stdcall),表示本函数自己平衡堆栈(和win32 API一致)
int WINAPI hook messagebox a(HWND HWND,LPCTSTR lpText,LPCTSTR lpCaption,UINT uType)
{
nHookCount
printf('HookMessageBoxA挂接成功.%d
,nHookCount);
返回1;
//return((PfnMessageBox)(addrMsgBoxA))(NULL,' HOOK成功,'挂钩成功,MB _ icon信息);
}
//-
//本函数一定要用WINAPI(即__stdcall),表示本函数自己平衡堆栈(和win32 API一致)
int WINAPI hook messageboxw(HWND HWND,LPCWSTR lpText,LPCWSTR lpCaption,UINT uType)
{
nHookCount
printf('HookMessageBoxW挂接成功.%d
,nHookCount);
返回1;
//return((PfnMessageBox)(addrMsgBoxW))(NULL,' HOOK成功,'挂钩成功,MB _ icon信息);
}
//-
//安装卸载空钩子(ProcessID=NULL:卸载)
extern ' C ' _ _ declspec(dll导出)void安装挂钩4 API(HWND HWND)
{
AFX _ MANAGE _ STATE(AfxGetStaticModuleState());
//GetWindowThreadProcessId(hwnd,目标PID);
//只钩窗口句柄为窗口句柄的线程
中频(hwnd)
hHook=SetWindowsHookEx(WH _ GETMESSAGE,(HOOKPROC)HookProc,hinstDll,GetWindowThreadProcessId(hwnd,目标PID));
其他
{
如果(hHook)
unhook windowshookex(hHook);
}
}
void set hook messagebox(HMODULE HMODULE)
{
hmodulehmoduleuser 32=0;
char cArrDllName[256];
hinst dll=(h instance)hm odule;
BOOL bNext=FALSE
程序输入32程序输入32;
//获取目标进程句柄。
处理32号入口。dwsize=sizeof(进程条目32);
hs nap=createtoolhelp 32 snapshot(th 32 cs _ snap process,0);
bNext=Process32First(hSnap,proce entry 32);
while(bNext)
{
如果(!stricmp(procEntry32.szExeFile,pcproessname))//-
{
hremoteprocess 32=open PROCESS(PROCESS _ CREATE _ THREAD | PROCESS _ VM _ WRITE | PROCESS _ VM _ OPERATION,1,procentry 32。th 32 processid);
打破;
}
bNext=Process32Next(hSnap,proce entry 32);
}
关闭手柄(hs nap);
dwCurrentPid=procentry 32。th 32 processid
//载入需要钩的动态链接库并保存原始电动选择型
hmoduleuser 32=LoadLibrary(' user 32。dll’);
fpApiAddrA=GetProcAddress(hmoduleuser 32,' messagebox a ');
if(fpApiAddrA==NULL)
返回;
/*MessageBoxA原前5字节存至旧代码[5]*/
_asm
{
保存现场
莱亚埃迪btOldCodeA
mov esi,fpApiAddrA
中央生活区
传送双字
传送字节串
恢复寄存器
}
/*MessageBoxA新前5字节存至新代码[5]*/
btNewCodeA[0]=0xe 9;
_asm
{
lea eax,HookMessageBoxA
mov ebx,fpApiAddrA
子eax,ebx
子eax,5
金属氧化物变阻器双字指针[btNewCodeA 1],eax
}
//修改电动选择型
/*改写MessageBoxA()的前5个字节*/
VirtualProtectEx(hremoteprocess 32,fpApiAddrA,5,PAGE_READWRITE,dw protect);
WriteProcessMemory(hRemoteProcess32,fpApiAddrA,btNewCodeA,5,0);
VirtualProtectEx(hremoteprocess 32,fpApiAddrA,5,dwProtect,dw protect);
//载入需要钩的动态链接库并保存原始电动选择型
fpApiAddrW=GetProcAddress(hmoduleuser 32,' MessageBoxW ');
if(fpApiAddrW==NULL)
返回;
/*MessageBoxA原前5字节存至旧代码[5]*/
_asm
{
保存现场
李埃迪,btOldCodeW
mov esi,fpApiAddrW
中央生活区
传送双字
传送字节串
恢复寄存器
}
/*MessageBoxW新前5字节存至新代码[5]*/
btNewCodeW[0]=0xe 9;
_asm
{
lea eax,HookMessageBoxW
mov ebx,fpApiAddrW
子eax,ebx
子eax,5
金属氧化物变阻器双字指针[btNewCodeW 1],eax
}
/*改写MessageBoxA()的前5个字节*/
//修改电动选择型
VirtualProtectEx(hremoteprocess 32,fpApiAddrW,5,PAGE_READWRITE,dw protect);
WriteProcessMemory(hRemoteProcess32,fpApiAddrW,btNewCodeW,5,0);
VirtualProtectEx(hremoteprocess 32,fpApiAddrW,5,dwProtect,dw protect);
bApiHook=true
//增加引用次数后立即卸钩(目的:卸钩后保留该动态链接库存在于目标进程中)
GetModuleFileName((h instance)hm module,cArrDllName,256);
LoadLibrary(cArrDllName);
//只能由目标程序卸钩,否则目标程序有可能来不及加载钩进来的动态链接库
if(hHook(dwCurrentPid==目标Pid))
unhook windowshookex(hHook);
}
void SetHookDispatchMessage(HMODULE HMODULE)
{
hmodulehmoduleuser 32=0;
char cArrDllName[256];
hinst dll=(h instance)hm odule;
BOOL bNext=FALSE
程序输入32程序输入32;
//获取目标进程句柄。
处理32号入口。dwsize=sizeof(进程条目32);
hs nap=createtoolhelp 32 snapshot(th 32 cs _ snap process,0);
bNext=Process32First(hSnap,proce entry 32);
while(bNext)
{
如果(!stricmp(procEntry32.szExeFile,pcProsessName))
{
hremoteprocess 32=open PROCESS(PROCESS _ CREATE _ THREAD | PROCESS _ VM _ WRITE | PROCESS _ VM _ OPERATION,1,procentry 32。th 32 processid);
打破;
}
bNext=Process32Next(hSnap,proce entry 32);
}
关闭手柄(hs卡扣
); 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; } 最后,记得修改所有项目的生成目录,令所有项目生成到一个目录。我设置的方法是直接在默认生成目录前加“..”。祝你成功。