Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Undefined Behavior on inner realloc()

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:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading