152
152
LinearExecutable::Loader::load_le_header_offset (void )
153
153
{
154
154
char id[2 ];
155
- uint8_t byte ;
155
+ uint16_t word ;
156
156
istream *is = this ->is ;
157
157
LinearExecutable *le = this ->le .get ();
158
158
@@ -174,19 +174,53 @@ LinearExecutable::Loader::load_le_header_offset(void)
174
174
return false ;
175
175
}
176
176
177
+ // Offset of relocation table; expected to have high enough value for new exec formats
177
178
is->seekg (0x18 );
178
- if (!read_u8 (is, &byte ))
179
+ if (!read_le (is, &word ))
179
180
return false ;
180
181
181
- if (byte < 0x40 )
182
+ // New executable info block starts at 0x1C, and has an offset to NE header within
183
+ is->seekg (0x3c );
184
+ if (!read_le (is, &this ->header_offset ))
185
+ return false ;
186
+
187
+ // If there is no new exe header offset, we may still have LE with an embedded extender
188
+ if (word < 0x40 )
189
+ {
190
+ char str[0x1000 ];
191
+ static char le_signature[] = " LE\0\0\0\0 " ;
192
+ is->seekg (0x240 );
193
+ is->read (str, 0x100 );
194
+ if (std::string (str, str+0x100 ).find (" DOS/4G " ) != std::string::npos)
195
+ {
196
+ size_t pos;
197
+ std::string signature_str (le_signature, le_signature+sizeof (le_signature));
198
+ cerr << " Embedded DOS/4G identified\n " ;
199
+ // Search for the LE head
200
+ is->seekg (0x29000 );
201
+ is->read (str, 0x1000 );
202
+ pos = std::string (str, str+0x1000 ).find (signature_str);
203
+ if (pos != std::string::npos && (pos & 3 ) == 0 )
204
+ {
205
+ this ->header_offset = 0x29000 + pos;
206
+ return true ;
207
+ }
208
+ cerr << " Not a LE executable, no signature found at expected offset range." << std::endl;
209
+ return false ;
210
+ }
211
+ }
212
+
213
+ if (word < 0x40 )
182
214
{
183
- cerr << " Not a LE executable, at offset 0x18: expected 0x40 or more, got 0x" << std::hex << ( int )byte << std::endl;
215
+ cerr << " Not a LE executable, at offset 0x18: expected 0x40 or more, got 0x" << std::hex << word << " . " << std::endl;
184
216
return false ;
185
217
}
186
218
187
- is->seekg (0x3c );
188
- if (!read_le (is, &this ->header_offset ))
189
- return false ;
219
+ if (this ->header_offset == 0 )
220
+ {
221
+ cerr << " Not a LE executable, at offset 0x3c: new executable header offset is zero." << std::endl;
222
+ return false ;
223
+ }
190
224
191
225
return true ;
192
226
}
0 commit comments