Skip to content

Commit

Permalink
chore: merge snipe-tmmp to master
Browse files Browse the repository at this point in the history
as title

log: as title
  • Loading branch information
Johnson-zs committed Sep 13, 2024
1 parent c7a1528 commit 8b45421
Show file tree
Hide file tree
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.
Empty file added 3rdparty/.gitkeep
Empty file.
280 changes: 280 additions & 0 deletions 3rdparty/testutils/cpp-stub/addr_any.h
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
Loading

0 comments on commit 8b45421

Please sign in to comment.