ReactOS 0.4.16-dev-251-ga17b6e9
image.c File Reference
#include "bl.h"
#include <bcd.h>
Include dependency graph for image.c:

Go to the source code of this file.

Functions

NTSTATUS ImgpGetFileSize (_In_ PBL_IMG_FILE File, _Out_ PULONG FileSize)
 
NTSTATUS ImgpReadAtFileOffset (_In_ PBL_IMG_FILE File, _In_ ULONG Size, _In_ ULONGLONG ByteOffset, _In_ PVOID Buffer, _Out_ PULONG BytesReturned)
 
NTSTATUS ImgpOpenFile (_In_ ULONG DeviceId, _In_ PWCHAR FileName, _In_ ULONG Flags, _Out_ PBL_IMG_FILE NewFile)
 
NTSTATUS ImgpCloseFile (_In_ PBL_IMG_FILE File)
 
NTSTATUS BlImgUnallocateImageBuffer (_In_ PVOID ImageBase, _In_ ULONG ImageSize, _In_ ULONG ImageFlags)
 
NTSTATUS BlImgAllocateImageBuffer (_Inout_ PVOID *ImageBuffer, _In_ ULONG MemoryType, _In_ ULONGLONG ImageSize, _In_ ULONG Flags)
 
NTSTATUS BlImgLoadImageWithProgress2 (_In_ ULONG DeviceId, _In_ BL_MEMORY_TYPE MemoryType, _In_ PWCHAR FileName, _Inout_ PVOID *MappedBase, _Inout_ PULONG MappedSize, _In_ ULONG ImageFlags, _In_ BOOLEAN ShowProgress, _Out_opt_ PUCHAR *HashBuffer, _Out_opt_ PULONG HashSize)
 
PIMAGE_SECTION_HEADER BlImgFindSection (_In_ PVOID ImageBase, _In_ ULONG ImageSize)
 
VOID BlImgQueryCodeIntegrityBootOptions (_In_ PBL_LOADED_APPLICATION_ENTRY ApplicationEntry, _Out_ PBOOLEAN IntegrityChecksDisabled, _Out_ PBOOLEAN TestSigning)
 
NTSTATUS BlImgUnLoadImage (_In_ PVOID ImageBase, _In_ ULONG ImageSize, _In_ ULONG ImageFlags)
 
NTSTATUS ImgpLoadPEImage (_In_ PBL_IMG_FILE ImageFile, _In_ BL_MEMORY_TYPE MemoryType, _Inout_ PVOID *ImageBase, _Out_opt_ PULONG ImageSize, _Inout_opt_ PVOID Hash, _In_ ULONG Flags)
 
NTSTATUS BlImgLoadPEImageEx (_In_ ULONG DeviceId, _In_ BL_MEMORY_TYPE MemoryType, _In_ PWCHAR Path, _Out_ PVOID *ImageBase, _Out_ PULONG ImageSize, _Out_ PVOID Hash, _In_ ULONG Flags)
 
NTSTATUS BlImgLoadBootApplication (_In_ PBL_LOADED_APPLICATION_ENTRY BootEntry, _Out_ PULONG AppHandle)
 
NTSTATUS BlpPdParseReturnArguments (_In_ PBL_RETURN_ARGUMENTS ReturnArguments)
 
NTSTATUS ImgpCopyApplicationBootDevice (__in PBL_DEVICE_DESCRIPTOR DestinationDevice, __in PBL_DEVICE_DESCRIPTOR SourceDevice)
 
NTSTATUS ImgpInitializeBootApplicationParameters (_In_ PBL_BUFFER_DESCRIPTOR ImageParameters, _In_ PBL_APPLICATION_ENTRY AppEntry, _In_ PVOID ImageBase, _In_ ULONG ImageSize)
 
NTSTATUS ImgArchEfiStartBootApplication (_In_ PBL_APPLICATION_ENTRY AppEntry, _In_ PVOID ImageBase, _In_ ULONG ImageSize, _In_ PBL_RETURN_ARGUMENTS ReturnArguments)
 
NTSTATUS BlImgStartBootApplication (_In_ ULONG AppHandle, _Inout_opt_ PBL_RETURN_ARGUMENTS ReturnArguments)
 
NTSTATUS BlImgUnloadBootApplication (_In_ ULONG AppHandle)
 

Variables

ULONG IapAllocatedTableEntries
 
ULONG IapTableEntries
 
PVOIDIapImageTable
 
KDESCRIPTOR GdtRegister
 
KDESCRIPTOR IdtRegister
 
KDESCRIPTOR BootAppGdtRegister
 
KDESCRIPTOR BootAppIdtRegister
 
PVOID BootApp32EntryRoutine
 
PBOOT_APPLICATION_PARAMETER_BLOCK BootApp32Parameters
 
PVOID BootApp32Stack
 

Function Documentation

◆ BlImgAllocateImageBuffer()

NTSTATUS BlImgAllocateImageBuffer ( _Inout_ PVOID ImageBuffer,
_In_ ULONG  MemoryType,
_In_ ULONGLONG  ImageSize,
_In_ ULONG  Flags 
)

Definition at line 248 of file image.c.

254{
256 ULONGLONG Pages, Size;
260
261 /* Read and reset the current buffer address */
262 CurrentBuffer = *ImageBuffer;
263 *ImageBuffer = NULL;
264
265 /* Align the image size to page */
266 Size = ROUND_TO_PAGES(ImageSize);
267
268 /* Not sure what this attribute does yet */
269 Attributes = 0;
271 {
272 Attributes = 0x10000;
273 }
274
275 /* Check if the caller wants a virtual buffer */
277 {
278 /* Set the physical address to the current buffer */
280 Pages = Size >> PAGE_SHIFT;
281
282 /* Allocate the physical pages */
284 Pages,
285 MemoryType,
287 0);
288 if (!NT_SUCCESS(Status))
289 {
290 /* If that failed, remove allocation attributes */
292 Attributes &= ~BlMemoryValidAllocationAttributeMask,
294 Pages,
295 MemoryType,
297 0);
298 }
299
300 /* Check if either attempts succeeded */
301 if (!NT_SUCCESS(Status))
302 {
303 return Status;
304 }
305
306 /* Now map the physical buffer at the address requested */
310 Size,
312 if (!NT_SUCCESS(Status))
313 {
314 /* Free on failure if needed */
316 return Status;
317 }
318 }
319 else
320 {
321 /* Otherwise, allocate raw physical pages */
323 Pages = Size >> PAGE_SHIFT;
325 MemoryType,
326 Pages,
328 0,
329 NULL,
330 0);
331 if (!NT_SUCCESS(Status))
332 {
333 /* If that failed, try without allocation attributes */
335 Attributes &= ~BlMemoryValidAllocationAttributeMask,
337 MemoryType,
338 Pages,
340 0,
341 NULL,
342 0);
343 }
344
345 /* Check if either attempts succeeded */
346 if (!NT_SUCCESS(Status))
347 {
348 return Status;
349 }
350 }
351
352 /* Success path, returned allocated address */
353 *ImageBuffer = MappedBase;
354 return STATUS_SUCCESS;
355}
static ACPI_BUFFER CurrentBuffer
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS BlMmAllocatePhysicalPages(_Inout_ PPHYSICAL_ADDRESS Address, _In_ BL_MEMORY_TYPE MemoryType, _In_ ULONGLONG PageCount, _In_ ULONG Attributes, _In_ ULONG Alignment)
NTSTATUS MmPapAllocatePagesInRange(_Inout_ PVOID *PhysicalAddress, _In_ BL_MEMORY_TYPE MemoryType, _In_ ULONGLONG Pages, _In_ ULONG Attributes, _In_ ULONG Alignment, _In_opt_ PBL_ADDRESS_RANGE Range, _In_ ULONG Type)
Definition: pagealloc.c:707
NTSTATUS BlMmFreePhysicalPages(_In_ PHYSICAL_ADDRESS Address)
Definition: pagealloc.c:1187
#define BL_LOAD_IMG_VIRTUAL_BUFFER
Definition: bl.h:171
#define BL_LOAD_IMG_UNKNOWN_BUFFER_FLAG
Definition: bl.h:173
NTSTATUS BlMmMapPhysicalAddressEx(_In_ PVOID *VirtualAddress, _In_ ULONG Attributes, _In_ ULONGLONG Size, _In_ PHYSICAL_ADDRESS PhysicalAddress)
Definition: mm.c:192
@ BlMemoryFixed
Definition: bl.h:368
FORCEINLINE PVOID PhysicalAddressToPtr(_In_ PHYSICAL_ADDRESS PhysicalAddress)
Definition: bl.h:1389
#define NULL
Definition: types.h:112
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define ULONG_PTR
Definition: config.h:101
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
Status
Definition: gdiplustypes.h:25
#define STATUS_SUCCESS
Definition: shellext.h:65
uint32_t ULONG
Definition: typedefs.h:59
uint64_t ULONGLONG
Definition: typedefs.h:67
LONGLONG QuadPart
Definition: typedefs.h:114
_Must_inspect_result_ _In_ WDFDMAENABLER _In_ _In_opt_ PWDF_OBJECT_ATTRIBUTES Attributes
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS PhysicalAddress
Definition: iotypes.h:1098
_Must_inspect_result_ _Outptr_result_bytebuffer_ ViewSize PVOID * MappedBase
Definition: mmfuncs.h:492
#define ROUND_TO_PAGES(Size)

Referenced by BlImgLoadImageWithProgress2(), and ImgpLoadPEImage().

◆ BlImgFindSection()

PIMAGE_SECTION_HEADER BlImgFindSection ( _In_ PVOID  ImageBase,
_In_ ULONG  ImageSize 
)

Definition at line 611 of file image.c.

615{
616 PIMAGE_SECTION_HEADER FoundSection;
617 ULONG i;
618 PIMAGE_SECTION_HEADER SectionHeader;
619 PIMAGE_NT_HEADERS NtHeader;
621
622 /* Assume failure */
623 FoundSection = NULL;
624
625 /* Make sure the image is valid */
626 Status = RtlImageNtHeaderEx(0, ImageBase, ImageSize, &NtHeader);
627 if (NT_SUCCESS(Status))
628 {
629 /* Get the first section and loop through them all */
630 SectionHeader = IMAGE_FIRST_SECTION(NtHeader);
631 for (i = 0; i < NtHeader->FileHeader.NumberOfSections; i++)
632 {
633 /* Check if this is the resource section */
634 if (!_stricmp((PCCH)SectionHeader->Name, ".rsrc"))
635 {
636 /* Yep, we're done */
637 FoundSection = SectionHeader;
638 break;
639 }
640
641 /* Nope, keep going */
642 SectionHeader++;
643 }
644 }
645
646 /* Return the matching section */
647 return FoundSection;
648}
NTSTATUS NTAPI RtlImageNtHeaderEx(_In_ ULONG Flags, _In_ PVOID Base, _In_ ULONG64 Size, _Out_ PIMAGE_NT_HEADERS *OutHeaders)
Definition: libsupp.c:32
#define _stricmp
Definition: cat.c:22
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
CONST CHAR * PCCH
Definition: ntbasedef.h:400
#define IMAGE_FIRST_SECTION(NtHeader)
Definition: ntimage.h:427
IMAGE_FILE_HEADER FileHeader
Definition: ntddk_ex.h:183
BYTE Name[IMAGE_SIZEOF_SHORT_NAME]
Definition: pedump.c:281

