示例#1
0
BOOLEAN WinLdrInitSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
                             IN LPCSTR DirectoryPath)
{
    CHAR SearchPath[1024];
    BOOLEAN Success;

    // There is a simple logic here: try to load usual hive (system), if it
    // fails, then give system.alt a try, and finally try a system.sav

    // FIXME: For now we only try system
    strcpy(SearchPath, DirectoryPath);
    strcat(SearchPath, "SYSTEM32\\CONFIG\\");
    Success = WinLdrLoadSystemHive(LoaderBlock, SearchPath, "SYSTEM");

    // Fail if failed...
    if (!Success)
        return FALSE;

    // Import what was loaded
    Success = RegImportBinaryHive(VaToPa(LoaderBlock->RegistryBase), LoaderBlock->RegistryLength);
    if (!Success)
    {
        UiMessageBox("Importing binary hive failed!");
        return FALSE;
    }

    // Initialize the 'CurrentControlSet' link
    if (RegInitCurrentControlSet(FALSE) != ERROR_SUCCESS)
    {
        UiMessageBox("Initializing CurrentControlSet link failed!");
        return FALSE;
    }

    return TRUE;
}
示例#2
0
VOID
List_PaToVa(LIST_ENTRY *ListEntry)
{
	LIST_ENTRY *ListHead = ListEntry;
	LIST_ENTRY *Next = ListEntry->Flink;
	LIST_ENTRY *NextPA;

	//Print(L"\n\nList_Entry: %X, First Next: %X\n", ListEntry, Next);
	//
	// Walk through the whole list
	//
	if (Next != NULL)
	{
		while (Next != PaToVa(ListHead))
		{
			NextPA = VaToPa(Next);
			//Print(L"Current: %X, Flink: %X, Blink: %X\n", Next, NextPA->Flink, NextPA->Blink);

			NextPA->Flink = PaToVa((PVOID)NextPA->Flink);
			NextPA->Blink = PaToVa((PVOID)NextPA->Blink);

			//Print(L"After converting Flink: %X, Blink: %X\n", NextPA->Flink, NextPA->Blink);

			Next = NextPA->Flink;
		}

		//
		// Finally convert first Flink/Blink
		//
		ListEntry->Flink = PaToVa((PVOID)ListEntry->Flink);
		if (ListEntry->Blink)
			ListEntry->Blink = PaToVa((PVOID)ListEntry->Blink);
	}
}
示例#3
0
/* DllName - physical, UnicodeString->Buffer - virtual */
static BOOLEAN
WinLdrpCompareDllName(IN PCH DllName,
                      IN PUNICODE_STRING UnicodeName)
{
    PWSTR Buffer;
    UNICODE_STRING UnicodeNamePA;
    SIZE_T i, Length;

    /* First obvious check: for length of two names */
    Length = strlen(DllName);

    UnicodeNamePA.Length = UnicodeName->Length;
    UnicodeNamePA.MaximumLength = UnicodeName->MaximumLength;
    UnicodeNamePA.Buffer = VaToPa(UnicodeName->Buffer);
    TRACE("WinLdrpCompareDllName: %s and %wZ, Length = %d "
        "UN->Length %d\n", DllName, &UnicodeNamePA, Length, UnicodeName->Length);

    if ((Length * sizeof(WCHAR)) > UnicodeName->Length)
        return FALSE;

    /* Store pointer to unicode string's buffer */
    Buffer = VaToPa(UnicodeName->Buffer);

    /* Loop character by character */
    for (i = 0; i < Length; i++)
    {
        /* Compare two characters, uppercasing them */
        if (toupper(*DllName) != toupper((CHAR)*Buffer))
            return FALSE;

        /* Move to the next character */
        DllName++;
        Buffer++;
    }

    /* Check, if strings either fully match, or match till the "." (w/o extension) */
    if ((UnicodeName->Length == Length * sizeof(WCHAR)) || (*Buffer == L'.'))
    {
        /* Yes they do */
        return TRUE;
    }

    /* Strings don't match, return FALSE */
    return FALSE;
}
示例#4
0
static BOOLEAN
WinLdrpLoadAndScanReferencedDll(PLIST_ENTRY ModuleListHead,
                                PCCH DirectoryPath,
                                PCH ImportName,
                                PLDR_DATA_TABLE_ENTRY *DataTableEntry)
{
    CHAR FullDllName[256];
    BOOLEAN Success;
    PVOID BasePA = NULL;

    /* Prepare the full path to the file to be loaded */
    strcpy(FullDllName, DirectoryPath);
    strcat(FullDllName, ImportName);

    TRACE("Loading referenced DLL: %s\n", FullDllName);
    //Print(L"Loading referenced DLL: %s\n", FullDllName);

    /* Load the image */
    Success = WinLdrLoadImage(FullDllName, LoaderBootDriver, &BasePA);
    if (!Success)
    {
        ERR("WinLdrLoadImage() failed\n");
        return Success;
    }

    /* Allocate DTE for newly loaded DLL */
    Success = WinLdrAllocateDataTableEntry(ModuleListHead,
                                           ImportName,
                                           FullDllName,
                                           BasePA,
                                           DataTableEntry);
    if (!Success)
    {
        ERR("WinLdrAllocateDataTableEntry() failed\n");
        return Success;
    }

    /* Scan its dependencies too */
    TRACE("WinLdrScanImportDescriptorTable() calling ourselves for %S\n",
        VaToPa((*DataTableEntry)->BaseDllName.Buffer));
    Success = WinLdrScanImportDescriptorTable(ModuleListHead, DirectoryPath, *DataTableEntry);
    if (!Success)
    {
        ERR("WinLdrScanImportDescriptorTable() failed\n");
        return Success;
    }

    return TRUE;
}
示例#5
0
/* Returns TRUE if DLL has already been loaded - looks in LoadOrderList in LPB */
BOOLEAN
WinLdrCheckForLoadedDll(IN OUT PLIST_ENTRY ModuleListHead,
                        IN PCH DllName,
                        OUT PLDR_DATA_TABLE_ENTRY *LoadedEntry)
{
    PLDR_DATA_TABLE_ENTRY DataTableEntry;
    LIST_ENTRY *ModuleEntry;

    TRACE("WinLdrCheckForLoadedDll: DllName %s\n", DllName);

    /* Just go through each entry in the LoadOrderList and compare loaded module's
       name with a given name */
    ModuleEntry = ModuleListHead->Flink;
    while (ModuleEntry != ModuleListHead)
    {
        /* Get pointer to the current DTE */
        DataTableEntry = CONTAINING_RECORD(ModuleEntry,
            LDR_DATA_TABLE_ENTRY,
            InLoadOrderLinks);

        TRACE("WinLdrCheckForLoadedDll: DTE %p, EP %p, base %p name '%.*ws'\n",
            DataTableEntry, DataTableEntry->EntryPoint, DataTableEntry->DllBase,
            DataTableEntry->BaseDllName.Length / 2, VaToPa(DataTableEntry->BaseDllName.Buffer));

        /* Compare names */
        if (WinLdrpCompareDllName(DllName, &DataTableEntry->BaseDllName))
        {
            /* Yes, found it, report pointer to the loaded module's DTE
               to the caller and increase load count for it */
            *LoadedEntry = DataTableEntry;
            DataTableEntry->LoadCount++;
            TRACE("WinLdrCheckForLoadedDll: LoadedEntry %X\n", DataTableEntry);
            return TRUE;
        }

        /* Go to the next entry */
        ModuleEntry = ModuleEntry->Flink;
    }

    /* Nothing found */
    return FALSE;
}
示例#6
0
BOOLEAN
WinLdrLoadNLSData(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
                  IN LPCSTR DirectoryPath,
                  IN LPCSTR AnsiFileName,
                  IN LPCSTR OemFileName,
                  IN LPCSTR LanguageFileName)
{
	CHAR FileName[255];
	ULONG AnsiFileId;
	ULONG OemFileId;
	ULONG LanguageFileId;
	ULONG AnsiFileSize, OemFileSize, LanguageFileSize;
	ULONG TotalSize;
	ULONG_PTR NlsDataBase;
	PVOID NlsVirtual;
	BOOLEAN AnsiEqualsOem = FALSE;
	FILEINFORMATION FileInfo;
	ULONG BytesRead, Status;

	/* There may be a case, when OEM and ANSI page coincide */
	if (!strcmp(AnsiFileName, OemFileName))
		AnsiEqualsOem = TRUE;

	/* Open file with ANSI and store its size */
	//Print(L"Loading %s...\n", Filename);
	strcpy(FileName, DirectoryPath);
	strcat(FileName, AnsiFileName);
	Status = ArcOpen(FileName, OpenReadOnly, &AnsiFileId);

	if (Status != ESUCCESS)
		goto Failure;

	Status = ArcGetFileInformation(AnsiFileId, &FileInfo);
	if (Status != ESUCCESS)
		goto Failure;
	AnsiFileSize = FileInfo.EndingAddress.LowPart;
	TRACE("AnsiFileSize: %d\n", AnsiFileSize);
	ArcClose(AnsiFileId);

	/* Open OEM file and store its length */
	if (AnsiEqualsOem)
	{
		OemFileSize = 0;
	}
	else
	{
		//Print(L"Loading %s...\n", Filename);
		strcpy(FileName, DirectoryPath);
		strcat(FileName, OemFileName);
		Status = ArcOpen(FileName, OpenReadOnly, &OemFileId);

		if (Status != ESUCCESS)
			goto Failure;

		Status = ArcGetFileInformation(OemFileId, &FileInfo);
		if (Status != ESUCCESS)
			goto Failure;
		OemFileSize = FileInfo.EndingAddress.LowPart;
		ArcClose(OemFileId);
	}
	TRACE("OemFileSize: %d\n", OemFileSize);

	/* And finally open the language codepage file and store its length */
	//Print(L"Loading %s...\n", Filename);
	strcpy(FileName, DirectoryPath);
	strcat(FileName, LanguageFileName);
	Status = ArcOpen(FileName, OpenReadOnly, &LanguageFileId);

	if (Status != ESUCCESS)
		goto Failure;

	Status = ArcGetFileInformation(LanguageFileId, &FileInfo);
	if (Status != ESUCCESS)
		goto Failure;
	LanguageFileSize = FileInfo.EndingAddress.LowPart;
	ArcClose(LanguageFileId);
	TRACE("LanguageFileSize: %d\n", LanguageFileSize);

	/* Sum up all three length, having in mind that every one of them
	   must start at a page boundary => thus round up each file to a page */
	TotalSize = MM_SIZE_TO_PAGES(AnsiFileSize) +
		MM_SIZE_TO_PAGES(OemFileSize)  +
		MM_SIZE_TO_PAGES(LanguageFileSize);

	/* Store it for later marking the pages as NlsData type */
	TotalNLSSize = TotalSize;

	NlsDataBase = (ULONG_PTR)MmAllocateMemoryWithType(TotalSize*MM_PAGE_SIZE, LoaderNlsData);

	if (NlsDataBase == 0)
		goto Failure;

	NlsVirtual = PaToVa((PVOID)NlsDataBase);
	LoaderBlock->NlsData->AnsiCodePageData = NlsVirtual;
	LoaderBlock->NlsData->OemCodePageData = (PVOID)((PUCHAR)NlsVirtual +
		(MM_SIZE_TO_PAGES(AnsiFileSize) << MM_PAGE_SHIFT));
	LoaderBlock->NlsData->UnicodeCodePageData = (PVOID)((PUCHAR)NlsVirtual +
		(MM_SIZE_TO_PAGES(AnsiFileSize) << MM_PAGE_SHIFT) +
		(MM_SIZE_TO_PAGES(OemFileSize) << MM_PAGE_SHIFT));

	/* Ansi and OEM data are the same - just set pointers to the same area */
	if (AnsiEqualsOem)
		LoaderBlock->NlsData->OemCodePageData = LoaderBlock->NlsData->AnsiCodePageData;


	/* Now actually read the data into memory, starting with Ansi file */
	strcpy(FileName, DirectoryPath);
	strcat(FileName, AnsiFileName);
	Status = ArcOpen(FileName, OpenReadOnly, &AnsiFileId);

	if (Status != ESUCCESS)
		goto Failure;

	Status = ArcRead(AnsiFileId, VaToPa(LoaderBlock->NlsData->AnsiCodePageData), AnsiFileSize, &BytesRead);

	if (Status != ESUCCESS)
		goto Failure;

	ArcClose(AnsiFileId);

	/* OEM now, if it doesn't equal Ansi of course */
	if (!AnsiEqualsOem)
	{
		strcpy(FileName, DirectoryPath);
		strcat(FileName, OemFileName);
		Status = ArcOpen(FileName, OpenReadOnly, &OemFileId);

		if (Status != ESUCCESS)
			goto Failure;

		Status = ArcRead(OemFileId, VaToPa(LoaderBlock->NlsData->OemCodePageData), OemFileSize, &BytesRead);

		if (Status != ESUCCESS)
			goto Failure;

		ArcClose(OemFileId);
	}

	/* finally the language file */
	strcpy(FileName, DirectoryPath);
	strcat(FileName, LanguageFileName);
	Status = ArcOpen(FileName, OpenReadOnly, &LanguageFileId);

	if (Status != ESUCCESS)
		goto Failure;

	Status = ArcRead(LanguageFileId, VaToPa(LoaderBlock->NlsData->UnicodeCodePageData), LanguageFileSize, &BytesRead);

	if (Status != ESUCCESS)
		goto Failure;

	ArcClose(LanguageFileId);

	//
	// THIS IS HAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACK
	// Should go to WinLdrLoadOemHalFont(), when it will be implemented
	//
	LoaderBlock->OemFontFile = VaToPa(LoaderBlock->NlsData->UnicodeCodePageData);

	/* Convert NlsTables address to VA */
	LoaderBlock->NlsData = PaToVa(LoaderBlock->NlsData);

	return TRUE;

Failure:
	//UiMessageBox("Error reading NLS file %s\n", Filename);
	UiMessageBox("Error reading NLS file!");
	return FALSE;
}
示例#7
0
BOOLEAN
WinLdrScanImportDescriptorTable(IN OUT PLIST_ENTRY ModuleListHead,
                                IN PCCH DirectoryPath,
                                IN PLDR_DATA_TABLE_ENTRY ScanDTE)
{
    PLDR_DATA_TABLE_ENTRY DataTableEntry;
    PIMAGE_IMPORT_DESCRIPTOR ImportTable;
    ULONG ImportTableSize;
    PCH ImportName;
    BOOLEAN Success;

    /* Get a pointer to the import table of this image */
    ImportTable = (PIMAGE_IMPORT_DESCRIPTOR)RtlImageDirectoryEntryToData(VaToPa(ScanDTE->DllBase),
        TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &ImportTableSize);

    {
        UNICODE_STRING BaseName;
        BaseName.Buffer = VaToPa(ScanDTE->BaseDllName.Buffer);
        BaseName.MaximumLength = ScanDTE->BaseDllName.MaximumLength;
        BaseName.Length = ScanDTE->BaseDllName.Length;
        TRACE("WinLdrScanImportDescriptorTable(): %wZ ImportTable = 0x%X\n",
            &BaseName, ImportTable);
    }

    /* If image doesn't have any import directory - just return success */
    if (ImportTable == NULL)
        return TRUE;

    /* Loop through all entries */
    for (;(ImportTable->Name != 0) && (ImportTable->FirstThunk != 0);ImportTable++)
    {
        /* Get pointer to the name */
        ImportName = (PCH)VaToPa(RVA(ScanDTE->DllBase, ImportTable->Name));
        TRACE("WinLdrScanImportDescriptorTable(): Looking at %s\n", ImportName);

        /* In case we get a reference to ourselves - just skip it */
        if (WinLdrpCompareDllName(ImportName, &ScanDTE->BaseDllName))
            continue;

        /* Load the DLL if it is not already loaded */
        if (!WinLdrCheckForLoadedDll(ModuleListHead, ImportName, &DataTableEntry))
        {
            Success = WinLdrpLoadAndScanReferencedDll(ModuleListHead,
                                                      DirectoryPath,
                                                      ImportName,
                                                      &DataTableEntry);
            if (!Success)
            {
                ERR("WinLdrpLoadAndScanReferencedDll() failed\n");
                return Success;
            }
        }

        /* Scan its import address table */
        Success = WinLdrpScanImportAddressTable(ModuleListHead,
                                                DataTableEntry->DllBase,
                                                ScanDTE->DllBase,
                                                (PIMAGE_THUNK_DATA)RVA(ScanDTE->DllBase, ImportTable->FirstThunk),
                                                DirectoryPath);

        if (!Success)
        {
            ERR("WinLdrpScanImportAddressTable() failed: ImportName = '%s', DirectoryPath = '%s'\n",
                ImportName, DirectoryPath);
            return Success;
        }
    }

    return TRUE;
}
示例#8
0
static BOOLEAN
WinLdrpScanImportAddressTable(IN OUT PLIST_ENTRY ModuleListHead,
                              IN PVOID DllBase,
                              IN PVOID ImageBase,
                              IN PIMAGE_THUNK_DATA ThunkData,
                              IN PCSTR DirectoryPath)
{
    PIMAGE_EXPORT_DIRECTORY ExportDirectory = NULL;
    BOOLEAN Success;
    ULONG ExportSize;

    TRACE("WinLdrpScanImportAddressTable(): DllBase 0x%X, "
        "ImageBase 0x%X, ThunkData 0x%X\n", DllBase, ImageBase, ThunkData);

    /* Obtain the export table from the DLL's base */
    if (DllBase == NULL)
    {
        ERR("Error, DllBase == NULL!\n");
        return FALSE;
    }
    else
    {
        ExportDirectory =
            (PIMAGE_EXPORT_DIRECTORY)RtlImageDirectoryEntryToData(VaToPa(DllBase),
                TRUE,
                IMAGE_DIRECTORY_ENTRY_EXPORT,
                &ExportSize);
    }

    TRACE("WinLdrpScanImportAddressTable(): ExportDirectory 0x%X\n", ExportDirectory);

    /* If pointer to Export Directory is */
    if (ExportDirectory == NULL)
    {
        ERR("DllBase=%p(%p)\n", DllBase, VaToPa(DllBase));
        return FALSE;
    }

    /* Go through each entry in the thunk table and bind it */
    while (((PIMAGE_THUNK_DATA)VaToPa(ThunkData))->u1.AddressOfData != 0)
    {
        /* Bind it */
        Success = WinLdrpBindImportName(ModuleListHead,
                                        DllBase,
                                        ImageBase,
                                        ThunkData,
                                        ExportDirectory,
                                        ExportSize,
                                        FALSE,
                                        DirectoryPath);

        /* Move to the next entry */
        ThunkData++;

        /* Return error if binding was unsuccessful */
        if (!Success)
            return Success;
    }

    /* Return success */
    return TRUE;
}
示例#9
0
static BOOLEAN
WinLdrpBindImportName(IN OUT PLIST_ENTRY ModuleListHead,
                      IN PVOID DllBase,
                      IN PVOID ImageBase,
                      IN PIMAGE_THUNK_DATA ThunkData,
                      IN PIMAGE_EXPORT_DIRECTORY ExportDirectory,
                      IN ULONG ExportSize,
                      IN BOOLEAN ProcessForwards,
                      IN PCSTR DirectoryPath)
{
    ULONG Ordinal;
    PULONG NameTable, FunctionTable;
    PUSHORT OrdinalTable;
    LONG High, Low, Middle, Result;
    ULONG Hint;
    PIMAGE_IMPORT_BY_NAME ImportData;
    PCHAR ExportName, ForwarderName;
    BOOLEAN Success;

    //TRACE("WinLdrpBindImportName(): DllBase 0x%X, ImageBase 0x%X, ThunkData 0x%X, ExportDirectory 0x%X, ExportSize %d, ProcessForwards 0x%X\n",
    //    DllBase, ImageBase, ThunkData, ExportDirectory, ExportSize, ProcessForwards);

    /* Check passed DllBase param */
    if(DllBase == NULL)
    {
        WARN("DllBase == NULL!\n");
        return FALSE;
    }

    /* Convert all non-critical pointers to PA from VA */
    ThunkData = VaToPa(ThunkData);

    /* Is the reference by ordinal? */
    if (IMAGE_SNAP_BY_ORDINAL(ThunkData->u1.Ordinal) && !ProcessForwards)
    {
        /* Yes, calculate the ordinal */
        Ordinal = (ULONG)(IMAGE_ORDINAL(ThunkData->u1.Ordinal) - (UINT32)ExportDirectory->Base);
        //TRACE("WinLdrpBindImportName(): Ordinal %d\n", Ordinal);
    }
    else
    {
        /* It's reference by name, we have to look it up in the export directory */
        if (!ProcessForwards)
        {
            /* AddressOfData in thunk entry will become a virtual address (from relative) */
            //TRACE("WinLdrpBindImportName(): ThunkData->u1.AOD was %p\n", ThunkData->u1.AddressOfData);
            ThunkData->u1.AddressOfData =
                (ULONG_PTR)RVA(ImageBase, ThunkData->u1.AddressOfData);
            //TRACE("WinLdrpBindImportName(): ThunkData->u1.AOD became %p\n", ThunkData->u1.AddressOfData);
        }

        /* Get the import name */
        ImportData = VaToPa((PVOID)ThunkData->u1.AddressOfData);

        /* Get pointers to Name and Ordinal tables (RVA -> VA) */
        NameTable = VaToPa(RVA(DllBase, ExportDirectory->AddressOfNames));
        OrdinalTable = VaToPa(RVA(DllBase, ExportDirectory->AddressOfNameOrdinals));

        //TRACE("NameTable 0x%X, OrdinalTable 0x%X, ED->AddressOfNames 0x%X, ED->AOFO 0x%X\n",
        //    NameTable, OrdinalTable, ExportDirectory->AddressOfNames, ExportDirectory->AddressOfNameOrdinals);

        /* Get the hint, convert it to a physical pointer */
        Hint = ((PIMAGE_IMPORT_BY_NAME)VaToPa((PVOID)ThunkData->u1.AddressOfData))->Hint;
        //TRACE("HintIndex %d\n", Hint);

        /* Get the export name from the hint */
        ExportName = VaToPa(RVA(DllBase, NameTable[Hint]));

        /* If Hint is less than total number of entries in the export directory,
           and import name == export name, then we can just get it from the OrdinalTable */
        if ((Hint < ExportDirectory->NumberOfNames) &&
            (strcmp(ExportName, (PCHAR)ImportData->Name) == 0))
        {
            Ordinal = OrdinalTable[Hint];
            //TRACE("WinLdrpBindImportName(): Ordinal %d\n", Ordinal);
        }
        else
        {
            /* It's not the easy way, we have to lookup import name in the name table.
               Let's use a binary search for this task. */

            //TRACE("WinLdrpBindImportName() looking up the import name using binary search...\n");

            /* Low boundary is set to 0, and high boundary to the maximum index */
            Low = 0;
            High = ExportDirectory->NumberOfNames - 1;

            /* Perform a binary-search loop */
            while (High >= Low)
            {
                /* Divide by 2 by shifting to the right once */
                Middle = (Low + High) / 2;

                /* Get the name from the name table */
                ExportName = VaToPa(RVA(DllBase, NameTable[Middle]));

                /* Compare the names */
                Result = strcmp(ExportName, (PCHAR)ImportData->Name);

                /*TRACE("Binary search: comparing Import '__', Export '%s'\n",*/
                    /*VaToPa(&((PIMAGE_IMPORT_BY_NAME)VaToPa(ThunkData->u1.AddressOfData))->Name[0]),*/
                    /*(PCHAR)VaToPa(RVA(DllBase, NameTable[Middle])));*/

                /*TRACE("TE->u1.AOD %p, fulladdr %p\n",
                    ThunkData->u1.AddressOfData,
                    ((PIMAGE_IMPORT_BY_NAME)VaToPa(ThunkData->u1.AddressOfData))->Name );*/


                /* Depending on result of strcmp, perform different actions */
                if (Result > 0)
                {
                    /* Adjust top boundary */
                    High = Middle - 1;
                }
                else if (Result < 0)
                {
                    /* Adjust bottom boundary */
                    Low = Middle + 1;
                }
                else
                {
                    /* Yay, found it! */
                    break;
                }
            }

            /* If high boundary is less than low boundary, then no result found */
            if (High < Low)
            {
                //Print(L"Error in binary search\n");
                ERR("Did not find export '%s'!\n", (PCHAR)ImportData->Name);
                return FALSE;
            }

            /* Everything alright, get the ordinal */
            Ordinal = OrdinalTable[Middle];

            //TRACE("WinLdrpBindImportName() found Ordinal %d\n", Ordinal);
        }
    }

    /* Check ordinal number for validity! */
    if (Ordinal >= ExportDirectory->NumberOfFunctions)
    {
        ERR("Ordinal number is invalid!\n");
        return FALSE;
    }

    /* Get a pointer to the function table */
    FunctionTable = (PULONG)VaToPa(RVA(DllBase, ExportDirectory->AddressOfFunctions));

    /* Save a pointer to the function */
    ThunkData->u1.Function = (ULONG_PTR)RVA(DllBase, FunctionTable[Ordinal]);

    /* Is it a forwarder? (function pointer is within the export directory) */
    ForwarderName = (PCHAR)VaToPa((PVOID)ThunkData->u1.Function);
    if (((ULONG_PTR)ForwarderName > (ULONG_PTR)ExportDirectory) &&
        ((ULONG_PTR)ForwarderName < ((ULONG_PTR)ExportDirectory + ExportSize)))
    {
        PLDR_DATA_TABLE_ENTRY DataTableEntry;
        CHAR ForwardDllName[255];
        PIMAGE_EXPORT_DIRECTORY RefExportDirectory;
        ULONG RefExportSize;
        TRACE("WinLdrpBindImportName(): ForwarderName %s\n", ForwarderName);

        /* Save the name of the forward dll */
        RtlCopyMemory(ForwardDllName, ForwarderName, sizeof(ForwardDllName));

        /* Strip out the symbol name */
        *strrchr(ForwardDllName,'.') = '\0';

        /* Check if the target image is already loaded */
        if (!WinLdrCheckForLoadedDll(ModuleListHead, ForwardDllName, &DataTableEntry))
        {
            /* Check if the forward dll name has an extension */
            if (strchr(ForwardDllName, '.') == NULL)
            {
                /* Name does not have an extension, append '.dll' */
                strcat(ForwardDllName, ".dll");
            }

            /* Now let's try to load it! */
            Success = WinLdrpLoadAndScanReferencedDll(ModuleListHead,
                                                      DirectoryPath,
                                                      ForwardDllName,
                                                      &DataTableEntry);
            if (!Success)
            {
                ERR("WinLdrpLoadAndScanReferencedDll() failed to load forwarder dll.\n");
                return Success;
            }
        }

        /* Get pointer to the export directory of loaded DLL */
        RefExportDirectory = (PIMAGE_EXPORT_DIRECTORY)
            RtlImageDirectoryEntryToData(VaToPa(DataTableEntry->DllBase),
            TRUE,
            IMAGE_DIRECTORY_ENTRY_EXPORT,
            &RefExportSize);

        /* Fail if it's NULL */
        if (RefExportDirectory)
        {
            UCHAR Buffer[128];
            IMAGE_THUNK_DATA RefThunkData;
            PIMAGE_IMPORT_BY_NAME ImportByName;
            PCHAR ImportName;

            /* Get pointer to the import name */
            ImportName = strrchr(ForwarderName, '.') + 1;

            /* Create a IMAGE_IMPORT_BY_NAME structure, pointing to the local Buffer */
            ImportByName = (PIMAGE_IMPORT_BY_NAME)Buffer;

            /* Fill the name with the import name */
            RtlCopyMemory(ImportByName->Name, ImportName, strlen(ImportName)+1);

            /* Set Hint to 0 */
            ImportByName->Hint = 0;

            /* And finally point ThunkData's AddressOfData to that structure */
            RefThunkData.u1.AddressOfData = (ULONG_PTR)ImportByName;

            /* And recursively call ourselves */
            Success = WinLdrpBindImportName(ModuleListHead,
                                            DataTableEntry->DllBase,
                                            ImageBase,
                                            &RefThunkData,
                                            RefExportDirectory,
                                            RefExportSize,
                                            TRUE,
                                            DirectoryPath);

            /* Fill out the ThunkData with data from RefThunkData */
            ThunkData->u1 = RefThunkData.u1;

            /* Return what we got from the recursive call */
            return Success;
        }
        else
        {
            /* Fail if ExportDirectory is NULL */
            return FALSE;
        }
    }

    /* Success! */
    return TRUE;
}
示例#10
0
BOOLEAN
WinLdrAllocateDataTableEntry(IN OUT PLIST_ENTRY ModuleListHead,
                             IN PCCH BaseDllName,
                             IN PCCH FullDllName,
                             IN PVOID BasePA,
                             OUT PLDR_DATA_TABLE_ENTRY *NewEntry)
{
    PVOID BaseVA = PaToVa(BasePA);
    PWSTR Buffer;
    PLDR_DATA_TABLE_ENTRY DataTableEntry;
    PIMAGE_NT_HEADERS NtHeaders;
    USHORT Length;
    TRACE("WinLdrAllocateDataTableEntry(, '%s', '%s', %p)\n",
       BaseDllName, FullDllName, BasePA);

    /* Allocate memory for a data table entry, zero-initialize it */
    DataTableEntry = (PLDR_DATA_TABLE_ENTRY)FrLdrHeapAlloc(sizeof(LDR_DATA_TABLE_ENTRY),
                                                           TAG_WLDR_DTE);
    if (DataTableEntry == NULL)
        return FALSE;
    RtlZeroMemory(DataTableEntry, sizeof(LDR_DATA_TABLE_ENTRY));

    /* Get NT headers from the image */
    NtHeaders = RtlImageNtHeader(BasePA);

    /* Initialize corresponding fields of DTE based on NT headers value */
    DataTableEntry->DllBase = BaseVA;
    DataTableEntry->SizeOfImage = NtHeaders->OptionalHeader.SizeOfImage;
    DataTableEntry->EntryPoint = RVA(BaseVA, NtHeaders->OptionalHeader.AddressOfEntryPoint);
    DataTableEntry->SectionPointer = 0;
    DataTableEntry->CheckSum = NtHeaders->OptionalHeader.CheckSum;

    /* Initialize BaseDllName field (UNICODE_STRING) from the Ansi BaseDllName
       by simple conversion - copying each character */
    Length = (USHORT)(strlen(BaseDllName) * sizeof(WCHAR));
    Buffer = (PWSTR)FrLdrHeapAlloc(Length, TAG_WLDR_NAME);
    if (Buffer == NULL)
    {
        FrLdrHeapFree(DataTableEntry, TAG_WLDR_DTE);
        return FALSE;
    }
    RtlZeroMemory(Buffer, Length);

    DataTableEntry->BaseDllName.Length = Length;
    DataTableEntry->BaseDllName.MaximumLength = Length;
    DataTableEntry->BaseDllName.Buffer = PaToVa(Buffer);
    while (*BaseDllName != 0)
    {
        *Buffer++ = *BaseDllName++;
    }

    /* Initialize FullDllName field (UNICODE_STRING) from the Ansi FullDllName
       using the same method */
    Length = (USHORT)(strlen(FullDllName) * sizeof(WCHAR));
    Buffer = (PWSTR)FrLdrHeapAlloc(Length, TAG_WLDR_NAME);
    if (Buffer == NULL)
    {
        FrLdrHeapFree(DataTableEntry, TAG_WLDR_DTE);
        return FALSE;
    }
    RtlZeroMemory(Buffer, Length);

    DataTableEntry->FullDllName.Length = Length;
    DataTableEntry->FullDllName.MaximumLength = Length;
    DataTableEntry->FullDllName.Buffer = PaToVa(Buffer);
    while (*FullDllName != 0)
    {
        *Buffer++ = *FullDllName++;
    }

    /* Initialize what's left - LoadCount which is 1, and set Flags so that
       we know this entry is processed */
    DataTableEntry->Flags = LDRP_ENTRY_PROCESSED;
    DataTableEntry->LoadCount = 1;

    /* Insert this DTE to a list in the LPB */
    InsertTailList(ModuleListHead, &DataTableEntry->InLoadOrderLinks);
    TRACE("Inserting DTE %p, name='%.*S' DllBase=%p \n", DataTableEntry,
          DataTableEntry->BaseDllName.Length / 2,
          VaToPa(DataTableEntry->BaseDllName.Buffer),
          DataTableEntry->DllBase);

    /* Save pointer to a newly allocated and initialized entry */
    *NewEntry = DataTableEntry;

    /* Return success */
    return TRUE;
}
示例#11
0
文件: heap.c 项目: killvxk/NT_OS
PVOID
HeapCreate(
    SIZE_T MaximumSize,
    TYPE_OF_MEMORY MemoryType)
{
    PHEAP Heap;
    PHEAP_BLOCK Block;
    SIZE_T Remaining;
    USHORT PreviousSize;
    TRACE("HeapCreate(MemoryType=%ld)\n", MemoryType);

    /* Allocate some memory for the heap */
    MaximumSize = ALIGN_UP_BY(MaximumSize, MM_PAGE_SIZE);
    Heap = /*MmAllocateMemoryWithType*/VaToPa(MmHeapAllocEx(MaximumSize/*, MemoryType*/));
    if (!Heap)
    {
        ERR("HEAP: Failed to allocate heap of size 0x%lx, Type\n",
            MaximumSize, MemoryType);
        return NULL;
    }

    /* Initialize the heap header */
    Heap->MaximumSize = MaximumSize;
    Heap->CurrentAllocBytes = 0;
    Heap->MaxAllocBytes = 0;
    Heap->NumAllocs = 0;
    Heap->NumFrees = 0;
    Heap->LargestAllocation = 0;

    /* Calculate what's left to process */
    Remaining = (MaximumSize - sizeof(HEAP)) / sizeof(HEAP_BLOCK);
    TRACE("Remaining = %ld\n", Remaining);

    /* Substract 2 for the terminating entry (header + free entry) */
    Remaining -= 2;

    Block = &Heap->Blocks;
    PreviousSize = 0;

    /* Create free blocks */
    while (Remaining > 1)
    {
        /* Initialize this free block */
        Block->Size = (USHORT)min(MAXUSHORT, Remaining - 1);
        Block->PreviousSize = PreviousSize;
        Block->Tag = 0;
        Block->Data[0].Flink = (Block - &Heap->Blocks) + Block->Size + 1;
        Block->Data[0].Blink = (Block - &Heap->Blocks) - 1 - PreviousSize;

        /* Substract current block size from remainder */
        Remaining -= (Block->Size + 1);

        /* Go to next block */
        PreviousSize = Block->Size;
        Block = Block + Block->Size + 1;

        TRACE("Remaining = %ld\n", Remaining);
    }

    /* Now finish with a terminating block */
    Heap->TerminatingBlock = Block - &Heap->Blocks;
    Block->Size = 0;
    Block->PreviousSize = PreviousSize;
    Block->Tag = 'dnE#';
    Block->Data[0].Flink = 0;
    Block->Data[0].Blink = (Block - &Heap->Blocks) - 1 - PreviousSize;
    Heap->Blocks.Data[0].Blink = Heap->TerminatingBlock;

    return Heap;
}
示例#12
0
// This function converts only Child->Child, and calls itself for each Sibling
VOID
ConvertConfigToVA(PCONFIGURATION_COMPONENT_DATA Start)
{
	PCONFIGURATION_COMPONENT_DATA Child;
	PCONFIGURATION_COMPONENT_DATA Sibling;

	TRACE("ConvertConfigToVA(Start 0x%X)\n", Start);
	Child = Start;

	while (Child != NULL)
	{
		if (Child->ConfigurationData)
			Child->ConfigurationData = PaToVa(Child->ConfigurationData);

		if (Child->Child)
			Child->Child = PaToVa(Child->Child);

		if (Child->Parent)
			Child->Parent = PaToVa(Child->Parent);

		if (Child->Sibling)
			Child->Sibling = PaToVa(Child->Sibling);

		if (Child->ComponentEntry.Identifier)
			Child->ComponentEntry.Identifier = PaToVa(Child->ComponentEntry.Identifier);

		TRACE("Device 0x%X class %d type %d id '%s', parent %p\n", Child,
			Child->ComponentEntry.Class, Child->ComponentEntry.Type, VaToPa(Child->ComponentEntry.Identifier), Child->Parent);

		// Go through siblings list
		Sibling = VaToPa(Child->Sibling);
		while (Sibling != NULL)
		{
			if (Sibling->ConfigurationData)
				Sibling->ConfigurationData = PaToVa(Sibling->ConfigurationData);

			if (Sibling->Child)
				Sibling->Child = PaToVa(Sibling->Child);

			if (Sibling->Parent)
				Sibling->Parent = PaToVa(Sibling->Parent);

			if (Sibling->Sibling)
				Sibling->Sibling = PaToVa(Sibling->Sibling);

			if (Sibling->ComponentEntry.Identifier)
				Sibling->ComponentEntry.Identifier = PaToVa(Sibling->ComponentEntry.Identifier);

			TRACE("Device 0x%X class %d type %d id '%s', parent %p\n", Sibling,
				Sibling->ComponentEntry.Class, Sibling->ComponentEntry.Type, VaToPa(Sibling->ComponentEntry.Identifier), Sibling->Parent);

			// Recurse into the Child tree
			if (VaToPa(Sibling->Child) != NULL)
				ConvertConfigToVA(VaToPa(Sibling->Child));

			Sibling = VaToPa(Sibling->Sibling);
		}

		// Go to the next child
		Child = VaToPa(Child->Child);
	}
}