/* * @implemented */ BOOLEAN NTAPI RtlConvertPropertyToVariant(IN PSERIALIZEDPROPERTYVALUE prop, IN USHORT CodePage, OUT PROPVARIANT * pvar, IN PPMemoryAllocator pma) { BOOLEAN Success = FALSE; PVOID BaseAddress = NULL; BOOLEAN (*ProcedureAddress)(PSERIALIZEDPROPERTYVALUE, USHORT, PROPVARIANT*, PPMemoryAllocator); _SEH2_TRY { /* Simply call the appropriate Ole32 export */ ProcedureAddress = LoadOle32Export(&BaseAddress, "StgConvertPropertyToVariant"); Success = ProcedureAddress(prop, CodePage, pvar, pma); } _SEH2_FINALLY { if (BaseAddress != NULL) { LdrUnloadDll(BaseAddress); } } _SEH2_END; return Success; }
/* * @implemented */ ULONG NTAPI PropertyLengthAsVariant(IN PSERIALIZEDPROPERTYVALUE pProp, IN ULONG cbProp, IN USHORT CodePage, IN BYTE bReserved) { ULONG Length = 0; PVOID BaseAddress = NULL; ULONG (*ProcedureAddress)(PSERIALIZEDPROPERTYVALUE, ULONG, USHORT, BYTE); _SEH2_TRY { /* Simply call the appropriate Ole32 export */ ProcedureAddress = LoadOle32Export(&BaseAddress, "StgPropertyLengthAsVariant"); Length = ProcedureAddress(pProp, cbProp, CodePage, bReserved); } _SEH2_FINALLY { if (BaseAddress != NULL) { LdrUnloadDll(BaseAddress); } } _SEH2_END; return Length; }
/* * @implemented */ PSERIALIZEDPROPERTYVALUE NTAPI RtlConvertVariantToProperty(IN const PROPVARIANT * pvar, IN USHORT CodePage, OUT PSERIALIZEDPROPERTYVALUE pprop OPTIONAL, IN OUT PULONG pcb, IN PROPID pid, IN BOOLEAN fReserved, IN OUT PULONG pcIndirect OPTIONAL) { PSERIALIZEDPROPERTYVALUE Serialized = NULL; PVOID BaseAddress = NULL; PSERIALIZEDPROPERTYVALUE (*ProcedureAddress)(const PROPVARIANT*, USHORT, PSERIALIZEDPROPERTYVALUE, PULONG, PROPID, BOOLEAN, PULONG); _SEH2_TRY { /* Simply call the appropriate Ole32 export */ ProcedureAddress = LoadOle32Export(&BaseAddress, "StgConvertVariantToProperty"); Serialized = ProcedureAddress(pvar, CodePage, pprop, pcb, pid, fReserved, pcIndirect); } _SEH2_FINALLY { if (BaseAddress != NULL) { LdrUnloadDll(BaseAddress); } } _SEH2_END; return Serialized; }
NTSTATUS WINAPI SafeLdrUnloadDll(HANDLE hModule) { NTSTATUS rc; if (CheckOldFunction(&OldLdrUnloadDll)) rc=OldLdrUnloadDll(hModule); else rc=LdrUnloadDll(hModule); return rc; }
if (NtHeaders) { /* Unmap view */ Status = NtUnmapViewOfSection(NtCurrentProcess(), (PVOID)((ULONG_PTR)hLibModule & ~1)); /* Unload alternate resource module */ LdrUnloadAlternateResourceModule(hLibModule); } else Status = STATUS_INVALID_IMAGE_FORMAT; } else { /* Just unload it */ Status = LdrUnloadDll((PVOID)hLibModule); } /* Check what kind of status we got */ if (!NT_SUCCESS(Status)) { /* Set last error */ BaseSetLastNTError(Status); /* Return failure */ return FALSE; } /* Return success */ return TRUE; }
NTSTATUS NTAPI LdrpLoadDll( IN PWSTR DllPath OPTIONAL, IN PULONG DllCharacteristics OPTIONAL, IN PUNICODE_STRING DllName, OUT PVOID *DllHandle, IN BOOLEAN RunInitRoutines ) { PPEB Peb; NTSTATUS st; PLDR_DATA_TABLE_ENTRY LdrDataTableEntry; PWSTR ActualDllName; PWCH p, pp; UNICODE_STRING ActualDllNameStr; #if defined (WX86) PWX86TIB Wx86Tib; #endif BOOLEAN Wx86KnownDll = FALSE; WCHAR FreeBuffer[266]; Peb = NtCurrentPeb(); st = STATUS_SUCCESS; try { // // Grab Peb lock and Snap All Links to specified DLL // if ( LdrpInLdrInit == FALSE ) { RtlEnterCriticalSection((PRTL_CRITICAL_SECTION)NtCurrentPeb()->LoaderLock); } #if defined (WX86) Wx86Tib = Wx86CurrentTib(); if (Wx86Tib) { if (Wx86Tib->UseKnownWx86Dll) { Wx86KnownDll = Wx86Tib->UseKnownWx86Dll; Wx86Tib->UseKnownWx86Dll = FALSE; } } #endif p = DllName->Buffer; pp = NULL; while (*p) { if (*p++ == (WCHAR)'.') { // // pp will point to first character after last '.' // pp = p; } } ActualDllName = FreeBuffer; if ( DllName->Length >= sizeof(FreeBuffer)) { return STATUS_NAME_TOO_LONG; } RtlMoveMemory(ActualDllName, DllName->Buffer, DllName->Length); if (!pp || *pp == (WCHAR)'\\') { // // No extension found (just ..\) // if ( DllName->Length+10 >= sizeof(FreeBuffer) ) { return STATUS_NAME_TOO_LONG; } RtlMoveMemory((PCHAR)ActualDllName+DllName->Length, DLLEXTENSION, 10); } else { ActualDllName[DllName->Length >> 1] = UNICODE_NULL; } if (ShowSnaps) { DbgPrint("LDR: LdrLoadDll, loading %ws from %ws\n", ActualDllName, ARGUMENT_PRESENT(DllPath) ? DllPath : L"" ); } RtlInitUnicodeString(&ActualDllNameStr,ActualDllName); ActualDllNameStr.MaximumLength = sizeof(FreeBuffer); if (!LdrpCheckForLoadedDll( DllPath, &ActualDllNameStr, FALSE, Wx86KnownDll, &LdrDataTableEntry ) ) { st = LdrpMapDll(DllPath, ActualDllName, DllCharacteristics, FALSE, Wx86KnownDll, &LdrDataTableEntry ); if (!NT_SUCCESS(st)) { return st; } if (ARGUMENT_PRESENT( DllCharacteristics ) && *DllCharacteristics & IMAGE_FILE_EXECUTABLE_IMAGE ) { LdrDataTableEntry->EntryPoint = 0; LdrDataTableEntry->Flags &= ~LDRP_IMAGE_DLL; } // // and walk the import descriptor. // if (LdrDataTableEntry->Flags & LDRP_IMAGE_DLL) { try { st = LdrpWalkImportDescriptor( DllPath, LdrDataTableEntry ); } except(EXCEPTION_EXECUTE_HANDLER) { st = GetExceptionCode(); } if ( LdrDataTableEntry->LoadCount != 0xffff ) { LdrDataTableEntry->LoadCount++; } LdrpReferenceLoadedDll(LdrDataTableEntry); if (!NT_SUCCESS(st)) { LdrDataTableEntry->EntryPoint = NULL; InsertTailList(&NtCurrentPeb()->Ldr->InInitializationOrderModuleList, &LdrDataTableEntry->InInitializationOrderLinks); LdrpClearLoadInProgress(); LdrUnloadDll((PVOID)LdrDataTableEntry->DllBase); return st; } } else { if ( LdrDataTableEntry->LoadCount != 0xffff ) { LdrDataTableEntry->LoadCount++; } } // // Add init routine to list // InsertTailList(&NtCurrentPeb()->Ldr->InInitializationOrderModuleList, &LdrDataTableEntry->InInitializationOrderLinks); // // If the loader data base is not fully setup, this load was because // of a forwarder in the static load set. Can't run init routines // yet because the load counts are NOT set // if ( RunInitRoutines && LdrpLdrDatabaseIsSetup ) { try { st = LdrpRunInitializeRoutines(NULL); if ( !NT_SUCCESS(st) ) { LdrUnloadDll((PVOID)LdrDataTableEntry->DllBase); } } except( EXCEPTION_EXECUTE_HANDLER ) { LdrUnloadDll((PVOID)LdrDataTableEntry->DllBase); return GetExceptionCode(); } } else {
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; }