Exemple #1
0
BOOLEAN NTAPI
RtlDebugDestroyHeap(HANDLE HeapPtr)
{
    SIZE_T Size = 0;
    PHEAP Heap = (PHEAP)HeapPtr;

    if (Heap == RtlGetCurrentPeb()->ProcessHeap)
    {
        DPRINT1("HEAP: It's forbidden delete process heap!");
        return FALSE;
    }

    if (Heap->Signature != HEAP_SIGNATURE)
    {
        DPRINT1("HEAP: Invalid heap %p signature 0x%x\n", Heap, Heap->Signature);
        return FALSE;
    }

    if (!RtlpValidateHeap(Heap, FALSE)) return FALSE;

    /* Make heap invalid by zeroing its signature */
    Heap->Signature = 0;

    /* Free validate headers copy if it was existing */
    if (Heap->HeaderValidateCopy)
    {
        ZwFreeVirtualMemory(NtCurrentProcess(),
                            &Heap->HeaderValidateCopy,
                            &Size,
                            MEM_RELEASE);
    }

    return TRUE;
}
Exemple #2
0
/* Usermode only! */
VOID
NTAPI
RtlpAddHeapToProcessList(PHEAP Heap)
{
    PPEB Peb;

    /* Get PEB */
    Peb = RtlGetCurrentPeb();

    /* Acquire the lock */
    RtlEnterCriticalSection(&RtlpProcessHeapsListLock);

    //_SEH2_TRY {
    /* Check if max number of heaps reached */
    if (Peb->NumberOfHeaps == Peb->MaximumNumberOfHeaps)
    {
        // TODO: Handle this case
        ASSERT(FALSE);
    }

    /* Add the heap to the process heaps */
    Peb->ProcessHeaps[Peb->NumberOfHeaps] = Heap;
    Peb->NumberOfHeaps++;
    Heap->ProcessHeapsListIndex = (USHORT)Peb->NumberOfHeaps;
    // } _SEH2_FINALLY {

    /* Release the lock */
    RtlLeaveCriticalSection(&RtlpProcessHeapsListLock);

    // } _SEH2_END
}
Exemple #3
0
/*
* SfuQueryEnvironmentVariableOffset
*
* Purpose:
*
* Return offset to the given environment variable.
*
*/
LPWSTR SfuQueryEnvironmentVariableOffset(
	PUNICODE_STRING Value
	)
{
	UNICODE_STRING   str1;
	PWCHAR           EnvironmentBlock, ptr;

	EnvironmentBlock = RtlGetCurrentPeb()->ProcessParameters->Environment;
	ptr = EnvironmentBlock;

	do {
		if (*ptr == 0)
			return 0;

		RtlSecureZeroMemory(&str1, sizeof(str1));
		RtlInitUnicodeString(&str1, ptr);
		if (RtlPrefixUnicodeString(Value, &str1, TRUE))
			break;
		
		ptr += _strlen(ptr) + 1;

	} while (1);

	return (ptr + Value->Length / sizeof(WCHAR));
}
Exemple #4
0
/* Usermode only! */
VOID
NTAPI
RtlpRemoveHeapFromProcessList(PHEAP Heap)
{
    PPEB Peb;
    PHEAP *Current, *Next;
    ULONG Count;

    /* Get PEB */
    Peb = RtlGetCurrentPeb();

    /* Acquire the lock */
    RtlEnterCriticalSection(&RtlpProcessHeapsListLock);

    /* Check if we don't need anything to do */
    if ((Heap->ProcessHeapsListIndex == 0) ||
        (Heap->ProcessHeapsListIndex > Peb->NumberOfHeaps) ||
        (Peb->NumberOfHeaps == 0))
    {
        /* Release the lock */
        RtlLeaveCriticalSection(&RtlpProcessHeapsListLock);

        return;
    }

    /* The process actually has more than one heap.
       Use classic, lernt from university times algorithm for removing an entry
       from a static array */

    Current = (PHEAP *)&Peb->ProcessHeaps[Heap->ProcessHeapsListIndex - 1];
    Next = Current + 1;

    /* How many items we need to shift to the left */
    Count = Peb->NumberOfHeaps - (Heap->ProcessHeapsListIndex - 1);

    /* Move them all in a loop */
    while (--Count)
    {
        /* Copy it and advance next pointer */
        *Current = *Next;

        /* Update its index */
        (*Current)->ProcessHeapsListIndex -= 1;

        /* Advance pointers */
        Current++;
        Next++;
    }

    /* Decrease total number of heaps */
    Peb->NumberOfHeaps--;

    /* Zero last unused item */
    Peb->ProcessHeaps[Peb->NumberOfHeaps] = NULL;
    Heap->ProcessHeapsListIndex = 0;

    /* Release the lock */
    RtlLeaveCriticalSection(&RtlpProcessHeapsListLock);
}
Exemple #5
0
BOOL kull_m_process_peb(PKULL_M_MEMORY_HANDLE memory, PPEB pPeb, BOOL isWOW)
{
    BOOL status = FALSE;
    PROCESS_BASIC_INFORMATION processInformations;
    HANDLE hProcess = (memory->type == KULL_M_MEMORY_TYPE_PROCESS) ? memory->pHandleProcess->hProcess : GetCurrentProcess();
    KULL_M_MEMORY_HANDLE  hBuffer = {KULL_M_MEMORY_TYPE_OWN, NULL};
    KULL_M_MEMORY_ADDRESS aBuffer = {pPeb, &hBuffer};
    KULL_M_MEMORY_ADDRESS aProcess= {NULL, memory};
    PROCESSINFOCLASS info;
    ULONG szPeb, szBuffer, szInfos;
    LPVOID buffer;

#ifdef _M_X64
    if(isWOW)
    {
        info = ProcessWow64Information;
        szBuffer = sizeof(processInformations.PebBaseAddress);
        buffer = &processInformations.PebBaseAddress;
        szPeb = sizeof(PEB_F32);
    }
    else
    {
#endif
        info = ProcessBasicInformation;
        szBuffer = sizeof(processInformations);
        buffer = &processInformations;
        szPeb = sizeof(PEB);
#ifdef _M_X64
    }
#endif

    switch(memory->type)
    {
#ifndef MIMIKATZ_W2000_SUPPORT
    case KULL_M_MEMORY_TYPE_OWN:
        if(!isWOW)
        {
            *pPeb = *RtlGetCurrentPeb();
            status = TRUE;
            break;
        }
#endif
    case KULL_M_MEMORY_TYPE_PROCESS:
        if(NT_SUCCESS(NtQueryInformationProcess(hProcess, info, buffer, szBuffer, &szInfos)) && (szInfos == szBuffer) && processInformations.PebBaseAddress)
        {
            aProcess.address = processInformations.PebBaseAddress;
            status = kull_m_memory_copy(&aBuffer, &aProcess, szPeb);
        }
        break;
    }
    return status;
}
Exemple #6
0
VOID
NTAPI
RtlInitializeHeapManager(VOID)
{
    PPEB Peb;

    /* Get PEB */
    Peb = RtlGetCurrentPeb();

    /* Initialize heap-related fields of PEB */
    Peb->NumberOfHeaps = 0;

    /* Initialize the process heaps list protecting lock */
    RtlInitializeCriticalSection(&RtlpProcessHeapsListLock);
}
Exemple #7
0
VOID
NTAPI
RtlpSetHeapParameters(IN PRTL_HEAP_PARAMETERS Parameters)
{
    PPEB Peb;

    /* Get PEB */
    Peb = RtlGetCurrentPeb();

    /* Apply defaults for non-set parameters */
    if (!Parameters->SegmentCommit) Parameters->SegmentCommit = Peb->HeapSegmentCommit;
    if (!Parameters->SegmentReserve) Parameters->SegmentReserve = Peb->HeapSegmentReserve;
    if (!Parameters->DeCommitFreeBlockThreshold) Parameters->DeCommitFreeBlockThreshold = Peb->HeapDeCommitFreeBlockThreshold;
    if (!Parameters->DeCommitTotalFreeThreshold) Parameters->DeCommitTotalFreeThreshold = Peb->HeapDeCommitTotalFreeThreshold;
}
Exemple #8
0
NTSYSAPI
NTSTATUS
STDAPIVCALLTYPE
RtlSetThreadIsCritical(
    IN  BOOLEAN  NewValue,
    OUT PBOOLEAN OldValue OPTIONAL,
    IN  BOOLEAN  CheckFlag
    )
{
    PPEB     Peb;
    ULONG    Enable;
    NTSTATUS Status;

    if ( ARGUMENT_PRESENT(OldValue) ) {
        *OldValue = FALSE;
    }

    Peb = RtlGetCurrentPeb();
    if ( CheckFlag
         && ! (Peb->NtGlobalFlag & FLG_ENABLE_SYSTEM_CRIT_BREAKS) ) {
        return STATUS_UNSUCCESSFUL;
    }
    if ( ARGUMENT_PRESENT(OldValue) ) {
        NtQueryInformationThread(NtCurrentThread(),
                                 ThreadBreakOnTermination,
                                 &Enable,
                                 sizeof(Enable),
                                 NULL);

        *OldValue = (BOOLEAN) Enable;
    }

    Enable = NewValue;

    Status = NtSetInformationThread(NtCurrentThread(),
                                    ThreadBreakOnTermination,
                                    &Enable,
                                    sizeof(Enable));

    return Status;
}
Exemple #9
0
/*
* SfuBuildBotPath
*
* Purpose:
*
* Return full path to bot in both variants.
*
*/
BOOL SfuBuildBotPath(
	_Inout_ PZA_BOT_PATH Context
	)
{
	BOOL                           cond = FALSE, bResult = FALSE;
	OBJECT_ATTRIBUTES              obja;
	UNICODE_STRING                 ustr1, ustr2;
	WCHAR                          szRegBuffer[MAX_PATH + 1];
	HANDLE                         ProcessHeap; 
	HANDLE                         hKey = NULL;
	NTSTATUS                       status;
	KEY_VALUE_PARTIAL_INFORMATION *pki = NULL;
	LPWSTR                         lpEnv;
	ULONG                          memIO = 0;
	LPWSTR                         lpLocalBotName, lpPFilesBotName;
	PVOID                          Wow64Information = NULL;

	GUID sfGUID;

	if (Context == NULL)
		return bResult;

	ProcessHeap = RtlGetCurrentPeb()->ProcessHeap;

	RtlSecureZeroMemory(&ustr1, sizeof(ustr1));

	do {

		if (!SfInitMD5())
			break;

		RtlSecureZeroMemory(&sfGUID, sizeof(sfGUID));
		SfuCalcVolumeMD5((BYTE*)&sfGUID);

		status = NtQueryInformationProcess(NtCurrentProcess(), ProcessWow64Information, 
			&Wow64Information, sizeof(PVOID), NULL);
		if (!NT_SUCCESS(status))
			break;

		//query current user registry string
		if (!NT_SUCCESS(RtlFormatCurrentUserKeyPath(&ustr1)))
			break;

		lpLocalBotName = Context->szBotPathLocal;
		lpPFilesBotName = Context->szBotPathPFiles;

		RtlSecureZeroMemory(&szRegBuffer, sizeof(szRegBuffer));
		wsprintf(szRegBuffer, T_SHELL_FOLDERS_KEY, ustr1.Buffer);

		RtlFreeUnicodeString(&ustr1);
		
		//open User Shell Folders key to query Local AppData value
		RtlSecureZeroMemory(&ustr2, sizeof(ustr2));
		RtlInitUnicodeString(&ustr2, szRegBuffer);
		InitializeObjectAttributes(&obja, &ustr2, OBJ_CASE_INSENSITIVE, NULL, NULL);
		status = NtOpenKey(&hKey, KEY_READ, &obja);
		if (!NT_SUCCESS(status))
			break;

		//query value size
		RtlInitUnicodeString(&ustr2, T_LOCAL_APPDATA_VALUE);
		NtQueryValueKey(hKey, &ustr2, KeyValuePartialInformation,
			NULL, 0, &memIO);

		if (memIO == 0)
			break;

		pki = RtlAllocateHeap(ProcessHeap, HEAP_ZERO_MEMORY, memIO);
		if (pki == NULL)
			break;
		
		//query value
		status = NtQueryValueKey(hKey, &ustr2, KeyValuePartialInformation,
			pki, memIO, &memIO);

		if (!NT_SUCCESS(status)) 
			break;

		RtlInitUnicodeString(&ustr2, (WCHAR*)pki->Data);
		memIO = 0;

		//expand environment variable inside value
		RtlSecureZeroMemory(&szRegBuffer, sizeof(szRegBuffer));
		ustr1.Buffer = szRegBuffer;
		ustr1.Length = 0;
		ustr1.MaximumLength = sizeof(szRegBuffer);

		status = RtlExpandEnvironmentStrings_U(NULL, &ustr2, &ustr1, &memIO);
		if (!NT_SUCCESS(status)) {
			ustr1.Buffer = NULL;
			break;
		}

		//build result string
		_strcpy(lpLocalBotName, T_GLOBAL_LINK);
		_strcat(lpLocalBotName, szRegBuffer);
		
		wsprintf(_strend(lpLocalBotName), T_SIREFEF_DIRECTORY,
			sfGUID.Data1, sfGUID.Data2, sfGUID.Data3,
			sfGUID.Data4[0],
			sfGUID.Data4[1],
			sfGUID.Data4[2],
			sfGUID.Data4[3],
			sfGUID.Data4[4],
			sfGUID.Data4[5],
			sfGUID.Data4[6],
			sfGUID.Data4[7]);

		ustr1.Buffer = NULL;

		_strcpy(lpPFilesBotName, T_GLOBAL_LINK);
		
		if (Wow64Information == NULL) {
			lpEnv = L"ProgramFiles=";
		}
		else {
			lpEnv = L"ProgramFiles(x86)=";
		}

		RtlInitUnicodeString(&ustr2, lpEnv);
		lpEnv = SfuQueryEnvironmentVariableOffset(&ustr2);
		if (lpEnv) {
			_strcat(lpPFilesBotName, lpEnv);

			wsprintf(_strend(lpPFilesBotName), T_SIREFEF_DIRECTORY,
				sfGUID.Data1, sfGUID.Data2, sfGUID.Data3,
				sfGUID.Data4[0],
				sfGUID.Data4[1],
				sfGUID.Data4[2],
				sfGUID.Data4[3],
				sfGUID.Data4[4],
				sfGUID.Data4[5],
				sfGUID.Data4[6],
				sfGUID.Data4[7]);
		}

		bResult = TRUE;

	} while (cond);

	if (hKey != NULL) {
		NtClose(hKey);
	}

	if (ustr1.Buffer != NULL) {
		RtlFreeUnicodeString(&ustr1);
	}

	if (pki != NULL) {
		RtlFreeHeap(ProcessHeap, 0, pki);
	}
	return bResult;
}
Exemple #10
0
/*
 * @implemented
 */
