Commit b54e8a19 authored by swift_gan's avatar swift_gan

new ELF parser

parent 6e884926
...@@ -24,6 +24,7 @@ add_library( # Sets the name of the library. ...@@ -24,6 +24,7 @@ add_library( # Sets the name of the library.
src/main/cpp/utils/hide_api.cpp src/main/cpp/utils/hide_api.cpp
src/main/cpp/utils/utils.cpp src/main/cpp/utils/utils.cpp
src/main/cpp/utils/offset.cpp src/main/cpp/utils/offset.cpp
src/main/cpp/utils/elf_util.cpp
src/main/cpp/casts/cast_art_method.cpp src/main/cpp/casts/cast_art_method.cpp
src/main/cpp/casts/cast_compiler_options.cpp src/main/cpp/casts/cast_compiler_options.cpp
src/main/cpp/art/art_method.cpp src/main/cpp/art/art_method.cpp
......
#ifndef SANDHOOK_ELF_UTIL_H
#define SANDHOOK_ELF_UTIL_H
#include <linux/elf.h>
#if defined(__LP64__)
typedef Elf64_Ehdr Elf_Ehdr;
typedef Elf64_Shdr Elf_Shdr;
typedef Elf64_Addr Elf_Addr;
typedef Elf64_Dyn Elf_Dyn;
typedef Elf64_Rela Elf_Rela;
typedef Elf64_Sym Elf_Sym;
typedef Elf64_Off Elf_Off;
#define ELF_R_SYM(i) ELF64_R_SYM(i)
#else
typedef Elf32_Ehdr Elf_Ehdr;
typedef Elf32_Shdr Elf_Shdr;
typedef Elf32_Addr Elf_Addr;
typedef Elf32_Dyn Elf_Dyn;
typedef Elf32_Rel Elf_Rela;
typedef Elf32_Sym Elf_Sym;
typedef Elf32_Off Elf_Off;
#define ELF_R_SYM(i) ELF32_R_SYM(i)
#endif
namespace SandHook {
class ElfImg {
public:
ElfImg(const char* elf);
Elf_Addr getSymbOffset(const char* name);
void* getModuleBase(int pid, const char* name);
Elf_Addr getSymbAddress(const char* name);
~ElfImg();
private:
const char* elf = nullptr;
void* base = nullptr;
char* buffer = nullptr;
Elf_Ehdr* header = nullptr;
Elf_Shdr* section_header = nullptr;
Elf_Shdr* symtab = nullptr;
Elf_Shdr* strtab = nullptr;
Elf_Sym* sym_start = nullptr;
Elf_Off symtab_count = 0;
Elf_Off symstr_offset = 0;
Elf_Off symtab_offset = 0;
Elf_Off symtab_size = 0;
};
}
#endif //SANDHOOK_ELF_UTIL_H
#include <malloc.h>
#include <string.h>
#include <stdlib.h>
#include "../includes/elf_util.h"
#include "../includes/log.h"
using namespace SandHook;
ElfImg::ElfImg(const char *elf) {
this->elf = elf;
//load elf
FILE *fp = NULL;
if (!(fp = fopen(elf, "rb"))) {
LOGE("Unable to open %s\n", elf);
return;
}
fseek(fp, 0, SEEK_END);
long size = ftell(fp);
fseek(fp, 0, SEEK_SET);
char *buffer = (char*)malloc(size);
if (fread(buffer, 1, size, fp) != size) {
LOGE("fread error\n");
return;
}
fclose(fp);
Elf_Off symtab_entsize = 0;
header = reinterpret_cast<Elf_Ehdr *>(buffer);
section_header = reinterpret_cast<Elf_Shdr *>(header + header->e_shoff);
Elf_Off shoff = reinterpret_cast<Elf_Off>(((void *) elf) + header->e_shoff);
for (int i = 0; i < header->e_shnum; i++, shoff += header->e_shentsize) {
Elf_Shdr *section_h = (Elf_Shdr *) shoff;
switch (section_h->sh_type) {
case SHT_SYMTAB:
symtab = section_h;
symtab_offset = section_h->sh_offset;
symtab_size = section_h->sh_size;
symtab_entsize = section_h->sh_entsize;
symtab_count = symtab_size / symtab_entsize;
break;
case SHT_STRTAB:
symstr_offset = section_h->sh_offset;
break;
}
}
if(!symtab_offset) {
LOGW("can't find symtab from sections\n");
}
sym_start = reinterpret_cast<Elf_Sym *>(header + symtab_offset);
//load module base
base = getModuleBase(0, elf);
}
ElfImg::~ElfImg() {
if (buffer) {
free(buffer);
buffer = nullptr;
}
}
Elf_Addr ElfImg::getSymbOffset(const char *name) {
Elf_Addr _offset = 0;
for(int i = 0 ; i < symtab_count; i++) {
unsigned int st_type = ELF_ST_TYPE(sym_start[i].st_info);
char* st_name = buffer + symstr_offset + sym_start[i].st_name;
if (st_type == STT_FUNC && sym_start[i].st_size) {
if(strcmp(st_name, name) == 0) {
_offset = sym_start[i].st_value;
LOGD("find %s: %x\n", elf ,_offset);
break;
}
}
}
return _offset;
}
Elf_Addr ElfImg::getSymbAddress(const char *name) {
return reinterpret_cast<Elf_Addr>(base + getSymbOffset(name));
}
void *ElfImg::getModuleBase(int pid, const char *name) {
FILE *fp;
long addr = 0;
char *pch;
char filename[32];
char line[1024];
if (pid <= 0) {
snprintf(filename, sizeof(filename), "/proc/self/maps");
} else {
snprintf(filename, sizeof(filename), "/proc/%d/maps", pid);
}
fp = fopen(filename, "r");
if (fp != NULL) {
while (fgets(line, sizeof(line), fp)) {
if (strstr(line, name)) {
pch = strtok(line, "-");
addr = strtoul(pch, NULL, 16);
break;
}
}
fclose(fp);
}
LOGD("get module base %s: %lu", name, addr);
return reinterpret_cast<void *>(addr);
}
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
// //
#include "../includes/hide_api.h" #include "../includes/hide_api.h"
#include "../includes/arch.h" #include "../includes/arch.h"
#include "../includes/elf_util.h"
extern int SDK_INT; extern int SDK_INT;
...@@ -82,6 +83,11 @@ extern "C" { ...@@ -82,6 +83,11 @@ extern "C" {
globalJitCompileHandlerAddr = reinterpret_cast<art::jit::JitCompiler **>(getSymCompat(art_lib_path, "_ZN3art3jit3Jit20jit_compiler_handle_E")); globalJitCompileHandlerAddr = reinterpret_cast<art::jit::JitCompiler **>(getSymCompat(art_lib_path, "_ZN3art3jit3Jit20jit_compiler_handle_E"));
getQuickGenericJniStub = reinterpret_cast<void *(*)(void *)>(getSymCompat(art_lib_path, "_ZNK3art11ClassLinker29GetRuntimeQuickGenericJniStubEv")); getQuickGenericJniStub = reinterpret_cast<void *(*)(void *)>(getSymCompat(art_lib_path, "_ZNK3art11ClassLinker29GetRuntimeQuickGenericJniStubEv"));
getQuickToInterpreterBridge = reinterpret_cast<void *(*)(void *)>(getSymCompat(art_lib_path, "_ZNK3art9OatHeader27GetQuickToInterpreterBridgeEv")); getQuickToInterpreterBridge = reinterpret_cast<void *(*)(void *)>(getSymCompat(art_lib_path, "_ZNK3art9OatHeader27GetQuickToInterpreterBridgeEv"));
SandHook::ElfImg elfImg(art_lib_path);
void* sym = reinterpret_cast<void *>(elfImg.getSymbAddress("art_quick_to_interpreter_bridge"));
int i = 1;
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment