parse: Fix DIR_SECURITY data directory retrieval (#122)

* parse: Fix DIR_SECURITY data directory retrieval

Fixes #121.

* parse: Fix variables

* parse: Add MSDN link for DIR_SECURITY special case
This commit is contained in:
William Woodruff 2020-03-30 10:04:57 -04:00 committed by GitHub
parent c0208d643f
commit 2bf8ad917e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -2655,20 +2655,37 @@ bool GetDataDirectoryEntry(parsed_pe *pe,
return false;
}
section sec;
if (!getSecForVA(pe->internal->secs, addr, sec)) {
PE_ERR(PEERR_SECTVA);
return false;
}
/* NOTE(ww): DIR_SECURITY is an annoying special case: its contents
* are never mapped into memory, so its "RVA" is actually a direct
* file offset.
* See:
* https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#the-attribute-certificate-table-image-only
*/
if (dirnum == DIR_SECURITY) {
auto *buf = splitBuffer(
pe->fileBuffer, dir.VirtualAddress, dir.VirtualAddress + dir.Size);
if (buf == nullptr) {
PE_ERR(PEERR_SIZE);
return false;
}
auto off = static_cast<std::uint32_t>(addr - sec.sectionBase);
if (off + dir.Size >= sec.sectionData->bufLen) {
PE_ERR(PEERR_SIZE);
return false;
}
raw_entry.assign(buf->buf, buf->buf + buf->bufLen);
} else {
section sec;
if (!getSecForVA(pe->internal->secs, addr, sec)) {
PE_ERR(PEERR_SECTVA);
return false;
}
raw_entry.assign(sec.sectionData->buf + off,
sec.sectionData->buf + off + dir.Size);
auto off = static_cast<std::uint32_t>(addr - sec.sectionBase);
if (off + dir.Size >= sec.sectionData->bufLen) {
PE_ERR(PEERR_SIZE);
return false;
}
raw_entry.assign(sec.sectionData->buf + off,
sec.sectionData->buf + off + dir.Size);
}
return true;
}