-
Notifications
You must be signed in to change notification settings - Fork 175
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Showing
4,525 changed files
with
966,963 additions
and
0 deletions.
The diff you're trying to view is too large. We only load the first 3000 changed files.
There are no files selected for viewing
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,280 @@ | ||
#ifndef __ADDR_ANY_H__ | ||
#define __ADDR_ANY_H__ | ||
|
||
|
||
//linux | ||
#include <regex.h> | ||
#include <cxxabi.h> | ||
//c | ||
#include <cinttypes> | ||
#include <cstdio> | ||
#include <cstdlib> | ||
|
||
//c++ | ||
#include <string> | ||
#include <map> | ||
//project | ||
#include "elfio.hpp" | ||
|
||
|
||
|
||
class AddrAny | ||
{ | ||
public: | ||
AddrAny() | ||
{ | ||
m_init = get_exe_pathname(m_fullname); | ||
m_baseaddr = 0; | ||
} | ||
AddrAny(std::string libname) | ||
{ | ||
m_init = get_lib_pathname_and_baseaddr(libname, m_fullname, m_baseaddr); | ||
} | ||
|
||
int get_local_func_addr_symtab(std::string func_name_regex_str, std::map<std::string,void*>& result) | ||
{ | ||
return get_func_addr(SHT_SYMTAB, STB_LOCAL, func_name_regex_str, result); | ||
} | ||
int get_global_func_addr_symtab(std::string func_name_regex_str, std::map<std::string,void*>& result) | ||
{ | ||
return get_func_addr(SHT_SYMTAB, STB_GLOBAL, func_name_regex_str, result); | ||
} | ||
int get_weak_func_addr_symtab(std::string func_name_regex_str, std::map<std::string,void*>& result) | ||
{ | ||
return get_func_addr(SHT_SYMTAB, STB_WEAK, func_name_regex_str, result); | ||
} | ||
|
||
int get_global_func_addr_dynsym( std::string func_name_regex_str, std::map<std::string,void*>& result) | ||
{ | ||
return get_func_addr(SHT_DYNSYM, STB_GLOBAL, func_name_regex_str, result); | ||
} | ||
int get_weak_func_addr_dynsym(std::string func_name_regex_str, std::map<std::string,void*>& result) | ||
{ | ||
return get_func_addr(SHT_DYNSYM, STB_WEAK, func_name_regex_str, result); | ||
} | ||
|
||
private: | ||
bool demangle(std::string& s, std::string& name) { | ||
int status; | ||
char* pname = abi::__cxa_demangle(s.c_str(), 0, 0, &status); | ||
if (status != 0) | ||
{ | ||
switch(status) | ||
{ | ||
case -1: name = "memory allocation error"; break; | ||
case -2: name = "invalid name given"; break; | ||
case -3: name = "internal error: __cxa_demangle: invalid argument"; break; | ||
default: name = "unknown error occured"; break; | ||
} | ||
return false; | ||
} | ||
name = pname; | ||
free(pname); | ||
return true; | ||
} | ||
bool get_exe_pathname( std::string& name) | ||
{ | ||
char line[512]; | ||
FILE *fp; | ||
uintptr_t base_addr; | ||
char perm[5]; | ||
unsigned long offset; | ||
int pathname_pos; | ||
char *pathname; | ||
size_t pathname_len; | ||
int match = 0; | ||
|
||
if(NULL == (fp = fopen("/proc/self/maps", "r"))) | ||
{ | ||
return false; | ||
} | ||
|
||
while(fgets(line, sizeof(line), fp)) | ||
{ | ||
if(sscanf(line, "%" PRIxPTR "-%*lx %4s %lx %*x:%*x %*d%n", &base_addr, perm, &offset, &pathname_pos) != 3) continue; | ||
|
||
if(0 != offset) continue; | ||
|
||
//get pathname | ||
while(isspace(line[pathname_pos]) && pathname_pos < (int)(sizeof(line) - 1)) | ||
pathname_pos += 1; | ||
if(pathname_pos >= (int)(sizeof(line) - 1)) continue; | ||
pathname = line + pathname_pos; | ||
pathname_len = strlen(pathname); | ||
if(0 == pathname_len) continue; | ||
if(pathname[pathname_len - 1] == '\n') | ||
{ | ||
pathname[pathname_len - 1] = '\0'; | ||
pathname_len -= 1; | ||
} | ||
if(0 == pathname_len) continue; | ||
if('[' == pathname[0]) continue; | ||
|
||
name = pathname; | ||
match = 1; | ||
break; | ||
|
||
} | ||
fclose(fp); | ||
|
||
if(0 == match) | ||
{ | ||
return false; | ||
} | ||
else | ||
{ | ||
return true; | ||
} | ||
|
||
} | ||
|
||
bool get_lib_pathname_and_baseaddr(std::string pathname_regex_str, std::string& name, unsigned long& addr) | ||
{ | ||
char line[512]; | ||
FILE *fp; | ||
uintptr_t base_addr; | ||
char perm[5]; | ||
unsigned long offset; | ||
int pathname_pos; | ||
char *pathname; | ||
size_t pathname_len; | ||
int match; | ||
regex_t pathname_regex; | ||
|
||
regcomp(&pathname_regex, pathname_regex_str.c_str(), 0); | ||
|
||
if(NULL == (fp = fopen("/proc/self/maps", "r"))) | ||
{ | ||
return false; | ||
} | ||
|
||
while(fgets(line, sizeof(line), fp)) | ||
{ | ||
if(sscanf(line, "%" PRIxPTR "-%*lx %4s %lx %*x:%*x %*d%n", &base_addr, perm, &offset, &pathname_pos) != 3) continue; | ||
|
||
//check permission | ||
if(perm[0] != 'r') continue; | ||
if(perm[3] != 'p') continue; //do not touch the shared memory | ||
|
||
//check offset | ||
// | ||
//We are trying to find ELF header in memory. | ||
//It can only be found at the beginning of a mapped memory regions | ||
//whose offset is 0. | ||
if(0 != offset) continue; | ||
|
||
//get pathname | ||
while(isspace(line[pathname_pos]) && pathname_pos < (int)(sizeof(line) - 1)) | ||
pathname_pos += 1; | ||
if(pathname_pos >= (int)(sizeof(line) - 1)) continue; | ||
pathname = line + pathname_pos; | ||
pathname_len = strlen(pathname); | ||
if(0 == pathname_len) continue; | ||
if(pathname[pathname_len - 1] == '\n') | ||
{ | ||
pathname[pathname_len - 1] = '\0'; | ||
pathname_len -= 1; | ||
} | ||
if(0 == pathname_len) continue; | ||
if('[' == pathname[0]) continue; | ||
|
||
//check pathname | ||
//if we need to hook this elf? | ||
match = 0; | ||
if(0 == regexec(&pathname_regex, pathname, 0, NULL, 0)) | ||
{ | ||
match = 1; | ||
name = pathname; | ||
addr = (unsigned long)base_addr; | ||
break; | ||
} | ||
if(0 == match) continue; | ||
|
||
} | ||
fclose(fp); | ||
if(0 == match) | ||
{ | ||
return false; | ||
} | ||
else | ||
{ | ||
return true; | ||
} | ||
|
||
} | ||
|
||
int get_func_addr(unsigned int ttype, unsigned int stype, std::string& func_name_regex_str, std::map<std::string,void*>& result) | ||
{ | ||
// Create an elfio reader | ||
ELFIO::elfio reader; | ||
int count = 0; | ||
regex_t pathname_regex; | ||
|
||
if(!m_init) | ||
{ | ||
return -1; | ||
} | ||
|
||
regcomp(&pathname_regex, func_name_regex_str.c_str(), 0); | ||
// Load ELF data | ||
if(!reader.load(m_fullname.c_str())) | ||
{ | ||
return -1; | ||
} | ||
|
||
ELFIO::Elf_Half sec_num = reader.sections.size(); | ||
for(int i = 0; i < sec_num; ++i) | ||
{ | ||
ELFIO::section* psec = reader.sections[i]; | ||
// Check section type | ||
if(psec->get_type() == ttype) | ||
{ | ||
const ELFIO::symbol_section_accessor symbols( reader, psec ); | ||
for ( unsigned int j = 0; j < symbols.get_symbols_num(); ++j ) | ||
{ | ||
std::string name; | ||
std::string name_mangle; | ||
ELFIO::Elf64_Addr value; | ||
ELFIO::Elf_Xword size; | ||
unsigned char bind; | ||
unsigned char type; | ||
ELFIO::Elf_Half section_index; | ||
unsigned char other; | ||
|
||
// Read symbol properties | ||
symbols.get_symbol( j, name, value, size, bind, type, section_index, other ); | ||
if(type == STT_FUNC && bind == stype) | ||
{ | ||
bool ret = demangle(name,name_mangle); | ||
if(ret == true) | ||
{ | ||
if (0 == regexec(&pathname_regex, name_mangle.c_str(), 0, NULL, 0)) | ||
{ | ||
result.insert ( std::pair<std::string,void *>(name_mangle,(void*)(value + m_baseaddr))); | ||
count++; | ||
} | ||
} | ||
else | ||
{ | ||
if (0 == regexec(&pathname_regex, name.c_str(), 0, NULL, 0)) | ||
{ | ||
result.insert ( std::pair<std::string,void *>(name,(void*)(value + m_baseaddr))); | ||
count++; | ||
} | ||
} | ||
} | ||
} | ||
break; | ||
} | ||
} | ||
|
||
return count; | ||
} | ||
private: | ||
bool m_init; | ||
std::string m_name; | ||
std::string m_fullname; | ||
unsigned long m_baseaddr; | ||
|
||
}; | ||
#endif |
Oops, something went wrong.