Referenced by BlpResourceInitialize(), and ResFindDataEntryFromImage().

◆ BlImgLoadBootApplication()

NTSTATUS BlImgLoadBootApplication ( _In_ PBL_LOADED_APPLICATION_ENTRY  BootEntry,
_Out_ PULONG  AppHandle 
)

Definition at line 1324 of file image.c.

1328{
1330 PULONGLONG AllowedList;
1331 ULONGLONG AllowedCount;
1332 ULONG i, DeviceId, ImageSize, Flags, ListSize;
1334 PVOID UnlockCode, ImageBase;
1335 PBL_DEVICE_DESCRIPTOR Device, BitLockerDevice;
1336 PWCHAR Path;
1337 PBL_APPLICATION_ENTRY AppEntry;
1339 BOOLEAN DisableIntegrity, TestSigning;
1340 UCHAR Hash[64];
1341 PBL_IMAGE_APPLICATION_ENTRY ImageAppEntry;
1342
1343 /* Initialize all locals */
1344 BitLockerDevice = NULL;
1345 UnlockCode = NULL;
1346 ImageFile = NULL;
1347 DeviceId = -1;
1348 Device = NULL;
1349 ImageAppEntry = NULL;
1350 AppEntry = NULL;
1351 Path = NULL;
1352 ImageSize = 0;
1353 ImageBase = NULL;
1354
1355 /* Check for "allowed in-memory settings" */
1356 Status = BlpGetBootOptionIntegerList(BootEntry->BcdData,
1358 &AllowedList,
1359 &AllowedCount,
1360 TRUE);
1361 if (Status == STATUS_SUCCESS)
1362 {
1363 /* Loop through the list of allowed setting */
1364 for (i = 0; i < AllowedCount; i++)
1365 {
1366 /* Find the super undocumented one */
1367 if (AllowedList[i] == BcdLibraryInteger_UndocumentedMagic)
1368 {
1369 /* If it's present, append the current perf frequence to it */
1371 BlAppendBootOptionInteger(BootEntry,
1374 }
1375 }
1376 }
1377
1378#if BL_BITLOCKER_SUPPORT
1379 /* Do bitlocker stuff */
1380 Status = BlFveSecureBootUnlockBootDevice(BootEntry, &BitLockerDevice, &UnlockCode);
1381 if (!NT_SUCCESS(Status))
1382 {
1383 goto Quickie;
1384 }
1385#endif
1386
1387 /* Get the device on which this application is on*/
1388 Status = BlGetBootOptionDevice(BootEntry->BcdData,
1390 &Device,
1391 NULL);
1392 if (!NT_SUCCESS(Status))
1393 {
1394 goto Quickie;
1395 }
1396
1397 /* Get the path of the application */
1398 Status = BlGetBootOptionString(BootEntry->BcdData,
1400 &Path);
1401 if (!NT_SUCCESS(Status))
1402 {
1403 goto Quickie;
1404 }
1405
1406 /* Open the device */
1409 0,
1410 &DeviceId);
1411 if (!NT_SUCCESS(Status))
1412 {
1413 goto Quickie;
1414 }
1415
1416 /* Check for integrity BCD options */
1418 &DisableIntegrity,
1419 &TestSigning);
1420
1421#if BL_TPM_SUPPORT
1422 RtlZeroMemory(&Context, sizeof(Context);
1423 Context.BootEntry = BootEntry;
1424 BlEnNotifyEvent(0x10000003, &Context);
1425#endif
1426
1427 /* Enable signing and hashing checks if integrity is enabled */
1428 Flags = 0;
1429 if (!DisableIntegrity)
1430 {
1431 Flags = 0x8070;
1432 }
1433
1434 /* Now call the PE loader to load the image */
1435 Status = BlImgLoadPEImageEx(DeviceId,
1437 Path,
1438 &ImageBase,
1439 &ImageSize,
1440 Hash,
1441 Flags);
1442 if (!NT_SUCCESS(Status))
1443 {
1444 goto Quickie;
1445 }
1446
1447#if BL_KD_SUPPORT
1448 /* Check if we should notify the debugger of load */
1449 if (BdDebugTransitions)
1450 {
1451 /* Initialize it */
1452 BdForceDebug = 1;
1453 Status = BlBdInitialize();
1454 if (NT_SUCCESS(Status))
1455 {
1456 /* Check if it's enabled */
1457 if (BlBdDebuggerEnabled())
1458 {
1459 /* Send it an image load notification */
1461 RtlInitUnicodeString(&PathString, Path);
1462 BlBdLoadImageSymbols(&PathString, ImageBase);
1463 }
1464 }
1465 }
1466#endif
1467
1468#if BL_BITLOCKER_SUPPORT
1469 /* Do bitlocker stuff */
1470 Status = BlSecureBootCheckPolicyOnFveDevice(BitLockerDevice);
1471 if (!NT_SUCCESS(Status))
1472 {
1473 goto Quickie;
1474 }
1475#endif
1476
1477#if BL_BITLOCKER_SUPPORT
1478 /* Do bitlocker stuff */
1479 Status = BlFveSecureBootCheckpointBootApp(BootEntry, BitLockerDevice, Hash, UnlockCode);
1480 if (!NT_SUCCESS(Status))
1481 {
1482 goto Quickie;
1483 }
1484#endif
1485
1486 /* Get the BCD option size */
1487 ListSize = BlGetBootOptionListSize(BootEntry->BcdData);
1488
1489 /* Allocate an entry with all the BCD options */
1490 AppEntry = BlMmAllocateHeap(ListSize + sizeof(*AppEntry));
1491 if (!AppEntry)
1492 {
1494 goto Quickie;
1495 }
1496
1497 /* Zero it out */
1498 RtlZeroMemory(AppEntry, sizeof(*AppEntry));
1499
1500 /* Initialize it */
1501 strcpy(AppEntry->Signature, "BTAPENT");
1502 AppEntry->Guid = BootEntry->Guid;
1503 AppEntry->Flags = BootEntry->Flags;
1504
1505 /* Copy the BCD options */
1506 RtlCopyMemory(&AppEntry->BcdData, BootEntry->BcdData, ListSize);
1507
1508 /* Allocate the image entry */
1509 ImageAppEntry = BlMmAllocateHeap(sizeof(*ImageAppEntry));
1510 if (!ImageAppEntry)
1511 {
1513 goto Quickie;
1514 }
1515
1516 /* Initialize it */
1517 ImageAppEntry->ImageBase = ImageBase;
1518 ImageAppEntry->ImageSize = ImageSize;
1519 ImageAppEntry->AppEntry = AppEntry;
1520
1521 /* Check if this is the first entry */
1522 if (!IapTableEntries)
1523 {
1524 /* Allocate two entries */
1526 IapTableEntries = 2;
1528 if (!IapImageTable)
1529 {
1531 goto Quickie;
1532 }
1533
1534 /* Zero out the entries for now */
1536 }
1537
1538 /* Set this entry into the table */
1541 ImageAppEntry,
1542 AppHandle,
1544
1545Quickie:
1546 /* Is the device open? Close it if so */
1547 if (DeviceId != 1)
1548 {
1549 BlDeviceClose(DeviceId);
1550 }
1551
1552 /* Is there an allocated device? Free it */
1553 if (Device)
1554 {
1556 }
1557
1558 /* Is there an allocated path? Free it */
1559 if (Path)
1560 {
1562 }
1563
1564 /* Is there a bitlocker device? Free it */
1565 if (BitLockerDevice)
1566 {
1567 BlMmFreeHeap(BitLockerDevice);
1568 }
1569
1570 /* Is there a bitlocker unlock code? Free it */
1571 if (UnlockCode)
1572 {
1573 BlMmFreeHeap(UnlockCode);
1574 }
1575
1576 /* Did we succeed in creating an entry? */
1577 if (NT_SUCCESS(Status))
1578 {
1579 /* Remember there's one more in the table */
1581
1582 /* Return success */
1583 return Status;
1584 }
1585
1586 /* Did we load an image after all? */
1587 if (ImageBase)
1588 {
1589 /* Unload it */
1590 BlImgUnLoadImage(ImageBase, ImageSize, 0);
1591 }
1592
1593 /* Did we allocate an app entry? Free it */
1594 if (AppEntry)
1595 {
1596 BlMmFreeHeap(AppEntry);
1597 }
1598
1599 /* Do we have an image file entry? Free it */
1600 if (ImageFile)
1601 {
1603 }
1604
1605 /* Do we no longer have a single entry in the table? */
1607 {
1608 /* Free and destroy the table */
1610 IapTableEntries = 0;
1612 }
1613
1614 /* Return the failure code */
1615 return Status;
1616}
unsigned char BOOLEAN
PRTL_UNICODE_STRING_BUFFER Path
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
@ BcdLibraryInteger_UndocumentedMagic
Definition: bcd.h:97
@ BcdLibraryDevice_ApplicationDevice
Definition: bcd.h:50
@ BcdLibraryIntegerList_AllowedInMemorySettings
Definition: bcd.h:103
@ BcdLibraryString_ApplicationPath
Definition: bcd.h:51
#define BL_DEVICE_READ_ACCESS
Definition: bl.h:152
@ BlLoaderMemory
Definition: bl.h:306
ULONGLONG BlTimeQueryPerformanceCounter(_Out_opt_ PLARGE_INTEGER Frequency)
Definition: time.c:101
NTSTATUS BlGetBootOptionDevice(_In_ PBL_BCD_OPTION List, _In_ ULONG Type, _Out_ PBL_DEVICE_DESCRIPTOR *Value, _In_opt_ PBL_BCD_OPTION *ExtraOptions)
Definition: bcdopt.c:321
PVOID BlMmAllocateHeap(_In_ SIZE_T Size)
Definition: heapalloc.c:569
NTSTATUS BlpDeviceOpen(_In_ PBL_DEVICE_DESCRIPTOR Device, _In_ ULONG Flags, _In_ ULONG Unknown, _Out_ PULONG DeviceId)
Definition: device.c:2111
NTSTATUS BlDeviceClose(_In_ ULONG DeviceId)
Definition: device.c:2073
NTSTATUS BlAppendBootOptionInteger(_In_ PBL_LOADED_APPLICATION_ENTRY AppEntry, _In_ ULONG OptionId, _In_ ULONGLONG Value)
Definition: bcdopt.c:657
NTSTATUS TblDoNotPurgeEntry(_In_ PVOID Entry)
Definition: util.c:495
NTSTATUS BlTblSetEntry(_Inout_ PVOID **Table, _Inout_ PULONG Count, _In_ PVOID Entry, _Out_ PULONG EntryIndex, _In_ PBL_TBL_SET_ROUTINE Callback)
Definition: util.c:321
NTSTATUS BlpGetBootOptionIntegerList(_In_ PBL_BCD_OPTION List, _In_ ULONG Type, _Out_ PULONGLONG *Value, _Out_ PULONGLONG Count, _In_ BOOLEAN NoCopy)
Definition: bcdopt.c:541
NTSTATUS BlGetBootOptionString(_In_ PBL_BCD_OPTION List, _In_ ULONG Type, _Out_ PWCHAR *Value)
Definition: bcdopt.c:146
BOOLEAN BlBdDebuggerEnabled(VOID)
Definition: debug.c:53
NTSTATUS BlMmFreeHeap(_In_ PVOID Buffer)
Definition: heapalloc.c:663
ULONG BlGetBootOptionListSize(_In_ PBL_BCD_OPTION BcdOption)
Definition: bcdopt.c:79
BOOLEAN BdDebuggerNotPresent
Definition: debug.c:16
VOID BlImgQueryCodeIntegrityBootOptions(_In_ PBL_LOADED_APPLICATION_ENTRY ApplicationEntry, _Out_ PBOOLEAN IntegrityChecksDisabled, _Out_ PBOOLEAN TestSigning)
Definition: image.c:651
ULONG IapAllocatedTableEntries
Definition: image.c:16
NTSTATUS BlImgLoadPEImageEx(_In_ ULONG DeviceId, _In_ BL_MEMORY_TYPE MemoryType, _In_ PWCHAR Path, _Out_ PVOID *ImageBase, _Out_ PULONG ImageSize, _Out_ PVOID Hash, _In_ ULONG Flags)
Definition: image.c:1276
NTSTATUS BlImgUnLoadImage(_In_ PVOID ImageBase, _In_ ULONG ImageSize, _In_ ULONG ImageFlags)
Definition: image.c:675
ULONG IapTableEntries
Definition: image.c:17
PVOID * IapImageTable
Definition: image.c:18
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static int Hash(const char *)
Definition: reader.c:2257
static PWSTR ImageFile
Definition: imagefile.c:10
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
__GNU_EXTENSION typedef unsigned __int64 * PULONGLONG
Definition: ntbasedef.h:391
Definition: bl.h:855
ULONG Flags
Definition: bl.h:857
CHAR Signature[8]
Definition: bl.h:856
GUID Guid
Definition: bl.h:858
BL_BCD_OPTION BcdData
Definition: bl.h:860
Definition: bl.h:1284
PBL_APPLICATION_ENTRY AppEntry
Definition: bl.h:1285
ULONG ImageSize
Definition: bl.h:1287
PVOID ImageBase
Definition: bl.h:1286
static LARGE_INTEGER Frequency
Definition: clock.c:41
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint16_t * PWCHAR
Definition: typedefs.h:56
_Must_inspect_result_ _In_ WDFDEVICE Device
Definition: wdfchildlist.h:474
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by BmpTransferExecution().

