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.
>Solution :
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.