[File] [PATCH] of Magdir/windows for boot status log BOOTSTAT.DAT

Jörg Jenderek joerg.jen.der.ek at gmx.net
Sun Nov 17 19:15:32 UTC 2019

Hash: SHA1

some days ago i had problems when booting Window after migrating to
version 10. In BOOT subdirectory are files with name BOOTSTAT.DAT.
When i run file command version 5.37 on such files, these are
misidentified as GLS_BINARY_LSB_FIRST or only described as data.

But in reality such files are Windows boot status logs. So i add
to Magdir/windows additional lines.

There is scarcely any documentation from Microsoft but many useful
information is found on site about the Boot Status Data Log from
Geoff Chappell. This is expressed by comment line with reference URL
 # Reference: www.geoffchappell.com/notes/windows/boot/bsd.htm

I use 2 sub routines to display information, because then it is
easier to update and maintain magic lines, when more file
information becomes available or used assumptions about file format
are wrong.
The main function that shows information about BOOTSTAT.DAT based on
values in header start like
 0	name		bootstat-dat
 >0		ulelong		x		Windows boot log
The files are binary. There does not exist an official mime type. So
i show afterwards a user defined one by line
 !:mime	application/x-ms-dat
Such files seem to have always the name BOOTSTAT.DAT and are located
in BOOT subdirectory on UEFI partitions or System partitions
depending on Windows versions/systems. This is expressed by line
 !:ext	dat

First value apparently is a version number. Geoff Chappell mainly
refers to older Windows Vista. There this number is 2, but i also
found 3 and 4 for Windows 10. To keep output columns low i only
display values if these are non standard or unusual. So version is
shown by line
 >0		ulelong		>2		\b, version %u

According to Geoff Chappell BOOTSTAT.DAT at the moment always
occupies 64 KiB Bytes on disc to be handled by BOOTMGR. This size is
stored as third value in header. So show this value for non standard
values by line
 >8		ulelong		!0x00010000	\b, file size 0x%x
Furthermore i use this this variable as characteristic magic for
BOOTSTAT.DAT files at the moment. So skip many ISO CD-ROM images by
test for valid file size and valid low version number below 5 by
lines like
 0		ulelong		<5
 >8		ulelong		=0x00010000
 >>0		use		bootstat-dat

After the header logged entries are stored and the remaining part
until 64 KiB limit are filled with nulls. The valid data includes
the file header and any number of logged entries that follow. That
size is stored as fourth value in header and is shown by line
 >0xc		ulelong		x		\b, 0x%x valid bytes

The header size is stored as second value. For older Windows like
Vista this value is 10h. For newer Windows version like 10 i also
find values 14h, 18h. So show unusual values by line
 >4		ulelong		!0x10		\b, header size 0x%x
With the information about header size it is possible to jump to
first boot log entry and inspect that data by second sub routine like
 >(0x4.l-1)	ubyte		x
 >>&0		use		bootstat-entry

At the beginning of a log entry a time stamp is stored as seconds.
This is shown by lines like
 0		name		bootstat-entry
 >0x00		ulelong		x		\b, 0x%x seconds

The size of a log entry is stored as fourth value. This is shown by
line like
 >0x18		ulelong		x		\b; entry size 0x%x

I had some problems with pointer handling inside file command, but
in the end i find a working pointer constructing using stored entry
So in first function jump step by step to second entry and display
stored information is done by lines:
 >(0x4.l-1)	ubyte		x
 >>&(&0x18.l-1)		ubyte	x
 >>>&0			use	bootstat-entry
So if somebody is interested in third log entry, this can be done by
lines like:
 >(0x4.l-1)	ubyte		x
 >>&(&0x18.l-1)		ubyte	x
 >>>&(&0x18.l-1)	ubyte	x
 >>>>&0			use	bootstat-entry

In log entry as third value the GUID of event source is stored, but
this is empty (that is null) if event source is BOOTMGR. So display
non standard GUID values by lines:
 >0x08		ubequad		!0		\b, GUID 0x%16.16llx
 >>0x10		ubequad		x		\b%16.16llx

