Пример #1
0
/*
 * @implemented
 */
PVOID
LoadOle32Export(PVOID * BaseAddress, const PCHAR ProcedureName)
{
    NTSTATUS Status;
    ANSI_STRING ExportName;
    PVOID ProcedureAddress;

    /* First load ole32.dll */
    Status = LdrLoadDll(NULL, NULL, &Old32Dll, BaseAddress);
    if (!NT_SUCCESS(Status))
    {
        RtlRaiseStatus(Status);
    }

    RtlInitAnsiString(&ExportName, ProcedureName);

    /* Look for the procedure */
    Status = LdrGetProcedureAddress(*BaseAddress, &ExportName,
                                    0, &ProcedureAddress);
    if (!NT_SUCCESS(Status))
    {
        RtlRaiseStatus(Status);
    }

    /* Return its address */
    return ProcedureAddress;
}
Пример #2
0
BOOL
NTAPI
FirstSoundSentry(VOID)
{
    UNICODE_STRING DllString = RTL_CONSTANT_STRING(L"winsrv");
    STRING FuncString = RTL_CONSTANT_STRING("_UserSoundSentry");
    HANDLE DllHandle;
    NTSTATUS Status;
    PUSER_SOUND_SENTRY NewSoundSentry = FailSoundSentry;

    /* Load winsrv manually */
    Status = LdrGetDllHandle(NULL, NULL, &DllString, &DllHandle);
    if (NT_SUCCESS(Status))
    {
        /* If it was found, get SoundSentry export */
        Status = LdrGetProcedureAddress(DllHandle,
                                        &FuncString,
                                        0,
                                        (PVOID*)&NewSoundSentry);
    }

    /* Set it as the callback for the future, and call it */
    _UserSoundSentry = NewSoundSentry;
    return _UserSoundSentry();
}
Пример #3
0
NTSTATUS
NTAPI
BaseSrvDelayLoadKernel32(VOID)
{
    NTSTATUS Status;
    ULONG i;
    ANSI_STRING ProcedureName;

    /* Only do this once */
    if (BaseSrvKernel32DelayLoadComplete) return STATUS_SUCCESS;

    /* Loop all imports */
    for (i = 0; i < RTL_NUMBER_OF(BaseSrvKernel32Imports); i++)
    {
        /* Only look them up once */
        if (!*BaseSrvKernel32Imports[i].FunctionPointer)
        {
            /* If we haven't loaded the DLL yet, do it now */
            if (!BaseSrvKernel32DllHandle)
            {
                Status = LdrLoadDll(0,
                                    0,
                                    &BaseSrvKernel32DllPath,
                                    &BaseSrvKernel32DllHandle);
                if (!NT_SUCCESS(Status))
                {
                    DPRINT1("Failed to load %wZ\n", &BaseSrvKernel32DllPath);
                    return Status;
                }
            }

            /* Get the address of the routine being looked up*/
            RtlInitAnsiString(&ProcedureName, BaseSrvKernel32Imports[i].FunctionName);
            Status = LdrGetProcedureAddress(BaseSrvKernel32DllHandle,
                                            &ProcedureName,
                                            0,
                                            BaseSrvKernel32Imports[i].FunctionPointer);
            DPRINT1("NLS: Found %Z at 0x%p\n",
                    &ProcedureName,
                    BaseSrvKernel32Imports[i].FunctionPointer);
            if (!NT_SUCCESS(Status)) break;
        }
    }

    /* Did we find them all? */
    if (i == RTL_NUMBER_OF(BaseSrvKernel32Imports))
    {
        /* Excellent */
        BaseSrvKernel32DelayLoadComplete = TRUE;
        return STATUS_SUCCESS;
    }

    /* Nope, fail */
    return Status;
}
Пример #4
0
/*
 * @implemented
 */
