android 打印内存地址,获取android bin、so文件符号偏移或者内存地址

代码

直接晒代码

external.h

/*

* external.h

*

* Created on: 2016年12月7日

* Author: lyz

*/

#ifndef BASE_ELF_READER_EXTERNAL_H_

#define BASE_ELF_READER_EXTERNAL_H_

/* ELF support for BFD.

Copyright 1991, 1992, 1993, 1995, 1997, 1998, 1999, 2001, 2003, 2005,

2008 Free Software Foundation, Inc.

Written by Fred Fish @ Cygnus Support, from information published

in "UNIX System V Release 4, Programmers Guide: ANSI C and

Programming Support Tools".

This file is part of BFD, the Binary File Descriptor library.

This program is free software; you can redistribute it and/or modify

it under the terms of the GNU General Public License as published by

the Free Software Foundation; either version 2 of the License, or

(at your option) any later version.

This program is distributed in the hope that it will be useful,

but WITHOUT ANY WARRANTY; without even the implied warranty of

MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the

GNU General Public License for more details.

You should have received a copy of the GNU General Public License

along with this program; if not, write to the Free Software

Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */

/* This file is part of ELF support for BFD, and contains the portions

that describe how ELF is represented externally by the BFD library.

I.E. it describes the in-file representation of ELF. It requires

the elf/common.h file which contains the portions that are common to

both the internal and external representations. */

/* The 64-bit stuff is kind of random. Perhaps someone will publish a

spec someday. */

/* Special section indices, which may show up in st_shndx fields, among

other places. */

#define SHN_LORESERVE 0xFF00 /* Begin range of reserved indices */

#define SHN_LOPROC 0xFF00 /* Begin range of appl-specific */

#define SHN_HIPROC 0xFF1F /* End range of appl-specific */

#define SHN_LOOS 0xFF20 /* OS specific semantics, lo */

#define SHN_HIOS 0xFF3F /* OS specific semantics, hi */

#define SHN_ABS 0xFFF1 /* Associated symbol is absolute */

#define SHN_COMMON 0xFFF2 /* Associated symbol is in common */

#define SHN_XINDEX 0xFFFF /* Section index is held elsewhere */

#define SHN_HIRESERVE 0xFFFF /* End range of reserved indices */

/* ELF Header (32-bit implementations) */

typedef struct {

unsigned char e_ident[16]; /* ELF "magic number" */

unsigned char e_type[2]; /* Identifies object file type */

unsigned char e_machine[2]; /* Specifies required architecture */

unsigned char e_version[4]; /* Identifies object file version */

unsigned char e_entry[4]; /* Entry point virtual address */

unsigned char e_phoff[4]; /* Program header table file offset */

unsigned char e_shoff[4]; /* Section header table file offset */

unsigned char e_flags[4]; /* Processor-specific flags */

unsigned char e_ehsize[2]; /* ELF header size in bytes */

unsigned char e_phentsize[2]; /* Program header table entry size */

unsigned char e_phnum[2]; /* Program header table entry count */

unsigned char e_shentsize[2]; /* Section header table entry size */

unsigned char e_shnum[2]; /* Section header table entry count */

unsigned char e_shstrndx[2]; /* Section header string table index */

} Elf32_External_Ehdr;

typedef struct {

unsigned char e_ident[16]; /* ELF "magic number" */

unsigned char e_type[2]; /* Identifies object file type */

unsigned char e_machine[2]; /* Specifies required architecture */

unsigned char e_version[4]; /* Identifies object file version */

unsigned char e_entry[8]; /* Entry point virtual address */

unsigned char e_phoff[8]; /* Program header table file offset */

unsigned char e_shoff[8]; /* Section header table file offset */

unsigned char e_flags[4]; /* Processor-specific flags */

unsigned char e_ehsize[2]; /* ELF header size in bytes */

unsigned char e_phentsize[2]; /* Program header table entry size */

unsigned char e_phnum[2]; /* Program header table entry count */

unsigned char e_shentsize[2]; /* Section header table entry size */

unsigned char e_shnum[2]; /* Section header table entry count */

unsigned char e_shstrndx[2]; /* Section header string table index */

} Elf64_External_Ehdr;

/* Program header */

typedef struct {

unsigned char p_type[4]; /* Identifies program segment type */

unsigned char p_offset[4]; /* Segment file offset */

unsigned char p_vaddr[4]; /* Segment virtual address */

unsigned char p_paddr[4]; /* Segment physical address */

unsigned char p_filesz[4]; /* Segment size in file */

unsigned char p_memsz[4]; /* Segment size in memory */

unsigned char p_flags[4]; /* Segment flags */

unsigned char p_align[4]; /* Segment alignment, file & memory */

} Elf32_External_Phdr;

typedef struct {

unsigned char p_type[4]; /* Identifies program segment type */

unsigned char p_flags[4]; /* Segment flags */

unsigned char p_offset[8]; /* Segment file offset */

unsigned char p_vaddr[8]; /* Segment virtual address */

unsigned char p_paddr[8]; /* Segment physical address */

unsigned char p_filesz[8]; /* Segment size in file */

unsigned char p_memsz[8]; /* Segment size in memory */

unsigned char p_align[8]; /* Segment alignment, file & memory */

} Elf64_External_Phdr;

/* Section header */

typedef struct {

unsigned char sh_name[4]; /* Section name, index in string tbl */

unsigned char sh_type[4]; /* Type of section */

unsigned char sh_flags[4]; /* Miscellaneous section attributes */

unsigned char sh_addr[4]; /* Section virtual addr at execution */

unsigned char sh_offset[4]; /* Section file offset */

unsigned char sh_size[4]; /* Size of section in bytes */

unsigned char sh_link[4]; /* Index of another section */

unsigned char sh_info[4]; /* Additional section information */

unsigned char sh_addralign[4]; /* Section alignment */

unsigned char sh_entsize[4]; /* Entry size if section holds table */

} Elf32_External_Shdr;

typedef struct {

unsigned char sh_name[4]; /* Section name, index in string tbl */

unsigned char sh_type[4]; /* Type of section */

unsigned char sh_flags[8]; /* Miscellaneous section attributes */

unsigned char sh_addr[8]; /* Section virtual addr at execution */

unsigned char sh_offset[8]; /* Section file offset */

unsigned char sh_size[8]; /* Size of section in bytes */

unsigned char sh_link[4]; /* Index of another section */

unsigned char sh_info[4]; /* Additional section information */

unsigned char sh_addralign[8]; /* Section alignment */

unsigned char sh_entsize[8]; /* Entry size if section holds table */

} Elf64_External_Shdr;

/* Symbol table entry */

typedef struct {

unsigned char st_name[4]; /* Symbol name, index in string tbl */

unsigned char st_value[4]; /* Value of the symbol */

unsigned char st_size[4]; /* Associated symbol size */

unsigned char st_info[1]; /* Type and binding attributes */

unsigned char st_other[1]; /* No defined meaning, 0 */

unsigned char st_shndx[2]; /* Associated section index */

} Elf32_External_Sym;

typedef struct {

unsigned char st_name[4]; /* Symbol name, index in string tbl */

unsigned char st_info[1]; /* Type and binding attributes */

unsigned char st_other[1]; /* No defined meaning, 0 */

unsigned char st_shndx[2]; /* Associated section index */

unsigned char st_value[8]; /* Value of the symbol */

unsigned char st_size[8]; /* Associated symbol size */

} Elf64_External_Sym;

typedef struct {

unsigned char est_shndx[4]; /* Section index */

} Elf_External_Sym_Shndx;

/* Note segments */

typedef struct {

unsigned char namesz[4]; /* Size of entry's owner string */

unsigned char descsz[4]; /* Size of the note descriptor */

unsigned char type[4]; /* Interpretation of the descriptor */

char name[1]; /* Start of the name+desc data */

} Elf_External_Note;

/* Relocation Entries */

typedef struct {

unsigned char r_offset[4]; /* Location at which to apply the action */

unsigned char r_info[4]; /* index and type of relocation */

} Elf32_External_Rel;

typedef struct {

unsigned char r_offset[4]; /* Location at which to apply the action */

unsigned char r_info[4]; /* index and type of relocation */

unsigned char r_addend[4]; /* Constant addend used to compute value */

} Elf32_External_Rela;

typedef struct {

unsigned char r_offset[8]; /* Location at which to apply the action */

unsigned char r_info[8]; /* index and type of relocation */

} Elf64_External_Rel;

typedef struct {

unsigned char r_offset[8]; /* Location at which to apply the action */

unsigned char r_info[8]; /* index and type of relocation */

unsigned char r_addend[8]; /* Constant addend used to compute value */

} Elf64_External_Rela;

/* dynamic section structure */

typedef struct {

unsigned char d_tag[4]; /* entry tag value */

union {

unsigned char d_val[4];

unsigned char d_ptr[4];

} d_un;

} Elf32_External_Dyn;

typedef struct {

unsigned char d_tag[8]; /* entry tag value */

union {

unsigned char d_val[8];

unsigned char d_ptr[8];

} d_un;

} Elf64_External_Dyn;

/* The version structures are currently size independent. They are

named without a 32 or 64. If that ever changes, these structures

will need to be renamed. */

/* This structure appears in a SHT_GNU_verdef section. */

typedef struct {

unsigned char vd_version[2];

unsigned char vd_flags[2];

unsigned char vd_ndx[2];

unsigned char vd_cnt[2];

unsigned char vd_hash[4];

unsigned char vd_aux[4];

unsigned char vd_next[4];

} Elf_External_Verdef;

/* This structure appears in a SHT_GNU_verdef section. */

typedef struct {

unsigned char vda_name[4];

unsigned char vda_next[4];

} Elf_External_Verdaux;

/* This structure appears in a SHT_GNU_verneed section. */

