radare2/libr/bin/p/bin_elf64.c
Álvaro Felipe Melchor b0c6ae4409 Fix #4295 and #4155
This commit is the first attempt to improve relocation
recognition when dealing with relocatables elf-files
2016-04-04 23:09:58 +02:00

150 lines
3.7 KiB
C

/* radare - LGPL - Copyright 2009-2015 - pancake, nibble */
#define R_BIN_ELF64 1
#include "bin_elf.c"
static int check(RBinFile *arch);
static int check_bytes(const ut8 *buf, ut64 length);
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 >= 5)
if (!memcmp (buf, "\x7F\x45\x4c\x46\x02", 5))
return true;
return false;
}
extern struct r_bin_dbginfo_t r_bin_dbginfo_elf64;
extern struct r_bin_write_t r_bin_write_elf64;
static ut64 get_elf_vaddr64 (RBinFile *arch, ut64 baddr, ut64 paddr, ut64 vaddr) {
//NOTE(aaSSfxxx): since RVA is vaddr - "official" image base, we just need to add imagebase to vaddr
struct Elf_(r_bin_elf_obj_t)* obj = arch->o->bin_obj;
return obj->baddr - obj->boffset + vaddr;
}
static RBuffer* create(RBin* bin, const ut8 *code, int codelen, const ut8 *data, int datalen) {
ut32 p_start, p_phoff, p_phdr;
ut32 p_vaddr, p_paddr, p_fs, p_fs2;
ut32 p_ehdrsz, p_phdrsz;
ut64 filesize, code_va, code_pa, phoff;
ut16 ehdrsz, phdrsz;
ut64 baddr = 0x400000LL;
RBuffer *buf = r_buf_new ();
#define B(x,y) r_buf_append_bytes(buf,(const ut8*)x,y)
#define Q(x) r_buf_append_ut64(buf,x)
#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)
/* Ehdr */
B ("\x7F" "ELF" "\x02\x01\x01\x00", 8); // e_ident (ei_class = ELFCLASS64)
Z (8);
H (2); // e_type = ET_EXEC
H (62); // e_machine = EM_X86_64
D (1); // e_version = EV_CURRENT
p_start = buf->length;
Q (-1); // e_entry = 0xFFFFFFFF
p_phoff = buf->length;
Q (-1); // e_phoff = 0xFFFFFFFF
Q (0); // e_shoff = 0xFFFFFFFF
D (0); // e_flags
p_ehdrsz = buf->length;
H (-1); // e_ehsize = 0xFFFFFFFF
p_phdrsz = buf->length;
H (-1); // e_phentsize = 0xFFFFFFFF
H (1); // e_phnum
H (0); // e_shentsize
H (0); // e_shnum
H (0); // e_shstrndx
/* Phdr */
p_phdr = buf->length;
D (1); // p_type
D (5); // p_flags = PF_R | PF_X
Q (0); // p_offset
p_vaddr = buf->length;
Q (-1); // p_vaddr = 0xFFFFFFFF
p_paddr = buf->length;
Q (-1); // p_paddr = 0xFFFFFFFF
p_fs = buf->length;
Q (-1); // p_filesz
p_fs2 = buf->length;
Q (-1); // p_memsz
Q (0x200000); // p_align
/* Calc fields */
ehdrsz = p_phdr;
phdrsz = buf->length - p_phdr;
code_pa = buf->length;
code_va = code_pa + baddr;
phoff = p_phdr;
filesize = code_pa + codelen + datalen;
/* Write fields */
W (p_start, &code_va, 8);
W (p_phoff, &phoff, 8);
W (p_ehdrsz, &ehdrsz, 2);
W (p_phdrsz, &phdrsz, 2);
W (p_fs, &filesize, 8);
W (p_fs2, &filesize, 8);
W (p_vaddr, &baddr, 8);
W (p_paddr, &baddr, 8);
/* Append code */
B (code, codelen);
if (data && datalen>0) {
eprintf ("Warning: DATA section not support for ELF yet\n");
B (data, datalen);
}
return buf;
}
RBinPlugin r_bin_plugin_elf64 = {
.name = "elf64",
.desc = "elf64 bin plugin",
.license = "LGPL3",
.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 = &sections,
.symbols = &symbols,
.imports = &imports,
.minstrlen = 4,
.info = &info,
.fields = &fields,
.size = &size,
.libs = &libs,
.relocs = &relocs,
.patch_relocs = &patch_relocs,
.dbginfo = &r_bin_dbginfo_elf64,
.create = &create,
.write = &r_bin_write_elf64,
.get_vaddr = &get_elf_vaddr64,
};
#ifndef CORELIB
struct r_lib_struct_t radare_plugin = {
.type = R_LIB_TYPE_BIN,
.data = &r_bin_plugin_elf64,
.version = R2_VERSION
};
#endif