From 044a792171add4cdec5f5ee1e2d4d47059665232 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Tue, 23 Jun 2020 05:54:13 +0000 Subject: [PATCH] progress on parsing "boot/Contents" --- dump-float2.c | 2 +- dump-spo2.c | 191 ++++++++++++++++++++++++++++++++++++++++++++++++-- spo-notes | 31 ++++---- 3 files changed, 201 insertions(+), 23 deletions(-) diff --git a/dump-float2.c b/dump-float2.c index 0d27404a43..8c9b57ea8d 100644 --- a/dump-float2.c +++ b/dump-float2.c @@ -5,7 +5,7 @@ int main (void) { - double d = 100; + double d = 100zz; fwrite (&d, 1, sizeof d, stdout); return 0; } diff --git a/dump-spo2.c b/dump-spo2.c index d50d861fa4..a76aff9762 100644 --- a/dump-spo2.c +++ b/dump-spo2.c @@ -296,7 +296,7 @@ match_string2_assert(const char *exp, const char *where) #define match_string2_assert(x) match_string2_assert(x, WHERE) static char * -get_string(const char *where) +get_string4(const char *where) { if (1 /*data[pos + 1] == 0 && data[pos + 2] == 0 && data[pos + 3] == 0*/ @@ -316,7 +316,15 @@ get_string(const char *where) exit(1); } } -#define get_string() get_string(WHERE) +#define get_string4() get_string4(WHERE) + +static char * +get_padded_string(int len) +{ + char *s = xmemdup0(&data[pos], len); + pos += len; + return s; +} static char * get_string_be(const char *where) @@ -435,6 +443,16 @@ format_name (int format, char *buf) } } +static void +parse_format(void) +{ + int d = data[pos++]; + int w = data[pos++]; + int fmt = data[pos++]; + char buf[32]; + printf ("%s%d.%d", format_name(fmt, buf), w, d); +} + static void parse_heading(const char *name) { @@ -444,18 +462,19 @@ parse_heading(const char *name) } static void -match_zeros_assert(int count) +match_zeros_assert(int count, const char *where) { for (int i = 0; i < count; i++) if (data[pos + i]) { fprintf (stderr, - "%#x: expected %d zeros here but offset %d is %#"PRIx8"\n", - pos, count, i, data[pos + i]); + "%s: %#x: expected %d zeros here but offset %d is %#"PRIx8"\n", + where, pos, count, i, data[pos + i]); exit (1); } pos += count; } +#define match_zeros_assert(count) match_zeros_assert(count, WHERE) static void parse_DspString(void) @@ -470,6 +489,43 @@ parse_DspString(void) printf ("DspString(\"%s\")\n", get_string1()); } +static void +match_DspString(void) +{ /* 05 80 */ + match_byte_assert(5); + match_byte_assert(0x80); + parse_DspString(); +} + +static void +match_DspSimpleText(void) +{ /* 03 80 */ + match_byte_assert(3); + match_byte_assert(0x80); + match_zeros_assert(10); +} + +static void +match_NavTreeViewItem(void) +{ /* 07 80 */ + match_byte_assert(7); + match_byte_assert(0x80); + match_zeros_assert(1); + if (!match_byte(0) && !match_byte(7)) + match_byte_assert(8); + match_zeros_assert(3); + pos++; + match_byte_assert(0); + match_byte_assert(1); + match_zeros_assert(3); + if (!match_byte(0)) + match_byte_assert(1); + match_zeros_assert(5); + match_byte_assert(1); + match_zeros_assert(5); + puts(get_string1()); +} + int main(int argc, char *argv[]) { @@ -543,7 +599,130 @@ main(int argc, char *argv[]) parse_DspString(); parse_heading("NavTreeViewItem"); - + match_byte_assert(0); + match_u32_assert(0); + match_byte_assert(2); + match_byte_assert(0); + match_byte_assert(1); + match_zeros_assert(9); + match_u32_assert(1); + assert (pos == 0xb0); + + pos += 0x28; + match_zeros_assert(5); + if (match_u32(8500)) + match_u32_assert(11000); + else + { + match_u32_assert(11000); + match_u32_assert(8500); + } + pos = 0x105; + match_string1_assert("(Continued)"); + match_byte_assert(1); + match_byte_assert(1); + match_zeros_assert(3); + get_string4(); /* page title */ + match_byte_assert(1); + match_byte_assert(1); + match_zeros_assert(3); + get_string4(); /* page number */ + match_byte_assert(0); + pos += 2; + match_u16_assert(2); + + parse_heading("NavLog"); + pos = 0x36b; + puts(get_padded_string(32)); + if (!match_u32(80)) + match_u32_assert(132); + match_zeros_assert(8); + match_u32_assert(1); + get_string4(); + match_byte_assert(0); + + parse_heading("NavHead"); + match_byte_assert(2); + match_zeros_assert(24); + match_u32_assert(1); + match_u32_assert(0); + match_DspSimpleText(); + match_DspString(); + match_NavTreeViewItem(); + match_zeros_assert(3); + + parse_heading("NavTitle"); + pos += 33; + match_DspSimpleText(); + match_DspString(); + match_NavTreeViewItem(); + + match_byte_assert(1); + match_byte_assert(1); + match_u32_assert(-19); + match_zeros_assert(12); + match_byte_assert(0xbc); + match_byte_assert(2); + match_zeros_assert(9); + match_byte_assert(0x22); + puts(get_padded_string(32)); + match_u32_assert(80); + match_zeros_assert(8); + match_u32_assert(1); + get_string4(); + match_byte_assert(0); + + parse_heading("NavNote"); + match_byte_assert(2); + match_zeros_assert(8); + match_u32_assert(24); + if (!match_u32(0)) + match_u32_assert(-40); + pos += 8; + match_u32_assert(2); + match_u32_assert(1); + match_DspSimpleText(); + match_DspString(); + match_NavTreeViewItem(); + match_byte_assert(1); + + parse_heading("PTPivotController"); + match_byte_assert(2); + pos += 8; + match_u32_assert(100); + match_u32_assert(100); + match_u32_assert(100); + match_u32_assert(100); + + parse_heading("PVPivotView"); + match_u32_assert(5); + match_byte_assert(0); + + parse_heading("PMPivotModel"); + match_byte_assert(3); + + parse_heading("NDimensional__DspCell"); + match_byte_assert(0); + match_u32_assert(1); + + parse_heading("IndexedCollection"); + match_byte_assert(0); + pos++; + match_zeros_assert(3); + match_byte_assert(1); + match_byte_assert(0); + + parse_heading("DspCell"); + match_byte_assert(0); + match_DspSimpleText(); + + parse_heading("DspNumber"); + match_byte_assert(1); + parse_format(); + match_byte_assert(0x80); + match_byte(2); + printf (" %f", get_double()); + printf (" \"%s\"\n", get_string1()); printf ("%#x: end of successful parse\n", pos); diff --git a/spo-notes b/spo-notes index 93682571b9..869eb14175 100644 --- a/spo-notes +++ b/spo-notes @@ -699,7 +699,8 @@ When the top-level "Output" node is selected for save: ffff 0000 "DspString" 01 02 28 00 00 01 b"Output" ffff 0000 "NavTreeViewItem" 00 i0 02 00 01 00*9 i1 -00c0 (i0 | i24) (i24 | i-40) (i0 | i40 | i-40) (i40 | i-34) +00b0 (i0 | i24) (i24 | i-40) (i0 | i40 | i-40) (i40 | i-34) +00c0 i24 i0 i40 i40 00d0 (i1048 | some other 3-hex-digit number | i0) 00d4 (i0 | some 3 to 4-hex-digit number | i-40) 00d8 00*5 @@ -717,7 +718,7 @@ When the top-level "Output" node is selected for save: 00ff s0 # charts: 0=asis, 1=full page, 2=half, 03=quarter 0101 s?? 0103 s1 # starting page number -0105 b"(Continued)" 01 01 00*3 byte 00*3 +0105 b"(Continued)" 01 01 00*3 0116 w"{\rtf... pagetitle}" 01fd 01 01 00*3 0202 w"{\rtf... page number}" @@ -731,13 +732,11 @@ When the top-level "Output" node is selected for save: 0318 03 80 00*10 0324 05 80 01 02 28 05 00 01 b"Log" -0333 07 80 00 02 00 00 00 0a 00 01 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 -0347 00*2 01 01 (i-13 | i-12) i0 -0357 00*8 90 01 00*9 (22|31) +0333 07 80 00 02 00 00 00 0a 00 01 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 b"" 00 +0347 01 01 (i-13 | i-12) 00*12 90 01 00*9 (22|31) 036b 32-bytes of null-padded font name, e.g. "Courier New". Sometimes garbage after the first null. 038b (i80 | i132) 00*8 i1 -038f 00*8 i1 039b w"{\rtf ... SPSS syntax...}" Almost past SPSS syntax (only the } included): @@ -745,7 +744,7 @@ Almost past SPSS syntax (only the } included): 0002 ffff 0000 "NavHead" 02 0010 00*24 i1 i0 -0030 03 80 00 00 00 00 00 00 00 00 00 00 +0030 03 80 00*10 05 80 01 02 28 05 00 01 b"Cluster|Crosstabs|..." Just past the string: @@ -756,25 +755,26 @@ Just past the string again: 0003 ffff 0000 "NavTitle" 0011 65 02 00 00 00 00 00 00 00 00 18 00 00 00 byte byte 0020 ff ff 00 04 00 00 byte byte -0028 ff ff 02 00 00 00 01 00 00 00 03 80 00*10 +0028 ff ff 02 00 00 00 01 00 00 00 +0032 03 80 00*10 003e 05 80 01 02 28 00 00 01 b"Title" 004c 07 80 00 08 00 00 00 14 00 01 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 b"Cluster|Crosstabs|..." Just past the third string: -0000 01 01 ed ff ff ff 00 00 00 00 00 00 00 00 00 00 -0010 00 00 bc 02 00 00 00 00 00 00 00 00 00 22 +0000 01 01 i-19 00*12 bc 02 00*9 22 001e 32-bytes of buggy zero-padded string "Arial" -003e 50 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 +003e i80 00*8 i1 004e w"{\rtf...}" Almost past the RTF (only } included): 0000 '}' 00 + 0002 ffff 0000 "NavNote" -0010 02 00 00 00 00 00 00 00 00 18 00 00 00 (i0 | i-40) +0010 02 00*8 i24 (i0 | i-40) 0020 int int i2 i1 0030 03 80 00*10 003c 05 80 01 02 28 05 00 01 b"Notes" -004a 07 80 00 07 00 00 00 19 00 01 00 00 00 01 00 00 00 00 00 01 00 00 00 00 00 b"Cluster|Crosstabs|..." +004a 07 80 00 07 00*3 19 00 01 00*3 01 00*5 01 00*5 b"Cluster|Crosstabs|..." Just past the fourth string: 0000 01 @@ -806,9 +806,8 @@ Fork: cell contains number ("as-number"): 00c5 80 02 00c7 double # seconds since 1582... 00cf b"16-APR-2007 15:20:00" # or whatever -00e4 27 -00e5 80 00 03 80 00 00 00 00 00 00 00 00 00 00 05 -00f4 80 01 02 28 05 00 01 01 20 +00e4 27 80 00 03 80 00 00 00 00 00 00 00 00 00 00 +00f3 05 80 01 02 28 05 00 01 01 20 # Some files have extra 00 00 here # but we're only considering as-number-nozeros 00fd 27 80 00 -- 2.30.2