Fix uninitialized entry field for MZ bins (jman issue)

This commit is contained in:
pancake 2016-08-08 10:45:32 +02:00
parent 3e5f636869
commit bf63107f9a
4 changed files with 96 additions and 87 deletions

View File

@ -764,7 +764,7 @@ static int bin_pe_init_tls(struct PE_(r_bin_pe_obj_t) *bin) {
PE_DWord tls_paddr = bin_pe_rva_to_paddr (bin,
data_dir_tls->VirtualAddress);
image_tls_directory = R_NEW (PE_(image_tls_directory));
image_tls_directory = R_NEW0 (PE_(image_tls_directory));
if (r_buf_read_at (bin->b, tls_paddr, (ut8*)image_tls_directory, sizeof (PE_(image_tls_directory))) != sizeof (PE_(image_tls_directory))) {
eprintf ("Warning: read (image_tls_directory)\n");
free(image_tls_directory);

View File

@ -1,4 +1,4 @@
/* radare - LGPL - Copyright 2015 nodepad */
/* radare - LGPL - Copyright 2015-2016 nodepad */
#include <r_types.h>
#include <r_bin.h>
@ -6,31 +6,31 @@
static Sdb * get_sdb(RBinObject *o) {
const struct r_bin_mz_obj_t *bin;
if (!o || !o->bin_obj) return NULL;
bin = (struct r_bin_mz_obj_t *) o->bin_obj;
if (bin && bin->kv) return bin->kv;
if (o && o->bin_obj) {
bin = (struct r_bin_mz_obj_t *) o->bin_obj;
if (bin && bin->kv) {
return bin->kv;
}
}
return NULL;
}
static int check_bytes(const ut8 *buf, ut64 length) {
unsigned int exth_offset;
int ret = false;
if (!buf)
if (!buf || length <= 0x3d) {
return false;
if (length <= 0x3d)
return false;
if (!memcmp (buf, "MZ", 2) || !memcmp (buf, "ZM", 2))
{
}
if (!memcmp (buf, "MZ", 2) || !memcmp (buf, "ZM", 2)) {
ret = true;
exth_offset = (buf[0x3c] | (buf[0x3d]<<8));
if (length > exth_offset+2)
{
if (length > exth_offset + 2) {
if (!memcmp (buf+exth_offset, "PE", 2) ||
!memcmp (buf+exth_offset, "NE", 2) ||
!memcmp (buf+exth_offset, "LE", 2) ||
!memcmp (buf+exth_offset, "LX", 2) )
!memcmp (buf+exth_offset, "NE", 2) ||
!memcmp (buf+exth_offset, "LE", 2) ||
!memcmp (buf+exth_offset, "LX", 2) ) {
ret = false;
}
}
}
return ret;
@ -50,23 +50,20 @@ static void * load_bytes(RBinFile *arch, const ut8 *buf, ut64 sz,
tbuf = r_buf_new ();
r_buf_set_bytes (tbuf, buf, sz);
res = r_bin_mz_new_buf (tbuf);
if (res)
if (res) {
sdb_ns_set (sdb, "info", res->kv);
}
r_buf_free (tbuf);
return (void *)res;
}
static int load(RBinFile *arch) {
const void *res;
const ut8 *bytes;
ut64 sz;
if (!arch || !arch->o)
if (!arch || !arch->o) {
return false;
bytes = r_buf_buffer (arch->buf);
sz = r_buf_size (arch->buf);
res = load_bytes (arch, bytes, sz, arch->o->loadaddr, arch->sdb);
}
const ut8 *bytes = r_buf_buffer (arch->buf);
ut64 sz = r_buf_size (arch->buf);
const void *res = load_bytes (arch, bytes, sz, arch->o->loadaddr, arch->sdb);
arch->o->bin_obj = (void *)res;
return res != NULL;
}
@ -77,34 +74,31 @@ static int destroy(RBinFile *arch) {
}
static RList * entries(RBinFile *arch) {
int entry;
RList *res = NULL;
RBinAddr *ptr = NULL;
if (!(res = r_list_new ()))
RList *res = NULL;
if (!(res = r_list_newf (free))) {
return NULL;
res->free = free;
entry = r_bin_mz_get_entrypoint (arch->o->bin_obj);
}
int entry = r_bin_mz_get_entrypoint (arch->o->bin_obj);
if (entry >= 0) {
if ((ptr = R_NEW (RBinAddr))) {
if ((ptr = R_NEW0 (RBinAddr))) {
ptr->paddr = (ut64) entry;
ptr->vaddr = (ut64) entry;
r_list_append (res, ptr);
}
}
return res;
}
static RList * sections(RBinFile *arch) {
RList *ret = NULL;
RBinSection *ptr = NULL;
const struct r_bin_mz_segment_t *segments = NULL;
RBinSection *ptr = NULL;
RList *ret = NULL;
int i;
if (!(ret = r_list_new ()))
if (!(ret = r_list_new ())) {
return NULL;
}
ret->free = free;
if (!(segments = r_bin_mz_get_segments (arch->o->bin_obj))){
r_list_free (ret);
@ -131,7 +125,9 @@ static RList * sections(RBinFile *arch) {
static RBinInfo * info(RBinFile *arch) {
RBinInfo * const ret = R_NEW0 (RBinInfo);
if (!ret) return NULL;
if (!ret) {
return NULL;
}
ret->file = strdup (arch->file);
ret->bclass = strdup ("MZ");
ret->rclass = strdup ("mz");
@ -140,19 +136,14 @@ static RBinInfo * info(RBinFile *arch) {
ret->machine = strdup ("i386");
ret->type = strdup ("EXEC (Executable file)");
ret->subsystem = strdup ("DOS");
ret->rpath = NULL;
ret->cpu = NULL;
ret->guid = NULL;
ret->debug_file_name = NULL;
ret->bits = 16;
ret->big_endian = false;
ret->dbg_info = 0;
ret->big_endian = false;
ret->has_crypto = false;
ret->has_canary = false;
ret->has_nx = false;
ret->has_pi = false;
ret->has_va = false;
return ret;
}
@ -162,17 +153,16 @@ static RList * relocs(RBinFile *arch) {
const struct r_bin_mz_reloc_t *relocs = NULL;
int i;
if (!arch || !arch->o || !arch->o->bin_obj)
if (!arch || !arch->o || !arch->o->bin_obj) {
return NULL;
if (!(ret = r_list_new ()))
}
if (!(ret = r_list_newf (free))) {
return NULL;
ret->free = free;
if (!(relocs = r_bin_mz_get_relocs (arch->o->bin_obj)))
}
if (!(relocs = r_bin_mz_get_relocs (arch->o->bin_obj))) {
return ret;
}
for (i = 0; !relocs[i].last; i++) {
if (!(rel = R_NEW0 (RBinReloc))) {
free ((void *)relocs);
r_list_free (ret);
@ -187,7 +177,7 @@ static RList * relocs(RBinFile *arch) {
return ret;
}
struct r_bin_plugin_t r_bin_plugin_mz = {
RBinPlugin r_bin_plugin_mz = {
.name = "mz",
.desc = "MZ bin plugin",
.license = "MIT",
@ -205,7 +195,7 @@ struct r_bin_plugin_t r_bin_plugin_mz = {
};
#ifndef CORELIB
struct r_lib_struct_t radare_plugin = {
RLibStruct radare_plugin = {
.type = R_LIB_TYPE_BIN,
.data = &r_bin_plugin_mz,
.version = R2_VERSION

View File

@ -94,19 +94,19 @@ static void add_tls_callbacks(RBinFile *arch, RList* list) {
}
count++;
} while (vaddr != 0);
}
static RList* entries(RBinFile *arch) {
RList* ret;
RBinAddr *ptr = NULL;
struct r_bin_pe_addr_t *entry = NULL;
RBinAddr *ptr = NULL;
RList* ret;
if (!(ret = r_list_new ()))
if (!(ret = r_list_newf (free))) {
return NULL;
ret->free = free;
if (!(entry = PE_(r_bin_pe_get_entrypoint) (arch->o->bin_obj)))
}
if (!(entry = PE_(r_bin_pe_get_entrypoint) (arch->o->bin_obj))) {
return ret;
}
if ((ptr = R_NEW0 (RBinAddr))) {
ptr->paddr = entry->paddr;
ptr->vaddr = entry->vaddr;
@ -114,7 +114,6 @@ static RList* entries(RBinFile *arch) {
r_list_append (ret, ptr);
}
free (entry);
// get TLS callback addresses
add_tls_callbacks (arch, ret);

View File

@ -9,7 +9,9 @@ R_API void r_io_section_init(RIO *io) {
io->enforce_rwx = 0; // do not enforce RWX section permissions by default
io->enforce_seek = 0; // do not limit seeks out of the file by default
io->sections = r_list_new ();
if (!io->sections) return;
if (!io->sections) {
return;
}
io->sections->free = r_io_section_free;
}
@ -25,8 +27,9 @@ R_API RIOSection *r_io_section_get_name(RIO *io, const char *name) {
RIOSection *s;
if (name)
r_list_foreach (io->sections, iter, s) {
if (!strcmp (name, s->name))
if (!strcmp (name, s->name)) {
return s;
}
}
return NULL;
}
@ -107,8 +110,9 @@ R_API RIOSection *r_io_section_get_i(RIO *io, int idx) {
R_API int r_io_section_rm(RIO *io, int idx) {
RListIter *iter;
RIOSection *s;
if (!io || !io->sections)
if (!io || !io->sections) {
return false;
}
r_list_foreach (io->sections, iter, s) {
if (s->id == idx) {
r_list_delete (io->sections, iter);
@ -121,8 +125,9 @@ R_API int r_io_section_rm(RIO *io, int idx) {
R_API int r_io_section_rm_all (RIO *io, int fd) {
RIOSection *section;
RListIter *iter, *ator;
if (!io || !io->sections)
if (!io || !io->sections) {
return false;
}
r_list_foreach_safe (io->sections, iter, ator, section) {
if (section->fd == fd || fd == -1)
r_list_delete (io->sections, iter);
@ -141,7 +146,9 @@ R_API void r_io_section_free(void *ptr) {
R_API void r_io_section_clear(RIO *io) {
r_list_free (io->sections);
io->sections = r_list_new ();
if (!io->sections) return;
if (!io->sections) {
return;
}
io->sections->free = r_io_section_free;
}
@ -191,7 +198,6 @@ R_API void r_io_section_list(RIO *io, ut64 offset, int rad) {
io->cb_printf ("| 0x%08"PFMT64x"\n", seek+len); \
}
static void list_section_visual_vaddr (RIO *io, ut64 seek, ut64 len, int use_color, int cols) {
ut64 mul, min = -1, max = -1;
RListIter *iter;
@ -200,10 +206,12 @@ static void list_section_visual_vaddr (RIO *io, ut64 seek, ut64 len, int use_col
int width = cols - 60;
if (width < 1) width = 30;
r_list_foreach (io->sections, iter, s) {
if (min == -1 || s->vaddr < min)
if (min == -1 || s->vaddr < min) {
min = s->vaddr;
if (max == -1 || s->vaddr+s->size > max)
}
if (max == -1 || s->vaddr+s->size > max) {
max = s->vaddr+s->size;
}
}
mul = (max-min) / width;
if (min != -1 && mul != 0) {
@ -241,7 +249,7 @@ static void list_section_visual_vaddr (RIO *io, ut64 seek, ut64 len, int use_col
color, s->vaddr + s->size, color_end,
r_str_rwx_i (s->rwx), s->name, buf);
i++;
}
}
PRINT_CURRENT_SEEK;
}
}
@ -415,9 +423,13 @@ R_API ut64 r_io_section_maddr_to_vaddr(RIO *io, ut64 offset) {
// TODO: deprecate ?
R_API int r_io_section_exists_for_paddr (RIO *io, ut64 paddr, int hasperm) {
RIOSection *s = r_io_section_mget_in (io, paddr);
if (!s) return false;
if (hasperm) return (s->rwx & hasperm)? true: false;
return true;
if (s) {
if (hasperm) {
return (s->rwx & hasperm);
}
return true;
}
return false;
}
// TODO: deprecate ?
@ -480,7 +492,9 @@ R_API RList *r_io_section_get_in_vaddr_range(RIO *io, ut64 addr, ut64 endaddr) {
//list but not the elements to avoid UAF. r_io_free will free sections for us
ut64 sec_from, sec_to;
r_list_foreach (io->sections, iter, s) {
if (!(s->rwx & R_IO_MAP)) continue;
if (!(s->rwx & R_IO_MAP)) {
continue;
}
sec_from = s->vaddr;
sec_to = sec_from + s->vsize;
if (sec_from <= addr && addr < sec_to) r_list_append (sections, s);
@ -495,7 +509,9 @@ R_API RIOSection * r_io_section_get_first_in_paddr_range(RIO *io, ut64 addr, ut6
RListIter *iter;
ut64 sec_from, sec_to;
r_list_foreach (io->sections, iter, s) {
if (!(s->rwx & R_IO_MAP)) continue;
if (!(s->rwx & R_IO_MAP)) {
continue;
}
sec_to = s->offset + s->size;
sec_from = s->offset;
if (sec_from <= addr && addr < sec_to) break;
@ -552,23 +568,27 @@ R_API RIOSection *r_io_section_getv_bin_id(RIO *io, ut64 vaddr, ut32 bin_id) {
RListIter *iter;
RIOSection *s;
r_list_foreach (io->sections, iter, s) {
if (!(s->rwx & R_IO_MAP)) continue;
if (s->bin_id != bin_id) continue;
if (vaddr >= s->vaddr && vaddr < s->vaddr + s->vsize)
if (!(s->rwx & R_IO_MAP) || s->bin_id != bin_id) {
continue;
}
if (vaddr >= s->vaddr && vaddr < s->vaddr + s->vsize) {
return s;
}
}
return NULL;
}
R_API int r_io_section_set_archbits_bin_id(RIO *io, ut64 addr, const char *arch, int bits, ut32 bin_id) {
RIOSection *s = r_io_section_getv_bin_id (io, addr, bin_id);
if (!s) return false;
if (arch) {
s->arch = r_sys_arch_id (arch);
s->bits = bits;
} else {
s->arch = 0;
s->bits = 0;
if (s) {
if (arch) {
s->arch = r_sys_arch_id (arch);
s->bits = bits;
} else {
s->arch = 0;
s->bits = 0;
}
return true;
}
return true;
return false;
}