zoukankan      html  css  js  c++  java
  • windows 64位 系统非HOOK方式监控进程创建

    以下内容参考黑客防线2012合订本354页

    MSDN 原话:

    The PsSetCreateProcessNotifyRoutineEx routine registers or removes a callback routine that notifies the caller when a process is created or exits.

    NTSTATUS
      PsSetCreateProcessNotifyRoutineEx(
        IN PCREATE_PROCESS_NOTIFY_ROUTINE_EX  NotifyRoutine,
        IN BOOLEAN  Remove
        );

    可以通过这个函数注册一个回调函数监控进程创建. 比hook方便很多.

    对于CreateProcessNotifyEx:

    VOID
      CreateProcessNotifyEx(
        __inout PEPROCESS  Process,
        __in HANDLE  ProcessId,
        __in_opt PPS_CREATE_NOTIFY_INFO  CreateInfo
        );

    其中CreateInfo是

    If this parameter is non-NULL, a new process is being created, and CreateInfo points to a PS_CREATE_NOTIFY_INFO structure that describes the new process. If this parameter is NULL, the specified process is exiting. 

    空的时候表示进程退出, 非空时表示进程创建.并且里面:

    typedef struct _PS_CREATE_NOTIFY_INFO {
      __in SIZE_T  Size;
      union {
        __in ULONG  Flags;
        struct {
          __in ULONG  FileOpenNameAvailable : 1;
          __in ULONG  Reserved : 31;
        };
      };
      __in HANDLE  ParentProcessId;  //创建者pid
      __in CLIENT_ID  CreatingThreadId;
      __inout struct _FILE_OBJECT  *FileObject;
      __in PCUNICODE_STRING  ImageFileName;//被创建进程完整路径
      __in_opt PCUNICODE_STRING  CommandLine;
      __inout NTSTATUS  CreationStatus;  //修改为错误的status禁止创建进程
    } PS_CREATE_NOTIFY_INFO, *PPS_CREATE_NOTIFY_INFO;

    测试结果:

     附上大佬的代码 (自己加了一些注释):

    //下面2个函数声明后就能用
    NTKERNELAPI PCHAR PsGetProcessImageFileName(PEPROCESS Process);
    NTKERNELAPI NTSTATUS PsLookupProcessByProcessId(HANDLE ProcessId, PEPROCESS *Process);
    
    PCHAR GetProcessNameByProcessId(HANDLE ProcessId)
    {
        NTSTATUS st = STATUS_UNSUCCESSFUL;
        PEPROCESS ProcessObj = NULL;
        PCHAR string = NULL;
        st = PsLookupProcessByProcessId(ProcessId, &ProcessObj);
        if (NT_SUCCESS(st))
        {
            string = PsGetProcessImageFileName(ProcessObj);
            ObfDereferenceObject(ProcessObj);
        }
        return string;
    }
    
    VOID
    NotifyCreateProcess(
        __inout PEPROCESS Process,//如果是创建(退出),则是被创建(退出)进程的exe名(不包括完整路径)
        __in HANDLE ProcessId,//如果是创建(退出)进程,则是被创建(退出)进程的pid
        __in_opt PPS_CREATE_NOTIFY_INFO CreateInfo//如果是创建进程,则里面包含被创建进程完整路径名
    )
    {
    
        if (CreateInfo)
        {
        //    DbgPrint("param ProcessId is %d
    ", ProcessId); //被创建进程id
        //    DbgPrint("param Process is %s
    ", PsGetProcessImageFileName(Process));
            DbgPrint("%s of who the pid is %d create process %wZ
    ",
                GetProcessNameByProcessId(CreateInfo->ParentProcessId),
                CreateInfo->ParentProcessId,
                CreateInfo->ImageFileName);
            if (_stricmp("calc.exe", PsGetProcessImageFileName(Process)) == 0)
            {
                DbgPrint("forbidding start calc.exe!
    ");
                CreateInfo->CreationStatus = STATUS_ACCESS_DENIED;
            }
    
        }
        else
        {
            DbgPrint("process %s exit
    ", PsGetProcessImageFileName(Process));
        }
    }
  • 相关阅读:
    [转]Putty中文乱码解决方法
    linux内核编译
    grub2的使用
    linux的简单网络配置
    [转]建立swap分区
    [转]ps/2键盘线序识别方法
    Linux下备份系统至另一硬盘
    [转]Vimium快捷键
    [转] C中的位域
    [转]diskpart命令
  • 原文地址:https://www.cnblogs.com/freesec/p/7623675.html
Copyright © 2011-2022 走看看