diff --git a/libr/bin/format/ne/ne.c b/libr/bin/format/ne/ne.c index d26860b26f6f2..210fe036925f6 100644 --- a/libr/bin/format/ne/ne.c +++ b/libr/bin/format/ne/ne.c @@ -1,4 +1,4 @@ -/* radare - LGPL - Copyright 2019 - GustavoLCR */ +/* radare - LGPL - Copyright 2019-2022 - GustavoLCR */ #include "ne.h" @@ -83,10 +83,10 @@ RList *r_bin_ne_get_segments(r_bin_ne_obj_t *bin) { RList *segments = r_list_newf (free); for (i = 0; i < bin->ne_header->SegCount; i++) { RBinSection *bs = R_NEW0 (RBinSection); - NE_image_segment_entry *se = &bin->segment_entries[i]; if (!bs) { return segments; } + NE_image_segment_entry *se = &bin->segment_entries[i]; bs->size = se->length; bs->vsize = se->minAllocSz ? se->minAllocSz : 64000; bs->bits = R_SYS_BITS_16; @@ -425,7 +425,7 @@ RList *r_bin_ne_get_relocs(r_bin_ne_obj_t *bin) { return NULL; } - ut16 *modref = malloc (bin->ne_header->ModRefs * sizeof (ut16)); + ut16 *modref = calloc (bin->ne_header->ModRefs, sizeof (ut16)); if (!modref) { return NULL; } @@ -451,7 +451,8 @@ RList *r_bin_ne_get_relocs(r_bin_ne_obj_t *bin) { continue; } off += 2; - while (off < start + length * sizeof (NE_image_reloc_item)) { + size_t buf_size = r_buf_size (bin->buf); + while (off < start + length * sizeof (NE_image_reloc_item) && off < buf_size) { RBinReloc *reloc = R_NEW0 (RBinReloc); if (!reloc) { return NULL; @@ -484,10 +485,11 @@ RList *r_bin_ne_get_relocs(r_bin_ne_obj_t *bin) { break; } char *name; - if (rel.index > bin->ne_header->ModRefs) { + if (rel.index < 1 || rel.index > bin->ne_header->ModRefs) { name = r_str_newf ("UnknownModule%d_%x", rel.index, off); // ???? } else { - offset = modref[rel.index - 1] + bin->header_offset + bin->ne_header->ImportNameTable; + int index = rel.index; + offset = modref[index - 1] + bin->header_offset + bin->ne_header->ImportNameTable; name = __read_nonnull_str_at (bin->buf, offset); } if (rel.flags & IMPORTED_ORD) { @@ -563,7 +565,14 @@ void __init(RBuffer *buf, r_bin_ne_obj_t *bin) { return; } bin->buf = buf; + // XXX this is endian unsafe r_buf_read_at (buf, bin->header_offset, (ut8 *)bin->ne_header, sizeof (NE_image_header)); + if (bin->ne_header->FileAlnSzShftCnt > 8) { + bin->ne_header->FileAlnSzShftCnt = 8; + } + if (bin->ne_header->ModRefs * sizeof (ut16) >= r_buf_size (bin->buf)) { + bin->ne_header->ModRefs = r_buf_size (bin->buf) / sizeof (ut16); + } bin->alignment = 1 << bin->ne_header->FileAlnSzShftCnt; if (!bin->alignment) { bin->alignment = 1 << 9; @@ -571,8 +580,16 @@ void __init(RBuffer *buf, r_bin_ne_obj_t *bin) { bin->os = __get_target_os (bin); ut16 offset = bin->ne_header->SegTableOffset + bin->header_offset; - ut16 size = bin->ne_header->SegCount * sizeof (NE_image_segment_entry); + size_t size = bin->ne_header->SegCount * sizeof (NE_image_segment_entry); + if (offset >= r_buf_size (bin->buf)) { + return; + } + size_t remaining = r_buf_size (bin->buf) - offset; + size = R_MIN (remaining, size); bin->segment_entries = calloc (1, size); + if (size >= remaining) { + bin->ne_header->SegCount = size / sizeof (NE_image_segment_entry); + } if (!bin->segment_entries) { return; }