NTSTATUS NTAPI
RtlQueryEnvironmentVariable_U(PWSTR Environment,
                              PUNICODE_STRING Name,
                              PUNICODE_STRING Value)
{
   NTSTATUS Status;
   PWSTR wcs;
   UNICODE_STRING var;
   PWSTR val;
   BOOLEAN SysEnvUsed = FALSE;

   DPRINT("RtlQueryEnvironmentVariable_U Environment %p Variable %wZ Value %p\n",
          Environment, Name, Value);

   if (Environment == NULL)
   {
      PPEB Peb = RtlGetCurrentPeb();
      if (Peb) {
          Environment = Peb->ProcessParameters->Environment;
          SysEnvUsed = TRUE;
      }
   }

   if (Environment == NULL)
   {
      return(STATUS_VARIABLE_NOT_FOUND);
   }

   Value->Length = 0;
   if (SysEnvUsed)
      RtlAcquirePebLock();

   wcs = Environment;
   DPRINT("Starting search at :%p\n", wcs);
   while (*wcs)
   {
      var.Buffer = wcs++;
      wcs = wcschr(wcs, L'=');
      if (wcs == NULL)
      {
         wcs = var.Buffer + wcslen(var.Buffer);
         DPRINT("Search at :%S\n", wcs);
      }
      if (*wcs)
      {
         var.Length = var.MaximumLength = (USHORT)(wcs - var.Buffer) * sizeof(WCHAR);
         val = ++wcs;
         wcs += wcslen(wcs);
         DPRINT("Search at :%S\n", wcs);

         if (RtlEqualUnicodeString(&var, Name, TRUE))
         {
            Value->Length = (USHORT)(wcs - val) * sizeof(WCHAR);
            if (Value->Length <= Value->MaximumLength)
            {
               memcpy(Value->Buffer, val,
                      min(Value->Length + sizeof(WCHAR), Value->MaximumLength));
               DPRINT("Value %S\n", val);
               DPRINT("Return STATUS_SUCCESS\n");
               Status = STATUS_SUCCESS;
            }
            else
            {
               DPRINT("Return STATUS_BUFFER_TOO_SMALL\n");
               Status = STATUS_BUFFER_TOO_SMALL;
            }

            if (SysEnvUsed)
               RtlReleasePebLock();

            return(Status);
         }
      }
      wcs++;
   }

   if (SysEnvUsed)
      RtlReleasePebLock();

   DPRINT("Return STATUS_VARIABLE_NOT_FOUND: %wZ\n", Name);
   return(STATUS_VARIABLE_NOT_FOUND);
}