Skip to content

Commit c9f7cc6

Browse files
committed
le: Rudimentary support of files with embedded extender
1 parent 14d1c35 commit c9f7cc6

File tree

1 file changed

+41
-7
lines changed

1 file changed

+41
-7
lines changed

src/le.cpp

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ bool
152152
LinearExecutable::Loader::load_le_header_offset(void)
153153
{
154154
char id[2];
155-
uint8_t byte;
155+
uint16_t word;
156156
istream *is = this->is;
157157
LinearExecutable *le = this->le.get();
158158

@@ -174,19 +174,53 @@ LinearExecutable::Loader::load_le_header_offset(void)
174174
return false;
175175
}
176176

177+
// Offset of relocation table; expected to have high enough value for new exec formats
177178
is->seekg (0x18);
178-
if (!read_u8 (is, &byte))
179+
if (!read_le (is, &word))
179180
return false;
180181

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)
182214
{
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;
184216
return false;
185217
}
186218

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+
}
190224

191225
return true;
192226
}

0 commit comments

Comments
 (0)