The severity code is stored as fifth value in entry part, where
value 1 means informational events and 0x03 is for error events. So
skip OK-events and display only severity for events with errors to
keep output small by line:
 >0x1C		ulelong		!1		\b, severity 0x%x

The event identifier is stored as values number 7. For typical
BOOTSTAT.DAT files first entry has value 1 and second has value 11h.
So display only unusual event identifieres by lines
 >0x24		ulelong		!1
 >>0x24		ulelong		!0x11		\b, event 0x%x

At the end of entry subroutine handle these 2 typical log entry types.
Event identifier 1 means log file initialised and the data part of
log entry mainly contains a complete time stamp structure starting
with year. This is shown by lines starting with lines:
 >0x24		ulelong		=0x1		\b, Init
 >>0x28		uleshort	x		%u

Event identifier 11h means "boot application launched". For such
null-terminated Unicode string of application is stored as third
part in data section. Typical names are winload.exe or winload.efi
in system32 subdirectory in Windows directory. This information is
shown by lines like:
 >0x24		ulelong		=0x11		\b, launched
 >>0x3C		lestring16	x		%s

After applying the above mentioned modifications by patch
file-5.37-windows-dat.diff then i get a output like:

	Windows boot log,
	0xc8 valid bytes;
	entry size 0x40, 0xcb9e seconds,
	Init 2016-6-14 14:28:45;
	entry size 0x78, 0xcb9e seconds,
	launched \Windows\system32\winload.exe
	Windows boot log,
	version 4, header size 0x18, 0x5d7c valid bytes;
	entry size 0x40, 0x1208 seconds,
	GUID 0x2c86ea9ddd5c704eacc1f32b344d4795,
	Init 2017-10-23 19:16:56;
	entry size 0x78, 0x120a seconds,
	GUID 0x2c86ea9ddd5c704eacc1f32b344d4795,
	launched \windows\system32\winload.efi
	Windows boot log,
	version 3, 0x50 valid bytes;
	entry size 0x40, 0x8245 seconds,
	Init 2017-5-16 9:15:49;
	entry size 0x78, 0x12173 seconds,
	launched \Windows\system32\winload.exe
	Windows boot log,
	version 3, 0xc8 valid bytes;
	entry size 0x40, 0x13a3 seconds,
	GUID 0x2c86ea9ddd5c704eacc1f32b344d4795,
	Init 2016-4-16 20:23:47;
	entry size 0x78, 0x13a4 seconds,
	GUID 0x2c86ea9ddd5c704eacc1f32b344d4795,
	launched \windows\system32\winload.efi
	Windows boot log,
	version 4, header size 0x14, 0x172 valid bytes;
	entry size 0x40, 0xdbfe seconds,
	GUID 0x2c86ea9ddd5c704eacc1f32b344d4795,
	Init 2019-5-7 15:38:38;
	entry size 0x9c, 0xdbff seconds,
	GUID 0x2c86ea9ddd5c704eacc1f32b344d4795,
	severity 0x3, event 0x50

I hope my diff file can be applied in future version of
file utility.

With best wishes
Jörg Jenderek
- --
Jörg Jenderek

Comment: Using GnuPG with Thunderbird - https://www.enigmail.net/

-------------- next part --------------
--- file-5.37/magic/Magdir/windows.old	2019-05-01 17:55:25 +0000
+++ file-5.37/magic/Magdir/windows	2019-11-17 19:01:28 +0000
@@ -119,6 +119,94 @@
 # 3rd BLOB
 >>0x480		string		>\0		\b, type %-3.8s