typedef struct {

unsigned char vn_version[2];

unsigned char vn_cnt[2];

unsigned char vn_file[4];

unsigned char vn_aux[4];

unsigned char vn_next[4];

} Elf_External_Verneed;

/* This structure appears in a SHT_GNU_verneed section. */

typedef struct {

unsigned char vna_hash[4];

unsigned char vna_flags[2];

unsigned char vna_other[2];

unsigned char vna_name[4];

unsigned char vna_next[4];

} Elf_External_Vernaux;

/* Structure for syminfo section. */

typedef struct

{

unsigned char si_boundto[2];

unsigned char si_flags[2];

} Elf_External_Syminfo;

/* This structure appears on the stack and in NT_AUXV core file notes. */

typedef struct

{

unsigned char a_type[4];

unsigned char a_val[4];

} Elf32_External_Auxv;

typedef struct

{

unsigned char a_type[8];

unsigned char a_val[8];

} Elf64_External_Auxv;

/* Size of SHT_GROUP section entry. */

#define GRP_ENTRY_SIZE 4

#define EI_NIDENT 16 /* Size of e_ident[] */

typedef unsigned long bfd_vma;

typedef unsigned long bfd_size_type;

typedef unsigned long file_ptr;

typedef struct elf_internal_ehdr {

unsigned char e_ident[EI_NIDENT]; /* ELF "magic number" */

unsigned long e_phoff; /* Program header table file offset */

unsigned long e_shoff; /* Section header table file offset */

unsigned long e_version; /* Identifies object file version */

unsigned long e_flags; /* Processor-specific flags */

unsigned short e_type; /* Identifies object file type */

unsigned short e_machine; /* Specifies required architecture */

unsigned int e_ehsize; /* ELF header size in bytes */

unsigned int e_phentsize; /* Program header table entry size */

unsigned int e_phnum; /* Program header table entry count */

unsigned int e_shentsize; /* Section header table entry size */

unsigned int e_shnum; /* Section header table entry count */

unsigned int e_shstrndx; /* Section header string table index */

} Elf_Internal_Ehdr;

typedef struct elf_internal_shdr {

unsigned int sh_name; /* Section name, index in string tbl */

unsigned int sh_type; /* Type of section */

bfd_vma sh_flags; /* Miscellaneous section attributes */

bfd_vma sh_addr; /* Section virtual addr at execution */

file_ptr sh_offset; /* Section file offset */

bfd_size_type sh_size; /* Size of section in bytes */

unsigned int sh_link; /* Index of another section */

unsigned int sh_info; /* Additional section information */

bfd_vma sh_addralign; /* Section alignment */

bfd_size_type sh_entsize; /* Entry size if section holds table */

/* The internal rep also has some cached info associated with it. */

unsigned char *contents; /* Section contents. */

} Elf_Internal_Shdr;

struct elf_internal_phdr {

unsigned long p_type; /* Identifies program segment type */

unsigned long p_flags; /* Segment flags */

bfd_vma p_offset; /* Segment file offset */

bfd_vma p_vaddr; /* Segment virtual address */

bfd_vma p_paddr; /* Segment physical address */

bfd_vma p_filesz; /* Segment size in file */

bfd_vma p_memsz; /* Segment size in memory */

bfd_vma p_align; /* Segment alignment, file & memory */

};

typedef struct elf_internal_phdr Elf_Internal_Phdr;

#define BYTE_GET(field) byte_get (field, sizeof (field))

typedef unsigned long long dwarf_vma;

typedef unsigned long long dwarf_size_type;

struct elf_internal_sym {

bfd_vma st_value; /* Value of the symbol */

bfd_vma st_size; /* Associated symbol size */

unsigned long st_name; /* Symbol name, index in string tbl */

unsigned char st_info; /* Type and binding attributes */

unsigned char st_other; /* Visibilty, and target specific */

unsigned int st_shndx; /* Associated section index */

};

typedef struct elf_internal_sym Elf_Internal_Sym;

#define GET_ELF_SYMBOLS(file, section) \

(is_32bit_elf ? get_32bit_elf_symbols (file, section) \

: get_64bit_elf_symbols (file, section))

#endif /* BASE_ELF_READER_EXTERNAL_H_ */

LibraryReader.h

/**

* @ name unpacker

* @ author xiaobaiyey

* @ email xiaobaiyey@outlook.com

* @ time 2018/11/20 5:04 PM

* @ class describe

*/

#ifndef UNPACKER_LIBRARYREADER_H

#define UNPACKER_LIBRARYREADER_H

#include

#include "external.h"

#include

#include

enum LIBRARYTYPE {

FROMFILE,

FROMMEMORY

};

/**

*so文件太大 个人感觉,在主线程中可能不能太适用

* 具体没试过时间消耗

*/

