// HookDll.cpp : ¶¨Òå DLL µÄ³õʼ»¯Àý³Ì¡£
//
#include "stdafx.h"
#include "HookDll.h"
#include <Windows.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
/*
È«¾Ö¹²Ïí±äÁ¿
*/
#pragma data_seg("Share")
HWND g_hWnd = NULL ; // Ö÷´°¿Ú¾ä±ú
HINSTANCE g_hInstance = NULL; // ±¾dllʵÀý¾ä±ú
HHOOK hhk = NULL; // Êó±ê¹³×Ó¾ä±ú
#pragma data_seg()
#pragma comment(linker,"/section:Share,rws")
HANDLE hProcess = NULL; // µ±Ç°½ø³Ì
BOOL bIsInJected = FALSE; // ÊÇ·ñÒÑ×¢Èë±ê¼Ç
TCHAR* msgToMain = new TCHAR[200]; // ·¢¸øÖ÷µ÷³ÌÐòµÄÐÅÏ¢
/*
Ôº¯Êý¶¨Òå
*/
typedef int (WINAPI *TypeMsgBoxA)(HWND hWnd,LPCSTR
lpText, LPCSTR lpCaption,UINT uType);
typedef int (WINAPI *TypeMsgBoxW)(HWND hWnd,LPCWSTR
lpText,LPCWSTR lpCaption,UINT uType);
TypeMsgBoxA oldMsgBoxA = NULL; // ÓÃÓÚ±£´æÔº¯ÊýµØÖ·
TypeMsgBoxW oldMsgBoxW = NULL; // ÓÃÓÚ±£´æÔ¿¬Ê鵨ַ
FARPROC pfMsgBoxA = NULL; // Ö¸ÏòÔº¯ÊýµØÖ·µÄÔ¶Ö¸Õë
FARPROC pfMsgBoxW = NULL; // Ö¸ÏòÔº¯ÊýµØÖ·µÄÔ¶Ö¸Õë
#define CODE_LENGTH 5
BYTE oldCodeA[CODE_LENGTH]; // ±£´æÔÀ´APIÈë¿Ú´úÂë
BYTE oldCodeW[CODE_LENGTH]; // ±£´æÔÀ´APIÈë¿Ú´úÂë
BYTE newCodeA[CODE_LENGTH]; // ±£´æÐÂAPIÈë¿Ú´úÂ룬jmp
xxxx
BYTE newCodeW[CODE_LENGTH]; // ±£´æÐÂAPIÈë¿Ú´úÂ룬jmp
xxxx
/*
×Ô¼º±àдµÄAPI
*/
int WINAPI MyMessageBoxA(HWND hWnd,LPCSTR lpText,LPCSTR
lpCation,UINT uType);
int WINAPI MyMessageBoxW(HWND hWnd,LPCWSTR lpText,LPCWSTR
lpCation,UINT uType);
/*
ÆäËüº¯ÊýÔÐÍÉùÃ÷
*/
void HookOn(); // ¿ªÊ¼HOOK
void HookOff(); // ¹Ø±ÕHOOK
void Inject(); // ×¢Èë
BOOL WINAPI StartHook(HWND hWnd); // ¼ÓÔØ¹³×Ó
BOOL WINAPI StopHook(); // Ð¶ÔØ¹³×Ó
bool AdjustPrivileges(); // ÌáÉýȨÏÞ
//
//TODO: Èç¹û´Ë DLL Ïà¶ÔÓÚ MFC DLL ÊǶ¯Ì¬Á´½ÓµÄ£¬
// Ôò´Ó´Ë DLL µ¼³öµÄÈκε÷Èë
// MFC µÄº¯Êý±ØÐ뽫 AFX_MANAGE_STATE ºêÌí¼Óµ½
// ¸Ãº¯ÊýµÄ×îÇ°Ãæ¡£
//
// ÀýÈç:
//
// extern "C" BOOL PASCAL EXPORT ExportedFunction()
// {
// AFX_MANAGE_STATE(AfxGetStaticModuleState());
// // ´Ë´¦ÎªÆÕͨº¯ÊýÌå
// }
//
// ´ËºêÏÈÓÚÈκΠMFC µ÷ÓÃ
// ³öÏÖÔÚÿ¸öº¯ÊýÖÐÊ®·ÖÖØÒª¡£ÕâÒâζ×Å
// Ëü±ØÐë×÷Ϊº¯ÊýÖеĵÚÒ»¸öÓï¾ä
// ³öÏÖ£¬ÉõÖÁÏÈÓÚËùÓжÔÏó±äÁ¿ÉùÃ÷£¬
// ÕâÊÇÒòΪËüÃǵĹ¹Ô캯Êý¿ÉÄÜÉú³É MFC
// DLL µ÷Óá£
//
// ÓÐ¹ØÆäËûÏêϸÐÅÏ¢£¬
// Çë²ÎÔÄ MFC ¼¼Êõ˵Ã÷ 33 ºÍ 58¡£
//
// CHookDllApp
BEGIN_MESSAGE_MAP(CHookDllApp, CWinApp)
END_MESSAGE_MAP()
// CHookDllApp ¹¹Ôì
CHookDllApp::CHookDllApp()
{
// TODO: ÔÚ´Ë´¦Ìí¼Ó¹¹Ôì´úÂ룬
// ½«ËùÓÐÖØÒªµÄ³õʼ»¯·ÅÖÃÔÚ InitInstance ÖÐ
}
// ΨһµÄÒ»¸ö CHookDllApp ¶ÔÏó
CHookDllApp theApp;
// CHookDllApp ³õʼ»¯
/*
dll³ÌÐòÈë¿Ú£¬µ±³ÌÐò¼ÓÔØdllʱ£¬»áÖ´ÐÐInitInstance()
*/
BOOL CHookDllApp::InitInstance()
{
CWinApp::InitInstance();
g_hInstance = AfxGetInstanceHandle();// »ñÈ¡µ±Ç°DLLʵÀý¾ä±ú
AdjustPrivileges(); // Ìá¸ßȨÏÞ
DWORD dwPid = ::GetCurrentProcessId();
hProcess = ::OpenProcess(PROCESS_ALL_ACCESS,0,dwPid);
if (hProcess == NULL)
{
CString str;
str.Format(_T("OpenProcess fail£¬ and error
code = %d"),GetLastError());
AfxMessageBox(str);
return FALSE;
}
Inject(); // ¿ªÊ¼×¢Èë
return TRUE;
}
int CHookDllApp::ExitInstance()
{
/*
dllÍ˳öʱ£¬Ò»¶¨Òª¼ÇµÃ»Ö¸´ÔAPIµÄÈë¿Ú£¡£¡£¡
ÎÒÃDZàдµÄdll»á±»×¢Èëµ½ËùÓÐÄ¿±ê½ø³ÌÖУ¬ÈôdllÍ˳öʱ£¬Ã»Óлָ´ÔAPIÈë¿Ú£¬
ÄÇô±»¹Ò¹³µÄ³ÌÐòÔٴε÷ÓøÃAPIʱ£¬»á·¢Éú´íÎó¡£
ÒòΪÎÒÃǵÄdll³ÌÐòÒѾÍ˳ö£¬µ«ÔAPIµÄÈë¿ÚÈÔΪÎÒÃÇËù¶¨ÒåµÄAPIµÄÈë¿Ú£¬Õâ
ʱ±»¹Ò¹³µÄ³ÌÐòÎÞ·¨ÕÒµ½ÎÒÃÇʵÏÖµÄAPI£¬È»¶øÔAPIµÄµØÖ·ÓÖûÓб»»Ö¸´£¬Ò²¾Í
µ÷Óò»µ½ÔAPI£¬Õâʱ³ÌÐò×ÔÈ»»á·¢Éú±ÀÀ£ÁË¡£
*/
HookOff();
return CWinApp::ExitInstance();
}
/*
ÌáÉýȨÏÞ
*/
bool AdjustPrivileges() {
HANDLE hToken;
TOKEN_PRIVILEGES tp;
TOKEN_PRIVILEGES oldtp;
DWORD dwSize=sizeof(TOKEN_PRIVILEGES);
LUID luid;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES
| TOKEN_QUERY, &hToken)) {
if (GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)
return true;
else return false;
}
if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME,
&luid)) {
CloseHandle(hToken);
return false;
}
ZeroMemory(&tp, sizeof(tp));
tp.PrivilegeCount=1;
tp.Privileges[0].Luid=luid;
tp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;
/* Adjust Token Privileges */
if (!AdjustTokenPrivileges(hToken, FALSE, &tp,
sizeof(TOKEN_PRIVILEGES), &oldtp, &dwSize))
{
CloseHandle(hToken);
return false;
}
// close handles
CloseHandle(hToken);
return true;
}
/*
Êó±ê¹³×Ó×Ó¹ý³Ì£¬Ä¿µÄÊǼÓÔØ±¾dllµ½Ê¹ÓÃÊó±êµÄ³ÌÐòÖС£
Êó±ê¹³×ÓµÄ×÷Ó㺵±Êó±êÔÚij³ÌÐò´°¿ÚÖÐʱ£¬¾Í»á¼ÓÔØÎÒÃÇÕâ¸ödll¡£
*/
LRESULT CALLBACK MouseProc(
int nCode, // hook code
WPARAM wParam,// message identifier
LPARAM lParam // mouse coordinates
)
{
return CallNextHookEx(hhk,nCode,wParam,lParam);
}
/*
½«³¤¶ÈΪlengthµÄpcodeдÈëµ½µØÖ·lpAddressÖС£
*/
void WriteMemory(LPVOID lpAddress,BYTE* pcode,int
length)
{
//
// ±£Ö¤±¾½ø³Ì¾ä±ú²»ÎªNULL
//
ASSERT(hProcess != NULL);
DWORD dwTemp,dwOldProtect,dwRet,dwWrited;
//
// ÐÞ¸ÄAPIÈë¿Úǰlength¸ö×Ö½ÚΪ jmp xxxx
//
VirtualProtectEx(hProcess,lpAddress,length,PAGE_READWRITE,&dwOldProtect);
dwRet = WriteProcessMemory(hProcess,lpAddress,pcode,length,&dwWrited);
if ( 0 == dwRet || 0 == dwWrited)
{
AfxMessageBox(_T("¿Þ£¡£¡Ð´Èëʧ°Ü"));
}
VirtualProtectEx(hProcess,lpAddress,length,dwOldProtect,&dwTemp);
}
/*
ÓÃÐÂAPIµØÖ·Ìæ»»ÔAPIµØÖ·
*/
void HookOn()
{
ASSERT(hProcess != NULL);
DWORD dwTemp,dwOldProtect,dwRet,dwWrited;
WriteMemory(pfMsgBoxA,newCodeA,CODE_LENGTH);
WriteMemory(pfMsgBoxW,newCodeW,CODE_LENGTH);
}
/*
»Ö¸´ÔAPIµØÖ·
*/
void HookOff()
{
ASSERT(hProcess != NULL);
DWORD dwTemp,dwOldProtect,dwRet,dwWrited;
WriteMemory(pfMsgBoxA,oldCodeA,CODE_LENGTH);
WriteMemory(pfMsgBoxW,oldCodeW,CODE_LENGTH);
}
/*
×¢Èë
*/
void Inject()
{
if ( TRUE == bIsInJected)
{
return;
}
bIsInJected = TRUE; // ±£Ö¤Ö»µ÷ÓÃÒ»´Î
//
// »ñÈ¡º¯Êý
//
HMODULE hmodle = ::LoadLibrary(_T("User32.dll"));
oldMsgBoxA = (TypeMsgBoxA) ::GetProcAddress(hmodle,"MessageBoxA");
pfMsgBoxA = (FARPROC)oldMsgBoxA;
oldMsgBoxW = (TypeMsgBoxW) ::GetProcAddress(hmodle,"MessageBoxW");
pfMsgBoxW = (FARPROC)oldMsgBoxW;
if (pfMsgBoxA == NULL)
{
AfxMessageBox(_T("»ñÈ¡ MessageBoxA º¯Êýʧ°Ü"));
return;
}
if ( pfMsgBoxW == NULL)
{
AfxMessageBox(_T("»ñÈ¡ MessageBoxW º¯Êýʧ°Ü"));
return;
}
//
// ±£´æÔAPIµØÖ·
//
_asm
{
lea edi,oldCodeA // È¡Êý×é»ùµØÖ·
mov esi,pfMsgBoxA // APIµØÖ·
cld // ÉèÖ÷½Ïò
mov ecx,CODE_LENGTH
rep movsb
}
_asm
{
lea edi,oldCodeW
mov esi,pfMsgBoxW
cld
mov ecx,CODE_LENGTH
rep movsb
}
//
// ½«ÐµØÖ·¸´ÖƵ½Èë¿Ú
//
newCodeA[0] = newCodeW [0] = 0xe9; // jmp Ö¸¶¨´úÂë
_asm
{
lea eax,MyMessageBoxA // ÐÂAPIµØÖ·
mov ebx,pfMsgBoxA // ÔAPIµØÖ·
sub eax,ebx
sub eax,CODE_LENGTH // Ìø×ªµØÖ· = ÐÂAPIµØÖ· - ÔAPIµØÖ·
- Ö¸Á¶È
mov dword ptr [newCodeA+1],eax // eax 32bit
= 4 BYTE
}
_asm
{
lea eax,MyMessageBoxW
mov ebx,pfMsgBoxW
sub eax,ebx
sub eax,CODE_LENGTH
mov dword ptr [newCodeW + 1],eax
}
HookOn(); // ¿ªÊ¼HOOK
}
//
// °²×°¹³×Ó
//
BOOL WINAPI StartHook(HWND hWnd)
{
g_hWnd = hWnd;
hhk = ::SetWindowsHookEx(WH_MOUSE,MouseProc,g_hInstance,0);
if (hhk == NULL)
{
return FALSE;
}
else
{
return TRUE;
}
}
//
// Ð¶ÔØ¹³×Ó
//
BOOL WINAPI StopHook()
{
/*
Ð¶ÔØ¹³×Óʱ£¬Ò»¶¨Òª¼ÇµÃ»Ö¸´ÔAPIÈë¿Ú¡£
ÕâÀï»Ö¸´µÄÖ»ÊÇÖ÷³ÌÐòµÄÔAPIÈë¿Ú£¬ÆäËü³ÌÐòµÄAPIÈë¿Ú»¹Ã»Óб»»Ö¸´¡£
Òò´ËÎÒÃDZØÐë´¦ÀídllÍ˳ö¹ý³Ì£¬¼´ÔÚº¯ÊýExitInstance()ÖУ¬µ÷Óûָ´
APIÈë¿ÚµÄº¯ÊýHookOff(),Ö»ÓÐÕâÑù£¬ÆäËü³ÌÐòÔٴε÷ÓÃÔAPIʱ£¬²Å²»
»á·¢Éú´íÎó¡£
µ±ÎÒÃÇHOOKËùÓгÌÐòµÄij¸öϵͳAPIʱ£¬Ç§ÍòҪעÒâÔÚExitInstance()ÖÐ
µ÷ÓÃHookOff()£¡£¡£¡£¡£¡
*/
HookOff();
if (hhk!=NULL)
{
UnhookWindowsHookEx(hhk);
FreeLibrary(g_hInstance);
}
return TRUE;
}
/*
×Ô¼ºÓÃÓÚÌæ»»µÄAPI
*/
int WINAPI MyMessageBoxA(HWND hWnd,LPCSTR lpText,LPCSTR
lpCation,UINT uType)
{
int nRet = 0;
HookOff();
nRet = ::MessageBoxA(hWnd,"¹þ¹þ ^_^£¬MessageBoxA
±» HOOK ¿©",lpCation,uType);
nRet = ::MessageBoxA(hWnd,lpText,lpCation,uType);
HookOn();
return nRet;
}
int WINAPI MyMessageBoxW(HWND hWnd,LPCWSTR lpText,LPCWSTR
lpCation,UINT uType)
{
int nRet = 0;
HookOff();
nRet = ::MessageBoxW(hWnd,_T("O(¡É_¡É)O¹þ¹þ~£¬MMessageBoxW
±» HOOK ¿©"),lpCation,uType);
nRet = ::MessageBoxW(hWnd,lpText,lpCation,uType);
HookOn();
return nRet;
}
|