+# Summary:	Windows boot status log BOOTSTAT.DAT
+# From:		Joerg Jenderek
+# Reference:	https://www.geoffchappell.com/notes/windows/boot/bsd.htm
+# Note:		mainly refers to older Windows Vista, sometimes
+#		BOOTSTAT.DAT only contains nulls or invalid data
+# checking for valid verson below 5
+0		ulelong		<5
+# skip many ISO images by checking for valid 64 KiB file size
+>8		ulelong		=0x00010000
+>>0		use		bootstat-dat
+# display information of BOOTSTAT.DAT
+0	name		bootstat-dat
+>0		ulelong		x		Windows boot log
+#!:mime	application/octet-stream
+!:mime	application/x-ms-dat
+# BOOTSTAT.DAT in BOOT subdirectory
+!:ext	dat
+# apparently a version number: 2 for older like Vista, 3, 4 Windows 10
+>0		ulelong		>2		\b, version %u
+# apparently the size of the header: often 10h in older Windows, 14h, 18h
+>4		ulelong		!0x10		\b, header size 0x%x
+#>4		ulelong		!0x10		\b, header size %u
+# apparently the size of the file: always 0x00010000~64KiB
+# the file is acceptable to BOOTMGR only if it is exactly 64 KiB
+>8		ulelong		!0x00010000	\b, file size 0x%x
+# size of valid data, in bytes: C8h 50h 172h 5D5Ch
+>0xc		ulelong		x		\b, 0x%x valid bytes
+# skip header and jump to first bootstat entry and display information
+>(0x4.l-1)	ubyte		x
+>>&0		use		bootstat-entry
+# jump to first entry again because pointer are bad after "use"
+>(0x4.l-1)	ubyte		x
+# by 1st entry size jump to 2nd entry and display information
+>>&(&0x18.l-1)	ubyte		x
+>>>&0		use		bootstat-entry
+# jump to possible 3rd boot entry and display information
+# >(0x4.l-1)	ubyte		x
+# >>&(&0x18.l-1)	ubyte		x
+# >>>&(&0x18.l-1)	ubyte		x
+# >>>>&0		use		bootstat-entry
+#	display BOOTSTAT.DAT entry
+0	name		bootstat-entry
+#>0x00		ubequad		x		\b, ENTRY %16.16llx
+# size of entry, in bytes: 40h(init) 78h(launced) 9Ch
+#>0x18		ulelong		x		\b; entry size %u
+>0x18		ulelong		x		\b; entry size 0x%x
+# time stamp, in seconds 
+>0x00		ulelong		x		\b, 0x%x seconds
+# always zero, significance unknown
+>0x04		ulelong		!0		\b, not null %u
+# GUID of event source; but empty if event source is BOOTMGR 
+>0x08		ubequad		!0		\b, GUID 0x%16.16llx
+>>0x10		ubequad		x		\b%16.16llx
+# severity code: 1~informational 3~errors
+>0x1C		ulelong		!1		\b, severity 0x%x
+# apparently a version number: 2 
+>0x20		ulelong		!2		\b, version %u
+# event identifier 1~log file initialised 11h~boot application launched 
+#>0x24		ulelong		x		\b, event 0x%x
+>0x24		ulelong		!1
+>>0x24		ulelong		!0x11		\b, event 0x%x
+# entry data; size depends on event identifier  
+#>0x28		ubequad		x		\b, data 0x%16.16llx
+>0x24		ulelong		=0x1		\b, Init
+# always 0, significance unknown 
+>>0x34		uleshort	!0		\b, not null %u
+# always 7, significance unknown 
+>>0x36		uleshort	!7		\b, not seven %u
+# year
+>>0x28		uleshort	x		%u
+# month
+>>0x2A		uleshort	x		\b-%u
+# day
+>>0x2C		uleshort	x		\b-%u
+# hour
+>>0x2E		uleshort	x		%u
+# minute
+>>0x30		uleshort	x		\b:%u
+# second
+>>0x32		uleshort	x		\b:%u
+# boot application launched
+>0x24		ulelong		=0x11		\b, launched
+# type of start: 0 normally, 1 or 2 maybe in a recovery sequence
+>>0x38		uleshort	!0		\b, type %u
+# pathname of boot application, as null-terminated Unicode string; typically
+# \Windows\system32\winload.exe \Windows\system32\winload.efi
+>>0x3C		lestring16	x		%s
 # Summary:	Windows Error Report text files
 # URL:		https://en.wikipedia.org/wiki/Windows_Error_Reporting
 # Reference:	https://www.nirsoft.net/utils/app_crash_view.html
-------------- next part --------------
A non-text attachment was scrubbed...
Name: file-5.37-windows-dat.diff.sig
Type: application/octet-stream
Size: 95 bytes
Desc: not available
URL: <https://mailman.astron.com/pipermail/file/attachments/20191117/b6e2810d/attachment.obj>

More information about the File mailing list