I'm attempting to write a PE parser, and my program contains two loops as shown below:
size_t i = 0;
while (condition_1) {
struct _IMAGE_IMPORT_DESCRIPTOR64 *importDescriptorArray = malloc(sizeof(struct _IMAGE_IMPORT_DESCRIPTOR64));
struct _IMAGE_THUNK_DATA64 *originalFirstThunkArray = malloc(sizeof(struct _IMAGE_THUNK_DATA64));
size_t originalFirstThunkArrayIndex = 0;
originalFirstThunkArray[originalFirstThunkArrayIndex].u1.ordinal = some_value; //set to a computed value
while (condition_2) {
originalFirstThunkArrayIndex++;
originalFirstThunkArray = realloc(originalFirstThunkArray, originalFirstThunkArrayIndex * sizeof(struct _IMAGE_THUNK_DATA64));
originalFirstThunkArrayOffset += sizeof(QWORD); //each element has its address stored as a QWORD, so I have to iterate QWORD-at-a-time.
originalFirstThunkArray[originalFirstThunkArrayIndex].u1.ordinal = reverse_endianess_u_int64_t(readQWord(file, originalFirstThunkArrayOffset, QWORD_Buffer));
}
i++;
importDescriptorArray = realloc(importDescriptorArray, i * sizeof(struct _IMAGE_IMPORT_DESCRIPTOR64));
}
I can execute the outer loop n
number of times and it will always give me the correct output. The inner loop however, randomly gives me correct answers or exits via a malloc: Incorrect checksum for freed object
error message.
My codebase is beyond copy/pasting, but here are the definitions of the structures:
struct _IMAGE_IMPORT_DESCRIPTOR64 {
union {
DWORD Characteristics;
IMAGE_THUNK_DATA32 OriginalFirstThunk;
} u;
DWORD timeDateStamp;
DWORD forwarderChain;
DWORD name;
IMAGE_THUNK_DATA32 FirstThunk;
} IMAGE_IMPORT_DESCRIPTOR64;
typedef struct _IMAGE_THUNK_DATA64 {
union {
QWORD forwarderString;
QWORD function;
QWORD ordinal;
QWORD addressOfData;
} u1;
} IMAGE_THUNK_DATA64;
I've narrowed down the line causing the error to the realloc()
function of the inner loop, but I fail to understand why - is it because I'm accessing the array immediately after reallocation (but I am changing the index so that I edit data of the newly allocated space and not something else)?
What I am trying to do is allocate a single struct at a time (in order to conserve memory) because unless the structures are read until a certain condition is met, there is no other way to know how many of them exist.
originalFirstThunkArrayIndex
is the index to the last element of the array, not the length of the array. You should reallocate with one extra element in the loop:
originalFirstThunkArray = realloc(originalFirstThunkArray,
(originalFirstThunkArrayIndex + 1) *
sizeof(struct _IMAGE_THUNK_DATA64));
Note that your identifiers are very long, making the code hard to read.
There is a similar problem for i
and importDescriptorArray
...
Finally a more important problem: importDescriptorArray
is defined locally in the outer while
loop body, so its value is lost at each iteration.