Home > OS >  How Do I Enumerate Boot Entries without Crashing My Program in C?
How Do I Enumerate Boot Entries without Crashing My Program in C?

Time:08-06

I am trying to enumerate boot entries using the undocumented function "NtEnumerateBootEntries".

I am using this webpage as a reference.

My code:

ULONG BufferLength;
NTSTATUS NtStatus = NtEnumerateBootEntries(NULL, &BufferLength);
if (NtStatus != STATUS_BUFFER_TOO_SMALL) { NtStatusErrorExit("NtEnumerateBootEntries", NtStatus); }

PBOOT_ENTRY_LIST* BootEntries = malloc(BufferLength);
NtStatus = NtEnumerateBootEntries(BootEntries, &BufferLength);
if (NT_ERROR(NtStatus)) { NtStatusErrorExit("NtEnumerateBootEntries", NtStatus); }

int NumBootEntries = sizeof(BootEntries) / sizeof(PBOOT_ENTRY_LIST*);
printf("Number of Boot Entries: %i\r\n", NumBootEntries);

for (int i = 0; i < NumBootEntries; i  ) {
    BOOT_ENTRY BootEntry = BootEntries[i]->BootEntry;
    printf("Boot Entry ID: %lu\r\n", BootEntry.Id);
}

When I compile and run my code, my program prints the number of boot entries and then crashes. It does not print the boot entry ID.

How can I solve this issue?

CodePudding user response:

You absolutely DON'T want "sizeof()".

I believe this should work (untested):

// Query buffer size
ULONG BufferLength;
NTSTATUS NtStatus = NtEnumerateBootEntries(NULL, &BufferLength);
if (NtStatus != STATUS_BUFFER_TOO_SMALL) { 
    NtStatusErrorExit("NtEnumerateBootEntries", NtStatus);
}

// Allocate buffer and query boot list
PBOOT_ENTRY_LIST* BootEntries = malloc(BufferLength);
if (BootEntries == NULL) { 
    // Flag malloc() error
} else {
    NtStatus = NtEnumerateBootEntries(BootEntries, &BufferLength);
    if (NT_ERROR(NtStatus)) {
        NtStatusErrorExit("NtEnumerateBootEntries", NtStatus);
    }
}

// Get #/Entries
// int NumBootEntries = sizeof(BootEntries) / sizeof(PBOOT_ENTRY_LIST*);  // <-- Don't do this...
UNIT Count;
NtStatus = pNtQueryBootEntryOrder(NULL, &Count);
PBOOT_ENTRY* BootEntries = new PBOOT_ENTRY[Count];
printf("Number of Boot Entries: %i\r\n", Count);

// Iterate list
UINT Length = 0;
for (UINT i = 0; i < Count; i  ) {
    BootEntries[i] = (PBOOT_ENTRY) (Buffer   Length   4);
    printf("Boot Entry ID: %lu\r\n", BootEntries[i].Id);
    Length  = *(PULONG) (Buffer   Length);
}

CodePudding user response:

I was doing two things wrong:

  • I was doing sizeof(BufferEntries) instead of BufferSize
  • I was doing PBOOT_ENTRY_LIST* instead of BOOT_ENTRY_LIST

Working code:

ULONG BufferLength;
NTSTATUS NtStatus = NtEnumerateBootEntries(NULL, &BufferLength);
if (NtStatus != STATUS_BUFFER_TOO_SMALL) { NtStatusErrorExit("NtEnumerateBootEntries", NtStatus); }

BOOT_ENTRY_LIST* BootEntries = malloc(BufferLength);
NtStatus = NtEnumerateBootEntries(BootEntries, &BufferLength);
if (NT_ERROR(NtStatus)) { NtStatusErrorExit("NtEnumerateBootEntries", NtStatus); }

int NumBootEntries = BufferLength / sizeof(BOOT_ENTRY_LIST);
printf("Number of Boot Entries: %i\r\n", NumBootEntries);

for (int i = 0; i < NumBootEntries; i  ) {
    BOOT_ENTRY BootEntry = BootEntries[i].BootEntry;
    printf("Boot Entry ID: %lu\r\n", BootEntry.Id);
}
  • Related