Example #1
1
NTSTATUS DllInject(HANDLE hProcessID, PEPROCESS pepProcess, PKTHREAD pktThread)
{
	HANDLE hProcess;
	OBJECT_ATTRIBUTES oaAttributes={sizeof(OBJECT_ATTRIBUTES)};
	CLIENT_ID cidProcess;
	PVOID pvMemory = 0;
	DWORD dwSize = 0x1000;

	cidProcess.UniqueProcess = hProcessID;
	cidProcess.UniqueThread = 0;
	if (NT_SUCCESS(ZwOpenProcess(&hProcess, PROCESS_ALL_ACCESS, &oaAttributes, &cidProcess)))
	{
		if (NT_SUCCESS(ZwAllocateVirtualMemory(hProcess, &pvMemory, 0, &dwSize, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE)))
		{
			KAPC_STATE kasState;
			PKAPC pkaApc;
			PVOID FunctionAddress;

			KeStackAttachProcess((PKPROCESS)pepProcess, &kasState);

			FunctionAddress = GetProcAddressInModule(L"kernel32.dll", "LoadLibraryExW");
			if (!FunctionAddress) DbgPrint("GetProcAddressInModule error\n");

			wcscpy((PWCHAR)pvMemory, g_wcDllName);

			KeUnstackDetachProcess(&kasState);

			pkaApc = (PKAPC)ExAllocatePool(NonPagedPool, sizeof(KAPC));
			if (pkaApc)
			{
				KeInitializeApc(pkaApc, pktThread, 0, APCKernelRoutine, 0, (PKNORMAL_ROUTINE)FunctionAddress, UserMode, pvMemory);
				KeInsertQueueApc(pkaApc, 0, 0, IO_NO_INCREMENT);

				return STATUS_SUCCESS;
			}
		}
		else
		{
			DbgPrint("ZwAllocateVirtualMemory error\n");
		}

		ZwClose(hProcess);
	}
	else
	{
		DbgPrint("ZwOpenProcess error\n");
	}

	return STATUS_NO_MEMORY;
}
Example #2
0
/// <summary>
/// Allocate/Free process memory
/// </summary>
/// <param name="pAllocFree">Request params.</param>
/// <param name="pResult">Allocated region info.</param>
/// <returns>Status code</returns>
NTSTATUS BBAllocateFreeMemory( IN PALLOCATE_FREE_MEMORY pAllocFree, OUT PALLOCATE_FREE_MEMORY_RESULT pResult )
{
    NTSTATUS status = STATUS_SUCCESS;
    PEPROCESS pProcess = NULL;

    ASSERT( pResult != NULL );
    if (pResult == NULL)
        return STATUS_INVALID_PARAMETER;

    status = PsLookupProcessByProcessId( (HANDLE)pAllocFree->pid, &pProcess );
    if (NT_SUCCESS( status ))
    {
        KAPC_STATE apc;
        PVOID base = (PVOID)pAllocFree->base;
        ULONG_PTR size = pAllocFree->size;

        KeStackAttachProcess( pProcess, &apc );

        if (pAllocFree->allocate)
        {
            if (pAllocFree->physical != FALSE)
            {
                status = BBAllocateFreePhysical( pProcess, pAllocFree, pResult );
            }
            else
            {
                status = ZwAllocateVirtualMemory( ZwCurrentProcess(), &base, 0, &size, pAllocFree->type, pAllocFree->protection );
                pResult->address = (ULONGLONG)base;
                pResult->size = size;
            }
        }
        else
        {
            MI_VAD_TYPE vadType = VadNone;
            BBGetVadType( pProcess, pAllocFree->base, &vadType );

            if (vadType == VadDevicePhysicalMemory)
                status = BBAllocateFreePhysical( pProcess, pAllocFree, pResult );
            else
                status = ZwFreeVirtualMemory( ZwCurrentProcess(), &base, &size, pAllocFree->type );
        }

        KeUnstackDetachProcess( &apc );        
    }
    else
        DPRINT( "BlackBone: %s: PsLookupProcessByProcessId failed with status 0x%X\n", __FUNCTION__, status );

    if (pProcess)
        ObDereferenceObject( pProcess );

    return status;
}
Example #3
0
VP_STATUS NTAPI
IntInt10AllocateBuffer(
   IN PVOID Context,
   OUT PUSHORT Seg,
   OUT PUSHORT Off,
   IN OUT PULONG Length)
{
   PVOID MemoryAddress;
   NTSTATUS Status;
   PKPROCESS CallingProcess = (PKPROCESS)PsGetCurrentProcess();
   KAPC_STATE ApcState;

   TRACE_(VIDEOPRT, "IntInt10AllocateBuffer\n");

   IntAttachToCSRSS(&CallingProcess, &ApcState);

   MemoryAddress = (PVOID)0x20000;
   Status = ZwAllocateVirtualMemory(NtCurrentProcess(), &MemoryAddress, 0,
      Length, MEM_COMMIT, PAGE_EXECUTE_READWRITE);

   if (!NT_SUCCESS(Status))
   {
      WARN_(VIDEOPRT, "- ZwAllocateVirtualMemory failed\n");
      IntDetachFromCSRSS(&CallingProcess, &ApcState);
      return ERROR_NOT_ENOUGH_MEMORY;
   }

   if (MemoryAddress > (PVOID)(0x100000 - *Length))
   {
      ZwFreeVirtualMemory(NtCurrentProcess(), &MemoryAddress, Length,
         MEM_RELEASE);
      WARN_(VIDEOPRT, "- Unacceptable memory allocated\n");
      IntDetachFromCSRSS(&CallingProcess, &ApcState);
      return ERROR_NOT_ENOUGH_MEMORY;
   }

   *Seg = (USHORT)((ULONG)MemoryAddress >> 4);
   *Off = (USHORT)((ULONG)MemoryAddress & 0xF);

   INFO_(VIDEOPRT, "- Segment: %x\n", (ULONG)MemoryAddress >> 4);
   INFO_(VIDEOPRT, "- Offset: %x\n", (ULONG)MemoryAddress & 0xF);
   INFO_(VIDEOPRT, "- Length: %x\n", *Length);

   IntDetachFromCSRSS(&CallingProcess, &ApcState);

   return NO_ERROR;
}
Example #4
0
static
PGDI_POOL_SECTION
GdiPoolAllocateSection(PGDI_POOL pPool)
{
    PGDI_POOL_SECTION pSection;
    PVOID pvBaseAddress;
    SIZE_T cjSize;
    NTSTATUS status;

    /* Allocate a section object */
    cjSize = sizeof(GDI_POOL_SECTION) + pPool->cSlotsPerSection / sizeof(ULONG);
    pSection = EngAllocMem(0, cjSize, pPool->ulTag);
    if (!pSection)
    {
        return NULL;
    }

    /* Reserve user mode memory */
    cjSize = GDI_POOL_ALLOCATION_GRANULARITY;
    pvBaseAddress = NULL;
    status = ZwAllocateVirtualMemory(NtCurrentProcess(),
                                     &pvBaseAddress,
                                     0,
                                     &cjSize,
                                     MEM_RESERVE,
                                     PAGE_READWRITE);
    if (!NT_SUCCESS(status))
    {
        EngFreeMem(pSection);
        return NULL;
    }

    /* Initialize the section */
    pSection->pvBaseAddress = pvBaseAddress;
    pSection->ulCommitBitmap = 0;
    pSection->cAllocCount = 0;
    RtlInitializeBitMap(&pSection->bitmap,
                        pSection->aulBits,
                        pPool->cSlotsPerSection);
    RtlClearAllBits(&pSection->bitmap);

    /* Return the section */
    return pSection;
}
Example #5
0
void test(PUCHAR arg1)
{
	PUCHAR shellcodeAddress = 0;
	SIZE_T RegionSize = sizeof(new_code);
	NTSTATUS status;
	DWORD ContinueAddress;

	KAPC_STATE kapc;

	PMDL  p_mdl;
	PDWORD MappedImTable;

	if (KeGetCurrentIrql() == PASSIVE_LEVEL)
	{
		status = ZwAllocateVirtualMemory(ZwCurrentProcess(), &shellcodeAddress, 0, &RegionSize, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
		if (!NT_SUCCESS(status))
		{
			return;
		}
		
		shellcodeAddress += 8;
		ContinueAddress = *(PDWORD)(arg1 + 0xB8);
		RtlCopyMemory((PVOID)(new_code + 4), &shellcodeAddress, 4);
		RtlCopyMemory((PVOID)(new_code + 8), &ContinueAddress, 4);
		RtlCopyMemory((PVOID)(shellcodeAddress-8), new_code, sizeof(new_code));

		//KdPrint(("%08X\n", shellcodeAddress - 8));

		if (ContinueAddress > 0x7fff0000)
		{
			//KdPrint(("in kernel address:%08X!\n", ContinueAddress));
		}
		else
		{
			*(PDWORD)(arg1 + 0xB8) = shellcodeAddress - 8;
			//KdPrint(("in user address:%08X!\n", ContinueAddress));
		}
	}

}
Example #6
0
int __cdecl main()
{
	PVOID address = ULongToPtr(1);
	SIZE_T length = 512;
	NTSTATUS status = ZwAllocateVirtualMemory(GetCurrentProcess(), &address, 0, &length, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
	if (NT_SUCCESS(status))
	{
		*static_cast<volatile int*>(ULongToPtr(0)) = 0;
		puts_red(strcpy(static_cast<char*>(ULongToPtr(1)), "null page allocated"));
	}
	else switch (status)
	{
	case STATUS_INVALID_PARAMETER_2:
		puts_green("null page alloc failed (may Windows 8 or MS13-031)");
		break;
	case STATUS_CONFLICTING_ADDRESSES:
		puts_green("null page alloc failed (may EMET)");
		break;
	default:
		printf_red("!ZwAllocateVirtualMemory");
		printf("->0x%lx\n", status);
	}
	return EXIT_SUCCESS;
}
Example #7
0
SECURITY_STATUS SEC_ENTRY
AcceptSecurityContext(
    PCredHandle                 phCredential,       // Cred to base context
    PCtxtHandle                 phContext,          // Existing context (OPT)
    PSecBufferDesc              pInput,             // Input buffer
    unsigned long               fContextReq,        // Context Requirements
    unsigned long               TargetDataRep,      // Target Data Rep
    PCtxtHandle                 phNewContext,       // (out) New context handle
    PSecBufferDesc              pOutput,            // (inout) Output buffers
    unsigned long SEC_FAR *     pfContextAttr,      // (out) Context attributes
    PTimeStamp                  ptsExpiry           // (out) Life span (OPT)
    )
{
    SECURITY_STATUS scRet;
    NTSTATUS SubStatus;
    PAUTHENTICATE_MESSAGE AuthenticateMessage;
    ULONG AuthenticateMessageSize;
    PNTLM_AUTHENTICATE_MESSAGE NtlmAuthenticateMessage;
    ULONG NtlmAuthenticateMessageSize;
    PNTLM_ACCEPT_RESPONSE NtlmAcceptResponse = NULL;
    PMSV1_0_LM20_LOGON LogonBuffer = NULL;
    ULONG LogonBufferSize;
    PMSV1_0_LM20_LOGON_PROFILE LogonProfile = NULL;
    ULONG LogonProfileSize;
    PSecBuffer AcceptResponseToken = NULL;
    PClient Client = NULL;
    ANSI_STRING SourceName;
    LUID LogonId;
    LUID UNALIGNED * TempLogonId;
    LARGE_INTEGER UNALIGNED * TempKickoffTime;
    HANDLE TokenHandle = NULL;
    QUOTA_LIMITS Quotas;
    PUCHAR Where;
    STRING DomainName;
    STRING UserName;
    STRING Workstation;
    STRING NtChallengeResponse;
    STRING LmChallengeResponse;
    ULONG EffectivePackageId;


    RtlInitString(
        &SourceName,
        NULL
        );

    PAGED_CODE();

    //
    // Check for valid sizes, pointers, etc.:
    //


    if (!phCredential)
    {
        return(SEC_E_INVALID_HANDLE);
    }


    //
    // Check that we can indeed call the LSA and get the client
    // handle to it.
    //

    scRet = IsOkayToExec(&Client);
    if (!NT_SUCCESS(scRet))
    {
        return(scRet);
    }

    //
    // Locate the buffers with the input data
    //

    if (!GetTokenBuffer(
            pInput,
            0,          // get the first security token
            (PVOID *) &AuthenticateMessage,
            &AuthenticateMessageSize,
            TRUE        // may be readonly
            ) ||
        (!GetTokenBuffer(
            pInput,
            1,          // get the second security token
            (PVOID *) &NtlmAuthenticateMessage,
            &NtlmAuthenticateMessageSize,
            TRUE        // may be readonly
            )))
    {
        scRet = SEC_E_INVALID_TOKEN;
        goto Cleanup;
    }

    //
    // Get the output tokens
    //

    if (!GetSecurityToken(
            pOutput,
            0,
            &AcceptResponseToken ) )
    {
        scRet = SEC_E_INVALID_TOKEN;
        goto Cleanup;
    }

    //
    // Make sure the sizes are o.k.
    //

    if ((AuthenticateMessageSize < sizeof(AUTHENTICATE_MESSAGE)) ||
        (NtlmAuthenticateMessageSize < sizeof(NTLM_AUTHENTICATE_MESSAGE)))
    {
        scRet = SEC_E_INVALID_TOKEN;
    }

    //
    // Make sure the caller does not want us to allocate memory:
    //

    if (fContextReq & ISC_REQ_ALLOCATE_MEMORY)
    {
        scRet = SEC_E_UNSUPPORTED_FUNCTION;
        goto Cleanup;
    }

    if (AcceptResponseToken->cbBuffer < sizeof(NTLM_ACCEPT_RESPONSE))
    {
        scRet = SEC_E_INVALID_TOKEN;
        goto Cleanup;
    }


    //
    // Verify the validity of the Authenticate message.
    //

    if (strncmp(
            AuthenticateMessage->Signature,
            NTLMSSP_SIGNATURE,
            sizeof(NTLMSSP_SIGNATURE)))
    {
        scRet = SEC_E_INVALID_TOKEN;
        goto Cleanup;
    }

    if (AuthenticateMessage->MessageType != NtLmAuthenticate)
    {
        scRet = SEC_E_INVALID_TOKEN;
        goto Cleanup;
    }

    //
    // Fixup the buffer pointers
    //

    UserName = AuthenticateMessage->UserName;
    UserName.Buffer =  UserName.Buffer + (ULONG) AuthenticateMessage;

    DomainName = AuthenticateMessage->DomainName;
    DomainName.Buffer =  DomainName.Buffer + (ULONG) AuthenticateMessage;

    Workstation = AuthenticateMessage->Workstation;
    Workstation.Buffer =  Workstation.Buffer + (ULONG) AuthenticateMessage;

    NtChallengeResponse = AuthenticateMessage->NtChallengeResponse;
    NtChallengeResponse.Buffer =  NtChallengeResponse.Buffer + (ULONG) AuthenticateMessage;

    LmChallengeResponse = AuthenticateMessage->LmChallengeResponse;
    LmChallengeResponse.Buffer =  LmChallengeResponse.Buffer + (ULONG) AuthenticateMessage;

    //
    // Allocate a buffer to pass into LsaLogonUser
    //

    LogonBufferSize = sizeof(MSV1_0_LM20_LOGON) +
                        UserName.Length +
                        DomainName.Length +
                        Workstation.Length +
                        LmChallengeResponse.Length +
                        NtChallengeResponse.Length;

    scRet = ZwAllocateVirtualMemory(
                NtCurrentProcess(),
                &LogonBuffer,
                0L,
                &LogonBufferSize,
                MEM_COMMIT,
                PAGE_READWRITE
                );

    if (!NT_SUCCESS(scRet))
    {
        goto Cleanup;
    }

    //
    // Fill in the fixed-length portions
    //

    LogonBuffer->MessageType = MsV1_0NetworkLogon;

    RtlCopyMemory(
        LogonBuffer->ChallengeToClient,
        NtlmAuthenticateMessage->ChallengeToClient,
        MSV1_0_CHALLENGE_LENGTH
        );

    //
    // Fill in the variable length pieces
    //

    Where = (PUCHAR) (LogonBuffer + 1);

    PutString(
        (PSTRING) &LogonBuffer->LogonDomainName,
        &DomainName,
        0,
        &Where
        );

    PutString(
        (PSTRING) &LogonBuffer->UserName,
        &UserName,
        0,
        &Where
        );

    PutString(
        (PSTRING) &LogonBuffer->Workstation,
        &Workstation,
        0,
        &Where
        );

    PutString(
        (PSTRING) &LogonBuffer->CaseSensitiveChallengeResponse,
        &NtChallengeResponse,
        0,
        &Where
        );

    PutString(
        (PSTRING) &LogonBuffer->CaseInsensitiveChallengeResponse,
        &LmChallengeResponse,
        0,
        &Where
        );

    LogonBuffer->ParameterControl = MSV1_0_CLEARTEXT_PASSWORD_ALLOWED |
                                     NtlmAuthenticateMessage->ParameterControl;

    scRet = RtlUnicodeStringToAnsiString(
                &SourceName,
                (PUNICODE_STRING) &Workstation,
                TRUE
                );

    if (!NT_SUCCESS(scRet))
    {
        goto Cleanup;
    }

    if ( fContextReq & ASC_REQ_LICENSING )
    {
        EffectivePackageId = PackageId | LSA_CALL_LICENSE_SERVER ;
    }
    else
    {
        EffectivePackageId = PackageId ;
    }

    scRet = LsaLogonUser(
                Client->hPort,
                &SourceName,
                Network,
                EffectivePackageId,
                LogonBuffer,
                LogonBufferSize,
                NULL,               // token groups
                &KsecTokenSource,
                (PVOID *) &LogonProfile,
                &LogonProfileSize,
                &LogonId,
                &TokenHandle,
                &Quotas,
                &SubStatus
                );

    if (scRet == STATUS_ACCOUNT_RESTRICTION)
    {
        scRet = SubStatus;
    }
    if (!NT_SUCCESS(scRet))
    {
        //
        // LsaLogonUser returns garbage for the token if it fails,
        // so zero it now so we don't try to close it later.
        //

        TokenHandle = NULL;
        goto Cleanup;
    }

    //
    // Create the kernel context
    //

    scRet = NtlmInitKernelContext(
                LogonProfile->UserSessionKey,
                LogonProfile->LanmanSessionKey,
                TokenHandle,
                phNewContext
                );

    if (!NT_SUCCESS(scRet))
    {
        goto Cleanup;
    }

    TokenHandle = NULL;

    //
    // Allocate the return buffer.
    //


    NtlmAcceptResponse = (PNTLM_ACCEPT_RESPONSE) AcceptResponseToken->pvBuffer;
    if (NtlmAcceptResponse == NULL)
    {
        scRet = SEC_E_INSUFFICIENT_MEMORY;
        goto Cleanup;
    }

    TempLogonId = (LUID UNALIGNED *) &NtlmAcceptResponse->LogonId;
    *TempLogonId = LogonId;
    NtlmAcceptResponse->UserFlags = LogonProfile->UserFlags;

    RtlCopyMemory(
        NtlmAcceptResponse->UserSessionKey,
        LogonProfile->UserSessionKey,
        MSV1_0_USER_SESSION_KEY_LENGTH
        );

    RtlCopyMemory(
        NtlmAcceptResponse->LanmanSessionKey,
        LogonProfile->LanmanSessionKey,
        MSV1_0_LANMAN_SESSION_KEY_LENGTH
        );

    TempKickoffTime = (LARGE_INTEGER UNALIGNED *) &NtlmAcceptResponse->KickoffTime;
    *TempKickoffTime = LogonProfile->KickOffTime;

    AcceptResponseToken->cbBuffer = sizeof(NTLM_ACCEPT_RESPONSE);

    if ( fContextReq & ASC_REQ_LICENSING )
    {
        *pfContextAttr = ASC_RET_ALLOCATED_MEMORY | ASC_RET_LICENSING ;
    }
    else
    {
        *pfContextAttr = ASC_RET_ALLOCATED_MEMORY;
    }

    *ptsExpiry = LogonProfile->LogoffTime;
    scRet = SEC_E_OK;


Cleanup:
    if (SourceName.Buffer != NULL)
    {
        RtlFreeAnsiString(&SourceName);
    }

    if (LogonBuffer != NULL)
    {
        ZwFreeVirtualMemory(
            NtCurrentProcess(),
            &LogonBuffer,
            &LogonBufferSize,
            MEM_RELEASE
            );
    }

    if (LogonProfile != NULL)
    {
        LsaFreeReturnBuffer(LogonProfile);
    }


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

    return(scRet);

}
Example #8
0
SECURITY_STATUS SEC_ENTRY
InitializeSecurityContextW(
    PCredHandle                 phCredential,       // Cred to base context
    PCtxtHandle                 phContext,          // Existing context (OPT)
    PSECURITY_STRING            pssTargetName,      // Name of target
    unsigned long               fContextReq,        // Context Requirements
    unsigned long               Reserved1,          // Reserved, MBZ
    unsigned long               TargetDataRep,      // Data rep of target
    PSecBufferDesc              pInput,             // Input Buffers
    unsigned long               Reserved2,          // Reserved, MBZ
    PCtxtHandle                 phNewContext,       // (out) New Context handle
    PSecBufferDesc              pOutput,            // (inout) Output Buffers
    unsigned long SEC_FAR *     pfContextAttr,      // (out) Context attrs
    PTimeStamp                  ptsExpiry           // (out) Life span (OPT)
    )
{
    SECURITY_STATUS scRet;
    PMSV1_0_GETCHALLENRESP_REQUEST ChallengeRequest = NULL;
    ULONG ChallengeRequestSize;
    PMSV1_0_GETCHALLENRESP_RESPONSE ChallengeResponse = NULL;
    ULONG ChallengeResponseSize;
    PCHALLENGE_MESSAGE ChallengeMessage = NULL;
    ULONG ChallengeMessageSize;
    PNTLM_CHALLENGE_MESSAGE NtlmChallengeMessage = NULL;
    ULONG NtlmChallengeMessageSize;
    PAUTHENTICATE_MESSAGE AuthenticateMessage = NULL;
    ULONG AuthenticateMessageSize;
    PNTLM_INITIALIZE_RESPONSE NtlmInitializeResponse = NULL;
    PClient Client = NULL;
    UNICODE_STRING PasswordToUse;
    UNICODE_STRING UserNameToUse;
    UNICODE_STRING DomainNameToUse;
    ULONG ParameterControl = USE_PRIMARY_PASSWORD |
                                RETURN_PRIMARY_USERNAME |
                                RETURN_PRIMARY_LOGON_DOMAINNAME;

    NTSTATUS FinalStatus = STATUS_SUCCESS;
    PUCHAR Where;
    PSecBuffer AuthenticationToken = NULL;
    PSecBuffer InitializeResponseToken = NULL;
    BOOLEAN UseSuppliedCreds = FALSE;


    PAGED_CODE();

    RtlInitUnicodeString(
        &PasswordToUse,
        NULL
        );

    RtlInitUnicodeString(
        &UserNameToUse,
        NULL
        );

    RtlInitUnicodeString(
        &DomainNameToUse,
        NULL
        );

    //
    // Check for valid sizes, pointers, etc.:
    //


    if (!phCredential)
    {
        return(SEC_E_INVALID_HANDLE);
    }


    //
    // Check that we can indeed call the LSA and get the client
    // handle to it.
    //

    scRet = IsOkayToExec(&Client);
    if (!NT_SUCCESS(scRet))
    {
        return(scRet);
    }

    //
    // Locate the buffers with the input data
    //

    if (!GetTokenBuffer(
            pInput,
            0,          // get the first security token
            (PVOID *) &ChallengeMessage,
            &ChallengeMessageSize,
            TRUE        // may be readonly
            ))
    {
        scRet = SEC_E_INVALID_TOKEN;
        goto Cleanup;
    }

    //
    // If we are using supplied creds, get them now too.
    //


    if (fContextReq & ISC_REQ_USE_SUPPLIED_CREDS)
    {
        if (!GetTokenBuffer(
            pInput,
            1,          // get the second security token
            (PVOID *) &NtlmChallengeMessage,
            &NtlmChallengeMessageSize,
            TRUE        // may be readonly
            ))
        {
            scRet = SEC_E_INVALID_TOKEN;
            goto Cleanup;
        }
        else
        {
            UseSuppliedCreds = TRUE;
        }

    }

    //
    // Get the output tokens
    //

    if (!GetSecurityToken(
            pOutput,
            0,
            &AuthenticationToken) ||
        !GetSecurityToken(
            pOutput,
            1,
            &InitializeResponseToken ) )
    {
        scRet = SEC_E_INVALID_TOKEN;
        goto Cleanup;
    }

    //
    // Make sure the sizes are o.k.
    //

    if ((ChallengeMessageSize < sizeof(CHALLENGE_MESSAGE)) ||
        (UseSuppliedCreds &&
            !(NtlmChallengeMessageSize < sizeof(NTLM_CHALLENGE_MESSAGE))))
    {
        scRet = SEC_E_INVALID_TOKEN;
    }

    //
    // Make sure the caller wants us to allocate memory:
    //

    if (!(fContextReq & ISC_REQ_ALLOCATE_MEMORY))
    {
        scRet = SEC_E_UNSUPPORTED_FUNCTION;
        goto Cleanup;
    }

//
// BUGBUG: allow calls requesting PROMPT_FOR_CREDS to go through.
// We won't prompt, but we will setup a context properly.
//

//    if ((fContextReq & ISC_REQ_PROMPT_FOR_CREDS) != 0)
//    {
//        scRet = SEC_E_UNSUPPORTED_FUNCTION;
//        goto Cleanup;
//    }

    //
    // Verify the validity of the challenge message.
    //

    if (strncmp(
            ChallengeMessage->Signature,
            NTLMSSP_SIGNATURE,
            sizeof(NTLMSSP_SIGNATURE)))
    {
        scRet = SEC_E_INVALID_TOKEN;
        goto Cleanup;
    }

    if (ChallengeMessage->MessageType != NtLmChallenge)
    {
        scRet = SEC_E_INVALID_TOKEN;
        goto Cleanup;
    }

    if (ChallengeMessage->NegotiateFlags & NTLMSSP_REQUIRED_NEGOTIATE_FLAGS !=
        NTLMSSP_REQUIRED_NEGOTIATE_FLAGS)
    {
        scRet = SEC_E_UNSUPPORTED_FUNCTION;
        goto Cleanup;
    }

    if ((ChallengeMessage->NegotiateFlags & NTLMSSP_REQUEST_NON_NT_SESSION_KEY) != 0)
    {
        ParameterControl |= RETURN_NON_NT_USER_SESSION_KEY;
    }

    if ((fContextReq & ISC_REQ_USE_SUPPLIED_CREDS) != 0)
    {
        if ( NtlmChallengeMessage->Password.Buffer != NULL)
        {
            ParameterControl &= ~USE_PRIMARY_PASSWORD;
            PasswordToUse = NtlmChallengeMessage->Password;
            PasswordToUse.Buffer = (LPWSTR) ((PCHAR) PasswordToUse.Buffer +
                                              (ULONG) NtlmChallengeMessage);
        }

        if (NtlmChallengeMessage->UserName.Length != 0)
        {
            UserNameToUse = NtlmChallengeMessage->UserName;
            UserNameToUse.Buffer = (LPWSTR) ((PCHAR) UserNameToUse.Buffer +
                                              (ULONG) NtlmChallengeMessage);
            ParameterControl &= ~RETURN_PRIMARY_USERNAME;
        }
        if (NtlmChallengeMessage->DomainName.Length != 0)
        {
            DomainNameToUse = NtlmChallengeMessage->DomainName;
            DomainNameToUse.Buffer = (LPWSTR) ((PCHAR) DomainNameToUse.Buffer +
                                              (ULONG) NtlmChallengeMessage);
            ParameterControl &= ~RETURN_PRIMARY_LOGON_DOMAINNAME;
        }

    }

    //
    // Package up the parameter for a call to the LSA.
    //

    ChallengeRequestSize = sizeof(MSV1_0_GETCHALLENRESP_REQUEST) +
                                PasswordToUse.Length;

    scRet = ZwAllocateVirtualMemory(
                NtCurrentProcess(),
                &ChallengeRequest,
                0L,
                &ChallengeRequestSize,
                MEM_COMMIT,
                PAGE_READWRITE
                );
    if (!NT_SUCCESS(scRet))
    {
        goto Cleanup;
    }


    //
    // Build the challenge request message.
    //

    ChallengeRequest->MessageType = MsV1_0Lm20GetChallengeResponse;
    ChallengeRequest->ParameterControl = ParameterControl;
    ChallengeRequest->LogonId = * (PLUID) phCredential;
    RtlCopyMemory(
        ChallengeRequest->ChallengeToClient,
        ChallengeMessage->Challenge,
        MSV1_0_CHALLENGE_LENGTH
        );
    if ((ParameterControl & USE_PRIMARY_PASSWORD) == 0)
    {
        ChallengeRequest->Password.Buffer = (LPWSTR) (ChallengeRequest+1);
        RtlCopyMemory(
            ChallengeRequest->Password.Buffer,
            PasswordToUse.Buffer,
            PasswordToUse.Length
            );
        ChallengeRequest->Password.Length = PasswordToUse.Length;
        ChallengeRequest->Password.MaximumLength = PasswordToUse.Length;
    }

    //
    // Call the LSA to get the challenge response.
    //

    scRet = LsaCallAuthenticationPackage(
                Client->hPort,
                PackageId,
                ChallengeRequest,
                ChallengeRequestSize,
                &ChallengeResponse,
                &ChallengeResponseSize,
                &FinalStatus
                );
    if (!NT_SUCCESS(scRet))
    {
        goto Cleanup;
    }
    if (!NT_SUCCESS(FinalStatus))
    {
        scRet = FinalStatus;
        goto Cleanup;
    }

    ASSERT(ChallengeResponse->MessageType == MsV1_0Lm20GetChallengeResponse);
    //
    // Now prepare the output message.
    //

    if (UserNameToUse.Buffer == NULL)
    {
        UserNameToUse = ChallengeResponse->UserName;
    }
    if (DomainNameToUse.Buffer == NULL)
    {
        DomainNameToUse = ChallengeResponse->LogonDomainName;
    }

    AuthenticateMessageSize = sizeof(AUTHENTICATE_MESSAGE) +
                                UserNameToUse.Length +
                                DomainNameToUse.Length +
                                ChallengeResponse->CaseSensitiveChallengeResponse.Length +
                                ChallengeResponse->CaseInsensitiveChallengeResponse.Length;

    //
    // BUGBUG: where do I get the workstation name from?
    //

    AuthenticateMessage = (PAUTHENTICATE_MESSAGE) SecAllocate(AuthenticateMessageSize);
    if (AuthenticateMessage == NULL)
    {
        scRet = SEC_E_INSUFFICIENT_MEMORY;
        goto Cleanup;
    }

    Where = (PUCHAR) (AuthenticateMessage + 1);
    RtlCopyMemory(
        AuthenticateMessage->Signature,
        NTLMSSP_SIGNATURE,
        sizeof(NTLMSSP_SIGNATURE)
        );
    AuthenticateMessage->MessageType = NtLmAuthenticate;

    PutString(
        &AuthenticateMessage->LmChallengeResponse,
        &ChallengeResponse->CaseInsensitiveChallengeResponse,
        AuthenticateMessage,
        &Where
        );

    PutString(
        &AuthenticateMessage->NtChallengeResponse,
        &ChallengeResponse->CaseSensitiveChallengeResponse,
        AuthenticateMessage,
        &Where
        );

    PutString(
        &AuthenticateMessage->DomainName,
        (PSTRING) &DomainNameToUse,
        AuthenticateMessage,
        &Where
        );

    PutString(
        &AuthenticateMessage->UserName,
        (PSTRING) &UserNameToUse,
        AuthenticateMessage,
        &Where
        );

    //
    // BUGBUG: no workstation name to fill in.
    //

    AuthenticateMessage->Workstation.Length = 0;
    AuthenticateMessage->Workstation.MaximumLength = 0;
    AuthenticateMessage->Workstation.Buffer = NULL;


    //
    // Build the initialize response.
    //

    NtlmInitializeResponse = (PNTLM_INITIALIZE_RESPONSE) SecAllocate(sizeof(NTLM_INITIALIZE_RESPONSE));
    if (NtlmInitializeResponse == NULL)
    {
        scRet = SEC_E_INSUFFICIENT_MEMORY;
        goto Cleanup;
    }


    RtlCopyMemory(
        NtlmInitializeResponse->UserSessionKey,
        ChallengeResponse->UserSessionKey,
        MSV1_0_USER_SESSION_KEY_LENGTH
        );

    RtlCopyMemory(
        NtlmInitializeResponse->LanmanSessionKey,
        ChallengeResponse->LanmanSessionKey,
        MSV1_0_LANMAN_SESSION_KEY_LENGTH
        );

    //
    // Fill in the output buffers now.
    //

    AuthenticationToken->pvBuffer = AuthenticateMessage;
    AuthenticationToken->cbBuffer = AuthenticateMessageSize;
    InitializeResponseToken->pvBuffer = NtlmInitializeResponse;
    InitializeResponseToken->cbBuffer = sizeof(NTLM_INITIALIZE_RESPONSE);


    //
    // Make a local context for this
    //

    scRet = NtlmInitKernelContext(
                NtlmInitializeResponse->UserSessionKey,
                NtlmInitializeResponse->LanmanSessionKey,
                NULL,           // no token,
                phNewContext
                );

    if (!NT_SUCCESS(scRet))
    {
        goto Cleanup;
    }
    scRet = SEC_E_OK;




Cleanup:

    if (ChallengeRequest != NULL)
    {
        ZwFreeVirtualMemory(
            NtCurrentProcess(),
            &ChallengeRequest,
            &ChallengeRequestSize,
            MEM_RELEASE
            );
    }

    if (ChallengeResponse != NULL)
    {
        LsaFreeReturnBuffer( ChallengeResponse );
    }

    if (!NT_SUCCESS(scRet))
    {
        if (AuthenticateMessage != NULL)
        {
            SecFree(AuthenticateMessage);
        }
        if (NtlmInitializeResponse != NULL)
        {
            SecFree(NtlmInitializeResponse);
        }
    }
    return(scRet);
}
Example #9
0
SECURITY_STATUS SEC_ENTRY
GetSecurityUserInfo(
    IN PLUID pLogonId,
    IN ULONG fFlags,
    OUT PSecurityUserData * ppUserInfo)
{
    NTSTATUS Status, FinalStatus;
    PVOID GetInfoBuffer = NULL;
    PVOID GetInfoResponseBuffer = NULL;
    PMSV1_0_GETUSERINFO_REQUEST GetInfoRequest;
    PMSV1_0_GETUSERINFO_RESPONSE GetInfoResponse;
    ULONG ResponseSize;
    ULONG RegionSize = sizeof(MSV1_0_GETUSERINFO_REQUEST);
    PSecurityUserData UserInfo = NULL;
    ULONG UserInfoSize;
    PUCHAR Where;
    SECURITY_STATUS scRet;
    PClient Client = NULL;


    scRet = IsOkayToExec(&Client);
    if (!NT_SUCCESS(scRet))
    {
        return(scRet);
    }

    //
    //  Allocate virtual memory for the response buffer.
    //

    Status = ZwAllocateVirtualMemory(
                NtCurrentProcess(),
                &GetInfoBuffer, 0L,
                &RegionSize,
                MEM_COMMIT,
                PAGE_READWRITE
                );

    GetInfoRequest = GetInfoBuffer;

    if (!NT_SUCCESS(Status)) {
        scRet = Status;
        goto Cleanup;
    }

    GetInfoRequest->MessageType = MsV1_0GetUserInfo;

    RtlCopyLuid(&GetInfoRequest->LogonId, pLogonId);

    Status = LsaCallAuthenticationPackage(
                Client->hPort,
                PackageId,
                GetInfoRequest,
                RegionSize,
                &GetInfoResponseBuffer,
                &ResponseSize,
                &FinalStatus);

    GetInfoResponse = GetInfoResponseBuffer;

    if (!NT_SUCCESS(Status)) {
        GetInfoResponseBuffer = NULL;
        scRet = Status;
        goto Cleanup;
    }


    if (!NT_SUCCESS(FinalStatus)) {
        scRet = FinalStatus;
        goto Cleanup;
    }

    ASSERT(GetInfoResponse->MessageType == MsV1_0GetUserInfo);

    //
    // Build a SecurityUserData
    //

    UserInfoSize = sizeof(SecurityUserData) +
                   GetInfoResponse->UserName.MaximumLength +
                   GetInfoResponse->LogonDomainName.MaximumLength +
                   GetInfoResponse->LogonServer.MaximumLength +
                   RtlLengthSid(GetInfoResponse->UserSid);



    scRet = ZwAllocateVirtualMemory(
                NtCurrentProcess(),
                &UserInfo,
                0L,
                &UserInfoSize,
                MEM_COMMIT,
                PAGE_READWRITE
                );
    if (!NT_SUCCESS(scRet))
    {
        goto Cleanup;
    }

    //
    // Pack in the SID first, to respectalignment boundaries.
    //

    Where = (PUCHAR) (UserInfo + 1);
    UserInfo->pSid = (PSID) (Where);
    RtlCopySid(
        UserInfoSize,
        Where,
        GetInfoResponse->UserSid
        );
    Where += RtlLengthSid(Where);

    //
    // Pack in the strings
    //

    PutString(
        (PSTRING) &UserInfo->UserName,
        (PSTRING) &GetInfoResponse->UserName,
        0,
        &Where
        );

    PutString(
        (PSTRING) &UserInfo->LogonDomainName,
        (PSTRING) &GetInfoResponse->LogonDomainName,
        0,
        &Where
        );

    PutString(
        (PSTRING) &UserInfo->LogonServer,
        (PSTRING) &GetInfoResponse->LogonServer,
        0,
        &Where
        );

    *ppUserInfo = UserInfo;
    UserInfo = NULL;
    scRet = STATUS_SUCCESS;

Cleanup:
    if (GetInfoRequest != NULL)
    {
        ZwFreeVirtualMemory(
            NtCurrentProcess(),
            &GetInfoRequest,
            &RegionSize,
            MEM_RELEASE
            );

    }

    if (UserInfo != NULL)
    {
        FreeContextBuffer(UserInfo);
    }

    if (GetInfoResponseBuffer != NULL)
    {
        LsaFreeReturnBuffer(GetInfoResponseBuffer);
    }

    return(scRet);
}
Example #10
0
/*
 * @implemented
 */
PRTL_HANDLE_TABLE_ENTRY
NTAPI
RtlAllocateHandle(
    PRTL_HANDLE_TABLE HandleTable,
    PULONG Index)
{
    PRTL_HANDLE_TABLE_ENTRY CurrentEntry, NextEntry;
    NTSTATUS Status;
    PRTL_HANDLE_TABLE_ENTRY HandleEntry;
    PVOID ArrayPointer;
    SIZE_T ArraySize;
    ULONG i, NumberOfEntries;

    /* Check if we are out of free handles entries */
    if (HandleTable->FreeHandles == NULL)
    {
        /* Check if we don't have uncomitted handle entries yet */
        if (HandleTable->UnCommittedHandles == NULL)
        {
            /* Use the maximum number of handle entries */
            ArraySize = HandleTable->SizeOfHandleTableEntry * HandleTable->MaximumNumberOfHandles;
            ArrayPointer = NULL;

            /* Reserve memory */
            Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
                                             &ArrayPointer,
                                             0,
                                             &ArraySize,
                                             MEM_RESERVE,
                                             PAGE_READWRITE);
            if (!NT_SUCCESS(Status))
                return NULL;

            /* Update handle array pointers */
            HandleTable->UnCommittedHandles = (PRTL_HANDLE_TABLE_ENTRY)ArrayPointer;
            HandleTable->MaxReservedHandles = (PRTL_HANDLE_TABLE_ENTRY)((ULONG_PTR)ArrayPointer + ArraySize);
        }

        /* Commit one reserved handle entry page */
        ArraySize = PAGE_SIZE;
        ArrayPointer = HandleTable->UnCommittedHandles;
        Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
                                         &ArrayPointer,
                                         0,
                                         &ArraySize,
                                         MEM_COMMIT,
                                         PAGE_READWRITE);
        if (!NT_SUCCESS(Status))
            return NULL;

        /* Update handle array pointers */
        HandleTable->FreeHandles = (PRTL_HANDLE_TABLE_ENTRY)ArrayPointer;
        HandleTable->CommittedHandles = (PRTL_HANDLE_TABLE_ENTRY)ArrayPointer;
        HandleTable->UnCommittedHandles = (PRTL_HANDLE_TABLE_ENTRY)((ULONG_PTR)ArrayPointer + ArraySize);

        /* Calculate the number of entries we can store in the array */
        NumberOfEntries = ArraySize / HandleTable->SizeOfHandleTableEntry;

        /* Loop all entries, except the last one */
        CurrentEntry = HandleTable->FreeHandles;
        for (i = 0; i < NumberOfEntries - 1; i++)
        {
            /* Calculate the address of the next handle entry */
            NextEntry = (PRTL_HANDLE_TABLE_ENTRY)((ULONG_PTR)CurrentEntry +
                                                  HandleTable->SizeOfHandleTableEntry);

            /* Link the next entry */
            CurrentEntry->NextFree = NextEntry;

            /* Continue with the next entry */
            CurrentEntry = NextEntry;
        }

        /* CurrentEntry now points to the last entry, terminate the list here */
        CurrentEntry->NextFree = NULL;
    }

    /* remove handle from free list */
    HandleEntry = HandleTable->FreeHandles;
    HandleTable->FreeHandles = HandleEntry->NextFree;
    HandleEntry->NextFree = NULL;

    if (Index)
    {
        *Index = ((ULONG)((ULONG_PTR)HandleEntry - (ULONG_PTR)HandleTable->CommittedHandles) /
                  HandleTable->SizeOfHandleTableEntry);
    }

    return HandleEntry;
}
Example #11
0
NTSTATUS
RtlpCreateStack(
    IN HANDLE Process,
    IN SIZE_T MaximumStackSize OPTIONAL,
    IN SIZE_T CommittedStackSize OPTIONAL,
    IN ULONG ZeroBits OPTIONAL,
    OUT PINITIAL_TEB InitialTeb
    )
{
    NTSTATUS Status;
    PCH Stack;
    SYSTEM_BASIC_INFORMATION SysInfo;
    BOOLEAN GuardPage;
    SIZE_T RegionSize;
    ULONG OldProtect;

    Status = ZwQuerySystemInformation( SystemBasicInformation,
                                       (PVOID)&SysInfo,
                                       sizeof( SysInfo ),
                                       NULL
                                     );
    if ( !NT_SUCCESS( Status ) ) {
        return( Status );
        }

    //
    // if stack is in the current process, then default to
    // the parameters from the image
    //

    if ( Process == NtCurrentProcess() ) {
        PPEB Peb;
        PIMAGE_NT_HEADERS NtHeaders;


        Peb = NtCurrentPeb();
        NtHeaders = RtlImageNtHeader(Peb->ImageBaseAddress);

        if (!NtHeaders) {
            return STATUS_INVALID_IMAGE_FORMAT;
        }


        if (!MaximumStackSize) {
            MaximumStackSize = NtHeaders->OptionalHeader.SizeOfStackReserve;
            }

        if (!CommittedStackSize) {
            CommittedStackSize = NtHeaders->OptionalHeader.SizeOfStackCommit;
            }

        }
    else {

        if (!CommittedStackSize) {
            CommittedStackSize = SysInfo.PageSize;
            }

        if (!MaximumStackSize) {
            MaximumStackSize = SysInfo.AllocationGranularity;
            }

        }

    //
    // Enforce a minimal stack commit if there is a PEB setting
    // for this.
    //

    if ( CommittedStackSize >= MaximumStackSize ) {
        MaximumStackSize = ROUND_UP(CommittedStackSize, (1024*1024));
        }


    CommittedStackSize = ROUND_UP( CommittedStackSize, SysInfo.PageSize );
    MaximumStackSize = ROUND_UP( MaximumStackSize,
                                 SysInfo.AllocationGranularity
                               );

    Stack = NULL;


    Status = ZwAllocateVirtualMemory( Process,
                                      (PVOID *)&Stack,
                                      ZeroBits,
                                      &MaximumStackSize,
                                      MEM_RESERVE,
                                      PAGE_READWRITE
                                    );

    if ( !NT_SUCCESS( Status ) ) {
#if DBG
        DbgPrint( "NTRTL: RtlpCreateStack( %lx ) failed.  Stack Reservation Status == %X\n",
                  Process,
                  Status
                );
#endif // DBG
        return( Status );
        }

    InitialTeb->OldInitialTeb.OldStackBase = NULL;
    InitialTeb->OldInitialTeb.OldStackLimit = NULL;
    InitialTeb->StackAllocationBase = Stack;
    InitialTeb->StackBase = Stack + MaximumStackSize;

    Stack += MaximumStackSize - CommittedStackSize;
    if (MaximumStackSize > CommittedStackSize) {
        Stack -= SysInfo.PageSize;
        CommittedStackSize += SysInfo.PageSize;
        GuardPage = TRUE;
        }
    else {
        GuardPage = FALSE;
        }
    Status = ZwAllocateVirtualMemory( Process,
                                      (PVOID *)&Stack,
                                      0,
                                      &CommittedStackSize,
                                      MEM_COMMIT,
                                      PAGE_READWRITE
                                    );
    InitialTeb->StackLimit = Stack;

    if ( !NT_SUCCESS( Status ) ) {
#if DBG
        DbgPrint( "NTRTL: RtlpCreateStack( %lx ) failed.  Stack Commit Status == %X\n",
                  Process,
                  Status
                );
#endif // DBG
        return( Status );
        }

    //
    // if we have space, create a guard page.
    //

    if (GuardPage) {
        RegionSize =  SysInfo.PageSize;
        Status = ZwProtectVirtualMemory( Process,
                                         (PVOID *)&Stack,
                                         &RegionSize,
                                         PAGE_GUARD | PAGE_READWRITE,
                                         &OldProtect);


        if ( !NT_SUCCESS( Status ) ) {
#if DBG
            DbgPrint( "NTRTL: RtlpCreateStack( %lx ) failed.  Guard Page Creation Status == %X\n",
                      Process,
                      Status
                    );
#endif // DBG
            return( Status );
            }
        InitialTeb->StackLimit = (PVOID)((PUCHAR)InitialTeb->StackLimit + RegionSize);
        }

    return( STATUS_SUCCESS );
}
Example #12
0
PVOID
NTAPI
GdiPoolAllocate(
    PGDI_POOL pPool)
{
    PGDI_POOL_SECTION pSection;
    ULONG ulIndex, cjOffset, ulPageBit;
    PLIST_ENTRY ple;
    PVOID pvAlloc, pvBaseAddress;
    SIZE_T cjSize;
    NTSTATUS status;

    /* Disable APCs and acquire the pool lock */
    KeEnterCriticalRegion();
    ExAcquirePushLockExclusive(&pPool->pushlock);

    /* Check if we have a ready section */
    if (!IsListEmpty(&pPool->leReadyList))
    {
        /* Get a free section */
        ple = pPool->leReadyList.Flink;
        pSection = CONTAINING_RECORD(ple, GDI_POOL_SECTION, leReadyLink);
        if (pSection->cAllocCount >= pPool->cSlotsPerSection)
        {
            DPRINT1("pSection->cAllocCount=%lu, pPool->cSlotsPerSection=%lu\n",
                    pSection->cAllocCount, pPool->cSlotsPerSection);
            DBG_DUMP_EVENT_LIST(&pPool->slhLog);
            ASSERT(FALSE);
        }
        ASSERT(pSection->cAllocCount < pPool->cSlotsPerSection);
    }
    else
    {
        /* No, check if we have something on the empty list */
        if (!IsListEmpty(&pPool->leEmptyList))
        {
            /* Yes, remove it from the empty list */
            ple = RemoveHeadList(&pPool->leEmptyList);
            pSection = CONTAINING_RECORD(ple, GDI_POOL_SECTION, leInUseLink);
            pPool->cEmptySections--;
            ASSERT(pSection->cAllocCount == 0);
        }
        else
        {
            /* No, allocate a new section */
            pSection = GdiPoolAllocateSection(pPool);
            if (!pSection)
            {
                DPRINT1("Couldn't allocate a section\n");
                pvAlloc = NULL;
                goto done;
            }
        }

        /* Insert it into the in-use and ready list */
        InsertHeadList(&pPool->leInUseList, &pSection->leInUseLink);
        InsertHeadList(&pPool->leReadyList, &pSection->leReadyLink);
    }

    /* Find and set a single bit */
    ulIndex = RtlFindClearBitsAndSet(&pSection->bitmap, 1, 0);
    ASSERT(ulIndex != MAXULONG);

    /* Calculate the allocation address */
    cjOffset = ulIndex * pPool->cjAllocSize;
    pvAlloc = (PVOID)((ULONG_PTR)pSection->pvBaseAddress + cjOffset);

    /* Check if memory is comitted */
    ulPageBit = 1 << (cjOffset / PAGE_SIZE);
    ulPageBit |= 1 << ((cjOffset + pPool->cjAllocSize - 1) / PAGE_SIZE);
    if ((pSection->ulCommitBitmap & ulPageBit) != ulPageBit)
    {
        /* Commit the pages */
        pvBaseAddress = PAGE_ALIGN(pvAlloc);
        cjSize = ADDRESS_AND_SIZE_TO_SPAN_PAGES(pvAlloc, pPool->cjAllocSize) * PAGE_SIZE;
        status = ZwAllocateVirtualMemory(NtCurrentProcess(),
                                         &pvBaseAddress,
                                         0,
                                         &cjSize,
                                         MEM_COMMIT,
                                         PAGE_READWRITE);
        if (!NT_SUCCESS(status))
        {
            pvAlloc = NULL;
            goto done;
        }

        pSection->ulCommitBitmap |= ulPageBit;
    }

    /* Increase alloc count */
    pSection->cAllocCount++;
    ASSERT(RtlNumberOfSetBits(&pSection->bitmap) == pSection->cAllocCount);
    DBG_LOGEVENT(&pPool->slhLog, EVENT_ALLOCATE, pvAlloc);

    /* Check if section is now busy */
    if (pSection->cAllocCount == pPool->cSlotsPerSection)
    {
        /* Remove the section from the ready list */
        RemoveEntryList(&pSection->leReadyLink);
    }

done:
    /* Release the pool lock and enable APCs */
    ExReleasePushLockExclusive(&pPool->pushlock);
    KeLeaveCriticalRegion();

    DPRINT("GdiPoolallocate: %p\n", pvAlloc);
    return pvAlloc;
}
Example #13
0
NTSTATUS VirtualAlloc(HANDLE hProcess, SIZE_T Size, OUT PVOID *VirtualAddress) {
	PVOID BaseAddress = NULL;
	NTSTATUS Status = ZwAllocateVirtualMemory(hProcess, &BaseAddress, 0, &Size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
	*VirtualAddress = BaseAddress;
	return Status;
};
Example #14
0
int GetHarddiskId(PWCHAR pwchDir)
{
	NTSTATUS			ntStatus;
	int					nRet = -1;

	OBJECT_ATTRIBUTES	ObjAttr;
	HANDLE				hDirectoryObject;
	UNICODE_STRING		Name;
	
	WCHAR				DriverStr[32];
	PWCHAR				pdrvid;
	int					len ;

	PMY_QUERY_DIRECTORY_STRUCT	qds;
	POBJECT_NAMETYPE_INFO		p;
	ULONG						RegionSize;

	int cou;
	
	qds = NULL;
	RegionSize = sizeof(MY_QUERY_DIRECTORY_STRUCT);

	if(!NT_SUCCESS(ntStatus = ZwAllocateVirtualMemory((HANDLE)-1, (PVOID*) &qds, 0, &RegionSize, 
		MEM_COMMIT,PAGE_READWRITE)))
	{
		return nRet;
	}

	wcscpy(DriverStr, L"DR0");
	len = wcslen(DriverStr);
	pdrvid = &DriverStr[len - 1];

	RtlInitUnicodeString(&Name, pwchDir);
	Name.Length -= sizeof(WCHAR);
	InitializeObjectAttributes(&ObjAttr, &Name, OBJ_CASE_INSENSITIVE, NULL, NULL);
	ntStatus = ZwOpenDirectoryObject(&hDirectoryObject, DIRECTORY_QUERY, &ObjAttr);

	if(NT_SUCCESS(ntStatus))
	{
		BOOLEAN First = TRUE;
		
		while(NtQueryDirectoryObject(hDirectoryObject, &qds->Buffer, QUERY_DIRECTORY_BUFF_SIZE, TRUE, First, 
			&qds->Index, &qds->Retlen) >= 0 && nRet == -1)
		{
			PWCHAR obj_name;
			int tmp_len;
			p = (POBJECT_NAMETYPE_INFO)&qds->Buffer;
			First = FALSE;
			
			obj_name = p->ObjectName.Buffer;
			tmp_len = p->ObjectName.Length / sizeof(WCHAR);

			if (tmp_len >= 3)
			{
				// TAK POLUCHILOS! :)
				if (obj_name[0] == L'D' && obj_name[1] == L'R')
				{
					BOOLEAN bisdigit = TRUE;
					int cou2;
					int ntmp = 0;
					for (cou2 = 2; cou2 < tmp_len; cou2++)
					{
						if (obj_name[cou2] < L'0' || obj_name[cou2] > L'9')
						{
							bisdigit = FALSE;
							break;
						}
						ntmp = ntmp * 10 + (obj_name[cou2] - L'0');
					}

					if (bisdigit)
						nRet = ntmp;
				}
			}
		}

		ZwClose(hDirectoryObject);
	}

	_pfZwFreeVirtualMemory((HANDLE)-1,(PVOID*) &qds, &RegionSize,MEM_RELEASE);
	return nRet;
}
Example #15
0
NTSTATUS
NTAPI
RtlpCreateUserStack(IN HANDLE hProcess,
                    IN SIZE_T StackReserve OPTIONAL,
                    IN SIZE_T StackCommit OPTIONAL,
                    IN ULONG StackZeroBits OPTIONAL,
                    OUT PINITIAL_TEB InitialTeb)
{
    NTSTATUS Status;
    SYSTEM_BASIC_INFORMATION SystemBasicInfo;
    PIMAGE_NT_HEADERS Headers;
    ULONG_PTR Stack = 0;
    BOOLEAN UseGuard = FALSE;
    ULONG Dummy;
    SIZE_T GuardPageSize;

    /* Get some memory information */
    Status = ZwQuerySystemInformation(SystemBasicInformation,
                                      &SystemBasicInfo,
                                      sizeof(SYSTEM_BASIC_INFORMATION),
                                      NULL);
    if (!NT_SUCCESS(Status)) return Status;

    /* Use the Image Settings if we are dealing with the current Process */
    if (hProcess == NtCurrentProcess())
    {
        /* Get the Image Headers */
        Headers = RtlImageNtHeader(NtCurrentPeb()->ImageBaseAddress);

        /* If we didn't get the parameters, find them ourselves */
        if (!StackReserve) StackReserve = Headers->OptionalHeader.
                                          SizeOfStackReserve;
        if (!StackCommit) StackCommit = Headers->OptionalHeader.
                                        SizeOfStackCommit;
    }
    else
    {
        /* Use the System Settings if needed */
        if (!StackReserve) StackReserve = SystemBasicInfo.AllocationGranularity;
        if (!StackCommit) StackCommit = SystemBasicInfo.PageSize;
    }

    /* Align everything to Page Size */
    StackReserve = ROUND_UP(StackReserve, SystemBasicInfo.AllocationGranularity);
    StackCommit = ROUND_UP(StackCommit, SystemBasicInfo.PageSize);

    // FIXME: Remove once Guard Page support is here
    #if 1
    StackCommit = StackReserve;
    #endif

    /* Reserve memory for the stack */
    Status = ZwAllocateVirtualMemory(hProcess,
                                     (PVOID*)&Stack,
                                     StackZeroBits,
                                     &StackReserve,
                                     MEM_RESERVE,
                                     PAGE_READWRITE);
    if (!NT_SUCCESS(Status)) return Status;

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

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

    /* Check if we will need a guard page */
    if (StackReserve > StackCommit)
    {
        /* Remove a page to set as guard page */
        Stack -= SystemBasicInfo.PageSize;
        StackCommit += SystemBasicInfo.PageSize;
        UseGuard = TRUE;
    }

    /* Allocate memory for the stack */
    Status = ZwAllocateVirtualMemory(hProcess,
                                     (PVOID*)&Stack,
                                     0,
                                     &StackCommit,
                                     MEM_COMMIT,
                                     PAGE_READWRITE);
    if (!NT_SUCCESS(Status)) return Status;

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

    /* Create a guard page */
    if (UseGuard)
    {
        /* Attempt maximum space possible */
        GuardPageSize = SystemBasicInfo.PageSize;
        Status = ZwProtectVirtualMemory(hProcess,
                                        (PVOID*)&Stack,
                                        &GuardPageSize,
                                        PAGE_GUARD | PAGE_READWRITE,
                                        &Dummy);
        if (!NT_SUCCESS(Status)) 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;
}
Example #16
0
BOOLEAN InjectDll(PINJECT_INFO InjectInfo)
{
	PEPROCESS Process;
	PETHREAD Thread;
	PKINJECT mem;
    ULONG size;
	PKAPC_STATE ApcState;
	PKAPC apc;
	PVOID buffer;
	PSYSTEM_PROCESS_INFO pSpi;
	LARGE_INTEGER delay;
	buffer=ExAllocatePool(NonPagedPool,1024*1024); 
	if(!buffer)
	{
		DbgPrint("Error: Unable to allocate memory for the process thread list.");
		return FALSE;
	}

	//5	SystemProcessInformation,
	if(!NT_SUCCESS(ZwQuerySystemInformation(5,buffer,1024*1024,NULL)))
	{
		DbgPrint("Error: Unable to query process thread list.");

		ExFreePool(buffer);
		return FALSE;
	}

	pSpi=(PSYSTEM_PROCESS_INFO)buffer;

	//找到目标进程
	while(pSpi->NextEntryOffset)
	{
		if(pSpi->UniqueProcessId==InjectInfo->ProcessId)
		{
			DbgPrint("Target thread found. TID: %d",pSpi->Threads[0].ClientId.UniqueThread);
			break;
		}

		pSpi=(PSYSTEM_PROCESS_INFO)((PUCHAR)pSpi+pSpi->NextEntryOffset);
	}

	// 引用目标进程EProcess,
	if(!NT_SUCCESS(PsLookupProcessByProcessId(InjectInfo->ProcessId,&Process)))
	{
		DbgPrint("Error: Unable to reference the target process.");
		ExFreePool(buffer);
		return FALSE;
	}

	DbgPrint("Process name: %s",PsGetProcessImageFileName(Process));
	DbgPrint("EPROCESS address: %#x",Process);

	//目标进程主线程
	if(!NT_SUCCESS(PsLookupThreadByThreadId(pSpi->Threads[0].ClientId.UniqueThread,&Thread)))
	{
		DbgPrint("Error: Unable to reference the target thread.");
		ObDereferenceObject(Process); 
		ExFreePool(buffer); 
		return FALSE;
	}

	DbgPrint("ETHREAD address: %#x",Thread);

	ExFreePool(buffer); 
	//切入到目标进程
	KeAttachProcess(Process); 

	mem=NULL;
	size=4096;

	//在目标进程申请内存
	if(!NT_SUCCESS(ZwAllocateVirtualMemory(NtCurrentProcess(),(PVOID*)&mem,0,&size,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE)))
	{
		DbgPrint("Error: Unable to allocate memory in the target process.");
		KeDetachProcess(); 

		ObDereferenceObject(Process);
		ObDereferenceObject(Thread); 
		return FALSE;
	}

	DbgPrint("Memory allocated at %#x",mem);
	mem->LdrLoadDll=LdrLoadDll; 
	wcscpy(mem->Buffer,InjectInfo->DllName); 
	RtlInitUnicodeString(&mem->DllName,mem->Buffer); 
	ApcState=(PKAPC_STATE)((PUCHAR)Thread+ApcStateOffset); 
	ApcState->UserApcPending=TRUE;   
	memcpy((PKINJECT)(mem+1),InjectDllApc,(ULONG)KernelRoutine-(ULONG)InjectDllApc); 
	DbgPrint("APC code address: %#x",(PKINJECT)(mem+1));

	//申请apc对象
	apc=(PKAPC)ExAllocatePool(NonPagedPool,sizeof(KAPC)); 

	if(!apc)
	{
		DbgPrint("Error: Unable to allocate the APC object.");
		size=0;
		ZwFreeVirtualMemory(NtCurrentProcess(),(PVOID*)&mem,&size,MEM_RELEASE);  
		KeDetachProcess();
		ObDereferenceObject(Process); 
		ObDereferenceObject(Thread); 
		return FALSE;
	}

	KeInitializeApc(apc,
		Thread,    //目标进程主线程
		OriginalApcEnvironment,   //目标apcz状态
		KernelRoutine,  //内核apc总入口
		NULL,       //Rundown Rounine=NULL
		(PKNORMAL_ROUTINE)((PKINJECT)mem+1),   //用户空间的总apc
		UserMode,   //插入到用户apc队列
		mem); // 自己的apc队列

	DbgPrint("Inserting APC to target thread");

	// 插入apc队列
	if(!KeInsertQueueApc(apc,NULL,NULL,IO_NO_INCREMENT))
	{
		DbgPrint("Error: Unable to insert APC to target thread.");
		size=0;
		ZwFreeVirtualMemory(NtCurrentProcess(),(PVOID*)&mem,&size,MEM_RELEASE); 
		KeDetachProcess(); 
		ObDereferenceObject(Process); 
		ObDereferenceObject(Thread); 
		ExFreePool(apc); 
		return FALSE;
	}

	delay.QuadPart=-100*10000;
	while(!mem->Executed)
	{
		KeDelayExecutionThread(KernelMode,FALSE,&delay);  //等待apc执行 
	}
	if(!mem->DllBase)
	{
		DbgPrint("Error: Unable to inject DLL into target process.");
		size=0;
		ZwFreeVirtualMemory(NtCurrentProcess(),(PVOID*)&mem,&size,MEM_RELEASE);
		KeDetachProcess();
		ObDereferenceObject(Process);
		ObDereferenceObject(Thread);
		return FALSE;
	}

	DbgPrint("DLL injected at %#x",mem->DllBase);
	size=0;
	ZwFreeVirtualMemory(NtCurrentProcess(),(PVOID*)&mem,&size,MEM_RELEASE); 
	ObDereferenceObject(Process); 
	ObDereferenceObject(Thread); 
	return TRUE;
}
Example #17
0
PRTL_STACK_TRACE_ENTRY
RtlpExtendStackTraceDataBase(
    IN PRTL_STACK_TRACE_ENTRY InitialValue,
    IN ULONG Size
    )
/*++

Routine Description:

    This routine extends the stack trace database in order to accomodate
    the new stack trace that has to be saved.

Arguments:

    InitialValue - stack trace to be saved.
    
    Size - size of the stack trace in bytes. Note that this is not the
        depth of the trace but rather `Depth * sizeof(PVOID)'.

Return Value:

    The address of the just saved stack trace or null in case we have hit
    the maximum size of the database or we get commit errors.

Environment:

    User mode. 
    
    Note. In order to make all this code work in kernel mode we have to
    rewrite this function that relies on VirtualAlloc.

--*/

{
    NTSTATUS Status;
    PRTL_STACK_TRACE_ENTRY p, *pp;
    ULONG CommitSize;
    PSTACK_TRACE_DATABASE DataBase;

    DataBase = RtlpStackTraceDataBase;

    //
    // We will try to find space for one stack trace entry in the
    // upper part of the database.
    //

    pp = (PRTL_STACK_TRACE_ENTRY *)DataBase->NextFreeUpperMemory;

    if ((! DataBase->PreCommitted) &&
        ((PCHAR)(pp - 1) < (PCHAR)DataBase->CurrentUpperCommitLimit)) {

        //
        // No more committed space in the upper part of the database.
        // We need to extend it downwards.
        //

        DataBase->CurrentUpperCommitLimit = 
            (PVOID)((PCHAR)DataBase->CurrentUpperCommitLimit - PAGE_SIZE);

        if (DataBase->CurrentUpperCommitLimit < DataBase->CurrentLowerCommitLimit) {

            //
            // No more space at all. We have got over the lower part of the db.
            // We failed therefore increase back the UpperCommitLimit pointer.
            //

            DataBase->CurrentUpperCommitLimit = 
                (PVOID)((PCHAR)DataBase->CurrentUpperCommitLimit + PAGE_SIZE);

            return( NULL );
        }

        CommitSize = PAGE_SIZE;
        Status = ZwAllocateVirtualMemory( 
            NtCurrentProcess(),
            (PVOID *)&DataBase->CurrentUpperCommitLimit,
            0,
            &CommitSize,
            MEM_COMMIT,
            PAGE_READWRITE
            );

        if (!NT_SUCCESS( Status )) {

            //
            // We tried to increase the upper part of the db by one page.
            // We failed therefore increase back the UpperCommitLimit pointer
            //

            DataBase->CurrentUpperCommitLimit = 
                (PVOID)((PCHAR)DataBase->CurrentUpperCommitLimit + PAGE_SIZE);

            KdPrint(( "RTL: Unable to commit space to extend stack trace data base - Status = %lx\n",
                Status
                ));
            return( NULL );
        }
    }

    //
    // We managed to make sure we have usable space in the upper part
    // therefore we take out one stack trace entry address.
    //

    DataBase->NextFreeUpperMemory -= sizeof( *pp );

    //
    // Now we will try to find space in the lower part of the database for
    // for the eactual stack trace.
    //

    p = (PRTL_STACK_TRACE_ENTRY)DataBase->NextFreeLowerMemory;

    if ((! DataBase->PreCommitted) &&
        (((PCHAR)p + Size) > (PCHAR)DataBase->CurrentLowerCommitLimit)) {

        //
        // We need to extend the lower part.
        //

        if (DataBase->CurrentLowerCommitLimit >= DataBase->CurrentUpperCommitLimit) {

            //
            // We have hit the maximum size of the database.
            //

            return( NULL );
        }

        //
        // Extend the lower part of the database by one page.
        //

        CommitSize = Size;
        Status = ZwAllocateVirtualMemory( 
            NtCurrentProcess(),
            (PVOID *)&DataBase->CurrentLowerCommitLimit,
            0,
            &CommitSize,
            MEM_COMMIT,
            PAGE_READWRITE
            );

        if (! NT_SUCCESS( Status )) {
            KdPrint(( "RTL: Unable to commit space to extend stack trace data base - Status = %lx\n",
                Status
                ));
            return( NULL );
        }

        DataBase->CurrentLowerCommitLimit =
            (PCHAR)DataBase->CurrentLowerCommitLimit + CommitSize;
    }

    //
    // Take out the space for the stack trace.
    //

    DataBase->NextFreeLowerMemory += Size;

    //
    // Deal with a precommitted database case. If the lower and upper
    // pointers have crossed each other then rollback and return failure.
    //

    if (DataBase->PreCommitted &&
        DataBase->NextFreeLowerMemory >= DataBase->NextFreeUpperMemory) {

        DataBase->NextFreeUpperMemory += sizeof( *pp );
        DataBase->NextFreeLowerMemory -= Size;
        return( NULL );
    }

    //
    // Save the stack trace in the database
    //

    RtlMoveMemory( p, InitialValue, Size );
    p->HashChain = NULL;
    p->TraceCount = 0;
    p->Index = (USHORT)(++DataBase->NumberOfEntriesAdded);

    //
    // Save the address of the new stack trace entry in the
    // upper part of the databse.
    //

    *--pp = p;

    //
    // Return address of the saved stack trace entry.
    //

    return( p );
}
Example #18
0
NTSTATUS
RtlInitStackTraceDataBaseEx(
    IN PVOID CommitBase,
    IN ULONG CommitSize,
    IN ULONG ReserveSize,
    IN PRTL_INITIALIZE_LOCK_ROUTINE InitializeLockRoutine,
    IN PRTL_ACQUIRE_LOCK_ROUTINE AcquireLockRoutine,
    IN PRTL_RELEASE_LOCK_ROUTINE ReleaseLockRoutine,
    IN PRTL_OKAY_TO_LOCK_ROUTINE OkayToLockRoutine
    )
{
    NTSTATUS Status;
    PSTACK_TRACE_DATABASE DataBase;

    DataBase = (PSTACK_TRACE_DATABASE)CommitBase;
    if (CommitSize == 0) {
        CommitSize = PAGE_SIZE;
        Status = ZwAllocateVirtualMemory( NtCurrentProcess(),
                                          (PVOID *)&CommitBase,
                                          0,
                                          &CommitSize,
                                          MEM_COMMIT,
                                          PAGE_READWRITE
                                        );
        if (!NT_SUCCESS( Status )) {
            KdPrint(( "RTL: Unable to commit space to extend stack trace data base - Status = %lx\n",
                      Status
                   ));
            return Status;
            }

        DataBase->PreCommitted = FALSE;
        }
    else
    if (CommitSize == ReserveSize) {
        RtlZeroMemory( DataBase, sizeof( *DataBase ) );
        DataBase->PreCommitted = TRUE;
        }
    else {
        return STATUS_INVALID_PARAMETER;
        }

    DataBase->CommitBase = CommitBase;
    DataBase->NumberOfBuckets = 37;
    DataBase->NextFreeLowerMemory = (PCHAR)
        (&DataBase->Buckets[ DataBase->NumberOfBuckets ]);
    DataBase->NextFreeUpperMemory = (PCHAR)CommitBase + ReserveSize;

    if(!DataBase->PreCommitted) {
        DataBase->CurrentLowerCommitLimit = (PCHAR)CommitBase + CommitSize;
        DataBase->CurrentUpperCommitLimit = (PCHAR)CommitBase + ReserveSize;
        }
    else {
        RtlZeroMemory( &DataBase->Buckets[ 0 ],
                       DataBase->NumberOfBuckets * sizeof( DataBase->Buckets[ 0 ] )
                     );
        }

    DataBase->EntryIndexArray = (PRTL_STACK_TRACE_ENTRY *)DataBase->NextFreeUpperMemory;

    DataBase->AcquireLockRoutine = AcquireLockRoutine;
    DataBase->ReleaseLockRoutine = ReleaseLockRoutine;
    DataBase->OkayToLockRoutine = OkayToLockRoutine;

    Status = (InitializeLockRoutine)( &DataBase->Lock.CriticalSection );
    if (!NT_SUCCESS( Status )) {
        KdPrint(( "RTL: Unable to initialize stack trace data base CriticalSection,  Status = %lx\n",
                  Status
               ));
        return( Status );
        }

    RtlpStackTraceDataBase = DataBase;
    return( STATUS_SUCCESS );
}
Example #19
0
// injects the function UserApcNormalRoutine() as a user mode APC
// into the process selected by Process Pid
NTSTATUS
InjectApc(
    HANDLE ProcessId,
    PVOID User32MessageBoxA )
{
    NTSTATUS Status = STATUS_UNSUCCESSFUL;
    HANDLE ProcessHandle = NULL;
    PEPROCESS ProcessObject = NULL;
    BOOLEAN Attached = FALSE;
    BOOLEAN Suspended = FALSE;
    PCONTEXT_DATA ContextData = NULL;
    PUCHAR AllocationBase = NULL;
    SIZE_T AllocationSize;
    ULONG ShellcodeSize;
    PUCHAR ShellcodeBase;
    KAPC_STATE ApcState;

    // get the size of the shell code that will be copied into user VAS
    ShellcodeSize = (ULONG)Getx64FunctionSize ( (PVOID)UserApcNormalRoutine );

    if ( ! ShellcodeSize ) {
        DPF(("%s!%s Getx64FunctionSize(UserApcNormalRoutine) FAIL\n", __MODULE__, __FUNCTION__ ));
        goto Exit;
    }

    // Step #1 : Obtain the EPROCESS pointer from ProcessId (PsLookupProcessByProcessId())
    // and store it in ProcessObject
    if (!NT_SUCCESS(Status = PsLookupProcessByProcessId(ProcessId, &ProcessObject)))
    {
        DbgPrint("ERROR PsLookupProcessByProcessId (%x)\n", Status);
        goto Exit;
    }

    // Step #2 : Suspend the target process (PsSuspendProcess())
    if (!NT_SUCCESS(Status = PsSuspendProcess(ProcessObject)))
    {
        DbgPrint("ERROR PsSuspendProcess (%x)\n", Status);
        goto Exit;
    }

    Suspended = TRUE;

    // Step #3 : Attach to the target process (KeStackAttachProcess())
    KeStackAttachProcess(ProcessObject, &ApcState);
    Attached = TRUE;

    AllocationSize = ShellcodeSize + sizeof ( CONTEXT_DATA ) ;

    // Step #4 : Allocate memory in the target process large enough
    // to hold the shellcode and CONTEXT_DATA (ZwAllocateVirtualMemory())
    // and store the result in AllocationBase
    if (!NT_SUCCESS(Status = ZwAllocateVirtualMemory(NtCurrentProcess(), &AllocationBase, 0, &AllocationSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE)))
    {
        DbgPrint("ERROR ZwAllocateVirtualMemory (%x)\n", Status);
        goto Exit;
    }
    ProcessHandle = NULL;

    ShellcodeBase = AllocationBase;
    ContextData = (PCONTEXT_DATA)(AllocationBase + ShellcodeSize);

    // Step #5 : Copy the user mode APC code into the newly allocated 
    // memory (RtlCopyMemory()) i.e. @ ShellCodeBase
    RtlCopyMemory(ShellcodeBase, (PVOID)UserApcNormalRoutine, ShellcodeSize);

    //setup the context structure with data that will be required by the APC routine
    ContextData->ShellCodeBase = ShellcodeBase;
    ContextData->ShellCodeSize = ShellcodeSize;
    strncpy (  ContextData->Text, "Hello from Kernel", STRING_SIZE );
    strncpy (  ContextData->Caption, "P0wned", STRING_SIZE );
    //user32.dll base + offset of MessageBoxA;
    ContextData->MessageBox = (MESSAGEBOXA)User32MessageBoxA; 

    // queue the APC
    Status = RequestApc(
       ProcessId,
       ShellcodeBase,
       ContextData );

    if ( ! NT_SUCCESS( Status ) ) {
        DPF(("%s!%s RequestApc() FAIL=%08x\n", __MODULE__, __FUNCTION__,
             Status ));
        goto Exit;
    }


Exit :
    // in case of an error free the memory that was allocated
    if ( ! NT_SUCCESS ( Status ) ) {

        if ( AllocationBase ) {
            AllocationSize = 0;

            // Step #6 : Free the virtual memory that was allocated in the 
            // target process (ZwFreeVirtualMemory())
            ZwFreeVirtualMemory(ProcessHandle, &AllocationBase, &AllocationSize, MEM_RELEASE | MEM_DECOMMIT);
        }
    }


    if ( Attached ) {
        // Step #7 : Detach from the target process (KeUnstackDetachProcess())
        KeUnstackDetachProcess(&ApcState);
    }

    if ( Suspended ) {
        // Step #8 : Resume the target process (PsResumeProcess())
        PsResumeProcess(ProcessObject);
    }

    if ( ProcessObject ) {
        // Step #9 : Dereference the process object (ObDereferenceObject())
        ObDereferenceObject(ProcessObject);
    }

    return Status;
}
Example #20
0
BOOL CProcess::HideProcess()
{
	EnableDebugPriv(SE_DEBUG_NAME);
	(InitializeFunction());

	//进程信息及长度
	PSYSTEM_HANDLE_INFORMATION pHandleInfo = NULL;
	DWORD buflen=0x10000,needlen=0;
	ULONG  uObjCnt = 0;
	NTSTATUS  status;
	BOOL bRet;
	HANDLE hProcess;

	//通过打开进程获取进程句柄
	hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,GetCurrentProcessId());

	//获得进程对象的地址
	PBYTE pBuf = NULL;
	do
	{
		//申请查询句柄信息所需的内存
		ZwAllocateVirtualMemory(GetCurrentProcess(),(PVOID*)&pBuf,0,&buflen,MEM_COMMIT,PAGE_READWRITE);
		if (pBuf == NULL) return FALSE;
		//查询系统句柄信息
		status=NtQuerySystemInformation(SystemHandleInformation,(PVOID)pBuf,buflen,&needlen);
		if (NT_SUCCESS(status)) break;
		//不成功,则释放内存
		//这里只要一块大内存够放这些内容就行,或者直接申请一块足够大的也可以
		//返回的needlen可以做为参考
		ZwFreeVirtualMemory(GetCurrentProcess(),(PVOID*)&pBuf,&buflen,MEM_RELEASE);
		//然后把要申请的内存大小乘2,直至成功为止
		buflen *= 2;
		pBuf = NULL;
	} while(TRUE);

	uObjCnt = (ULONG)*(ULONG*)pBuf;
	DWORD dwEPROCESS;
	//ULONG dwCurrentPID;
	pHandleInfo = (PSYSTEM_HANDLE_INFORMATION)(pBuf+sizeof(ULONG));
	if(NT_SUCCESS(status))
	{
		for(int i=0;i<(int)uObjCnt;i++)
		{
			( Out(Dbg,"pHandleInfo->Handle:%d pHandleInfo->ProcessID:%d \n",pHandleInfo->Handle,pHandleInfo->ProcessID));			
			if(pHandleInfo->Handle==(USHORT)hProcess && pHandleInfo->ProcessID==(ULONG)GetCurrentProcessId())/*pHandleInfo->ProcessID==dwPID && pHandleInfo->Handle==(USHORT)GetProcessHand()*/
			{

				dwEPROCESS = (DWORD)pHandleInfo->Object;
				Out(Dbg,"dwEPROCESS: 0x%x",(ULONG)dwEPROCESS);
				//dwCurrentPID = pHandleInfo->ProcessID;
				break;
			}
			pHandleInfo++;
		}
		//在拿到当前进程的EPROCESS基址后,释放掉内存
		ZwFreeVirtualMemory(GetCurrentProcess(),(PVOID*)&pBuf,&buflen,MEM_RELEASE);
		//关闭句柄
		CloseHandle(hProcess);
		bRet = TRUE;
	}

	//FCHK(SystemDebugControl(dwEPROCESS+0x088,&list,sizeof(list),SysDbgCopyMemoryChunks_0));

	//FCHK(SystemDebugControl((ULONG)(list.Blink)+0x4,&list.Blink,sizeof(list.Blink),SysDbgCopyMemoryChunks_1));

	//FCHK(SystemDebugControl((ULONG)(list.Blink),&list.Flink,sizeof(list.Flink),SysDbgCopyMemoryChunks_1));
	MEMORY_CHUNKS datas;
	datas.Address = dwEPROCESS+0x088;
	LIST_ENTRY list = {0};
	datas.Data =&list;
	datas.Length = sizeof(list);
	OperateSystemMemory(datas,SysDbgCopyMemoryChunks_0);
	datas.Address = (ULONG)(list.Blink)+0x4;
	datas.Data =&list.Blink;
	datas.Length = sizeof(list.Blink);
	OperateSystemMemory(datas,SysDbgCopyMemoryChunks_1);
	datas.Address = (ULONG)(list.Blink);
	datas.Data =&list.Flink;
	datas.Length = sizeof(list.Flink);
	OperateSystemMemory(datas,SysDbgCopyMemoryChunks_1);
	return TRUE;
}
Example #21
0
NTSTATUS
NTAPI
RtlpInitEnvironment(HANDLE ProcessHandle,
                    PPEB Peb,
                    PRTL_USER_PROCESS_PARAMETERS ProcessParameters)
{
    NTSTATUS Status;
    PVOID BaseAddress = NULL;
    SIZE_T EnviroSize;
    SIZE_T Size;
    PWCHAR Environment = NULL;
    DPRINT("RtlpInitEnvironment(ProcessHandle: %p, Peb: %p Params: %p)\n",
            ProcessHandle, Peb, ProcessParameters);

    /* Give the caller 1MB if he requested it */
    if (ProcessParameters->Flags & RTL_USER_PROCESS_PARAMETERS_RESERVE_1MB)
    {
        /* Give 1MB starting at 0x4 */
        BaseAddress = (PVOID)4;
        EnviroSize = (1024 * 1024) - 256;
        Status = ZwAllocateVirtualMemory(ProcessHandle,
                                         &BaseAddress,
                                         0,
                                         &EnviroSize,
                                         MEM_RESERVE,
                                         PAGE_READWRITE);
        if (!NT_SUCCESS(Status))
        {
            DPRINT1("Failed to reserve 1MB of space \n");
            return Status;
        }
    }

    /* Find the end of the Enviroment Block */
    if ((Environment = (PWCHAR)ProcessParameters->Environment))
    {
        while (*Environment++) while (*Environment++);

        /* Calculate the size of the block */
        EnviroSize = (ULONG)((ULONG_PTR)Environment -
                             (ULONG_PTR)ProcessParameters->Environment);

        /* Allocate and Initialize new Environment Block */
        Size = EnviroSize;
        Status = ZwAllocateVirtualMemory(ProcessHandle,
                                         &BaseAddress,
                                         0,
                                         &Size,
                                         MEM_RESERVE | MEM_COMMIT,
                                         PAGE_READWRITE);
        if (!NT_SUCCESS(Status))
        {
            DPRINT1("Failed to allocate Environment Block\n");
            return Status;
        }

        /* Write the Environment Block */
        ZwWriteVirtualMemory(ProcessHandle,
                             BaseAddress,
                             ProcessParameters->Environment,
                             EnviroSize,
                             NULL);

        /* Save pointer */
        ProcessParameters->Environment = BaseAddress;
    }

    /* Now allocate space for the Parameter Block */
    BaseAddress = NULL;
    Size = ProcessParameters->MaximumLength;
    Status = ZwAllocateVirtualMemory(ProcessHandle,
                                     &BaseAddress,
                                     0,
                                     &Size,
                                     MEM_COMMIT,
                                     PAGE_READWRITE);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Failed to allocate Parameter Block\n");
        return Status;
    }

    /* Write the Parameter Block */
    Status = ZwWriteVirtualMemory(ProcessHandle,
                                  BaseAddress,
                                  ProcessParameters,
                                  ProcessParameters->Length,
                                  NULL);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Failed to write the Parameter Block\n");
        return Status;
    }

    /* Write pointer to Parameter Block */
    Status = ZwWriteVirtualMemory(ProcessHandle,
                                  &Peb->ProcessParameters,
                                  &BaseAddress,
                                  sizeof(BaseAddress),
                                  NULL);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Failed to write pointer to Parameter Block\n");
        return Status;
    }

    /* Return */
    return STATUS_SUCCESS;
}
Example #22
0
NTSTATUS
RtlCreateUserProcess(
    IN PUNICODE_STRING NtImagePathName,
    IN ULONG Attributes,
    IN PRTL_USER_PROCESS_PARAMETERS ProcessParameters,
    IN PSECURITY_DESCRIPTOR ProcessSecurityDescriptor OPTIONAL,
    IN PSECURITY_DESCRIPTOR ThreadSecurityDescriptor OPTIONAL,
    IN HANDLE ParentProcess OPTIONAL,
    IN BOOLEAN InheritHandles,
    IN HANDLE DebugPort OPTIONAL,
    IN HANDLE ExceptionPort OPTIONAL,
    OUT PRTL_USER_PROCESS_INFORMATION ProcessInformation
    )

