Exemplo n.º 1
1
/*
 * @implemented
 */
HINSTANCE
WINAPI
LoadLibraryExW(LPCWSTR lpLibFileName,
               HANDLE hFile,
               DWORD dwFlags)
{
    UNICODE_STRING DllName;
    HINSTANCE hInst;
    NTSTATUS Status;
    PWSTR SearchPath;
    ULONG DllCharacteristics = 0;
    BOOL FreeString = FALSE;

    /* Check for any flags LdrLoadDll might be interested in */
    if (dwFlags & DONT_RESOLVE_DLL_REFERENCES)
    {
        /* Tell LDR to treat it as an EXE */
        DllCharacteristics = IMAGE_FILE_EXECUTABLE_IMAGE;
    }

    /* Build up a unicode dll name from null-terminated string */
    RtlInitUnicodeString(&DllName, (LPWSTR)lpLibFileName);

    /* Lazy-initialize BasepExeLdrEntry */
    if (!BasepExeLdrEntry)
        LdrEnumerateLoadedModules(0, BasepLocateExeLdrEntry, NtCurrentPeb()->ImageBaseAddress);

    /* Check if that module is our exe*/
    if (BasepExeLdrEntry && !(dwFlags & LOAD_LIBRARY_AS_DATAFILE) &&
        DllName.Length == BasepExeLdrEntry->FullDllName.Length)
    {
        /* Lengths match and it's not a datafile, so perform name comparison */
        if (RtlEqualUnicodeString(&DllName, &BasepExeLdrEntry->FullDllName, TRUE))
        {
            /* That's us! */
            return BasepExeLdrEntry->DllBase;
        }
    }

    /* Check for trailing spaces and remove them if necessary */
    if (DllName.Buffer[DllName.Length/sizeof(WCHAR) - 1] == L' ')
    {
        RtlCreateUnicodeString(&DllName, (LPWSTR)lpLibFileName);
        while (DllName.Length > sizeof(WCHAR) &&
            DllName.Buffer[DllName.Length/sizeof(WCHAR) - 1] == L' ')
        {
            DllName.Length -= sizeof(WCHAR);
        }
        DllName.Buffer[DllName.Length/sizeof(WCHAR)] = UNICODE_NULL;
        FreeString = TRUE;
    }

    /* Compute the load path */
    SearchPath = BaseComputeProcessDllPath((dwFlags & LOAD_WITH_ALTERED_SEARCH_PATH) ?
                                           DllName.Buffer : NULL,
                                           NULL);
    if (!SearchPath)
    {
        /* Getting DLL path failed, so set last error, free mem and return */
        BaseSetLastNTError(STATUS_NO_MEMORY);
        if (FreeString) RtlFreeUnicodeString(&DllName);
        return NULL;
    }

    _SEH2_TRY
    {
        if (dwFlags & LOAD_LIBRARY_AS_DATAFILE)
        {
            /* If the image is loaded as a datafile, try to get its handle */
            Status = LdrGetDllHandleEx(0, SearchPath, NULL, &DllName, (PVOID*)&hInst);
            if (!NT_SUCCESS(Status))
            {
                /* It's not loaded yet - so load it up */
                Status = BasepLoadLibraryAsDatafile(SearchPath, DllName.Buffer, &hInst);
            }
            _SEH2_YIELD(goto done;)
        }

        /* Call the API Properly */
        Status = LdrLoadDll(SearchPath,
                            &DllCharacteristics,
                            &DllName,
                            (PVOID*)&hInst);
    }
Exemplo n.º 2
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;
}
Exemplo n.º 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;
}
Exemplo n.º 4
0
NTSTATUS WINAPI SafeLdrLoadDll(PWCHAR PathToFile,ULONG Flags,PUNICODE_STRING ModuleFileName,PHANDLE ModuleHandle)
{
	NTSTATUS rc;

	if (CheckOldFunction(&OldLdrLoadDll))
		rc=OldLdrLoadDll(PathToFile,Flags,ModuleFileName,ModuleHandle);
	else
		rc=LdrLoadDll(PathToFile,Flags,ModuleFileName,ModuleHandle);

	return rc;
}
Exemplo n.º 5
0
// my loadlibrary, uses only ntdll functions 
LPVOID engine_NtLoadLibraryA(LPSTR lpModuleName)
{
	STRING asModuleName;
	UNICODE_STRING usModuleName;
	HANDLE hModule;

	asModuleName.Buffer=(PCHAR)lpModuleName;
	asModuleName.Length=strlen(lpModuleName);
	asModuleName.MaximumLength=asModuleName.Length;

	if (!NT_SUCCESS(RtlAnsiStringToUnicodeString(&usModuleName,&asModuleName,TRUE)))
		return NULL;

	if (!NT_SUCCESS(LdrLoadDll(NULL,0,&usModuleName,&hModule)))
	{
		RtlFreeUnicodeString(&usModuleName);
		return NULL;
	}

	RtlFreeUnicodeString(&usModuleName);

	return hModule;
}
Exemplo n.º 6
0
NTSTATUS getAndLoadDllByInput(PVOID* ppDllBase){
	WCHAR szDllName[MAX_PATH];		///It's impossible, that the DLL's image name length exceeds 260 chars,
									///since the maximum length of a file path part is limited to ~255 by Windows.
	ULONGLONG dllStrSize;
	UNICODE_STRING uDllName;

	ULONG loadFlags = 0x0;
	NTSTATUS status = STATUS_HANDLE_NO_LONGER_VALID;

	status = myfgetws(szDllName, sizeof(szDllName), &dllStrSize);
	if (status)
		return status;

	///Although we don't want any DllMain() to be called, we intend to use standard PE math
	///when walking the EAT at a later time. So we still need to load the DLL as an image file.	
	loadFlags = LOAD_LIBRARY_AS_IMAGE_RESOURCE;
	loadFlags |= LOAD_LIBRARY_SEARCH_SYSTEM32;
	loadFlags |= LOAD_LIBRARY_SEARCH_APPLICATION_DIR;

	RtlInitUnicodeString(&uDllName, szDllName);
	status = LdrLoadDll(NULL, &loadFlags, &uDllName, ppDllBase);

	return status;
}
Exemplo n.º 7
0
HOOKFUNC NTSTATUS NTAPI MyLdrLoadDll(PWCHAR PathToFile, ULONG Flags, PUNICODE_STRING ModuleFileName, PHANDLE ModuleHandle)
{
//debugprintf(__FUNCTION__ "(ModuleFileName=\"%S\") called.\n", ModuleFileName->Buffer);
//cmdprintf("SHORTTRACE: 3,50");

	//debugprintf(__FUNCTION__ "(ModuleFileName=\"%S\") called.\n", ModuleFileName->Buffer);
	//DWORD myEBP;
 //   __asm
 //   {
 //     mov [myEBP], ebp;
 //   }
	//debugsplatmem(myEBP, "ebp");

#if 1 // new method, get list of loaded dlls from debugger (because LdrLoadDll can load multiple dlls)
	//_asm{int 3} // to print callstack... debugprintf/cmdprintf can cause problems in this context
	ThreadLocalStuff* pCurtls = 0;
	if(tlsIsSafeToUse)
	{
		pCurtls = &tls;
		ThreadLocalStuff& curtls = *pCurtls;
		if(curtls.callingClientLoadLibrary || curtls.treatDLLLoadsAsClient)
		{
			curtls.callingClientLoadLibrary = FALSE; // see MyKiUserCallbackDispatcher
			watchForCLLApiNum = false; // if we were watching for the apiNum, it must have worked
			if(!ShouldLoadUserDll(ModuleFileName->Buffer))
			{
				//debuglog(LCF_MODULE, "DENIED loading DLL: %S\n", ModuleFileName->Buffer);
				//cmdprintf("SHORTTRACE: 3,50");
				return /*STATUS_DLL_NOT_FOUND*/0xC0000135;
			}
		}
		
		// TEST HACK
		if(WideStringContains(ModuleFileName->Buffer, "dpofeedb.dll"))
			return /*STATUS_DLL_NOT_FOUND*/0xC0000135;

		pCurtls->callerisuntrusted++;
	}
	//if(tlsIsSafeToUse)
	//{
	//	debuglog(LCF_MODULE, "Loaded DLL: %S\n", ModuleFileName->Buffer);
	//	//cmdprintf("SHORTTRACE: 3,50");
	//}

	NTSTATUS rv = LdrLoadDll(PathToFile, Flags, ModuleFileName, ModuleHandle);
	//if(rv < 0)
	//	debuglog(LCF_MODULE|LCF_ERROR, "FAILED to load DLL: %S (0x%X)\n", ModuleFileName->Buffer, rv);
	UpdateLoadedOrUnloadedDllHooks();
	if(pCurtls)
		pCurtls->callerisuntrusted--;
	return rv;
#else

	// for some reason this function is INCREDIBLY fragile.
	// the slightest bit too much processing will make games fail to load certain critical DLLs.
	// I'd like to call ShouldAllowDLLLoad to deny certain DLLs from loading, but currently can't.

	LPWSTR lpFileName = ModuleFileName->Buffer;

	// store the string first because LdrLoadDll puts garbage in the string (registry keys?)
	// this way of doing it seems to be more reliable than sprintf(name, "%S", lpFileName);
	char name [1024];
	int i = 0;
	for(; lpFileName[i] && i != sizeof(name)-1; i++)
		name[i] = (char)lpFileName[i];
	name[i] = 0;

	//debuglog(LCF_MODULE, __FUNCTION__ "(%S, 0x%X, %S, 0x%X)\n", lpFileName, Flags, PathToFile, ModuleHandle);
	//if(!ShouldAllowDLLLoad(name))
	//{
	//	//return 0xC0000135;
	//}

	NTSTATUS rv = LdrLoadDll(PathToFile, Flags, ModuleFileName, ModuleHandle);

	//static int inside = 0;
	//if(inside) if(inside != GetCurrentThreadId()) while(inside) {OutputDebugString("WTFA\n");}
	//inside = GetCurrentThreadId();

//#if defined(_MSC_VER) && _MSC_VER >= 1400 && _MSC_VER < 1500
	// terrible mystery hack! to fix some games from failing to find kernel32.dll when this file is compiled with VS2005
	//static bool already = false;
	//if(!already)
//	if(lpFileName[0] == 'K' && lpFileName[6] == '3')
//	{
//		//already = true;
//		NTSTATUS rv = LdrLoadDll(PathToFile, Flags, ModuleFileName, ModuleHandle);
////		inside = 0;
//		return rv;
//	}
//#endif


//	NTSTATUS rv = LdrLoadDll(PathToFile, Flags, ModuleFileName, ModuleHandle);

	if(rv >= 0)
	{
		int namelen = i;
		if(!(namelen < 4 || !stricmp(name+namelen-4,".exe")))
		{
			char* slash = max(strrchr(name, '\\'), strrchr(name, '/'));
			const char* dllname = slash ? slash+1 : name;
			//debuglog(LCF_MODULE, "Rehooking: %s\n", dllname);
			RetryInterceptAPIs(dllname);
// disabled because it will make AVIs captured on different machines be slightly different lengths
			//// loading DLLs takes time
			//detTimer.AddDelay(/*10*/15, FALSE, FALSE); // must both be FALSE to signal async delay add, otherwise really weird things will happen like inaccurate thread creation reports to the debugger
		}
	}
	else
	{
		//HANDLE handle = GetModuleHandleA(name);
		//if(handle)
		//{
		//	*ModuleHandle = handle;
		//	rv = 0;
		//}
		//while(rv < 0)
		{
			debuglog(LCF_MODULE|LCF_ERROR, "FAILED to load DLL: %s (0x%X)\n", name, rv);
//			debuglog(LCF_MODULE|LCF_ERROR, "%S, 0x%X, 0x%X, %S\n", ModuleFileName->Buffer, Flags, ModuleHandle, PathToFile);
//			rv = LdrLoadDll(PathToFile, Flags, ModuleFileName, ModuleHandle);
		}

	//NTSTATUS rv = LdrLoadDll(PathToFile, Flags, ModuleFileName, ModuleHandle);
	}

//	inside = 0;
	return rv;
#endif
}
Exemplo n.º 8
0
BOOL
SetConsolePalette(
    IN HANDLE hConsoleOutput,
    IN HPALETTE hPalette,
    IN UINT dwUsage
)