◆ BlImgLoadImageWithProgress2()

NTSTATUS BlImgLoadImageWithProgress2 ( _In_ ULONG  DeviceId,
_In_ BL_MEMORY_TYPE  MemoryType,
_In_ PWCHAR  FileName,
_Inout_ PVOID MappedBase,
_Inout_ PULONG  MappedSize,
_In_ ULONG  ImageFlags,
_In_ BOOLEAN  ShowProgress,
_Out_opt_ PUCHAR HashBuffer,
_Out_opt_ PULONG  HashSize 
)

Definition at line 358 of file image.c.

369{
372 ULONG RemainingLength, CurrentSize, ImageSize, ReadSize;
373 BOOLEAN ComputeSignature, ComputeHash, Completed;
377
378 /* Initialize variables */
379 BaseAddress = 0;
380 ImageSize = 0;
381 Completed = FALSE;
383
384 /* Check for missing parameters */
385 if (!MappedBase)
386 {
388 goto Quickie;
389 }
390 if (!FileName)
391 {
393 goto Quickie;
394 }
395 if (!MappedSize)
396 {
398 goto Quickie;
399 }
400
401 /* Check if the image buffer is being provided */
403 {
404 /* An existing base must already exist */
405 if (!(*MappedBase))
406 {
408 goto Quickie;
409 }
410 }
411
412 /* Check of a hash is being requested */
414 {
415 /* Make sure we can return the hash */
416 if (!HashBuffer)
417 {
419 goto Quickie;
420 }
421 if (!HashSize)
422 {
424 goto Quickie;
425 }
426 }
427
428 /* Check for invalid combination of parameters */
430 {
432 goto Quickie;
433 }
434
435 /* Initialize hash if requested by caller */
436 if (HashBuffer)
437 {
438 *HashBuffer = 0;
439 }
440
441 /* Do the same for the hash size */
442 if (HashSize)
443 {
444 *HashSize = 0;
445 }
446
447 /* Open the image file */
448 Status = ImgpOpenFile(DeviceId, FileName, DeviceId, &FileHandle);
449 if (!NT_SUCCESS(Status))
450 {
451 EfiPrintf(L"Error opening file: %lx\r\n", Status);
452 goto Quickie;
453 }
454
455 /* Get the size of the image */
456 Status = ImgpGetFileSize(&FileHandle, &ImageSize);
457 if (!NT_SUCCESS(Status))
458 {
459 EfiPrintf(L"Error getting file size: %lx\r\n", Status);
460 goto Quickie;
461 }
462
463 /* Read the current base address */
466 {
467 /* Check if the current buffer is too small */
468 if (*MappedSize < ImageSize)
469 {
470 /* Return the required size of the buffer */
471 *MappedSize = ImageSize;
473 }
474 }
475 else
476 {
477 /* A buffer was not provided, allocate one ourselves */
479 MemoryType,
480 ImageSize,
481 ImageFlags);
482 }
483
484 /* Bail out if allocation failed */
485 if (!NT_SUCCESS(Status))
486 {
487 goto Quickie;
488 }
489
490 /* Set the initial byte offset and length to read */
491 RemainingLength = ImageSize;
492 ByteOffset = 0;
494
495 /* Update the initial progress */
496 Completed = FALSE;
497 if (ShowProgress)
498 {
499 BlUtlUpdateProgress(0, &Completed);
500 ShowProgress &= (Completed != 0) - 1;
501 }
502
503 /* Set the chunk size for each read */
504 ReadSize = 0x100000;
505 if (ReadSize > ImageSize)
506 {
507 ReadSize = ImageSize;
508 }
509
510 /* Check if we should compute hash and/or signatures */
511 ComputeSignature = ImageFlags & BL_LOAD_IMG_COMPUTE_SIGNATURE;
512 ComputeHash = FALSE;
513 if ((ComputeSignature) || (ImageFlags & BL_LOAD_IMG_COMPUTE_HASH))
514 {
515 ComputeHash = TRUE;
516 // todo: crypto is hard
517 }
518
519 /* Begin the read loop */
520 while (RemainingLength)
521 {
522 /* Check if we've got more than a chunk left to read */
523 if (RemainingLength > ReadSize)
524 {
525 /* Read a chunk*/
526 CurrentSize = ReadSize;
527 }
528 else
529 {
530 /* Read only what's left */
531 CurrentSize = RemainingLength;
532 }
533
534 /* Read the chunk */
536 CurrentSize,
538 Buffer,
539 0);
540 if (!NT_SUCCESS(Status))
541 {
542 goto Quickie;
543 }
544
545 /* Check if we need to compute the hash of this chunk */
546 if (ComputeHash)
547 {
548 // todo: crypto is hard
549 }
550
551 /* Update our position and read information */
552 Buffer = (PVOID)((ULONG_PTR)Buffer + CurrentSize);
553 RemainingLength -= CurrentSize;
554 ByteOffset += CurrentSize;
555
556 /* Check if we should update the progress bar */
557 if (ShowProgress)
558 {
559 /* Compute new percentage completed, check if we're done */
560 BlUtlUpdateProgress(100 - 100 * RemainingLength / ImageSize,
561 &Completed);
562 ShowProgress &= (Completed != 0) - 1;
563 }
564 }
565
566 /* Is the read fully complete? We need to finalize the hash if requested */
567 if (ComputeHash)
568 {
569 // todo: CRYPTO IS HARD
570 }
571
572 /* Success path, return back the buffer and the size of the image */
574 *MappedSize = ImageSize;
575
576Quickie:
577 /* Close the file handle */
579
580 /* Check if we failed and had allocated a buffer */
581 if (!(NT_SUCCESS(Status)) &&
582 (BaseAddress) &&
584 {
585 /* Check what kind of buffer we had allocated */
587 {
588 /* Unmap and free the virtual buffer */
592 }
593 else
594 {
595 /* Free the physical buffer */
597 }
598 }
599
600 /* If we hadn't gotten to 100% yet, do it now */
601 if (ShowProgress)
602 {
603 BlUtlUpdateProgress(100, &Completed);
604 }
605
606 /* Return the final status */
607 return Status;
608}
VOID EfiPrintf(_In_ PWCHAR Format,...)
Definition: firmware.c:126
#define BL_MM_INCLUDE_MAPPED_ALLOCATED
Definition: bl.h:96
NTSTATUS BlMmUnmapVirtualAddressEx(_In_ PVOID VirtualAddress, _In_ ULONGLONG Size)
Definition: mm.c:487
NTSTATUS MmPapFreePages(_In_ PVOID Address, _In_ ULONG WhichList)
Definition: pagealloc.c:1196
#define BL_LOAD_IMG_COMPUTE_SIGNATURE
Definition: bl.h:174
#define BL_LOAD_IMG_EXISTING_BUFFER
Definition: bl.h:172
#define BL_LOAD_IMG_COMPUTE_HASH
Definition: bl.h:175
VOID BlUtlUpdateProgress(_In_ ULONG Percentage, _Out_opt_ PBOOLEAN Completed)
Definition: util.c:181
NTSTATUS BlImgAllocateImageBuffer(_Inout_ PVOID *ImageBuffer, _In_ ULONG MemoryType, _In_ ULONGLONG ImageSize, _In_ ULONG Flags)
Definition: image.c:248
NTSTATUS ImgpReadAtFileOffset(_In_ PBL_IMG_FILE File, _In_ ULONG Size, _In_ ULONGLONG ByteOffset, _In_ PVOID Buffer, _Out_ PULONG BytesReturned)
Definition: image.c:72
NTSTATUS ImgpCloseFile(_In_ PBL_IMG_FILE File)
Definition: image.c:178
NTSTATUS ImgpOpenFile(_In_ ULONG DeviceId, _In_ PWCHAR FileName, _In_ ULONG Flags, _Out_ PBL_IMG_FILE NewFile)
Definition: image.c:124
NTSTATUS ImgpGetFileSize(_In_ PBL_IMG_FILE File, _Out_ PULONG FileSize)
Definition: image.c:33
Definition: bufpool.h:45
IN PDCB IN PCCB IN VBO IN OUT PULONG OUT PDIRENT OUT PBCB OUT PVBO ByteOffset
Definition: fatprocs.h:732
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE FileHandle
Definition: fltkernel.h:1231
ImageFlags
Definition: gdiplusenums.h:332
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
#define L(x)
Definition: ntvdm.h:50
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
void * PVOID
Definition: typedefs.h:50
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135

Referenced by BiLoadHive().

◆ BlImgLoadPEImageEx()

NTSTATUS BlImgLoadPEImageEx ( _In_ ULONG  DeviceId,
_In_ BL_MEMORY_TYPE  MemoryType,
_In_ PWCHAR  Path,
_Out_ PVOID ImageBase,
_Out_ PULONG  ImageSize,
_Out_ PVOID  Hash,
_In_ ULONG  Flags 
)

Definition at line 1276 of file image.c.

