Skip to content

Commit 53c32a9

Browse files
committed
[BOOTLIB]: Begin PE loader. Works so far. Next up is loading the sections, zeroing out the .bss, and computing checksum.
svn path=/trunk/; revision=70629
1 parent 26f25f6 commit 53c32a9

File tree

2 files changed

+238
-15
lines changed

2 files changed

+238
-15
lines changed

reactos/boot/environ/include/bl.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,13 @@ DEFINE_GUID(BadMemoryGuid, 0x54B8275B, 0xD431, 0x473F, 0xAC, 0xFB, 0xE5, 0x36, 0
148148
#define BL_LOAD_IMG_COMPUTE_SIGNATURE 0x10
149149
#define BL_LOAD_IMG_COMPUTE_HASH 0x40000
150150

151+
#define BL_LOAD_PE_IMG_VIRTUAL_BUFFER BL_LOAD_IMG_VIRTUAL_BUFFER
152+
#define BL_LOAD_PE_IMG_CHECK_MACHINE 0x02
153+
#define BL_LOAD_PE_IMG_EXISTING_BUFFER BL_LOAD_IMG_EXISTING_BUFFER
154+
#define BL_LOAD_PE_IMG_COMPUTE_HASH 0x10
155+
#define BL_LOAD_PE_IMG_CHECK_SUBSYSTEM 0x80
156+
#define BL_LOAD_PE_IMG_CHECK_FORCED_INTEGRITY 0x200
157+
151158
/* ENUMERATIONS **************************************************************/
152159

153160
typedef enum _BL_COLOR

reactos/boot/environ/lib/misc/image.c

Lines changed: 231 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -655,15 +655,240 @@ NTSTATUS
655655
ImgpLoadPEImage (
656656
_In_ PBL_IMG_FILE ImageFile,
657657
_In_ BL_MEMORY_TYPE MemoryType,
658-
_Out_ PVOID* ImageBase,
658+
_Inout_ PVOID* ImageBase,
659659
_Out_ PULONG ImageSize,
660-
_Out_ PVOID Hash,
660+
_Inout_opt_ PVOID Hash,
661661
_In_ ULONG Flags
662662
)
663663
{
664-
/* Micro-PE loader (no imports/exports/etc) */
665-
EfiPrintf(L"PE not implemented\r\n");
666-
return STATUS_NOT_IMPLEMENTED;
664+
NTSTATUS Status;
665+
ULONG FileSize, HeaderSize;
666+
PVOID ImageBuffer;
667+
BL_IMG_FILE LocalFileBuffer;
668+
PBL_IMG_FILE LocalFile;
669+
PVOID VirtualAddress;
670+
ULONGLONG VirtualSize;
671+
PHYSICAL_ADDRESS PhysicalAddress;
672+
PIMAGE_NT_HEADERS NtHeaders;
673+
674+
/* Initialize locals */
675+
LocalFile = NULL;
676+
ImageBuffer = NULL;
677+
FileSize = 0;
678+
679+
/* Get the size of the image */
680+
Status = ImgpGetFileSize(ImageFile, &FileSize);
681+
if (!NT_SUCCESS(Status))
682+
{
683+
return STATUS_FILE_INVALID;
684+
}
685+
686+
/* Allocate a flat buffer for it */
687+
Status = BlImgAllocateImageBuffer(&ImageBuffer, BlLoaderData, FileSize, 0);
688+
if (!NT_SUCCESS(Status))
689+
{
690+
goto Quickie;
691+
}
692+
693+
/* Read the whole file flat for now */
694+
Status = ImgpReadAtFileOffset(ImageFile, FileSize, 0, ImageBuffer, NULL);
695+
if (!NT_SUCCESS(Status))
696+
{
697+
goto Quickie;
698+
}
699+
700+
/* Build a local file handle */
701+
LocalFile = &LocalFileBuffer;
702+
LocalFileBuffer.FileName = ImageFile->FileName;
703+
LocalFileBuffer.Flags = BL_IMG_MEMORY_FILE | BL_IMG_VALID_FILE;
704+
LocalFileBuffer.BaseAddress = ImageBuffer;
705+
LocalFileBuffer.FileSize = FileSize;
706+
707+
/* Get the NT headers of the file */
708+
Status = RtlImageNtHeaderEx(0, ImageBuffer, FileSize, &NtHeaders);
709+
if (!NT_SUCCESS(Status))
710+
{
711+
goto Quickie;
712+
}
713+
714+
/* Check if we should validate the machine type */
715+
if (Flags & BL_LOAD_PE_IMG_CHECK_MACHINE)
716+
{
717+
/* Is it different than our current machine type? */
718+
#if _M_AMD64
719+
if (NtHeaders->FileHeader.Machine != IMAGE_FILE_MACHINE_AMD64)
720+
#else
721+
if (NtHeaders->FileHeader.Machine != IMAGE_FILE_MACHINE_I386)
722+
#endif
723+
{
724+
/* Is it x86 (implying we are x64) ? */
725+
if (NtHeaders->FileHeader.Machine == IMAGE_FILE_MACHINE_I386)
726+
{
727+
/* Return special error code */
728+
Status = STATUS_INVALID_IMAGE_WIN_32;
729+
}
730+
else if (NtHeaders->FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64)
731+
{
732+
/* Otherwise, it's x64 but we are x86 */
733+
Status = STATUS_INVALID_IMAGE_WIN_64;
734+
}
735+
else
736+
{
737+
/* Or it's ARM or something... */
738+
Status = STATUS_INVALID_IMAGE_FORMAT;
739+
}
740+
741+
/* Return with the distinguished error code */
742+
goto Quickie;
743+
}
744+
}
745+
746+
/* Check if we should validate the subsystem */
747+
if (Flags & BL_LOAD_PE_IMG_CHECK_SUBSYSTEM)
748+
{
749+
/* It must be a Windows boot Application */
750+
if (NtHeaders->OptionalHeader.Subsystem !=
751+
IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION)
752+
{
753+
Status = STATUS_INVALID_IMAGE_FORMAT;
754+
goto Quickie;
755+
}
756+
}
757+
758+
/* Check if we should validate the /INTEGRITYCHECK flag */
759+
if (Flags & BL_LOAD_PE_IMG_CHECK_FORCED_INTEGRITY)
760+
{
761+
/* Check if it's there */
762+
if (!(NtHeaders->OptionalHeader.DllCharacteristics &
763+
IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY))
764+
{
765+
/* Nope, fail otherwise */
766+
Status = STATUS_INVALID_IMAGE_FORMAT;
767+
goto Quickie;
768+
}
769+
}
770+
771+
/* Check if we should compute the image hash */
772+
if ((Flags & BL_LOAD_PE_IMG_COMPUTE_HASH) || (Hash))
773+
{
774+
EfiPrintf(L"No hash support\r\n");
775+
}
776+
777+
/* Read the current base address, if any */
778+
VirtualAddress = *ImageBase;
779+
780+
/* Get the virtual size of the image */
781+
VirtualSize = NtHeaders->OptionalHeader.SizeOfImage;
782+
783+
/* Safely align the virtual size to a page */
784+
Status = RtlULongLongAdd(VirtualSize,
785+
PAGE_SIZE - 1,
786+
&VirtualSize);
787+
if (!NT_SUCCESS(Status))
788+
{
789+
goto Quickie;
790+
}
791+
VirtualSize = ALIGN_DOWN_BY(VirtualSize, PAGE_SIZE);
792+
793+
/* Make sure the image isn't larger than 4GB */
794+
if (VirtualSize > ULONG_MAX)
795+
{
796+
Status = STATUS_INVALID_IMAGE_FORMAT;
797+
goto Quickie;
798+
}
799+
800+
/* Check if we have a buffer already */
801+
if (Flags & BL_LOAD_IMG_EXISTING_BUFFER)
802+
{
803+
/* Check if it's too small */
804+
if (*ImageSize < VirtualSize)
805+
{
806+
/* Fail, letting the caller know how big to make it */
807+
*ImageSize = VirtualSize;
808+
Status = STATUS_BUFFER_TOO_SMALL;
809+
}
810+
}
811+
else
812+
{
813+
/* Allocate the buffer with the flags and type the caller wants */
814+
Status = BlImgAllocateImageBuffer(&VirtualAddress,
815+
MemoryType,
816+
VirtualSize,
817+
Flags);
818+
}
819+
820+
/* Bail out if allocation failed, or existing buffer is too small */
821+
if (!NT_SUCCESS(Status))
822+
{
823+
goto Quickie;
824+
}
825+
826+
/* Read the size of the headers */
827+
HeaderSize = NtHeaders->OptionalHeader.SizeOfHeaders;
828+
if (VirtualSize < HeaderSize)
829+
{
830+
/* Bail out if they're bigger than the image! */
831+
Status = STATUS_INVALID_IMAGE_FORMAT;
832+
goto Quickie;
833+
}
834+
835+
/* Now read the header into the buffer */
836+
Status = ImgpReadAtFileOffset(LocalFile, HeaderSize, 0, VirtualAddress, NULL);
837+
if (!NT_SUCCESS(Status))
838+
{
839+
goto Quickie;
840+
}
841+
842+
/* Get the NT headers of the file */
843+
Status = RtlImageNtHeaderEx(0, VirtualAddress, HeaderSize, &NtHeaders);
844+
if (!NT_SUCCESS(Status))
845+
{
846+
goto Quickie;
847+
}
848+
849+
EfiPrintf(L"MORE PE TODO: %lx\r\n", NtHeaders->OptionalHeader.AddressOfEntryPoint);
850+
EfiStall(100000000);
851+
852+
Quickie:
853+
/* Check if we had an image buffer allocated */
854+
if ((ImageBuffer) && (FileSize))
855+
{
856+
/* Free it */
857+
BlImgUnallocateImageBuffer(ImageBuffer, FileSize, 0);
858+
}
859+
860+
/* Check if we had a local file handle */
861+
if (LocalFile)
862+
{
863+
/* Close it */
864+
ImgpCloseFile(LocalFile);
865+
}
866+
867+
/* Check if this is the failure path */
868+
if (!NT_SUCCESS(Status))
869+
{
870+
/* Check if we had started mapping in the image already */
871+
if ((VirtualAddress) && !(Flags & BL_LOAD_PE_IMG_EXISTING_BUFFER))
872+
{
873+
/* Into a virtual buffer? */
874+
if (Flags & BL_LOAD_PE_IMG_VIRTUAL_BUFFER)
875+
{
876+
/* Unmap and free it */
877+
BlMmUnmapVirtualAddressEx(VirtualAddress, VirtualSize);
878+
PhysicalAddress.QuadPart = (ULONG_PTR)VirtualAddress;
879+
BlMmFreePhysicalPages(PhysicalAddress);
880+
}
881+
else
882+
{
883+
/* Into a physical buffer -- free it */
884+
EfiPrintf(L"Leaking physical pages\r\n");
885+
// MmPapFreePages(VirtualAddress, TRUE);
886+
}
887+
}
888+
}
889+
890+
/* Return back to caller */
891+
return Status;
667892
}
668893

669894
NTSTATUS
@@ -691,7 +916,7 @@ BlImgLoadPEImageEx (
691916
}
692917

693918
/* If we are loading a pre-allocated image, make sure we have it */
694-
if ((Flags & 4) && (!(*ImageBase) || !(ImageSize)))
919+
if ((Flags & BL_LOAD_IMG_EXISTING_BUFFER) && (!(*ImageBase) || !(ImageSize)))
695920
{
696921
return STATUS_INVALID_PARAMETER;
697922
}
@@ -708,11 +933,6 @@ BlImgLoadPEImageEx (
708933
Hash,
709934
Flags);
710935
}
711-
else
712-
{
713-
/* For temporary debugging */
714-
EfiPrintf(L"Couldn't open file: %lx\r\n", Status);
715-
}
716936

717937
/* Close the image file and return back to caller */
718938
ImgpCloseFile(&ImageFile);
@@ -750,8 +970,6 @@ BlImgLoadBootApplication (
750970
ImageSize = 0;
751971
ImageBase = NULL;
752972

753-
EfiPrintf(L"Loading application %p\r\n", BootEntry);
754-
755973
/* Check for "allowed in-memory settings" */
756974
Status = BlpGetBootOptionIntegerList(BootEntry->BcdData,
757975
BcdLibraryIntegerList_AllowedInMemorySettings,
@@ -804,12 +1022,10 @@ BlImgLoadBootApplication (
8041022
}
8051023

8061024
/* Open the device */
807-
EfiPrintf(L"Opening device for path: %s\r\n", Path);
8081025
Status = BlpDeviceOpen(Device,
8091026
BL_DEVICE_READ_ACCESS,
8101027
0,
8111028
&DeviceId);
812-
EfiPrintf(L"Device ID: %lx %lx\r\n", Status, DeviceId);
8131029
if (!NT_SUCCESS(Status))
8141030
{
8151031
goto Quickie;

0 commit comments

Comments
 (0)