Commit d7ef0bd9 authored by swift_gan's avatar swift_gan Committed by swift_gan

[NativeHook]update elf

parent 0c0d3112
...@@ -54,11 +54,17 @@ namespace SandHook { ...@@ -54,11 +54,17 @@ namespace SandHook {
Elf_Shdr* symtab = nullptr; Elf_Shdr* symtab = nullptr;
Elf_Shdr* strtab = nullptr; Elf_Shdr* strtab = nullptr;
Elf_Shdr* dynsym = nullptr; Elf_Shdr* dynsym = nullptr;
Elf_Sym* sym_start = nullptr; Elf_Off dynsym_count = 0;
Elf_Sym* symtab_start = nullptr;
Elf_Sym* dynsym_start = nullptr;
Elf_Sym* strtab_start = nullptr;
Elf_Off symtab_count = 0; Elf_Off symtab_count = 0;
Elf_Off symstr_offset = 0; Elf_Off symstr_offset = 0;
Elf_Off symstr_offset_for_symtab = 0;
Elf_Off symtab_offset = 0; Elf_Off symtab_offset = 0;
Elf_Off dynsym_offset = 0;
Elf_Off symtab_size = 0; Elf_Off symtab_size = 0;
Elf_Off dynsym_size = 0;
}; };
} }
......
...@@ -29,54 +29,58 @@ ElfImg::ElfImg(const char *elf) { ...@@ -29,54 +29,58 @@ ElfImg::ElfImg(const char *elf) {
close(fd); close(fd);
Elf_Off symtab_entsize = 0;
section_header = reinterpret_cast<Elf_Shdr *>(((size_t) header) + header->e_shoff); section_header = reinterpret_cast<Elf_Shdr *>(((size_t) header) + header->e_shoff);
size_t shoff = reinterpret_cast<size_t>(section_header); size_t shoff = reinterpret_cast<size_t>(section_header);
char* section_str = reinterpret_cast<char *>(section_header[header->e_shstrndx].sh_offset + ((size_t) header)); char *section_str = reinterpret_cast<char *>(section_header[header->e_shstrndx].sh_offset +
((size_t) header));
bool has_strtab = false;
bool has_dynsym = false;
for (int i = 0; i < header->e_shnum; i++, shoff += header->e_shentsize) { for (int i = 0; i < header->e_shnum; i++, shoff += header->e_shentsize) {
Elf_Shdr *section_h = (Elf_Shdr *) shoff; Elf_Shdr *section_h = (Elf_Shdr *) shoff;
char* sname = section_h->sh_name + section_str; char *sname = section_h->sh_name + section_str;
Elf_Off entsize = section_h->sh_entsize;
switch (section_h->sh_type) { switch (section_h->sh_type) {
case SHT_DYNSYM: case SHT_DYNSYM:
has_dynsym = true; if (bias == -4396) {
dynsym = section_h; dynsym = section_h;
dynsym_offset = section_h->sh_offset;
dynsym_size = section_h->sh_size;
dynsym_count = dynsym_size / entsize;
dynsym_start = reinterpret_cast<Elf_Sym *>(((size_t) header) + dynsym_offset);
}
break; break;
case SHT_SYMTAB: case SHT_SYMTAB:
if (strcmp(sname, ".symtab") == 0) { if (strcmp(sname, ".symtab") == 0) {
symtab = section_h; symtab = section_h;
symtab_offset = section_h->sh_offset; symtab_offset = section_h->sh_offset;
symtab_size = section_h->sh_size; symtab_size = section_h->sh_size;
symtab_entsize = section_h->sh_entsize; symtab_count = symtab_size / entsize;
symtab_count = symtab_size / symtab_entsize; symtab_start = reinterpret_cast<Elf_Sym *>(((size_t) header) + symtab_offset);
} }
break; break;
case SHT_STRTAB: case SHT_STRTAB:
has_strtab = true; if (bias == -4396) {
if (strcmp(sname, ".strtab") == 0) {
strtab = section_h; strtab = section_h;
symstr_offset = section_h->sh_offset; symstr_offset = section_h->sh_offset;
strtab_start = reinterpret_cast<Elf_Sym *>(((size_t) header) + symstr_offset);
}
if (strcmp(sname, ".strtab") == 0) {
symstr_offset_for_symtab = section_h->sh_offset;
} }
break; break;
case SHT_PROGBITS: case SHT_PROGBITS:
if (has_dynsym && has_strtab && bias == -4396) { if (strtab == nullptr || dynsym == nullptr) break;
if (bias == -4396) {
bias = (off_t) section_h->sh_addr - (off_t) section_h->sh_offset; bias = (off_t) section_h->sh_addr - (off_t) section_h->sh_offset;
} }
break; break;
} }
} }
if(!symtab_offset) { if (!symtab_offset) {
LOGW("can't find symtab from sections\n"); LOGW("can't find symtab from sections\n");
} }
sym_start = reinterpret_cast<Elf_Sym *>(((size_t) header) + symtab_offset);
//load module base //load module base
base = getModuleBase(elf); base = getModuleBase(elf);
} }
...@@ -95,24 +99,42 @@ ElfImg::~ElfImg() { ...@@ -95,24 +99,42 @@ ElfImg::~ElfImg() {
Elf_Addr ElfImg::getSymbOffset(const char *name) { Elf_Addr ElfImg::getSymbOffset(const char *name) {
Elf_Addr _offset = 0; Elf_Addr _offset = 0;
for(int i = 0 ; i < symtab_count; i++) {
unsigned int st_type = ELF_ST_TYPE(sym_start[i].st_info); //search dynmtab
char* st_name = reinterpret_cast<char *>(((size_t) header) + symstr_offset + sym_start[i].st_name); if (dynsym_start != nullptr && strtab_start != nullptr) {
if (st_type == STT_FUNC && sym_start[i].st_size) { Elf_Sym *sym = dynsym_start;
if(strcmp(st_name, name) == 0) { char *strings = (char *) strtab_start;
_offset = sym_start[i].st_value; int k;
LOGD("find %s: %x\n", elf ,_offset); for (k = 0; k < dynsym_count; k++, sym++)
break; if (strcmp(strings + sym->st_name, name) == 0) {
_offset = sym->st_value;
LOGD("find %s: %x\n", elf, _offset);
return _offset;
}
}
//search symtab
if (symtab_start != nullptr && symstr_offset_for_symtab != 0) {
for (int i = 0; i < symtab_count; i++) {
unsigned int st_type = ELF_ST_TYPE(symtab_start[i].st_info);
char *st_name = reinterpret_cast<char *>(((size_t) header) + symstr_offset_for_symtab +
symtab_start[i].st_name);
if (st_type == STT_FUNC && symtab_start[i].st_size) {
if (strcmp(st_name, name) == 0) {
_offset = symtab_start[i].st_value;
LOGD("find %s: %x\n", elf, _offset);
return _offset;
}
} }
} }
} }
return _offset; return 0;
} }
Elf_Addr ElfImg::getSymbAddress(const char *name) { Elf_Addr ElfImg::getSymbAddress(const char *name) {
Elf_Addr offset = getSymbOffset(name); Elf_Addr offset = getSymbOffset(name);
if (offset > 0 && base != nullptr) { if (offset > 0 && base != nullptr) {
return static_cast<Elf_Addr>((size_t)base + offset - bias); return static_cast<Elf_Addr>((size_t) base + offset - bias);
} else { } else {
return 0; return 0;
} }
......
...@@ -32,54 +32,58 @@ ElfImg::ElfImg(const char *elf) { ...@@ -32,54 +32,58 @@ ElfImg::ElfImg(const char *elf) {
close(fd); close(fd);
Elf_Off symtab_entsize = 0;
section_header = reinterpret_cast<Elf_Shdr *>(((size_t) header) + header->e_shoff); section_header = reinterpret_cast<Elf_Shdr *>(((size_t) header) + header->e_shoff);
size_t shoff = reinterpret_cast<size_t>(section_header); size_t shoff = reinterpret_cast<size_t>(section_header);
char* section_str = reinterpret_cast<char *>(section_header[header->e_shstrndx].sh_offset + ((size_t) header)); char *section_str = reinterpret_cast<char *>(section_header[header->e_shstrndx].sh_offset +
((size_t) header));
bool has_strtab = false;
bool has_dynsym = false;
for (int i = 0; i < header->e_shnum; i++, shoff += header->e_shentsize) { for (int i = 0; i < header->e_shnum; i++, shoff += header->e_shentsize) {
Elf_Shdr *section_h = (Elf_Shdr *) shoff; Elf_Shdr *section_h = (Elf_Shdr *) shoff;
char* sname = section_h->sh_name + section_str; char *sname = section_h->sh_name + section_str;
Elf_Off entsize = section_h->sh_entsize;
switch (section_h->sh_type) { switch (section_h->sh_type) {
case SHT_DYNSYM: case SHT_DYNSYM:
has_dynsym = true; if (bias == -4396) {
dynsym = section_h; dynsym = section_h;
dynsym_offset = section_h->sh_offset;
dynsym_size = section_h->sh_size;
dynsym_count = dynsym_size / entsize;
dynsym_start = reinterpret_cast<Elf_Sym *>(((size_t) header) + dynsym_offset);
}
break; break;
case SHT_SYMTAB: case SHT_SYMTAB:
if (strcmp(sname, ".symtab") == 0) { if (strcmp(sname, ".symtab") == 0) {
symtab = section_h; symtab = section_h;
symtab_offset = section_h->sh_offset; symtab_offset = section_h->sh_offset;
symtab_size = section_h->sh_size; symtab_size = section_h->sh_size;
symtab_entsize = section_h->sh_entsize; symtab_count = symtab_size / entsize;
symtab_count = symtab_size / symtab_entsize; symtab_start = reinterpret_cast<Elf_Sym *>(((size_t) header) + symtab_offset);
} }
break; break;
case SHT_STRTAB: case SHT_STRTAB:
has_strtab = true; if (bias == -4396) {
if (strcmp(sname, ".strtab") == 0) {
strtab = section_h; strtab = section_h;
symstr_offset = section_h->sh_offset; symstr_offset = section_h->sh_offset;
strtab_start = reinterpret_cast<Elf_Sym *>(((size_t) header) + symstr_offset);
}
if (strcmp(sname, ".strtab") == 0) {
symstr_offset_for_symtab = section_h->sh_offset;
} }
break; break;
case SHT_PROGBITS: case SHT_PROGBITS:
if (has_dynsym && has_strtab && bias == -4396) { if (strtab == nullptr || dynsym == nullptr) break;
if (bias == -4396) {
bias = (off_t) section_h->sh_addr - (off_t) section_h->sh_offset; bias = (off_t) section_h->sh_addr - (off_t) section_h->sh_offset;
} }
break; break;
} }
} }
if(!symtab_offset) { if (!symtab_offset) {
LOGW("can't find symtab from sections\n"); LOGW("can't find symtab from sections\n");
} }
sym_start = reinterpret_cast<Elf_Sym *>(((size_t) header) + symtab_offset);
//load module base //load module base
base = getModuleBase(elf); base = getModuleBase(elf);
} }
...@@ -98,24 +102,42 @@ ElfImg::~ElfImg() { ...@@ -98,24 +102,42 @@ ElfImg::~ElfImg() {
Elf_Addr ElfImg::getSymbOffset(const char *name) { Elf_Addr ElfImg::getSymbOffset(const char *name) {
Elf_Addr _offset = 0; Elf_Addr _offset = 0;
for(int i = 0 ; i < symtab_count; i++) {
unsigned int st_type = ELF_ST_TYPE(sym_start[i].st_info); //search dynmtab
char* st_name = reinterpret_cast<char *>(((size_t) header) + symstr_offset + sym_start[i].st_name); if (dynsym_start != nullptr && strtab_start != nullptr) {
if (st_type == STT_FUNC && sym_start[i].st_size) { Elf_Sym *sym = dynsym_start;
if(strcmp(st_name, name) == 0) { char *strings = (char *) strtab_start;
_offset = sym_start[i].st_value; int k;
LOGD("find %s: %x\n", elf ,_offset); for (k = 0; k < dynsym_count; k++, sym++)
break; if (strcmp(strings + sym->st_name, name) == 0) {
_offset = sym->st_value;
LOGD("find %s: %x\n", elf, _offset);
return _offset;
}
}
//search symtab
if (symtab_start != nullptr && symstr_offset_for_symtab != 0) {
for (int i = 0; i < symtab_count; i++) {
unsigned int st_type = ELF_ST_TYPE(symtab_start[i].st_info);
char *st_name = reinterpret_cast<char *>(((size_t) header) + symstr_offset_for_symtab +
symtab_start[i].st_name);
if (st_type == STT_FUNC && symtab_start[i].st_size) {
if (strcmp(st_name, name) == 0) {
_offset = symtab_start[i].st_value;
LOGD("find %s: %x\n", elf, _offset);
return _offset;
}
} }
} }
} }
return _offset; return 0;
} }
Elf_Addr ElfImg::getSymbAddress(const char *name) { Elf_Addr ElfImg::getSymbAddress(const char *name) {
Elf_Addr offset = getSymbOffset(name); Elf_Addr offset = getSymbOffset(name);
if (offset > 0 && base != nullptr) { if (offset > 0 && base != nullptr) {
return static_cast<Elf_Addr>((size_t)base + offset - bias); return static_cast<Elf_Addr>((size_t) base + offset - bias);
} else { } else {
return 0; return 0;
} }
......
...@@ -39,7 +39,7 @@ namespace SandHook { ...@@ -39,7 +39,7 @@ namespace SandHook {
Elf_Addr getSymbOffset(const char* name); Elf_Addr getSymbOffset(const char* name);
void* getModuleBase(const char* name); static void* getModuleBase(const char* name);
Elf_Addr getSymbAddress(const char* name); Elf_Addr getSymbAddress(const char* name);
...@@ -56,11 +56,17 @@ namespace SandHook { ...@@ -56,11 +56,17 @@ namespace SandHook {
Elf_Shdr* symtab = nullptr; Elf_Shdr* symtab = nullptr;
Elf_Shdr* strtab = nullptr; Elf_Shdr* strtab = nullptr;
Elf_Shdr* dynsym = nullptr; Elf_Shdr* dynsym = nullptr;
Elf_Sym* sym_start = nullptr; Elf_Off dynsym_count = 0;
Elf_Sym* symtab_start = nullptr;
Elf_Sym* dynsym_start = nullptr;
Elf_Sym* strtab_start = nullptr;
Elf_Off symtab_count = 0; Elf_Off symtab_count = 0;
Elf_Off symstr_offset = 0; Elf_Off symstr_offset = 0;
Elf_Off symstr_offset_for_symtab = 0;
Elf_Off symtab_offset = 0; Elf_Off symtab_offset = 0;
Elf_Off dynsym_offset = 0;
Elf_Off symtab_size = 0; Elf_Off symtab_size = 0;
Elf_Off dynsym_size = 0;
}; };
} }
} }
......
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