r0调用ntOpenprocess函数枚举进程

    技术2024-11-06  26

    需要先把Kthread中的PreviousMode的值置成KernelMode

    因为调用CqEnumProcessInfoByMyOpenProcess这个函数的时候,是由应用层的程序调用DeviceIoControl进入内核的,所以要经过

    Kifastcallentry,Kifastcallentry在执行中会把当前要进入内核的这个线程的PreviousMode设置成UserMode,所以当我调用NtOpenProcess时,NtOpenprocess在执行中会判断当前的调用模式,如果不改Kthread中的PreviousMode,NtOpenprocess发现是UserMode,所以要判断clientId则个参数的地址是不是用户层地址,当它发现这个地址是内核地址的时候,执行就是败了,所以要把当前线程的Ktrhead的PerviousMode这个值置成KernelMode,欺骗NtOpenProcess,,这样NtOpenProcess判断的时候就认为这个调用是内核的调用,所以就可以执行成功。

    NTSTATUS  CqEnumProcessInfoByMyOpenProcess(PPROCESS_INFO pProcessInfo){ NTSTATUS Status = STATUS_UNSUCCESSFUL; CLIENT_ID ClientId = {0}; ULONG i = 0; HANDLE ProcessHandle = 0; PEPROCESS Process = NULL; PKTHREAD Kthread = NULL; OBJECT_ATTRIBUTES ProcAttr = {0};

     InitializeObjectAttributes(&ProcAttr, 0, 0, 0, 0); Kthread = (PKTHREAD)PsGetCurrentThread(); *((PUCHAR)Kthread + CqGetOffset(enumPreviousModeOffsetByKthread)) = KernelMode; for(i = 0; i < 65535; i++) {  ClientId.UniqueProcess = (HANDLE)i;  Status = MyNtOpenProcess(&ProcessHandle, PROCESS_ALL_ACCESS , &ProcAttr, &ClientId);  if( STATUS_SUCCESS == Status )  {   Status = PsLookupProcessByProcessId(i, &Process);   if( STATUS_SUCCESS != Status )   {    goto Exit0;   }   Status = CqSetProcessInfoByEProcess(pProcessInfo, Process);   if( NULL != Process )   {    ObDereferenceObject(Process);   }   if( NULL != ProcessHandle )   {    ZwClose(ProcessHandle);   }   ProcessHandle = 0;   Process = 0;   i+=3;  }  else  {   continue;  }

     }

     *((PUCHAR)Kthread + CqGetOffset(enumPreviousModeOffsetByKthread)) = UserMode;

     Status = STATUS_SUCCESS;Exit0: return Status;}

    最新回复(0)