3 # Determine the subsystem of a PE32 executable.
5 # Copyright © 2022 Nick Bowler
7 # License WTFPL2: Do What The Fuck You Want To Public License, version 2.
8 # This is free software: you are free to do what the fuck you want to.
9 # There is NO WARRANTY, to the extent permitted by law.
19 probe_dumper(filename);
24 } else if ($2 == "046532") {
31 val = 65536*od_decode($3) + od_decode($2);
33 pe_offset = sprintf("%o", val);
34 pe32_offset = sprintf("%o", val+24);
35 subsys_offset = sprintf("%o", val+24+68);
38 if ($2 != "042520" || $3 != "000000") {
44 if ($2 != "000413" && $2 != "001013") {
49 od_read(subsys_offset);
50 subsys = od_decode($2);
56 subsys = "unknown (" subsys ")";
65 function probe_dumper(filename)
67 (cmd = "od " filename " +10 2>/dev/null") | getline
72 dumper_style = "od_traditional";
76 (cmd = "od -j010 " filename " 2>/dev/null") | getline
81 dumper_style = "od_posix";
88 function od_read(offset, cmd)
90 if (dumper_style == "od_traditional") {
91 cmd = "od " filename " +" offset;
92 } else if (dumper_style == "od_posix") {
93 cmd = "od -j0" offset " " filename;
99 if (endian == "big") {
105 # Byte-swap one of the 2-byte blocks of octal digits emitted by od.
106 function od_bswap(word, i, digits, carry)
108 for (i = 0; i < 6; i++) {
109 digits[i] = substr(word, i+1, 1);
112 # suss out the first byte by adjusting the first 4 digits left by 1 bit
113 if (carry = (digits[3] >= 4))
116 for (i = 2; i >= 0; i--) {
117 if (carry = ( (digits[i] = digits[i]*2 + carry) >= 8 ))
121 # now munge the second byte by adjusting the last 3 digits right 1 bit
123 for (i = 3; i < 6; i++) {
124 carry = (digits[i] += 8*carry) % 2;
125 digits[i] = int(digits[i] / 2);
128 # and put the leftover bit in place
129 digits[0] += 4*carry;
131 return digits[3] digits[4] digits[5] digits[0] digits[1] digits[2];
134 # Parse a string of octal digits into a number.
135 function od_decode(word, result)
140 result = 8*result + substr(word, 1, 1);
141 word = substr(word, 2);