Use 'offsetof' to resolve undefined behavior (#142)

* Use 'offsetof' to resolve undefined behavior

../pe-parser-library/src/parse.cpp:1821:7: runtime error: member access
within null pointer of type 'typeof (curEnt)' (aka
'peparse::import_dir_entry')

* Fix bad rename
This commit is contained in:
Eric Kilmer 2020-11-26 12:49:19 -05:00 committed by GitHub
parent 68297aff83
commit d38c7daa7e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 40 additions and 42 deletions

View File

@ -28,10 +28,6 @@ THE SOFTWARE.
#include <string> #include <string>
#include <vector> #include <vector>
#define _offset(t, f) \
static_cast<std::uint32_t>( \
reinterpret_cast<std::ptrdiff_t>(&static_cast<t *>(nullptr)->f))
// need to pack these structure definitions // need to pack these structure definitions
// some constant definitions // some constant definitions

View File

@ -40,28 +40,28 @@ THE SOFTWARE.
err_loc.assign(__func__); \ err_loc.assign(__func__); \
err_loc += ":" + to_string<std::uint32_t>(__LINE__, std::dec); err_loc += ":" + to_string<std::uint32_t>(__LINE__, std::dec);
#define READ_WORD(b, o, inst, member) \ #define READ_WORD(b, o, inst, member) \
if (!readWord(b, o + _offset(__typeof__(inst), member), inst.member)) { \ if (!readWord(b, o + offsetof(__typeof__(inst), member), inst.member)) { \
PE_ERR(PEERR_READ); \
return false; \
}
#define READ_DWORD(b, o, inst, member) \
if (!readDword(b, o + _offset(__typeof__(inst), member), inst.member)) { \
PE_ERR(PEERR_READ); \ PE_ERR(PEERR_READ); \
return false; \ return false; \
} }
#define READ_QWORD(b, o, inst, member) \ #define READ_DWORD(b, o, inst, member) \
if (!readQword(b, o + _offset(__typeof__(inst), member), inst.member)) { \ if (!readDword(b, o + offsetof(__typeof__(inst), member), inst.member)) { \
PE_ERR(PEERR_READ); \ PE_ERR(PEERR_READ); \
return false; \ return false; \
} }
#define READ_BYTE(b, o, inst, member) \ #define READ_QWORD(b, o, inst, member) \
if (!readByte(b, o + _offset(__typeof__(inst), member), inst.member)) { \ if (!readQword(b, o + offsetof(__typeof__(inst), member), inst.member)) { \
PE_ERR(PEERR_READ); \ PE_ERR(PEERR_READ); \
return false; \ return false; \
}
#define READ_BYTE(b, o, inst, member) \
if (!readByte(b, o + offsetof(__typeof__(inst), member), inst.member)) { \
PE_ERR(PEERR_READ); \
return false; \
} }
#define TEST_MACHINE_CHARACTERISTICS(h, m, ch) \ #define TEST_MACHINE_CHARACTERISTICS(h, m, ch) \

View File

@ -671,7 +671,7 @@ bool parse_resource_table(bounded_buffer *sectionData,
rde = new resource_dir_entry; rde = new resource_dir_entry;
} }
if (!readDword(sectionData, o + _offset(__typeof__(*rde), ID), rde->ID)) { if (!readDword(sectionData, o + offsetof(__typeof__(*rde), ID), rde->ID)) {
PE_ERR(PEERR_READ); PE_ERR(PEERR_READ);
if (dirent == nullptr) { if (dirent == nullptr) {
delete rde; delete rde;
@ -679,7 +679,8 @@ bool parse_resource_table(bounded_buffer *sectionData,
return false; return false;
} }
if (!readDword(sectionData, o + _offset(__typeof__(*rde), RVA), rde->RVA)) { if (!readDword(
sectionData, o + offsetof(__typeof__(*rde), RVA), rde->RVA)) {
PE_ERR(PEERR_READ); PE_ERR(PEERR_READ);
if (dirent == nullptr) { if (dirent == nullptr) {
delete rde; delete rde;
@ -760,7 +761,7 @@ bool parse_resource_table(bounded_buffer *sectionData,
*/ */
if (!readDword(sectionData, if (!readDword(sectionData,
rde->RVA + _offset(__typeof__(rdat), RVA), rde->RVA + offsetof(__typeof__(rdat), RVA),
rdat.RVA)) { rdat.RVA)) {
PE_ERR(PEERR_READ); PE_ERR(PEERR_READ);
if (dirent == nullptr) { if (dirent == nullptr) {
@ -770,7 +771,7 @@ bool parse_resource_table(bounded_buffer *sectionData,
} }
if (!readDword(sectionData, if (!readDword(sectionData,
rde->RVA + _offset(__typeof__(rdat), size), rde->RVA + offsetof(__typeof__(rdat), size),
rdat.size)) { rdat.size)) {
PE_ERR(PEERR_READ); PE_ERR(PEERR_READ);
if (dirent == nullptr) { if (dirent == nullptr) {
@ -780,7 +781,7 @@ bool parse_resource_table(bounded_buffer *sectionData,
} }
if (!readDword(sectionData, if (!readDword(sectionData,
rde->RVA + _offset(__typeof__(rdat), codepage), rde->RVA + offsetof(__typeof__(rdat), codepage),
rdat.codepage)) { rdat.codepage)) {
PE_ERR(PEERR_READ); PE_ERR(PEERR_READ);
if (dirent == nullptr) { if (dirent == nullptr) {
@ -790,7 +791,7 @@ bool parse_resource_table(bounded_buffer *sectionData,
} }
if (!readDword(sectionData, if (!readDword(sectionData,
rde->RVA + _offset(__typeof__(rdat), reserved), rde->RVA + offsetof(__typeof__(rdat), reserved),
rdat.reserved)) { rdat.reserved)) {
PE_ERR(PEERR_READ); PE_ERR(PEERR_READ);
if (dirent == nullptr) { if (dirent == nullptr) {
@ -994,15 +995,15 @@ bool readOptionalHeader(bounded_buffer *b, optional_header_32 &header) {
for (std::uint32_t i = 0; i < header.NumberOfRvaAndSizes; i++) { for (std::uint32_t i = 0; i < header.NumberOfRvaAndSizes; i++) {
std::uint32_t c = (i * sizeof(data_directory)); std::uint32_t c = (i * sizeof(data_directory));
c += _offset(optional_header_32, DataDirectory[0]); c += offsetof(optional_header_32, DataDirectory[0]);
std::uint32_t o; std::uint32_t o;
o = c + _offset(data_directory, VirtualAddress); o = c + offsetof(data_directory, VirtualAddress);
if (!readDword(b, o, header.DataDirectory[i].VirtualAddress)) { if (!readDword(b, o, header.DataDirectory[i].VirtualAddress)) {
return false; return false;
} }
o = c + _offset(data_directory, Size); o = c + offsetof(data_directory, Size);
if (!readDword(b, o, header.DataDirectory[i].Size)) { if (!readDword(b, o, header.DataDirectory[i].Size)) {
return false; return false;
} }
@ -1049,15 +1050,15 @@ bool readOptionalHeader64(bounded_buffer *b, optional_header_64 &header) {
for (std::uint32_t i = 0; i < header.NumberOfRvaAndSizes; i++) { for (std::uint32_t i = 0; i < header.NumberOfRvaAndSizes; i++) {
std::uint32_t c = (i * sizeof(data_directory)); std::uint32_t c = (i * sizeof(data_directory));
c += _offset(optional_header_64, DataDirectory[0]); c += offsetof(optional_header_64, DataDirectory[0]);
std::uint32_t o; std::uint32_t o;
o = c + _offset(data_directory, VirtualAddress); o = c + offsetof(data_directory, VirtualAddress);
if (!readDword(b, o, header.DataDirectory[i].VirtualAddress)) { if (!readDword(b, o, header.DataDirectory[i].VirtualAddress)) {
return false; return false;
} }
o = c + _offset(data_directory, Size); o = c + offsetof(data_directory, Size);
if (!readDword(b, o, header.DataDirectory[i].Size)) { if (!readDword(b, o, header.DataDirectory[i].Size)) {
return false; return false;
} }
@ -1092,7 +1093,7 @@ bool readNtHeader(bounded_buffer *b, nt_header_32 &header) {
header.Signature = pe_magic; header.Signature = pe_magic;
bounded_buffer *fhb = bounded_buffer *fhb =
splitBuffer(b, _offset(nt_header_32, FileHeader), b->bufLen); splitBuffer(b, offsetof(nt_header_32, FileHeader), b->bufLen);
if (fhb == nullptr) { if (fhb == nullptr) {
PE_ERR(PEERR_MEM); PE_ERR(PEERR_MEM);
@ -1131,7 +1132,7 @@ bool readNtHeader(bounded_buffer *b, nt_header_32 &header) {
* buffer regardless. * buffer regardless.
*/ */
bounded_buffer *ohb = bounded_buffer *ohb =
splitBuffer(b, _offset(nt_header_32, OptionalHeader), b->bufLen); splitBuffer(b, offsetof(nt_header_32, OptionalHeader), b->bufLen);
if (ohb == nullptr) { if (ohb == nullptr) {
deleteBuffer(fhb); deleteBuffer(fhb);
@ -1489,7 +1490,7 @@ bool getExports(parsed_pe *p) {
// get the name of this module // get the name of this module
std::uint32_t nameRva; std::uint32_t nameRva;
if (!readDword(s.sectionData, if (!readDword(s.sectionData,
rvaofft + _offset(export_dir_table, NameRVA), rvaofft + offsetof(export_dir_table, NameRVA),
nameRva)) { nameRva)) {
return false; return false;
} }
@ -1517,7 +1518,7 @@ bool getExports(parsed_pe *p) {
// now, get all the named export symbols // now, get all the named export symbols
std::uint32_t numNames; std::uint32_t numNames;
if (!readDword(s.sectionData, if (!readDword(s.sectionData,
rvaofft + _offset(export_dir_table, NumberOfNamePointers), rvaofft + offsetof(export_dir_table, NumberOfNamePointers),
numNames)) { numNames)) {
return false; return false;
} }
@ -1526,7 +1527,7 @@ bool getExports(parsed_pe *p) {
// get the names section // get the names section
std::uint32_t namesRVA; std::uint32_t namesRVA;
if (!readDword(s.sectionData, if (!readDword(s.sectionData,
rvaofft + _offset(export_dir_table, NamePointerRVA), rvaofft + offsetof(export_dir_table, NamePointerRVA),
namesRVA)) { namesRVA)) {
return false; return false;
} }
@ -1551,7 +1552,8 @@ bool getExports(parsed_pe *p) {
// get the EAT section // get the EAT section
std::uint32_t eatRVA; std::uint32_t eatRVA;
if (!readDword(s.sectionData, if (!readDword(s.sectionData,
rvaofft + _offset(export_dir_table, ExportAddressTableRVA), rvaofft +
offsetof(export_dir_table, ExportAddressTableRVA),
eatRVA)) { eatRVA)) {
return false; return false;
} }
@ -1575,7 +1577,7 @@ bool getExports(parsed_pe *p) {
// get the ordinal base // get the ordinal base
std::uint32_t ordinalBase; std::uint32_t ordinalBase;
if (!readDword(s.sectionData, if (!readDword(s.sectionData,
rvaofft + _offset(export_dir_table, OrdinalBase), rvaofft + offsetof(export_dir_table, OrdinalBase),
ordinalBase)) { ordinalBase)) {
return false; return false;
} }
@ -1583,7 +1585,7 @@ bool getExports(parsed_pe *p) {
// get the ordinal table // get the ordinal table
std::uint32_t ordinalTableRVA; std::uint32_t ordinalTableRVA;
if (!readDword(s.sectionData, if (!readDword(s.sectionData,
rvaofft + _offset(export_dir_table, OrdinalTableRVA), rvaofft + offsetof(export_dir_table, OrdinalTableRVA),
ordinalTableRVA)) { ordinalTableRVA)) {
return false; return false;
} }
@ -1726,13 +1728,13 @@ bool getRelocations(parsed_pe *p) {
std::uint32_t blockSize; std::uint32_t blockSize;
if (!readDword(d.sectionData, if (!readDword(d.sectionData,
rvaofft + _offset(reloc_block, PageRVA), rvaofft + offsetof(reloc_block, PageRVA),
pageRva)) { pageRva)) {
return false; return false;
} }
if (!readDword(d.sectionData, if (!readDword(d.sectionData,
rvaofft + _offset(reloc_block, BlockSize), rvaofft + offsetof(reloc_block, BlockSize),
blockSize)) { blockSize)) {
return false; return false;
} }