1285{
1288
1289 /* Initialize the image file structure */
1290 ImageFile.Flags = 0;
1291 ImageFile.FileName = NULL;
1292
1293 /* Check if the required parameter are missing */
1294 if (!(ImageBase) || !(Path))
1295 {
1297 }
1298
1299 /* If we are loading a pre-allocated image, make sure we have it */
1300 if ((Flags & BL_LOAD_IMG_EXISTING_BUFFER) && (!(*ImageBase) || !(ImageSize)))
1301 {
1303 }
1304
1305 /* Load the file from disk */
1306 Status = ImgpOpenFile(DeviceId, Path, 0, &ImageFile);
1307 if (NT_SUCCESS(Status))
1308 {
1309 /* If that worked, do the PE parsing */
1311 MemoryType,
1312 ImageBase,
1313 ImageSize,
1314 Hash,
1315 Flags);
1316 }
1317
1318 /* Close the image file and return back to caller */
1320 return Status;
1321}
NTSTATUS ImgpLoadPEImage(_In_ PBL_IMG_FILE ImageFile, _In_ BL_MEMORY_TYPE MemoryType, _Inout_ PVOID *ImageBase, _Out_opt_ PULONG ImageSize, _Inout_opt_ PVOID Hash, _In_ ULONG Flags)
Definition: image.c:693

Referenced by BlImgLoadBootApplication().

◆ BlImgQueryCodeIntegrityBootOptions()

VOID BlImgQueryCodeIntegrityBootOptions ( _In_ PBL_LOADED_APPLICATION_ENTRY  ApplicationEntry,
_Out_ PBOOLEAN  IntegrityChecksDisabled,
_Out_ PBOOLEAN  TestSigning 
)

Definition at line 651 of file image.c.

656{
657
660
661 /* Check if /DISABLEINTEGRITYCHECKS is on */
662 Status = BlGetBootOptionBoolean(ApplicationEntry->BcdData,
664 &Value);
665 *IntegrityChecksDisabled = NT_SUCCESS(Status) && (Value);
666
667 /* Check if /TESTSIGNING is on */
668 Status = BlGetBootOptionBoolean(ApplicationEntry->BcdData,
670 &Value);
671 *TestSigning = NT_SUCCESS(Status) && (Value);
672}
@ BcdLibraryBoolean_DisableIntegrityChecks
Definition: bcd.h:88
@ BcdLibraryBoolean_AllowPrereleaseSignatures
Definition: bcd.h:89
NTSTATUS BlGetBootOptionBoolean(_In_ PBL_BCD_OPTION List, _In_ ULONG Type, _Out_ PBOOLEAN Value)
Definition: bcdopt.c:504
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413

Referenced by BlImgLoadBootApplication(), and BmMain().

◆ BlImgStartBootApplication()

NTSTATUS BlImgStartBootApplication ( _In_ ULONG  AppHandle,
_Inout_opt_ PBL_RETURN_ARGUMENTS  ReturnArguments 
)

Definition at line 1931 of file image.c.

1935{
1936 PBL_IMAGE_APPLICATION_ENTRY ImageAppEntry;
1937 BL_RETURN_ARGUMENTS LocalReturnArgs;
1939 PLIST_ENTRY NextEntry, ListHead;
1941
1942 /* Check if we don't have an argument structure */
1943 if (!ReturnArguments)
1944 {
1945 /* Initialize a local copy and use it instead */
1946 LocalReturnArgs.Version = BL_RETURN_ARGUMENTS_VERSION;
1947 LocalReturnArgs.Status = STATUS_SUCCESS;
1948 LocalReturnArgs.Flags = 0;
1949 LocalReturnArgs.DataPage = 0;
1950 LocalReturnArgs.DataSize = 0;
1951 ReturnArguments = &LocalReturnArgs;
1952 }
1953
1954 /* Make sure the handle index is valid */
1955 if (IapTableEntries <= AppHandle)
1956 {
1958 }
1959
1960 /* Get the entry for this handle, making sure it exists */
1961 ImageAppEntry = IapImageTable[AppHandle];
1962 if (!ImageAppEntry)
1963 {
1965 }
1966
1967 /* Loop the registered file systems */
1968 ListHead = &RegisteredFileSystems;
1969 NextEntry = RegisteredFileSystems.Flink;
1970 while (NextEntry != ListHead)
1971 {
1972 /* Get the filesystem entry */
1973 FileSystem = CONTAINING_RECORD(NextEntry,
1975 ListEntry);
1976
1977 /* See if it has a purge callback */
1978 if (FileSystem->PurgeCallback)
1979 {
1980 /* Call it */
1981 FileSystem->PurgeCallback();
1982 }
1983
1984 /* Move to the next entry */
1985 NextEntry = NextEntry->Flink;
1986 }
1987
1988 /* TODO -- flush the block I/O cache too */
1989 //BlockIoPurgeCache();
1990
1991 /* Call into EFI land to start the boot application */
1993 ImageAppEntry->ImageBase,
1994 ImageAppEntry->ImageSize,
1995 ReturnArguments);
1996
1997 /* Parse any arguments we got on the way back */
1998 BlpPdParseReturnArguments(ReturnArguments);
1999
2000#if BL_BITLOCKER_SUPPORT
2001 /* Bitlocker stuff */
2002 FvebpCheckAllPartitions(TRUE);
2003#endif
2004
2005#if BL_TPM_SUPPORT
2006 /* Notify a TPM/SI event */
2007 BlEnNotifyEvent(0x10000005, NULL);
2008#endif
2009
2010 /* Reset the display */
2012
2013 /* TODO -- reset ETW */
2014 //BlpLogInitialize();
2015
2016 /* All done */
2017 return Status;
2018}
PWCHAR FileSystem
Definition: format.c:72
NTSTATUS BlpDisplayReinitialize(VOID)
Definition: display.c:542
#define BL_RETURN_ARGUMENTS_VERSION
Definition: bl.h:63
NTSTATUS BlpPdParseReturnArguments(_In_ PBL_RETURN_ARGUMENTS ReturnArguments)
Definition: image.c:1619
NTSTATUS ImgArchEfiStartBootApplication(_In_ PBL_APPLICATION_ENTRY AppEntry, _In_ PVOID ImageBase, _In_ ULONG ImageSize, _In_ PBL_RETURN_ARGUMENTS ReturnArguments)
Definition: image.c:1830
static FILE_SYSTEM RegisteredFileSystems[]
Definition: fsutil.c:159
Definition: bl.h:1052
ULONG Version
Definition: bl.h:816
ULONGLONG DataPage
Definition: bl.h:820
NTSTATUS Status
Definition: bl.h:817
ULONGLONG DataSize
Definition: bl.h:819
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260

◆ BlImgUnallocateImageBuffer()

NTSTATUS BlImgUnallocateImageBuffer ( _In_ PVOID  ImageBase,
_In_ ULONG  ImageSize,
_In_ ULONG  ImageFlags 
)

Definition at line 208 of file image.c.

213{
216
217 /* Make sure required parameters are present */
218 if (!(ImageBase) || !(ImageSize))
219 {
221 }
222
223 /* Check if this was a physical allocation */
225 {
227 }
228
229 /* It's virtual, so translate it first */
231 {
233 }
234
235 /* Unmap the virtual mapping */
236 Status = BlMmUnmapVirtualAddressEx(ImageBase, ROUND_TO_PAGES(ImageSize));
237 if (NT_SUCCESS(Status))
238 {
239 /* Now free the physical pages */
241 }
242
243 /* All done */
244 return Status;
245}
BOOLEAN BlMmTranslateVirtualAddress(_In_ PVOID VirtualAddress, _Out_ PPHYSICAL_ADDRESS PhysicalAddress)
Definition: mm.c:525

Referenced by BlImgUnLoadImage(), and ImgpLoadPEImage().

◆ BlImgUnloadBootApplication()

NTSTATUS BlImgUnloadBootApplication ( _In_ ULONG  AppHandle)

Definition at line 2021 of file image.c.

2024{
2025 PBL_IMAGE_APPLICATION_ENTRY ImageAppEntry;
2027
2028 /* Make sure the handle index is valid */
2029 if (IapTableEntries <= AppHandle)
2030 {
2032 }
2033
2034 /* Get the entry for this handle, making sure it exists */
2035 ImageAppEntry = IapImageTable[AppHandle];
2036 if (!ImageAppEntry)
2037 {
2039 }
2040
2041 /* Unload the image */
2042 Status = BlImgUnLoadImage(ImageAppEntry->ImageBase,
2043 ImageAppEntry->ImageSize,
2044 0);
2045 if (NT_SUCCESS(Status))
2046 {
2047 /* Normalize the success code */
2049 }
2050 else
2051 {
2052 /* Normalize the failure code */
2054 }
2055
2056 /* Free the entry and the image entry as well */
2057 BlMmFreeHeap(ImageAppEntry->AppEntry);
2058 BlMmFreeHeap(ImageAppEntry);
2059
2060 /* Clear the handle */
2061 IapImageTable[AppHandle] = NULL;
2062
2063 /* Free one entry */
2064 if (!(--IapAllocatedTableEntries))
2065 {
2066 /* There are no more, so get rid of the table itself */
2069 IapTableEntries = 0;
2070 }
2071
2072 /* All good */
2073 return Status;
2074}
#define STATUS_MEMORY_NOT_ALLOCATED
Definition: ntstatus.h:396

Referenced by BmpTransferExecution().

◆ BlImgUnLoadImage()

NTSTATUS BlImgUnLoadImage ( _In_ PVOID  ImageBase,
_In_ ULONG  ImageSize,
_In_ ULONG  ImageFlags 
)

Definition at line 675 of file image.c.

680{
681 /* Check for missing parameters */
682 if (!(ImageSize) || !(ImageBase))
683 {
684 /* Bail out */
686 }
687
688 /* Unallocate the image buffer */
689 return BlImgUnallocateImageBuffer(ImageBase, ImageSize, ImageFlags);
690}
NTSTATUS BlImgUnallocateImageBuffer(_In_ PVOID ImageBase, _In_ ULONG ImageSize, _In_ ULONG ImageFlags)
Definition: image.c:208

Referenced by BlImgLoadBootApplication(), and BlImgUnloadBootApplication().

◆ BlpPdParseReturnArguments()

NTSTATUS BlpPdParseReturnArguments ( _In_ PBL_RETURN_ARGUMENTS  ReturnArguments)

Definition at line 1619 of file image.c.

1622{
1623 /* Check if any custom data was returned */
1624 if (ReturnArguments->DataPage == 0)
1625 {
1626 /* Nope, nothing to do */
1627 return STATUS_SUCCESS;
1628 }
1629
1630 /* Yes, we have to parse it */
1631 EfiPrintf(L"Return arguments not supported\r\n");
1633}
#define STATUS_NOT_IMPLEMENTED
Definition: d3dkmdt.h:42

Referenced by BlImgStartBootApplication().

◆ ImgArchEfiStartBootApplication()

NTSTATUS ImgArchEfiStartBootApplication ( _In_ PBL_APPLICATION_ENTRY  AppEntry,
_In_ PVOID  ImageBase,
_In_ ULONG  ImageSize,
_In_ PBL_RETURN_ARGUMENTS  ReturnArguments 
)

Definition at line 1830 of file image.c.

