diff --git a/libr/bin/format/pe/pe.c b/libr/bin/format/pe/pe.c index 252f9befde..76780430ef 100644 --- a/libr/bin/format/pe/pe.c +++ b/libr/bin/format/pe/pe.c @@ -411,8 +411,9 @@ static struct r_bin_pe_export_t* parse_symbol_table(struct PE_(r_bin_pe_obj_t)* } else { char *longname, name[128]; ut32 *idx = (ut32 *) (buf+I+4) ; - if (r_buf_read_at (bin->b, off+ *idx+shsz, (ut8*)name, 128)) { + if (r_buf_read_at (bin->b, off+ *idx+shsz, (ut8*)name, 128)) {// == 128) { longname = name; + name[sizeof(name)-1] = 0; D printf ("0x%08"PFMT64x" %s\n", text + sr->value, longname); strncpy ((char*)exp[symctr].name, longname, PE_NAME_LENGTH-1); } else { @@ -542,8 +543,8 @@ static int PE_(r_bin_pe_init_imports)(struct PE_(r_bin_pe_obj_t) *bin) { bin->import_directory = NULL; if (import_dir_paddr != 0) { if (import_dir_size<1 || import_dir_size>maxidsz) { - eprintf ("Warning: Invalid import directory size: 0x%x\n", - import_dir_size); + eprintf ("Warning: Invalid import directory size: 0x%x is now 0x%x\n", + import_dir_size, maxidsz); import_dir_size = maxidsz; } bin->import_directory_offset = import_dir_offset; @@ -1927,13 +1928,28 @@ struct r_bin_pe_import_t* PE_(r_bin_pe_get_imports)(struct PE_(r_bin_pe_obj_t) * if (!bin) return NULL; + if (bin->import_directory_offset+32 >= bin->b->length) { + return NULL; + } if (bin->import_directory_offset < bin->size && bin->import_directory_offset > 0) { + void *last; curr_import_dir = (PE_(image_import_directory)*)(bin->b->buf + bin->import_directory_offset); dll_name_offset = curr_import_dir->Name; - void *last = curr_import_dir + bin->import_directory_size; - while (curr_import_dir->FirstThunk != 0 || curr_import_dir->Name != 0 || + if (bin->import_directory_offset<1) { + return NULL; + } + if (bin->import_directory_size<1) { + return NULL; + } + if (bin->import_directory_offset+bin->import_directory_size > bin->b->length) { + eprintf ("Error: read (import directory too big)\n"); + bin->import_directory_size = bin->b->length - bin->import_directory_offset; + } + last = curr_import_dir + bin->import_directory_size; + while (((void*)curr_import_dir+sizeof (*curr_import_dir)) < last && ( + curr_import_dir->FirstThunk != 0 || curr_import_dir->Name != 0 || curr_import_dir->TimeDateStamp != 0 || curr_import_dir->Characteristics != 0 || - curr_import_dir->ForwarderChain != 0) { + curr_import_dir->ForwarderChain != 0)) { dll_name_offset = curr_import_dir->Name; int rr = r_buf_read_at (bin->b, PE_(r_bin_pe_vaddr_to_paddr)(bin, dll_name_offset), @@ -1944,10 +1960,11 @@ struct r_bin_pe_import_t* PE_(r_bin_pe_get_imports)(struct PE_(r_bin_pe_obj_t) * } if (!PE_(r_bin_pe_parse_imports)(bin, &imports, &nimp, dll_name, curr_import_dir->Characteristics, - curr_import_dir->FirstThunk)) + curr_import_dir->FirstThunk)) { break; + } curr_import_dir++; - if ((void*)curr_import_dir>= last) { + if (curr_import_dir+2 >= last) { break; } } @@ -2008,17 +2025,35 @@ struct r_bin_pe_lib_t* PE_(r_bin_pe_get_libs)(struct PE_(r_bin_pe_obj_t) *bin) { return NULL; } + if (bin->import_directory_offset + bin->import_directory_size > bin->b->length) { + eprintf ("import directory offset bigger than file\n"); +bin->import_directory_size = bin->b->length - bin->import_directory_offset; + return NULL; + } RStrHT *lib_map = r_strht_new(); if (bin->import_directory_offset < bin->size && bin->import_directory_offset > 0) { + void *last = NULL; // normal imports curr_import_dir = (PE_(image_import_directory)*)( bin->b->buf + bin->import_directory_offset); - while (curr_import_dir->FirstThunk != 0 || curr_import_dir->Name != 0 || + if (bin->import_directory_offset+bin->import_directory_size > bin->b->length) { + // chop + bin->import_directory_size = bin->b->length - bin->import_directory_offset; + eprintf ("Warning: read libs (import directory too big) %d %d size %d\n", + bin->import_directory_offset, bin->import_directory_size, bin->b->length); + //return NULL; + } + last = curr_import_dir + bin->import_directory_size; + while ((void*)(curr_import_dir+1) < last && ( + curr_import_dir->FirstThunk != 0 || curr_import_dir->Name != 0 || curr_import_dir->TimeDateStamp != 0 || curr_import_dir->Characteristics != 0 || - curr_import_dir->ForwarderChain != 0) { + curr_import_dir->ForwarderChain != 0)) { name_off = PE_(r_bin_pe_vaddr_to_paddr)(bin, curr_import_dir->Name); len = r_buf_read_at (bin->b, name_off, (ut8*)libs[index].name, PE_STRING_LENGTH); - if (len <2) { // minimum string length + if (libs[index].name[0] == 0) { // minimum string length + break; + } + if (len <2 || libs[index].name[0] == 0) { // minimum string length eprintf ("Error: read (libs - import dirs) %d\n", len); break; } @@ -2038,6 +2073,10 @@ struct r_bin_pe_lib_t* PE_(r_bin_pe_get_libs)(struct PE_(r_bin_pe_obj_t) *bin) { } } curr_import_dir++; + if ((void*)curr_import_dir >= last) { + eprintf ("eof in imports dir\n"); + break; + } } } diff --git a/libr/core/bin.c b/libr/core/bin.c index 4964157a40..649e2274b9 100644 --- a/libr/core/bin.c +++ b/libr/core/bin.c @@ -1551,7 +1551,13 @@ static int bin_libs (RCore *r, int mode) { r_cons_printf ("%s\n", lib); i++; } - if (!mode) r_cons_printf ("\n%i libraries\n", i); + if (!mode) { + if (i==1) { + r_cons_printf ("\n%i library\n", i); + } else { + r_cons_printf ("\n%i libraries\n", i); + } + } } return R_TRUE; }