// MonitorDll.cpp : ¶¨Òå DLL µÄ³õʼ»¯Àý³Ì¡£
//
#include "stdafx.h"
#include "MonitorDll.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
/*
È«¾Ö±äÁ¿
*/
// ¹²Ïí±äÁ¿
#pragma data_seg("Share")
HWND g_hwnd = NULL; // Ö÷´°¿Ú¾ä±ú£¬¼ÓÔØHOOKʱ´«Èë
HINSTANCE hInstance = NULL; // ±¾DLLµÄʵÀý¾ä±ú
HHOOK hhook = NULL; // Êó±ê¹³×Ó¾ä±ú
DWORD g_dwProcessId; // ½ø³Ìid
HANDLE g_hProcess = NULL; // ±£´æ±¾½ø³ÌÔÚÔ¶½ø³ÌÖеľä±ú
#pragma data_seg()
#pragma comment(linker,"/section:Share,rws")
// ÆäËû±äÁ¿¶¨Òå
HANDLE hProcess = NULL; // µ±Ç°½ø³Ì¾ä±ú
bool bIsInjected = false; // ±£Ö¤Ö»×¢ÈëÒ»´Î
#define CODE_LENGTH 5 // Èë¿ÚÖ¸Á¶È
// TerminateProcess
typedef BOOL (WINAPI *TypeTerminateProcess)(_In_
HANDLE hProcess, _In_ UINT uExitCode); //Kernel32.dll
TypeTerminateProcess oldTerminateProcess = NULL;
FARPROC pfOldTerminateProcess = NULL;
BOOL WINAPI MyTerminateProcess(_In_ HANDLE hProcess,
_In_ UINT uExitCode);
BYTE oldCodeTermPro[CODE_LENGTH]; // ÔAPIÈë¿Ú
BYTE newCodeTermpro[CODE_LENGTH]; // ÐÂAPIÈë¿Ú
// OpenProcess
typedef HANDLE(WINAPI *TypeOpenProcess)( _In_
DWORD dwDesiredAccess,_In_ BOOL bInheritHandle,_In_
DWORD dwProcessId);
TypeOpenProcess oldOpenProcess = NULL;
FARPROC pfOldOpenProcess = NULL;
HANDLE WINAPI MyOpenProcess(_In_ DWORD dwDesiredAccess,_In_
BOOL bInheritHandle,_In_ DWORD dwProcessId);
BYTE oldCodeOpenPro[CODE_LENGTH];
BYTE newCodeOpenPro[CODE_LENGTH];
BOOL WINAPI HookLoad(HWND hwnd,DWORD dwProcessId);
// ¹ØÓÚdll hook ²Ù×÷
VOID WINAPI HookUnload();
VOID Inject();
VOID HookOn();
VOID HookOff();
BOOL SetPrivilege(
HANDLE hToken, // access token handle
LPCTSTR lpszPrivilege, // name of privilege
to enable/disable
BOOL bEnablePrivilege // to enable or disable
privilege
) ;
LRESULT CALLBACK MouseProc( // Êó±ê¹³×Ó×Ó¹ý³Ìµ÷ÓÃ
int nCode, // hook code
WPARAM wParam,// message identifier
LPARAM lParam // mouse coordinates
);
BOOL WriteMemory(LPVOID lpAddress,BYTE* pcode,size_t
length); //½«³¤¶ÈΪ length µÄ pcode дÈëµØÖ· lpAddress
µÄ½ø³ÌÄÚ´æÖÐ
//
//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¡£
//
// CMonitorDllApp
BEGIN_MESSAGE_MAP(CMonitorDllApp, CWinApp)
END_MESSAGE_MAP()
// CMonitorDllApp ¹¹Ôì
CMonitorDllApp::CMonitorDllApp()
{
// TODO: ÔÚ´Ë´¦Ìí¼Ó¹¹Ôì´úÂ룬
// ½«ËùÓÐÖØÒªµÄ³õʼ»¯·ÅÖÃÔÚ InitInstance ÖÐ
}
// ΨһµÄÒ»¸ö CMonitorDllApp ¶ÔÏó
CMonitorDllApp theApp;
// CMonitorDllApp ³õʼ»¯
BOOL CMonitorDllApp::InitInstance()
{
CWinApp::InitInstance();
hInstance = AfxGetInstanceHandle(); // »ñÈ¡±¾dll¾ä±ú
/*
ÏÈÌá¸ßȨÏÞ£¬ÔÙ»ñÈ¡½ø³Ì¾ä±ú¡£
ÒòΪֻÓÐȨÏÞ×ã¹»£¬²ÅÄÜ»ñÈ¡µ½µ±Ç°½ø³ÌµÄ¾ä±ú¡£
*/
HANDLE hToken;
BOOL bRet = OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES
| TOKEN_QUERY,&hToken);
if (bRet == FALSE)
{
AfxMessageBox(_T("ȨÏÞÌáÉýʧ°Ü"));
}
SetPrivilege(hToken,SE_DEBUG_NAME,TRUE);
DWORD dwPid = ::GetCurrentProcessId();
hProcess = ::OpenProcess(PROCESS_ALL_ACCESS,0,dwPid);
if (hProcess == NULL)
{
CString str;
str.Format(_T("OpenProcess fail!!, error
code = [%d]"),GetLastError());
AfxMessageBox(str);
return FALSE;
}
Inject(); // ¿ªÊ¼×¢Èë
return TRUE;
}
//
// ʵÀýÍ˳öº¯Êý¡£Í˳öʱ£¬Ò»¶¨Òª¼ÇµÃ»Ö¸´Ôº¯ÊýµØÖ·£¡£¡£¡
//
int CMonitorDllApp::ExitInstance()
{
HookOff(); //Òª¼ÇµÃ»Ö¸´Ôº¯ÊýµØÖ·
return CWinApp::ExitInstance();
}
/*
Êó±ê¹³×Ó×Ó¹ý³Ì£¬Ä¿µÄÊǼÓÔØ±¾dllµ½Ê¹ÓÃÊó±êµÄ³ÌÐò.
Êó±ê¹³×ÓµÄ×÷Ó㺵±Êó±êÔÚij³ÌÐò´°¿ÚÖÐʱ£¬¾Í»á¼ÓÔØÎÒÃÇÕâ¸ödll¡£
¼´Ê¹±¾DLLËæ×ÅÊó±ê¹³×Ó×¢È뵽Ŀ±ê½ø³ÌÖС£
*/
LRESULT CALLBACK MouseProc(
int nCode, // hook code
WPARAM wParam, // message identifier
LPARAM lParam // mouse coordinates
)
{
return CallNextHookEx(hhook,nCode,wParam,lParam);
}
/*
°²×°¹³×Ó¡£
Ö÷µ÷³ÌÐò´«Èë´°¿Ú¾ä±úºÍ½ø³Ìid¡£
*/
BOOL WINAPI HookLoad(HWND hwnd,DWORD dwProcessId)
{
BOOL ret = FALSE;
g_hwnd = hwnd;
g_dwProcessId = dwProcessId;
hhook = ::SetWindowsHookEx(WH_MOUSE,MouseProc,hInstance,0);
if (hhook == NULL)
{
return FALSE;
}
else
{
return TRUE;
}
}
/*
Ð¶ÔØ¹³×Ó¡£
×¢£ºÐ¶Ôع³×Ó֮ǰ£¬Ò»¶¨Òª¼ÇµÃ»Ö¸´Ôº¯ÊýµØÖ·£¡£¡£¡
*/
VOID WINAPI HookUnload()
{
HookOff(); // »Ö¸´Ôº¯ÊýµØÖ·
if (hhook != NULL)
{
UnhookWindowsHookEx(hhook);
}
if (hInstance != NULL)
{
FreeLibrary(hInstance);
}
}
/*
×¢È뺯Êý¡£
Ö÷ÒªÍê³ÉÔº¯ÊýµØÖ·µÄ±£´æ£¬±£´æµ½ oldCode_[]ÖУ»
ÐÂÈë¿ÚµØÖ·µÄ¼ÆË㣬±£´æµ½newCode_[]ÖУ¬¼´ jmp xxxx Ö¸Áî¡£
ÐÂÈë¿ÚµØÖ· = к¯ÊýµØÖ· - Ôº¯ÊýµØÖ· - Ö¸Á¶È
×îºóÒ»¶¨Òª¼ÇµÃHookOn£¡£¡
*/
VOID Inject()
{
if (bIsInjected == TRUE)
{
return;
}
bIsInjected = TRUE;// ±£Ö¤Ö»×¢ÈëÒ»´Î
// TerminateProcess
HMODULE hmodleKernel32;
hmodleKernel32 = ::LoadLibrary(_T("Kernel32.dll"));
if (NULL == hmodleKernel32)
{
AfxMessageBox(_T("¼ÓÔØKernel32.dllʧ°Ü"));
return;
}
// »ñȡԺ¯ÊýµØÖ·
oldTerminateProcess = (TypeTerminateProcess)GetProcAddress(hmodleKernel32,"TerminateProcess");
if (NULL == oldTerminateProcess)
{
AfxMessageBox(_T("»ñÈ¡TerminateProcessº¯Êýʧ°Ü"));
return;
}
pfOldTerminateProcess = (FARPROC)oldTerminateProcess;
// ±£´æÔº¯ÊýÈë¿Ú
_asm
{
lea edi,oldCodeTermPro
mov esi,pfOldTerminateProcess
cld
mov ecx,CODE_LENGTH
rep movsb
}
// Ìæ»»Ðº¯ÊýÈë¿Ú
newCodeTermpro[0] = 0xe9;
_asm
{
lea eax,MyTerminateProcess
mov ebx,pfOldTerminateProcess
sub eax,ebx
sub eax,CODE_LENGTH
mov dword ptr [newCodeTermpro+1],eax
}
// OpenProcess
oldOpenProcess = (TypeOpenProcess)GetProcAddress(hmodleKernel32,"OpenProcess");
if (NULL == oldOpenProcess)
{
AfxMessageBox(_T("»ñÈ¡OpenProcessµØÖ·Ê§°Ü"));
return;
}
pfOldOpenProcess = (FARPROC)oldOpenProcess;
_asm
{
lea edi,oldCodeOpenPro
mov esi,pfOldOpenProcess
cld
mov ecx,CODE_LENGTH
rep movsb
}
newCodeOpenPro[0] = 0xe9;
_asm
{
lea eax,MyOpenProcess
mov ebx,pfOldOpenProcess
sub eax,ebx
sub eax,CODE_LENGTH
mov dword ptr [newCodeOpenPro+1],eax
}
HookOn(); //Ìî³äÍê±Ï£¬¿ªÊ¼HOOK
}
/*
½«³¤¶ÈΪ length µÄ pcode дÈëµØÖ· lpAddress µÄ½ø³ÌÄÚ´æÖÐ
*/
BOOL WriteMemory(LPVOID lpAddress,BYTE* pcode,size_t
length)
{
ASSERT(hProcess != NULL);
DWORD dwtemp,dwOldProtect,dwRet,dwWrited;
dwRet = VirtualProtectEx(hProcess,lpAddress,length,PAGE_READWRITE,&dwOldProtect);
CString logInfo;
if ( 0 == dwRet)
{
logInfo.Format(_T("WriteMemory :: Call
VirtualProtectEx fail, eror code = [%d]\n\n"),GetLastError());
AfxMessageBox(logInfo);
return FALSE;
}
dwRet = WriteProcessMemory(hProcess,lpAddress,pcode,length,&dwWrited);
if ( 0 == dwRet || 0 == dwWrited)
{
logInfo.Format(_T("WriteMemory :: Call
WriteProcessMomory fail, error code = [%d]\n\n"),GetLastError());
AfxMessageBox(logInfo);
return FALSE;
}
dwRet = VirtualProtectEx(hProcess,lpAddress,length,dwOldProtect,&dwtemp);
if ( 0 == dwRet )
{
logInfo.Format(_T("WriteMemory :: Recover
Protect fail, error code = [%d]\n\n"),GetLastError());
AfxMessageBox(logInfo);
return FALSE;
}
return TRUE;
}
/*
¿ªÊ¼HOOK¡£
¼´£¬½«Inject ³õʼ»¯ºÃµÄÈë¿ÚµØÖ·½øÐÐдÈë½ø³ÌÄÚ´æÖС£
ÕâÀ½«Ðº¯ÊýÈë¿Ú newCode_[]£¬Ð´ÈëÄÚ´æÖС£
ÕâÑùÒ»À´£¬ÔÚÔº¯Êý±»µ÷ÓõÄʱºò£¬¾Í»áÌø×ªµ½ÎÒÃÇк¯ÊýµÄλÖá£
×¢: ÕâÀï´¦ÀíµÄº¯Êý£¬Êǵ±Ç°ÐèÒªÌæ»»µÄËùÓк¯Êý£¬ËùÒÔÖ»ÔÚInject()º¯ÊýÖе÷Óã¬
¼´½øÐгõʼ»¯µÄʱºòÓõ½¸Ãº¯Êý¡£
*/
VOID HookOn()
{
BOOL ret;
ret = WriteMemory(pfOldTerminateProcess,newCodeTermpro,CODE_LENGTH);
if (FALSE == ret)
{
AfxMessageBox(_T("HookOn :: Fail to write
pfOldTerminateProcess"));
}
ret = WriteMemory(pfOldOpenProcess,newCodeOpenPro,CODE_LENGTH);
if (FALSE == ret)
{
AfxMessageBox(_T("HookOn :: Fail to write
pfOldOpenProcess"));
}
}
/*
Í£Ö¹HOOK¡£
»Ö¸´Ôº¯ÊýµØÖ·¡£
×¢£ºÕâÀï´¦ÀíµÄÊÇËùÓÐÌæ»»µÄº¯Êý£¬ËùÒÔÒ»°ãÇé¿öÏÂÖ»ÓÐÔÚÐ¶ÔØHOOKº¯ÊýÖе÷ÓÃ
*/
VOID HookOff()
{
ASSERT(hProcess != NULL);
BOOL ret;
ret = WriteMemory(pfOldTerminateProcess,oldCodeTermPro,CODE_LENGTH);
if (FALSE == ret)
{
AfxMessageBox(_T("HookOff :: fail to recover
pfOldTerminateProcess \n\n"));
}
ret = WriteMemory(pfOldOpenProcess,oldCodeOpenPro,CODE_LENGTH);
if (FALSE == ret)
{
AfxMessageBox(_T("HookOff :: fail to recover
pfOldOpenProcess"));
}
}
/*
ÌáÉý½ø³ÌȨÏÞ¡£
*/
BOOL SetPrivilege(
HANDLE hToken, // access token handle
LPCTSTR lpszPrivilege, // name of privilege
to enable/disable
BOOL bEnablePrivilege // to enable or disable
privilege
)
{
TOKEN_PRIVILEGES tp;
LUID luid;
CString info;
if ( !LookupPrivilegeValue(
NULL, // lookup privilege on local system
lpszPrivilege, // privilege to lookup
&luid ) ) // receives LUID of privilege
{
info.Format(_T("LookupPrivilegeValue error:
%u\n"), GetLastError() );
AfxMessageBox(info);
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;
// Enable the privilege or disable all privileges.
if ( !AdjustTokenPrivileges(
hToken,
FALSE,
&tp,
sizeof(TOKEN_PRIVILEGES),
(PTOKEN_PRIVILEGES) NULL,
(PDWORD) NULL) )
{
info.Format(_T("AdjustTokenPrivileges error:
%u\n"), GetLastError() );
AfxMessageBox(info);
return FALSE;
}
if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
{
info.Format(_T("The token does not have
the specified privilege. \n"));
AfxMessageBox(info);
return FALSE;
}
return TRUE;
}
//
// ×Ô¼ºÖØÐ¶¨ÒåµÄ½ø³ÌÖÕÖ¹º¯Êý¡£
// ¼ì²éµ±Ç°ÒªÖÕÖ¹µÄ½ø³ÌÊÇ·ñÊÇÊܱ£»¤½ø³Ì£¬ÈôÊÇÔò½ûÖ¹¹Ø±Õ¡£
//
BOOL WINAPI MyTerminateProcess(_In_ HANDLE hProcess,
_In_ UINT uExitCode)
{
BOOL ret;
if (g_hProcess == hProcess)
{
AfxMessageBox(_T("²»ÄܹرÕÊܱ£»¤½ø³ÌŶ£¡£¡"));
ret = TRUE;
}
else
{
WriteMemory(pfOldTerminateProcess,oldCodeTermPro,CODE_LENGTH);
ret = oldTerminateProcess(hProcess,uExitCode);
WriteMemory(pfOldTerminateProcess,newCodeTermpro,CODE_LENGTH);
}
return ret;
}
//
// ×Ô¼º¶¨ÒåµÄ´ò¿ª½ø³Ìº¯Êý¡£
// Èôµ±Ç°´ò¿ª½ø³ÌΪÊܱ£»¤½ø³Ì£¬Ôò¼Ç¼Ï¸ÃÔ¶³Ìµ÷Óþä±ú¡£
//
HANDLE WINAPI MyOpenProcess(_In_ DWORD dwDesiredAccess,_In_
BOOL bInheritHandle,_In_ DWORD dwProcessId)
{
HANDLE hProcess = NULL;
WriteMemory(pfOldOpenProcess,oldCodeOpenPro,CODE_LENGTH);
hProcess = oldOpenProcess(dwDesiredAccess,bInheritHandle,dwProcessId);
if ( dwProcessId == g_dwProcessId)
{
g_hProcess = hProcess;
}
WriteMemory(pfOldOpenProcess,newCodeOpenPro,CODE_LENGTH);
return hProcess;
}
|