class LibraryReader {

public:

LibraryReader(const char *path, LIBRARYTYPE= FROMFILE);

LibraryReader();

unsigned long get_symbol_offset(const char *symbol);

unsigned long get_symbol_address(const char *symbol);

void print_symbol();

static unsigned long get_so_address(const char *sopath);

static uint32_t calculate_elf_hash(const char *name);

private:

LIBRARYTYPE librarytype;

std::string path;

int is_32bit_elf;

bool elf_parse_pass;

bool _lock = true;

unsigned long min_vaddr = 0xffffffff;

Elf_Internal_Ehdr elf_header;

Elf_Internal_Phdr *program_headers;

Elf_Internal_Shdr *section_headers;

Elf_Internal_Shdr *symtab_shndx_hdr;

std::map<:string bfd_vma> symbol_maps;

private:

//读取头文件

bool read_elf_file_header(FILE *file);

//读取program_headers

bool process_program_headers(FILE *file);

bool read_program_headers(FILE *file);

bool get_32bit_program_headers(FILE *file, Elf_Internal_Phdr *program_headers);

bool get_64bit_program_headers(FILE *file, Elf_Internal_Phdr *program_headers);

//读取section_headers

bool process_section_headers(FILE *file);

bool get_32bit_section_headers(FILE *file, unsigned int num);

bool get_64bit_section_headers(FILE *file, unsigned int num);

//读取解析数据

bool process_symbol_table(FILE *file);

Elf_Internal_Sym *get_32bit_elf_symbols(FILE *file, Elf_Internal_Shdr *section);

Elf_Internal_Sym *get_64bit_elf_symbols(FILE *file, Elf_Internal_Shdr *section);

};

#endif //UNPACKER_LIBRARYREADER_H

LibraryReader.cpp

/**

* @ name unpacker

* @ author xiaobaiyey

* @ email xiaobaiyey@outlook.com

* @ time 2018/11/20 5:04 PM

* @ class describe

*/

#include "LibraryReader.h"

#include

#include

#define DEBUG

#ifdef DEBUG

#define LOGI(...) printf(__VA_ARGS__);printf("\n")

#define LOGW(...) printf(__VA_ARGS__);printf("\n")

#define LOGE(...) printf(__VA_ARGS__);printf("\n")

#define LOGD(...)

#else

#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, __FUNCTION__, __VA_ARGS__))

#define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, __FUNCTION__, __VA_ARGS__))

#define LOGD(...)

#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, __FUNCTION__, __VA_ARGS__))

#endif

#define ABORT(...)

static dwarf_vma byte_get_little_endian(unsigned char *field, int size) {

switch (size) {

case 1:

return *field;

case 2:

return ((unsigned int) (field[0])) | (((unsigned int) (field[1])) << 8);

case 4:

return ((unsigned long) (field[0])) | (((unsigned long) (field[1])) << 8) |

(((unsigned long) (field[2])) << 16) | (((unsigned long) (field[3])) << 24);

case 8:

if (sizeof(dwarf_vma) == 8)

return ((dwarf_vma) (field[0])) | (((dwarf_vma) (field[1])) << 8) |

(((dwarf_vma) (field[2])) << 16) | (((dwarf_vma) (field[3])) << 24)

| (((dwarf_vma) (field[4])) << 32) | (((dwarf_vma) (field[5])) << 40) |

(((dwarf_vma) (field[6])) << 48) | (((dwarf_vma) (field[7])) << 56);

else if (sizeof(dwarf_vma) == 4)

/* We want to extract data from an 8 byte wide field and

place it into a 4 byte wide field. Since this is a little

endian source we can just use the 4 byte extraction code. */

return ((unsigned long) (field[0])) | (((unsigned long) (field[1])) << 8) |

(((unsigned long) (field[2])) << 16)

| (((unsigned long) (field[3])) << 24);

else {

ABORT("error size (%d)", size);

}

default:

ABORT("error size (%d)", size);

}

return *field;

}

static dwarf_vma byte_get_big_endian(unsigned char *field, int size) {

switch (size) {

case 1:

return *field;

case 2:

return ((unsigned int) (field[1])) | (((int) (field[0])) << 8);

case 4:

return ((unsigned long) (field[3])) | (((unsigned long) (field[2])) << 8) |

(((unsigned long) (field[1])) << 16) | (((unsigned long) (field[0])) << 24);

case 8:

if (sizeof(dwarf_vma) == 8)

return ((dwarf_vma) (field[7])) | (((dwarf_vma) (field[6])) << 8) |

(((dwarf_vma) (field[5])) << 16) | (((dwarf_vma) (field[4])) << 24)

| (((dwarf_vma) (field[3])) << 32) | (((dwarf_vma) (field[2])) << 40) |

(((dwarf_vma) (field[1])) << 48) | (((dwarf_vma) (field[0])) << 56);

else if (sizeof(dwarf_vma) == 4) {

/* Although we are extracing data from an 8 byte wide field,

we are returning only 4 bytes of data. */

field += 4;

return ((unsigned long) (field[3])) | (((unsigned long) (field[2])) << 8) |

(((unsigned long) (field[1])) << 16)

| (((unsigned long) (field[0])) << 24);

} else {

ABORT("error size (%d)", size);

}

default:

//error (_("Unhandled data length: %d\n"), size);

ABORT("error size (%d)", size);

}

return *field;

}

