mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-04-17 01:23:51 +00:00
fix: prevent buffer overflows in Warden PE parsing
- Add bounds checks to readLE32/readLE16 — malformed Warden modules could cause out-of-bounds reads on untrusted PE data - Fix unsigned underflow in PE section loading: if rawDataOffset or virtualAddr exceeds buffer size, the subtraction wrapped to a huge uint32_t causing memcpy to read/write far beyond bounds. Now skips the section entirely and uses std::min with pre-validated maxima
This commit is contained in:
parent
b39f0f3605
commit
fe7912b5fa
1 changed files with 11 additions and 5 deletions
|
|
@ -14,12 +14,16 @@
|
|||
namespace wowee {
|
||||
namespace game {
|
||||
|
||||
// Bounds-checked little-endian reads for PE parsing — malformed Warden modules
|
||||
// must not cause out-of-bounds access.
|
||||
static inline uint32_t readLE32(const std::vector<uint8_t>& data, size_t offset) {
|
||||
if (offset + 4 > data.size()) return 0;
|
||||
return data[offset] | (uint32_t(data[offset+1]) << 8)
|
||||
| (uint32_t(data[offset+2]) << 16) | (uint32_t(data[offset+3]) << 24);
|
||||
}
|
||||
|
||||
static inline uint16_t readLE16(const std::vector<uint8_t>& data, size_t offset) {
|
||||
if (offset + 2 > data.size()) return 0;
|
||||
return data[offset] | (uint16_t(data[offset+1]) << 8);
|
||||
}
|
||||
|
||||
|
|
@ -95,12 +99,14 @@ bool WardenMemory::parsePE(const std::vector<uint8_t>& fileData) {
|
|||
|
||||
if (rawDataSize == 0 || rawDataOffset == 0) continue;
|
||||
|
||||
// Clamp copy size to file and image bounds
|
||||
// Clamp copy size to file and image bounds.
|
||||
// Guard against underflow: if offset exceeds buffer size, skip the section
|
||||
// entirely rather than wrapping to a huge uint32_t in the subtraction.
|
||||
if (rawDataOffset >= fileData.size() || virtualAddr >= imageSize_) continue;
|
||||
uint32_t copySize = std::min(rawDataSize, virtualSize);
|
||||
if (rawDataOffset + copySize > fileData.size())
|
||||
copySize = static_cast<uint32_t>(fileData.size()) - rawDataOffset;
|
||||
if (virtualAddr + copySize > imageSize_)
|
||||
copySize = imageSize_ - virtualAddr;
|
||||
uint32_t maxFromFile = static_cast<uint32_t>(fileData.size()) - rawDataOffset;
|
||||
uint32_t maxFromImage = imageSize_ - virtualAddr;
|
||||
copySize = std::min({copySize, maxFromFile, maxFromImage});
|
||||
|
||||
std::memcpy(image_.data() + virtualAddr, fileData.data() + rawDataOffset, copySize);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue