进程监控

    本来以hook方式hook系统api函数,后来发现不同的进程启动走的函数api是不同的,特别的对于父进程不是explorer的,比如在cmd下启动的exe这样hook的方式就不能够实现的。linux下有do_fork函数。win只能走内核去监控,幸好,微软为我们考虑了这层。开放了PsSetCreateProcessNotifyRoutine函数来实现进程线程的监控.

#include "ntddk.h"
#include "windef.h"
#include "define.h"

#define SYSNAME "System"
#define VERSIONLEN 100

const WCHAR devLink[] = L"\\DosDevices\\MyEvent";
const WCHAR devName[] = L"\\Device\\MyEvent";
UNICODE_STRING          devNameUnicd;
UNICODE_STRING          devLinkUnicd;
PVOID                    gpEventObject = NULL;            // 与应用程序通信的 Event 对象
ULONG                    ProcessNameOffset = 0;
PVOID                    outBuf[255];
BOOL                    g_bMainThread;
ULONG                    g_dwParentId;
CHECKLIST                CheckList;
ULONG                    BuildNumber;                    //系统版本号                    
ULONG                    SYSTEMID;                    //System进程的ID
PWCHAR                    Version[VERSIONLEN];

NTSTATUS PsLookupProcessByProcessId(IN ULONG ulProcId, OUT PEPROCESS * pEProcess);

ULONG GetProcessNameOffset()
{
    PEPROCESS curproc;
    int i;

    curproc = PsGetCurrentProcess();

    for (i = 0; i < 3 * PAGE_SIZE; i++)
    {
        if (!strncmp(SYSNAME, (PCHAR)curproc + i, strlen(SYSNAME)))
        {
            return i;
        }
    }

    return 0;
}

NTSTATUS GetRegValue(PCWSTR RegPath, PCWSTR ValueName, PWCHAR Value)
{
    int ReturnValue = 0;
    NTSTATUS Status;
    OBJECT_ATTRIBUTES ObjectAttributes;
    HANDLE KeyHandle;
    PKEY_VALUE_PARTIAL_INFORMATION valueInfoP;
    ULONG valueInfoLength, returnLength;
    UNICODE_STRING UnicodeRegPath;
    UNICODE_STRING UnicodeValueName;

    RtlInitUnicodeString(&UnicodeRegPath, RegPath);
    RtlInitUnicodeString(&UnicodeValueName, ValueName);

    InitializeObjectAttributes(&ObjectAttributes,
        &UnicodeRegPath,
        OBJ_CASE_INSENSITIVE, // Flags
        NULL, // Root directory
        NULL); // Security descriptor

    Status = ZwOpenKey(&KeyHandle,
        KEY_ALL_ACCESS,
        &ObjectAttributes);
    if (Status != STATUS_SUCCESS)
    {
        DbgPrint("ZwOpenKey Wrong\n");
        return 0;
    }

    valueInfoLength = sizeof(KEY_VALUE_PARTIAL_INFORMATION)+VERSIONLEN;
    valueInfoP = (PKEY_VALUE_PARTIAL_INFORMATION)ExAllocatePool
        (NonPagedPool, valueInfoLength);
    Status = ZwQueryValueKey(KeyHandle,
        &UnicodeValueName,
        KeyValuePartialInformation,
        valueInfoP,
        valueInfoLength,
        &returnLength);

    if (!NT_SUCCESS(Status))
    {
        DbgPrint("ZwQueryValueKey Wrong:%08x\n", Status);
        return Status;
    }
    else
    {
        RtlCopyMemory((PCHAR)Value, (PCHAR)valueInfoP->Data, valueInfoP->DataLength);
        ReturnValue = 1;
    }

    if (!valueInfoP);
    ExFreePool(valueInfoP);
    ZwClose(KeyHandle);
    return ReturnValue;
}

