-
Feb 1st, 2009, 05:20 PM
#1
Thread Starter
Hyperactive Member
[Linux] Redirecting parent functions from shared object
Hi deLusion`
Okay so an implementation of the following would be if you need to redirect a library to another one.
For example, application aaa.x86 loads bbb.so, and you would like to load your own shared library (via LD_PRELOAD), which would in turn stop xxx.x86 loading bbb.so, and make it load ccc.so.
elf.cpp
Code:
#include "elf.h"
bool HookGlobalFunc(const char *SymbolName, void *HookFunc) {
int fileDescriptor = open("/proc/self/exe", O_RDONLY); // We'll only need to hook Global funcs from et.x86
elf_version(EV_CURRENT);
Elf *elf = elf_begin(fileDescriptor, ELF_C_READ, NULL);
Elf32_Ehdr *header = 0; // ELF Header
Elf_Scn *section = 0; // ELF Section
Elf_Data *sectionData = 0; // ELF Section Data
Elf32_Shdr *sectionHeader = 0; // ELF Section Header
int symbolNumber = -1;
if(!elf) { goto end; /* close(fileDescriptor); return false;*/ }
unsigned short ndx;
if((header = elf32_getehdr(elf)) == 0) {
goto error;
//elf_end(elf);
//close(fileDescriptor);
//return false;
}
ndx = header->e_shstrndx;
// Go through the sections
// .dynsym = Dynamic Symbol Location (linked with .hash and .dynstr)
while((section = elf_nextscn(elf, section)) != 0) {
char *name = 0;
if((sectionHeader = elf32_getshdr(section)) != 0) {
name = elf_strptr(elf, ndx, (size_t)sectionHeader->sh_name);
if(!strcmp(name, ".dynsym")) {
Elf32_Shdr *strtabhdr;
Elf32_Sym *symbol, *symbolp; // ELF Symbol Pointers
char *string;
strtabhdr = §ionHeader[sectionHeader->sh_link];
string = (char *)malloc(strtabhdr->sh_size);
if(string == NULL) goto error;
if((size_t)lseek(fileDescriptor, strtabhdr->sh_offset, SEEK_SET) != strtabhdr->sh_offset) goto error;
if((size_t)read(fileDescriptor, string, strtabhdr->sh_size) != strtabhdr->sh_size) goto error;
symbol = (Elf32_Sym *)malloc(sectionHeader->sh_size);
if(symbol == NULL) goto error;
if((size_t)lseek(fileDescriptor, sectionHeader->sh_offset, SEEK_SET) != sectionHeader->sh_offset) goto error;
if((size_t)read(fileDescriptor, symbol, sectionHeader->sh_size) != sectionHeader->sh_size) goto error;
symbolp = symbol;
for(int i = 0; (size_t)i < sectionHeader->sh_size; i += sizeof(Elf32_Sym)) {
if(!strcmp(elf_strptr(elf, sectionHeader->sh_link, symbolp->st_name), SymbolName)) {
symbolNumber = symbolp - symbol;
break;
}
++symbolp;
}
free(string);
} else continue;
} else continue;
}
// .rel.plt = Relocation Procedure Linkage Table (Actual GOT)
if(symbolNumber == -1) goto error;
// Lookup the Hash from .dynsym in .rel.plt
section = 0; sectionHeader = 0;
while((section = elf_nextscn(elf, section)) != 0) {
char *name = 0;
if((sectionHeader = elf32_getshdr(section)) != 0) {
name = elf_strptr(elf, ndx, (size_t)sectionHeader->sh_name);
if(!strcmp(name, ".rel.plt")) {
sectionData = elf_getdata(section, NULL);
if(!sectionData) goto error;
for(int i = 0; (size_t)i < (sectionHeader->sh_size / sectionHeader->sh_entsize); i++) {
GElf_Rel relocation;
gelf_getrel(sectionData, i, &relocation);
if(ELF64_R_SYM(relocation.r_info) == (size_t)symbolNumber) {
if(HookFunc == NULL) {
// Debug
printf("Symbol '%s' found at 0x%x\n", SymbolName, (unsigned int)relocation.r_offset);
} else {
#ifdef DEBUG
// Only on absolute debug build in muppetTools/
printf("Found symbol (%i) at %x redirecting to %x\n", symbolNumber, relocation.r_offset, &HookFunc);
#endif
*(void **)(unsigned int)relocation.r_offset = HookFunc;
}
}
}
} else continue;
} else continue;
}
end:
close(fileDescriptor);
elf_end(elf);
return true;
error:
close(fileDescriptor);
elf_end(elf);
return false;
}
elf.h
Code:
#pragma once
#include <libelf.h>
#include <gelf.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
bool HookGlobalFunc(const char *SymbolName, void *HookFunc);
Implementation example (.cpp for compilation into a shared object):
Code:
void *_dlopen(const char *fileName, int flags) {
if(strstr(fileName, "bbb.so"))
return dlopen("ccc.so", flags);
else
return dlopen(fileName, flags);
}
void __atrribute__ ((constructor)) MyMain(void) {
HookGlobalFunc("dlopen", (void *)&_dlopen);
}
Last edited by RudiVisser; Feb 2nd, 2009 at 03:40 PM.
» Twitter: @rudi_visser : Website: www.rudiv.se «
If Apple fixes security flaws, they are heralded as proactive. If Microsoft fixes a security flaw, they finally got around to fixing their buggy OS.
-
Mar 10th, 2009, 12:31 AM
#2
Banned
Re: [Linux] Redirecting parent functions from shared object
That is interesting one thanks for sharing it..
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|