进程创建监控

    上次讲了下进程保护原理,这次讲一下进程监控。监视进程创建,也就是监视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

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页