NtCreateProcessEx

NTSTATUS __stdcall NtCreateProcessEx(OUT PHANDLE ProcessHandle,
            IN ACCESS_MASK DesiredAccess,
            IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
            IN HANDLE ParentProcess,
            IN BOOLEAN InheritObjectTable,
            IN HANDLE SectionHandle OPTIONAL,
            IN HANDLE DebugPort OPTIONAL,
            IN HANDLE ExceptionPort OPTIONAL,
            IN BOOLEAN InJob)

参数说明:
ProcessHandle 是一个输出参数,如果创建成功,则它包含了所创建的进程的句柄。

DesiredAccess 包含了对新进程的访问权限。

ObjectAttributes 是一个可选的指针参数(意指可以为NULL),它指定了进程对象的属性。

ParentProcess 指向父进程的句柄,这是一个必需的参数,不能为NULL,并且调用者必须对该进程具有PROCESS_CREATE_PROCESS 访问权限。Flags 是创建标志,其中有一个标志PROCESS_CREATE_FLAGS_INHERIT_HANDLES 特别值得一提:NtCreateProcess专门有一个布尔参数指定是否该标志为TRUE,表明新进程的对象句柄表是否要复制父进程的句柄表,或者初始设置为空。

SectionHandle 是一个可选的句柄,指向一个内存区对象,代表了该进程的映像文件,调用者对于此内存区对象必须具有SECTION_MAP_EXECUTE 访问权限。

DebugPort 也是一个可选的句柄,指向一个端口对象,如果此句柄参数不为NULL,则此端口被赋为新进程的调试端口,否则,新进程没有调试端口。而且,调用者对于调试端口对象必须具有PORT_WRITE 和PORT_READ 访问权限。

ExceptionPort 也是一个可选的句柄,指向一个端口对象,如果此句柄参数不为NULL,则此端口被赋为新进程的异常端口,否则,新进程没有异常端口。调用者对于异常端口对象必须具有PORT_WRITE 和PORT_READ 访问权限。

JobMemberLevel 指定了要创建的进程在一个Job 集中的级别。

 

获得路径名:

一般创建进程时ObjectAttributes其实是空的,SectionHandle才是有内容的。因此一般通过这个SectionHandle获取进程文件名。
原理是:
ObReferenceObjectByHandle,通过SectionHandle得到SectionObject,即指向_SECTION_OBJECT结构的指针。
通过_SECTION_OBJECT得到SegmentObject成员,指向一个_SEGMENT_OBJECT结构。
_SEGMENT_OBJECT结构的BaseAddress成员,指向一个_CONTROL_AREA结构。
这个_CONTROL_AREA结构的FilePointer成员,就是指向描述文件的_FILE_OBJECT结构的指针
从_FILE_OBJECT结构的DeviceObject成员中得到所在盘符(调用RtlVolumeDeviceToDosName),加上FileName成员指定的路径,就是这个文件的全路径。

函数如下:

传入的是SectionHandle

NTSTATUS   GetFullName(HANDLE     KeyHandle,char   *fullname)   
{   
  NTSTATUS   ns;   
  PVOID   pKey=NULL,pFile=NULL;   
  UNICODE_STRING                   fullUniName;   
  ANSI_STRING                           akeyname;   
  ULONG   actualLen;   
  UNICODE_STRING   dosName;   

  fullUniName.Buffer=NULL;   
  fullUniName.Length=0;   
  fullname[0]=0x00;   
  ns=   ObReferenceObjectByHandle(   KeyHandle,   0,   NULL,   KernelMode,   &pKey,   NULL   )   ;   
  if(   !NT_SUCCESS(ns))   return   ns;   

  fullUniName.Buffer   =   ExAllocatePool(   PagedPool,   MAXPATHLEN*2);//1024*2   
  fullUniName.MaximumLength   =   MAXPATHLEN*2;   

  __try   
  {   

    pFile=(PVOID)*(ULONG   *)((char   *)pKey+20);   
    pFile=(PVOID)*(ULONG   *)((char   *)pFile);   
    pFile=(PVOID)*(ULONG   *)((char   *)pFile+36);   


    ObReferenceObjectByPointer(pFile,   0,   NULL,   KernelMode);   
    RtlVolumeDeviceToDosName(((PFILE_OBJECT)pFile)->DeviceObject,&dosName);     
    RtlCopyUnicodeString(&fullUniName,   &dosName);   
    RtlAppendUnicodeStringToString(&fullUniName,&((PFILE_OBJECT)pFile)->FileName);   

    ObDereferenceObject(pFile);   
    ObDereferenceObject(pKey   );   

    RtlUnicodeStringToAnsiString(   &akeyname,   &fullUniName,   TRUE   );   
    if(akeyname.Length<MAXPATHLEN)     
    {   
      memcpy(fullname,akeyname.Buffer,akeyname.Length);   
      fullname[akeyname.Length]=0x00;   
    }   
    else   
    {   
      memcpy(fullname,akeyname.Buffer,MAXPATHLEN);   
      fullname[MAXPATHLEN-1]=0x00;   
    }   

    RtlFreeAnsiString(   &akeyname   );   
    ExFreePool(dosName.Buffer);   
    ExFreePool(   fullUniName.Buffer   );   

    return   STATUS_SUCCESS;   

  }   

  __except(1)   
  {   
    if(fullUniName.Buffer)   ExFreePool(   fullUniName.Buffer     );   
    if(pKey)   ObDereferenceObject(pKey   );   
    return   STATUS_SUCCESS;   

  }   

}   


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值