1836{
1837#ifndef _M_ARM
1838 KDESCRIPTOR Gdt, Idt;
1839 ULONG BootSizeNeeded;
1841 PVOID BootData;
1842 PIMAGE_NT_HEADERS NtHeaders;
1843 PVOID NewStack, NewGdt, NewIdt;
1845
1846 /* Read the current IDT and GDT */
1847 _sgdt(&Gdt.Limit);
1848 __sidt(&Idt.Limit);
1849
1850 /* Allocate space for the IDT, GDT, and 24 pages of stack */
1851 BootSizeNeeded = (ULONG_PTR)PAGE_ALIGN(Idt.Limit + Gdt.Limit + 1 + 25 * PAGE_SIZE);
1854 BootSizeNeeded >> PAGE_SHIFT,
1855 0,
1856 0,
1857 NULL,
1858 0);
1859 if (!NT_SUCCESS(Status))
1860 {
1861 goto Quickie;
1862 }
1863
1864 /* Zero the boot data */
1865 RtlZeroMemory(BootData, BootSizeNeeded);
1866
1867 /* Set the new stack, GDT and IDT */
1868 NewStack = (PVOID)((ULONG_PTR)BootData + (24 * PAGE_SIZE) - 8);
1869 NewGdt = (PVOID)((ULONG_PTR)BootData + (24 * PAGE_SIZE));
1870 NewIdt = (PVOID)((ULONG_PTR)BootData + (24 * PAGE_SIZE) + Gdt.Limit + 1);
1871
1872 /* Copy the current (firmware) GDT and IDT */
1873 RtlCopyMemory(NewGdt, (PVOID)Gdt.Base, Gdt.Limit + 1);
1874 RtlCopyMemory(NewIdt, (PVOID)Idt.Base, Idt.Limit + 1);
1875
1876 /* Read the NT headers so that we can get the entrypoint later on */
1877 RtlImageNtHeaderEx(0, ImageBase, ImageSize, &NtHeaders);
1878
1879 /* Prepare the application parameters */
1882 AppEntry,
1883 ImageBase,
1884 ImageSize);
1885 if (NT_SUCCESS(Status))
1886 {
1887 /* Set the firmware GDT/IDT as the one the application will use */
1888 BootAppGdtRegister = Gdt;
1889 BootAppIdtRegister = Idt;
1890
1891 /* Set the entrypoint, parameters, and stack */
1892 BootApp32EntryRoutine = (PVOID)((ULONG_PTR)ImageBase +
1893 NtHeaders->OptionalHeader.
1894 AddressOfEntryPoint);
1896 BootApp32Stack = NewStack;
1897
1898#if BL_KD_SUPPORT
1899 /* Disable the kernel debugger */
1900 BlBdStop();
1901#endif
1902 /* Make it so */
1904
1905 /* Not yet implemented. This is the last step! */
1906 EfiPrintf(L"EFI APPLICATION RETURNED!!!\r\n");
1907 EfiStall(100000000);
1908
1909#if BL_KD_SUPPORT
1910 /* Re-enable the kernel debugger */
1911 BlBdStart();
1912#endif
1913 }
1914
1915Quickie:
1916 /* Check if we had boot data allocated */
1917 if (BootData)
1918 {
1919 /* Free it */
1921 }
1922#else
1923 EfiPrintf(L"ImgArchEfiStartBootApplication not implemented for this platform.\r\n");
1924#endif
1925
1926 /* All done */
1928}
@ BlLoaderArchData
Definition: bl.h:312
NTSTATUS EfiStall(_In_ ULONG StallTime)
Definition: firmware.c:1003
VOID Archx86TransferTo32BitApplicationAsm(VOID)
Definition: arch.c:51
NTSTATUS ImgpInitializeBootApplicationParameters(_In_ PBL_BUFFER_DESCRIPTOR ImageParameters, _In_ PBL_APPLICATION_ENTRY AppEntry, _In_ PVOID ImageBase, _In_ ULONG ImageSize)
Definition: image.c:1656
PBOOT_APPLICATION_PARAMETER_BLOCK BootApp32Parameters
Definition: image.c:26
KDESCRIPTOR BootAppGdtRegister
Definition: image.c:23
PVOID BootApp32Stack
Definition: image.c:27
KDESCRIPTOR BootAppIdtRegister
Definition: image.c:24
PVOID BootApp32EntryRoutine
Definition: image.c:25
#define PAGE_SIZE
Definition: env_spec_w32.h:49
__INTRIN_INLINE void _sgdt(void *Destination)
Definition: intrin_x86.h:2028
__INTRIN_INLINE void __sidt(void *Destination)
Definition: intrin_x86.h:2023
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
PVOID Base
Definition: ketypes.h:560
USHORT Limit
Definition: ketypes.h:559
_Must_inspect_result_ _In_ WDFQUEUE _In_opt_ WDFREQUEST _In_opt_ WDFFILEOBJECT _Inout_opt_ PWDF_REQUEST_PARAMETERS Parameters
Definition: wdfio.h:869
#define PAGE_ALIGN(Va)

Referenced by BlImgStartBootApplication().

◆ ImgpCloseFile()

NTSTATUS ImgpCloseFile ( _In_ PBL_IMG_FILE  File)

Definition at line 178 of file image.c.

181{
183
184 /* Make sure this is a valid file, otherwise no-op */
186 if (File->Flags & BL_IMG_VALID_FILE)
187 {
188 /* Is this a memory mapped file? */
189 if (!(File->Flags & BL_IMG_MEMORY_FILE))
190 {
191 /* Nope, close the file handle */
192 return BlFileClose(File->FileId);
193 }
194
195 /* Is this a remote file? */
196 if (File->Flags & BL_IMG_REMOTE_FILE)
197 {
198 /* Then only free the memory in that scenario */
200 }
201 }
202
203 /* Return the final status */
204 return Status;
205}
#define BL_IMG_VALID_FILE
Definition: bl.h:167
#define BL_IMG_REMOTE_FILE
Definition: bl.h:169
NTSTATUS BlFileClose(_In_ ULONG FileId)
Definition: file.c:220
#define BL_IMG_MEMORY_FILE
Definition: bl.h:168
Definition: File.h:16

Referenced by BlImgLoadImageWithProgress2(), BlImgLoadPEImageEx(), and ImgpLoadPEImage().

◆ ImgpCopyApplicationBootDevice()

NTSTATUS ImgpCopyApplicationBootDevice ( __in PBL_DEVICE_DESCRIPTOR  DestinationDevice,
__in PBL_DEVICE_DESCRIPTOR  SourceDevice 
)

Definition at line 1636 of file image.c.

1640{
1641 /* Is this a partition device? */
1642 if (SourceDevice->DeviceType != PartitionDevice)
1643 {
1644 /* It's not -- a simple copy will do */
1645 RtlCopyMemory(DestinationDevice, SourceDevice, SourceDevice->Size);
1646 return STATUS_SUCCESS;
1647 }
1648
1649 /* TODO */
1650 EfiPrintf(L"Partition copy not supported\r\n");
1652
1653}
@ PartitionDevice
Definition: bl.h:252
_Must_inspect_result_ __drv_aliasesMem PDEVICE_OBJECT SourceDevice
Definition: iofuncs.h:690

Referenced by ImgpInitializeBootApplicationParameters().

◆ ImgpGetFileSize()

NTSTATUS ImgpGetFileSize ( _In_ PBL_IMG_FILE  File,
_Out_ PULONG  FileSize 
)

Definition at line 33 of file image.c.

37{
39 ULONG Size;
41
42 /* Check if the file was memory mapped */
43 if (File->Flags & BL_IMG_MEMORY_FILE)
44 {
45 /* Just read the size of the mapping */
46 Size = File->FileSize;
47 }
48 else
49 {
50 /* Do file I/O to get the file size */
53 if (!NT_SUCCESS(Status))
54 {
55 return Status;
56 }
57
58 /* We only support files less than 4GB in the Image Mapped */
59 Size = FileInformation.Size;
60 if (FileInformation.Size > ULONG_MAX)
61 {
63 }
64 }
65
66 /* Return the size and success */
67 *FileSize = Size;
68 return STATUS_SUCCESS;
69}
NTSTATUS BlFileGetInformation(_In_ ULONG FileId, _In_ PBL_FILE_INFORMATION FileInfo)
Definition: file.c:564
#define STATUS_NOT_SUPPORTED
Definition: d3dkmdt.h:48
_Must_inspect_result_ _Out_ PLARGE_INTEGER FileSize
Definition: fsrtlfuncs.h:108
#define ULONG_MAX
Definition: intsafe.h:155
static OUT PIO_STATUS_BLOCK OUT PVOID FileInformation
Definition: pipe.c:75

Referenced by BlImgLoadImageWithProgress2(), and ImgpLoadPEImage().

◆ ImgpInitializeBootApplicationParameters()

NTSTATUS ImgpInitializeBootApplicationParameters ( _In_ PBL_BUFFER_DESCRIPTOR  ImageParameters,
_In_ PBL_APPLICATION_ENTRY  AppEntry,
_In_ PVOID  ImageBase,
_In_ ULONG  ImageSize 
)

Definition at line 1656 of file image.c.

