@@ -655,15 +655,240 @@ NTSTATUS
655
655
ImgpLoadPEImage (
656
656
_In_ PBL_IMG_FILE ImageFile ,
657
657
_In_ BL_MEMORY_TYPE MemoryType ,
658
- _Out_ PVOID * ImageBase ,
658
+ _Inout_ PVOID * ImageBase ,
659
659
_Out_ PULONG ImageSize ,
660
- _Out_ PVOID Hash ,
660
+ _Inout_opt_ PVOID Hash ,
661
661
_In_ ULONG Flags
662
662
)
663
663
{
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 ;
667
892
}
668
893
669
894
NTSTATUS
@@ -691,7 +916,7 @@ BlImgLoadPEImageEx (
691
916
}
692
917
693
918
/* 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 )))
695
920
{
696
921
return STATUS_INVALID_PARAMETER ;
697
922
}
@@ -708,11 +933,6 @@ BlImgLoadPEImageEx (
708
933
Hash ,
709
934
Flags );
710
935
}
711
- else
712
- {
713
- /* For temporary debugging */
714
- EfiPrintf (L"Couldn't open file: %lx\r\n" , Status );
715
- }
716
936
717
937
/* Close the image file and return back to caller */
718
938
ImgpCloseFile (& ImageFile );
@@ -750,8 +970,6 @@ BlImgLoadBootApplication (
750
970
ImageSize = 0 ;
751
971
ImageBase = NULL ;
752
972
753
- EfiPrintf (L"Loading application %p\r\n" , BootEntry );
754
-
755
973
/* Check for "allowed in-memory settings" */
756
974
Status = BlpGetBootOptionIntegerList (BootEntry -> BcdData ,
757
975
BcdLibraryIntegerList_AllowedInMemorySettings ,
@@ -804,12 +1022,10 @@ BlImgLoadBootApplication (
804
1022
}
805
1023
806
1024
/* Open the device */
807
- EfiPrintf (L"Opening device for path: %s\r\n" , Path );
808
1025
Status = BlpDeviceOpen (Device ,
809
1026
BL_DEVICE_READ_ACCESS ,
810
1027
0 ,
811
1028
& DeviceId );
812
- EfiPrintf (L"Device ID: %lx %lx\r\n" , Status , DeviceId );
813
1029
if (!NT_SUCCESS (Status ))
814
1030
{
815
1031
goto Quickie ;
0 commit comments