From 2702c3f3468389465e6e9d33d0e6b3a5ae17c953 Mon Sep 17 00:00:00 2001 From: pancake Date: Thu, 2 Jun 2016 14:16:57 +0200 Subject: [PATCH] Initial regload support for linux-x32/64 coredumps --- libr/bin/format/elf/elf.c | 41 ++++++++++++++++++++++++++++++++++----- libr/bin/format/elf/elf.h | 1 + libr/bin/p/bin_elf.c | 16 +++++++++++---- 3 files changed, 49 insertions(+), 9 deletions(-) diff --git a/libr/bin/format/elf/elf.c b/libr/bin/format/elf/elf.c index 81cb2788b8fef..6884270fe9239 100644 --- a/libr/bin/format/elf/elf.c +++ b/libr/bin/format/elf/elf.c @@ -23,13 +23,14 @@ static RBinElfSection *g_sections = NULL; static inline int __strnlen(const char *str, int len) { int l = 0; - while (IS_PRINTABLE(*str) && --len) { - if (((ut8)*str)==0xff) + while (IS_PRINTABLE (*str) && --len) { + if (((ut8)*str) == 0xff) { break; + } str++; l++; } - return l+1; + return l + 1; } static int handle_e_ident(struct Elf_(r_bin_elf_obj_t) *bin) { @@ -159,10 +160,12 @@ static int init_shdr(struct Elf_(r_bin_elf_obj_t) *bin) { int len; if (!bin || bin->shdr) return true; - if (!UT32_MUL(&shdr_size, bin->ehdr.e_shnum, sizeof (Elf_(Shdr)))) + if (!UT32_MUL(&shdr_size, bin->ehdr.e_shnum, sizeof (Elf_(Shdr)))) { return false; - if (shdr_size < 1) + } + if (shdr_size < 1) { return false; + } if (shdr_size > bin->size) return false; if (bin->ehdr.e_shoff > bin->size) @@ -1589,6 +1592,34 @@ char* Elf_(r_bin_elf_get_osabi_name)(struct Elf_(r_bin_elf_obj_t) *bin) { return strdup ("linux"); } +ut8 *Elf_(r_bin_elf_grab_regstate)(struct Elf_(r_bin_elf_obj_t) *bin, int *len) { + RListIter *iter; + if (bin->phdr) { + int i; + int num = bin->ehdr.e_phnum; + for (i = 0; i < num; i++) { + if (bin->phdr[i].p_type != PT_NOTE) { + continue; + } + int bits = Elf_(r_bin_elf_get_bits)(bin); + int regdelta = (bits == 64)? 0x84: 0x40; // x64 vs x32 + int regsize = 160; // for x86-64 + ut8 *buf = malloc (regsize); + if (r_buf_read_at (bin->b, bin->phdr[i].p_offset + regdelta, buf, regsize) != regsize) { + free (buf); + eprintf ("Cannot read register state from CORE file\n"); + return NULL; + } + if (len) { + *len = regsize; + } + return buf; + } + } + eprintf ("Cannot find NOTE section\n"); + return NULL; +} + int Elf_(r_bin_elf_is_big_endian)(struct Elf_(r_bin_elf_obj_t) *bin) { return (bin->ehdr.e_ident[EI_DATA] == ELFDATA2MSB); } diff --git a/libr/bin/format/elf/elf.h b/libr/bin/format/elf/elf.h index 379caab1f0674..ce052ba284562 100644 --- a/libr/bin/format/elf/elf.h +++ b/libr/bin/format/elf/elf.h @@ -143,6 +143,7 @@ bool Elf_(r_bin_elf_entry_write)(struct Elf_(r_bin_elf_obj_t) *bin, ut64 addr); int Elf_(r_bin_elf_del_rpath)(struct Elf_(r_bin_elf_obj_t) *bin); int Elf_(r_bin_elf_has_relro)(struct Elf_(r_bin_elf_obj_t) *bin); int Elf_(r_bin_elf_has_nx)(struct Elf_(r_bin_elf_obj_t) *bin); +ut8 *Elf_(r_bin_elf_grab_regstate)(struct Elf_(r_bin_elf_obj_t) *bin, int *len); #endif diff --git a/libr/bin/p/bin_elf.c b/libr/bin/p/bin_elf.c index 61268276b58c2..ab8f05b8e30e1 100644 --- a/libr/bin/p/bin_elf.c +++ b/libr/bin/p/bin_elf.c @@ -47,6 +47,16 @@ static void * load_bytes(RBinFile *arch, const ut8 *buf, ut64 sz, ut64 loadaddr, if (res) { sdb_ns_set (sdb, "info", res->kv); } + const char *elf_type = Elf_(r_bin_elf_get_file_type (res)); + if (elf_type && !strncmp (elf_type, "CORE", 4)) { + int len; + ut8 *regs = Elf_(r_bin_elf_grab_regstate)(res, &len); + eprintf ("LEN = %d\n", len); + char *hexregs = r_hex_bin2strdup (regs, len); + eprintf ("arw %s\n", hexregs); + free (hexregs); + free (regs); + } r_buf_free (tbuf); return res; } @@ -55,15 +65,14 @@ static int load(RBinFile *arch) { const ut8 *bytes = arch ? r_buf_buffer (arch->buf) : NULL; ut64 sz = arch ? r_buf_size (arch->buf): 0; if (!arch || !arch->o) return false; - arch->o->bin_obj = load_bytes (arch, bytes, sz, - arch->o->loadaddr, arch->sdb); + arch->o->bin_obj = load_bytes (arch, bytes, sz, arch->o->loadaddr, arch->sdb); return arch->o->bin_obj != NULL; } static int destroy(RBinFile *arch) { int i; ELFOBJ* eobj = arch->o->bin_obj; - for (i=0; i< eobj->imports_by_ord_size; i++) { + for (i = 0; i < eobj->imports_by_ord_size; i++) { RBinImport *imp = eobj->imports_by_ord[i]; if (imp) { free (imp->name); @@ -138,7 +147,6 @@ static RList* sections(RBinFile *arch) { struct Elf_(r_bin_elf_obj_t)* obj = arch && arch->o ? arch->o->bin_obj : NULL; Elf_(Phdr)* phdr = NULL; - if (!obj || !(ret = r_list_new ())) return NULL; ret->free = free;