上次讲了下进程保护原理,这次讲一下进程监控。监视进程创建,也就是监视EXE程序启动,就要hook掉创建进程的API,创建进程的API有ntdll!ZwCreateProcessEx、ZwCreateSection、ZwCreateThread等,kernel32里有CreateProcessA(W)和CreateProcessInternalA(W),hook ZW函数比较麻烦,因为那时进程刚创建,还没有加载模块,所以无法获取EXE路径,而ZwCreateSection可以获取文件句柄,然后再转路径,但在VB下测试失败了,hook后进程创建不起来,不知道VC下如何。hook ZwCreateThread也行,但是只能得到进程ID,进程虽创建但仍然是空的,找不到获取路径的办法,所以我们还是以hook kernel32的函数为例,最终,我们决定hook CreateProcessInternalA(W),两个都要hook。完成后生成DLL,再用VB调用测试,效果不错,运行进程时会弹出提示框,提示是否允许运行。不过,同样的,消息hook只对GUI进程管用,对cmd之类的无界面进程无效,想做彻底的话还是用驱动比较好。
DLL代码如下:
// HookApi.cpp : Defines the entry point for the DLL application.
//************* http://zzmzzff.blog.163.com ************************
//***************** 进程创建监控 ***********************************
#include "stdafx.h"
#include "windows.h"
#include "stdio.h"
#include <stdlib.h>
#pragma data_seg(".Shared")
HINSTANCE g_hThisDLL=NULL;
HHOOK g_hHook=NULL;
HWND g_hWnd=NULL;
//DWORD g_PID=NULL;
BOOL g_Lock=false;
#pragma data_seg()
typedef BOOL (WINAPI *FNCreateProcessInternalA)(
HANDLE hToken,
LPCSTR lpApplicationName,
LPSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPCSTR lpCurrentDirectory,
LPSTARTUPINFOA lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation,
PHANDLE hNewToken
);
typedef BOOL (WINAPI *FNCreateProcessInternalW)(
HANDLE hToken,
LPCWSTR lpApplicationName,
LPWSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPCSTR lpCurrentDirectory,
LPSTARTUPINFOA lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation,
PHANDLE hNewToken
);
//hook类
class CHookInfo
{
private:
BYTE m_OldCode[5];
BYTE m_NewCode[5];
DWORD m_FunAddr;
public:
BOOL HookApi(LPCSTR sDllName,LPCSTR sFunName,DWORD pNewFunc)
{
if(sDllName)m_FunAddr=(DWORD)GetProcAddress(GetModuleHandle(sDllName),sFunName);
else m_FunAddr=(DWORD)sFunName;
if(!m_FunAddr)return FALSE;
memcpy(m_OldCode, (PVOID)m_FunAddr, 5);
m_NewCode[0]=0xE9;
int dwJmpAddr=pNewFunc-m_FunAddr-5;
memcpy(&m_NewCode[1],&dwJmpAddr,4);
return HookStatus(TRUE);
}
BOOL HookStatus(BOOL bIsHook)
{
if(bIsHook)return WriteProcessMemory(GetCurrentProcess(), (PVOID)m_FunAddr, m_NewCode, 5, 0);
return WriteProcessMemory(GetCurrentProcess(), (PVOID)m_FunAddr, m_OldCode, 5, 0);
}
};
FNCreateProcessInternalA CreateProcessInternalA=NULL;
FNCreateProcessInternalW CreateProcessInternalW=NULL;
DWORD ThisProcessID=NULL;
HANDLE hProcess=NULL;
WCHAR szwFilePath[MAX_PATH] = {0};
char szFilePath[MAX_PATH] = {0};
char szModuleName[MAX_PATH] = {0};
char szInfo[1024] = {0};
CHookInfo g_HookCreateProcessInternalA;
CHookInfo g_HookCreateProcessInternalW;
BOOL lpWstrToPath(LPWSTR lpwstr,char *lpchar)
{
DWORD dwNum = WideCharToMultiByte(CP_OEMCP, 0, (LPCWCH)lpwstr, -1, NULL, 0, NULL, false);
if (dwNum != 0)
{
char *lpAnsiName = new char[dwNum + 1];
dwNum = WideCharToMultiByte(CP_OEMCP, NULL, (LPCWCH)lpwstr, -1, lpAnsiName, dwNum + 1, NULL, false);
memset(lpchar, 0x0, MAX_PATH * sizeof(char));
strncpy(lpchar, lpAnsiName, strlen(lpAnsiName));
return TRUE;
}
}
BOOL ShowMsg()
{
sprintf(szInfo, "命令行: %s\n\n父进程: %s\n", szFilePath, szModuleName);
return (IDYES==::MessageBox(NULL, szInfo, "有进程将要创建,是否允许?", MB_YESNO|MB_TOPMOST));
}
BOOL WINAPI HookCreateProcessInternalA(
HANDLE hToken,
LPCSTR lpApplicationName,
LPSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPCSTR lpCurrentDirectory,
LPSTARTUPINFOA lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation,
PHANDLE hNewToken
)
{
BOOL RetVal;
if (g_Lock) return FALSE;
if (lpCommandLine != NULL)
{
memset(szFilePath, 0x0, MAX_PATH * sizeof(char));
strcpy(szFilePath, lpCommandLine);
if (ShowMsg()==false) return FALSE;
}
g_HookCreateProcessInternalA.HookStatus(false);
RetVal=CreateProcessInternalA(
hToken,
lpApplicationName,
lpCommandLine,
lpProcessAttributes,
lpThreadAttributes,
bInheritHandles,
dwCreationFlags,
lpEnvironment,
lpCurrentDirectory,
lpStartupInfo,
lpProcessInformation,
hNewToken
);
g_HookCreateProcessInternalA.HookStatus(true);
//if(NT_ERROR(RetVal))return RetVal;
return RetVal;
}
BOOL WINAPI HookCreateProcessInternalW(
HANDLE hToken,
LPCWSTR lpApplicationName,
LPWSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPCSTR lpCurrentDirectory,
LPSTARTUPINFOA lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation,
PHANDLE hNewToken
)
{
BOOL RetVal;
if (g_Lock) return FALSE;
if (lpCommandLine != NULL)
{
lpWstrToPath(lpCommandLine,szFilePath);
if (ShowMsg()==false) return FALSE;
}
g_HookCreateProcessInternalW.HookStatus(false);
RetVal=CreateProcessInternalW(
hToken,
lpApplicationName,
lpCommandLine,
lpProcessAttributes,
lpThreadAttributes,
bInheritHandles,
dwCreationFlags,
lpEnvironment,
lpCurrentDirectory,
lpStartupInfo,
lpProcessInformation,
hNewToken
);
g_HookCreateProcessInternalW.HookStatus(true);
return RetVal;
}
BOOL WINAPI InitHook() //初始化hook
{
hProcess = GetCurrentProcess();
ThisProcessID=GetCurrentProcessId();
::GetModuleFileName(NULL,szModuleName,MAX_PATH);
CreateProcessInternalA=(FNCreateProcessInternalA)GetProcAddress(LoadLibrary("kernel32.dll"), "CreateProcessInternalA");
CreateProcessInternalW=(FNCreateProcessInternalW)GetProcAddress(LoadLibrary("kernel32.dll"), "CreateProcessInternalW");
g_HookCreateProcessInternalA.HookApi("kernel32.dll", "CreateProcessInternalA", (DWORD)HookCreateProcessInternalA);
g_HookCreateProcessInternalW.HookApi("kernel32.dll", "CreateProcessInternalW", (DWORD)HookCreateProcessInternalW);
return TRUE;
}
void WINAPI EndHook()
{
g_HookCreateProcessInternalA.HookStatus(false);
g_HookCreateProcessInternalW.HookStatus(false);
}
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
g_hThisDLL = (HINSTANCE)hModule;
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
InitHook();
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
EndHook();
break;
}
return TRUE;
}
LRESULT CALLBACK KeyboardProc(int Code,WPARAM wParam,LPARAM lParam)
{
return CallNextHookEx(g_hHook,Code,wParam,lParam);
}
LONG WINAPI StartHookMon()
{
if(!g_hHook)g_hHook=SetWindowsHookEx(WH_DEBUG, (HOOKPROC)KeyboardProc, g_hThisDLL, 0);
return (LONG)g_hHook;
}
BOOL WINAPI UnHookMon()
{
UnhookWindowsHookEx(g_hHook);
g_hHook=NULL;
g_hWnd=NULL;
return TRUE;
}
BOOL WINAPI LockMon(BOOL bLock)
{
g_Lock=bLock;
return TRUE;
}
HWND WINAPI SetReceiveWindow(HWND hReceiveWnd)
{
HWND LastWnd=g_hWnd;
if(!g_hWnd)g_hWnd=hReceiveWnd;
return LastWnd;
}
//HookApi.def
EXPORTS
StartHookMon
UnHookMon
LockMon
SEGMENTS
.Shared READ WRITE SHARED
'VB中调用
Option Explicit
Private Declare Function GetCurrentProcessId Lib "kernel32" () As Long
Private Declare Function StartHookMon Lib "HookApi.dll" () As Boolean
Private Declare Function UnHookMon Lib "HookApi.dll" () As Boolean
Private Declare Function LockMon Lib "HookApi.dll" (ByVal bLock As Boolean) As Boolean
Private Sub Check1_Click()
If Command2.Enabled Then LockMon Check1.Value
End Sub
Private Sub Command1_Click()
StartHookMon
LockMon Check1.Value
Command1.Enabled = False
Command2.Enabled = True
End Sub
Private Sub Command2_Click()
UnHookMon '取消
Command1.Enabled = True
Command2.Enabled = False
End Sub
Private Sub Form_Load()
Command2.Enabled = False
End Sub
Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
If Command2.Enabled Then Command2_Click
End Sub
//******************* 完 ***************************
http://pan.baidu.com/s/1o8jLtrk