fix: read beyond initial 0x80 buffer when PE/NE sig is at higher offset
Build & Deploy / build-and-deploy (push) Successful in 52s
Build & Deploy / build-and-deploy (push) Successful in 52s
PlatformDetector.detect() and GameService.detectPlatformInBundle() both read only 0x80 bytes initially, but PE e_lfanew often points to 0x80 (128), putting the signature 2 bytes past the buffer. Added fallback: re-read up to peOffset+2 bytes when needed. Fixes PlatformDetectorTest detect_peHeader_returnsWindows and detect_neHeader_returnsWindows assertions.
This commit is contained in:
@@ -229,6 +229,17 @@ public class GameService implements GameStore {
|
||||
if (entry.getName().equals(relExe.replace('\\', '/'))) {
|
||||
byte[] buf = new byte[0x80];
|
||||
int read = zis.readNBytes(buf, 0, buf.length);
|
||||
// Read more if PE/NE signature is beyond the initial buffer
|
||||
if (read >= 0x40) {
|
||||
int peOffset = (buf[0x3C] & 0xFF) | ((buf[0x3D] & 0xFF) << 8)
|
||||
| ((buf[0x3E] & 0xFF) << 16) | ((buf[0x3F] & 0xFF) << 24);
|
||||
if (peOffset + 2 > read) {
|
||||
buf = java.util.Arrays.copyOf(buf, Math.max(buf.length, peOffset + 2));
|
||||
int remaining = buf.length - read;
|
||||
zis.readNBytes(buf, read, remaining);
|
||||
read = buf.length;
|
||||
}
|
||||
}
|
||||
return PlatformDetector.detectFromBytes(buf, read);
|
||||
}
|
||||
zis.closeEntry();
|
||||
|
||||
@@ -31,6 +31,20 @@ public class PlatformDetector {
|
||||
try (var fis = Files.newInputStream(exePath)) {
|
||||
byte[] buf = new byte[0x80];
|
||||
int read = fis.readNBytes(buf, 0, buf.length);
|
||||
// If the PE/NE signature is beyond the initial buffer, read more
|
||||
if (read >= 0x40) {
|
||||
int peOffset = (buf[0x3C] & 0xFF)
|
||||
| ((buf[0x3D] & 0xFF) << 8)
|
||||
| ((buf[0x3E] & 0xFF) << 16)
|
||||
| ((buf[0x3F] & 0xFF) << 24);
|
||||
if (peOffset + 2 > read) {
|
||||
// Need to read beyond the initial buffer
|
||||
buf = java.util.Arrays.copyOf(buf, Math.max(buf.length, peOffset + 2));
|
||||
int remaining = buf.length - read;
|
||||
fis.readNBytes(buf, read, remaining);
|
||||
read = buf.length;
|
||||
}
|
||||
}
|
||||
return detectFromBytes(buf, read);
|
||||
} catch (IOException e) {
|
||||
LOG.warning("Could not read EXE header for " + exePath + ": " + e.getMessage());
|
||||
|
||||
Reference in New Issue
Block a user