📄 hookwproc.cpp
字号:
// HookWProc.cpp.
#include "stdafx.h"
#include <stdio.h>
//---------------------------------------------------------------------
typedef LONG (WINAPI *SETWINDOWLONG) (HWND,int,LONG);
typedef BOOL (WINAPI *SETWINDOWTEXT) (HWND,LPCSTR);
typedef LRESULT (WINAPI *CALLWINDOWPROC) (WNDPROC,HWND,UINT,WPARAM,LPARAM);
typedef struct {
SETWINDOWLONG fnSetWindowLong;
CALLWINDOWPROC fnCallWindowProc;
SETWINDOWTEXT fnSetWindowText;
HWND hwnd;
WNDPROC fnNewProc;
char pszStr[20];
WNDPROC fnOldProc;
} INJDATA, *PINJDATA;
//---------------------------------------------------------------------
DWORD WINAPI InjectFunc (INJDATA *pData)
{
pData->fnOldProc = (WNDPROC)pData->fnSetWindowLong
( pData->hwnd, GWL_WNDPROC,(long)pData->fnNewProc );
return (pData->fnOldProc != NULL);
}
//---------------------------------------------------------------------
// 新的Windows过程函数.
static LRESULT CALLBACK NewProc(HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam )
{
// 计算INJDATA的位置,注意在远进程中INJDATA紧放在NewProc前.
INJDATA* pData;
_asm {
call dummy
dummy:
pop ecx // 此时ECX 指向当前 EIP (指示指针).
sub ecx, 14 // 此时ECX 指向 NewProc的地址.
mov pData, ecx
}
pData--;
switch (uMsg)
{
case WM_LBUTTONDOWN:
break;
case WM_PAINT:
pData->fnSetWindowText(hwnd,pData->pszStr);
break;
}
return pData->fnCallWindowProc
(pData->fnOldProc, hwnd,uMsg,wParam,lParam );
}
//---------------------------------------------------------------------
int InjectCode (HWND hWnd, char *pszText)
{
HANDLE hProcess;
HANDLE hThread;
DWORD dwPID;
BYTE *pCodeRemote;
BYTE *pDataRemote;
BYTE *pNewProcRemote;
DWORD dwThreadId;
DWORD dwNumBytes;
int nSuccess = 0;
int nNewProc = 250;
int nInjectFunc = 1024;
__try {
GetWindowThreadProcessId( hWnd, &dwPID );
hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, dwPID);
if (hProcess == NULL)
__leave;
int size = sizeof(INJDATA) + nNewProc;
pDataRemote = (BYTE*) VirtualAllocEx( hProcess, 0,
size, MEM_COMMIT, PAGE_EXECUTE_READWRITE );
if ( pDataRemote == NULL )
__leave;
pNewProcRemote = pDataRemote + sizeof(INJDATA);
WriteProcessMemory( hProcess, pNewProcRemote,
NewProc, nNewProc, &dwNumBytes);
// 初始化INJDATA结构.
HMODULE hUser32 = GetModuleHandle("user32");
INJDATA DataLocal = {
(SETWINDOWLONG) GetProcAddress(hUser32, "SetWindowLongA"),
(CALLWINDOWPROC)GetProcAddress(hUser32, "CallWindowProcA"),
(SETWINDOWTEXT) GetProcAddress(hUser32, "SetWindowTextA"),
hWnd,
(WNDPROC) (pNewProcRemote)
};
strcpy(DataLocal.pszStr,pszText);
if (DataLocal.fnSetWindowLong == NULL ||
DataLocal.fnCallWindowProc == NULL ||
DataLocal.fnSetWindowText == NULL)
__leave;
// 把初始化的INJDATA拷贝到远进程中.
WriteProcessMemory( hProcess,pDataRemote,
&DataLocal, sizeof(INJDATA), &dwNumBytes);
pCodeRemote = (BYTE*) VirtualAllocEx(
hProcess, 0, nInjectFunc, MEM_COMMIT, PAGE_EXECUTE_READWRITE );
if ( pCodeRemote == 0 )
__leave;
WriteProcessMemory( hProcess, pCodeRemote,
InjectFunc, nInjectFunc, &dwNumBytes);
// Start execution of remote InjectFunc
hThread = CreateRemoteThread(hProcess, NULL, 0,
(LPTHREAD_START_ROUTINE) pCodeRemote,
pDataRemote, 0 , &dwThreadId);
if ( hThread == 0 )
__leave;
WaitForSingleObject(hThread, INFINITE);
GetExitCodeThread(hThread, (PDWORD) &nSuccess);
}
__finally {
if( !nSuccess )
VirtualFreeEx( hProcess, pDataRemote, 0, MEM_RELEASE );
if ( pCodeRemote != NULL )
VirtualFreeEx( hProcess, pCodeRemote, 0, MEM_RELEASE );
if ( hThread != NULL )
CloseHandle(hThread);
if ( hProcess != NULL )
CloseHandle( hProcess );
}
return nSuccess;
}
void NewProcCode()
{
// 定义最大代码长度.
#define Max_Sc_Len 45
char buffer[Max_Sc_Len];
// 复制代码到buffer.
memcpy(buffer,(char *)NewProc,Max_Sc_Len);
// 显示代码.
for(int i=0;i<Max_Sc_Len;i++){
printf(" %02x", buffer[i]&0xff);
}
getchar();
}
void main()
{
// 调用显示NewProc()函数代码的函数.
// NewProcCode();
HWND hWnd;
hWnd = FindWindow (NULL,TEXT("HookMsgbx"));
if(!hWnd) return;
hWnd = FindWindowEx (hWnd, NULL,TEXT("BUTTON"),"确定");
if(!hWnd) return;
InjectCode(hWnd,"Hello!");
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -