进程监控

来源:互联网 发布:阿里软件的网站 编辑:程序博客网 时间:2024/06/06 04:04

    本来以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 100const 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进程的IDPWCHAR                    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安全

0 0
原创粉丝点击