PDA

View Full Version : question in startup\main.c


yangzhengbao
04-04-2006, 09:22 PM
OptionalHeader = (PIMAGE_OPTIONAL_HEADER)((PUCHAR)&edata + sizeof(IMAGE_FILE_HEADER)); ????????????????
edata=?








VOID
SuMain(
IN FPVOID BtRootDir,
IN FPDISKBPB BtBiosBlock,
IN SHORT BtBootDrive
)
/*++

Routine Description:

Main entrypoint of the SU module. Control is passed from the boot
sector to startup.asm which does some run-time fixups on the stack
and data segments and then passes control here.

Arguments:

BtRootDir - Address of root directory left in memory by boot sector

BtBiosBlock - Address of bios parameter block.

BtBootDrive - Drive that we booted from.

Returns:

Does not return. Passes control to the OS loader


--*/
{
ULONG LoaderEntryPoint;
ULONG EisaNumPages;
USHORT IsaNumPages;
MEMORY_LIST_ENTRY _far *CurrentEntry;
PIMAGE_OPTIONAL_HEADER OptionalHeader;
ULONG BlockEnd;
ULONG ImageSize;
ULONG ImageBase;

//
// Save fs context info
//

FsContext.BootDrive = (ULONG)BtBootDrive;
FsContext.PointerToBPB = MAKE_FLAT_ADDRESS(BtBiosBlock);

//
// Initialize the video subsystem first so that
// errors end exceptions can be displayed.
//

InitializeVideoSubSystem();

//
// In case we booted from a floppy, turn the drive motor off.
//

TurnMotorOff();

//
// Copy floppy disk-base table and patch it so we can talk to both
// 5.25 and 3.5 floppies
//
PatchDiskBaseTable();

//
// Set up machine type based on its Bus type.
//

if (BtIsEisaSystem()) {
MachineType = MACHINE_TYPE_EISA;
} else {
if (BtIsMcaSystem()) {
MachineType = MACHINE_TYPE_MCA;
} else {
MachineType = MACHINE_TYPE_ISA;
}
}

if (!ConstructMemoryDescriptors()) {
//
// If INT 15 E802h fails...
//

if (MachineType == MACHINE_TYPE_EISA) {

//
// HACKHACK John Vert (jvert)
// This is completely bogus. Since there are a number of EISA
// machines which do not let you correctly configure the EISA
// NVRAM, and even MORE machines which are improperly configured,
// we first check to see how much memory the ISA routines say
// exists. Then we check what the EISA routines tell us, and
// compare the two. If the EISA number is much lower (where "much"
// is a completely random fudge factor) than the ISA number, we
// assume the machine is improperly configured and we throw away
// the EISA numbers and use the ISA ones. If not, we assume that
// the machine is actually configured properly and we trust the
// EISA numbers..
//

IsaNumPages = IsaConstructMemoryDescriptors();
EisaNumPages = EisaConstructMemoryDescriptors();
if (EisaNumPages + 0x80 < IsaNumPages) {
IsaConstructMemoryDescriptors();
}
} else {
if (MachineType == MACHINE_TYPE_MCA) {
McaConstructMemoryDescriptors();
} else {
IsaConstructMemoryDescriptors();
}
}
}

//
// Search for memory descriptor describing low memory
//
CurrentEntry = MemoryDescriptorList;
while ((CurrentEntry->BlockBase != 0) &&
(CurrentEntry->BlockSize != 0)) {
CurrentEntry++;
}

if ((CurrentEntry->BlockBase == 0) &&
(CurrentEntry->BlockSize < (ULONG)512 * (ULONG)1024)) {

BlPrint(SU_NO_LOW_MEMORY,CurrentEntry->BlockSize/1024);
while (1) {
}
}

//
// Ensure there is a memory descriptor to contain osloader image
//
OptionalHeader = (PIMAGE_OPTIONAL_HEADER)((PUCHAR)&edata + sizeof(IMAGE_FILE_HEADER));
ImageBase = OptionalHeader->ImageBase;
ImageSize = OptionalHeader->SizeOfImage;
OsLoaderBase = ImageBase;
OsLoaderExports = ImageBase + OptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
CurrentEntry = MemoryDescriptorList;
while (ImageSize > 0) {
while (CurrentEntry->BlockSize != 0) {
BlockEnd = CurrentEntry->BlockBase + CurrentEntry->BlockSize;

if ((CurrentEntry->BlockBase <= ImageBase) &&
(BlockEnd > ImageBase)) {

//
// this descriptor at least partially contains a chunk
// of the osloader.
//
if (BlockEnd-ImageBase > ImageSize) {
ImageSize = 0;
} else {
ImageSize -= (BlockEnd-ImageBase);
ImageBase = BlockEnd;
}

//
// look for remaining part (if any) of osloader
//
CurrentEntry = MemoryDescriptorList;
break;
}
CurrentEntry++;
}
if (CurrentEntry->BlockSize == 0) {
break;
}
}

if (ImageSize > 0) {
//
// We could not relocate the osloader to high memory. Error out
// and display the memory map.
//
BlPrint(SU_NO_EXTENDED_MEMORY);

CurrentEntry = MemoryDescriptorList;
while (CurrentEntry->BlockSize != 0) {
BlPrint(" %lx - %lx\n",
CurrentEntry->BlockBase,
CurrentEntry->BlockBase + CurrentEntry->BlockSize);

CurrentEntry++;
}
while (1) {
}

}

//
// Enable the A20 line for protect mode
//

EnableA20();

//
// Relocate x86 structures. This includes the GDT, IDT,
// page directory, and first level page table.
//

Relocatex86Structures();

//
// Enable protect and paging modes for the first time
//


EnableProtectPaging(ENABLING);

//
// Go relocate loader sections and build page table entries
//

LoaderEntryPoint = RelocateLoaderSections(&OsLoaderStart, &OsLoaderEnd);

//
// Search for memory descriptor containing the osloader and
// change it.
//

//
// Transfer control to the OS loader
//

TransferToLoader(LoaderEntryPoint);

}

0x517A5D
04-06-2006, 03:48 AM
Originally posted by yangzhengbao@Apr 4 2006, 06:22 PM
OptionalHeader = (PIMAGE_OPTIONAL_HEADER)((PUCHAR)&edata + sizeof(IMAGE_FILE_HEADER)); ????????????????
edata=?1337


edata is a globally known location, presumably the start of the PE header of osloader.exe in the 32-bit code segment (if I've deciphered this correctly).

We take the address with &edata, cast it to a pointer to unsigned char so we can do byte math, bump past an IMAGE_FILE_HEADER, and recast the resulting pointer as a PIMAGE_OPTIONAL_HEADER.

IMAGE_FILE_HEADER, IMAGE_OPTIONAL_HEADER, and the P* variants are defined in <winnt.h> in your C compiler's include directory tree. They are intimately related to Win32 executables.


0x517A5D out.

yangzhengbao
04-07-2006, 08:42 AM
OptionalHeader = (PIMAGE_OPTIONAL_HEADER)((PUCHAR)&edata + sizeof(IMAGE_NT_HEADER)); x