-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Description
Hi there! Apparently PIE is enabled default in my distro and/or since gcc 6, which breaks this library. It looks for the PLT section in elf->plt
which here has the value 0x6a0
but the elf is loaded at addresses like 0x555555554000
(when aslr is disabled)
$ ASYNCSAFE_LOGGING=1 gdb --args ./testlink
Reading symbols from ./testlink...done.
(gdb) run
Starting program: /home/dx/test/asd/monorail/asyncsafe/testlink
getting ELF info for [/proc/7859/exe]
asyncsafe: intercept signal 10 registration of handler 0x5555555547fa
asyncsafe: intercept signal 12 registration of handler 0x55555555481e
Program received signal SIGUSR1, User defined signal 1.
0x00007ffff7850860 in raise () from /usr/lib/libc.so.6
(gdb) c
Continuing.
asyncsafe on vvv
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7bd593d in change_resolve_func (elf=0x7ffff7dd7800 <elf>, hijack=1)
at plt.c:28
28 unsigned long handler = *(unsigned int *)(elf->plt + 8) + elf->plt + 8 + 4;
(gdb) bt
#0 0x00007ffff7bd593d in change_resolve_func (elf=0x7ffff7dd7800 <elf>, hijack=1)
at plt.c:28
#1 0x00007ffff7bd5c6c in enable_intercept () at plt.c:84
#2 0x00007ffff7bd5025 in asyncsafe_intercept (signum=10, info=0x7fffffffdff0,
context=0x7fffffffdec0) at safe.c:47
#3 <signal handler called>
#4 0x00007ffff7850860 in raise () from /usr/lib/libc.so.6
#5 0x0000555555554868 in main () at test.c:17
(gdb) p elf
$1 = (elf_t *) 0x7ffff7dd7800 <elf>
(gdb) p *elf
$2 = {map = 0x7ffff7ff1000, length = 12664, fd = 3, header = 0x7ffff7ff1000,
sheader = 0x7ffff7ff38b8, pheader = 0x7ffff7ff1040,
shstrtab = 0x7ffff7ff375f "", strtab = 0x7ffff7ff3520 "",
dynstr = 0x7ffff7ff1438 "", plt = 1696, plt_size = 80,
rela_plt = 0x7ffff7ff3b38, got_plt = 0x7ffff7ff3e38, symtab = 0x7ffff7ff40b8,
dynsym = 0x7ffff7ff39f8}
(gdb) p elf->plt
$3 = 1696
Stupid/dirty patch that assumes no aslr:
diff --git a/elfmap.c b/elfmap.c
index 4354e8a..c97b023 100644
--- a/elfmap.c
+++ b/elfmap.c
@@ -11,6 +11,8 @@
#define die(str) \
puts(str), exit(1)
+extern unsigned long base_address;
+
static void verify_elf(elf_t *elf);
static void find_basic(elf_t *elf);
static void find_strtab(elf_t *elf);
@@ -106,7 +108,7 @@ static void find_got_and_plt(elf_t *elf) {
Elf64_Shdr *s = &elf->sheader[i];
const char *name = elf->shstrtab + s->sh_name;
if(!strcmp(name, ".plt")) {
- elf->plt = (unsigned long)s->sh_addr;
+ elf->plt = (unsigned long)s->sh_addr + base_address;
elf->plt_size = (unsigned long)s->sh_size;
}
else if(!strcmp(name, ".got.plt")) {
diff --git a/safe.c b/safe.c
index fdae01d..3ab05bb 100644
--- a/safe.c
+++ b/safe.c
@@ -11,7 +11,7 @@
/* --- Initialization & ELF processing--- */
elf_t elf;
-unsigned long base_address = 0; // base of elf, for shared libraries
+unsigned long base_address = 0x555555554000; // base of elf, for shared libraries
void asyncsafe_init(void) {
static int initialized = 0;
Not sure what's the right way to get the base address, first line of /proc/pid/maps
?
Metadata
Metadata
Assignees
Labels
No labels