|
|
#include "bldr.h"
#include "sal.h"
#include "ssc.h"
#include "ntimage.h"
#define SECTOR_SIZE 512
SalDiskReadWrite( ULONG ReadWrite, ULONG SectorsToRead, ULONG Cylinder, ULONG CylinderPerSector, ULONG Head, ULONG Drive, PUCHAR Buffer ) { IA32_BIOS_REGISTER_STATE IA32RegisterState; BIT32_AND_BIT16 IA32Register;
if (ReadWrite == 0) { IA32Register.HighPart16 = 0x02; } else { IA32Register.HighPart16 = 0x03; }
IA32Register.LowPart16 = SectorsToRead; IA32RegisterState.eax = IA32Register.Part32;
IA32Register.HighPart16 = Cylinder; IA32Register.LowPart16 = CylinderPerSector; IA32RegisterState.ecx = IA32Register.Part32;
IA32Register.HighPart16 = Head; IA32Register.LowPart16 = Drive; IA32RegisterState.edx = IA32Register.Part32;
IA32RegisterState.es = 0;
IA32Register.HighPart16 = 0; IA32Register.LowPart16 = Buffer; IA32RegisterState.ebx = IA32Register.Part32; // SAL_PROC(0x100,&IA32RegisterState,0,0,0,0,0,0,);
}
ReadSectors( ULONG SectorBase, USHORT SectorCount, PUCHAR Buffer) { static char *VolumeName = "\\\\.\\D:"; SSC_HANDLE VolumeHandle; SSC_DISK_REQUEST Request[1]; SSC_DISK_COMPLETION DiskCompletion; LARGE_INTEGER VolumeNamePtr; LARGE_INTEGER RequestPtr; LARGE_INTEGER VolumeOffset; LARGE_INTEGER DiskCompletionPtr;
VolumeNamePtr.LowPart = VolumeName; VolumeNamePtr.HighPart = 0; VolumeHandle = SscDiskOpenVolume (VolumeNamePtr, SSC_ACCESS_READ);
Request[0].DiskBufferAddress.LowPart = Buffer; Request[0].DiskBufferAddress.HighPart = 0; Request[0].DiskByteCount = SectorCount * SECTOR_SIZE; RequestPtr.LowPart = Request; RequestPtr.HighPart = 0;
VolumeOffset.LowPart = SectorBase * SECTOR_SIZE; VolumeOffset.HighPart = 0; SscDiskReadVolume(VolumeHandle, 1, RequestPtr, VolumeOffset);
DiskCompletion.VolumeHandle = VolumeHandle; DiskCompletionPtr.LowPart = &DiskCompletion; DiskCompletionPtr.HighPart = 0; while (1) { if (SscDiskWaitIoCompletion(DiskCompletionPtr) == 0) break; } }
SalPrint( PUCHAR Buffer ) { IA32_BIOS_REGISTER_STATE IA32RegisterState; BIT32_AND_BIT16 IA32Register; ULONG i;
for (i = 0; Buffer[i] != 0 && i < 256; i++) { IA32Register.HighPart16 = 14; IA32Register.LowPart16 = Buffer[i]; IA32RegisterState.eax = IA32Register.Part32;
IA32RegisterState.ebx = 7; // SAL_PROC(0x100,&IA32RegisterState,0,0,0,0,0,0,);
} }
Multiply( ULONG Multiplicant, ULONG Multiplier) { return(Multiplicant * Multiplier); }
Divide( ULONG Numerator, ULONG Denominator, PULONG Result, PULONG Remainder ) { float f1, f2;
f1 = (float) Numerator; f2 = (float) Denominator; *Result = (ULONG) (f1 / f2); *Remainder = Numerator % Denominator; }
memcpy( PUCHAR Source, PUCHAR Destination, ULONG Length ) { while (Length--) { *Destination++ = *Source++; } }
memmove( PUCHAR Source, PUCHAR Destination, ULONG Length ) { while (Length--) { *Destination++ = *Source++; } }
memset( PUCHAR Destination, ULONG Length, ULONG Value ) { while (Length--) { *Destination++ = Value; } }
strncmp( PUCHAR String1, PUCHAR String2, ULONG Length ) { while (Length--) { if (*String1++ != *String2++) return(String1); } return(0); }
PrintName( PUCHAR String ) { LARGE_INTEGER StringPtr;
StringPtr.LowPart = String; StringPtr.HighPart = 0; SscDbgPrintf(StringPtr); }
BootErr$Print( PUCHAR String ) { LARGE_INTEGER StringPtr;
StringPtr.LowPart = String; StringPtr.HighPart = 0; SscDbgPrintf(StringPtr); }
LoadNtldrSymbols() { static char *NtfsBoot = "\\ntfsboot.exe"; static char *Ntldr = "\\NTLDR"; LARGE_INTEGER PhysicalPtr;
PhysicalPtr.LowPart = NtfsBoot; PhysicalPtr.HighPart = 0;
SscUnloadImage(PhysicalPtr, 0x0, (ULONG)-1, (ULONG)0);
PhysicalPtr.LowPart = Ntldr; PhysicalPtr.HighPart = 0;
SscLoadImage(PhysicalPtr, 0xE00000, 0x118A00, 0x7cc, 0, // process ID
1); // load count
}
ULONG RelocateLoaderSections( ULONG NtldrBuffer ) /*++
Routine Description:
The SU module is prepended to the OS loader file. The OS loader file is a coff++ file. This routine computes the beginning of the OS loader file, then relocates the OS loader's sections as if it were just loading the file from disk file.
Arguments:
NtldrBuffer - Buffer that contains the NTLDR raw image from disk
Returns:
Entry point of loader
--*/ { ULONG Start, End; USHORT Section; ULONG Source,Destination; ULONG VirtualSize; ULONG SizeOfRawData; PIMAGE_FILE_HEADER FileHeader; PIMAGE_OPTIONAL_HEADER OptionalHeader; PIMAGE_SECTION_HEADER SectionHeader;
//
// Make a pointer to the beginning of the loader's coff header
//
FileHeader = (PIMAGE_FILE_HEADER) NtldrBuffer;
//
// Validate the appended loader image by checking signatures.
// 1st - is it an executable image?
// 2nd - is the target environment the 386?
//
if ((FileHeader->Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE) == 0) { SalPrint("SU_NTLDR_CORRUPT"); return; }
if (FileHeader->Machine != IMAGE_FILE_MACHINE_IA64) { SalPrint("SU_NTLDR_CORRUPT"); return; }
//
// Make a pointer to the optional header in the header-buffer
//
OptionalHeader = (PIMAGE_OPTIONAL_HEADER)((PUCHAR)FileHeader + sizeof(IMAGE_FILE_HEADER));
//
// Make a pointer to the first section in the header buffer
//
SectionHeader = (PIMAGE_SECTION_HEADER)((PUCHAR)OptionalHeader + FileHeader->SizeOfOptionalHeader);
Start = OptionalHeader->ImageBase+SectionHeader->VirtualAddress; End = Start + SectionHeader->SizeOfRawData;
//
// Loop and relocate each section with a non-zero RawData size
//
for (Section=FileHeader->NumberOfSections ; Section-- ; SectionHeader++) {
//
// Compute source, destination, and count arguments
//
Source = NtldrBuffer + SectionHeader->PointerToRawData; Destination = OptionalHeader->ImageBase + SectionHeader->VirtualAddress;
VirtualSize = SectionHeader->Misc.VirtualSize; SizeOfRawData = SectionHeader->SizeOfRawData;
if (VirtualSize == 0) { VirtualSize = SizeOfRawData; }
if (SectionHeader->PointerToRawData == 0) { //
// SizeOfRawData can be non-zero even if PointerToRawData is zero
//
SizeOfRawData = 0; } else if (SizeOfRawData > VirtualSize) { //
// Don't load more from image than is expected in memory
//
SizeOfRawData = VirtualSize; }
if (Destination < Start) { Start = Destination; }
if (Destination+VirtualSize > End) { End = Destination+VirtualSize; }
if (SizeOfRawData != 0) { //
// This section is either a code (.TEXT) section or an
// initialized data (.DATA) section.
// Relocate the section to memory at the virtual/physical
// addresses specified in the section header.
//
memmove(Source,Destination,SizeOfRawData); }
if (SizeOfRawData < VirtualSize) { //
// Zero the portion not loaded from the image
//
memset(Destination+SizeOfRawData,0,VirtualSize - SizeOfRawData); } #if 0
//
// Check if this is the resource section. If so, we need
// to pass its location to the osloader.
//
if ((SectionHeader->Name[0] == '.') && (SectionHeader->Name[1] == 'r') && (SectionHeader->Name[2] == 's') && (SectionHeader->Name[3] == 'r') && (SectionHeader->Name[4] == 'c')) { ResourceDirectory = Destination; ResourceOffset = SectionHeader->VirtualAddress; } #endif
}
return(OptionalHeader->AddressOfEntryPoint + OptionalHeader->ImageBase); }
|