From 6a517aa66b511d2943905fb6d14f93bee999e2cc Mon Sep 17 00:00:00 2001 From: Riccardo Schirone Date: Tue, 8 Sep 2015 20:35:57 +0200 Subject: [PATCH] bin/p: add CGC bin format plugin --- libr/bin/Jamroot | 3 + libr/bin/format/elf/elf.c | 20 ++++- libr/bin/format/elf/elf_specs.h | 2 + libr/bin/p/Makefile | 2 +- libr/bin/p/bin_cgc.c | 137 ++++++++++++++++++++++++++++++++ libr/bin/p/bin_elf.c | 19 ++--- libr/bin/p/cgc.mk | 12 +++ libr/include/r_bin.h | 1 + plugins.def.cfg | 1 + 9 files changed, 181 insertions(+), 16 deletions(-) create mode 100644 libr/bin/p/bin_cgc.c create mode 100644 libr/bin/p/cgc.mk diff --git a/libr/bin/Jamroot b/libr/bin/Jamroot index 922a37567a..b818b9abe6 100644 --- a/libr/bin/Jamroot +++ b/libr/bin/Jamroot @@ -26,6 +26,9 @@ OBJS += p/bin_write_elf.c format/elf/elf_write.c ; OBJS += p/bin_elf64.c format/elf/elf64.c ; OBJS += p/bin_write_elf64.c format/elf/elf64_write.c ; +# CGC +OBJS += p/bin_cgc.c format/elf/elf.c ; + # MACH0 OBJS += p/bin_mach0.c format/mach0/mach0.c ; OBJS += p/bin_mach064.c format/mach0/mach064.c ; diff --git a/libr/bin/format/elf/elf.c b/libr/bin/format/elf/elf.c index 22f8c37e57..9bed9e8934 100644 --- a/libr/bin/format/elf/elf.c +++ b/libr/bin/format/elf/elf.c @@ -18,6 +18,11 @@ static inline int __strnlen(const char *str, int len) { return l+1; } +static int handle_e_ident(struct Elf_(r_bin_elf_obj_t) *bin) { + return strncmp ((char *)bin->ehdr.e_ident, ELFMAG, SELFMAG) == 0 || + strncmp ((char *)bin->ehdr.e_ident, CGCMAG, SCGCMAG) == 0; +} + static int init_ehdr(struct Elf_(r_bin_elf_obj_t) *bin) { ut8 e_ident[EI_NIDENT]; int len; @@ -74,9 +79,8 @@ static int init_ehdr(struct Elf_(r_bin_elf_obj_t) *bin) { eprintf ("Warning: read (ehdr)\n"); return R_FALSE; } - if (strncmp ((char *)bin->ehdr.e_ident, ELFMAG, SELFMAG)) - return R_FALSE; - return R_TRUE; + + return handle_e_ident (bin); } static int init_phdr(struct Elf_(r_bin_elf_obj_t) *bin) { @@ -691,6 +695,16 @@ ut64 Elf_(r_bin_elf_get_main_offset)(struct Elf_(r_bin_elf_obj_t) *bin) { (buf[48 + 3] << 24))); return Elf_(r_bin_elf_v2p) (bin, addr); } + // X86-CGC + if (buf[0] == 0xe8 && !memcmp (buf + 5, "\x50\xe8\x00\x00\x00\x00\xb8\x01\x00\x00\x00\x53", 12)) { + size_t SIZEOF_CALL = 5; + ut64 rel_addr = (ut64)((int)(buf[1] + (buf[2] << 8) + + (buf[3] << 16) + (buf[4] << 24))); + ut64 addr = Elf_(r_bin_elf_p2v)(bin, entry + SIZEOF_CALL); + + addr += rel_addr; + return Elf_(r_bin_elf_v2p) (bin, addr); + } // X86-PIE if (buf[0x1d] == 0x48 && buf[0x1e] == 0x8b) { if (!memcmp (buf, "\x31\xed\x49\x89", 4)) {// linux diff --git a/libr/bin/format/elf/elf_specs.h b/libr/bin/format/elf/elf_specs.h index ea15b4d145..0af2be7341 100644 --- a/libr/bin/format/elf/elf_specs.h +++ b/libr/bin/format/elf/elf_specs.h @@ -152,6 +152,8 @@ typedef struct /* Conglomeration of the identification bytes, for easy testing as a word. */ #define ELFMAG "\177ELF" #define SELFMAG 4 +#define CGCMAG "\177CGC" +#define SCGCMAG 4 #define EI_CLASS 4 /* File class byte index */ #define ELFCLASSNONE 0 /* Invalid class */ diff --git a/libr/bin/p/Makefile b/libr/bin/p/Makefile index b008690fcf..442a01b57c 100644 --- a/libr/bin/p/Makefile +++ b/libr/bin/p/Makefile @@ -11,7 +11,7 @@ ALL_TARGETS= FORMATS=any.mk elf.mk elf64.mk pe.mk pe64.mk te.mk mach0.mk FORMATS+=bios.mk mach064.mk fatmach0.mk dyldcache.mk java.mk FORMATS+=dex.mk fs.mk ningb.mk coff.mk ningba.mk xbe.mk zimg.mk -FORMATS+=omf.mk +FORMATS+=omf.mk cgc.mk include $(FORMATS) all: ${ALL_TARGETS} diff --git a/libr/bin/p/bin_cgc.c b/libr/bin/p/bin_cgc.c new file mode 100644 index 0000000000..cc2a914801 --- /dev/null +++ b/libr/bin/p/bin_cgc.c @@ -0,0 +1,137 @@ +/* radare - LGPL - Copyright 2009-2015 - ret2libc, pancake */ + +#include +#include +#include +#include +#include + +#define R_BIN_CGC 1 +#include "bin_elf.c" + +extern struct r_bin_dbginfo_t r_bin_dbginfo_elf; +extern struct r_bin_write_t r_bin_write_elf; + +static int check_bytes(const ut8 *buf, ut64 length) { + return buf && length > 4 && memcmp (buf, CGCMAG, SCGCMAG) == 0 + && buf[4] != 2; +} + +static int check(RBinFile *arch) { + const ut8 *bytes = arch ? r_buf_buffer (arch->buf) : NULL; + ut64 sz = arch ? r_buf_size (arch->buf): 0; + return check_bytes (bytes, sz); +} + +static RBuffer* create(RBin* bin, const ut8 *code, int codelen, const ut8 *data, int datalen) { + ut32 filesize, code_va, code_pa, phoff; + ut32 p_start, p_phoff, p_phdr; + ut32 p_ehdrsz, p_phdrsz; + ut16 ehdrsz, phdrsz; + ut32 p_vaddr, p_paddr, p_fs, p_fs2; + ut32 baddr = 0x8048000; + RBuffer *buf = r_buf_new (); + +#define B(x,y) r_buf_append_bytes(buf,(const ut8*)x,y) +#define D(x) r_buf_append_ut32(buf,x) +#define H(x) r_buf_append_ut16(buf,x) +#define Z(x) r_buf_append_nbytes(buf,x) +#define W(x,y,z) r_buf_write_at(buf,x,(const ut8*)y,z) +#define WZ(x,y) p_tmp=buf->length;Z(x);W(p_tmp,y,strlen(y)) + + B ("\x7F" "CGC" "\x01\x01\x01\x43", 8); + Z (8); + H (2); // ET_EXEC + H (3); // e_machne = EM_I386 + + D (1); + p_start = buf->length; + D (-1); // _start + p_phoff = buf->length; + D (-1); // phoff -- program headers offset + D (0); // shoff -- section headers offset + D (0); // flags + p_ehdrsz = buf->length; + H (-1); // ehdrsz + p_phdrsz = buf->length; + H (-1); // phdrsz + H (1); + H (0); + H (0); + H (0); + // phdr: + p_phdr = buf->length; + D (1); + D (0); + p_vaddr = buf->length; + D (-1); // vaddr = $$ + p_paddr = buf->length; + D (-1); // paddr = $$ + p_fs = buf->length; + D (-1); // filesize + p_fs2 = buf->length; + D (-1); // filesize + D (5); // flags + D (0x1000); // align + + ehdrsz = p_phdr; + phdrsz = buf->length - p_phdr; + code_pa = buf->length; + code_va = code_pa + baddr; + phoff = 0x34;//p_phdr ; + filesize = code_pa + codelen + datalen; + + W (p_start, &code_va, 4); + W (p_phoff, &phoff, 4); + W (p_ehdrsz, &ehdrsz, 2); + W (p_phdrsz, &phdrsz, 2); + + code_va = baddr; // hack + W (p_vaddr, &code_va, 4); + code_pa = baddr; // hack + W (p_paddr, &code_pa, 4); + + W (p_fs, &filesize, 4); + W (p_fs2, &filesize, 4); + + B (code, codelen); + + if (data && datalen>0) { + //ut32 data_section = buf->length; + eprintf ("Warning: DATA section not support for ELF yet\n"); + B (data, datalen); + } + return buf; +} + +RBinPlugin r_bin_plugin_cgc = { + .name = "cgc", + .desc = "CGC format r_bin plugin", + .license = "LGPL3", + .init = NULL, + .fini = NULL, + .get_sdb = &get_sdb, + .load = &load, + .load_bytes = &load_bytes, + .destroy = &destroy, + .check = &check, + .check_bytes = &check_bytes, + .baddr = &baddr, + .boffset = &boffset, + .binsym = &binsym, + .entries = &entries, + .sections = §ions, + .symbols = &symbols, + .minstrlen = 4, + .imports = &imports, + .strings = NULL, + .info = &info, + .fields = &fields, + .size = &size, + .libs = &libs, + .relocs = &relocs, + .dbginfo = &r_bin_dbginfo_elf, + .create = &create, + .write = &r_bin_write_elf, + .get_vaddr = NULL, +}; diff --git a/libr/bin/p/bin_elf.c b/libr/bin/p/bin_elf.c index 53b6964878..3392d8c6ab 100644 --- a/libr/bin/p/bin_elf.c +++ b/libr/bin/p/bin_elf.c @@ -8,8 +8,6 @@ #include "elf/elf.h" #define ELFOBJ struct Elf_(r_bin_elf_obj_t) -static int check(RBinFile *arch); -static int check_bytes(const ut8 *buf, ut64 length); //TODO: implement r_bin_symbol_dup() and r_bin_symbol_free ? static void setsymord (ELFOBJ* eobj, ut32 ord, RBinSymbol *ptr) { @@ -516,7 +514,7 @@ static RBinInfo* info(RBinFile *arch) { ret->lang = "c"; if (arch->file) ret->file = strdup (arch->file); - else ret->file = '\0'; + else ret->file = NULL; if ((str = Elf_(r_bin_elf_get_rpath)(arch->o->bin_obj))) { ret->rpath = strdup (str); free (str); @@ -607,20 +605,17 @@ static int size(RBinFile *arch) { return off+len; } -#if !R_BIN_ELF64 +#if !R_BIN_ELF64 && !R_BIN_CGC + +static int check_bytes(const ut8 *buf, ut64 length) { + return buf && length > 4 && memcmp (buf, ELFMAG, SELFMAG) == 0 + && buf[4] != 2; +} static int check(RBinFile *arch) { const ut8 *bytes = arch ? r_buf_buffer (arch->buf) : NULL; ut64 sz = arch ? r_buf_size (arch->buf): 0; return check_bytes (bytes, sz); - -} - -static int check_bytes(const ut8 *buf, ut64 length) { - if (buf && length > 4 && - !memcmp (buf, "\x7F\x45\x4c\x46", 4) && buf[4] != 2) - return R_TRUE; - return R_FALSE; } extern struct r_bin_dbginfo_t r_bin_dbginfo_elf; diff --git a/libr/bin/p/cgc.mk b/libr/bin/p/cgc.mk new file mode 100644 index 0000000000..17750a6608 --- /dev/null +++ b/libr/bin/p/cgc.mk @@ -0,0 +1,12 @@ +OBJ_CGC=bin_cgc.o + +STATIC_OBJ+=${OBJ_CGC} +TARGET_CGC=bin_cgc.${EXT_SO} +LINK+=-L../../db -lr_db + +ifeq ($(WITHPIC),1) +ALL_TARGETS+=${TARGET_CGC} + +${TARGET_CGC}: ${OBJ_CGC} + -${CC} $(call libname,bin_cgc) ${CFLAGS} ${OBJ_CGC} $(LINK) $(LDFLAGS) +endif diff --git a/libr/include/r_bin.h b/libr/include/r_bin.h index f608d58ff1..bcccd44874 100644 --- a/libr/include/r_bin.h +++ b/libr/include/r_bin.h @@ -511,6 +511,7 @@ R_API void r_bin_filter_classes (RList *list); /* plugin pointers */ extern RBinPlugin r_bin_plugin_any; extern RBinPlugin r_bin_plugin_fs; +extern RBinPlugin r_bin_plugin_cgc; extern RBinPlugin r_bin_plugin_elf; extern RBinPlugin r_bin_plugin_elf64; extern RBinPlugin r_bin_plugin_p9; diff --git a/plugins.def.cfg b/plugins.def.cfg index f9eb32ed1f..c27ffb2c0e 100644 --- a/plugins.def.cfg +++ b/plugins.def.cfg @@ -89,6 +89,7 @@ bin.any bin.art bin.bf bin.bios +bin.cgc bin.coff bin.dex bin.elf