VOID ThreadCreateMon(IN HANDLE PId, IN HANDLE TId, IN BOOLEAN  bCreate)
{

    PEPROCESS   EProcess, PEProcess;
    NTSTATUS    status;
    HANDLE        dwParentPID;

    status = PsLookupProcessByProcessId((ULONG)PId, &EProcess);
    if (!NT_SUCCESS(status))
    {
        DbgPrint("PsLookupProcessByProcessId()\n");
        return;
    }

    if (bCreate)
    {
        dwParentPID = PsGetCurrentProcessId();
        status = PsLookupProcessByProcessId(
            (ULONG)dwParentPID,
            &PEProcess);
        if (!NT_SUCCESS(status))
        {
            DbgPrint("PsLookupProcessByProcessId()\n");
            return;
        }
        if (PId == 4)    //System进程创建的东东我们不管
            //在2000下是0,在XP后是4
            return;
        if ((g_bMainThread == TRUE)
            && (g_dwParentId != dwParentPID)
            && (dwParentPID != PId)
            )
        {
            g_bMainThread = FALSE;
            sprintf(outBuf, "=============================="
                "Remote Thread :"
                "=============================="
                "\nT:%18s%9d%9d%25s%9d\n"
                "======================================"
                "======================================\n",
                (char *)((char *)EProcess + ProcessNameOffset),
                PId, TId,
                (char *)((char *)PEProcess + ProcessNameOffset), dwParentPID);
            if (gpEventObject != NULL)
                KeSetEvent((PRKEVENT)gpEventObject, 0, FALSE);
        }
        if (CheckList.ONLYSHOWREMOTETHREAD)    //只显示远线程
            return;
        DbgPrint("T:%18s%9d%9d%25s%9d\n",
            (char *)((char *)EProcess + ProcessNameOffset),
            PId, TId,
            (char *)((char *)PEProcess + ProcessNameOffset), dwParentPID);
        sprintf(outBuf, "T:%18s%9d%9d%25s%9d\n",
            (char *)((char *)EProcess + ProcessNameOffset),
            PId, TId,
            (char *)((char *)PEProcess + ProcessNameOffset), dwParentPID);
        if (gpEventObject != NULL)
            KeSetEvent((PRKEVENT)gpEventObject, 0, FALSE);
    }
    else if (CheckList.SHOWTERMINATETHREAD)
    {
        DbgPrint("TERMINATED == THREAD ID: %d\n", TId);
        sprintf(outBuf, "TERMINATED == THREAD ID: %d\n", TId);
        if (gpEventObject != NULL)
            KeSetEvent((PRKEVENT)gpEventObject, 0, FALSE);
    }
}


VOID ProcessCreateMon(HANDLE hParentId, HANDLE PId, BOOLEAN bCreate)
{

    PEPROCESS        EProcess, PProcess;
    NTSTATUS        status;
    HANDLE            TId;

    g_dwParentId = hParentId;
    status = PsLookupProcessByProcessId((ULONG)PId, &EProcess);
    if (!NT_SUCCESS(status))
    {
        DbgPrint("PsLookupProcessByProcessId()\n");
        return;
    }
    status = PsLookupProcessByProcessId((ULONG)hParentId, &PProcess);
    if (!NT_SUCCESS(status))
    {
        DbgPrint("PsLookupProcessByProcessId()\n");
        return;
    }

    if (bCreate)
    {
        g_bMainThread = TRUE;
        DbgPrint("P:%18s%9d%9d%25s%9d\n",
            (char *)((char *)EProcess + ProcessNameOffset),
            PId, PsGetCurrentThreadId(),
            (char *)((char *)PProcess + ProcessNameOffset),
            hParentId
            );
        sprintf(outBuf, "P:%18s%9d%9d%25s%9d\n",
            (char *)((char *)EProcess + ProcessNameOffset),
            PId, PsGetCurrentThreadId(),
            (char *)((char *)PProcess + ProcessNameOffset),
            hParentId
            );
        if (gpEventObject != NULL)
            KeSetEvent((PRKEVENT)gpEventObject, 0, FALSE);
    }
    else if (CheckList.SHOWTERMINATEPROCESS)
    {
        DbgPrint("TERMINATED == PROCESS ID: %d\n", PId);
        sprintf(outBuf, "TERMINATED == PROCESS ID: %d\n", PId);
        if (gpEventObject != NULL)
            KeSetEvent((PRKEVENT)gpEventObject, 0, FALSE);
    }

}

NTSTATUS OnUnload(IN PDRIVER_OBJECT pDriverObject)
{
    DbgPrint("OnUnload called\n");
    return STATUS_SUCCESS;
}

NTSTATUS DeviceIoControlDispatch(
    IN  PDEVICE_OBJECT  DeviceObject,
    IN  PIRP            pIrp
    )
{
    PIO_STACK_LOCATION              irpStack;
    NTSTATUS                        status;
    PVOID                           inputBuffer;
    ULONG                           inputLength;
    PVOID                           outputBuffer;
    ULONG                           outputLength;
    OBJECT_HANDLE_INFORMATION        objHandleInfo;

    status = STATUS_SUCCESS;
    // 取出IOCTL请求代码
    irpStack = IoGetCurrentIrpStackLocation(pIrp);

    switch (irpStack->MajorFunction)
    {
    case IRP_MJ_CREATE:
        DbgPrint("Call IRP_MJ_CREATE\n");
        break;
    case IRP_MJ_CLOSE:
        DbgPrint("Call IRP_MJ_CLOSE\n");
        break;
    case IRP_MJ_DEVICE_CONTROL:
        DbgPrint("IRP_MJ_DEVICE_CONTROL\n");
        inputLength = irpStack->Parameters.DeviceIoControl.InputBufferLength;
        outputLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength;
        switch (irpStack->Parameters.DeviceIoControl.IoControlCode)
        {
        case IOCTL_PASSEVENT:    //用事件做通信
            inputBuffer = pIrp->AssociatedIrp.SystemBuffer;

            DbgPrint("inputBuffer:%08x\n", (HANDLE)inputBuffer);
            status = ObReferenceObjectByHandle(*(HANDLE *)inputBuffer,
                GENERIC_ALL,
                NULL,
                KernelMode,
                &gpEventObject,
                &objHandleInfo);

            if (status != STATUS_SUCCESS)
            {
                DbgPrint("wrong\n");
                break;
            }
            break;
        case IOCTL_UNPASSEVENT:
            if (gpEventObject)
                ObDereferenceObject(gpEventObject);
            DbgPrint("UNPASSEVENT called\n");
            break;
        case IOCTL_PASSBUF:
            RtlCopyMemory(pIrp->UserBuffer, outBuf, outputLength);
            break;
        case IOCTL_PASSEVSTRUCT:
            inputBuffer = pIrp->AssociatedIrp.SystemBuffer;
            memset(&CheckList, 0, sizeof(CheckList));
            RtlCopyMemory(&CheckList, inputBuffer, sizeof(CheckList));
            DbgPrint("%d:%d\n", CheckList.ONLYSHOWREMOTETHREAD, CheckList.SHOWTHREAD);
            break;
        default:
            break;
        }
        break;
    default:
        DbgPrint("Call IRP_MJ_UNKNOWN\n");
        break;
    }

    pIrp->IoStatus.Status = status;
    pIrp->IoStatus.Information = 0;
    IoCompleteRequest(pIrp, IO_NO_INCREMENT);
    return status;
}

NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING theRegistryPath)
{
    NTSTATUS                Status;
    PDEVICE_OBJECT            pDevice;

    DbgPrint("DriverEntry called!\n");
    g_bMainThread = FALSE;

    if (1 != GetRegValue(L"\\Registry\\Machine\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", L"CSDVersion", Version))
    {
        DbgPrint("GetRegValueDword Wrong\n");
    }
    PsGetVersion(NULL, NULL, &BuildNumber, NULL);
    DbgPrint("[[[%d]]]:[[[%ws]]]", BuildNumber, Version);

    RtlInitUnicodeString(&devNameUnicd, devName);
    RtlInitUnicodeString(&devLinkUnicd, devLink);

    Status = IoCreateDevice(pDriverObject,
        0,
        &devNameUnicd,
        FILE_DEVICE_UNKNOWN,
        0,
        TRUE,
        &pDevice);
    if (!NT_SUCCESS(Status))
    {
        DbgPrint(("Can not create device.\n"));
        return Status;
    }

    Status = IoCreateSymbolicLink(&devLinkUnicd, &devNameUnicd);
    if (!NT_SUCCESS(Status))
    {
        DbgPrint(("Cannot create link.\n"));
        return Status;
    }

    ProcessNameOffset = GetProcessNameOffset();

    pDriverObject->DriverUnload = OnUnload;
    pDriverObject->MajorFunction[IRP_MJ_CREATE] =
        pDriverObject->MajorFunction[IRP_MJ_CLOSE] =
        pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DeviceIoControlDispatch;//irp有27个派遣例程 具体参照相关的头文件

    Status = PsSetCreateProcessNotifyRoutine(ProcessCreateMon, FALSE);
    if (!NT_SUCCESS(Status))
    {
        DbgPrint("PsSetCreateProcessNotifyRoutine()\n");
        return Status;
    }

    Status = PsSetCreateThreadNotifyRoutine(ThreadCreateMon);
    if (!NT_SUCCESS(Status))
    {
        DbgPrint("PsSetCreateThreadNotifyRoutine()\n");
        return Status;
    }

    return STATUS_SUCCESS;
}#include "stdio.h"

#define FILE_DEVICE_EVENT  0x8000

// Define Interface reference/dereference routines for
// Interfaces exported by IRP_MN_QUERY_INTERFACE

#define EVENT_IOCTL(index) \
    CTL_CODE(FILE_DEVICE_EVENT, index, METHOD_BUFFERED, FILE_READ_DATA)

#define IOCTL_PASSEVENT \
    CTL_CODE(FILE_DEVICE_EVENT, 0x801, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_PASSBUF \
    CTL_CODE(FILE_DEVICE_EVENT, 0x802, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_UNPASSEVENT \
    CTL_CODE(FILE_DEVICE_EVENT, 0x803, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_PASSEVSTRUCT \
    CTL_CODE(FILE_DEVICE_EVENT, 0x804, METHOD_BUFFERED, FILE_ANY_ACCESS)

typedef struct        
{
    int SHOWTHREAD;
    int ONLYSHOWREMOTETHREAD;
    int SHOWTERMINATEPROCESS;
    int SHOWTERMINATETHREAD;
}CHECKLIST, *PCHECKLIST;


win2003 部分头找不到 

用这个
#include "stdio.h"
#define FILE_DEVICE_EVENT  0x8000

#define FILE_ANY_ACCESS  0
#define METHOD_BUFFERED  0

#define CTL_CODE( DeviceType, Function, Method, Access ) (                 \
    ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \
    )

// Define Interface reference/dereference routines for
// Interfaces exported by IRP_MN_QUERY_INTERFACE

#define EVENT_IOCTL(index) \
    CTL_CODE(FILE_DEVICE_EVENT, index, METHOD_BUFFERED, FILE_READ_DATA)

#define IOCTL_PASSEVENT \
    CTL_CODE(FILE_DEVICE_EVENT, 0x801, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_PASSBUF \
    CTL_CODE(FILE_DEVICE_EVENT, 0x802, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_UNPASSEVENT \
    CTL_CODE(FILE_DEVICE_EVENT, 0x803, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_PASSEVSTRUCT \
    CTL_CODE(FILE_DEVICE_EVENT, 0x804, METHOD_BUFFERED, FILE_ANY_ACCESS)

typedef struct        
{
    BOOL SHOWTHREAD;
    BOOL ONLYSHOWREMOTETHREAD;
    BOOL SHOWTERMINATEPROCESS;
    BOOL SHOWTERMINATETHREAD;
}CHECKLIST, *PCHECKLIST;

可以参考0day安全

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值