Fix several segfaults found by matalaz in PE, MACH0 and COFF

This commit is contained in:
pancake 2014-05-23 14:34:27 +02:00
parent 13d0c246eb
commit 98d33eb084
5 changed files with 87 additions and 31 deletions

View File

@ -156,7 +156,8 @@ R_API char *r_bin_demangle_objc(RBinFile *binfile, const char *sym) {
}
if (type) {
if (!strcmp (type, "field")) {
ret = malloc (strlen (clas)+strlen (name)+32);
int namelen = name?strlen (name):0;
ret = malloc (strlen (clas)+namelen+32);
if (ret) sprintf (ret, "field int %s::%s", clas, name);
} else {
if (nargs) {

View File

@ -200,7 +200,6 @@ static int r_bin_coff_init_symtable(struct r_bin_coff_obj *obj)
for (i = 0; i < obj->hdr.symbols_num; i++) {
r_mem_copyendian((ut8*)&short_name, obj->b->buf + offset,
sizeof(ut32), obj->endian);
if (short_name) {
obj->symbols[i].name = malloc(sizeof(char) * 9);
strncpy(obj->symbols[i].name,
@ -209,9 +208,12 @@ static int r_bin_coff_init_symtable(struct r_bin_coff_obj *obj)
offset += 8;
} else {
offset += sizeof(ut32);
r_mem_copyendian((ut8*)&ofst, obj->b->buf + offset,
r_mem_copyendian ((ut8*)&ofst, obj->b->buf + offset,
sizeof(ut32), obj->endian);
if (ofst+obj->hdr.symtable_offset > obj->b->length) {
eprintf ("Symtable offset out of bounds\n");
return 0;
}
obj->symbols[i].name = strdup((char*)(obj->b->buf +
obj->hdr.symtable_offset + ofst +
obj->hdr.symbols_num * 18));

View File

@ -12,6 +12,8 @@ ut64 PE_(r_bin_pe_get_main_vaddr)(struct PE_(r_bin_pe_obj_t) *bin) {
ut64 addr = 0;
ut8 buf[512];
if (!bin || !bin->b)
return 0LL;
// option2: /x 8bff558bec83ec20
buf[367] = 0;
if (r_buf_read_at (bin->b, entry->paddr, buf, sizeof (buf)) == -1) {
@ -56,14 +58,19 @@ static PE_DWord PE_(r_bin_pe_paddr_to_vaddr)(struct PE_(r_bin_pe_obj_t)* bin, PE
#endif
static int PE_(r_bin_pe_get_import_dirs_count)(struct PE_(r_bin_pe_obj_t) *bin) {
if (!bin || !bin->nt_headers)
return 0;
PE_(image_data_directory) *data_dir_import = &bin->nt_headers->optional_header.DataDirectory[PE_IMAGE_DIRECTORY_ENTRY_IMPORT];
return (int)(data_dir_import->Size / sizeof(PE_(image_import_directory)) - 1);
}
static int PE_(r_bin_pe_get_delay_import_dirs_count)(struct PE_(r_bin_pe_obj_t) *bin) {
PE_(image_data_directory) *data_dir_delay_import = \
&bin->nt_headers->optional_header.DataDirectory[PE_IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT];
PE_(image_data_directory) *data_dir_delay_import;
if (!bin || !bin->nt_headers)
return 0;
data_dir_delay_import = \
&bin->nt_headers->optional_header.DataDirectory[PE_IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT];
return (int)(data_dir_delay_import->Size / sizeof(PE_(image_delay_import_directory)) - 1);
}
@ -162,13 +169,11 @@ typedef struct {
static struct r_bin_pe_export_t* parse_symbol_table(struct PE_(r_bin_pe_obj_t)* bin, struct r_bin_pe_export_t *exports, int sz) {
//ut64 baddr = (ut64)bin->nt_headers->optional_header.ImageBase;
ut64 off = bin->nt_headers->file_header.PointerToSymbolTable;
ut64 num = bin->nt_headers->file_header.NumberOfSymbols;
ut64 off, num;
const int srsz = 18; // symbol record size
struct r_bin_pe_section_t* sections;
struct r_bin_pe_export_t* exp;
int bufsz = num * srsz;
int I, i, shsz = bufsz;
int bufsz, I, i, shsz = bufsz;
SymbolRecord *sr;
ut64 text_off = 0LL;
ut64 text_vaddr = 0LL;
@ -177,8 +182,11 @@ static struct r_bin_pe_export_t* parse_symbol_table(struct PE_(r_bin_pe_obj_t)*
int exports_sz;
int symctr = 0;
char *buf;
if (bufsz<1 || bufsz>bin->size)
if (!bin || bufsz<1 || bufsz>bin->size)
return 0;
off = bin->nt_headers->file_header.PointerToSymbolTable;
num = bin->nt_headers->file_header.NumberOfSymbols;
shsz = bufsz = num * srsz;
buf = malloc (bufsz);
if (!buf)
return 0;
@ -510,6 +518,8 @@ static int PE_(r_bin_pe_init)(struct PE_(r_bin_pe_obj_t)* bin) {
char* PE_(r_bin_pe_get_arch)(struct PE_(r_bin_pe_obj_t)* bin) {
char *arch;
if (!bin || !bin->nt_headers)
return strdup ("x86");
switch (bin->nt_headers->file_header.Machine) {
case PE_IMAGE_FILE_MACHINE_ALPHA:
case PE_IMAGE_FILE_MACHINE_ALPHA64:
@ -543,6 +553,8 @@ char* PE_(r_bin_pe_get_arch)(struct PE_(r_bin_pe_obj_t)* bin) {
struct r_bin_pe_addr_t* PE_(r_bin_pe_get_entrypoint)(struct PE_(r_bin_pe_obj_t)* bin) {
struct r_bin_pe_addr_t *entry = NULL;
if (!bin || !bin->nt_headers)
return NULL;
if ((entry = malloc(sizeof(struct r_bin_pe_addr_t))) == NULL) {
perror("malloc (entrypoint)");
return NULL;
@ -560,12 +572,18 @@ struct r_bin_pe_export_t* PE_(r_bin_pe_get_exports)(struct PE_(r_bin_pe_obj_t)*
PE_VWord functions_paddr, names_paddr, ordinals_paddr, function_vaddr, name_vaddr, name_paddr;
char function_name[PE_NAME_LENGTH + 1], forwarder_name[PE_NAME_LENGTH + 1];
char dll_name[PE_NAME_LENGTH + 1], export_name[PE_NAME_LENGTH + 1];
PE_(image_data_directory) *data_dir_export = \
&bin->nt_headers->optional_header.DataDirectory[PE_IMAGE_DIRECTORY_ENTRY_EXPORT];
PE_VWord export_dir_vaddr = data_dir_export->VirtualAddress;
int i, export_dir_size = data_dir_export->Size;
PE_(image_data_directory) *data_dir_export;
PE_VWord export_dir_vaddr ;
int i, export_dir_size;
int exports_sz = 0;
if (!bin || !bin->nt_headers)
return NULL;
data_dir_export = \
&bin->nt_headers->optional_header.DataDirectory[PE_IMAGE_DIRECTORY_ENTRY_EXPORT];
export_dir_vaddr = data_dir_export->VirtualAddress;
export_dir_size = data_dir_export->Size;
if (bin->export_directory) {
exports_sz = (bin->export_directory->NumberOfNames + 1) * sizeof(struct r_bin_pe_export_t);
if (!(exports = malloc (exports_sz)))
@ -633,6 +651,8 @@ int PE_(r_bin_pe_get_file_alignment)(struct PE_(r_bin_pe_obj_t)* bin) {
}
ut64 PE_(r_bin_pe_get_image_base)(struct PE_(r_bin_pe_obj_t)* bin) {
if (!bin || !bin->nt_headers)
return 0LL;
return (ut64)bin->nt_headers->optional_header.ImageBase;
}
@ -683,6 +703,8 @@ struct r_bin_pe_lib_t* PE_(r_bin_pe_get_libs)(struct PE_(r_bin_pe_obj_t) *bin) {
int delay_import_dirs_count = PE_(r_bin_pe_get_delay_import_dirs_count)(bin);
int mallocsz, i, j = 0;
if (!bin)
return NULL;
/* NOTE: import_dirs and delay_import_dirs can be -1 */
mallocsz = (import_dirs_count + delay_import_dirs_count + 3) * \
sizeof (struct r_bin_pe_lib_t);
@ -737,6 +759,8 @@ int PE_(r_bin_pe_get_image_size)(struct PE_(r_bin_pe_obj_t)* bin) {
char* PE_(r_bin_pe_get_machine)(struct PE_(r_bin_pe_obj_t)* bin) {
char *machine;
if (!bin || !bin->nt_headers)
return NULL;
switch (bin->nt_headers->file_header.Machine) {
case PE_IMAGE_FILE_MACHINE_ALPHA:
machine = strdup("Alpha");
@ -831,7 +855,8 @@ char* PE_(r_bin_pe_get_machine)(struct PE_(r_bin_pe_obj_t)* bin) {
// TODO: make it const! like in elf
char* PE_(r_bin_pe_get_os)(struct PE_(r_bin_pe_obj_t)* bin) {
char *os;
if (!bin || !bin->nt_headers)
return NULL;
switch (bin->nt_headers->optional_header.Subsystem) {
case PE_IMAGE_SUBSYSTEM_NATIVE:
os = strdup("native");
@ -863,23 +888,23 @@ char* PE_(r_bin_pe_get_os)(struct PE_(r_bin_pe_obj_t)* bin) {
// TODO: make it const
char* PE_(r_bin_pe_get_class)(struct PE_(r_bin_pe_obj_t)* bin) {
char *class;
if (!bin || !bin->nt_headers)
return NULL;
switch (bin->nt_headers->optional_header.Magic) {
case PE_IMAGE_FILE_TYPE_PE32:
class = strdup("PE32");
break;
return strdup("PE32");
case PE_IMAGE_FILE_TYPE_PE32PLUS:
class = strdup("PE32+");
break;
return strdup("PE32+");
default:
class = strdup("Unknown");
return strdup("Unknown");
}
return class;
return NULL;
}
int PE_(r_bin_pe_get_bits)(struct PE_(r_bin_pe_obj_t)* bin) {
int bits;
if (!bin || !bin->nt_headers)
return 32;
switch (bin->nt_headers->optional_header.Magic) {
case PE_IMAGE_FILE_TYPE_PE32:
bits = 32;
@ -894,14 +919,20 @@ int PE_(r_bin_pe_get_bits)(struct PE_(r_bin_pe_obj_t)* bin) {
}
int PE_(r_bin_pe_get_section_alignment)(struct PE_(r_bin_pe_obj_t)* bin) {
if (!bin || !bin->nt_headers)
return 0;
return bin->nt_headers->optional_header.SectionAlignment;
}
struct r_bin_pe_section_t* PE_(r_bin_pe_get_sections)(struct PE_(r_bin_pe_obj_t)* bin) {
struct r_bin_pe_section_t *sections = NULL;
PE_(image_section_header) *shdr = bin->section_header;
int i, sections_count = bin->nt_headers->file_header.NumberOfSections;
PE_(image_section_header) *shdr;
int i, sections_count;
if (!bin || !bin->nt_headers)
return 0;
shdr = bin->section_header;
sections_count = bin->nt_headers->file_header.NumberOfSections;
if ((sections = malloc ((sections_count + 1) * sizeof (struct r_bin_pe_section_t))) == NULL) {
perror ("malloc (sections)");
return NULL;
@ -922,7 +953,8 @@ struct r_bin_pe_section_t* PE_(r_bin_pe_get_sections)(struct PE_(r_bin_pe_obj_t)
char* PE_(r_bin_pe_get_subsystem)(struct PE_(r_bin_pe_obj_t)* bin) {
char *subsystem;
if (!bin || !bin->nt_headers)
return NULL;
switch (bin->nt_headers->optional_header.Subsystem) {
case PE_IMAGE_SUBSYSTEM_NATIVE:
subsystem = strdup("Native");
@ -961,10 +993,14 @@ char* PE_(r_bin_pe_get_subsystem)(struct PE_(r_bin_pe_obj_t)* bin) {
}
int PE_(r_bin_pe_is_dll)(struct PE_(r_bin_pe_obj_t)* bin) {
if (!bin || !bin->nt_headers)
return 0;
return bin->nt_headers->file_header.Characteristics & PE_IMAGE_FILE_DLL;
}
int PE_(r_bin_pe_is_pie)(struct PE_(r_bin_pe_obj_t)* bin) {
if (!bin || !bin->nt_headers)
return 0;
return bin->nt_headers->optional_header.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE;
#if 0
BOOL aslr = inh->OptionalHeader.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE;
@ -974,22 +1010,32 @@ int PE_(r_bin_pe_is_pie)(struct PE_(r_bin_pe_obj_t)* bin) {
}
int PE_(r_bin_pe_is_big_endian)(struct PE_(r_bin_pe_obj_t)* bin) {
if (!bin || !bin->nt_headers)
return 0;
return bin->nt_headers->file_header.Characteristics & PE_IMAGE_FILE_BYTES_REVERSED_HI;
}
int PE_(r_bin_pe_is_stripped_relocs)(struct PE_(r_bin_pe_obj_t)* bin) {
if (!bin || !bin->nt_headers)
return 0;
return bin->nt_headers->file_header.Characteristics & PE_IMAGE_FILE_RELOCS_STRIPPED;
}
int PE_(r_bin_pe_is_stripped_line_nums)(struct PE_(r_bin_pe_obj_t)* bin) {
if (!bin || !bin->nt_headers)
return 0;
return bin->nt_headers->file_header.Characteristics & PE_IMAGE_FILE_LINE_NUMS_STRIPPED;
}
int PE_(r_bin_pe_is_stripped_local_syms)(struct PE_(r_bin_pe_obj_t)* bin) {
if (!bin || !bin->nt_headers)
return 0;
return bin->nt_headers->file_header.Characteristics & PE_IMAGE_FILE_LOCAL_SYMS_STRIPPED;
}
int PE_(r_bin_pe_is_stripped_debug)(struct PE_(r_bin_pe_obj_t)* bin) {
if (!bin || !bin->nt_headers)
return 0;
return bin->nt_headers->file_header.Characteristics & PE_IMAGE_FILE_DEBUG_STRIPPED;
}

View File

@ -129,8 +129,10 @@ static RList *symbols(RBinFile *arch)
if (!(ptr = R_NEW0 (RBinSymbol)))
break;
strncpy (ptr->name, obj->symbols[i].name,
if (obj->symbols[i].name)
strncpy (ptr->name, obj->symbols[i].name,
R_BIN_SIZEOF_STRINGS);
else *ptr->name = 0;
strncpy (ptr->forwarder, "NONE",
R_BIN_SIZEOF_STRINGS);
strncpy (ptr->bind, "", R_BIN_SIZEOF_STRINGS);

View File

@ -10,8 +10,9 @@ static int check(RBinFile *arch);
static int check_bytes(const ut8 *buf, ut64 length);
static Sdb* get_sdb (RBinObject *o) {
if (!o) return NULL;
struct PE_(r_bin_pe_obj_t) *bin = (struct PE_(r_bin_pe_obj_t) *) o->bin_obj;
struct PE_(r_bin_pe_obj_t) *bin;
if (!o || !o->bin_obj) return NULL;
bin = (struct PE_(r_bin_pe_obj_t) *) o->bin_obj;
if (bin->kv) return bin->kv;
return NULL;
}
@ -163,6 +164,8 @@ static RList* imports(RBinFile *arch) {
struct r_bin_pe_import_t *imports = NULL;
int i;
if (!arch || !arch->o || !arch->o->bin_obj)
return NULL;
if (!(ret = r_list_new ()) || !(relocs = r_list_new ()))
return NULL;
@ -205,7 +208,9 @@ static RList* imports(RBinFile *arch) {
}
static RList* relocs(RBinFile *arch) {
return ((struct PE_(r_bin_pe_obj_t)*)arch->o->bin_obj)->relocs;
struct PE_(r_bin_pe_obj_t)* obj= arch->o->bin_obj;
if (obj) return obj->relocs;
return NULL;
}
static RList* libs(RBinFile *arch) {