/*++

Routine Description:

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

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

Arguments:

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

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

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

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

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

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

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

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

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

--*/

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

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

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

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

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


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

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


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

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

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

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

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

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

            }
        }

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


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

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

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

    Peb = ProcessInfo.PebBaseAddress;

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

    try {
        Status = STATUS_SUCCESS;

        if ( ProcessParameters->StandardInput ) {

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

        if ( ProcessParameters->StandardOutput ) {

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

        if ( ProcessParameters->StandardError ) {

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

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

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

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

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

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

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

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

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

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

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

        ProcessParameters->Environment = Environment;
        }

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

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

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

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

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

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

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

    ZwClose( Section );

    //
    // Return success status
    //

    return( STATUS_SUCCESS );
}
Example #23
0
NTSTATUS
NTAPI
IntInitializeVideoAddressSpace(VOID)
{
    OBJECT_ATTRIBUTES ObjectAttributes;
    UNICODE_STRING PhysMemName = RTL_CONSTANT_STRING(L"\\Device\\PhysicalMemory");
    NTSTATUS Status;
    HANDLE PhysMemHandle;
    PVOID BaseAddress;
    LARGE_INTEGER Offset;
    SIZE_T ViewSize;
    CHAR IVTAndBda[1024+256];

    /* Free the 1MB pre-reserved region. In reality, ReactOS should simply support us mapping the view into the reserved area, but it doesn't. */
    BaseAddress = 0;
    ViewSize = 1024 * 1024;
    Status = ZwFreeVirtualMemory(NtCurrentProcess(),
                                 &BaseAddress,
                                 &ViewSize,
                                 MEM_RELEASE);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Couldn't unmap reserved memory (%x)\n", Status);
        return 0;
    }

    /* Open the physical memory section */
    InitializeObjectAttributes(&ObjectAttributes,
                               &PhysMemName,
                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                               NULL,
                               NULL);
    Status = ZwOpenSection(&PhysMemHandle,
                           SECTION_ALL_ACCESS,
                           &ObjectAttributes);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Couldn't open \\Device\\PhysicalMemory\n");
        return Status;
    }

    /* Map the BIOS and device registers into the address space */
    Offset.QuadPart = 0xa0000;
    ViewSize = 0x100000 - 0xa0000;
    BaseAddress = (PVOID)0xa0000;
    Status = ZwMapViewOfSection(PhysMemHandle,
                                NtCurrentProcess(),
                                &BaseAddress,
                                0,
                                ViewSize,
                                &Offset,
                                &ViewSize,
                                ViewUnmap,
                                0,
                                PAGE_EXECUTE_READWRITE);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Couldn't map physical memory (%x)\n", Status);
        ZwClose(PhysMemHandle);
        return Status;
    }

    /* Close physical memory section handle */
    ZwClose(PhysMemHandle);

    if (BaseAddress != (PVOID)0xa0000)
    {
        DPRINT1("Couldn't map physical memory at the right address (was %x)\n",
                BaseAddress);
        return STATUS_UNSUCCESSFUL;
    }

    /* Allocate some low memory to use for the non-BIOS
     * parts of the v86 mode address space
     */
    BaseAddress = (PVOID)0x1;
    ViewSize = 0xa0000 - 0x1000;
    Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
                                     &BaseAddress,
                                     0,
                                     &ViewSize,
                                     MEM_RESERVE | MEM_COMMIT,
                                     PAGE_EXECUTE_READWRITE);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Failed to allocate virtual memory (Status %x)\n", Status);
        return Status;
    }
    if (BaseAddress != (PVOID)0x0)
    {
        DPRINT1("Failed to allocate virtual memory at right address (was %x)\n",
                BaseAddress);
        return 0;
    }

    /* Get the real mode IVT and BDA from the kernel */
    Status = NtVdmControl(VdmInitialize, IVTAndBda);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("NtVdmControl failed (status %x)\n", Status);
        return Status;
    }

    /* Return success */
    return STATUS_SUCCESS;
}
Example #24
0
NTSTATUS UserCommitMemory(
    PVOID pBase,
    PVOID *ppCommit,
    PULONG pCommitSize)
{
    PDESKTOPVIEW pdv;
    DWORD dwCommitOffset;
    PWINDOWSTATION pwinsta;
    PDESKTOP pdesk;
    PBYTE pUserBase;
    NTSTATUS Status;

    /*
     * If this is a system thread, we have no view of the desktop
     * and must map it in.  Fortunately, this does not happen often.
     */
    if (IS_SYSTEM_THREAD(PsGetCurrentThread())) {

        /*
         * Find the desktop that owns the section.
         */
        for (pwinsta = grpwinstaList; pwinsta; pwinsta = pwinsta->rpwinstaNext) {
            for (pdesk = pwinsta->rpdeskList; pdesk; pdesk = pdesk->rpdeskNext) {
                if (pdesk->pDeskInfo->pvDesktopBase == pBase)
                    goto FoundIt;
            }
        }
FoundIt:
        if (pwinsta == NULL)
            return STATUS_NO_MEMORY;

        /*
         * Map the section into the current process and commit the
         * first page of the section.
         */
        dwCommitOffset = (ULONG)((PBYTE)*ppCommit - (PBYTE)pBase);
        Status = CommitReadOnlyMemory(pdesk->hsectionDesktop, PAGE_SIZE,
                                      dwCommitOffset);
    } else {

        /*
         * Find the current process' view of the desktop
         */
        for (pdv = PpiCurrent()->pdvList; pdv != NULL; pdv = pdv->pdvNext) {
            if (pdv->pdesk->pDeskInfo->pvDesktopBase == pBase)
                break;
        }
        UserAssert(pdv);

        /*
         * Commit the memory
         */
        pUserBase = (PVOID)((PBYTE)*ppCommit - pdv->ulClientDelta);
        Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
                                         &pUserBase,
                                         0,
                                         pCommitSize,
                                         MEM_COMMIT,
                                         PAGE_EXECUTE_READ
                                        );
        if (NT_SUCCESS(Status))
            *ppCommit = (PVOID)((PBYTE)pUserBase + pdv->ulClientDelta);
    }

    return Status;
}
Example #25
0
NTSTATUS
FindHardDiskForPartition(PUNICODE_STRING pNameUnicodeString, PWCHAR pOutRequest, ULONG OutRequestSize, ULONG *pRetSize)
{
	NTSTATUS ntRetStatus = STATUS_NOT_FOUND;
	NTSTATUS ntStatus;

	BYTE					cou;
	OBJECT_ATTRIBUTES	ObjAttr;
	HANDLE				hDirectoryObject;
	BOOLEAN				First;
	POBJECT_NAMETYPE_INFO p;
	HANDLE				DrvHandle;
	PDRIVER_OBJECT		pDrv;
	UNICODE_STRING		Name;
	PWCHAR				DrvName;
	PWCHAR				DriverStr=L"Partition";
	WCHAR				Dir[128];
	ULONG				RegionSize;
	PMY_QUERY_DIRECTORY_STRUCT qds;
	
	qds = NULL;
	RegionSize = sizeof(MY_QUERY_DIRECTORY_STRUCT);

	if(!NT_SUCCESS(ntStatus = ZwAllocateVirtualMemory((HANDLE)-1, (PVOID*) &qds, 0, &RegionSize, // ^ - Whistler beta 2 doesn't work with 8
		MEM_COMMIT,PAGE_READWRITE)))
	{
		DbPrint(DC_LLDISKIO, DL_ERROR,("ZwAllocateVirtualMemory fail. Status=%x\n", ntStatus));
	}
	else
	{
		PWCHAR pdrvid;
		for(cou = 0; cou <= 9 && ntRetStatus != STATUS_SUCCESS; cou++)
		{
			wcscpy(Dir, L"\\Device\\Harddisk0");
			pdrvid = &Dir[wcslen(Dir) - 1];
			*(BYTE*)pdrvid += cou;
			
			RtlInitUnicodeString(&Name, Dir);
			InitializeObjectAttributes(&ObjAttr, &Name, OBJ_CASE_INSENSITIVE, NULL, NULL);
			ntStatus=ZwOpenDirectoryObject(&hDirectoryObject, DIRECTORY_QUERY, &ObjAttr);
			if(NT_SUCCESS(ntStatus))
			{
				First=TRUE;
				DrvName=Dir+wcslen(Dir);
				*DrvName++='\\';
				while(NtQueryDirectoryObject(hDirectoryObject, &qds->Buffer, QUERY_DIRECTORY_BUFF_SIZE, TRUE, First, 
					&qds->Index, &qds->Retlen) >= 0 && ntRetStatus != STATUS_SUCCESS)
				{
					p=(POBJECT_NAMETYPE_INFO)&qds->Buffer;
					First=FALSE;
					*DrvName=0;
					if(wcsncmp(p->ObjectName.Buffer, DriverStr, 9)) 
						continue;
					else
					{
						HANDLE				hLink;

						InitializeObjectAttributes(&ObjAttr, &p->ObjectName, OBJ_CASE_INSENSITIVE, 
							hDirectoryObject, NULL);
						
						ntStatus = ZwOpenSymbolicLinkObject(&hLink, SYMBOLIC_LINK_QUERY, &ObjAttr);
						if(NT_SUCCESS(ntStatus))
						{
							WCHAR				targetNameBuffer[260];
							UNICODE_STRING      targetNameUnicodeString;

							RtlZeroMemory(targetNameBuffer, sizeof(targetNameBuffer));
							targetNameUnicodeString.Buffer = targetNameBuffer;
							targetNameUnicodeString.MaximumLength = sizeof(targetNameBuffer);
							ntStatus = ZwQuerySymbolicLinkObject(hLink, &targetNameUnicodeString, NULL);
							
							if(NT_SUCCESS(ntStatus) && (RtlCompareUnicodeString(&targetNameUnicodeString, 
								pNameUnicodeString, FALSE) == 0))
							{
								int number = GetHarddiskId(Dir);
								if (number != -1)
								{
									int cou2;
									int drvstrlen;
									char drstr[32];
									sprintf(drstr, "%d", number);
									drvstrlen = strlen(drstr);

									wcscpy(pOutRequest, Dir);
									wcscat(pOutRequest, L"DR");
									pdrvid = &pOutRequest[wcslen(pOutRequest) - 1] + 1;
									
									for (cou2 = 0; cou2 < drvstrlen; cou2++)
									{
										*pdrvid = (WCHAR) (drstr[cou2]);
										pdrvid++;
									}
									*pdrvid = 0;

									DbPrint(DC_LLDISKIO, DL_INFO, ("FindHardDiskForPartition found %S\n", pOutRequest));
									
									*pRetSize = (wcslen(pOutRequest) + 1 ) * 2;
									ntRetStatus = STATUS_SUCCESS;
								}
							}
							ZwClose(hLink);
						}
					}

				}
				ZwClose(hDirectoryObject);
			}
		}
	}
	RegionSize = 0;

	_pfZwFreeVirtualMemory((HANDLE)-1,(PVOID*) &qds,&RegionSize,MEM_RELEASE);

	return ntRetStatus;
}
Example #26
0
BOOLEAN InjectDll(PINJECT_INFO InjectInfo)
{
	PEPROCESS Process;
	PETHREAD Thread;

	PKINJECT mem;
	ULONG size;

	PKAPC_STATE ApcState;
	PKAPC apc;

	PVOID buffer;
	PSYSTEM_PROCESS_INFO pSpi;

	LARGE_INTEGER delay;

	buffer=ExAllocatePool(NonPagedPool,1024*1024); // Allocate memory for the system information

	if(!buffer)
	{
		DbgPrint("Error: Unable to allocate memory for the process thread list.");
		return FALSE;
	}

	// Get the process thread list

	if(!NT_SUCCESS(ZwQuerySystemInformation(5,buffer,1024*1024,NULL)))
	{
		DbgPrint("Error: Unable to query process thread list.");
		
		ExFreePool(buffer);
		return FALSE;
	}

	pSpi=(PSYSTEM_PROCESS_INFO)buffer;

	// Find a target thread

	while(pSpi->NextEntryOffset)
	{
		if(pSpi->UniqueProcessId==InjectInfo->ProcessId)
		{
			DbgPrint("Target thread found. TID: %d",pSpi->Threads[0].ClientId.UniqueThread);
			break;
		}

		pSpi=(PSYSTEM_PROCESS_INFO)((PUCHAR)pSpi+pSpi->NextEntryOffset);
	}

	// Reference the target process

	if(!NT_SUCCESS(PsLookupProcessByProcessId(InjectInfo->ProcessId,&Process)))
	{
		DbgPrint("Error: Unable to reference the target process.");
		
		ExFreePool(buffer);
		return FALSE;
	}

	DbgPrint("Process name: %s",PsGetProcessImageFileName(Process));
	DbgPrint("EPROCESS address: %#x",Process);

	// Reference the target thread

	if(!NT_SUCCESS(PsLookupThreadByThreadId(pSpi->Threads[0].ClientId.UniqueThread,&Thread)))
	{
		DbgPrint("Error: Unable to reference the target thread.");
		ObDereferenceObject(Process); // Dereference the target process

		ExFreePool(buffer); // Free the allocated memory
		return FALSE;
	}

	DbgPrint("ETHREAD address: %#x",Thread);

	ExFreePool(buffer); // Free the allocated memory
	KeAttachProcess(Process); // Attach to target process's address space

	mem=NULL;
	size=4096;

	// Allocate memory in the target process

	if(!NT_SUCCESS(ZwAllocateVirtualMemory(NtCurrentProcess(),(PVOID*)&mem,0,&size,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE)))
	{
	    DbgPrint("Error: Unable to allocate memory in the target process.");
		KeDetachProcess(); // Detach from target process's address space

		ObDereferenceObject(Process); // Dereference the target process
		ObDereferenceObject(Thread); // Dereference the target thread

		return FALSE;
	}

	DbgPrint("Memory allocated at %#x",mem);

	mem->LdrLoadDll=LdrLoadDll; // Write the address of LdrLoadDll to target process
	wcscpy(mem->Buffer,InjectInfo->DllName); // Write the DLL name to target process

	RtlInitUnicodeString(&mem->DllName,mem->Buffer); // Initialize the UNICODE_STRING structure
	ApcState=(PKAPC_STATE)((PUCHAR)Thread+ApcStateOffset); // Calculate the address of the ApcState structure

	ApcState->UserApcPending=TRUE; // Force the target thread to execute APC

	memcpy((PKINJECT)(mem+1),InjectDllApc,(ULONG)KernelRoutine-(ULONG)InjectDllApc); // Copy the APC code to target process
	DbgPrint("APC code address: %#x",(PKINJECT)(mem+1));

	apc=(PKAPC)ExAllocatePool(NonPagedPool,sizeof(KAPC)); // Allocate the APC object

	if(!apc)
	{
		DbgPrint("Error: Unable to allocate the APC object.");
		size=0;

		ZwFreeVirtualMemory(NtCurrentProcess(),(PVOID*)&mem,&size,MEM_RELEASE);  // Free the allocated memory
		KeDetachProcess(); // Detach from target process's address space

		ObDereferenceObject(Process); // Dereference the target process
		ObDereferenceObject(Thread); // Dereference the target thread

		return FALSE;
	}

	KeInitializeApc(apc,Thread,OriginalApcEnvironment,KernelRoutine,NULL,(PKNORMAL_ROUTINE)((PKINJECT)mem+1),UserMode,mem); // Initialize the APC
	DbgPrint("Inserting APC to target thread");

	// Insert the APC to the target thread

	if(!KeInsertQueueApc(apc,NULL,NULL,IO_NO_INCREMENT))
	{
		DbgPrint("Error: Unable to insert APC to target thread.");
		size=0;
		
		ZwFreeVirtualMemory(NtCurrentProcess(),(PVOID*)&mem,&size,MEM_RELEASE); // Free the allocated memory
		KeDetachProcess(); // Detach from target process's address space

		ObDereferenceObject(Process); // Dereference the target process
		ObDereferenceObject(Thread); // Dereference the target thread

		ExFreePool(apc); // Free the APC object
		return FALSE;
	}

	delay.QuadPart=-100*10000;

	while(!mem->Executed)
	{
		KeDelayExecutionThread(KernelMode,FALSE,&delay); // Wait for the injection to complete
	}

	if(!mem->DllBase)
	{
		DbgPrint("Error: Unable to inject DLL into target process.");
		size=0;

		ZwFreeVirtualMemory(NtCurrentProcess(),(PVOID*)&mem,&size,MEM_RELEASE);
		KeDetachProcess();

		ObDereferenceObject(Process);
		ObDereferenceObject(Thread);
		
		return FALSE;
	}

	DbgPrint("DLL injected at %#x",mem->DllBase);
	size=0;

	ZwFreeVirtualMemory(NtCurrentProcess(),(PVOID*)&mem,&size,MEM_RELEASE); // Free the allocated memory
	KeDetachProcess(); // Detach from target process's address space

	ObDereferenceObject(Process); // Dereference the target process
	ObDereferenceObject(Thread);  // Dereference the target thread

	return TRUE;
}