static void *

get_data(void *var, FILE *file, long offset, size_t size, size_t nmemb, const char *reason) {

void *mvar;

if (size == 0 || nmemb == 0)

return NULL;

if (fseek(file, offset, SEEK_SET)) {

LOGE("Unable to seek to 0x%lx for %s\n", (unsigned long) offset, reason);

return NULL;

}

mvar = var;

if (mvar == NULL) {

/* Check for overflow. */

if (nmemb < (~(size_t) 0 - 1) / size)

/* + 1 so that we can '\0' terminate invalid string table sections. */

mvar = malloc(size * nmemb + 1);

if (mvar == NULL) {

LOGE("Out of memory allocating 0x%lx bytes for %s\n", (unsigned long) (size * nmemb),

reason);

return NULL;

}

((char *) mvar)[size * nmemb] = '\0';

}

if (fread(mvar, size, nmemb, file) != nmemb) {

LOGE("Unable to read in 0x%lx bytes of %s\n", (unsigned long) (size * nmemb), reason);

if (mvar != var)

free(mvar);

return NULL;

}

return mvar;

}

dwarf_vma (*byte_get)(unsigned char *, int);

LibraryReader::LibraryReader(const char *path, LIBRARYTYPE librarytype) {

this->librarytype = librarytype;

this->path = path;

if (this->librarytype == FROMFILE) {

FILE *file = fopen(path, "rb");

if (file == nullptr) {

LOGE("read %s fail", path);

elf_parse_pass = false;

return;

}

LOGD("read file over");

if (!read_elf_file_header(file)) {

LOGE("read_elf_file_header fail");

elf_parse_pass = false;

}

LOGD("read_elf_file_header over");

if (!process_program_headers(file)) {

LOGE("process_program_headers fail");

elf_parse_pass = false;

}

LOGD("process_program_headers over");

if (!process_section_headers(file)) {

LOGE("process_section_headers fail");

elf_parse_pass = false;

}

LOGD("process_section_headers over");

if (!process_symbol_table(file)) {

LOGE("process_symbol_table fail");

elf_parse_pass = false;

}

LOGD("process_symbol_table over");

fclose(file);

elf_parse_pass = true;

} else {

}

}

bool LibraryReader::read_elf_file_header(FILE *file) {

unsigned char e_ident[EI_NIDENT];

if (fread(e_ident, EI_NIDENT, 1, file) != 1) {

LOGE("read EI_NIDENT fail");

return false;

}

switch (e_ident[EI_DATA]) {

default: /* fall through */

case ELFDATANONE: /* fall through */

case ELFDATA2LSB:

byte_get = byte_get_little_endian;

break;

case ELFDATA2MSB:

byte_get = byte_get_big_endian;

break;

}

is_32bit_elf = (e_ident[EI_CLASS] != ELFCLASS64);

if (is_32bit_elf) {

Elf32_External_Ehdr ehdr32;

if (fread(ehdr32.e_type, sizeof(ehdr32) - EI_NIDENT, 1, file) != 1) {

LOGE("read ehdr32.e_type fail");

return false;

}

elf_header.e_type = BYTE_GET(ehdr32.e_type);

elf_header.e_machine = BYTE_GET(ehdr32.e_machine);

elf_header.e_version = BYTE_GET(ehdr32.e_version);

elf_header.e_phoff = BYTE_GET(ehdr32.e_phoff);

elf_header.e_shoff = BYTE_GET(ehdr32.e_shoff);

elf_header.e_flags = BYTE_GET(ehdr32.e_flags);

elf_header.e_ehsize = BYTE_GET(ehdr32.e_ehsize);

elf_header.e_phentsize = BYTE_GET(ehdr32.e_phentsize);

elf_header.e_phnum = BYTE_GET(ehdr32.e_phnum);

elf_header.e_shentsize = BYTE_GET(ehdr32.e_shentsize);

elf_header.e_shnum = BYTE_GET(ehdr32.e_shnum);

elf_header.e_shstrndx = BYTE_GET(ehdr32.e_shstrndx);

} else {

Elf64_External_Ehdr ehdr64;

if (fread(ehdr64.e_type, sizeof(ehdr64) - EI_NIDENT, 1, file) != 1) {

LOGE("read ehdr64.e_type fail");

return false;

}

elf_header.e_type = BYTE_GET(ehdr64.e_type);

elf_header.e_machine = BYTE_GET(ehdr64.e_machine);

elf_header.e_version = BYTE_GET(ehdr64.e_version);

elf_header.e_phoff = BYTE_GET(ehdr64.e_phoff);

elf_header.e_shoff = BYTE_GET(ehdr64.e_shoff);

elf_header.e_flags = BYTE_GET(ehdr64.e_flags);

elf_header.e_ehsize = BYTE_GET(ehdr64.e_ehsize);

elf_header.e_phentsize = BYTE_GET(ehdr64.e_phentsize);

elf_header.e_phnum = BYTE_GET(ehdr64.e_phnum);

elf_header.e_shentsize = BYTE_GET(ehdr64.e_shentsize);

elf_header.e_shnum = BYTE_GET(ehdr64.e_shnum);

elf_header.e_shstrndx = BYTE_GET(ehdr64.e_shstrndx);

}

return true;

}