/*++

Description:

    Sets the palette for the console screen buffer.

Parameters:

    hOutput - Supplies a console output handle.

    hPalette - Supplies a handle to the palette to set.

    dwUsage - Specifies use of the system palette.

        SYSPAL_NOSTATIC - System palette contains no static colors
                          except black and white.

        SYSPAL_STATIC -   System palette contains static colors
                          which will not change when an application
                          realizes its logical palette.

Return value:

    TRUE - The operation was successful.

    FALSE/NULL - The operation failed. Extended error status is available
        using GetLastError.

--*/

{

    HANDLE hmodGdi;
    UNICODE_STRING ModuleNameString;
    NTSTATUS Status;

    if ( !pfnGdiConvertPalette ) {
        RtlInitUnicodeString( &ModuleNameString, L"gdi32" );
        Status = LdrLoadDll( UNICODE_NULL, NULL, &ModuleNameString, &hmodGdi );
        if ( !NT_SUCCESS(Status) ) {
            SET_LAST_NT_ERROR(Status);
            return FALSE;
        }
        pfnGdiConvertPalette = (PCONVPALFUNC)GetProcAddress(hmodGdi, "GdiConvertPalette");
        if (pfnGdiConvertPalette == NULL) {
            SET_LAST_NT_ERROR(STATUS_PROCEDURE_NOT_FOUND);
            return FALSE;
        }

    }

    hPalette = (*pfnGdiConvertPalette)(hPalette);

    return SetConsolePaletteInternal(hConsoleOutput,
                                     hPalette,
                                     dwUsage);
}
Exemplo n.º 9
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;
}