1662{
1664 PIMAGE_NT_HEADERS NtHeaders;
1665 BL_BUFFER_DESCRIPTOR MemoryParameters;
1666 LIST_ENTRY MemoryList;
1667 PBL_FIRMWARE_DESCRIPTOR FirmwareParameters;
1669 PBL_MEMORY_DATA MemoryData;
1670 PBL_APPLICATION_ENTRY BootAppEntry;
1671 PBL_RETURN_ARGUMENTS ReturnArguments;
1672 PBOOT_APPLICATION_PARAMETER_BLOCK ParameterBlock;
1674
1675 /* Get the image headers and validate it */
1676 Status = RtlImageNtHeaderEx(0, ImageBase, ImageSize, &NtHeaders);
1677 if (!NT_SUCCESS(Status))
1678 {
1679 return Status;
1680 }
1681
1682 /* Get the size of the entire non-firmware, allocated, memory map */
1683 MemoryParameters.BufferSize = 0;
1684 Status = BlMmGetMemoryMap(&MemoryList,
1685 &MemoryParameters,
1691 0);
1693 {
1694 /* We failed due to an unknown reason -- bail out */
1695 return Status;
1696 }
1697
1698 /* Compute the list of the BCD plus the application entry */
1699 EntrySize = BlGetBootOptionListSize(&AppEntry->BcdData) +
1701
1702 /* Compute the total size required for the entire structure */
1705 MemoryParameters.BufferSize +
1706 sizeof(*ReturnArguments) +
1707 sizeof(*MemoryData) +
1708 sizeof(*FirmwareParameters) +
1709 sizeof(*ParameterBlock);
1710
1711 /* Check if this gives us enough space */
1712 if (ImageParameters->BufferSize < BufferSize)
1713 {
1714 /* It does not -- free the existing buffer */
1715 if (ImageParameters->BufferSize)
1716 {
1717 BlMmFreeHeap(ImageParameters->Buffer);
1718 }
1719
1720 /* Allocate a new buffer of sufficient size */
1721 ImageParameters->BufferSize = BufferSize;
1722 ImageParameters->Buffer = BlMmAllocateHeap(BufferSize);
1723 if (!ImageParameters->Buffer)
1724 {
1725 /* Bail out if we couldn't allocate it */
1726 return STATUS_NO_MEMORY;
1727 }
1728 }
1729
1730 /* Zero out the parameter block */
1731 ParameterBlock = (PBOOT_APPLICATION_PARAMETER_BLOCK)ImageParameters->Buffer;
1732 RtlZeroMemory(ParameterBlock, BufferSize);
1733
1734 /* Initialize it */
1735 ParameterBlock->Version = BOOT_APPLICATION_VERSION;
1736 ParameterBlock->Size = BufferSize;
1737 ParameterBlock->Signature[0] = BOOT_APPLICATION_SIGNATURE_1;
1738 ParameterBlock->Signature[1] = BOOT_APPLICATION_SIGNATURE_2;
1739 ParameterBlock->MemoryTranslationType = MmTranslationType;
1740 ParameterBlock->ImageType = IMAGE_FILE_MACHINE_I386;
1741 ParameterBlock->ImageBase = (ULONG_PTR)ImageBase;
1742 ParameterBlock->ImageSize = NtHeaders->OptionalHeader.SizeOfImage;
1743
1744 /* Get the offset to the memory data */
1745 ParameterBlock->MemoryDataOffset = sizeof(*ParameterBlock);
1746
1747 /* Fill it out */
1748 MemoryData = (PBL_MEMORY_DATA)((ULONG_PTR)ParameterBlock +
1749 ParameterBlock->MemoryDataOffset);
1750 MemoryData->Version = BL_MEMORY_DATA_VERSION;
1751 MemoryData->MdListOffset = sizeof(*MemoryData);
1752 MemoryData->DescriptorSize = sizeof(BL_MEMORY_DESCRIPTOR);
1753 MemoryData->DescriptorOffset = FIELD_OFFSET(BL_MEMORY_DESCRIPTOR, BasePage);
1754
1755 /* And populate the memory map */
1756 MemoryParameters.Buffer = MemoryData + 1;
1757 Status = BlMmGetMemoryMap(&MemoryList,
1758 &MemoryParameters,
1764 0);
1765 if (!NT_SUCCESS(Status))
1766 {
1767 return Status;
1768 }
1769
1770 /* Now that we have the map, indicate the number of descriptors */
1771 MemoryData->DescriptorCount = MemoryParameters.ActualSize /
1772 MemoryData->DescriptorSize;
1773
1774 /* Get the offset to the application entry */
1775 ParameterBlock->AppEntryOffset = ParameterBlock->MemoryDataOffset +
1776 MemoryData->MdListOffset +
1777 MemoryParameters.BufferSize;
1778
1779 /* Fill it out */
1780 BootAppEntry = (PBL_APPLICATION_ENTRY)((ULONG_PTR)ParameterBlock +
1781 ParameterBlock->AppEntryOffset);
1782 RtlCopyMemory(BootAppEntry, AppEntry, EntrySize);
1783
1784 /* Get the offset to the boot device */
1785 ParameterBlock->BootDeviceOffset = ParameterBlock->AppEntryOffset +
1786 EntrySize;
1787
1788 /* Fill it out */
1789 BootDevice = (PBL_DEVICE_DESCRIPTOR)((ULONG_PTR)ParameterBlock +
1790 ParameterBlock->BootDeviceOffset);
1792 if (!NT_SUCCESS(Status))
1793 {
1794 return Status;
1795 }
1796
1797 /* Get the offset to the firmware data */
1798 ParameterBlock->FirmwareParametersOffset = ParameterBlock->BootDeviceOffset +
1799 BootDevice->Size;
1800
1801 /* Fill it out */
1802 FirmwareParameters = (PBL_FIRMWARE_DESCRIPTOR)((ULONG_PTR)ParameterBlock +
1803 ParameterBlock->
1804 FirmwareParametersOffset);
1805 Status = BlFwGetParameters(FirmwareParameters);
1806 if (!NT_SUCCESS(Status))
1807 {
1808 return Status;
1809 }
1810
1811 /* Get the offset to the return arguments */
1812 ParameterBlock->ReturnArgumentsOffset = ParameterBlock->FirmwareParametersOffset +
1813 sizeof(BL_FIRMWARE_DESCRIPTOR);
1814
1815 /* Fill them out */
1816 ReturnArguments = (PBL_RETURN_ARGUMENTS)((ULONG_PTR)ParameterBlock +
1817 ParameterBlock->
1818 ReturnArgumentsOffset);
1819 ReturnArguments->Version = BL_RETURN_ARGUMENTS_VERSION;
1820 ReturnArguments->DataPage = 0;
1821 ReturnArguments->DataSize = 0;
1822
1823 /* Structure complete */
1824 ImageParameters->ActualSize = ParameterBlock->ReturnArgumentsOffset +
1825 sizeof(*ReturnArguments);
1826 return STATUS_SUCCESS;
1827}
struct _BL_MEMORY_DESCRIPTOR BL_MEMORY_DESCRIPTOR
struct _BL_FIRMWARE_DESCRIPTOR BL_FIRMWARE_DESCRIPTOR
NTSTATUS BlMmGetMemoryMap(_In_ PLIST_ENTRY MemoryMap, _In_ PBL_BUFFER_DESCRIPTOR MemoryParameters, _In_ ULONG WhichTypes, _In_ ULONG Flags)
Definition: pagealloc.c:1222
struct _BL_FIRMWARE_DESCRIPTOR * PBL_FIRMWARE_DESCRIPTOR
struct _BL_DEVICE_DESCRIPTOR * PBL_DEVICE_DESCRIPTOR
struct _BOOT_APPLICATION_PARAMETER_BLOCK * PBOOT_APPLICATION_PARAMETER_BLOCK
#define BOOT_APPLICATION_SIGNATURE_2
Definition: bl.h:56
BL_TRANSLATION_TYPE MmTranslationType
Definition: mm.c:17
#define BL_MEMORY_DATA_VERSION
Definition: bl.h:62
struct _BL_RETURN_ARGUMENTS * PBL_RETURN_ARGUMENTS
struct _BL_APPLICATION_ENTRY * PBL_APPLICATION_ENTRY
struct _BL_MEMORY_DATA * PBL_MEMORY_DATA
PBL_DEVICE_DESCRIPTOR BlpBootDevice
Definition: bootlib.c:16
#define BL_MM_INCLUDE_MAPPED_UNALLOCATED
Definition: bl.h:97
@ BootDevice
Definition: bl.h:251
#define BOOT_APPLICATION_VERSION
Definition: bl.h:61
#define BL_MM_INCLUDE_PERSISTENT_MEMORY
Definition: bl.h:104
#define BOOT_APPLICATION_SIGNATURE_1
Definition: bl.h:55
NTSTATUS BlFwGetParameters(_In_ PBL_FIRMWARE_DESCRIPTOR Parameters)
Definition: firmware.c:2359
#define BL_MM_INCLUDE_UNMAPPED_ALLOCATED
Definition: bl.h:98
#define BL_MM_INCLUDE_RESERVED_ALLOCATED
Definition: bl.h:100
NTSTATUS ImgpCopyApplicationBootDevice(__in PBL_DEVICE_DESCRIPTOR DestinationDevice, __in PBL_DEVICE_DESCRIPTOR SourceDevice)
Definition: image.c:1636
#define BufferSize
Definition: mmc.h:75
#define IMAGE_FILE_MACHINE_I386
Definition: pedump.c:174
ULONG ActualSize
Definition: bl.h:1293
ULONG BufferSize
Definition: bl.h:1294
ULONG DescriptorCount
Definition: bl.h:801
ULONG Version
Definition: bl.h:799
ULONG DescriptorSize
Definition: bl.h:802
ULONG MdListOffset
Definition: bl.h:800
ULONG DescriptorOffset
Definition: bl.h:803
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
Definition: wdfmemory.h:254
_In_ UCHAR EntrySize
Definition: iofuncs.h:642

Referenced by ImgArchEfiStartBootApplication().

◆ ImgpLoadPEImage()

NTSTATUS ImgpLoadPEImage ( _In_ PBL_IMG_FILE  ImageFile,
_In_ BL_MEMORY_TYPE  MemoryType,
_Inout_ PVOID ImageBase,
_Out_opt_ PULONG  ImageSize,
_Inout_opt_ PVOID  Hash,
_In_ ULONG  Flags 
)

Definition at line 693 of file image.c.