FARPROC
WINAPI
GetProcAddress(HMODULE hModule, LPCSTR lpProcName)
{
    ANSI_STRING ProcedureName, *ProcNamePtr = NULL;
    FARPROC fnExp = NULL;
    NTSTATUS Status;
    PVOID hMapped;
    ULONG Ordinal = 0;

    if (HIWORD(lpProcName) != 0)
    {
        /* Look up by name */
        RtlInitAnsiString(&ProcedureName, (LPSTR)lpProcName);
        ProcNamePtr = &ProcedureName;
    }
    else
    {
        /* Look up by ordinal */
        Ordinal = (ULONG)lpProcName;
    }

    /* Map provided handle */
    hMapped = BasepMapModuleHandle(hModule, FALSE);

    /* Get the proc address */
    Status = LdrGetProcedureAddress(hMapped,
                                    ProcNamePtr,
                                    Ordinal,
                                    (PVOID*)&fnExp);

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

    /* Check for a special case when returned pointer is
       the same as iamge's base address */
    if (fnExp == hMapped)
    {
        /* Set correct error code */
        if (HIWORD(lpProcName) != 0)
            BaseSetLastNTError(STATUS_ENTRYPOINT_NOT_FOUND);
        else
            BaseSetLastNTError(STATUS_ORDINAL_NOT_FOUND);

        return NULL;
    }

    /* All good, return procedure pointer */
    return fnExp;
}
Пример #5
0
// my getprocaddress, uses only ntdll functions 
LPVOID engine_NtGetProcAddress(HMODULE hModule,LPSTR lpFunctionName)
{
	STRING asFunctionName;
	LPVOID lpAddress;
	
	asFunctionName.Buffer=(PCHAR)lpFunctionName;
	asFunctionName.Length=strlen(lpFunctionName);
	asFunctionName.MaximumLength=asFunctionName.Length;

	if (!NT_SUCCESS(LdrGetProcedureAddress(hModule,&asFunctionName,0,&lpAddress)))
		return NULL;
	
	return lpAddress;
}
Пример #6
0
PCSR_THREAD CsrConnectToUser( VOID )
{
    static BOOLEAN (*ClientThreadSetupRoutine)(VOID) = NULL;
    NTSTATUS Status;
    ANSI_STRING DllName;
    UNICODE_STRING DllName_U;
    STRING ProcedureName;
    HANDLE UserClientModuleHandle;
    PTEB Teb;
    PCSR_THREAD Thread;
    BOOLEAN fConnected;

    if (ClientThreadSetupRoutine == NULL) {
        RtlInitAnsiString(&DllName, "user32");
        Status = RtlAnsiStringToUnicodeString(&DllName_U, &DllName, TRUE);
        ASSERT(NT_SUCCESS(Status));
        Status = LdrGetDllHandle(
                    UNICODE_NULL,
                    NULL,
                    &DllName_U,
                    (PVOID *)&UserClientModuleHandle
                    );

        RtlFreeUnicodeString(&DllName_U);

        if ( NT_SUCCESS(Status) ) {
            RtlInitString(&ProcedureName,"ClientThreadSetup");
            Status = LdrGetProcedureAddress(
                            UserClientModuleHandle,
                            &ProcedureName,
                            0L,
                            (PVOID *)&ClientThreadSetupRoutine
                            );
            ASSERT(NT_SUCCESS(Status));
        }
    }

    try {
        fConnected = ClientThreadSetupRoutine();
    } except (EXCEPTION_EXECUTE_HANDLER) {
        fConnected = FALSE;
    }
    if (!fConnected) {
            IF_DEBUG {
            DbgPrint("CSRSS: CsrConnectToUser failed\n");
                }
        return NULL;
    }
Пример #7
0
NTSTATUS
CsrClientConnectToServer(
    IN PWSTR ObjectDirectory,
    IN ULONG ServerDllIndex,
    IN PCSR_CALLBACK_INFO CallbackInformation OPTIONAL,
    IN PVOID ConnectionInformation,
    IN OUT PULONG ConnectionInformationLength OPTIONAL,
    OUT PBOOLEAN CalledFromServer OPTIONAL
    )

/*++

Routine Description:

    This function is called by the client side DLL to connect with its
    server side DLL.

Arguments:

    ObjectDirectory - Points to a null terminate string that is the same
        as the value of the ObjectDirectory= argument passed to the CSRSS
        program.

    ServerDllIndex - Index of the server DLL that is being connected to.
        It should match one of the ServerDll= arguments passed to the CSRSS
        program.

    CallbackInformation - An optional pointer to a structure that contains
        a pointer to the client callback function dispatch table.

    ConnectionInformation - An optional pointer to uninterpreted data.
        This data is intended for clients to pass package, version and
        protocol identification information to the server to allow the
        server to determine if it can satisify the client before
        accepting the connection.  Upon return to the client, the
        ConnectionInformation data block contains any information passed
        back from the server DLL by its call to the
        CsrCompleteConnection call.  The output data overwrites the
        input data.

    ConnectionInformationLength - Pointer to the length of the
        ConnectionInformation data block.  The output value is the
        length of the data stored in the ConnectionInformation data
        block by the server's call to the NtCompleteConnectPort
        service.  This parameter is OPTIONAL only if the
        ConnectionInformation parameter is NULL, otherwise it is
        required.

    CalledFromServer - On output, TRUE if the dll has been called from
        a server process.

Return Value:

    Status value.

--*/

{
    NTSTATUS Status;
    CSR_API_MSG m;
    PCSR_CLIENTCONNECT_MSG a = &m.u.ClientConnect;
    PCSR_CAPTURE_HEADER CaptureBuffer;
    HANDLE CsrServerModuleHandle;
    STRING ProcedureName;
    ANSI_STRING DllName;
    UNICODE_STRING DllName_U;
    PIMAGE_NT_HEADERS NtHeaders;

    if (ARGUMENT_PRESENT( ConnectionInformation ) &&
        (!ARGUMENT_PRESENT( ConnectionInformationLength ) ||
          *ConnectionInformationLength == 0
        )
       ) {
        return( STATUS_INVALID_PARAMETER );
        }

    if (!CsrInitOnceDone) {
        Status = CsrOneTimeInitialize();
        if (!NT_SUCCESS( Status )) {
            return( Status );
            }
        }

    if (ARGUMENT_PRESENT( CallbackInformation )) {
        CsrLoadedClientDll[ ServerDllIndex ] = RtlAllocateHeap( CsrHeap, MAKE_TAG( CSR_TAG ), sizeof(CSR_CALLBACK_INFO) );
        CsrLoadedClientDll[ ServerDllIndex ]->ApiNumberBase =
                CallbackInformation->ApiNumberBase;
        CsrLoadedClientDll[ ServerDllIndex ]->MaxApiNumber =
                CallbackInformation->MaxApiNumber;
        CsrLoadedClientDll[ ServerDllIndex ]->CallbackDispatchTable =
                CallbackInformation->CallbackDispatchTable;
    }

    //
    // if we are being called by a server process, skip lpc port initialization
    // and call to server connect routine and just initialize heap.  the
    // dll initialization routine will do any necessary initialization.  this
    // stuff only needs to be done for the first connect.
    //

    if ( CsrServerProcess == TRUE ) {
        *CalledFromServer = CsrServerProcess;
        return STATUS_SUCCESS;
        }

    //
    // If the image is an NT Native image, we are running in the
    // context of the server.
    //

    NtHeaders = RtlImageNtHeader(NtCurrentPeb()->ImageBaseAddress);
    CsrServerProcess =
        (NtHeaders->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_NATIVE) ? TRUE : FALSE;

    if ( CsrServerProcess ) {
        extern PVOID NtDllBase;
        RtlInitAnsiString( &DllName, "csrsrv" );
        Status = RtlAnsiStringToUnicodeString(&DllName_U, &DllName, TRUE);
        ASSERT(NT_SUCCESS(Status));

        LdrDisableThreadCalloutsForDll(NtDllBase);

        Status = LdrGetDllHandle(
        		UNICODE_NULL,
                    NULL,
        		&DllName_U,
                    (PVOID *)&CsrServerModuleHandle
                    );

        RtlFreeUnicodeString(&DllName_U);

        CsrServerProcess = TRUE;

        RtlInitString(&ProcedureName,"CsrCallServerFromServer");
        Status = LdrGetProcedureAddress(
                        CsrServerModuleHandle,
                        &ProcedureName,
                        0L,
                        (PVOID *)&CsrServerApiRoutine
                        );
        ASSERT(NT_SUCCESS(Status));

        RtlInitString(&ProcedureName, "CsrLocateThreadInProcess");
        Status = LdrGetProcedureAddress(
                        CsrServerModuleHandle,
                        &ProcedureName,
                        0L,
                        (PVOID *)&CsrpLocateThreadInProcess
                        );
        ASSERT(NT_SUCCESS(Status));

        ASSERT (CsrPortHeap==NULL);
        CsrPortHeap = RtlProcessHeap();

        CsrPortBaseTag = RtlCreateTagHeap( CsrPortHeap,
                                           0,
                                           L"CSRPORT!",
                                           L"CAPTURE\0"
                                         );

        if (ARGUMENT_PRESENT(CalledFromServer)) {
            *CalledFromServer = CsrServerProcess;
            }
        return STATUS_SUCCESS;
        }

    if ( ARGUMENT_PRESENT(ConnectionInformation) ) {
        CsrServerProcess = FALSE;
        if (CsrPortHandle == NULL) {
            Status = CsrpConnectToServer( ObjectDirectory );
            if (!NT_SUCCESS( Status )) {
                return( Status );
                }
            }

        a->ServerDllIndex = ServerDllIndex;
        a->ConnectionInformationLength = *ConnectionInformationLength;
        if (ARGUMENT_PRESENT( ConnectionInformation )) {
            CaptureBuffer = CsrAllocateCaptureBuffer( 1,
                                                      0,
                                                      a->ConnectionInformationLength
                                                    );
            if (CaptureBuffer == NULL) {
                return( STATUS_NO_MEMORY );
                }

            CsrAllocateMessagePointer( CaptureBuffer,
                                       a->ConnectionInformationLength,
                                       (PVOID *)&a->ConnectionInformation
                                     );
            RtlMoveMemory( a->ConnectionInformation,
                           ConnectionInformation,
                           a->ConnectionInformationLength
                         );

            *ConnectionInformationLength = a->ConnectionInformationLength;
            }
        else {
            CaptureBuffer = NULL;
            }

        Status = CsrClientCallServer( &m,
                                      CaptureBuffer,
                                      CSR_MAKE_API_NUMBER( CSRSRV_SERVERDLL_INDEX,
                                                           CsrpClientConnect
                                                         ),
                                      sizeof( *a )
                                    );

        if (CaptureBuffer != NULL) {
            if (ARGUMENT_PRESENT( ConnectionInformation )) {
                RtlMoveMemory( ConnectionInformation,
                               a->ConnectionInformation,
                               *ConnectionInformationLength
                             );
                }

            CsrFreeCaptureBuffer( CaptureBuffer );
            }
        }
    else {
        Status = STATUS_SUCCESS;
        }

    if (ARGUMENT_PRESENT(CalledFromServer)) {
        *CalledFromServer = CsrServerProcess;
        }
    return( Status );
}
Пример #8
0
ULONG
BaseSrvDebugProcess(
    IN OUT PCSR_API_MSG m,
    IN OUT PCSR_REPLY_STATUS ReplyStatus
    )
{
    NTSTATUS Status;
    PBASE_DEBUGPROCESS_MSG a = (PBASE_DEBUGPROCESS_MSG)&m->u.ApiMessageData;
    HANDLE Thread,ProcessHandle,Token;
    PCSR_PROCESS Process;
    DWORD ThreadId;
    PTOKEN_DEFAULT_DACL lpDefaultDacl;
    TOKEN_DEFAULT_DACL DefaultDacl;
    ULONG DaclLength;
    SECURITY_ATTRIBUTES ThreadAttributes;
    SECURITY_DESCRIPTOR SecurityDescriptor;
    UNICODE_STRING ModuleNameString_U;
    PVOID ModuleHandle;
    STRING ProcedureNameString;
    PCREATE_REMOTE_THREAD CreateRemoteThreadRoutine;


    if (a->dwProcessId == -1 && a->AttachCompleteRoutine == NULL) {
        HANDLE DebugPort;

        DebugPort = (HANDLE)NULL;
        Status = NtQueryInformationProcess(
                    NtCurrentProcess(),
                    ProcessDebugPort,
                    (PVOID)&DebugPort,
                    sizeof(DebugPort),
                    NULL
                    );

        if ( NT_SUCCESS(Status) && DebugPort ) {
            return (ULONG)STATUS_ACCESS_DENIED;
            }

        return STATUS_SUCCESS;
        }
#if DEVL
    if (a->dwProcessId != -1) {
#endif // DEVL
        if ( a->AttachCompleteRoutine == NULL ) {
            Status = CsrLockProcessByClientId((HANDLE)a->dwProcessId,&Process);
            if ( NT_SUCCESS(Status) ) {

                ProcessHandle = Process->ProcessHandle;
                Status = NtOpenProcessToken(ProcessHandle,
                                            TOKEN_QUERY,
                                            &Token
                                           );
                if ( !NT_SUCCESS(Status) ) {
                    CsrUnlockProcess(Process);
                    return Status;
                    }
                lpDefaultDacl = &DefaultDacl;
                Status = NtQueryInformationToken(Token,
                                                 TokenDefaultDacl,
                                                 lpDefaultDacl,
                                                 sizeof(DefaultDacl),
                                                 &DaclLength
                                                );
                if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_TOO_SMALL) {
                    Status = STATUS_ACCESS_DENIED;
                    }
                else {
                    Status = STATUS_SUCCESS;
                    }

                if ( Process->DebugUserInterface.UniqueProcess ||
                     Process->DebugUserInterface.UniqueThread ) {
                    Status = STATUS_ACCESS_DENIED;
                    }

                NtClose(Token);
                CsrUnlockProcess(Process);
                }
                return (ULONG)Status;
            }

        //
        // Can't call base, but I know it is there
        //

        RtlInitUnicodeString( &ModuleNameString_U, L"kernel32" );
        Status = LdrLoadDll( UNICODE_NULL, NULL, &ModuleNameString_U, &ModuleHandle );
        if ( !NT_SUCCESS(Status) ) {
            return (ULONG)Status;
            }
        RtlInitString( &ProcedureNameString, "CreateRemoteThread" );
        Status = LdrGetProcedureAddress( ModuleHandle,
                                         &ProcedureNameString,
                                         (ULONG) NULL,
                                         (PVOID *) &CreateRemoteThreadRoutine
                                       );
        if ( !NT_SUCCESS(Status) ) {
            LdrUnloadDll( ModuleHandle );
            return (ULONG)Status;
            }

        Status = CsrLockProcessByClientId((HANDLE)a->dwProcessId,&Process);
        if ( NT_SUCCESS(Status) ) {

            ProcessHandle = Process->ProcessHandle;
            Status = NtOpenProcessToken(ProcessHandle,
                                        TOKEN_QUERY,
                                        &Token
                                       );
            if (!NT_SUCCESS(Status)) {
                CsrUnlockProcess(Process);
                LdrUnloadDll( ModuleHandle );
                return (ULONG)Status;
                }

            lpDefaultDacl = &DefaultDacl;
            Status = NtQueryInformationToken(Token,
                                             TokenDefaultDacl,
                                             lpDefaultDacl,
                                             sizeof(DefaultDacl),
                                             &DaclLength
                                            );
            if (!NT_SUCCESS(Status)) {
                lpDefaultDacl = RtlAllocateHeap(RtlProcessHeap(), MAKE_TAG( TMP_TAG ), DaclLength);
                if (lpDefaultDacl) {
                    Status = NtQueryInformationToken(Token,
                                                     TokenDefaultDacl,
                                                     lpDefaultDacl,
                                                     DaclLength,
                                                     &DaclLength
                                                    );
                    }
                else {
                    Status = STATUS_NO_MEMORY;
                    }
                NtClose(Token);
                if (!NT_SUCCESS(Status)) {
                    CsrUnlockProcess(Process);
                    LdrUnloadDll( ModuleHandle );
                    return (ULONG)Status;
                    }
                }
            else {
                NtClose(Token);
                }

            ThreadAttributes.nLength = sizeof(ThreadAttributes);
            RtlCreateSecurityDescriptor(&SecurityDescriptor,SECURITY_DESCRIPTOR_REVISION1);
            ThreadAttributes.lpSecurityDescriptor = &SecurityDescriptor;
            SecurityDescriptor.Control = SE_DACL_PRESENT;
            SecurityDescriptor.Dacl = lpDefaultDacl->DefaultDacl;
            ThreadAttributes.bInheritHandle = FALSE;

            CsrUnlockProcess(Process);
            }
#if DEVL
        }
#endif // DEVL

    //
    // Set up the specified user-interface as the debugger of the
    // target process. Whip through the target process and
    // suspend all threads. Then Send CreateProcess, LoadModule, and
    // CreateThread Messages. Finally send the attach complete
    // exception.
    //

    Status = CsrDebugProcess(
                a->dwProcessId,
                &a->DebuggerClientId,
                (PCSR_ATTACH_COMPLETE_ROUTINE)a->AttachCompleteRoutine
                );
#if DEVL
    if (a->dwProcessId != -1) {
#endif // DEVL
        if ( NT_SUCCESS(Status) ) {
            Thread = (PVOID)(CreateRemoteThreadRoutine)(ProcessHandle,
                                        &ThreadAttributes,
                                        0L,
                                        (LPTHREAD_START_ROUTINE)a->AttachCompleteRoutine,
                                        0,
                                        0,
                                        &ThreadId
                                        );
            LdrUnloadDll( ModuleHandle );
            if ( lpDefaultDacl != &DefaultDacl ) {
                RtlFreeHeap(RtlProcessHeap(), 0,lpDefaultDacl);
                }
            if ( !Thread ) {
                return (ULONG)STATUS_UNSUCCESSFUL;
                }
            NtClose(Thread);
            }
#if DEVL
        }
#endif // DEVL
    return (ULONG) Status;
}