Пример #1
0
extern "C" bool LoadPE(char* filename, char* address, SPEFile* outPEFile)
{
	void* fp = FsOpenFile(filename, 0);
	outPEFile->dosHeader = (SPEDOSHeader*)address;
	FsReadFile(fp, (char*)outPEFile->dosHeader, sizeof(SPEDOSHeader));
	if (outPEFile->dosHeader->Magic != DOS_HEADER_MAGIC)
	{
		CDisplayDriver::PrintString("DOS_HEADER_MAGIC is wrong!");
		FsCloseFile(fp);
		return false;
	}
	int dumpsize = outPEFile->dosHeader->HeaderAddress - sizeof(SPEDOSHeader);
	char* dump = new char[dumpsize];
	FsReadFile(fp, dump, dumpsize);
	delete[] dump;
	outPEFile->peHeader = (SPEHeader*)(address + outPEFile->dosHeader->HeaderAddress);
	FsReadFile(fp, (char*)outPEFile->peHeader, sizeof(SPEHeader));
	if (outPEFile->peHeader->Magic != PE_HEADER_MAGIC)
	{
		CDisplayDriver::PrintString("PE_HEADER_MAGIC is wrong!");
		FsCloseFile(fp);
		return false;
	}
	outPEFile->peoHeader = (SPEOptionalHeader*)((char*)outPEFile->peHeader + sizeof(SPEHeader));
	FsReadFile(fp, (char*)outPEFile->peoHeader, sizeof(SPEOptionalHeader));
	CDisplayDriver::PrintString("%X", outPEFile->peoHeader->SizeOfImage);
	if (outPEFile->peoHeader->Magic != PE_OPTIONAL_MAGIC_64)
	{
		
		CDisplayDriver::PrintString("PE_OPTIONAL_MAGIC_64 is wrong!");
		FsCloseFile(fp);
		return false;
	}
	outPEFile->dataDirectories = (SPEDataDirectories*)((char*)outPEFile->peoHeader + sizeof(SPEOptionalHeader));
	FsReadFile(fp, (char*)outPEFile->dataDirectories, sizeof(SPEDataDirectories));
	outPEFile->sections = new SPESection*[outPEFile->peHeader->NumberOfSections];
	for (unsigned int i = 0; i < outPEFile->peHeader->NumberOfSections; ++i)
	{
		SFile* handle = (SFile*)fp;
		outPEFile->sections[i] = (SPESection*)((char*)outPEFile->dataDirectories + sizeof(SPEDataDirectories) + (i*sizeof(SPESection)));
		FsReadFile(fp, (char*)outPEFile->sections[i], sizeof(SPESection));
	}
	for (unsigned int i = 0; i < outPEFile->peHeader->NumberOfSections; ++i)
	{		
		if (outPEFile->sections[i]->SizeOfRawData == 0)
		{
			continue;
		}
		int dumpsize = outPEFile->sections[i]->PointerToRawData - ((SFile*)fp)->bytesread;
		char* dump = new char[dumpsize];
		FsReadFile(fp, dump, dumpsize);
		delete[] dump;
		FsReadFile(fp, (char*)address + outPEFile->sections[i]->VirtualAddress, outPEFile->sections[i]->SizeOfRawData);
	}
	outPEFile->exportDirectoryTable = (SPEExportDirectoryTable*)((char*)address + outPEFile->dataDirectories->ExportTable.VirtualAddress);
	outPEFile->importDirectoryTable = (SPEImportDirectoryTable*)((char*)address + outPEFile->dataDirectories->ImportTable.VirtualAddress);	
	if (*(unsigned long long*)outPEFile->importDirectoryTable)
	{
		SPEImportLookupTable* start = (SPEImportLookupTable*)(address + outPEFile->importDirectoryTable->ImportLookupTableRVA);
		int count = 0;
		while (*(unsigned long long*)start)
		{
			start++;
			count++;
		}
		start = (SPEImportLookupTable*)(address + outPEFile->importDirectoryTable->ImportLookupTableRVA);
		outPEFile->importLookups = new SPEImportLookupTable*[count];
		int i = 0;
		while (*(unsigned long long*)start)
		{
			bool isOrdinal = start->LookupEntry & 0x8000000000000000;
			if (isOrdinal)
			{
			}
			else
			{
				unsigned long long HintNameRVA = start->LookupEntry & ~0x8000000000000000;
				SPEImportHintNameTable* HintNameTable = (SPEImportHintNameTable*)(address + HintNameRVA);
				//CDisplayDriver::PrintString("%s", &HintNameTable->Name);
				count++;
			}
			outPEFile->importLookups[i]->LookupEntry = *(unsigned long long*)start;
			start++;
			i++;
		}

		unsigned long long* startAddr = (unsigned long long*)(address + outPEFile->importDirectoryTable->ImportAddressTableRVA);
		while (*startAddr)
		{
			*startAddr += 0x20000;
			startAddr++;
		}
	}	
	FsCloseFile(fp);
	return true;
}
Пример #2
0
VOID
LoadAndBootBootSector(IN OperatingSystemItem* OperatingSystem,
                      IN USHORT OperatingSystemVersion)
{
    ULONG_PTR    SectionId;
    PCSTR    SectionName = OperatingSystem->SystemPartition;
    CHAR    FileName[260];
    PFILE    FilePointer;
    ULONG    BytesRead;
    CHAR    SettingName[80];

    // Find all the message box settings and run them
    UiShowMessageBoxesInSection(SectionName);

    // Try to open the operating system section in the .ini file
    if (!IniOpenSection(SectionName, &SectionId))
    {
        sprintf(SettingName, "Section [%s] not found in freeldr.ini.\n", SectionName);
        UiMessageBox(SettingName);
        return;
    }

    if (!IniReadSettingByName(SectionId, "BootSectorFile", FileName, sizeof(FileName)))
    {
        UiMessageBox("Boot sector file not specified for selected OS!");
        return;
    }

    FilePointer = FsOpenFile(FileName);
    if (!FilePointer)
    {
        strcat(FileName, " not found.");
        UiMessageBox(FileName);
        return;
    }

    // Read boot sector
    if (!FsReadFile(FilePointer, 512, &BytesRead, (void*)0x7c00) || (BytesRead != 512))
    {
        UiMessageBox("Unable to read boot sector.");
        return;
    }

    // Check for validity
    if (*((USHORT*)(0x7c00 + 0x1fe)) != 0xaa55)
    {
        UiMessageBox("Invalid boot sector magic (0xaa55)");
        return;
    }

    UiUnInitialize("Booting...");
    // Don't stop the floppy drive motor when we
    // are just booting a bootsector, or drive, or partition.
    // If we were to stop the floppy motor then
    // the BIOS wouldn't be informed and if the
    // next read is to a floppy then the BIOS will
    // still think the motor is on and this will
    // result in a read error.
    //DiskStopFloppyMotor();
    //DisableA20();
    ChainLoadBiosBootSectorCode();
}