提问人:smellyourbooks 提问时间:6/22/2023 最后编辑:chqrliesmellyourbooks 更新时间:6/22/2023 访问量:55
内部 realloc() 上的未定义行为
Undefined Behavior on inner realloc()
问:
我正在尝试编写一个 PE 解析器,我的程序包含两个循环,如下所示:
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));
}
我可以执行多次外部循环,它总是会给我正确的输出。然而,内部循环随机给我正确的答案或通过错误消息退出。n
malloc: Incorrect checksum for freed object
我的代码库无法复制/粘贴,但以下是结构的定义:
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;
我已经缩小了导致内部循环函数错误的行,但我不明白为什么 - 是因为我在重新分配后立即访问数组(但我正在更改索引以便编辑新分配空间的数据而不是其他内容)?realloc()
我试图做的是一次分配一个结构(以节省内存),因为除非在满足特定条件之前读取结构,否则没有其他方法可以知道它们存在多少个。
答:
2赞
chqrlie
6/22/2023
#1
originalFirstThunkArrayIndex
是数组最后一个元素的索引,而不是数组的长度。您应该在循环中使用一个额外的元素进行重新分配:
originalFirstThunkArray = realloc(originalFirstThunkArray,
(originalFirstThunkArrayIndex + 1) *
sizeof(struct _IMAGE_THUNK_DATA64));
请注意,您的标识符很长,使代码难以阅读。
和...i
importDescriptorArray
最后,一个更重要的问题:在外部循环体中本地定义,因此在每次迭代时都会丢失其值。importDescriptorArray
while
评论
1赞
smellyourbooks
6/22/2023
是的,谢谢,我想我们同时意识到了索引错误!而且我错误地将外部 while 循环放入内部 - 为复制/粘贴错误道歉 - 正如您正确指出的那样,这很可能是由于我这边的命名实践不佳。吸取了教训!importDescriptorArray
评论
for
for(size_t i=0; i<n; i++)
old_data = realloc(old_data, new_size);
void *new_data = realloc(old_data, new_size); if (new_data == NULL) { …deal with error… } old_data = new_data; old_size = new_size;