Пример #1
0
static VOID
TH32FreeAllocatedResources(PRTL_DEBUG_INFORMATION HeapDebug,
                           PRTL_DEBUG_INFORMATION ModuleDebug,
                           PVOID ProcThrdInfo,
                           SIZE_T ProcThrdInfoSize)
{
  if(HeapDebug != NULL)
  {
    RtlDestroyQueryDebugBuffer(HeapDebug);
  }
  if(ModuleDebug != NULL)
  {
    RtlDestroyQueryDebugBuffer(ModuleDebug);
  }

  if(ProcThrdInfo != NULL)
  {
    NtFreeVirtualMemory(NtCurrentProcess(),
                        &ProcThrdInfo,
                        &ProcThrdInfoSize,
                        MEM_RELEASE);
  }
}
Пример #2
0
BOOL
NTAPI
BaseDestroyVDMEnvironment(IN PANSI_STRING AnsiEnv,
                          IN PUNICODE_STRING UnicodeEnv)
{
    ULONG Dummy = 0;

    /* Clear the ASCII buffer since Rtl creates this for us */
    if (AnsiEnv->Buffer) RtlFreeAnsiString(AnsiEnv);

    /* The Unicode buffer is build by hand, though */
    if (UnicodeEnv->Buffer)
    {
        /* So clear it through the API */
        NtFreeVirtualMemory(NtCurrentProcess(),
                            (PVOID*)&UnicodeEnv->Buffer,
                            &Dummy,
                            MEM_RELEASE);
    }

    /* All done */
    return TRUE;
}
Пример #3
0
/*
* SfcIsFileLegit
*
* Purpose:
*
* Verify file to be legit ZeroAccess signed binary.
*
* Verification algorithm (as for current version)
*
* 1. Open dll file, read it to the allocated buffer, read extended attribute VER, 
*    containing retL packet data regarding file FileName, TimeStamp, FileSize, 
*    Signature (unusued in this verification);
*
* 2. Import required RSA key (hardcoded in the bot);
* 
* 3. Calc MD5 for FileName+TimeStamp+FileSize values;
* 
* 4. Find resource [1] in dll file, which is embedded signature used to check;
*
* 5. Remember PE header CRC value, set it to zero in PE file buffer;
* 
* 6. Copy embedded signature [1] to preallocated buffer, zero it in PE file buffer;
*
* 7. Update MD5 for PE file buffer (excluding PE CRC and signature);
*
* 8. Use result MD5 as hash value; 
*
* 9. Verify embedded signature.
*
* If anything from the above fail - file is not legit by ZeroAccess opinion.
*
* If you copy ZeroAccess downloaded files without copying EA data, it cannot be verified.
*
*/
NTSTATUS SfcIsFileLegit(
	_In_ LPWSTR lpFileName,
	_In_ PBYTE BotKey,
	_In_ DWORD BotKeySize
	)
{
	BOOL                cond = FALSE;
	PVOID               pBuffer;
	MD5_CTX             context;
	ZA_FILEHEADER       zaHeader;
	HCRYPTPROV          lh_prov = 0;
	HCRYPTKEY           lh_key = 0;
	HANDLE              hFile = NULL;
	NTSTATUS            status = STATUS_UNSUCCESSFUL;
	OBJECT_ATTRIBUTES   ObjectAttributes;
	IO_STATUS_BLOCK     IoStatusBlock;
	UNICODE_STRING      usFileName;
	SIZE_T              memIO = 0;

	if (
		(lpFileName == NULL) ||
		(BotKey == NULL) ||
		(BotKeySize == 0)
		)
	{
		return status;
	}


	RtlSecureZeroMemory(&usFileName, sizeof(usFileName));

	do {

		if (RtlDosPathNameToNtPathName_U(lpFileName, &usFileName, NULL, NULL) == FALSE)
			break;

		InitializeObjectAttributes(&ObjectAttributes, &usFileName, OBJ_CASE_INSENSITIVE, NULL, NULL);
		status = NtOpenFile(&hFile, FILE_GENERIC_READ, &ObjectAttributes, &IoStatusBlock,
			FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
			FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT
			);

		if (!NT_SUCCESS(status))
			break;

		RtlFreeUnicodeString(&usFileName);

		RtlSecureZeroMemory(&zaHeader, sizeof(zaHeader));
		if (!SfNtfsQueryFileHeaderFromEa(hFile, &zaHeader)) {
			status = STATUS_EA_LIST_INCONSISTENT;
			break;
		}

		status = STATUS_UNSUCCESSFUL;
		memIO = zaHeader.Size;
		pBuffer = NULL;
		if (
			(NT_SUCCESS(NtAllocateVirtualMemory(NtCurrentProcess(), &pBuffer, 0, &memIO, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE))) &&
			(pBuffer != NULL)
			)
		{
			if (NT_SUCCESS(NtReadFile(hFile, NULL, NULL, NULL, &IoStatusBlock, pBuffer, zaHeader.Size, NULL, NULL))) {
				if (CryptAcquireContext(&lh_prov, NULL, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
					if (CryptImportKey(lh_prov, (const BYTE *)BotKey, BotKeySize, 0, 0, &lh_key)) {
						RtlSecureZeroMemory(&context, sizeof(context));
						MD5Init(&context);
						MD5Update(&context, (UCHAR*)&zaHeader, (UINT)3 * sizeof(ULONG)); //note: ZA_FILEHEADER without signature
						if (SfcVerifyFile(lh_prov, lh_key, &context, pBuffer, zaHeader.Size))
							status = STATUS_SUCCESS;

						CryptDestroyKey(lh_key);
					}
					CryptReleaseContext(lh_prov, 0);
				}
			}
			memIO = 0;
			NtFreeVirtualMemory(NtCurrentProcess(), &pBuffer, &memIO, MEM_RELEASE);
		}
		NtClose(hFile);
		hFile = NULL;

	} while (cond);

	if (hFile != NULL) NtClose(hFile);

	if (usFileName.Buffer != NULL) {
		RtlFreeUnicodeString(&usFileName);
	}
	return status;
}
Пример #4
0
LPVOID engine_HookFunctionInProcess(HANDLE hProcess,LPSTR lpModuleName,LPSTR lpFunctionName,LPVOID lpHookFunctionAddress,PDWORD pdwHookFunctionSize,LPVOID* lpFunctionAddress,INT iRndJmp)
{
	LPVOID lpModule=NULL;
	LPVOID lpFunction=NULL;
	MEMORY_BASIC_INFORMATION mbi;
	CHAR  lpTmpFunction[MAX_FUNC_LEN*2];
	CHAR  lpLocalStub[MAX_FUNC_LEN*3];
	CHAR  lpLocalFunc[MAX_FUNC_LEN*3];
	DWORD dwBytesRead;
	DWORD dwReadLen=0;
	DWORD dwExistingJMP=0;
	DWORD dwStubSize;
	DWORD dwFree=0;
	DWORD dwBytesWritten;
	DWORD dwOldProtect;

	LPVOID lpRemoteStub=NULL;
	INT   iFuncLen;
	PBYTE pReadAddress;
	NTSTATUS ntStatus;

	// Get module address
	lpModule=(LPVOID)engine_GetRemoteModuleHandle(hProcess,lpModuleName);
	if (!lpModule)
		return NULL;
		
	// Get function address
	lpFunction=engine_GetRemoteProcAddress(hProcess,lpModule,lpFunctionName);
	if (!lpFunction)
		return NULL;

	// Get info about the function address
	if (!NT_SUCCESS(SafeNtQueryVirtualMemory(hProcess,lpFunction,MemoryBasicInformation,&mbi,sizeof(mbi),NULL)))
		return NULL;

	// Flush instruction cache
	NtFlushInstructionCache(hProcess,mbi.BaseAddress,mbi.RegionSize);

	// Change the protection for the region
	if (!NT_SUCCESS(NtProtectVirtualMemory(hProcess,&mbi.BaseAddress,&mbi.RegionSize,PAGE_EXECUTE_READWRITE,&mbi.Protect)))
		return NULL;

	// Fill stub buffer with nops
	RtlFillMemory(lpLocalStub,MAX_FUNC_LEN*3,NOP);

	// Read MAX_FUNC_LEN instruction(s) from the function into our function buffer
	if (!NT_SUCCESS(SafeNtReadVirtualMemory(hProcess,lpFunction,lpTmpFunction,MAX_FUNC_LEN*2,&dwBytesRead)))
	{
		NtProtectVirtualMemory(hProcess,&mbi.BaseAddress,&mbi.RegionSize,mbi.Protect,NULL);
		return NULL;
	}

	pReadAddress=(PBYTE)lpTmpFunction;

	// check if first opcode in the function is a another jump
	if (*pReadAddress==LONG_JMP_OPCODE)
	{
		// get relative address
		memcpy(&dwExistingJMP,pReadAddress+1,4);
		// get absolute address
		dwExistingJMP=(DWORD)lpFunction+dwExistingJMP;
		// readlen
		dwReadLen=jtJmpTable[RELATIVE_JMP].iCodeSize

		engine_BuildJMPBuffer((CHAR*)lpLocalStub,((DWORD)lpRemoteStub+dwReadLen)-dwExistingJMP,RELATIVE_JMP);

		NtProtectVirtualMemory(hProcess,&mbi.BaseAddress,&mbi.RegionSize,mbi.Protect,NULL);
		return NULL;
	}

	// Get the length of the first instruction(s)
	// This part is done by Z0MBiE's LDE32 v1.05
	iFuncLen=disasm_main(pReadAddress); // get first instruction length
	while (iFuncLen!=-1 && dwReadLen<(DWORD)jtJmpTable[iRndJmp].iCodeSize)
	{
		dwReadLen+=iFuncLen;
		pReadAddress+=iFuncLen;
		iFuncLen=disasm_main(pReadAddress); // next instruction length
	}

	// API code is too short or too long too hook this way (for now ;))
	if (dwReadLen<(DWORD)jtJmpTable[iRndJmp].iCodeSize||dwReadLen>MAX_FUNC_LEN*2)
	{
		NtProtectVirtualMemory(hProcess,&mbi.BaseAddress,&mbi.RegionSize,mbi.Protect,NULL);
		return NULL;
	}

	// Read the first instruction(s) from the function into our stub buffer
	if (!NT_SUCCESS(SafeNtReadVirtualMemory(hProcess,lpFunction,lpLocalStub,dwReadLen,&dwBytesRead)))
	{	
		NtProtectVirtualMemory(hProcess,&mbi.BaseAddress,&mbi.RegionSize,mbi.Protect,NULL);
		return NULL;
	}

	// Allocate space with read/write access for our "stub"
	// note: always use a relative jump for our stub -> RELATIVE_JMP

	dwStubSize=dwReadLen+jtJmpTable[RELATIVE_JMP].iCodeSize;
	if (!NT_SUCCESS(NtAllocateVirtualMemory(hProcess,&lpRemoteStub,0,&dwStubSize,MEM_COMMIT|MEM_TOP_DOWN,PAGE_READWRITE)))
	{	
		NtProtectVirtualMemory(hProcess,&mbi.BaseAddress,&mbi.RegionSize,mbi.Protect,NULL);
		return NULL;
	}

	// Check
	if (dwStubSize<dwReadLen+jtJmpTable[RELATIVE_JMP].iCodeSize)
	{
		NtProtectVirtualMemory(hProcess,&mbi.BaseAddress,&mbi.RegionSize,mbi.Protect,NULL);
		
		// Free allocated buffer
		NtFreeVirtualMemory(hProcess,&lpRemoteStub,&dwFree,MEM_RELEASE);
		return NULL;
	}

	engine_BuildJMPBuffer((CHAR*)lpLocalStub+dwReadLen,jtJmpTable[RELATIVE_JMP].jcStub((DWORD)lpFunction+dwReadLen,(DWORD)lpRemoteStub,dwReadLen+jtJmpTable[RELATIVE_JMP].iCodeSize),RELATIVE_JMP);

	// Copy the "stub" buffer to process memory
	if (!NT_SUCCESS(NtWriteVirtualMemory(hProcess,lpRemoteStub,lpLocalStub,dwReadLen+jtJmpTable[RELATIVE_JMP].iCodeSize,&dwBytesWritten)))
	{
		NtProtectVirtualMemory(hProcess,&mbi.BaseAddress,&mbi.RegionSize,mbi.Protect,NULL);
		
		// Free allocated buffer
		NtFreeVirtualMemory(hProcess,&lpRemoteStub,&dwFree,MEM_RELEASE);
		return NULL;
	}

	// Check
	if (dwBytesWritten<dwReadLen+jtJmpTable[RELATIVE_JMP].iCodeSize)
	{
		NtProtectVirtualMemory(hProcess,&mbi.BaseAddress,&mbi.RegionSize,mbi.Protect,NULL);
		
		// Free allocated buffer
		NtFreeVirtualMemory(hProcess,&lpRemoteStub,&dwFree,MEM_RELEASE);
		return NULL;
	}
	
	// change access
	if (!NT_SUCCESS(NtProtectVirtualMemory(hProcess,&lpRemoteStub,&dwStubSize,PAGE_EXECUTE_READ,&dwOldProtect)))
	{
		NtProtectVirtualMemory(hProcess,&mbi.BaseAddress,&mbi.RegionSize,mbi.Protect,NULL);
		
		// Free allocated buffer
		NtFreeVirtualMemory(hProcess,&lpRemoteStub,&dwFree,MEM_RELEASE);
		return NULL;
	}
		
	// Fill it with NOP
	RtlFillMemory(lpLocalFunc,MAX_FUNC_LEN*3,NOP);

	// Prepare jmpcode
	engine_BuildJMPBuffer((CHAR*)lpLocalFunc,jtJmpTable[iRndJmp].jcFunc((DWORD)lpHookFunctionAddress,(DWORD)lpFunction,(DWORD)jtJmpTable[iRndJmp].iCodeSize),iRndJmp);
	
	ntStatus=NtWriteVirtualMemory(hProcess,lpFunction,lpLocalFunc,dwReadLen,&dwBytesWritten);
		
	// Check that we really wrote our jmpcode completely
	if (!NT_SUCCESS(ntStatus) || dwBytesWritten!=dwReadLen)
	{
		// Try to fix stuff
		if (dwBytesWritten)
			NtWriteVirtualMemory(hProcess,lpFunction,lpRemoteStub,dwBytesWritten,&dwBytesWritten);

		NtProtectVirtualMemory(hProcess,&mbi.BaseAddress,&mbi.RegionSize,mbi.Protect,NULL);
		
		// Free allocated buffer
		NtFreeVirtualMemory(hProcess,&lpRemoteStub,&dwFree,MEM_RELEASE);
		return NULL;
	}
	
	// Restore protection
	NtProtectVirtualMemory(hProcess,&mbi.BaseAddress,&mbi.RegionSize,mbi.Protect,NULL);

	// Save size of read function length
	if (pdwHookFunctionSize) *pdwHookFunctionSize=dwReadLen;
	// Save address of function
	if (lpFunctionAddress) *lpFunctionAddress=lpFunction;

	return lpRemoteStub;
}
Пример #5
0
static NTSTATUS
CopyLoop (
	HANDLE			FileHandleSource,
	HANDLE			FileHandleDest,
	LARGE_INTEGER		SourceFileSize,
	LPPROGRESS_ROUTINE	lpProgressRoutine,
	LPVOID			lpData,
	BOOL			*pbCancel,
	BOOL                 *KeepDest
	)
{
   NTSTATUS errCode;
   IO_STATUS_BLOCK IoStatusBlock;
   UCHAR *lpBuffer = NULL;
   SIZE_T RegionSize = 0x10000;
   LARGE_INTEGER BytesCopied;
   DWORD CallbackReason;
   DWORD ProgressResult;
   BOOL EndOfFileFound;

   *KeepDest = FALSE;
   errCode = NtAllocateVirtualMemory(NtCurrentProcess(),
				     (PVOID *)&lpBuffer,
				     2,
				     &RegionSize,
				     MEM_RESERVE | MEM_COMMIT,
				     PAGE_READWRITE);

   if (NT_SUCCESS(errCode))
     {
	BytesCopied.QuadPart = 0;
	EndOfFileFound = FALSE;
	CallbackReason = CALLBACK_STREAM_SWITCH;
	while (! EndOfFileFound &&
	       NT_SUCCESS(errCode) &&
	       (NULL == pbCancel || ! *pbCancel))
	  {
	     if (NULL != lpProgressRoutine)
	       {
		   ProgressResult = (*lpProgressRoutine)(SourceFileSize,
							 BytesCopied,
							 SourceFileSize,
							 BytesCopied,
							 0,
							 CallbackReason,
							 FileHandleSource,
							 FileHandleDest,
							 lpData);
		   switch (ProgressResult)
		     {
		     case PROGRESS_CANCEL:
			TRACE("Progress callback requested cancel\n");
			errCode = STATUS_REQUEST_ABORTED;
			break;
		     case PROGRESS_STOP:
			TRACE("Progress callback requested stop\n");
			errCode = STATUS_REQUEST_ABORTED;
			*KeepDest = TRUE;
			break;
		     case PROGRESS_QUIET:
			lpProgressRoutine = NULL;
			break;
		     case PROGRESS_CONTINUE:
		     default:
			break;
		     }
		   CallbackReason = CALLBACK_CHUNK_FINISHED;
	       }
	     if (NT_SUCCESS(errCode))
	       {
		  errCode = NtReadFile(FileHandleSource,
				       NULL,
				       NULL,
				       NULL,
				       (PIO_STATUS_BLOCK)&IoStatusBlock,
				       lpBuffer,
				       RegionSize,
				       NULL,
				       NULL);
		  if (NT_SUCCESS(errCode) && (NULL == pbCancel || ! *pbCancel))
		    {
		       errCode = NtWriteFile(FileHandleDest,
					     NULL,
					     NULL,
					     NULL,
					     (PIO_STATUS_BLOCK)&IoStatusBlock,
					     lpBuffer,
					     IoStatusBlock.Information,
					     NULL,
					     NULL);
		       if (NT_SUCCESS(errCode))
			 {
			    BytesCopied.QuadPart += IoStatusBlock.Information;
			 }
		       else
			 {
			    WARN("Error 0x%08x reading writing to dest\n", errCode);
			 }
		    }
		  else if (!NT_SUCCESS(errCode))
		    {
		       if (STATUS_END_OF_FILE == errCode)
			 {
			    EndOfFileFound = TRUE;
			    errCode = STATUS_SUCCESS;
			 }
		       else
			 {
			    WARN("Error 0x%08x reading from source\n", errCode);
			 }
		    }
	       }
	  }

	if (! EndOfFileFound && (NULL != pbCancel && *pbCancel))
	  {
	  TRACE("User requested cancel\n");
	  errCode = STATUS_REQUEST_ABORTED;
	  }

	NtFreeVirtualMemory(NtCurrentProcess(),
			    (PVOID *)&lpBuffer,
			    &RegionSize,
			    MEM_RELEASE);
     }
   else
     {
	TRACE("Error 0x%08x allocating buffer of %d bytes\n", errCode, RegionSize);
     }

   return errCode;
}
Пример #6
0
void
Test_PageFileSection(void)
{
    NTSTATUS Status;
    HANDLE SectionHandle;
    LARGE_INTEGER MaximumSize, SectionOffset;
    PVOID BaseAddress;
    SIZE_T ViewSize;

    /* Create a page file backed section */
    MaximumSize.QuadPart = 0x20000;
    Status = NtCreateSection(&SectionHandle,
                             SECTION_ALL_ACCESS,
                             NULL,
                             &MaximumSize,
                             PAGE_READWRITE,
                             SEC_COMMIT,
                             NULL);
    ok(NT_SUCCESS(Status), "NtCreateSection failed with Status %lx\n", Status);
    if (!NT_SUCCESS(Status))
        return;

    /* Try to map a page at an address that is not 64k aligned */
    BaseAddress = (PVOID)0x30001000;
    SectionOffset.QuadPart = 0;
    ViewSize = 0x1000;
    Status = NtMapViewOfSection(SectionHandle,
                                NtCurrentProcess(),
                                &BaseAddress,
                                0,
                                0,
                                &SectionOffset,
                                &ViewSize,
                                ViewShare,
                                0,
                                PAGE_READWRITE);
    ok(Status == STATUS_MAPPED_ALIGNMENT,
       "NtMapViewOfSection returned wrong Status %lx\n", Status);

    /* Try to map a page with execute rights */
    BaseAddress = (PVOID)0x30000000;
    SectionOffset.QuadPart = 0;
    ViewSize = 0x1000;
    Status = NtMapViewOfSection(SectionHandle,
                                NtCurrentProcess(),
                                &BaseAddress,
                                0,
                                0,
                                &SectionOffset,
                                &ViewSize,
                                ViewShare,
                                0,
                                PAGE_EXECUTE_READWRITE);
    ok(Status == STATUS_SECTION_PROTECTION,
       "NtMapViewOfSection returned wrong Status %lx\n", Status);

    /* Map 2 pages, not comitting them */
    BaseAddress = (PVOID)0x30000000;
    SectionOffset.QuadPart = 0;
    ViewSize = 0x2000;
    Status = NtMapViewOfSection(SectionHandle,
                                NtCurrentProcess(),
                                &BaseAddress,
                                0,
                                0,
                                &SectionOffset,
                                &ViewSize,
                                ViewShare,
                                0,
                                PAGE_READWRITE);
    ok(NT_SUCCESS(Status), "NtMapViewOfSection failed with Status %lx\n", Status);
    if (!NT_SUCCESS(Status))
        return;

    /* Commit a page in the section */
    BaseAddress = (PVOID)0x30000000;
    ViewSize = 0x1000;
    Status = NtAllocateVirtualMemory(NtCurrentProcess(),
                                     &BaseAddress,
                                     0,
                                     &ViewSize,
                                     MEM_COMMIT,
                                     PAGE_READWRITE);
    ok(NT_SUCCESS(Status), "NtAllocateVirtualMemory failed with Status %lx\n", Status);
    Status = NtFreeVirtualMemory(NtCurrentProcess(),
                                 &BaseAddress,
                                 &ViewSize,
                                 MEM_DECOMMIT);
    ok(Status == STATUS_UNABLE_TO_DELETE_SECTION, "NtFreeVirtualMemory returned wrong Status %lx\n", Status);
    /* Try to commit a range larger than the section */
    BaseAddress = (PVOID)0x30000000;
    ViewSize = 0x3000;
    Status = NtAllocateVirtualMemory(NtCurrentProcess(),
                                     &BaseAddress,
                                     0,
                                     &ViewSize,
                                     MEM_COMMIT,
                                     PAGE_READWRITE);
    ok(Status == STATUS_CONFLICTING_ADDRESSES,
       "NtAllocateVirtualMemory failed with wrong Status %lx\n", Status);

    /* Try to commit a page after the section */
    BaseAddress = (PVOID)0x30002000;
    ViewSize = 0x1000;
    Status = NtAllocateVirtualMemory(NtCurrentProcess(),
                                     &BaseAddress,
                                     0,
                                     &ViewSize,
                                     MEM_COMMIT,
                                     PAGE_READWRITE);
    ok(!NT_SUCCESS(Status), "NtAllocateVirtualMemory Should fail\n");

    /* Try to allocate a page after the section */
    BaseAddress = (PVOID)0x30002000;
    ViewSize = 0x1000;
    Status = NtAllocateVirtualMemory(NtCurrentProcess(),
                                     &BaseAddress,
                                     0,
                                     &ViewSize,
                                     MEM_RESERVE | MEM_COMMIT,
                                     PAGE_READWRITE);
    ok(!NT_SUCCESS(Status), "NtAllocateVirtualMemory should fail\n");

    /* Need to go to next 64k boundary */
    BaseAddress = (PVOID)0x30010000;
    ViewSize = 0x1000;
    Status = NtAllocateVirtualMemory(NtCurrentProcess(),
                                     &BaseAddress,
                                     0,
                                     &ViewSize,
                                     MEM_RESERVE | MEM_COMMIT,
                                     PAGE_READWRITE);
    ok(NT_SUCCESS(Status), "NtAllocateVirtualMemory failed with Status %lx\n", Status);
    if (!NT_SUCCESS(Status))
        return;

    /* Free the allocation */
    BaseAddress = (PVOID)0x30010000;
    ViewSize = 0x1000;
    Status = NtFreeVirtualMemory(NtCurrentProcess(),
                                 &BaseAddress,
                                 &ViewSize,
                                 MEM_RELEASE);
    ok(NT_SUCCESS(Status), "NtFreeVirtualMemory failed with Status %lx\n", Status);

    /* Free the section mapping */
    BaseAddress = (PVOID)0x30000000;
    ViewSize = 0x1000;
    Status = NtFreeVirtualMemory(NtCurrentProcess(),
                                 &BaseAddress,
                                 &ViewSize,
                                 MEM_RELEASE);
    ok(Status == STATUS_UNABLE_TO_DELETE_SECTION,
       "NtFreeVirtualMemory failed with wrong Status %lx\n", Status);

    /* Commit a page in the section */
    BaseAddress = (PVOID)0x30001000;
    ViewSize = 0x1000;
    Status = NtAllocateVirtualMemory(NtCurrentProcess(),
                                     &BaseAddress,
                                     0,
                                     &ViewSize,
                                     MEM_COMMIT,
                                     PAGE_READWRITE);
    ok(NT_SUCCESS(Status), "NtAllocateVirtualMemory failed with Status %lx\n", Status);

    /* Try to decommit the page */
    BaseAddress = (PVOID)0x30001000;
    ViewSize = 0x1000;
    Status = NtFreeVirtualMemory(NtCurrentProcess(),
                                 &BaseAddress,
                                 &ViewSize,
                                 MEM_DECOMMIT);
    ok(Status == STATUS_UNABLE_TO_DELETE_SECTION,
       "NtFreeVirtualMemory failed with wrong Status %lx\n", Status);

    BaseAddress = UlongToPtr(0x40000000);
    SectionOffset.QuadPart = 0;
    ViewSize = 0x1000;
    Status = NtMapViewOfSection(SectionHandle,
                                NtCurrentProcess(),
                                &BaseAddress,
                                0,
                                0,
                                &SectionOffset,
                                &ViewSize,
                                ViewShare,
                                0,
                                PAGE_READWRITE);
    ok(NT_SUCCESS(Status), "NtMapViewOfSection failed with Status %lx\n", Status);
    if (!NT_SUCCESS(Status))
        return;

    ok(BaseAddress == UlongToPtr(0x40000000), "Invalid BaseAddress: %p", BaseAddress);

    BaseAddress = (PVOID)0x40080000;
    SectionOffset.QuadPart = 0x10000;
    ViewSize = 0x1000;
    Status = NtMapViewOfSection(SectionHandle,
                                NtCurrentProcess(),
                                &BaseAddress,
                                0,
                                0,
                                &SectionOffset,
                                &ViewSize,
                                ViewShare,
                                0,
                                PAGE_READWRITE);
    ok(NT_SUCCESS(Status), "NtMapViewOfSection failed with Status %lx\n", Status);
    if (!NT_SUCCESS(Status))
        return;

    ok(BaseAddress == (PVOID)0x40080000, "Invalid BaseAddress: %p", BaseAddress);

    /* Commit a page in the section */
    BaseAddress = (PVOID)0x40000000;
    Status = NtAllocateVirtualMemory(NtCurrentProcess(),
                                     &BaseAddress,
                                     0,
                                     &ViewSize,
                                     MEM_COMMIT,
                                     PAGE_READWRITE);
    ok(NT_SUCCESS(Status), "NtAllocateVirtualMemory failed with Status %lx\n", Status);
    if (!NT_SUCCESS(Status))
        return;

}
Пример #7
0
BOOL
NTAPI
BaseCreateVDMEnvironment(IN PWCHAR lpEnvironment,
                         IN PANSI_STRING AnsiEnv,
                         IN PUNICODE_STRING UnicodeEnv)
{
    BOOL Result;
    ULONG RegionSize, EnvironmentSize = 0;
    PWCHAR p, Environment, NewEnvironment = NULL;
    NTSTATUS Status;

    /* Make sure we have both strings */
    if (!(AnsiEnv) || !(UnicodeEnv))
    {
        /* Fail */
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }

    /* Check if an environment was passed in */
    if (!lpEnvironment)
    {
        /* Nope, create one */
        Status = RtlCreateEnvironment(TRUE, (PWCHAR*)&Environment);
        if (!NT_SUCCESS(Status)) goto Quickie;
    }
    else
    {
        /* Use the one we got */
        Environment = lpEnvironment;
    }

    /* Do we have something now ? */
    if (!Environment)
    {
        /* Still not, fail out */
        SetLastError(ERROR_BAD_ENVIRONMENT);
        goto Quickie;
    }

    /* Count how much space the whole environment takes */
    p = Environment;
    while ((*p++ != UNICODE_NULL) && (*p != UNICODE_NULL)) EnvironmentSize++;
    EnvironmentSize += sizeof(UNICODE_NULL);

    /* Allocate a new copy */
    RegionSize = (EnvironmentSize + MAX_PATH) * sizeof(WCHAR);
    if (!NT_SUCCESS(NtAllocateVirtualMemory(NtCurrentProcess(),
                                            (PVOID*)&NewEnvironment,
                                            0,
                                            &RegionSize,
                                            MEM_COMMIT,
                                            PAGE_READWRITE)))
    {
        /* We failed, bail out */
        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
        NewEnvironment = NULL;
        goto Quickie;
    }

    /* Begin parsing the new environment */
    p = NewEnvironment;

    /* FIXME: Code here */

    /* Terminate it */
    *p++ = UNICODE_NULL;

    /* Initialize the unicode string to hold it */
    EnvironmentSize = (p - NewEnvironment) * sizeof(WCHAR);
    RtlInitEmptyUnicodeString(UnicodeEnv, NewEnvironment, (USHORT)EnvironmentSize);
    UnicodeEnv->Length = (USHORT)EnvironmentSize;

    /* Create the ASCII version of it */
    Status = RtlUnicodeStringToAnsiString(AnsiEnv, UnicodeEnv, TRUE);
    if (!NT_SUCCESS(Status))
    {
        /* Set last error if conversion failure */
        BaseSetLastNTError(Status);
    }
    else
    {
        /* Everything went okay, so return success */
        Result = TRUE;
        NewEnvironment = NULL;
    }

Quickie:
    /* Cleanup path starts here, start by destroying the envrionment copy */
    if (!(lpEnvironment) && (Environment)) RtlDestroyEnvironment(Environment);

    /* See if we are here due to failure */
    if (NewEnvironment)
    {
        /* Initialize the paths to be empty */
        RtlInitEmptyUnicodeString(UnicodeEnv, NULL, 0);
        RtlInitEmptyAnsiString(AnsiEnv, NULL, 0);

        /* Free the environment copy */
        RegionSize = 0;
        Status = NtFreeVirtualMemory(NtCurrentProcess(),
                                     (PVOID*)&NewEnvironment,
                                     &RegionSize,
                                     MEM_RELEASE);
        ASSERT(NT_SUCCESS(Status));
    }

    /* Return the result */
    return Result;
}
Пример #8
0
// free buffer ...
void misc_FreeBuffer(LPVOID* lpBuffer)
{
	DWORD dwFree=0;

	NtFreeVirtualMemory(NtCurrentProcess(),lpBuffer,&dwFree,MEM_RELEASE);
}
Пример #9
0
static NTSTATUS
TH32CreateSnapshot(DWORD dwFlags,
                   DWORD th32ProcessID,
                   PRTL_DEBUG_INFORMATION *HeapDebug,
                   PRTL_DEBUG_INFORMATION *ModuleDebug,
                   PVOID *ProcThrdInfo,
                   SIZE_T *ProcThrdInfoSize)
{
  NTSTATUS Status = STATUS_SUCCESS;

  *HeapDebug = NULL;
  *ModuleDebug = NULL;
  *ProcThrdInfo = NULL;
  *ProcThrdInfoSize = 0;

  /*
   * Allocate the debug information for a heap snapshot
   */
  if(dwFlags & TH32CS_SNAPHEAPLIST)
  {
    *HeapDebug = RtlCreateQueryDebugBuffer(0, FALSE);
    if(*HeapDebug != NULL)
    {
      Status = RtlQueryProcessDebugInformation(th32ProcessID,
                                               RTL_DEBUG_QUERY_HEAPS,
                                               *HeapDebug);
    }
    else
      Status = STATUS_UNSUCCESSFUL;
  }

  /*
   * Allocate the debug information for a module snapshot
   */
  if(dwFlags & TH32CS_SNAPMODULE &&
     NT_SUCCESS(Status))
  {
    *ModuleDebug = RtlCreateQueryDebugBuffer(0, FALSE);
    if(*ModuleDebug != NULL)
    {
      Status = RtlQueryProcessDebugInformation(th32ProcessID,
                                               RTL_DEBUG_QUERY_MODULES,
                                               *ModuleDebug);
    }
    else
      Status = STATUS_UNSUCCESSFUL;
  }

  /*
   * Allocate enough memory for the system's process list
   */

  if(dwFlags & (TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD) &&
     NT_SUCCESS(Status))
  {
    for(;;)
    {
      (*ProcThrdInfoSize) += 0x10000;
      Status = NtAllocateVirtualMemory(NtCurrentProcess(),
                                       ProcThrdInfo,
                                       0,
                                       ProcThrdInfoSize,
                                       MEM_COMMIT,
                                       PAGE_READWRITE);
      if(!NT_SUCCESS(Status))
      {
        break;
      }

      Status = NtQuerySystemInformation(SystemProcessInformation,
                                        *ProcThrdInfo,
                                        *ProcThrdInfoSize,
                                        NULL);
      if(Status == STATUS_INFO_LENGTH_MISMATCH)
      {
        NtFreeVirtualMemory(NtCurrentProcess(),
                            ProcThrdInfo,
                            ProcThrdInfoSize,
                            MEM_RELEASE);
        *ProcThrdInfo = NULL;
      }
      else
      {
        break;
      }
    }
  }

  /*
   * Free resources in case of failure!
   */

  if(!NT_SUCCESS(Status))
  {
    TH32FreeAllocatedResources(*HeapDebug,
                               *ModuleDebug,
                               *ProcThrdInfo,
                               *ProcThrdInfoSize);
  }

  return Status;
}
Пример #10
0
int
Uninstall(int argc, LPWSTR *argv)
{
  DWORD dwPid = wcstoul(argv[1], NULL, 0);
  DWORD dwTid;
  HANDLE hProcess;
  HANDLE hThread;
  LPVOID lpMemBlock = NULL;
  static WCHAR wszModFile[32768] = L"";
  DWORD dwBaseAddress = 0;
  DWORD dwFunctionOffset =
    (DWORD) UninstallHandler - (DWORD) GetModuleHandle(L"noexcept.dll");
  NTSTATUS status;
  const WCHAR wczString[] = L"noexcept.dll";
  SIZE_T dwStringLength = sizeof wczString;
  SIZE_T dwRegionSize = dwStringLength;

  if (argc < 2)
    {
      MessageBoxA(NULL, "/u requires a process identifier as parameter.",
		  "Syntax error", MB_ICONEXCLAMATION);
      return 2;
    }

  hProcess = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION |
			 PROCESS_VM_WRITE | PROCESS_QUERY_INFORMATION |
			 SYNCHRONIZE, FALSE, dwPid);
  if (hProcess == NULL)
    {
      MessageBoxA(NULL, win_errmsgA(win_errno), "Cannot open process",
		  MB_ICONEXCLAMATION);
      return 1;
    }

  status = NtAllocateVirtualMemory(hProcess, &lpMemBlock, 0, &dwRegionSize,
				   MEM_COMMIT, PAGE_READWRITE);
  if (!NT_SUCCESS(status))
    {
      MessageBoxA(NULL, win_errmsgA(RtlNtStatusToDosError(status)),
		  "Cannot allocate memory in the process",
		  MB_ICONEXCLAMATION);
      return 1;
    }

  if (!WriteProcessMemory(hProcess, lpMemBlock, wczString, dwStringLength,
			  NULL))
    {
      MessageBoxA(NULL, win_errmsgA(win_errno),
		  "Cannot write memory in the process", MB_ICONEXCLAMATION);
      NtFreeVirtualMemory(hProcess, &lpMemBlock, &dwRegionSize, MEM_RELEASE);
      return 1;
    }

  hThread =
    CreateRemoteThread(hProcess, NULL, 0,
		       (LPTHREAD_START_ROUTINE) GetModuleHandleW, lpMemBlock,
		       4096, &dwTid);
  if (hThread == NULL)
    {
      MessageBoxA(NULL, win_errmsgA(win_errno),
		  "Cannot create thread in the process", MB_ICONEXCLAMATION);
      dwRegionSize = 0;
      NtFreeVirtualMemory(hProcess, &lpMemBlock, &dwRegionSize, MEM_RELEASE);
      return 1;
    }

  WaitForSingleObject(hThread, INFINITE);

  dwRegionSize = 0;
  NtFreeVirtualMemory(hProcess, &lpMemBlock, &dwRegionSize, MEM_RELEASE);

  GetExitCodeThread(hThread, &dwBaseAddress);
  CloseHandle(hThread);
  
  if (dwBaseAddress == 0)
    {
      MessageBoxA(NULL,
		  "The noexcept.dll module is not loaded into the specified "
		  "process and can therefore not be uninstalled from it.",
		  "Not installed", MB_ICONEXCLAMATION);
      return 1;
    }

  hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)
			       (dwBaseAddress + dwFunctionOffset),
			       (LPVOID) ((argc > 2) ?
					 wcstoul(argv[2], NULL, 0) : 0), 4096,
			       &dwTid);
  if (hThread == NULL)
    {
      MessageBoxA(NULL, win_errmsgA(win_errno),
		  "Cannot create thread in the process", MB_ICONEXCLAMATION);
      return 1;
    }

  WaitForSingleObject(hThread, INFINITE);

  return 0;
}
Пример #11
0
/*
 * @implemented
 */
NTSTATUS NTAPI
RtlSetEnvironmentVariable(PWSTR *Environment,
                          PUNICODE_STRING Name,
                          PUNICODE_STRING Value)
{
   MEMORY_BASIC_INFORMATION mbi;
   UNICODE_STRING var;
   size_t hole_len, new_len, env_len = 0;
   WCHAR *new_env = 0, *env_end = 0, *wcs, *env, *val = 0, *tail = 0, *hole = 0;
   PWSTR head = NULL;
   SIZE_T size = 0, new_size;
   LONG f = 1;
   NTSTATUS Status = STATUS_SUCCESS;

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

   /* Variable name must not be empty */
   if (Name->Length < sizeof(WCHAR))
      return STATUS_INVALID_PARAMETER;

   /* Variable names can't contain a '=' except as a first character. */
   for (wcs = Name->Buffer + 1;
        wcs < Name->Buffer + (Name->Length / sizeof(WCHAR));
        wcs++)
   {
      if (*wcs == L'=')
          return STATUS_INVALID_PARAMETER;
   }

   if (Environment)
   {
      env = *Environment;
   }
   else
   {
      RtlAcquirePebLock();
      env = NtCurrentPeb()->ProcessParameters->Environment;
   }

   if (env)
   {
      /* get environment length */
      wcs = env_end = env;
      do
      {
         env_end += wcslen(env_end) + 1;
      }
      while (*env_end);
      env_end++;
      env_len = env_end - env;
      DPRINT("environment length %lu characters\n", env_len);

      /* find where to insert */
      while (*wcs)
      {
         var.Buffer = wcs++;
         wcs = wcschr(wcs, L'=');
         if (wcs == NULL)
         {
            wcs = var.Buffer + wcslen(var.Buffer);
         }
         if (*wcs)
         {
            var.Length = (USHORT)(wcs - var.Buffer) * sizeof(WCHAR);
            var.MaximumLength = var.Length;
            val = ++wcs;
            wcs += wcslen(wcs);
            f = RtlCompareUnicodeString(&var, Name, TRUE);
            if (f >= 0)
            {
               if (f) /* Insert before found */
               {
                  hole = tail = var.Buffer;
               }
               else /* Exact match */
               {
                  head = var.Buffer;
                  tail = ++wcs;
                  hole = val;
               }
               goto found;
            }
         }
         wcs++;
      }
      hole = tail = wcs; /* Append to environment */
   }

found:
   if (Value != NULL && Value->Buffer != NULL)
   {
      hole_len = tail - hole;
      /* calculate new environment size */
      new_size = Value->Length + sizeof(WCHAR);
      /* adding new variable */
      if (f)
         new_size += Name->Length + sizeof(WCHAR);
      new_len = new_size / sizeof(WCHAR);
      if (hole_len < new_len)
      {
         /* enlarge environment size */
         /* check the size of available memory */
         new_size += (env_len - hole_len) * sizeof(WCHAR);
         new_size = ROUND_UP(new_size, PAGE_SIZE);
         mbi.RegionSize = 0;
         DPRINT("new_size %lu\n", new_size);

         if (env)
         {
            Status = NtQueryVirtualMemory(NtCurrentProcess(),
                                          env,
                                          MemoryBasicInformation,
                                          &mbi,
                                          sizeof(MEMORY_BASIC_INFORMATION),
                                          NULL);
            if (!NT_SUCCESS(Status))
            {
               if (Environment == NULL)
               {
                  RtlReleasePebLock();
               }
               return(Status);
            }
         }

         if (new_size > mbi.RegionSize)
         {
            /* reallocate memory area */
            Status = NtAllocateVirtualMemory(NtCurrentProcess(),
                                             (PVOID)&new_env,
                                             0,
                                             &new_size,
                                             MEM_RESERVE | MEM_COMMIT,
                                             PAGE_READWRITE);
            if (!NT_SUCCESS(Status))
            {
               if (Environment == NULL)
               {
                  RtlReleasePebLock();
               }
               return(Status);
            }

            if (env)
            {
               memmove(new_env,
                       env,
                       (hole - env) * sizeof(WCHAR));
               hole = new_env + (hole - env);
            }
            else
            {
               /* absolutely new environment */
               tail = hole = new_env;
               *hole = 0;
               env_end = hole + 1;
            }
         }
      }

      /* move tail */
      memmove (hole + new_len, tail, (env_end - tail) * sizeof(WCHAR));

      if (new_env)
      {
         /* we reallocated environment, let's free the old one */
         if (Environment)
            *Environment = new_env;
         else
            NtCurrentPeb()->ProcessParameters->Environment = new_env;

         if (env)
         {
            size = 0;
            NtFreeVirtualMemory(NtCurrentProcess(),
                                (PVOID)&env,
                                &size,
                                MEM_RELEASE);
         }
      }

      /* and now copy given stuff */
      if (f)
      {
         /* copy variable name and '=' character */
         memmove(hole,
                 Name->Buffer,
                 Name->Length);
         hole += Name->Length / sizeof(WCHAR);
         *hole++ = L'=';
      }

      /* copy value */
      memmove(hole,
              Value->Buffer,
              Value->Length);
      hole += Value->Length / sizeof(WCHAR);
      *hole = 0;
   }
   else
   {
      /* remove the environment variable */
      if (f == 0)
      {
         memmove(head,
                 tail,
                 (env_end - tail) * sizeof(WCHAR));
      }
   }

   if (Environment == NULL)
   {
      RtlReleasePebLock();
   }

   return(Status);
}
CustomFilterUnicode::~CustomFilterUnicode()
{
	NtFreeVirtualMemory(NtCurrentProcess(),(PVOID*)&map,&size,MEM_RELEASE);
	map=0;
}
Пример #13
0
int
wmain(int argc, LPWSTR *argv)
{
  PROCESS_INFORMATION process_information = { 0 };
  HANDLE hThread;
  DWORD dwTid;
  LPVOID lpMemBlock = NULL;
  SIZE_T dwStringLength;
  SIZE_T dwRegionSize;
  static WCHAR wszModFile[32768] = L"";
  DWORD dwBaseAddress = 0;
  DWORD dwFunctionOffset =
    (DWORD) InstallHandler - (DWORD) GetModuleHandle(L"noexcept.dll");
  NTSTATUS status;
  DWORD dwMemSize = GetModuleFileName(GetModuleHandle(L"noexcept.dll"),
				      wszModFile, sizeof(wszModFile) /
				      sizeof(*wszModFile));

  if (dwMemSize == 0)
    {
      MessageBoxA(NULL, win_errmsgA(win_errno), "Cannot attach noexcept.dll",
		  MB_ICONSTOP);
      return 1;
    }

  if (argc < 2)
    {
      MessageBoxA(NULL,
		  "Syntax:\r\n"
		  "noexcept <commandline>\r\n"
		  "Starts a new process and attaches noexcept.dll to it with "
		  "special exception handling.\r\n"
		  "\n"
		  "noexcept <pid>\r\n"
		  "Attaches noexcept.dll with special exception handling to a "
		  "running process.\r\n"
		  "\n"
		  "noexcept /u <pid>\r\n"
		  "Detaches noexcept.dll from a running process and restores "
		  "default exception handling in the process.",
		  "noexcept",
		  MB_ICONINFORMATION);
      return 2;
    }

  if (wcsicmp(argv[1], L"/u") == 0)
    return Uninstall(argc - 1, argv + 1);
  
  if (wcstoul(argv[1], NULL, 0) != 0)
    {
      process_information.hProcess =
	OpenProcess(PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION |
		    PROCESS_VM_WRITE | PROCESS_QUERY_INFORMATION |
		    SYNCHRONIZE, FALSE, wcstoul(argv[1], NULL, 0));
      if (process_information.hProcess == NULL)
	{
	  MessageBoxA(NULL, win_errmsgA(win_errno), "Cannot open process",
		      MB_ICONEXCLAMATION);
	  return 1;
	}
    }
  else
    {
      LPWSTR lpCmdLine = GetCommandLine();
      DWORD_PTR dwOffset = argv[1] - argv[0];
      STARTUPINFO startupinfo = { 0 };
      startupinfo.cb = sizeof startupinfo;

      if (dwOffset > 1)
	if (lpCmdLine[dwOffset] == L'"')
	  if (lpCmdLine[dwOffset+1] == L' ')
	    lpCmdLine += dwOffset + 2;
	  else
	    lpCmdLine += dwOffset;
	else
	  lpCmdLine += dwOffset;
      else
	lpCmdLine += dwOffset;

      while (lpCmdLine[0] == ' ')
	++lpCmdLine;

      if (!CreateProcess(NULL, lpCmdLine, NULL, NULL, FALSE, CREATE_SUSPENDED,
			 NULL, NULL, &startupinfo, &process_information))
	{
	  MessageBoxA(NULL,
		      mprintfA("Cannot execute command line:%n%1>%2!ws!<",
			       win_errmsgA(win_errno), lpCmdLine),
		      "Cannot create process", MB_ICONEXCLAMATION);
	  return 1;
	}
    }

  dwStringLength = (wcslen(wszModFile) + 1) * sizeof *wszModFile;
  dwRegionSize = dwStringLength;
  status = NtAllocateVirtualMemory(process_information.hProcess, &lpMemBlock,
				   0, &dwRegionSize, MEM_COMMIT,
				   PAGE_READWRITE);
  if (!NT_SUCCESS(status))
    {
      MessageBoxA(NULL, win_errmsgA(RtlNtStatusToDosError(status)),
		  "Cannot allocate memory in the process",
		  MB_ICONEXCLAMATION);
      if (process_information.hThread != NULL)
	TerminateProcess(process_information.hProcess, -1);
      return 1;
    }

  if (!WriteProcessMemory(process_information.hProcess, lpMemBlock, wszModFile,
			  dwStringLength, NULL))
    {
      MessageBoxA(NULL, win_errmsgA(win_errno),
		  "Cannot write memory in the process", MB_ICONEXCLAMATION);
      NtFreeVirtualMemory(process_information.hProcess, &lpMemBlock,
			  &dwRegionSize, MEM_RELEASE);
      if (process_information.hThread != NULL)
	TerminateProcess(process_information.hProcess, -1);
      return 1;
    }

  hThread =
    CreateRemoteThread(process_information.hProcess, NULL, 0,
		       (LPTHREAD_START_ROUTINE) LoadLibraryW, lpMemBlock, 4096,
		       &dwTid);
  if (hThread == NULL)
    {
      MessageBoxA(NULL, win_errmsgA(win_errno),
		  "Cannot create thread in the process", MB_ICONEXCLAMATION);
      dwRegionSize = 0;
      NtFreeVirtualMemory(process_information.hProcess, &lpMemBlock,
			  &dwRegionSize, MEM_RELEASE);
      if (process_information.hThread != NULL)
	TerminateProcess(process_information.hProcess, -1);
      return 1;
    }

  WaitForSingleObject(hThread, INFINITE);
  GetExitCodeThread(hThread, &dwBaseAddress);
  CloseHandle(hThread);

  dwRegionSize = 0;
  NtFreeVirtualMemory(process_information.hProcess, &lpMemBlock, &dwRegionSize,
		      MEM_RELEASE);

  if (dwBaseAddress == 0)
    {
      MessageBoxA(NULL, "Cannot load noexcept.dll into the process.",
		  "LoadLibrary() failed in the process",
		  MB_ICONEXCLAMATION);
      if (process_information.hThread != NULL)
	TerminateProcess(process_information.hProcess, -1);
      return 1;
    }

  hThread =
    CreateRemoteThread(process_information.hProcess, NULL, 0,
		       (LPTHREAD_START_ROUTINE)
		       (dwBaseAddress + dwFunctionOffset),
		       (LPVOID) (((process_information.hThread == NULL)
				  & (argc > 2)) ?
				 wcstoul(argv[2], NULL, 0) : 0), 4096, &dwTid);
  if (hThread == NULL)
    {
      MessageBoxA(NULL, win_errmsgA(win_errno),
		  "Cannot create thread in the process", MB_ICONEXCLAMATION);
      if (process_information.hThread != NULL)
	TerminateProcess(process_information.hProcess, -1);
      return 1;
    }

  WaitForSingleObject(hThread, INFINITE);

  if (process_information.hThread != NULL)
    ResumeThread(process_information.hThread);

  return 0;
}
Пример #14
0
NTSTATUS openProcByName(PHANDLE pProcess, PUNICODE_STRING pProcName, BOOLEAN useDebugPrivilege) {
	SYSTEM_PROCESS_INFORMATION procInfo;
	OBJECT_ATTRIBUTES procAttr;
	OBJECT_BASIC_INFORMATION processHandleInfo;
	CLIENT_ID cid;
	BOOLEAN oldValue;
	HANDLE pid;

	NTSTATUS status = STATUS_CACHE_PAGE_LOCKED;
	ULONG procListSize = 0;
	ULONGLONG memSize = 0;
	ULONG obQueryLen = 0;
	PVOID pProcListHead = NULL;
	PSYSTEM_PROCESS_INFORMATION pProcEntry = NULL;

	do {
		if (!pProcName || !pProcess) {
			status = STATUS_INVALID_PARAMETER;
			break;
		}
		
		*pProcess = NULL;

		///Since we specify a buffer size of 0 the buffer must overflow for sure even if there was running a
		///single process only. If we don't receive the dedicated error, something other has gone wrong
		///and we cannot rely on the return length.
		status = NtQuerySystemInformation(SystemProcessInformation, &procInfo, procListSize, &procListSize);
		if (STATUS_INFO_LENGTH_MISMATCH != status)
			break;

		memSize = PAGE_ROUND_UP(procListSize) + PAGE_SIZE; ///We better allocate one page extra
														   ///since between our "test" call and the real call below
														   ///additional processes might be started. (race condition)
		status = NtAllocateVirtualMemory(INVALID_HANDLE_VALUE, &pProcListHead, 0, &memSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
		if (status) {
			pProcListHead = NULL;
			break;
		}

		///By now, we have allocated a buffer large enough for the complete process list,
		///even if some new processes have been started in the mean time.
		///Hence, the next call is entirely expected to succeed.
		procListSize = (ULONG)memSize;
		status = NtQuerySystemInformation(SystemProcessInformation, pProcListHead, procListSize, &procListSize);
		if (status)
			break;

		pid = NULL;
		pProcEntry = pProcListHead;				///The list of all system processes is a so called singly linked list.
		while (pProcEntry->NextEntryOffset) {	///If NextEntryOffset member is NULL, we have reached the list end (tail).
			pProcEntry = (PSYSTEM_PROCESS_INFORMATION)((PUCHAR)pProcEntry + pProcEntry->NextEntryOffset);
			//DebugPrint2A("PID: %d, %wZ", pProcEntry->UniqueProcessId, pProcEntry->ImageName);
			if (0 == RtlCompareUnicodeString(pProcName, &pProcEntry->ImageName, TRUE)) {
				pid = pProcEntry->UniqueProcessId;
				break;
			}
		}

		if (!pid) {
			status = STATUS_OBJECT_NAME_NOT_FOUND;
			break;
		}
			
		if (useDebugPrivilege) {
			status = RtlAdjustPrivilege(SE_DEBUG_PRIVILEGE, TRUE, FALSE, &oldValue);
			if (status){			///Since we're for some reason supposed to use the SeDebugPrivilege,
				useDebugPrivilege = FALSE;
				break;				///we fail deliberately if we can't enable it.
			}
		}

		InitializeObjectAttributes(&procAttr, NULL, 0, NULL, NULL);
		cid.UniqueThread = (HANDLE)0;
		cid.UniqueProcess = pid;

		///Opening a process for full access might be less suspicious than opening with our real intentions.
		status = NtOpenProcess(pProcess, PROCESS_ALL_ACCESS, &procAttr, &cid);
		if (status) {
			///Most likely STATUS_ACCESS_DENIED if
			///either we didn't specify the useDebugPrivilege flag when opening a cross session process
			///or if we tried to open an elevated process while running non-elevated
			///or if the process being opened is a so-called "Protected Process".

			///In x64 windows, HIPS or AV drivers have the possibility to legally
			///receive a notification if a process is about to open a handle to another process.
			///In those ObCallback routines they cannot completely deny the opening.
			///However, they are able to modify the access masks, so a handle supposed for VM operations still
			///will be lacking the PROCESS_VM_XXX rights, for example. If we therefore query the handle rights
			///we can still return an appropriate error if wasn't granted the rights we want
			///And are not going to fail at first when performing our process operations.
			*pProcess = NULL;
			break;
		}

		status = NtQueryObject(*pProcess, ObjectBasicInformation, &processHandleInfo, sizeof(OBJECT_BASIC_INFORMATION), &obQueryLen);
		if (status)	///Not sure if this call ever will fail...
			break;

		///Maybe, HIPS just wanted to deny PROCESS_TERMINATE/PROCESS_SUSPEND right?
		///If so, we don't care. We're only interested in VM rights.
		if (MIN_VM_ACCESS_MASK & ~processHandleInfo.GrantedAccess) {
			status = STATUS_UNSUCCESSFUL;
			break;
		}
	} while (status);

	if (status && pProcess) {
		if (*pProcess) {
			NtClose(*pProcess);
			*pProcess = NULL;
		}
	}

	if (pProcListHead) {
		memSize = 0;
		NtFreeVirtualMemory(INVALID_HANDLE_VALUE, &pProcListHead, &memSize, MEM_RELEASE); ///We don't need the list anymore.
	}
		
	if (useDebugPrivilege)
		RtlAdjustPrivilege(SE_DEBUG_PRIVILEGE, oldValue, FALSE, &oldValue);		///We don't need the privilege anymore.

	return status;
}
Пример #15
0
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
    void *(*start_routine)(void*), void *arg)
{
 HANDLE hThread;
 OBJECT_ATTRIBUTES oaThreadAttrs;
 CLIENT_ID ciId;
 CONTEXT cxThreadContext;
 INITIAL_TEB itInitialTeb;
 BOOLEAN fSuspended;
 ULONG nOldPageProtection;
 NTSTATUS nErrCode;

 /* initialize generic object attributes */
 oaThreadAttrs.Length = sizeof(OBJECT_ATTRIBUTES);
 oaThreadAttrs.RootDirectory = NULL;
 oaThreadAttrs.ObjectName = NULL;
 oaThreadAttrs.Attributes = 0;
 oaThreadAttrs.SecurityDescriptor = NULL;
 oaThreadAttrs.SecurityQualityOfService = NULL;

 /* initialize thread attributes */
 fSuspended = FALSE; /* FIXME? really needed? can we hardcode this to FALSE? */

 /* stack attributes */
 FIXME("stack size defaulted to 0x100000 - thread attributes ignored");

 /* stack reserve size */
 itInitialTeb.StackReserve = 0x100000;

 /* stack commit size */
 itInitialTeb.StackCommit = itInitialTeb.StackReserve - PAGE_SIZE;

 /* guard page */
 itInitialTeb.StackCommit += PAGE_SIZE;

 /* reserve stack */
 itInitialTeb.StackAllocate = NULL;

 nErrCode = NtAllocateVirtualMemory
 (
  NtCurrentProcess(),
  &itInitialTeb.StackAllocate,
  0,
  &itInitialTeb.StackReserve,
  MEM_RESERVE,
  PAGE_READWRITE
 );

 if(!NT_SUCCESS(nErrCode))
 {
  return (__status_to_errno(nErrCode)); /* FIXME? TODO? pthread specific error codes? */
 }

 itInitialTeb.StackBase = (PVOID)((ULONG)itInitialTeb.StackAllocate + itInitialTeb.StackReserve);
 itInitialTeb.StackLimit = (PVOID)((ULONG)itInitialTeb.StackBase - itInitialTeb.StackCommit);

 /* commit stack */
 nErrCode = NtAllocateVirtualMemory
 (
  NtCurrentProcess(),
  &itInitialTeb.StackLimit,
  0,
  &itInitialTeb.StackCommit,
  MEM_COMMIT,
  PAGE_READWRITE
 );

 if(!NT_SUCCESS(nErrCode))
 {
  NtFreeVirtualMemory
  (
   NtCurrentProcess(),
   itInitialTeb.StackAllocate,
   &itInitialTeb.StackReserve,
   MEM_RELEASE
  );

  return (__status_to_errno(nErrCode));
 }

 /* protect guard page */
 nErrCode = NtProtectVirtualMemory
 (
  NtCurrentProcess(),
  itInitialTeb.StackLimit,
  PAGE_SIZE,
  PAGE_GUARD | PAGE_READWRITE,
  &nOldPageProtection
 );

 if(!NT_SUCCESS(nErrCode))
 {
  NtFreeVirtualMemory
  (
   NtCurrentProcess(),
   itInitialTeb.StackAllocate,
   &itInitialTeb.StackReserve,
   MEM_RELEASE
  );

  return (__status_to_errno(nErrCode));
 }

 /* initialize thread registers */

//#ifdef __i386__
 memset(&cxThreadContext, 0, sizeof(CONTEXT));
 cxThreadContext.Eip = (LONG)__threadentry;
 cxThreadContext.SegGs = USER_DS;
 cxThreadContext.SegFs = TEB_SELECTOR;
 cxThreadContext.SegEs = USER_DS;
 cxThreadContext.SegDs = USER_DS;
 cxThreadContext.SegCs = USER_CS;
 cxThreadContext.SegSs = USER_DS;
 cxThreadContext.Esp = (ULONG)itInitialTeb.StackBase - 12;
 cxThreadContext.EFlags = (1<<1) + (1<<9);

 /* initialize call stack */
 *((PULONG)((ULONG)itInitialTeb.StackBase - 4)) = (ULONG)arg; /* thread argument */
 *((PULONG)((ULONG)itInitialTeb.StackBase - 8)) = (ULONG)start_routine; /* thread start routine */
 *((PULONG)((ULONG)itInitialTeb.StackBase - 12)) = 0xDEADBEEF; /* "shouldn't see me" */
//#else
//#error Unsupported architecture
//#endif

 INFO("about to create new thread - start routine at %#x, argument %#x", start_routine, arg);

 /* create thread */
 nErrCode = NtCreateThread
 (
  &hThread,
  THREAD_ALL_ACCESS,
  &oaThreadAttrs,
  NtCurrentProcess(),
  &ciId,
  &cxThreadContext,
  &itInitialTeb,
  fSuspended
 );

 if(!NT_SUCCESS(nErrCode))
 {
  NtFreeVirtualMemory
  (
   NtCurrentProcess(),
   itInitialTeb.StackAllocate,
   &itInitialTeb.StackReserve,
   MEM_RELEASE
  );

  return (__status_to_errno(nErrCode));
 }

 /* FIXME? should we return the thread handle or the thread id? */
 if(thread != 0)
  *thread = (pthread_t)&ciId.UniqueThread; /* for the moment, we return the id */

 return (0);

}
Пример #16
0
_CRTAPI1 main()
{
    LONG i, j;
    PULONG p4, p3, p2, p1, oldp1, vp1;
    ULONG Size1, Size2, Size3;
    NTSTATUS status, alstatus;
    HANDLE CurrentProcessHandle;
    HANDLE GiantSection;
    HANDLE Section2, Section4;
    MEMORY_BASIC_INFORMATION MemInfo;
    ULONG OldProtect;
    STRING Name3;
    HANDLE Section1;
    OBJECT_ATTRIBUTES ObjectAttributes;
    OBJECT_ATTRIBUTES Object1Attributes;
    ULONG ViewSize;
    LARGE_INTEGER Offset;
    LARGE_INTEGER SectionSize;
    UNICODE_STRING Unicode;

    CurrentProcessHandle = NtCurrentProcess();

    DbgPrint(" Memory Management Tests - AllocVm, FreeVm, ProtectVm, QueryVm\n");

    p1 = (PULONG)0x20020000;
    Size1 = 0xbc0000;

    alstatus = NtAllocateVirtualMemory (CurrentProcessHandle, (PVOID *)&p1,
                        0, &Size1, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);

    if (!NT_SUCCESS(alstatus)) {
        DbgPrint("failed first created vm status %X start %lx size %lx\n",
            alstatus, (ULONG)p1, Size1);
        DbgPrint("******** FAILED TEST 1 **************\n");
    }

    status = NtQueryVirtualMemory (CurrentProcessHandle, p1,
                                    MemoryBasicInformation,
                                    &MemInfo, sizeof (MEMORY_BASIC_INFORMATION),
                                    NULL);

    if (!NT_SUCCESS(status)) {
        DbgPrint("******** FAILED TEST 2 **************\n");
        DbgPrint("FAILURE query vm status %X address %lx Base %lx size %lx\n",
             status,
             p1,
             MemInfo.BaseAddress,
             MemInfo.RegionSize);
        DbgPrint("     state %lx protect %lx type %lx\n",
             MemInfo.State,
             MemInfo.Protect,
             MemInfo.Type);
    }
    if ((MemInfo.RegionSize != Size1) || (MemInfo.BaseAddress != p1) ||
        (MemInfo.Protect != PAGE_READWRITE) || (MemInfo.Type != MEM_PRIVATE) ||
        (MemInfo.State != MEM_COMMIT)) {

        DbgPrint("******** FAILED TEST 3 **************\n");
        DbgPrint("FAILURE query vm status %X address %lx Base %lx size %lx\n",
             status,
             p1,
             MemInfo.BaseAddress,
             MemInfo.RegionSize);
        DbgPrint("     state %lx protect %lx type %lx\n",
             MemInfo.State,
             MemInfo.Protect,
             MemInfo.Type);
    }

    p2 = (PULONG)NULL;
    Size2 = 0x100000;

    alstatus = NtAllocateVirtualMemory (CurrentProcessHandle,
                                      (PVOID *)&p2,
                                       3,
                                       &Size2,
                                       MEM_TOP_DOWN | MEM_RESERVE | MEM_COMMIT,
                                       PAGE_READWRITE);

    if (!NT_SUCCESS(alstatus)) {
        DbgPrint("failed first created vm status %lC start %lx size %lx\n",
            status, (ULONG)p1, Size1);
        DbgPrint("******** FAILED TEST 3a.1 **************\n");
        NtTerminateProcess(NtCurrentProcess(),status);

    }

    //
    // Touch every other page.
    //

    vp1 = p2 + 3000;
    while (vp1 < (PULONG)((PCHAR)p2 + Size2)) {
        *vp1 = 938;
        vp1 += 3000;
    }

    //
    // Decommit pages.
    //

    Size3 = Size2 - 5044;
    vp1 = p2 + 3000;

    status = NtFreeVirtualMemory (CurrentProcessHandle,
                                      (PVOID *)&p2,
                                      &Size3,
                                      MEM_DECOMMIT);

    if (!(NT_SUCCESS(status))) {
        DbgPrint(" free vm failed - status %lx\n",status);
        DbgPrint("******** FAILED TEST 3a.4 **************\n");
        NtTerminateProcess(NtCurrentProcess(),status);
    }

    //
    // Split the memory block using MEM_RELEASE.
    //


    vp1 = p2 + 5000;
    Size3 = Size2 - 50000;

    status = NtFreeVirtualMemory (CurrentProcessHandle,
                                      (PVOID *)&vp1,
                                      &Size3,
                                      MEM_RELEASE);

    if (!(NT_SUCCESS(status))) {
        DbgPrint(" free vm failed - status %lx\n",status);
        DbgPrint("******** FAILED TEST 3a.b **************\n");
        NtTerminateProcess(NtCurrentProcess(),status);
    }

    vp1 = p2 + 3000;
    Size3 = 41;

    status = NtFreeVirtualMemory (CurrentProcessHandle,
                                      (PVOID *)&vp1,
                                      &Size3,
                                      MEM_RELEASE);

    if (!(NT_SUCCESS(status))) {
        DbgPrint(" free vm failed - status %lx\n",status);
        DbgPrint("******** FAILED TEST 3a.5 **************\n");
        NtTerminateProcess(NtCurrentProcess(),status);
    }

    //
    // free every page, ignore the status.
    //

    vp1 = p2;
    Size3 = 30;
    while (vp1 < (PULONG)((PCHAR)p2 + Size2)) {

        status = NtFreeVirtualMemory (CurrentProcessHandle,
                                      (PVOID *)&vp1,
                                      &Size3,
                                      MEM_RELEASE);
        vp1 += 128;
    }

    p2 = (PULONG)NULL;
    Size2 = 0x10000;

    status = NtAllocateVirtualMemory (CurrentProcessHandle,
                                      (PVOID *)&p2,
                                       3,
                                       &Size2,
                                       MEM_TOP_DOWN | MEM_RESERVE | MEM_COMMIT,
                                       PAGE_READWRITE);

    if (!NT_SUCCESS(status)) {
        DbgPrint("failed first created vm status %X start %lx size %lx\n",
            status, (ULONG)p1, Size1);
        DbgPrint("******** FAILED TEST 3.1 **************\n");
    } else {
        if (p2 != (PVOID)0x1fff0000) {
            DbgPrint("******** FAILED TEST 3.2 **************\n");
            DbgPrint("p2 = %lx\n",p2);
        }
        status = NtFreeVirtualMemory (CurrentProcessHandle,
                                      (PVOID *)&p2,
                                      &Size2,
                                      MEM_RELEASE);

        if (!(NT_SUCCESS(status))) {
            DbgPrint(" free vm failed - status %lx\n",status);
            DbgPrint("******** FAILED TEST 3.3 **************\n");
            NtTerminateProcess(NtCurrentProcess(),status);
        }
    }

    if (NT_SUCCESS(alstatus)) {
        status = NtFreeVirtualMemory (CurrentProcessHandle,
                                      (PVOID *)&p1,
                                      &Size1,
                                      MEM_RELEASE);
    }

    if (!(NT_SUCCESS(status))) {
        DbgPrint(" free vm failed - status %lx\n",status);
        DbgPrint("******** FAILED TEST 4 **************\n");
        NtTerminateProcess(NtCurrentProcess(),status);
    }

    p1 = (PULONG)NULL;
    Size1 = 16 * 4096;
    status = NtAllocateVirtualMemory (CurrentProcessHandle, (PVOID *)&p1,
                        0, &Size1, MEM_RESERVE, PAGE_READWRITE | PAGE_GUARD);

    if (!NT_SUCCESS(status)) {
        DbgPrint("******** FAILED TEST 5 **************\n");

        DbgPrint("created vm status %X start %lx size %lx\n",
            status, (ULONG)p1, Size1);
    }
    status = NtQueryVirtualMemory (CurrentProcessHandle, p1,
                                    MemoryBasicInformation,
                                    &MemInfo, sizeof (MEMORY_BASIC_INFORMATION),
                                    NULL);

    if (!NT_SUCCESS(status)) {
        DbgPrint("******** FAILED TEST 6 **************\n");
        DbgPrint("query vm status %X address %lx Base %lx size %lx\n",
             status,
             p1,
             MemInfo.BaseAddress,
             MemInfo.RegionSize);
        DbgPrint("     state %lx protect %lx alloc_protect %lx type %lx\n",
             MemInfo.State,
             MemInfo.Protect,
             MemInfo.AllocationProtect,
             MemInfo.Type);
    }

    if ((MemInfo.RegionSize != Size1) || (MemInfo.BaseAddress != p1) ||
        (MemInfo.AllocationProtect != (PAGE_READWRITE | PAGE_GUARD)) ||
        (MemInfo.Protect != 0) ||
        (MemInfo.Type != MEM_PRIVATE) ||
        (MemInfo.State != MEM_RESERVE)) {

        DbgPrint("******** FAILED TEST 7 **************\n");
        DbgPrint("query vm status %X address %lx Base %lx size %lx\n",
             status,
             p1,
             MemInfo.BaseAddress,
             MemInfo.RegionSize);
        DbgPrint("     state %lx protect %lx alloc_protect %lx type %lx\n",
             MemInfo.State,
             MemInfo.Protect,
             MemInfo.AllocationProtect,
             MemInfo.Type);
    }

    Size2 = 8192;

    oldp1 = p1;
    p1 = p1 + 14336;  // 64k -8k /4

    status = NtAllocateVirtualMemory (CurrentProcessHandle, (PVOID *)&p1,
                        0, &Size2, MEM_COMMIT, PAGE_EXECUTE_READWRITE);

    if (!NT_SUCCESS(status)) {
        DbgPrint("******** FAILED TEST 8 **************\n");
        DbgPrint("created vm status %X start %lx size %lx\n",
            status, (ULONG)p1, Size1);
    }
    status = NtQueryVirtualMemory (CurrentProcessHandle, oldp1,
                                    MemoryBasicInformation,
                                    &MemInfo, sizeof (MEMORY_BASIC_INFORMATION),
                                    NULL);

    if (!NT_SUCCESS(status)) {
        DbgPrint("******** FAILED TEST 9 **************\n");
        DbgPrint("query vm status %X address %lx Base %lx size %lx\n",
             status,
             oldp1,
             MemInfo.BaseAddress,
             MemInfo.RegionSize);
        DbgPrint("     state %lx protect %lx type %lx\n",
             MemInfo.State,
             MemInfo.Protect,
             MemInfo.Type);
    }

    if ((MemInfo.RegionSize != 56*1024) || (MemInfo.BaseAddress != oldp1) ||
        (MemInfo.AllocationProtect != (PAGE_READWRITE | PAGE_GUARD)) ||
        (MemInfo.Protect != 0) ||
        (MemInfo.Type != MEM_PRIVATE) ||
        (MemInfo.State != MEM_RESERVE)) {

        DbgPrint("******** FAILED TEST 10 **************\n");
        DbgPrint("query vm status %X address %lx Base %lx size %lx\n",
             status,
             oldp1,
             MemInfo.BaseAddress,
             MemInfo.RegionSize);
        DbgPrint("     state %lx protect %lx alloc_protect %lx type %lx\n",
             MemInfo.State,
             MemInfo.Protect,
             MemInfo.AllocationProtect,
             MemInfo.Type);
    }

    status = NtQueryVirtualMemory (CurrentProcessHandle, p1,
                                    MemoryBasicInformation,
                                    &MemInfo, sizeof (MEMORY_BASIC_INFORMATION),
                                    NULL);

    if (!NT_SUCCESS(status)) {
        DbgPrint("******** FAILED TEST 11 **************\n");
        DbgPrint("query vm status %X address %lx Base %lx size %lx\n",
             status,
             p1,
             MemInfo.BaseAddress,
             MemInfo.RegionSize);
        DbgPrint("     state %lx protect %lx type %lx\n",
             MemInfo.State,
             MemInfo.Protect,
             MemInfo.Type);
    }
    if ((MemInfo.RegionSize != Size2) || (MemInfo.BaseAddress != p1) ||
        (MemInfo.Protect != PAGE_EXECUTE_READWRITE) || (MemInfo.Type != MEM_PRIVATE) ||
        (MemInfo.State != MEM_COMMIT)
        || (MemInfo.AllocationBase != oldp1)) {

        DbgPrint("******** FAILED TEST 12 **************\n");
        DbgPrint("query vm status %X address %lx Base %lx size %lx\n",
             status,
             oldp1,
             MemInfo.BaseAddress,
             MemInfo.RegionSize);
        DbgPrint("     state %lx protect %lx type %lx\n",
             MemInfo.State,
             MemInfo.Protect,
             MemInfo.Type);
    }

    Size1 = Size2;

    status = NtProtectVirtualMemory (CurrentProcessHandle, (PVOID *)&p1,
                        &Size1, PAGE_READONLY | PAGE_NOCACHE, &OldProtect);

    if ((!NT_SUCCESS(status)) || (OldProtect != PAGE_EXECUTE_READWRITE)) {
        DbgPrint("******** FAILED TEST 13 **************\n");
        DbgPrint("protected VM status %X, base %lx, size %lx, old protect %lx\n",
                    status, p1, Size1, OldProtect);
    }
    status = NtQueryVirtualMemory (CurrentProcessHandle, p1,
                                    MemoryBasicInformation,
                                    &MemInfo, sizeof (MEMORY_BASIC_INFORMATION),
                                    NULL);

    if ((!NT_SUCCESS(status)) ||
        MemInfo.Protect != (PAGE_NOCACHE | PAGE_READONLY)) {

        DbgPrint("******** FAILED TEST 14 **************\n");

        DbgPrint("query vm status %X address %lx Base %lx size %lx\n",
                 status,
                 p1,
                 MemInfo.BaseAddress,
                 MemInfo.RegionSize);
        DbgPrint("     state %lx protect %lx type %lx\n",
                 MemInfo.State,
                 MemInfo.Protect,
             MemInfo.Type);
    }
    i = *p1;

    status = NtProtectVirtualMemory (CurrentProcessHandle, (PVOID *)&p1,
                        &Size1, PAGE_NOACCESS | PAGE_NOCACHE, &OldProtect);

    if (status != STATUS_INVALID_PAGE_PROTECTION) {
        DbgPrint("******** FAILED TEST 15 **************\n");
        DbgPrint("protected VM status %X, base %lx, size %lx, old protect %lx\n",
                    status, p1, Size1, OldProtect, i);
    }
    status = NtProtectVirtualMemory (CurrentProcessHandle, (PVOID *)&p1,
                        &Size1, PAGE_READONLY, &OldProtect);

    if ((!NT_SUCCESS(status)) || (OldProtect != (PAGE_NOCACHE | PAGE_READONLY))) {
        DbgPrint("******** FAILED TEST 16 **************\n");
        DbgPrint("protected VM status %X, base %lx, size %lx, old protect %lx\n",
                    status, p1, Size1, OldProtect);
    }
    status = NtProtectVirtualMemory (CurrentProcessHandle, (PVOID *)&p1,
                        &Size1, PAGE_READWRITE, &OldProtect);

    if ((!NT_SUCCESS(status)) || (OldProtect != (PAGE_READONLY))) {
        DbgPrint("******** FAILED TEST 17 **************\n");
        DbgPrint("protected VM status %X, base %lx, size %lx, old protect %lx\n",
                    status, p1, Size1, OldProtect);
    }

    for (i = 1; i < 12; i++) {

        p2 = (PULONG)NULL;
        Size2 = i * 4096;

        status = NtAllocateVirtualMemory (CurrentProcessHandle, (PVOID *)&p2,
                        0, &Size2, MEM_COMMIT, PAGE_READWRITE);

        if (!NT_SUCCESS(status)) {
            DbgPrint("******** FAILED TEST 18 **************\n");
            DbgPrint("created vm status %X start %lx size %lx\n",
                status, (ULONG)p2, Size2);
        }
        if (i==4) {
            p3 = p2;
        }
        if (i == 8) {
            Size3 = 12000;
            status = NtFreeVirtualMemory (CurrentProcessHandle,(PVOID *)&p3, &Size3,
                                  MEM_RELEASE);

            if (!NT_SUCCESS(status)) {
                DbgPrint("******** FAILED TEST 19 **************\n");
                DbgPrint("free vm status %X start %lx size %lx\n",
                    status, (ULONG)p3, Size3);
            }
        }

    }

    p3 = p1 + 8 * 1024;

    status = NtQueryVirtualMemory (CurrentProcessHandle, p3,
                                    MemoryBasicInformation,
                                    &MemInfo, sizeof (MEMORY_BASIC_INFORMATION),
                                    NULL);

    if (!NT_SUCCESS(status)) {
        DbgPrint("******** FAILED TEST 20 **************\n");

        DbgPrint("query vm status %X address %lx Base %lx size %lx\n",
             status,
             p3,
             MemInfo.BaseAddress,
             MemInfo.RegionSize);
        DbgPrint("     state %lx protect %lx type %lx\n",
             MemInfo.State,
             MemInfo.Protect,
             MemInfo.Type);
    }
    p3 = p1 - 8 * 1024;

    status = NtQueryVirtualMemory (CurrentProcessHandle, p3,
                                    MemoryBasicInformation,
                                    &MemInfo, sizeof (MEMORY_BASIC_INFORMATION),
                                    NULL);

    if (!NT_SUCCESS(status)) {
        DbgPrint("******** FAILED TEST 21 **************\n");
        DbgPrint("query vm status %X address %lx Base %lx size %lx\n",
             status,
             p3,
             MemInfo.BaseAddress,
             MemInfo.RegionSize);
        DbgPrint("     state %lx protect %lx type %lx\n",
             MemInfo.State,
             MemInfo.Protect,
             MemInfo.Type);
    }

    Size3 = 16 * 4096;
    status = NtFreeVirtualMemory (CurrentProcessHandle, (PVOID *)&p3, &Size3,
                                  MEM_RELEASE);

    if (status != STATUS_UNABLE_TO_FREE_VM) {
        DbgPrint("******** FAILED TEST 22 **************\n");
        DbgPrint("free vm status %X start %lx size %lx\n",
            status, (ULONG)p3, Size3);
    }

    Size3 = 1 * 4096;
    status = NtFreeVirtualMemory (CurrentProcessHandle, (PVOID *)&p3, &Size3,
                                    MEM_RELEASE);

    if (!NT_SUCCESS(status)) {
        DbgPrint("******** FAILED TEST 23 **************\n");
        DbgPrint("free vm status %X start %lx size %lx\n",
            status, (ULONG)p3, Size3);
    }

    p3 = (PULONG)NULL;
    Size3 = 300 * 4096;

    status = NtAllocateVirtualMemory (CurrentProcessHandle, (PVOID *)&p3,
                        0, &Size3, MEM_COMMIT, PAGE_READWRITE);

    if (!NT_SUCCESS(status)) {
        DbgPrint("******** FAILED TEST 24 **************\n");
        DbgPrint("created vm status %X start %lx size %lx\n",
            status, (ULONG)p3, Size3);
    }

    p1 = p3;

    p2 = ((PULONG)((PUCHAR)p3 + Size3));
    p4 = p1;
    j = 0;

    while (p3 < p2) {
        j += 1;
        if (j % 8 == 0) {
            if (*p4 != (ULONG)p4) {
                DbgPrint("bad value in xcell %lx value is %lx\n",p4, *p4);

            }
            p4 += 1;
            *p4 = (ULONG)p4;
            p4 = p4 + 1026;
        }

        *p3 = (ULONG)p3;
        p3 += 1027;
    }

    DbgPrint("checking values\n");

    status = NtQueryVirtualMemory (CurrentProcessHandle, p3,
                                    MemoryBasicInformation,
                                    &MemInfo, sizeof (MEMORY_BASIC_INFORMATION),
                                    NULL);

    if (!NT_SUCCESS(status)) {
        DbgPrint("******** FAILED TEST 25 **************\n");

        DbgPrint("query vm status %X address %lx Base %lx size %lx\n",
             status,
             p3,
             MemInfo.BaseAddress,
             MemInfo.RegionSize);
        DbgPrint("     state %lx protect %lx type %lx\n",
             MemInfo.State,
             MemInfo.Protect,
             MemInfo.Type);
    }

    p3 = p1;

    while (p3 < p2) {

        if (*p3 != (ULONG)p3) {
            DbgPrint("bad value in 1cell %lx value is %lx\n",p3, *p3);
        }
        p3 += 1027;

    }
    p3 = p1;

    while (p3 < p2) {

        if (*p3 != (ULONG)p3) {
            DbgPrint("bad value in 2cell %lx value is %lx\n",p3, *p3);
        }
        p3 += 1027;

    }
    p3 = p1;

    while (p3 < p2) {

        if (*p3 != (ULONG)p3) {
            DbgPrint("bad value in 3cell %lx value is %lx\n",p3, *p3);
        }
        p3 += 1027;

    }
    p3 = p1;

    while (p3 < p2) {

        if (*p3 != (ULONG)p3) {
            DbgPrint("bad value in 4cell %lx value is %lx\n",p3, *p3);
        }
        p3 += 1027;

    }
    p3 = p1;

    while (p3 < p2) {

        if (*p3 != (ULONG)p3) {
            DbgPrint("bad value in 5cell %lx value is %lx\n",p3, *p3);
        }
        p3 += 1027;

    }
    p3 = p1;

    while (p3 < p2) {

        if (*p3 != (ULONG)p3) {
            DbgPrint("bad value in cell %lx value is %lx\n",p3, *p3);
        }
        p3 += 1027;

    }

    //
    // Check physical frame mapping.
    //

    //
    // Check physical frame mapping.
    //

    RtlInitAnsiString (&Name3, "\\Device\\PhysicalMemory");

    status = RtlAnsiStringToUnicodeString(&Unicode,&Name3,TRUE);
    if (!NT_SUCCESS(status)) {
        printf("string conversion failed status %lx\n", status);
        ExitProcess (status);
    }
    InitializeObjectAttributes( &ObjectAttributes,
                                &Unicode,
                                OBJ_CASE_INSENSITIVE,
                                NULL,
                                NULL );

    status = NtOpenSection ( &Section1,
                             SECTION_MAP_READ | SECTION_MAP_WRITE,
                             &ObjectAttributes );

    RtlFreeUnicodeString(&Unicode);

    if (status != 0) {
        DbgPrint("******** FAILED TEST 26 **************\n");
        DbgPrint("open physical section failed %lx\n", status);
    }

    p1 = NULL;
    Offset.LowPart = 0x810ff033;
    Offset.HighPart = 0;
    ViewSize = 300*4096;

    status = NtMapViewOfSection (Section1,
                                 NtCurrentProcess(),
                                 (PVOID *)&p1,
                                 0,
                                 ViewSize,
                                 &Offset,
                                 &ViewSize,
                                 ViewUnmap,
                                 0,
                                 PAGE_READWRITE
                                 );
    if (!NT_SUCCESS(status)) {
        DbgPrint("******** FAILED TEST 27 **************\n");
        DbgPrint ("map physical section %X offset = %lx, base %lx\n",status,
                Offset.LowPart, p1);
    }



    p1 = NULL;
    Size1 = 8 * 1024 * 1024;

    alstatus = NtAllocateVirtualMemory (CurrentProcessHandle, (PVOID *)&p1,
                        0, &Size1, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);

    if (!NT_SUCCESS(alstatus)) {
        DbgPrint("failed first created vm status %X start %lx size %lx\n",
            alstatus, (ULONG)p1, Size1);
        DbgPrint("******** FAILED TEST 28 **************\n");
    }

    RtlZeroMemory (p1, Size1);

    Size1 -= 20000;
    (PUCHAR)p1 += 5000;
    status = NtFreeVirtualMemory (CurrentProcessHandle,
                                      (PVOID *)&p1,
                                      &Size1 ,
                                      MEM_DECOMMIT);

    if (!(NT_SUCCESS(status))) {
        DbgPrint(" free vm failed - status %lx\n",status);
        DbgPrint("******** FAILED TEST 29 **************\n");
        NtTerminateProcess(NtCurrentProcess(),status);
    }

    Size1 -= 20000;
    (PUCHAR)p1 += 5000;
    alstatus = NtAllocateVirtualMemory (CurrentProcessHandle, (PVOID *)&p1,
                        0, &Size1, MEM_COMMIT, PAGE_EXECUTE_READWRITE);


    if (!NT_SUCCESS(alstatus)) {
        DbgPrint("failed first created vm status %X start %lx size %lx\n",
            alstatus, (ULONG)p1, Size1);
        DbgPrint("******** FAILED TEST 30 **************\n");
    }

    RtlZeroMemory (p1, Size1);


    Size1 = 28 * 4096;
    p1 = NULL;

    status = NtAllocateVirtualMemory (CurrentProcessHandle, (PVOID *)&p1,
                        0, &Size1, MEM_COMMIT, PAGE_READWRITE | PAGE_GUARD);

    if (!NT_SUCCESS(status)) {
        DbgPrint("failed first created vm status %X start %lx size %lx\n",
            status, (ULONG)p1, Size1);
        DbgPrint("******** FAILED TEST 31 **************\n");
    }

    try {

        //
        // attempt to write the guard page.
        //

        *p1 = 973;
        DbgPrint("************ FAILURE TEST 31.3 guard page exception did not occur\n");

    } except (EXCEPTION_EXECUTE_HANDLER) {
        status = GetExceptionCode();
        if (status != STATUS_GUARD_PAGE_VIOLATION) {
            DbgPrint("******** FAILED TEST 32 ******\n");
        }
    }

    p2 = NULL;
    Size2 = 200*1024*1024;  //200MB

    status = NtAllocateVirtualMemory (CurrentProcessHandle, (PVOID *)&p2,
                    0, &Size2, MEM_COMMIT, PAGE_READWRITE);

    if (NT_SUCCESS(status)) {
        status = NtFreeVirtualMemory (CurrentProcessHandle,
                                          (PVOID *)&p2,
                                          &Size2,
                                          MEM_RELEASE);
    } else {
        if ((status != STATUS_COMMITMENT_LIMIT) &&
             (status != STATUS_PAGEFILE_QUOTA_EXCEEDED)) {
            DbgPrint("******** FAILED TEST 33 ************** %lx\n",status);
        }
    }

    //
    // Create a giant section (2gb)
    //

    InitializeObjectAttributes( &Object1Attributes,
                                NULL,
                                0,
                                NULL,
                                NULL );

    SectionSize.LowPart = 0x7f000000;
    SectionSize.HighPart = 0;

    status = NtCreateSection (&GiantSection,
                              SECTION_MAP_READ | SECTION_MAP_WRITE,
                              &Object1Attributes,
                              &SectionSize,
                              PAGE_READWRITE,
                              SEC_RESERVE,
                              NULL);

    if (!NT_SUCCESS(status)) {
        DbgPrint("failed create big section status %X\n",
            status);
        DbgPrint("******** FAILED TEST 41 **************\n");
    }

    //
    // Attempt to map the section (this should fail).
    //

    p1 = NULL;
    ViewSize = 0;

    status = NtMapViewOfSection (GiantSection,
                                 CurrentProcessHandle,
                                 (PVOID *)&p1,
                                 0L,
                                 0,
                                 0,
                                 &ViewSize,
                                 ViewUnmap,
                                 0,
                                 PAGE_READWRITE );

    if (status != STATUS_NO_MEMORY) {
        DbgPrint("failed map big section status %X\n",
            status);
        DbgPrint("******** FAILED TEST 42 **************\n");
    }

#ifdef i386
    //
    // Test MEM_DOS_LIM support.
    //

    InitializeObjectAttributes( &Object1Attributes,
                                NULL,
                                OBJ_CASE_INSENSITIVE,
                                NULL,
                                NULL );
    SectionSize.LowPart = 1575757,
    SectionSize.HighPart = 0;
    status = NtCreateSection (&Section4,
                              SECTION_MAP_READ | SECTION_MAP_WRITE,
                              &Object1Attributes,
                              &SectionSize,
                              PAGE_READWRITE,
                              SEC_COMMIT,
                              NULL);

    if (!NT_SUCCESS(status)) {
        DbgPrint("******** FAILED TEST 42 **************\n");
        DbgPrint("t1 create section  status %X section handle %lx\n", status,
        (ULONG)Section4);
    }

    p3 = (PVOID)0x9001000;
    ViewSize = 8000;

    status = NtMapViewOfSection (Section4,
                                 CurrentProcessHandle,
                                 (PVOID *)&p3,
                                 0L,
                                 0,
                                 0,
                                 &ViewSize,
                                 ViewUnmap,
                                 MEM_DOS_LIM,
                                 PAGE_READWRITE );

    if (!NT_SUCCESS(status)) {
        DbgPrint("******** FAILED TEST 43 **************\n");
        DbgPrint("t1 map section status %X base %lx size %lx\n", status, (ULONG)p3,
            ViewSize);
        NtTerminateProcess(NtCurrentProcess(),STATUS_SUCCESS);
    }

    p2 = (PVOID)0x9003000;
    ViewSize = 8000;

    status = NtMapViewOfSection (Section4,
                                 CurrentProcessHandle,
                                 (PVOID *)&p2,
                                 0L,
                                 0,
                                 0,
                                 &ViewSize,
                                 ViewUnmap,
                                 MEM_DOS_LIM,
                                 PAGE_READWRITE );

    if (!NT_SUCCESS(status)) {
        DbgPrint("******** FAILED TEST 44 **************\n");
        DbgPrint("t1 map section status %X base %lx size %lx\n", status, (ULONG)p3,
            ViewSize);
        NtTerminateProcess(NtCurrentProcess(),STATUS_SUCCESS);
    }

    status = NtQueryVirtualMemory (CurrentProcessHandle, p3,
                                    MemoryBasicInformation,
                                    &MemInfo, sizeof (MEMORY_BASIC_INFORMATION),
                                    NULL);

    if (!NT_SUCCESS(status)) {
        DbgPrint("******** FAILED TEST 44 **************\n");
        DbgPrint("FAILURE query vm status %X address %lx Base %lx size %lx\n",
             status,
             p1,
             MemInfo.BaseAddress,
             MemInfo.RegionSize);
        DbgPrint("     state %lx protect %lx type %lx\n",
             MemInfo.State,
             MemInfo.Protect,
             MemInfo.Type);
    }

    *p3 = 98;
    if (*p3 != *p2) {
        DbgPrint("******** FAILED TEST 45 **************\n");
    }


    Size2 = 8;

    p1 = (PVOID)((ULONG)p2 - 0x3000);
    status = NtAllocateVirtualMemory (CurrentProcessHandle, (PVOID *)&p1,
                        0, &Size2, MEM_COMMIT, PAGE_EXECUTE_READWRITE);

    if (NT_SUCCESS(status)) {
        DbgPrint("******** FAILED TEST 46 **************\n");
        DbgPrint("created vm status %X start %lx size %lx\n",
            status, (ULONG)p1, Size1);
    }
#endif

    DbgPrint(" End of Memory Management Tests - CreateSection, MapView\n");


    DbgPrint("creating too much virtual address space\n");
    i = 0;

    do {
        p2 = NULL;
        Size2 = 8*1024*1024 + 9938;
        i += 1;

        status = NtAllocateVirtualMemory (CurrentProcessHandle, (PVOID *)&p2,
                        0, &Size2, MEM_RESERVE, PAGE_READWRITE);

    } while (NT_SUCCESS (status));

    if (status != STATUS_NO_MEMORY) {
        DbgPrint("******** FAILED TEST 46 **************\n");
    }

    DbgPrint("created vm done (successfully) status %X, number of allocs %ld\n",
            status, i);
    DbgPrint(" End of Memory Management Tests - AllocVm, FreeVm, ProtectVm, QueryVm\n");

{
    ULONG size, Size;
    PVOID BaseAddress;
    NTSTATUS Status;

    Size = 50*1024;
    size = Size - 1;
    BaseAddress = (PVOID)1;

    // we pass an address of 1, so mm will round it down to 0.  if we
    // passed 0, it looks like a not present argument

    // N.B.  We have to make two separate calls to allocatevm, because
    //       we want a specific virtual address.  If we don't first reserve
    //       the address, the mm fails the commit call.

    Status = NtAllocateVirtualMemory( NtCurrentProcess(),
                                      &BaseAddress,
                                      0L,
                                      &size,
                                      MEM_RESERVE,
                                      PAGE_READWRITE );

    if (!NT_SUCCESS(Status)) {
        DbgPrint("NtReserveVirtualMemory failed !!!! Status = %lx\n",
          Status);
    }

    size = Size - 1;
    BaseAddress = (PVOID)1;
    Status = NtAllocateVirtualMemory( NtCurrentProcess(),
                                      &BaseAddress,
                                      0L,
                                      &size,
                                      MEM_COMMIT,
                                      PAGE_READWRITE );

    if (!NT_SUCCESS(Status)) {
        DbgPrint("NtCommitVirtualMemory failed !!!! Status = %lx\n",
          Status);
    }
}

    ExitProcess (0);
}
Пример #17
0
void test_alloc_free(void)
{
	VOID *address, *a;
	ULONG size;
	NTSTATUS r;
	HANDLE handle = (HANDLE) ~0;

	/* allocate a page and free it */
	address = NULL;
	size = 0x1000;
	r = NtAllocateVirtualMemory( handle, &address, 0, &size, MEM_RESERVE, PAGE_NOACCESS );
	ok(r == STATUS_SUCCESS, "wrong return code\n");
	ok(address != NULL, "NULL allocated\n");
	ok(size == 0x1000, "size wrong\n");

	r = NtFreeVirtualMemory( handle, &address, &size, MEM_RELEASE );
	ok(r == STATUS_SUCCESS, "wrong return code\n");

	/* attempt a double free */
	r = NtFreeVirtualMemory( handle, &address, &size, MEM_RELEASE );
	ok(r == STATUS_MEMORY_NOT_ALLOCATED, "wrong return code\n");

	/* free two halves */
	address = NULL;
	size = 0x2000;
	r = NtAllocateVirtualMemory( handle, &address, 0, &size, MEM_RESERVE, PAGE_NOACCESS );
	ok(r == STATUS_SUCCESS, "wrong return code\n");
	ok(address != NULL, "NULL allocated\n");
	ok(size == 0x2000, "size wrong\n");

	size = 0x1000;
	a = address;
	r = NtFreeVirtualMemory( handle, &address, &size, MEM_RELEASE );
	ok(r == STATUS_SUCCESS, "wrong return code\n");
	ok(size == 0x1000, "size wrong\n");
	ok(address == a, "address changed\n");

	size = 0x1000;
	address += 0x1000;
	a = address;
	r = NtFreeVirtualMemory( handle, &address, &size, MEM_RELEASE );
	ok(r == STATUS_SUCCESS, "wrong return code\n");
	ok(size == 0x1000, "size wrong\n");
	ok(address == a, "address changed\n");

	/* alloc and free with a one byte size */
	address = NULL;
	size = 1;
	r = NtAllocateVirtualMemory( handle, &address, 0, &size, MEM_RESERVE, PAGE_NOACCESS );
	ok(r == STATUS_SUCCESS, "wrong return code\n");
	ok(address != NULL, "NULL allocated\n");
	ok(size == 0x1000, "size wrong\n");

	size = 1;
	r = NtFreeVirtualMemory( handle, &address, &size, MEM_RELEASE );
	ok(r == STATUS_SUCCESS, "wrong return code\n");
	ok(size == 0x1000, "size wrong\n");

	/* allocate at an offset address */
	a = address++; /* reuse the previously free'd address... no threads! */
	size = 1;
	r = NtAllocateVirtualMemory( handle, &address, 0, &size, MEM_RESERVE, PAGE_NOACCESS );
	ok(r == STATUS_SUCCESS, "wrong return code\n");
	ok(address == a, "address changed\n");
	ok(size == 0x1000, "size wrong\n");

	a = address++;
	size = 1;
	r = NtFreeVirtualMemory( handle, &address, &size, MEM_RELEASE );
	ok(r == STATUS_SUCCESS, "wrong return code\n");
	ok(address == a, "address changed\n");
	ok(size == 0x1000, "size wrong\n");

	r = NtFreeVirtualMemory( handle, &address, &size, MEM_RELEASE );
	ok(r == STATUS_MEMORY_NOT_ALLOCATED, "wrong return code\n");

	/* try a double allocate */
	address = NULL;
	size = 0x1000;
	r = NtAllocateVirtualMemory( handle, &address, 0, &size, MEM_RESERVE, PAGE_NOACCESS );
	ok(r == STATUS_SUCCESS, "wrong return code\n");
	ok(address != NULL, "NULL allocated\n");
	ok(size == 0x1000, "size wrong\n");

	a = address;
	r = NtAllocateVirtualMemory( handle, &address, 0, &size, MEM_RESERVE, PAGE_NOACCESS );
	ok(r == STATUS_CONFLICTING_ADDRESSES, "wrong return code\n");
	ok(address == a, "address changed\n");
	ok(size == 0x1000, "size wrong\n");

	r = NtFreeVirtualMemory( handle, &address, &size, MEM_RELEASE );
	ok(r == STATUS_SUCCESS, "wrong return code\n");

	/* test MEM_RESERVE, MEM_COMMIT, MEM_DECOMMIT, MEM_RELEASE */
	address = NULL;
	size = 0x1000;
	r = NtAllocateVirtualMemory( handle, &address, 0, &size, MEM_RESERVE, PAGE_NOACCESS );
	ok(r == STATUS_SUCCESS, "wrong return code\n");
	ok(address != NULL, "NULL allocated\n");
	ok(size == 0x1000, "size wrong\n");

	a = address;
	r = NtAllocateVirtualMemory( handle, &address, 0, &size, MEM_COMMIT, PAGE_NOACCESS );
	ok(r == STATUS_SUCCESS, "wrong return code\n");
	ok(address == a, "address changed\n");
	ok(size == 0x1000, "size wrong\n");

	r = NtFreeVirtualMemory( handle, &address, &size, MEM_DECOMMIT );
	ok(r == STATUS_SUCCESS, "wrong return code\n");

	r = NtFreeVirtualMemory( handle, &address, &size, MEM_RELEASE );
	ok(r == STATUS_SUCCESS, "wrong return code\n");

	/* commit then reserve? */
	address = NULL;
	size = 0x1000;
	r = NtAllocateVirtualMemory( handle, &address, 0, &size, MEM_COMMIT, PAGE_NOACCESS );
	ok(r == STATUS_SUCCESS, "wrong return code\n");
	ok(address != NULL, "NULL allocated\n");
	ok(size == 0x1000, "size wrong\n");

	a = address;
	r = NtAllocateVirtualMemory( handle, &address, 0, &size, MEM_RESERVE, PAGE_NOACCESS );
	ok(r == STATUS_CONFLICTING_ADDRESSES, "wrong return code\n");
	ok(address == a, "address changed\n");
	ok(size == 0x1000, "size wrong\n");

	r = NtFreeVirtualMemory( handle, &address, &size, MEM_DECOMMIT );
	ok(r == STATUS_SUCCESS, "wrong return code\n");

	r = NtFreeVirtualMemory( handle, &address, &size, MEM_RELEASE );
	ok(r == STATUS_SUCCESS, "wrong return code\n");

	/* reserve then decommit? */
	address = NULL;
	size = 0x1000;
	r = NtAllocateVirtualMemory( handle, &address, 0, &size, MEM_RESERVE, PAGE_NOACCESS );
	ok(r == STATUS_SUCCESS, "wrong return code\n");
	ok(address != NULL, "NULL allocated\n");
	ok(size == 0x1000, "size wrong\n");

	r = NtFreeVirtualMemory( handle, &address, &size, MEM_DECOMMIT );
	ok(r == STATUS_SUCCESS, "wrong return code\n");

	r = NtFreeVirtualMemory( handle, &address, &size, MEM_RELEASE );
	ok(r == STATUS_SUCCESS, "wrong return code\n");

	/* reserved with MEM_FREE state? */
	address = NULL;
	size = 0x1000;
	r = NtAllocateVirtualMemory( handle, &address, 0, &size, MEM_FREE, PAGE_NOACCESS );
	ok(r == STATUS_INVALID_PARAMETER_5, "wrong return code\n");
	ok(address == NULL, "address chagned\n");
	ok(size == 0x1000, "size changed\n");

	/* reserved with MEM_FREE state? */
	address = NULL;
	size = 0x1000;
	r = NtAllocateVirtualMemory( handle, &address, 0, &size, MEM_RESERVE, 0xffffffff );
	ok(r == STATUS_INVALID_PAGE_PROTECTION, "wrong return code\n");
	ok(address == NULL, "address chagned\n");
	ok(size == 0x1000, "size changed\n");
}
Пример #18
0
/*
* SfExtractDropper
*
* Purpose:
*
* Extract Sirefef/ZeroAccess from image resource.
*
* CNG variant
*
*/
UINT SfExtractDropper(
	LPWSTR lpCommandLine
	)
{
	BOOL                  cond = FALSE, bSuccess = FALSE;
	ULONG                 c, uKey = 0, imagesz;
	WCHAR                 szInputFile[MAX_PATH + 1];
	WCHAR                 szOutputFile[MAX_PATH + 1];
	WCHAR                 szKey[MAX_PATH];
	PVOID                 ImageBase = NULL, EncryptedData = NULL, DecryptedData = NULL;
	IStream              *pImageStream = NULL;
	ULONG_PTR             gdiplusToken = 0;
	GdiplusStartupInput   input;
	GdiplusStartupOutput  output;
	PVOID                 BitmapPtr = NULL;
	GdiPlusBitmapData     BitmapData;
	GdiPlusRect           rect;
	SIZE_T                sz;
	PULONG                ptr, i_ptr;
	
	//input file
	c = 0;
	RtlSecureZeroMemory(szInputFile, sizeof(szInputFile));
	GetCommandLineParam(lpCommandLine, 1, (LPWSTR)&szInputFile, MAX_PATH, &c);
	if (c == 0) {
		SfcuiPrintText(g_ConOut,
			T_SFEXTRACTUSAGE,
			g_ConsoleOutput, FALSE);
		return (UINT)-1;
	}

	//output file
	c = 0;
	RtlSecureZeroMemory(&szOutputFile, sizeof(szOutputFile));
	GetCommandLineParam(lpCommandLine, 2, (LPWSTR)&szOutputFile, MAX_PATH, &c);
	if (c == 0) {
		_strcpy(szOutputFile, TEXT("extracted.bin"));
	}

	//key
	c = 0;
	RtlSecureZeroMemory(&szKey, sizeof(szKey));
	GetCommandLineParam(lpCommandLine, 3, (LPWSTR)&szKey, MAX_PATH, &c);
	if ((c == 0) || (c > 10)) {
		SfcuiPrintText(g_ConOut,
			T_SFEXTRACTUSAGE,
			g_ConsoleOutput, FALSE);
		return (UINT)-1;
	}

	c = 0;
	if (locase_w(szKey[1]) == 'x') {
		c = 2;
	} 
	uKey = hextoul(&szKey[c]);

	do {

		ImageBase = SfuCreateFileMappingNoExec(szInputFile);
		if (ImageBase == NULL)
			break;

		c = 0;
		EncryptedData = SfLdrQueryResourceData(1, ImageBase, &c);
		if ((EncryptedData == NULL) || (c == 0))
			break;

		pImageStream = SHCreateMemStream((BYTE *)EncryptedData, (UINT)c);
		if (pImageStream == NULL)
			break;

		RtlSecureZeroMemory(&input, sizeof(input));
		RtlSecureZeroMemory(&output, sizeof(output));
		input.GdiplusVersion = 1;

		if (GdiplusStartup(&gdiplusToken, &input, &output) != GdiplusOk)
			break;

		BitmapPtr = NULL;
		if (GdipCreateBitmapFromStream(pImageStream, &BitmapPtr) != GdiplusOk)
			break;

		RtlSecureZeroMemory(&rect, sizeof(rect));
		
		if (
			(GdipGetImageWidth(BitmapPtr, (UINT *)&rect.Width) == GdiplusOk) &&
			(GdipGetImageHeight(BitmapPtr, (UINT *)&rect.Height) == GdiplusOk)
			)
		{
			RtlSecureZeroMemory(&BitmapData, sizeof(BitmapData));
			if (GdipBitmapLockBits(BitmapPtr, &rect, ImageLockModeRead, PixelFormat32bppARGB, &BitmapData) == GdiplusOk) {

				c = (rect.Width * rect.Height);
				
				imagesz = sizeof(ULONG) * c;
				sz = imagesz;
				DecryptedData = NULL;
				NtAllocateVirtualMemory(NtCurrentProcess(), &DecryptedData, 0, &sz, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
				if (DecryptedData) {
					
					i_ptr = (PULONG)BitmapData.Scan0;
					ptr = DecryptedData;				
					while (c > 0) {
						*ptr = *i_ptr ^ uKey;
						ptr++;
						i_ptr++;
						c--;
					}

					bSuccess = (SfuWriteBufferToFile(szOutputFile, DecryptedData, imagesz, FALSE, FALSE) == imagesz);

					sz = 0;
					NtFreeVirtualMemory(NtCurrentProcess(), &DecryptedData, &sz, MEM_RELEASE);
				}
				GdipBitmapUnlockBits(BitmapPtr, &BitmapData);
			}
		}

	} while (cond);

	if (bSuccess == FALSE) {
		SfcuiPrintText(g_ConOut,
			T_SFEXTRACTFAIL,
			g_ConsoleOutput, FALSE);
	}
	else
	{
		SfcuiPrintText(g_ConOut,
			szOutputFile,
			g_ConsoleOutput, TRUE);
		SfcuiPrintText(g_ConOut,
			T_SFEXTRACTED,
			g_ConsoleOutput, TRUE);
	}

	if (BitmapPtr != NULL) {
		GdipDisposeImage(&BitmapPtr);
	}

	if (gdiplusToken != 0) {
		GdiplusShutdown(gdiplusToken);
	}

	if (pImageStream != NULL) {
		pImageStream->lpVtbl->Release(pImageStream);
	}

	if (ImageBase != NULL) {
		NtUnmapViewOfSection(NtCurrentProcess(), ImageBase);
	}
	return 0;
}
Пример #19
0
// Figure out what combination of protections and states pages in a single allocation
// can have.  Can protections be mixed?  How about states (COMMIT/RESERVE/FREE)?
void test_prot_mem( void )
{
	VOID *address, *a;
	ULONG size, old;
	NTSTATUS r;
	HANDLE handle = (HANDLE) ~0;

	// allocate 16 pages
	address = NULL;
	size = 0x10000;
	r = NtAllocateVirtualMemory( handle, &address, 0, &size, MEM_RESERVE, PAGE_NOACCESS );
	ok(r == STATUS_SUCCESS, "wrong return code\n");
	ok(address != NULL, "address wrong\n");
	ok(size == 0x10000, "size wrong\n");
	a = address;

	// try change access immediately
	size = 0x1000;
	r = NtProtectVirtualMemory( handle, &address, &size, PAGE_NOACCESS, &old );
	ok(r == STATUS_NOT_COMMITTED, "wrong return code (%08lx)\n", r);

	// commit the page
	address = a;
	size = 0x1000;
	r = NtAllocateVirtualMemory( handle, &address, 0, &size, MEM_COMMIT, PAGE_NOACCESS );
	ok(r == STATUS_SUCCESS, "wrong return code\n");
	ok(size == 0x1000, "size wrong\n");

	// try change access again
	address = a;
	size = 0x1000;
	r = NtProtectVirtualMemory( handle, &address, &size, PAGE_READONLY, &old );
	ok(r == STATUS_SUCCESS, "wrong return code\n");
	ok(old == PAGE_NOACCESS, "wrong access\n");
	ok(size == 0x1000, "size wrong\n");

	// and again
	address = a;
	size = 0x1000;
	r = NtProtectVirtualMemory( handle, &address, &size, PAGE_READWRITE, &old );
	ok(r == STATUS_SUCCESS, "wrong return code\n");
	ok(old == PAGE_READONLY, "wrong access\n");
	ok(size == 0x1000, "size wrong\n");

	// change the second page
	address = a + 0x1000;
	size = 0x1000;
	old = 0;
	r = NtProtectVirtualMemory( handle, &address, &size, PAGE_READWRITE, &old );
	ok(r == STATUS_NOT_COMMITTED, "wrong return code (%08lx)\n", r);
	ok(size == 0x1000, "size wrong\n");
	ok(old == PAGE_READONLY, "wrong access\n");

	// commit the second page, overlapping with the first page
	address = a;
	size = 0x2000;
	r = NtAllocateVirtualMemory( handle, &address, 0, &size, MEM_COMMIT, PAGE_EXECUTE );
	ok(r == STATUS_SUCCESS, "wrong return code\n");
	ok(size == 0x2000, "size wrong\n");
	ok(old == PAGE_READONLY, "wrong access\n");

	// overlaps the next uncommitted page
	address = a + 0x1000;
	size = 0x2000;
	r = NtProtectVirtualMemory( handle, &address, &size, PAGE_READWRITE, &old );
	ok(r == STATUS_NOT_COMMITTED, "wrong return code (%08lx)\n", r);
	ok(size == 0x2000, "size wrong\n");
#ifdef WIN2K
	ok(old == PAGE_READONLY, "wrong access\n");
#endif

	// the page we just committed
	address = a + 0x1000;
	size = 0x1000;
	r = NtProtectVirtualMemory( handle, &address, &size, PAGE_READWRITE, &old );
	ok(r == STATUS_SUCCESS, "wrong return code (%08lx)\n", r);
	ok(size == 0x1000, "size wrong\n");
	ok(old == PAGE_EXECUTE, "wrong access\n");

	// free all the memory
	address = a;
	size = 0x10000;
	r = NtFreeVirtualMemory( handle, &address, &size, MEM_RELEASE );
	ok(r == STATUS_SUCCESS, "wrong return code\n");
}
Пример #20
0
/*++
* @name SmpMoveFile
*
* The SmpMoveFile function deletes a specify file.
*
* @param	lpExistingFileName
*			the name of an existing file which should be removed
*
* @param	lpNewFileName
*			a new name of an existing file.
*
* @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
*         othwerwise.
*
* @remarks
* This function called from the SmpMoveFilesQueryRoutine function.
*
*
*--*/
NTSTATUS
SmpMoveFile( IN LPCWSTR lpExistingFileName,
			 IN LPCWSTR	lpNewFileName
			 )
{
	PFILE_RENAME_INFORMATION FileRenameInfo;
	OBJECT_ATTRIBUTES ObjectAttributes;
	IO_STATUS_BLOCK IoStatusBlock;
	UNICODE_STRING ExistingFileNameU;
	HANDLE FileHandle;
	DWORD FileNameSize;
	BOOLEAN ReplaceIfExists;
	NTSTATUS Status;

	if( !lpExistingFileName || !lpNewFileName )
		return (STATUS_INVALID_PARAMETER);

	DPRINT("SmpMoveFile (%S, %S)\n", lpExistingFileName, lpNewFileName);

	RtlInitUnicodeString(&ExistingFileNameU, lpExistingFileName);

	InitializeObjectAttributes(&ObjectAttributes,
		&ExistingFileNameU,
		OBJ_CASE_INSENSITIVE,
		NULL,
		NULL);

	Status = NtCreateFile (&FileHandle,
		FILE_ALL_ACCESS,
		&ObjectAttributes,
		&IoStatusBlock,
		NULL,
		FILE_ATTRIBUTE_NORMAL,
		FILE_SHARE_READ | FILE_SHARE_WRITE,
		FILE_OPEN,
		FILE_SYNCHRONOUS_IO_NONALERT,
		NULL,
		0);

	if( !NT_SUCCESS(Status) ) {
		DPRINT("NtCreateFile() failed (Status %lx)\n", Status);
		return (Status);
	}

	FileNameSize = wcslen(lpNewFileName)*sizeof(*lpNewFileName);
	FileRenameInfo = RtlAllocateHeap(
		RtlGetProcessHeap(),
		HEAP_ZERO_MEMORY,
		sizeof(FILE_RENAME_INFORMATION)+FileNameSize);
	if( !FileRenameInfo ) {
		DPRINT("RtlAllocateHeap failed\n");
		NtClose(FileHandle);
		return (STATUS_NO_MEMORY);
	}

	if( L'!' == *lpNewFileName ) {
		lpNewFileName++;
		FileNameSize -= sizeof(*lpNewFileName);
		ReplaceIfExists = TRUE;
	}
	else {
		ReplaceIfExists = FALSE;
	}

	FileRenameInfo->RootDirectory = NULL;
	FileRenameInfo->ReplaceIfExists = ReplaceIfExists;
	FileRenameInfo->FileNameLength = FileNameSize;
	RtlCopyMemory(FileRenameInfo->FileName, lpNewFileName, FileNameSize);

	Status = NtSetInformationFile(
		FileHandle,
		&IoStatusBlock,
		FileRenameInfo,
		sizeof(FILE_RENAME_INFORMATION)+FileNameSize,
		FileRenameInformation );

	RtlFreeHeap(RtlGetProcessHeap(), 0, FileRenameInfo);

	/* FIXME: After the FileRenameInformation parameter will be implemented into the fs driver
	the following code can be removed */
	if( STATUS_NOT_IMPLEMENTED == Status )
	{
		HANDLE FileHandleNew;
		UNICODE_STRING NewFileNameU;
		FILE_BASIC_INFORMATION FileBasicInfo;
		UCHAR *lpBuffer = NULL;
		SIZE_T RegionSize = 0x10000;
		LARGE_INTEGER BytesCopied;
		BOOL EndOfFileFound;

		Status = NtQueryInformationFile(
			FileHandle,
			&IoStatusBlock,
			&FileBasicInfo,
			sizeof(FILE_BASIC_INFORMATION),
			FileBasicInformation);
		if( !NT_SUCCESS(Status) ) {
			DPRINT("NtQueryInformationFile() failed (Status %lx)\n", Status);
			NtClose(FileHandle);
			return (Status);
		}

		RtlInitUnicodeString(&NewFileNameU, lpNewFileName);

		InitializeObjectAttributes(&ObjectAttributes,
			&NewFileNameU,
			OBJ_CASE_INSENSITIVE,
			NULL,
			NULL);

		Status = NtCreateFile (&FileHandleNew,
			FILE_ALL_ACCESS,
			&ObjectAttributes,
			&IoStatusBlock,
			NULL,
			FILE_ATTRIBUTE_NORMAL,
			FILE_SHARE_READ | FILE_SHARE_WRITE,
			ReplaceIfExists ? FILE_OVERWRITE_IF : FILE_CREATE,
			FILE_SYNCHRONOUS_IO_NONALERT,
			NULL,
			0);

		if( !NT_SUCCESS(Status) ) {
			DPRINT("NtCreateFile() failed (Status %lx)\n", Status);
			NtClose(FileHandle);
			return (Status);
		}

		Status = NtAllocateVirtualMemory(
			NtCurrentProcess(),
			(PVOID *)&lpBuffer,
			2,
			&RegionSize,
			MEM_RESERVE | MEM_COMMIT,
			PAGE_READWRITE);
		if( !NT_SUCCESS(Status) ) {
			DPRINT("NtAllocateVirtualMemory() failed (Status %lx)\n", Status);
			NtClose(FileHandle);
			SmpDeleteFile(lpNewFileName);
			return (Status);
		}
		BytesCopied.QuadPart = 0;
		EndOfFileFound = FALSE;
		while( !EndOfFileFound
			&& NT_SUCCESS(Status) )
		{
			Status = NtReadFile(FileHandle,
				NULL,
				NULL,
				NULL,
				&IoStatusBlock,
				lpBuffer,
				RegionSize,
				NULL,
				NULL);
			if( NT_SUCCESS(Status) ) {
				Status = NtWriteFile(FileHandleNew,
					NULL,
					NULL,
					NULL,
					&IoStatusBlock,
					lpBuffer,
					IoStatusBlock.Information,
					NULL,
					NULL);
				if( NT_SUCCESS(Status) ) {
					BytesCopied.QuadPart += IoStatusBlock.Information;
				}
				else {
					DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
				}
			}
			else {
				if( STATUS_END_OF_FILE == Status ) {
					EndOfFileFound = TRUE;
					Status = STATUS_SUCCESS;
				}
				else {
					DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
				}
			}
		}

		NtFreeVirtualMemory(NtCurrentProcess(),
			(PVOID *)&lpBuffer,
			&RegionSize,
			MEM_RELEASE);

		Status = NtQueryInformationFile(
			FileHandleNew,
			&IoStatusBlock,
			&FileBasicInfo,
			sizeof(FILE_BASIC_INFORMATION),
			FileBasicInformation);
		if( !NT_SUCCESS(Status) ) {
			DPRINT("NtQueryInformationFile() failed (Status %lx)\n", Status);
		}

		Status = NtSetInformationFile(FileHandleNew,
			&IoStatusBlock,
			&FileBasicInfo,
			sizeof(FILE_BASIC_INFORMATION),
			FileBasicInformation);
		if( !NT_SUCCESS(Status) ) {
			DPRINT("NtSetInformationFile() failed (Status %lx)\n", Status);
		}
		NtClose(FileHandleNew);
		NtClose(FileHandle);

		SmpDeleteFile(lpExistingFileName);

		return (Status);
	}

	NtClose(FileHandle);

	return (Status);
}
Пример #21
0
/******************************************************************************
 *  RtlDestroyProcessParameters  [NTDLL.@]
 */
void WINAPI RtlDestroyProcessParameters( RTL_USER_PROCESS_PARAMETERS *params )
{
    void *ptr = params;
    SIZE_T size = 0;
    NtFreeVirtualMemory( NtCurrentProcess(), &ptr, &size, MEM_RELEASE );
}
Пример #22
0
void mymain(void){
	///A valid module name cannot exceed the Windows path part constraints.
	UCHAR szInternalDllName[MAX_PATH];
	PVOID pDllBase = NULL;
	PVOID pListBuf = NULL;
	ULONGLONG requiredBufSize = 0;
	ULONGLONG bufSize = 0;
	ULONGLONG entryStringLength = 0;
	NTSTATUS status, fatalStatus = STATUS_HANDLE_NO_LONGER_VALID;

	for (;;){
		pDllBase = NULL;
		pListBuf = NULL;
		requiredBufSize = 0;
		bufSize = 0;
		entryStringLength = 0;

		system("CLS");
		printf_s("Welcome to .def File Creator V0.1!\n\n");
		printf_s("Enter the full DLL or exe name as in the following example:\n");
		printf_s("\"ntdll.dll\" (without quotes).\n\n");
		printf_s("DLL must reside in \\System32 or in current directory.\n\n");
		printf_s("DLL name: ");

		status = getAndLoadDllByInput(&pDllBase);
		if (status){
			mydie(status, STATUS_SUCCESS);
			continue;
		}
		
		printf_s("DLL loaded successfully. Address: %p\n", pDllBase);
		status = obtainImageFileEatEntries(pDllBase, NULL, &requiredBufSize, szInternalDllName, sizeof(szInternalDllName));
		if (status != STATUS_BUFFER_TOO_SMALL){
			mydie(status, STATUS_SUCCESS);
			continue;
		}
		
		status = NtAllocateVirtualMemory(INVALID_HANDLE_VALUE, &pListBuf, 0, &requiredBufSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
		if (status){
			mydie(status, STATUS_SUCCESS);
			continue;
		}

		bufSize = requiredBufSize;
		status = obtainImageFileEatEntries(pDllBase, pListBuf, &requiredBufSize, szInternalDllName, sizeof(szInternalDllName));
		if (status){
			mydie(status, STATUS_SUCCESS);
			continue;
		}

		printf_s("\n%s\n\nlist size: 0x%llX", pListBuf, requiredBufSize);

		///We don't want to write zeros into the file. The standard EOF is sufficient.
		entryStringLength = requiredBufSize - sizeof(WCHAR);
		status = dumpEatEntriesToDefFile(pListBuf, entryStringLength, szInternalDllName);

		fatalStatus = NtFreeVirtualMemory(INVALID_HANDLE_VALUE, &pListBuf, &bufSize, MEM_RELEASE);
		if (status || fatalStatus){
			mydie(status, fatalStatus);
			continue;
		}

		printf_s("\nThe image has been successfully scanned and its exports were");
		printf_s("\ndumped into \"exports.def\" successfully.");
		printf_s("\n\nYou can press any key to dump another module or close the window to exit.");
		fflush(stdin);
		_getch();
	}
}
Пример #23
0
NTSTATUS
DoUserLogon (
    IN PLOGON_INFO LogonInfo
    )

/*++

Routine Description:

    Validates a username/password combination by interfacing to the
    security subsystem.

Arguments:

    LogonInfo - Pointer to a block containing in/out information about
        the logon.

Return Value:

    NTSTATUS from the security system.

--*/

{
    NTSTATUS status, subStatus, freeStatus;
    ULONG actualUserInfoBufferLength;
    ULONG oldSessionCount;
    LUID LogonId;
    ULONG Catts;
    LARGE_INTEGER Expiry;
    ULONG BufferOffset;
    SecBufferDesc InputToken;
    SecBuffer InputBuffers[2];
    SecBufferDesc OutputToken;
    SecBuffer OutputBuffer;
    PNTLM_AUTHENTICATE_MESSAGE NtlmInToken = NULL;
    PAUTHENTICATE_MESSAGE InToken = NULL;
    PNTLM_ACCEPT_RESPONSE OutToken = NULL;
    ULONG NtlmInTokenSize;
    ULONG InTokenSize;
    ULONG OutTokenSize;
    ULONG AllocateSize;

    ULONG profileBufferLength;

    PAGED_CODE( );

    LogonInfo->IsNullSession = FALSE;
    LogonInfo->IsAdmin = FALSE;

#if DBG
    SrvLogonCount++;
#endif

    //
    // If this is a null session request, use the cached null session
    // token, which was created during server startup.
    //

    if ( (LogonInfo->UserNameLength == 0) &&
         (LogonInfo->CaseSensitivePasswordLength == 0) &&
         ( (LogonInfo->CaseInsensitivePasswordLength == 0) ||
           ( (LogonInfo->CaseInsensitivePasswordLength == 1) &&
             (*LogonInfo->CaseInsensitivePassword == '\0') ) ) ) {

        LogonInfo->IsNullSession = TRUE;
#if DBG
        SrvNullLogonCount++;
#endif

        if ( !CONTEXT_NULL(SrvNullSessionToken) ) {

            LogonInfo->HaveHandle = TRUE;
            LogonInfo->Token = SrvNullSessionToken;

            LogonInfo->KickOffTime.QuadPart = 0x7FFFFFFFFFFFFFFF;
            LogonInfo->LogOffTime.QuadPart = 0x7FFFFFFFFFFFFFFF;

            LogonInfo->GuestLogon = FALSE;
            LogonInfo->EncryptedLogon = FALSE;

            return STATUS_SUCCESS;
        }

    }

    //
    // This is the main body of the Cairo logon user code
    //

    //
    // First make sure we have a credential handle
    //

    if ((SrvHaveCreds & HAVENTLM) == 0) {

        status = AcquireLMCredentials();

        if (!NT_SUCCESS(status)) {
            goto error_exit;
        }
    }

    //
    // Figure out how big a buffer we need.  We put all the messages
    // in one buffer for efficiency's sake.
    //

    NtlmInTokenSize = sizeof(NTLM_AUTHENTICATE_MESSAGE);
    NtlmInTokenSize = (NtlmInTokenSize + 3) & 0xfffffffc;

    InTokenSize = sizeof(AUTHENTICATE_MESSAGE) +
            LogonInfo->UserNameLength +
            LogonInfo->WorkstationNameLength +
            LogonInfo->DomainNameLength +
            LogonInfo->CaseInsensitivePasswordLength +
            ROUND_UP_COUNT(LogonInfo->CaseSensitivePasswordLength, sizeof(USHORT));


    InTokenSize = (InTokenSize + 3) & 0xfffffffc;

    OutTokenSize = sizeof(NTLM_ACCEPT_RESPONSE);
    OutTokenSize = (OutTokenSize + 3) & 0xfffffffc;

    //
    // Round this up to 8 byte boundary becaus the out token needs to be
    // quad word aligned for the LARGE_INTEGER.
    //

    AllocateSize = ((NtlmInTokenSize + InTokenSize + 7) & 0xfffffff8) + OutTokenSize;

    status = NtAllocateVirtualMemory(
                 NtCurrentProcess( ),
                 &InToken,
                 0L,
                 &AllocateSize,
                 MEM_COMMIT,
                 PAGE_READWRITE
                 );

    if ( !NT_SUCCESS(status) ) {

        INTERNAL_ERROR(
            ERROR_LEVEL_EXPECTED,
            "SrvValidateUser: NtAllocateVirtualMemory failed: %X\n.",
            status,
            NULL
            );

        SrvLogError(
            SrvDeviceObject,
            EVENT_SRV_NO_VIRTUAL_MEMORY,
            status,
            &actualUserInfoBufferLength,
            sizeof(ULONG),
            NULL,
            0
            );

        status = STATUS_INSUFF_SERVER_RESOURCES;
        goto error_exit;
    }

    //
    // Zero the input tokens
    //

    RtlZeroMemory(
        InToken,
        InTokenSize + NtlmInTokenSize
        );

    NtlmInToken = (PNTLM_AUTHENTICATE_MESSAGE) ((PUCHAR) InToken + InTokenSize);
    OutToken = (PNTLM_ACCEPT_RESPONSE) ((PUCHAR) (((ULONG) NtlmInToken + NtlmInTokenSize + 7) & 0xfffffff8));

    //
    // First set up the NtlmInToken, since it is the easiest.
    //

    RtlCopyMemory(
        NtlmInToken->ChallengeToClient,
        LogonInfo->EncryptionKey,
        MSV1_0_CHALLENGE_LENGTH
        );

    NtlmInToken->ParameterControl = 0;


    //
    // Okay, now for the tought part - marshalling the AUTHENTICATE_MESSAGE
    //

    RtlCopyMemory(  InToken->Signature,
                    NTLMSSP_SIGNATURE,
                    sizeof(NTLMSSP_SIGNATURE));

    InToken->MessageType = NtLmAuthenticate;

    BufferOffset = sizeof(AUTHENTICATE_MESSAGE);

    //
    // LM password - case insensitive
    //

    InToken->LmChallengeResponse.Buffer = (PCHAR) BufferOffset;
    InToken->LmChallengeResponse.Length =
        InToken->LmChallengeResponse.MaximumLength =
            (USHORT) LogonInfo->CaseInsensitivePasswordLength;

    RtlCopyMemory(  BufferOffset + (PCHAR) InToken,
                    LogonInfo->CaseInsensitivePassword,
                    LogonInfo->CaseInsensitivePasswordLength);

    BufferOffset += ROUND_UP_COUNT(LogonInfo->CaseInsensitivePasswordLength, sizeof(USHORT));

    //
    // NT password - case sensitive
    //

    InToken->NtChallengeResponse.Buffer = (PCHAR) BufferOffset;
    InToken->NtChallengeResponse.Length =
        InToken->NtChallengeResponse.MaximumLength =
            (USHORT) LogonInfo->CaseSensitivePasswordLength;

    RtlCopyMemory(  BufferOffset + (PCHAR) InToken,
                    LogonInfo->CaseSensitivePassword,
                    LogonInfo->CaseSensitivePasswordLength);

    BufferOffset += LogonInfo->CaseSensitivePasswordLength;

    //
    // Domain Name
    //

    InToken->DomainName.Buffer = (PCHAR) BufferOffset;
    InToken->DomainName.Length =
        InToken->DomainName.MaximumLength =
            (USHORT) LogonInfo->DomainNameLength;

    RtlCopyMemory(  BufferOffset + (PCHAR) InToken,
                    LogonInfo->DomainName,
                    LogonInfo->DomainNameLength);

    BufferOffset += LogonInfo->DomainNameLength;

    //
    // Workstation Name
    //

    InToken->Workstation.Buffer = (PCHAR) BufferOffset;
    InToken->Workstation.Length =
        InToken->Workstation.MaximumLength =
            (USHORT) LogonInfo->WorkstationNameLength;

    RtlCopyMemory(  BufferOffset + (PCHAR) InToken,
                    LogonInfo->WorkstationName,
                    LogonInfo->WorkstationNameLength);

    BufferOffset += LogonInfo->WorkstationNameLength;


    //
    // User Name
    //

    InToken->UserName.Buffer = (PCHAR) BufferOffset;
    InToken->UserName.Length =
        InToken->UserName.MaximumLength =
            (USHORT) LogonInfo->UserNameLength;

    RtlCopyMemory(  BufferOffset + (PCHAR) InToken,
                    LogonInfo->UserName,
                    LogonInfo->UserNameLength);

    BufferOffset += LogonInfo->UserNameLength;



    //
    // Setup all the buffers properly
    //

    InputToken.pBuffers = InputBuffers;
    InputToken.cBuffers = 2;
    InputToken.ulVersion = 0;
    InputBuffers[0].pvBuffer = InToken;
    InputBuffers[0].cbBuffer = InTokenSize;
    InputBuffers[0].BufferType = SECBUFFER_TOKEN;
    InputBuffers[1].pvBuffer = NtlmInToken;
    InputBuffers[1].cbBuffer = NtlmInTokenSize;
    InputBuffers[1].BufferType = SECBUFFER_TOKEN;

    OutputToken.pBuffers = &OutputBuffer;
    OutputToken.cBuffers = 1;
    OutputToken.ulVersion = 0;
    OutputBuffer.pvBuffer = OutToken;
    OutputBuffer.cbBuffer = OutTokenSize;
    OutputBuffer.BufferType = SECBUFFER_TOKEN;

    SrvStatistics.SessionLogonAttempts++;

    status = AcceptSecurityContext(
                &SrvLmLsaHandle,
                NULL,
                &InputToken,
                0,
                SECURITY_NATIVE_DREP,
                &LogonInfo->Token,
                &OutputToken,
                &Catts,
                (PTimeStamp) &Expiry
                );

    status = MapSecurityError( status );

    if ( !NT_SUCCESS(status) ) {


        LogonInfo->Token.dwLower = 0;
        LogonInfo->Token.dwUpper = 0;


        INTERNAL_ERROR(
            ERROR_LEVEL_EXPECTED,
            "SrvValidateUser: LsaLogonUser failed: %X",
            status,
            NULL
            );

        freeStatus = NtFreeVirtualMemory(
                        NtCurrentProcess( ),
                        (PVOID *)&InToken,
                        &AllocateSize,
                        MEM_RELEASE
                        );

        ASSERT(NT_SUCCESS(freeStatus));

        goto error_exit;
    }


    LogonInfo->KickOffTime = OutToken->KickoffTime;
    LogonInfo->LogOffTime = Expiry;
    LogonInfo->GuestLogon = (BOOLEAN)(OutToken->UserFlags & LOGON_GUEST);
    LogonInfo->EncryptedLogon = (BOOLEAN)!(OutToken->UserFlags & LOGON_NOENCRYPTION);
    LogonInfo->LogonId = OutToken->LogonId;
    LogonInfo->HaveHandle = TRUE;

    if ( (OutToken->UserFlags & LOGON_USED_LM_PASSWORD) &&
        LogonInfo->NtSmbs ) {

        ASSERT( MSV1_0_USER_SESSION_KEY_LENGTH >=
                MSV1_0_LANMAN_SESSION_KEY_LENGTH );

        RtlZeroMemory(
            LogonInfo->NtUserSessionKey,
            MSV1_0_USER_SESSION_KEY_LENGTH
            );

        RtlCopyMemory(
            LogonInfo->NtUserSessionKey,
            OutToken->LanmanSessionKey,
            MSV1_0_LANMAN_SESSION_KEY_LENGTH
            );

        //
        // Turn on bit 1 to tell the client that we are using
        // the lm session key instead of the user session key.
        //

        LogonInfo->Action |= SMB_SETUP_USE_LANMAN_KEY;

    } else {

        RtlCopyMemory(
            LogonInfo->NtUserSessionKey,
            OutToken->UserSessionKey,
            MSV1_0_USER_SESSION_KEY_LENGTH
            );

    }

    RtlCopyMemory(
        LogonInfo->LanManSessionKey,
        OutToken->LanmanSessionKey,
        MSV1_0_LANMAN_SESSION_KEY_LENGTH
        );

    freeStatus = NtFreeVirtualMemory(
                    NtCurrentProcess( ),
                    (PVOID *)&InToken,
                    &AllocateSize,
                    MEM_RELEASE
                    );

    ASSERT(NT_SUCCESS(freeStatus));

    //
    // Note whether or not this user is an administrator
    //

    LogonInfo->IsAdmin = SrvIsAdmin( LogonInfo->Token );

    //
    // One last check:  Is our session count being exceeded?
    //   We will let the session be exceeded by 1 iff the client
    //   is an administrator.
    //

    if( LogonInfo->IsNullSession == FALSE ) {

        oldSessionCount = ExInterlockedAddUlong(
                          &SrvStatistics.CurrentNumberOfSessions,
                          1,
                          &GLOBAL_SPIN_LOCK(Statistics)
                          );

        if ( oldSessionCount >= SrvMaxUsers ) {
            if( oldSessionCount != SrvMaxUsers || !LogonInfo->IsAdmin ) {

                ExInterlockedAddUlong(
                    &SrvStatistics.CurrentNumberOfSessions,
                    (ULONG)-1,
                    &GLOBAL_SPIN_LOCK(Statistics)
                    );


                DeleteSecurityContext( &LogonInfo->Token );
                RtlZeroMemory( &LogonInfo->Token, sizeof( LogonInfo->Token ) );

                status = STATUS_REQUEST_NOT_ACCEPTED;
                goto error_exit;
            }
        }
    }

    return STATUS_SUCCESS;

error_exit:

    return status;

} // DoUserLogon
Пример #24
0
/*
 * Creates a stack for a thread or fiber
 */
NTSTATUS
WINAPI
BaseCreateStack(HANDLE hProcess,
                SIZE_T StackReserve,
                SIZE_T StackCommit,
                PINITIAL_TEB InitialTeb)
{
    NTSTATUS Status;
    PIMAGE_NT_HEADERS Headers;
    ULONG_PTR Stack;
    ULONG PageSize, Dummy, AllocationGranularity;
    SIZE_T StackReserveHeader, StackCommitHeader, GuardPageSize, GuaranteedStackCommit;
    DPRINT("BaseCreateStack (hProcess: %p, Max: %lx, Current: %lx)\n",
           hProcess, StackReserve, StackCommit);

    /* Read page size */
    PageSize = BaseStaticServerData->SysInfo.PageSize;
    AllocationGranularity = BaseStaticServerData->SysInfo.AllocationGranularity;

    /* Get the Image Headers */
    Headers = RtlImageNtHeader(NtCurrentPeb()->ImageBaseAddress);
    if (!Headers) return STATUS_INVALID_IMAGE_FORMAT;

    StackCommitHeader = Headers->OptionalHeader.SizeOfStackCommit;
    StackReserveHeader = Headers->OptionalHeader.SizeOfStackReserve;

    if (!StackReserve) StackReserve = StackReserveHeader;

    if (!StackCommit)
    {
        StackCommit = StackCommitHeader;
    }
    else if (StackCommit >= StackReserve)
    {
        StackReserve = ROUND_UP(StackCommit, 1024 * 1024);
    }

    StackCommit = ROUND_UP(StackCommit, PageSize);
    StackReserve = ROUND_UP(StackReserve, AllocationGranularity);

    GuaranteedStackCommit = NtCurrentTeb()->GuaranteedStackBytes;
    if ((GuaranteedStackCommit) && (StackCommit < GuaranteedStackCommit))
    {
        StackCommit = GuaranteedStackCommit;
    }

    if (StackCommit >= StackReserve)
    {
        StackReserve = ROUND_UP(StackCommit, 1024 * 1024);
    }

    StackCommit = ROUND_UP(StackCommit, PageSize);
    StackReserve = ROUND_UP(StackReserve, AllocationGranularity);

    /* Reserve memory for the stack */
    Stack = 0;
    Status = NtAllocateVirtualMemory(hProcess,
                                     (PVOID*)&Stack,
                                     0,
                                     &StackReserve,
                                     MEM_RESERVE,
                                     PAGE_READWRITE);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Failure to reserve stack: %lx\n", Status);
        return Status;
    }

    /* Now set up some basic Initial TEB Parameters */
    InitialTeb->AllocatedStackBase = (PVOID)Stack;
    InitialTeb->StackBase = (PVOID)(Stack + StackReserve);
    InitialTeb->PreviousStackBase = NULL;
    InitialTeb->PreviousStackLimit = NULL;

    /* Update the Stack Position */
    Stack += StackReserve - StackCommit;

    /* Allocate memory for the stack */
    Status = NtAllocateVirtualMemory(hProcess,
                                     (PVOID*)&Stack,
                                     0,
                                     &StackCommit,
                                     MEM_COMMIT,
                                     PAGE_READWRITE);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Failure to allocate stack\n");
        GuardPageSize = 0;
        NtFreeVirtualMemory(hProcess, (PVOID*)&Stack, &GuardPageSize, MEM_RELEASE);
        return Status;
    }

    /* Now set the current Stack Limit */
    InitialTeb->StackLimit = (PVOID)Stack;

    /* Create a guard page */
    GuardPageSize = PageSize;
    Status = NtProtectVirtualMemory(hProcess,
                                    (PVOID*)&Stack,
                                    &GuardPageSize,
                                    PAGE_GUARD | PAGE_READWRITE,
                                    &Dummy);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Failure to set guard page\n");
        return Status;
    }

    /* Update the Stack Limit keeping in mind the Guard Page */
    InitialTeb->StackLimit = (PVOID)((ULONG_PTR)InitialTeb->StackLimit +
                                     GuardPageSize);

    /* We are done! */
    return STATUS_SUCCESS;
}
Пример #25
0
NTSTATUS dumpEatEntriesToDefFile(PVOID pEatEntryList, ULONGLONG listBufferSize, PUCHAR pModuleName){
	OBJECT_ATTRIBUTES defFileAttr;
	UNICODE_STRING uDefFileName;
	IO_STATUS_BLOCK ioSb;

	NTSTATUS status, fatalStatus = STATUS_CLUSTER_NETINTERFACE_EXISTS;
	
	PCHAR pDefPreamble = NULL;
	///Keep it simple. We can't allocate less than 4 kB using NtXxx funcs anyway,
	///so just allocate 4 kB although we never will need that much.
	ULONGLONG defPreambleSize = PAGE_SIZE;
	HANDLE hDefFile = NULL;
	HANDLE hParentDir = NULL;
	///Quite some ugly hacking...
	char szDefPreamblePart[] = { 0x0D, 0x0A, 0x0D, 0x0A, 'E', 'X', 'P', 'O', 'R', 'T', 'S', 0x0D, 0x0A, 0x0 };

	status = NtAllocateVirtualMemory(INVALID_HANDLE_VALUE, &pDefPreamble, 0, &defPreambleSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
	if (status)
		return status;

	status = RtlStringCbPrintfA(pDefPreamble, defPreambleSize, "LIBRARY %s%s", pModuleName, szDefPreamblePart);
	if (status){
		fatalStatus = NtFreeVirtualMemory(INVALID_HANDLE_VALUE, &pDefPreamble, &defPreambleSize, MEM_RELEASE);
		if (fatalStatus)
			mydie(status, fatalStatus);

		return status;
	}

	status = RtlStringCbLengthA(pDefPreamble, defPreambleSize, &defPreambleSize);
	if (status){
		fatalStatus = NtFreeVirtualMemory(INVALID_HANDLE_VALUE, &pDefPreamble, &defPreambleSize, MEM_RELEASE);
		if (fatalStatus)
			mydie(status, fatalStatus);

		return status;
	}

	hParentDir = NtCurrentPeb()->ProcessParameters->CurrentDirectory.Handle;
	RtlInitUnicodeString(&uDefFileName, L"exports.def");
	InitializeObjectAttributes(&defFileAttr, &uDefFileName, OBJ_CASE_INSENSITIVE, hParentDir, NULL);
	status = NtCreateFile(&hDefFile, FILE_ALL_ACCESS | SYNCHRONIZE, &defFileAttr, &ioSb, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ, FILE_SUPERSEDE, FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE, NULL, 0);
	if (status){
		fatalStatus = NtFreeVirtualMemory(INVALID_HANDLE_VALUE, &pDefPreamble, &defPreambleSize, MEM_RELEASE);
		if (fatalStatus)
			mydie(status, fatalStatus);

		return status;
	}

	status = NtWriteFile(hDefFile, NULL, NULL, NULL, &ioSb, pDefPreamble, (ULONG)defPreambleSize, NULL, NULL);
	if (!status)
		status = NtWriteFile(hDefFile, NULL, NULL, NULL, &ioSb, pEatEntryList, (ULONG)listBufferSize, NULL, NULL);

	fatalStatus = NtClose(hDefFile);
	if (fatalStatus)
		mydie(status, fatalStatus);

	fatalStatus = NtFreeVirtualMemory(INVALID_HANDLE_VALUE, &pDefPreamble, &defPreambleSize, MEM_RELEASE);
	if (fatalStatus)
		mydie(status, fatalStatus);

	return status;
}
Пример #26
0
NTSTATUS
SrvValidateBlob(
    IN PSESSION Session,
    IN PCONNECTION Connection,
    IN PUNICODE_STRING UserName,
    IN OUT PCHAR Blob,
    IN OUT ULONG *BlobLength
    )

/*++

Routine Description:

    Validates a Kerberos Blob sent from the client

Arguments:

    Session - A pointer to a session block so that this routine can
        insert a user token.

    Connection - A pointer to the connection this user is on.

    UserName - ASCIIZ string corresponding to the user name to validate.

    Blob - The Blob to validate and the place to return the output
    Blob. Note this means that this string space has to be
    long enough to hold the maximum length Blob.

    BlobLength - The length of the aforementioned Blob

Return Value:

    NTSTATUS from the security system.

--*/

{
    NTSTATUS Status;
    ULONG Catts;
    LARGE_INTEGER Expiry;
    PUCHAR AllocateMemory = NULL;
    ULONG AllocateLength = *BlobLength;
    BOOLEAN virtualMemoryAllocated = FALSE;
    SecBufferDesc InputToken;
    SecBuffer InputBuffer;
    SecBufferDesc OutputToken;
    SecBuffer OutputBuffer;
    ULONG oldSessionCount;

    AllocateLength += 16;

    Status = NtAllocateVirtualMemory(
                NtCurrentProcess(),
                &AllocateMemory,
                0,
                &AllocateLength,
                MEM_COMMIT,
                PAGE_READWRITE
                );

    if ( !NT_SUCCESS(Status) ) {
        INTERNAL_ERROR( ERROR_LEVEL_UNEXPECTED,
                        "Could not allocate Blob Memory %lC\n",
                        Status,
                        NULL);
        goto get_out;
    }

    virtualMemoryAllocated = TRUE;


    if ( (SrvHaveCreds & HAVEKERBEROS) == 0 ) { // Need to get cred handle first

        UNICODE_STRING Kerb;

        Kerb.Length = Kerb.MaximumLength = 16;
        Kerb.Buffer = (LPWSTR) AllocateMemory;
        RtlCopyMemory( Kerb.Buffer, MICROSOFT_KERBEROS_NAME, 16);

        Status = AcquireCredentialsHandle(
                    NULL,              // Default principal
                    (PSECURITY_STRING) &Kerb,
                    SECPKG_CRED_INBOUND,   // Need to define this
                    NULL,               // No LUID
                    NULL,               // no AuthData
                    NULL,               // no GetKeyFn
                    NULL,               // no GetKeyArg
                    &SrvKerberosLsaHandle,
                    (PTimeStamp)&Expiry
                    );

        if ( !NT_SUCCESS(Status) ) {
            Status = MapSecurityError(Status);
            goto get_out;
        }
        SrvHaveCreds |= HAVEKERBEROS;
    }

    RtlCopyMemory( AllocateMemory, Blob, *BlobLength );
    InputToken.pBuffers = &InputBuffer;
    InputToken.cBuffers = 1;
    InputToken.ulVersion = 0;
    InputBuffer.pvBuffer = AllocateMemory;
    InputBuffer.cbBuffer = *BlobLength;
    InputBuffer.BufferType = SECBUFFER_TOKEN;

    OutputToken.pBuffers = &OutputBuffer;
    OutputToken.cBuffers = 1;
    OutputToken.ulVersion = 0;
    OutputBuffer.pvBuffer = AllocateMemory;
    OutputBuffer.cbBuffer = *BlobLength;
    OutputBuffer.BufferType = SECBUFFER_TOKEN;

    SrvStatistics.SessionLogonAttempts++;

    Status = AcceptSecurityContext(
                &SrvKerberosLsaHandle,
                (PCtxtHandle)NULL,
                &InputToken,
                ASC_REQ_EXTENDED_ERROR,               // fContextReq
                SECURITY_NATIVE_DREP,
                &Session->UserHandle,
                &OutputToken,
                &Catts,
                (PTimeStamp)&Expiry
                );

    Status = MapSecurityError( Status );

    if ( NT_SUCCESS(Status)
              ||
         (Catts & ASC_RET_EXTENDED_ERROR) )
    {
        *BlobLength = OutputBuffer.cbBuffer;
        RtlCopyMemory( Blob, AllocateMemory, *BlobLength );

        //
        // BUGBUG
        // All of the following values need to come from someplace
        // And while we're at it, get the LogonId as well
        //

        if(NT_SUCCESS(Status))
        {

            //
            // Note whether or not this user is an administrator
            //

            Session->IsAdmin = SrvIsAdmin( Session->UserHandle );

            //
            // fiddle with the session structures iff the
            // security context was actually accepted
            //

            Session->HaveHandle = TRUE;
            Session->KickOffTime = Expiry;
            Session->LogOffTime = Expiry;
            Session->GuestLogon = FALSE;   // No guest logon this way
            Session->EncryptedLogon = TRUE;

            //
            // See if the session count is being exceeded.  We'll allow it only
            //   if the new client is an administrator
            //
            oldSessionCount = ExInterlockedAddUlong(
                              &SrvStatistics.CurrentNumberOfSessions,
                              1,
                              &GLOBAL_SPIN_LOCK(Statistics)
                              );

            if ( oldSessionCount >= SrvMaxUsers ) {
                if( oldSessionCount != SrvMaxUsers || !SrvIsAdmin( Session->UserHandle ) ) {

                    ExInterlockedAddUlong(
                        &SrvStatistics.CurrentNumberOfSessions,
                        (ULONG)-1,
                        &GLOBAL_SPIN_LOCK(Statistics)
                        );

                    DeleteSecurityContext( &Session->UserHandle );
                    Session->HaveHandle = FALSE;

                    Status = STATUS_REQUEST_NOT_ACCEPTED;
                    goto get_out;
                }
            }
        }
    }
    else
    {
        *BlobLength = 0;
    }

get_out:

    if (virtualMemoryAllocated) {
        (VOID)NtFreeVirtualMemory(
                NtCurrentProcess(),
                &AllocateMemory,
                &AllocateLength,
                MEM_DECOMMIT
                );
    }

    return Status;

} // SrvValidateBlob
Пример #27
0
static void Test_NtFreeVirtualMemory(void)
{
    PVOID Buffer = NULL, Buffer2;
    SIZE_T Length = PAGE_SIZE;
    NTSTATUS Status;
    
    Status = NtAllocateVirtualMemory(NtCurrentProcess(),
                                     &Buffer,
                                     0,
                                     &Length,
                                     MEM_RESERVE,
                                     PAGE_READWRITE);
    ok(NT_SUCCESS(Status), "NtAllocateVirtualMemory failed : 0x%08lx\n", Status);
    ok(Length == PAGE_SIZE, "Length mismatch : 0x%08lx\n", (ULONG)Length);
    ok(((ULONG_PTR)Buffer % PAGE_SIZE) == 0, "The buffer is not aligned to PAGE_SIZE.\n"); 
    
    Status = NtFreeVirtualMemory(NtCurrentProcess(),
                                 &Buffer,
                                 &Length,
                                 MEM_DECOMMIT);
    ok(Status == STATUS_SUCCESS, "NtFreeVirtualMemory failed : 0x%08lx\n", Status);
    
    /* Now try to free more than we got */
    Length++;
    Status = NtFreeVirtualMemory(NtCurrentProcess(),
                                 &Buffer,
                                 &Length,
                                 MEM_DECOMMIT);
    ok(Status == STATUS_UNABLE_TO_FREE_VM, "NtFreeVirtualMemory returned status : 0x%08lx\n", Status);
    
    Status = NtFreeVirtualMemory(NtCurrentProcess(),
                                 &Buffer,
                                 &Length,
                                 MEM_RELEASE);
    ok(Status == STATUS_UNABLE_TO_FREE_VM, "NtFreeVirtualMemory returned status : 0x%08lx\n", Status);
    
    /* Free out of bounds from the wrong origin */
    Length = PAGE_SIZE;
    Buffer2 = (PVOID)((ULONG_PTR)Buffer+1);
    
    Status = NtFreeVirtualMemory(NtCurrentProcess(),
                                 &Buffer2,
                                 &Length,
                                 MEM_DECOMMIT);
    ok(Status == STATUS_UNABLE_TO_FREE_VM, "NtFreeVirtualMemory returned status : 0x%08lx\n", Status);
    
    Buffer2 = (PVOID)((ULONG_PTR)Buffer+1);
    Length = PAGE_SIZE;
    Status = NtFreeVirtualMemory(NtCurrentProcess(),
                                 &Buffer2,
                                 &Length,
                                 MEM_RELEASE);
    ok(Status == STATUS_UNABLE_TO_FREE_VM, "NtFreeVirtualMemory returned status : 0x%08lx\n", Status);
    
    /* Same but in bounds */
    Length = PAGE_SIZE - 1;
    Buffer2 = (PVOID)((ULONG_PTR)Buffer+1);
    
    Status = NtFreeVirtualMemory(NtCurrentProcess(),
                                 &Buffer2,
                                 &Length,
                                 MEM_DECOMMIT);
    ok(Status == STATUS_SUCCESS, "NtFreeVirtualMemory returned status : 0x%08lx\n", Status);
    ok(Buffer2 == Buffer, "NtFreeVirtualMemory set wrong buffer.\n");
    ok(Length == PAGE_SIZE, "NtFreeVirtualMemory did not round Length to PAGE_SIZE.\n");
    
    Buffer2 = (PVOID)((ULONG_PTR)Buffer+1);
    Length = PAGE_SIZE-1;
    Status = NtFreeVirtualMemory(NtCurrentProcess(),
                                 &Buffer2,
                                 &Length,
                                 MEM_RELEASE);
    ok(Status == STATUS_SUCCESS, "NtFreeVirtualMemory returned status : 0x%08lx\n", Status);
    ok(Buffer2 == Buffer, "NtFreeVirtualMemory set wrong buffer.\n");
    ok(Length == PAGE_SIZE, "NtFreeVirtualMemory did not round Length to PAGE_SIZE.\n");
    
    /* Now allocate two pages and try to free them one after the other */
    Length = 2*PAGE_SIZE;
    Status = NtAllocateVirtualMemory(NtCurrentProcess(),
                                     &Buffer,
                                     0,
                                     &Length,
                                     MEM_RESERVE,
                                     PAGE_READWRITE);
    ok(NT_SUCCESS(Status), "NtAllocateVirtualMemory failed : 0x%08lx\n", Status);
    ok(Length == 2*PAGE_SIZE, "Length mismatch : 0x%08lx\n", (ULONG)Length);
    ok(((ULONG_PTR)Buffer % PAGE_SIZE) == 0, "The buffer is not aligned to PAGE_SIZE.\n");
    
    Buffer2 = Buffer;
    Length = PAGE_SIZE;
    Status = NtFreeVirtualMemory(NtCurrentProcess(),
                                 &Buffer2,
                                 &Length,
                                 MEM_RELEASE);
    ok(NT_SUCCESS(Status), "NtFreeVirtualMemory failed : 0x%08lx\n", Status);
    ok(Length == PAGE_SIZE, "Length mismatch : 0x%08lx\n", (ULONG)Length);
    ok(Buffer2 == Buffer, "The buffer is not aligned to PAGE_SIZE.\n");

    Buffer2 = (PVOID)((ULONG_PTR)Buffer+PAGE_SIZE);
    Length = PAGE_SIZE;
    Status = NtFreeVirtualMemory(NtCurrentProcess(),
                                 &Buffer2,
                                 &Length,
                                 MEM_RELEASE);
    ok(NT_SUCCESS(Status), "NtFreeVirtualMemory failed : 0x%08lx\n", Status);
    ok(Length == PAGE_SIZE, "Length mismatch : 0x%08lx\n", (ULONG)Length);
    ok(Buffer2 == (PVOID)((ULONG_PTR)Buffer+PAGE_SIZE), "The buffer is not aligned to PAGE_SIZE.\n");
    
    /* Same, but try to free the second page before the first one */
    Length = 2*PAGE_SIZE;
    Status = NtAllocateVirtualMemory(NtCurrentProcess(),
                                     &Buffer,
                                     0,
                                     &Length,
                                     MEM_RESERVE,
                                     PAGE_READWRITE);
    ok(NT_SUCCESS(Status), "NtAllocateVirtualMemory failed : 0x%08lx\n", Status);
    ok(Length == 2*PAGE_SIZE, "Length mismatch : 0x%08lx\n", (ULONG)Length);
    ok(((ULONG_PTR)Buffer % PAGE_SIZE) == 0, "The buffer is not aligned to PAGE_SIZE.\n");
    
    Buffer2 = (PVOID)((ULONG_PTR)Buffer+PAGE_SIZE);
    Length = PAGE_SIZE;
    Status = NtFreeVirtualMemory(NtCurrentProcess(),
                                 &Buffer2,
                                 &Length,
                                 MEM_RELEASE);
    ok(NT_SUCCESS(Status), "NtFreeVirtualMemory failed : 0x%08lx\n", Status);
    ok(Length == PAGE_SIZE, "Length mismatch : 0x%08lx\n", (ULONG)Length);
    ok(Buffer2 == (PVOID)((ULONG_PTR)Buffer+PAGE_SIZE), "The buffer is not aligned to PAGE_SIZE.\n");
    
    Buffer2 = Buffer;
    Length = PAGE_SIZE;
    Status = NtFreeVirtualMemory(NtCurrentProcess(),
                                 &Buffer2,
                                 &Length,
                                 MEM_RELEASE);
    ok(NT_SUCCESS(Status), "NtFreeVirtualMemory failed : 0x%08lx\n", Status);
    ok(Length == PAGE_SIZE, "Length mismatch : 0x%08lx\n", (ULONG)Length);
    ok(Buffer2 == Buffer, "The buffer is not aligned to PAGE_SIZE.\n");
    
    /* Now allocate two pages and try to free them in the middle */
    Length = 2*PAGE_SIZE;
    Status = NtAllocateVirtualMemory(NtCurrentProcess(),
                                     &Buffer,
                                     0,
                                     &Length,
                                     MEM_RESERVE,
                                     PAGE_READWRITE);
    ok(NT_SUCCESS(Status), "NtAllocateVirtualMemory failed : 0x%08lx\n", Status);
    ok(Length == 2*PAGE_SIZE, "Length mismatch : 0x%08lx\n", (ULONG)Length);
    ok(((ULONG_PTR)Buffer % PAGE_SIZE) == 0, "The buffer is not aligned to PAGE_SIZE.\n");
    
    Buffer2 = (PVOID)((ULONG_PTR)Buffer+1);
    Length = PAGE_SIZE;
    Status = NtFreeVirtualMemory(NtCurrentProcess(),
                                 &Buffer2,
                                 &Length,
                                 MEM_RELEASE);
    ok(NT_SUCCESS(Status), "NtFreeVirtualMemory failed : 0x%08lx\n", Status);
    ok(Length == 2*PAGE_SIZE, "Length mismatch : 0x%08lx\n", (ULONG)Length);
    ok(Buffer2 == Buffer, "The buffer is not aligned to PAGE_SIZE.\n");
}
Пример #28
0
_CRTAPI1 main()
{
    LONG i, j;
    PULONG p4, p3, p2, p1, Ro3, Noaccess;
    ULONG Size1, Size2, Size3, SizeRo3, SizeNoaccess;
    NTSTATUS status;
    HANDLE CurrentProcessHandle;
    ULONG id = 0;
    ULONG OldProtect;

    CurrentProcessHandle = NtCurrentProcess();

    for(i=0; i<3; i++) {
        DbgPrint("Hello World...\n\n");
    }

    DbgPrint("allocating virtual memory\n");

    p1 = (PULONG)NULL;
    Size1 = 30 * 4096;

    status = NtAllocateVirtualMemory (CurrentProcessHandle, (PVOID *)&p1,
                                      0, &Size1, MEM_COMMIT, PAGE_READWRITE);

    DbgPrint("created vm1 status %X start %lx size %lx\n",
             status, (ULONG)p1, Size1);

    p2 = (PULONG)NULL;
    Size2 = 16 * 4096;

    status = NtAllocateVirtualMemory (CurrentProcessHandle, (PVOID *)&p2,
                                      0, &Size2, MEM_COMMIT, PAGE_READWRITE);

    DbgPrint("created vm2 status %X start %lx size %lx\n",
             status, (ULONG)p2, Size2);


    id = fork () + id;

    DbgPrint("fork complete id %lx\n",id);

    p3 = p1 + 8 * 1024;
    Size3 = 16 * 4096;

    DbgPrint("deleting va from %lx for %lx bytes\n",p3, Size3);

    status = NtFreeVirtualMemory (CurrentProcessHandle,(PVOID *)&p3, &Size3,
                                  MEM_RELEASE);

    DbgPrint("free vm status %X start %lx size %lx\n",
             status, (ULONG)p3, Size3);

    p3 = (PULONG)NULL;
    Size3 = 50 * 4096;

    DbgPrint("allocating 50 pages of vm\n");

    status = NtAllocateVirtualMemory (CurrentProcessHandle, (PVOID *)&p3,
                                      0, &Size3, MEM_COMMIT, PAGE_READWRITE);

    DbgPrint("created vm3 status %X start %lx size %lx\n",
             status, (ULONG)p3, Size3);

    Ro3 = (PULONG)NULL;
    SizeRo3 = 393933;

    status = NtAllocateVirtualMemory (CurrentProcessHandle, (PVOID *)&Ro3,
                                      0, &SizeRo3, MEM_COMMIT, PAGE_READONLY);


    DbgPrint("created vm4 status %X start %lx size %lx\n",
             status, (ULONG)Ro3, SizeRo3);

    *p3 = *Ro3;

    p1 = p3;

    p2 = ((PULONG)((PUCHAR)p3 + Size3));
    p4 = p1;
    j = 0;

    while (p3 < p2) {
        j += 1;

        if (j % 8 == 0) {
            if (*p4 != (ULONG)p4) {
                DbgPrint("bad value in cell %lx value is %lx\n",p4, *p4);

            }
            p4 += 1;
            *p4 = (ULONG)p4;
            p4 = p4 + 1026;
        }

        *p3 = (ULONG)p3;
        p3 += 1027;

    }

    p3 = p1;

    //
    // Protect page as no access.
    //

    Noaccess = NULL;
    SizeNoaccess = 200*4096;

    status = NtAllocateVirtualMemory (CurrentProcessHandle, (PVOID *)&Noaccess,
                                      0, &SizeNoaccess, MEM_COMMIT, PAGE_READWRITE);


    DbgPrint("created vm5 status %X start %lx size %lx\n",
             status, (ULONG)Ro3, SizeRo3);

    //
    // Touch all the pages.
    //

    RtlZeroMemory (Noaccess, SizeNoaccess);

    *Noaccess = 91;
    Size1 = 30 * 4097;

    status = NtProtectVirtualMemory (CurrentProcessHandle, (PVOID *)&Noaccess,
                                     &Size1, PAGE_NOACCESS,
                                     &OldProtect);

    DbgPrint("protected VM1 status %X, base %lx, size %lx, old protect %lx\n",
             status, p1, Size1, OldProtect);


    DbgPrint("forking a second time\n");

    id = fork () + id;
    DbgPrint("fork2 complete id %lx\n",id);

    DbgPrint("changing page protection\n");

    Size1 = 9000;

    OldProtect = *p3;

    status = NtProtectVirtualMemory (CurrentProcessHandle, (PVOID *)&p3,
                                     &Size1, PAGE_EXECUTE_READWRITE | PAGE_NOCACHE,
                                     &OldProtect);

    DbgPrint("protected VM2 status %X, base %lx, size %lx, old protect %lx\n",
             status, p1, Size1, OldProtect);


    status = NtProtectVirtualMemory (CurrentProcessHandle, (PVOID *)&Ro3,
                                     &Size1, PAGE_READONLY | PAGE_NOCACHE, &OldProtect);

    DbgPrint("protected VM3 status %X, base %lx, size %lx, old protect %lx\n",
             status, Ro3, Size1, OldProtect);
    p1 += 1;

    while (p3 < p2) {

        *p1 = (ULONG)p1;

        if (*p3 != (ULONG)p3) {
            DbgPrint("bad value in cell %lx value is %lx\n",p3, *p3);
        }
        p3 += 1027;
        p1 += 1027;

    }

    DbgPrint("trying noacess test\n");

    try {
        if (*Noaccess != 91) {
            DbgPrint("*************** FAILED NOACCESS TEST 1 *************\n");

        }

    }
    except (EXCEPTION_EXECUTE_HANDLER) {
        if (GetExceptionCode() != STATUS_ACCESS_VIOLATION) {
            DbgPrint("*************** FAILED NOACCESS TEST 2 *************\n");
        }
    }

    //
    // Make no access page accessable.
    //

    status = NtProtectVirtualMemory (CurrentProcessHandle, (PVOID *)&Noaccess,
                                     &Size1, PAGE_READWRITE,
                                     &OldProtect);

    if (*Noaccess != 91) {
        DbgPrint("*************** FAILED NOACCESS TEST 3 *************\n");
    }

    DbgPrint("that's all process %lx\n",id);

    NtTerminateProcess(NtCurrentProcess(),STATUS_SUCCESS);
}
Пример #29
0
/***********************************************************************
 *             VirtualFreeEx   (KERNEL32.@)
 *
 * Releases or decommits a region of pages in virtual address space.
 *
 * PARAMS
 *  process [I] Handle to process.
 *  addr    [I] Address of region to free.
 *  size    [I] Size of region.
 *  type    [I] Type of operation.
 *
 * RETURNS
 *	Success: TRUE.
 *	Failure: FALSE.
 */
BOOL WINAPI VirtualFreeEx( HANDLE process, LPVOID addr, SIZE_T size, DWORD type )
{
    NTSTATUS status = NtFreeVirtualMemory( process, &addr, &size, type );
    if (status) SetLastError( RtlNtStatusToDosError(status) );
    return !status;
}
Пример #30
0
static NTSTATUS NTAPI TerminatorM1(
    _In_ HANDLE ProcessId
    )
{
    NTSTATUS status;
    HANDLE processHandle;

    if (NT_SUCCESS(status = PhOpenProcess(
        &processHandle,
        PROCESS_QUERY_INFORMATION | PROCESS_VM_WRITE,
        ProcessId
        )))
    {
        PVOID pageOfGarbage;
        SIZE_T pageSize;
        PVOID baseAddress;
        MEMORY_BASIC_INFORMATION basicInfo;

        pageOfGarbage = NULL;
        pageSize = PAGE_SIZE;

        if (!NT_SUCCESS(NtAllocateVirtualMemory(
            NtCurrentProcess(),
            &pageOfGarbage,
            0,
            &pageSize,
            MEM_COMMIT,
            PAGE_READONLY
            )))
        {
            NtClose(processHandle);
            return STATUS_NO_MEMORY;
        }

        baseAddress = (PVOID)0;

        while (NT_SUCCESS(NtQueryVirtualMemory(
            processHandle,
            baseAddress,
            MemoryBasicInformation,
            &basicInfo,
            sizeof(MEMORY_BASIC_INFORMATION),
            NULL
            )))
        {
            ULONG i;

            // Make sure we don't write to views of mapped files. That
            // could possibly corrupt files!
            if (basicInfo.Type == MEM_PRIVATE)
            {
                for (i = 0; i < basicInfo.RegionSize; i += PAGE_SIZE)
                {
                    PhWriteVirtualMemory(
                        processHandle,
                        PTR_ADD_OFFSET(baseAddress, i),
                        pageOfGarbage,
                        PAGE_SIZE,
                        NULL
                        );
                }
            }

            baseAddress = PTR_ADD_OFFSET(baseAddress, basicInfo.RegionSize);
        }

        // Size needs to be zero if we're freeing.
        pageSize = 0;
        NtFreeVirtualMemory(
            NtCurrentProcess(),
            &pageOfGarbage,
            &pageSize,
            MEM_RELEASE
            );

        NtClose(processHandle);
    }

    return status;
}