bool LibraryReader::read_program_headers(FILE *file) {

Elf_Internal_Phdr *phdrs;

/* Check cache of prior read. */

if (program_headers != NULL)

return true;

phdrs = (Elf_Internal_Phdr *) malloc(elf_header.e_phnum * sizeof(Elf_Internal_Phdr));

if (phdrs == NULL) {

return false;

}

if (is_32bit_elf ? get_32bit_program_headers(file, phdrs) : get_64bit_program_headers(file,

phdrs)) {

program_headers = phdrs;

return true;

}

free(phdrs);

return false;

}

bool LibraryReader::get_32bit_program_headers(FILE *file, Elf_Internal_Phdr *program_headers) {

Elf32_External_Phdr *phdrs;

Elf32_External_Phdr *external;

Elf_Internal_Phdr *internal;

unsigned int i;

phdrs = (Elf32_External_Phdr *) get_data(NULL, file, elf_header.e_phoff, elf_header.e_phentsize,

elf_header.e_phnum, "program headers");

if (!phdrs)

return false;

for (i = 0, internal = program_headers, external = phdrs;

i < elf_header.e_phnum; i++, internal++, external++) {

internal->p_type = BYTE_GET(external->p_type);

internal->p_offset = BYTE_GET(external->p_offset);

internal->p_vaddr = BYTE_GET(external->p_vaddr);

internal->p_paddr = BYTE_GET(external->p_paddr);

internal->p_filesz = BYTE_GET(external->p_filesz);

internal->p_memsz = BYTE_GET(external->p_memsz);

internal->p_flags = BYTE_GET(external->p_flags);

internal->p_align = BYTE_GET(external->p_align);

}

free(phdrs);

return true;

}

bool LibraryReader::get_64bit_program_headers(FILE *file, Elf_Internal_Phdr *program_headers) {

Elf64_External_Phdr *phdrs;

Elf64_External_Phdr *external;

Elf_Internal_Phdr *internal;

unsigned int i;

phdrs = (Elf64_External_Phdr *) get_data(NULL, file, elf_header.e_phoff, elf_header.e_phentsize,

elf_header.e_phnum, "program headers");

if (!phdrs)

return false;

for (i = 0, internal = program_headers, external = phdrs;

i < elf_header.e_phnum; i++, internal++, external++) {

internal->p_type = BYTE_GET(external->p_type);

internal->p_flags = BYTE_GET(external->p_flags);

internal->p_offset = BYTE_GET(external->p_offset);

internal->p_vaddr = BYTE_GET(external->p_vaddr);

internal->p_paddr = BYTE_GET(external->p_paddr);

internal->p_filesz = BYTE_GET(external->p_filesz);

internal->p_memsz = BYTE_GET(external->p_memsz);

internal->p_align = BYTE_GET(external->p_align);

}

free(phdrs);

return true;

}

bool LibraryReader::process_program_headers(FILE *file) {

Elf_Internal_Phdr *segment;

unsigned int i;

if (elf_header.e_phnum == 0) {

return 0;

}

if (!read_program_headers(file))

return false;

for (i = 0, segment = program_headers; i < elf_header.e_phnum; i++, segment++) {

if (segment->p_type == PT_LOAD) {

if ((unsigned long) segment->p_vaddr < min_vaddr) {

min_vaddr = (unsigned long) segment->p_vaddr;

}

}

}

return true;

}

bool LibraryReader::get_32bit_section_headers(FILE *file, unsigned int num) {

Elf32_External_Shdr *shdrs;

Elf_Internal_Shdr *internal;

unsigned int i;

shdrs = (Elf32_External_Shdr *) get_data(NULL, file, elf_header.e_shoff, elf_header.e_shentsize,

num, "section headers");

if (!shdrs)

return false;

section_headers = (Elf_Internal_Shdr *) malloc(num * sizeof(Elf_Internal_Shdr));

if (section_headers == NULL) {

LOGE("Out of memory\n");

return false;

}

for (i = 0, internal = section_headers; i < num; i++, internal++) {

internal->sh_name = BYTE_GET(shdrs[i].sh_name);

internal->sh_type = BYTE_GET(shdrs[i].sh_type);

internal->sh_flags = BYTE_GET(shdrs[i].sh_flags);

internal->sh_addr = BYTE_GET(shdrs[i].sh_addr);

internal->sh_offset = BYTE_GET(shdrs[i].sh_offset);

internal->sh_size = BYTE_GET(shdrs[i].sh_size);

internal->sh_link = BYTE_GET(shdrs[i].sh_link);

internal->sh_info = BYTE_GET(shdrs[i].sh_info);

internal->sh_addralign = BYTE_GET(shdrs[i].sh_addralign);

internal->sh_entsize = BYTE_GET(shdrs[i].sh_entsize);

}

free(shdrs);

return true;

}