701{
703 ULONG FileSize, HeaderSize;
704 BL_IMG_FILE LocalFileBuffer;
705 PBL_IMG_FILE LocalFile;
706 PVOID VirtualAddress, PreferredBase, ImageBuffer, CertBuffer, HashBuffer;
707 ULONGLONG VirtualSize;
708 PIMAGE_DATA_DIRECTORY CertDirectory;
710 PIMAGE_NT_HEADERS NtHeaders;
711 USHORT SectionCount, CheckSum, PartialSum, FinalSum;
712 PIMAGE_SECTION_HEADER Section;
713 ULONG_PTR EndOfHeaders, SectionStart, Slack, SectionEnd;
714 ULONG i, SectionSize, RawSize, BytesRead, RemainingLength, Offset, AlignSize;
715 BOOLEAN First, ImageHashValid;
716 UCHAR LocalBuffer[1024];
717 UCHAR TrustedBootInformation[52];
718 ULONG WorkaroundForBinutils;
719
720 /* Initialize locals */
721 WorkaroundForBinutils = 0;
722 LocalFile = NULL;
723 ImageBuffer = NULL;
724 FileSize = 0;
725 First = FALSE;
727 CertBuffer = NULL;
728 CertDirectory = NULL;
729 HashBuffer = NULL;
730 Offset = 0;
731 VirtualSize = 0;
732 ImageHashValid = FALSE;
733 RtlZeroMemory(&TrustedBootInformation, sizeof(TrustedBootInformation));
734
735 /* Get the size of the image */
737 if (!NT_SUCCESS(Status))
738 {
739 return STATUS_FILE_INVALID;
740 }
741
742 /* Allocate a flat buffer for it */
744 if (!NT_SUCCESS(Status))
745 {
746 goto Quickie;
747 }
748
749 /* Read the whole file flat for now */
751 if (!NT_SUCCESS(Status))
752 {
753 goto Quickie;
754 }
755
756 /* Build a local file handle */
757 LocalFile = &LocalFileBuffer;
758 LocalFileBuffer.FileName = ImageFile->FileName;
759 LocalFileBuffer.Flags = BL_IMG_MEMORY_FILE | BL_IMG_VALID_FILE;
760 LocalFileBuffer.BaseAddress = ImageBuffer;
761 LocalFileBuffer.FileSize = FileSize;
762
763 /* Get the NT headers of the file */
764 Status = RtlImageNtHeaderEx(0, ImageBuffer, FileSize, &NtHeaders);
765 if (!NT_SUCCESS(Status))
766 {
767 goto Quickie;
768 }
769
770 /* Check if we should validate the machine type */
772 {
773 /* Is it different than our current machine type? */
774#if _M_AMD64
776#else
778#endif
779 {
780 /* Is it x86 (implying we are x64) ? */
782 {
783 /* Return special error code */
785 }
786 else if (NtHeaders->FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64)
787 {
788 /* Otherwise, it's x64 but we are x86 */
790 }
791 else
792 {
793 /* Or it's ARM or something... */
795 }
796
797 /* Return with the distinguished error code */
798 goto Quickie;
799 }
800 }
801
802 /* Check if we should validate the subsystem */
804 {
805 /* It must be a Windows boot Application */
806 if (NtHeaders->OptionalHeader.Subsystem !=
808 {
810 goto Quickie;
811 }
812 }
813
814 /* Check if we should validate the /INTEGRITYCHECK flag */
816 {
817 /* Check if it's there */
818 if (!(NtHeaders->OptionalHeader.DllCharacteristics &
820 {
821 /* Nope, fail otherwise */
823 goto Quickie;
824 }
825 }
826
827 /* Check if we should compute the image hash */
829 {
830 EfiPrintf(L"No hash support\r\n");
831 }
832
833 /* Read the current base address, if any */
834 VirtualAddress = *ImageBase;
835
836 /* Get the virtual size of the image */
837 VirtualSize = NtHeaders->OptionalHeader.SizeOfImage;
838
839 /* Safely align the virtual size to a page */
840 Status = RtlULongLongAdd(VirtualSize,
841 PAGE_SIZE - 1,
842 &VirtualSize);
843 if (!NT_SUCCESS(Status))
844 {
845 goto Quickie;
846 }
847 VirtualSize = ALIGN_DOWN_BY(VirtualSize, PAGE_SIZE);
848
849 /* Make sure the image isn't larger than 4GB */
850 if (VirtualSize > ULONG_MAX)
851 {
853 goto Quickie;
854 }
855
856 /* Check if we have a buffer already */
858 {
859 /* Check if it's too small */
860 if (*ImageSize < VirtualSize)
861 {
862 /* Fail, letting the caller know how big to make it */
863 *ImageSize = VirtualSize;
865 }
866 }
867 else
868 {
869 /* Allocate the buffer with the flags and type the caller wants */
871 MemoryType,
872 VirtualSize,
873 Flags);
874 }
875
876 /* Bail out if allocation failed, or existing buffer is too small */
877 if (!NT_SUCCESS(Status))
878 {
879 goto Quickie;
880 }
881
882 /* Read the size of the headers */
883 HeaderSize = NtHeaders->OptionalHeader.SizeOfHeaders;
884 if (VirtualSize < HeaderSize)
885 {
886 /* Bail out if they're bigger than the image! */
888 goto Quickie;
889 }
890
891 /* Now read the header into the buffer */
892 Status = ImgpReadAtFileOffset(LocalFile, HeaderSize, 0, VirtualAddress, NULL);
893 if (!NT_SUCCESS(Status))
894 {
895 goto Quickie;
896 }
897
898 /* Get the NT headers of the file */
899 Status = RtlImageNtHeaderEx(0, VirtualAddress, HeaderSize, &NtHeaders);
900 if (!NT_SUCCESS(Status))
901 {
902 goto Quickie;
903 }
904
905 First = FALSE;
906
907 /* Record how many sections we have */
908 SectionCount = NtHeaders->FileHeader.NumberOfSections;
909
910 /* Capture the current checksum and reset it */
911 CheckSum = NtHeaders->OptionalHeader.CheckSum;
912 NtHeaders->OptionalHeader.CheckSum = 0;
913
914 /* Calculate the checksum of the header, and restore the original one */
915 PartialSum = BlUtlCheckSum(0,
917 HeaderSize,
920 NtHeaders->OptionalHeader.CheckSum = CheckSum;
921
922 /* Record our current position (right after the headers) */
923 EndOfHeaders = (ULONG_PTR)VirtualAddress + HeaderSize;
924
925 /* Get the first section and iterate through each one */
926 Section = IMAGE_FIRST_SECTION(NtHeaders);
927 for (i = 0; i < SectionCount; i++)
928 {
929 /* Compute where this section starts */
930 SectionStart = (ULONG_PTR)VirtualAddress + Section->VirtualAddress;
931
932 /* Make sure that the section fits within the image */
933 if ((VirtualSize < Section->VirtualAddress) ||
934 ((PVOID)SectionStart < VirtualAddress))
935 {
936 EfiPrintf(L"fail 1\r\n");
938 goto Quickie;
939 }
940
941 /* Check if there's slack space between header end and the section */
942 if (!(First) && (EndOfHeaders < SectionStart))
943 {
944 /* Zero it out */
945 Slack = SectionStart - EndOfHeaders;
946 RtlZeroMemory((PVOID)EndOfHeaders, Slack);
947 }
948
949 /* Get the section virtual size and the raw size */
950 SectionSize = Section->Misc.VirtualSize;
951 RawSize = Section->SizeOfRawData;
952
953 /* Safely align the raw size by 2 */
954 Status = RtlULongAdd(RawSize, 1, &AlignSize);
955 if (!NT_SUCCESS(Status))
956 {
957 goto Quickie;
958 }
959 AlignSize = ALIGN_DOWN_BY(AlignSize, 2);
960
961 /* IF we don't have a virtual size, use the raw size */
962 if (!SectionSize)
963 {
964 SectionSize = RawSize;
965 }
966
967 /* If we don't have raw data, ignore the raw size */
968 if (!Section->PointerToRawData)
969 {
970 RawSize = 0;
971 }
972 else if (SectionSize < RawSize)
973 {
974 /* And if the virtual size is smaller, use it as the final size */
975 RawSize = SectionSize;
976 }
977
978 /* Make sure that the section doesn't overflow in memory */
979 Status = RtlULongPtrAdd(Section->VirtualAddress,
980 SectionSize,
981 &SectionEnd);
982 if (!NT_SUCCESS(Status))
983 {
984 EfiPrintf(L"fail 21\r\n");
986 goto Quickie;
987 }
988
989 /* Make sure that it fits within the image */
990 if (VirtualSize < SectionEnd)
991 {
993 goto Quickie;
994 }
995
996 /* Make sure it doesn't overflow on disk */
997 Status = RtlULongPtrAdd(Section->VirtualAddress,
998 AlignSize,
999 &SectionEnd);
1000 if (!NT_SUCCESS(Status))
1001 {
1002 EfiPrintf(L"fail 31\r\n");
1004 goto Quickie;
1005 }
1006
1007 /* Make sure that it fits within the disk image as well */
1008 if (VirtualSize < SectionEnd)
1009 {
1011 goto Quickie;
1012 }
1013
1014 /* So does this section have a valid size after all? */
1015 if (RawSize)
1016 {
1017 /* Are we in the first iteration? */
1018 if (!First)
1019 {
1020 /* FUCK YOU BINUTILS */
1021 if (NtHeaders->OptionalHeader.MajorLinkerVersion < 7)
1022 {
1023 if ((*(PULONG)&Section->Name == 'ler.') && (RawSize < AlignSize))
1024 {
1025 /* Piece of shit won't build relocations when you tell it to,
1026 * either by using --emit-relocs or --dynamicbase. People online
1027 * have found out that by using -pie-executable you can get this
1028 * to happen, but then it turns out that the .reloc section is
1029 * incorrectly sized, and results in a corrupt PE. However, they
1030 * still compute the checksum using the correct value. What idiots.
1031 */
1032 WorkaroundForBinutils = AlignSize - RawSize;
1033 AlignSize -= WorkaroundForBinutils;
1034 }
1035 }
1036
1037 /* Yes, read the section data */
1038 Status = ImgpReadAtFileOffset(LocalFile,
1039 AlignSize,
1040 Section->PointerToRawData,
1041 (PVOID)SectionStart,
1042 NULL);
1043 if (!NT_SUCCESS(Status))
1044 {
1045 goto Quickie;
1046 }
1047
1048 /* Update our current offset */
1049 Offset = AlignSize + Section->PointerToRawData;
1050
1051 /* Update the checksum to include this section */
1052 PartialSum = BlUtlCheckSum(PartialSum,
1053 (PUCHAR)SectionStart,
1054 AlignSize,
1057 AlignSize += WorkaroundForBinutils;
1058 }
1059 }
1060
1061 /* Are we in the first iteration? */
1062 if (!First)
1063 {
1064 /* Is there space at the end of the section? */
1065 if (RawSize < SectionSize)
1066 {
1067 /* Zero out the slack space that's there */
1068 Slack = SectionSize - RawSize;
1069 RtlZeroMemory((PVOID)(SectionStart + RawSize), Slack);
1070 }
1071
1072 /* Update our tail offset */
1073 EndOfHeaders = SectionStart + SectionSize;
1074 }
1075
1076 /* Move to the next section */
1077 Section++;
1078 }
1079
1080 /* Are we in the first iteration? */
1081 if (!First)
1082 {
1083 /* Go to the end of the file */
1084 SectionStart = (ULONG_PTR)VirtualAddress + VirtualSize;
1085
1086 /* Is there still some slack space left? */
1087 if (EndOfHeaders < SectionStart)
1088 {
1089 /* Zero it out */
1090 Slack = SectionStart - EndOfHeaders;
1091 RtlZeroMemory((PVOID)EndOfHeaders, Slack);
1092 }
1093 }
1094
1095 /* Did the first iteration complete OK? */
1096 if ((NT_SUCCESS(Status)) && !(First))
1097 {
1098 /* Check how many non-image bytes are left in the file */
1099 RemainingLength = FileSize - Offset;
1100 while (RemainingLength)
1101 {
1102 /* See if the read will fit into our local buffer */
1103 if (RemainingLength >= sizeof(LocalBuffer))
1104 {
1105 /* Nope, cap it */
1106 BytesRead = sizeof(LocalBuffer);
1107 }
1108 else
1109 {
1110 /* Yes, but there's less to read */
1111 BytesRead = RemainingLength;
1112 }
1113
1114 /* Read 1024 bytes into the local buffer */
1115 Status = ImgpReadAtFileOffset(LocalFile,
1116 BytesRead,
1117 Offset,
1118 LocalBuffer,
1119 &BytesRead);
1120 if (!(NT_SUCCESS(Status)) || !(BytesRead))
1121 {
1123 goto Quickie;
1124 }
1125
1126 /* Advance the offset and reduce the length */
1127 RemainingLength -= BytesRead;
1128 Offset += BytesRead;
1129
1130 /* Compute the checksum of this leftover space */
1131 PartialSum = BlUtlCheckSum(PartialSum,
1132 LocalBuffer,
1133 BytesRead,
1136 }
1137
1138 /* Finally, calculate the final checksum and compare it */
1139 FinalSum = FileSize + PartialSum + WorkaroundForBinutils;
1140 if ((FinalSum != CheckSum) && (PartialSum == 0xFFFF))
1141 {
1142 /* It hit overflow, so set it to the file size */
1143 FinalSum = FileSize;
1144 }
1145
1146 /* If the checksum doesn't match, and caller is enforcing, bail out */
1147 if ((FinalSum != CheckSum) &&
1149 {
1151 goto Quickie;
1152 }
1153 }
1154
1155 /* Check if the .rsrc section should be checked with the filename */
1157 {
1158 EfiPrintf(L"Not yet supported\r\n");
1159 Status = 0xC0430007; // STATUS_SECUREBOOT_FILE_REPLACED
1160 goto Quickie;
1161 }
1162
1163 /* Check if we should relocate */
1165 {
1166 /* Check if we loaded at a different address */
1167 PreferredBase = (PVOID)NtHeaders->OptionalHeader.ImageBase;
1168 if (VirtualAddress != PreferredBase)
1169 {
1170 /* Yep -- do relocations */
1172 "Boot Environment Library",
1176 if (!NT_SUCCESS(Status))
1177 {
1178 /* That's bad */
1179 goto Quickie;
1180 }
1181 }
1182 }
1183
1184#if BL_TPM_SUPPORT
1185 /* Check if the image hash was valid */
1186 if (!ImageHashValid)
1187 {
1188 /* Send a TPM/SI notification without a context */
1189 BlEnNotifyEvent(0x10000002, NULL);
1190 }
1191
1192 /* Now send a TPM/SI notification with the hash of the loaded image */
1194 Context.HashAlgorithm = HashAlgorithm;
1195 Context.HashSize = HashSize;
1196 Context.FileName = ImageFile->FileName;
1197 Context.ImageSize = VirtualSize;
1198 Context.HashValid = ImageHashValid;
1199 Context.Hash = Hash;
1200 BlEnNotifyEvent(0x10000002, &Context);
1201#endif
1202
1203 /* Return the loaded address to the caller */
1204 *ImageBase = VirtualAddress;
1205
1206 /* If the caller wanted the image size, return it too */
1207 if (ImageSize)
1208 {
1209 *ImageSize = VirtualSize;
1210 }
1211
1212Quickie:
1213 /* Check if we computed the image hash OK */
1214 if (ImageHashValid)
1215 {
1216 /* Then free the information that ImgpValidateImageHash set up */
1217 EfiPrintf(L"leadking trusted boot\r\n");
1218 //ImgpDestroyTrustedBootInformation(&TrustedBootInformation);
1219 }
1220
1221 /* Check if we had a hash buffer */
1222 if (HashBuffer)
1223 {
1224 /* Free it */
1226 }
1227
1228 /* Check if we have a certificate directory */
1229 if ((CertBuffer) && (CertDirectory))
1230 {
1231 /* Free it */
1232 BlImgUnallocateImageBuffer(CertBuffer, CertDirectory->Size, 0);
1233 }
1234
1235 /* Check if we had an image buffer allocated */
1236 if ((ImageBuffer) && (FileSize))
1237 {
1238 /* Free it */
1239 BlImgUnallocateImageBuffer(ImageBuffer, FileSize, 0);
1240 }
1241
1242 /* Check if we had a local file handle */
1243 if (LocalFile)
1244 {
1245 /* Close it */
1246 ImgpCloseFile(LocalFile);
1247 }
1248
1249 /* Check if this is the failure path */
1250 if (!NT_SUCCESS(Status))
1251 {
1252 /* Check if we had started mapping in the image already */
1254 {
1255 /* Into a virtual buffer? */
1257 {
1258 /* Unmap and free it */
1262 }
1263 else
1264 {
1265 /* Into a physical buffer -- free it */
1267 }
1268 }
1269 }
1270
1271 /* Return back to caller */
1272 return Status;
1273}
WCHAR First[]
Definition: FormatMessage.c:11
#define ALIGN_DOWN_BY(size, align)
#define BL_LOAD_PE_IMG_VALIDATE_ORIGINAL_FILENAME
Definition: bl.h:185
#define BL_LOAD_PE_IMG_SKIP_RELOCATIONS
Definition: bl.h:182
@ BlLoaderData
Definition: bl.h:313
#define BL_UTL_CHECKSUM_USHORT_BUFFER
Definition: bl.h:191
#define BL_UTL_CHECKSUM_COMPLEMENT
Definition: bl.h:187
ULONG BlUtlCheckSum(_In_ ULONG PartialSum, _In_ PUCHAR Buffer, _In_ ULONG Length, _In_ ULONG Flags)
Definition: util.c:777
#define BL_LOAD_PE_IMG_EXISTING_BUFFER
Definition: bl.h:179
#define BL_LOAD_PE_IMG_CHECK_SUBSYSTEM
Definition: bl.h:181
#define BL_LOAD_PE_IMG_VIRTUAL_BUFFER
Definition: bl.h:177
#define BL_LOAD_PE_IMG_CHECK_FORCED_INTEGRITY
Definition: bl.h:183
#define BL_LOAD_PE_IMG_IGNORE_CHECKSUM_MISMATCH
Definition: bl.h:184
#define BL_LOAD_PE_IMG_CHECK_MACHINE
Definition: bl.h:178
#define BL_LOAD_PE_IMG_COMPUTE_HASH
Definition: bl.h:180
ULONG NTAPI LdrRelocateImage(_In_ PVOID BaseAddress, _In_opt_ PCSTR LoaderName, _In_ ULONG Success, _In_ ULONG Conflict, _In_ ULONG Invalid)
Definition: image.c:462
if(dx< 0)
Definition: linetemp.h:194
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
#define IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY
Definition: ntimage.h:456
#define IMAGE_FILE_MACHINE_AMD64
Definition: ntimage.h:17
#define IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION
Definition: ntimage.h:448
#define STATUS_INVALID_IMAGE_WIN_64
Definition: ntstatus.h:901
#define STATUS_IMAGE_CHECKSUM_MISMATCH
Definition: ntstatus.h:677
#define STATUS_INVALID_IMAGE_FORMAT
Definition: ntstatus.h:359
#define STATUS_FILE_INVALID
Definition: ntstatus.h:388
#define STATUS_INVALID_IMAGE_WIN_32
Definition: ntstatus.h:900
unsigned short USHORT
Definition: pedump.c:61
ULONG FileSize
Definition: bl.h:1279
UCHAR Flags
Definition: bl.h:1273
PVOID BaseAddress
Definition: bl.h:1276
PWCHAR FileName
Definition: bl.h:1280
DWORD PointerToRawData
Definition: pedump.c:290
union _IMAGE_SECTION_HEADER::@1571 Misc
uint32_t * PULONG
Definition: typedefs.h:59
unsigned char * PUCHAR
Definition: typedefs.h:53
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
_Must_inspect_result_ _In_ WDFDMATRANSACTION _In_ PFN_WDF_PROGRAM_DMA _In_ WDF_DMA_DIRECTION _In_ PMDL _In_ PVOID VirtualAddress
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR _In_opt_ PLONGLONG _In_opt_ PWDF_REQUEST_SEND_OPTIONS _Out_opt_ PULONG_PTR BytesRead
Definition: wdfiotarget.h:870
_In_ BOOLEAN _In_ ULONG HashAlgorithm
Definition: rtlfuncs.h:2055

Referenced by BlImgLoadPEImageEx().

◆ ImgpOpenFile()

NTSTATUS ImgpOpenFile ( _In_ ULONG  DeviceId,
_In_ PWCHAR  FileName,
_In_ ULONG  Flags,
_Out_ PBL_IMG_FILE  NewFile 
)

Definition at line 124 of file image.c.

130{
133 ULONGLONG RemoteFileSize;
134 PVOID RemoteFileAddress;
135 ULONG FileId;
136
137 /* First, try to see if BD has this file remotely */
139 &RemoteFileAddress,
140 &RemoteFileSize);
141 if (NT_SUCCESS(Status))
142 {
143 /* Yep, get the file size and make sure it's < 4GB */
144 FileSize = RemoteFileSize;
145 if (RemoteFileSize <= ULONG_MAX)
146 {
147 /* Remember this is a memory mapped remote file */
148 NewFile->Flags |= (BL_IMG_MEMORY_FILE | BL_IMG_REMOTE_FILE);
149 NewFile->FileSize = FileSize;
150 NewFile->BaseAddress = RemoteFileAddress;
151 goto Quickie;
152 }
153 }
154
155 /* Use File I/O instead */
156 Status = BlFileOpen(DeviceId,
157 FileName,
159 &FileId);
160 if (!NT_SUCCESS(Status))
161 {
162 /* Bail out on failure */
163 return Status;
164 }
165
166 /* Make sure nobody thinks this is a memory file */
167 NewFile->Flags &= ~BL_IMG_MEMORY_FILE;
168 NewFile->FileId = FileId;
169
170Quickie:
171 /* Set common data for both memory and I/O based file */
172 NewFile->Flags |= BL_IMG_VALID_FILE;
173 NewFile->FileName = FileName;
174 return Status;
175}
NTSTATUS BlFileOpen(_In_ ULONG DeviceId, _In_ PWCHAR FileName, _In_ ULONG Flags, _Out_ PULONG FileId)
Definition: file.c:477
NTSTATUS BlBdPullRemoteFile(_In_ PWCHAR FilePath, _Out_ PVOID BaseAddress, _Out_ PULONGLONG FileSize)
Definition: debug.c:34
#define BL_FILE_READ_ACCESS
Definition: bl.h:147
struct _FileName FileName
Definition: fatprocs.h:897

Referenced by BlImgLoadImageWithProgress2(), and BlImgLoadPEImageEx().

◆ ImgpReadAtFileOffset()

NTSTATUS ImgpReadAtFileOffset ( _In_ PBL_IMG_FILE  File,
_In_ ULONG  Size,
_In_ ULONGLONG  ByteOffset,
_In_ PVOID  Buffer,
_Out_ PULONG  BytesReturned 
)

Definition at line 72 of file image.c.

79{
81
82 /* Check what if this is a mapped file or not */
83 if (File->Flags & BL_IMG_MEMORY_FILE)
84 {
85 /* Check if the boundaries are within the file size */
86 if ((ByteOffset + Size) <= File->FileSize)
87 {
88 /* Yep, copy into the caller-supplied buffer */
90 (PVOID)((ULONG_PTR)File->BaseAddress + (ULONG_PTR)ByteOffset),
91 Size);
92
93 /* If caller wanted to know, return the size copied */
94 if (BytesReturned)
95 {
97 }
98
99 /* All good */
101 }
102 else
103 {
104 /* Doesn't fit */
106 }
107 }
108 else
109 {
110 /* Issue the file I/O instead */
112 Size,
114 Buffer,
116 0);
117 }
118
119 /* Return the final status */
120 return Status;
121}
NTSTATUS BlFileReadAtOffsetEx(_In_ ULONG FileId, _In_ ULONG Size, _In_ ULONGLONG ByteOffset, _In_ PVOID Buffer, _Out_ PULONG BytesReturned, _In_ ULONG Flags)
Definition: file.c:788
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_ ULONG _In_opt_ PWDF_MEMORY_DESCRIPTOR _In_opt_ PWDF_MEMORY_DESCRIPTOR _In_opt_ PWDF_REQUEST_SEND_OPTIONS _Out_opt_ PULONG_PTR BytesReturned
Definition: wdfiotarget.h:1052

Referenced by BlImgLoadImageWithProgress2(), and ImgpLoadPEImage().

Variable Documentation

◆ BootApp32EntryRoutine

PVOID BootApp32EntryRoutine

Definition at line 25 of file image.c.

Referenced by ImgArchEfiStartBootApplication().

◆ BootApp32Parameters

PBOOT_APPLICATION_PARAMETER_BLOCK BootApp32Parameters

Definition at line 26 of file image.c.

Referenced by ImgArchEfiStartBootApplication().

◆ BootApp32Stack

PVOID BootApp32Stack

Definition at line 27 of file image.c.

Referenced by ImgArchEfiStartBootApplication().

◆ BootAppGdtRegister

KDESCRIPTOR BootAppGdtRegister

Definition at line 23 of file image.c.

Referenced by ImgArchEfiStartBootApplication().

◆ BootAppIdtRegister

KDESCRIPTOR BootAppIdtRegister

Definition at line 24 of file image.c.

Referenced by ImgArchEfiStartBootApplication().

◆ GdtRegister

KDESCRIPTOR GdtRegister

Definition at line 21 of file image.c.

◆ IapAllocatedTableEntries

ULONG IapAllocatedTableEntries

Definition at line 16 of file image.c.

Referenced by BlImgLoadBootApplication(), and BlImgUnloadBootApplication().

◆ IapImageTable

PVOID* IapImageTable

◆ IapTableEntries

ULONG IapTableEntries

◆ IdtRegister

KDESCRIPTOR IdtRegister

Definition at line 22 of file image.c.