bool LibraryReader::get_64bit_section_headers(FILE *file, unsigned int num) {

Elf64_External_Shdr *shdrs;

Elf_Internal_Shdr *internal;

unsigned int i;

shdrs = (Elf64_External_Shdr *) get_data(NULL, file, elf_header.e_shoff, elf_header.e_shentsize,

num, "section headers");

if (!shdrs)

return false;

section_headers = (Elf_Internal_Shdr *) malloc(num * sizeof(Elf_Internal_Shdr));

if (section_headers == NULL) {

LOGE("Out of memory\n");

return false;

}

for (i = 0, internal = section_headers; i < num; i++, internal++) {

internal->sh_name = BYTE_GET(shdrs[i].sh_name);

internal->sh_type = BYTE_GET(shdrs[i].sh_type);

internal->sh_flags = BYTE_GET(shdrs[i].sh_flags);

internal->sh_addr = BYTE_GET(shdrs[i].sh_addr);

internal->sh_size = BYTE_GET(shdrs[i].sh_size);

internal->sh_entsize = BYTE_GET(shdrs[i].sh_entsize);

internal->sh_link = BYTE_GET(shdrs[i].sh_link);

internal->sh_info = BYTE_GET(shdrs[i].sh_info);

internal->sh_offset = BYTE_GET(shdrs[i].sh_offset);

internal->sh_addralign = BYTE_GET(shdrs[i].sh_addralign);

}

free(shdrs);

return true;

}

bool LibraryReader::process_section_headers(FILE *file) {

if (elf_header.e_shoff) {

/* There may be some extensions in the first section header. Don't

bomb if we can't read it. */

if (is_32bit_elf)

return get_32bit_section_headers(file, elf_header.e_shnum);

else

return get_64bit_section_headers(file, elf_header.e_shnum);

}

return false;

}

bool LibraryReader::process_symbol_table(FILE *file) {

unsigned int i;

Elf_Internal_Shdr *section;

unsigned long result = 0;

for (i = 0, section = section_headers; i < elf_header.e_shnum; i++, section++) {

unsigned int si;

char *strtab = NULL;

unsigned long int strtab_size = 0;

Elf_Internal_Sym *symtab;

Elf_Internal_Sym *psym;

if (section->sh_type != SHT_SYMTAB && section->sh_type != SHT_DYNSYM) {

continue;

}

symtab = GET_ELF_SYMBOLS(file, section);

if (symtab == NULL)

continue;

if (section->sh_link == elf_header.e_shstrndx) {

continue;

} else if (section->sh_link < elf_header.e_shnum) {

Elf_Internal_Shdr *string_sec;

string_sec = section_headers + section->sh_link;

strtab = (char *) get_data(NULL, file, string_sec->sh_offset, 1, string_sec->sh_size,

"string table");

strtab_size = strtab != NULL ? string_sec->sh_size : 0;

}

int number = section->sh_size / section->sh_entsize;

for (si = 0, psym = symtab; si < number; si++, psym++) {

const char *name = psym->st_name < strtab_size ? strtab + psym->st_name : "";

if (name != nullptr && strlen(name) > 0 && psym->st_value != 0) {

symbol_maps.insert(std::make_pair(std::string(name), psym->st_value));

}

}

free(symtab);

}

return true;

}

Elf_Internal_Sym *LibraryReader::get_32bit_elf_symbols(FILE *file, Elf_Internal_Shdr *section) {

unsigned long number;

Elf32_External_Sym *esyms;

Elf_External_Sym_Shndx *shndx;

Elf_Internal_Sym *isyms;

Elf_Internal_Sym *psym;

unsigned int j;

esyms = (Elf32_External_Sym *) get_data(NULL, file, section->sh_offset, 1, section->sh_size,

"symbols");

if (!esyms)

return NULL;

shndx = NULL;

if (symtab_shndx_hdr != NULL &&

(symtab_shndx_hdr->sh_link == (unsigned long) (section - section_headers))) {

shndx = (Elf_External_Sym_Shndx *) get_data(NULL, file, symtab_shndx_hdr->sh_offset, 1,

symtab_shndx_hdr->sh_size, "symtab shndx");

if (!shndx) {

free(esyms);

return NULL;

}

}

number = section->sh_size / section->sh_entsize;

isyms = (Elf_Internal_Sym *) malloc(number * sizeof(Elf_Internal_Sym));

if (isyms == NULL) {

LOGE("Out of memory\n");

if (shndx)

free(shndx);

free(esyms);

return NULL;

}

for (j = 0, psym = isyms; j < number; j++, psym++) {

psym->st_name = BYTE_GET(esyms[j].st_name);

psym->st_value = BYTE_GET(esyms[j].st_value);

psym->st_size = BYTE_GET(esyms[j].st_size);

psym->st_shndx = BYTE_GET(esyms[j].st_shndx);

if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)

psym->st_shndx = byte_get((unsigned char *) &shndx[j], sizeof(shndx[j]));

else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))

psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);

psym->st_info = BYTE_GET(esyms[j].st_info);

psym->st_other = BYTE_GET(esyms[j].st_other);

}

if (shndx)

free(shndx);

free(esyms);

return isyms;

}

Elf_Internal_Sym *LibraryReader::get_64bit_elf_symbols(FILE *file, Elf_Internal_Shdr *section) {

unsigned long number;

Elf64_External_Sym *esyms;

Elf_External_Sym_Shndx *shndx;

Elf_Internal_Sym *isyms;

Elf_Internal_Sym *psym;

unsigned int j;

esyms = (Elf64_External_Sym *) get_data(NULL, file, section->sh_offset, 1, section->sh_size,

"symbols");

if (!esyms)

return NULL;

shndx = NULL;

if (symtab_shndx_hdr != NULL &&

(symtab_shndx_hdr->sh_link == (unsigned long) (section - section_headers))) {

shndx = (Elf_External_Sym_Shndx *) get_data(NULL, file, symtab_shndx_hdr->sh_offset, 1,

symtab_shndx_hdr->sh_size, "symtab shndx");

if (!shndx) {

free(esyms);

return NULL;

}

}

number = section->sh_size / section->sh_entsize;

isyms = (Elf_Internal_Sym *) malloc(number * sizeof(Elf_Internal_Sym));

if (isyms == NULL) {

LOGE("Out of memory\n");

if (shndx)

free(shndx);

free(esyms);

return NULL;

}

for (j = 0, psym = isyms; j < number; j++, psym++) {

psym->st_name = BYTE_GET(esyms[j].st_name);

psym->st_info = BYTE_GET(esyms[j].st_info);

psym->st_other = BYTE_GET(esyms[j].st_other);

psym->st_shndx = BYTE_GET(esyms[j].st_shndx);

if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)

psym->st_shndx = byte_get((unsigned char *) &shndx[j], sizeof(shndx[j]));

else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))

psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);

psym->st_value = BYTE_GET(esyms[j].st_value);

psym->st_size = BYTE_GET(esyms[j].st_size);

}

if (shndx)

free(shndx);

free(esyms);

return isyms;

}

void LibraryReader::print_symbol() {

if (!elf_parse_pass) {

LOGE("elf_parse_pass false");

return;

}

std::map<:string bfd_vma>::iterator iterator;

for (iterator = symbol_maps.begin(); iterator != symbol_maps.end(); iterator++) {

std::string symbol = iterator->first;

bfd_vma bfd_vma1 = iterator->second;

LOGI("symbol:%s offset:0x%x", symbol.c_str(), bfd_vma1);

}

}

unsigned long LibraryReader::get_symbol_offset(const char *symbol) {

if (!elf_parse_pass) {

LOGE("elf_parse_pass false");

return 0;

}

// clock_t start =clock();

std::string str(symbol);

auto it = symbol_maps.find(str);

if (it == symbol_maps.end()) {

return 0;

}

/* clock_t end = clock();

clock_t duration = (end - start);

//LOGI( "%ld seconds", duration );*/

return it->second;

}

LibraryReader::LibraryReader() {

}

unsigned long LibraryReader::get_so_address(const char *sopath) {

char line[1024] = {0};

FILE *fp;

unsigned long addr = 0;

char *pch;

if ((fp = fopen("/proc/self/maps", "r")) == NULL) {

LOGE("/proc/self/maps open failed (%s)", strerror(errno));

return 0;

}

while (fgets(line, sizeof(line), fp)) {

if (strstr(line, sopath)) {

pch = strtok(line, "-");

addr = strtoul(pch, NULL, 16);

break;

}

}

fclose(fp);

return addr;

}

unsigned long LibraryReader::get_symbol_address(const char *symbol) {

if (!elf_parse_pass) {

LOGE("elf_parse_pass false");

return 0;

}

// clock_t start =clock();

std::string str(symbol);

auto it = symbol_maps.find(str);

if (it == symbol_maps.end()) {

return 0;

}

/* clock_t end = clock();

clock_t duration = (end - start);

//LOGI( "%ld seconds", duration );*/

return it->second + get_so_address(this->path.c_str());

}

uint32_t LibraryReader::calculate_elf_hash(const char *name) {

const uint8_t *name_bytes = reinterpret_cast(name);

uint32_t h = 0, g;

while (*name_bytes) {

h = (h << 4) + *name_bytes++;

g = h & 0xf0000000;

h ^= g;

h ^= g >> 24;

}

return h;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值