-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 9accf90
Showing
6 changed files
with
580 additions
and
0 deletions.
There are no files selected for viewing
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,13 @@ | ||
all: ld-shatner interpatch | ||
|
||
obj.elf: obj.c | ||
gcc -fpie -c obj.c -o obj.o | ||
ld -pie obj.o -o $@ -e func | ||
|
||
ld-shatner: hooked.s ld-shatner.c obj.elf | ||
gcc hooked.s ld-shatner.c -o $@ | ||
|
||
interpatch: interpatch.o | ||
|
||
clean: | ||
rm -f ld-shatner interpatch ld-hook.so obj.elf *.o |
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,9 @@ | ||
$ make clean all | ||
$ cp /lib/ld-linux.so.2 . | ||
$ cp /bin/ls . | ||
$ ./ld-shatner ld-linux.so.2 obj.elf | ||
$ sudo cp ld-hook.so /lib/ | ||
$ ./interpatch ls | ||
$ ./ls | ||
ld-hook <---------------------- output of obj.elf | ||
[...] |
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,111 @@ | ||
.text | ||
.globl shatner, payload | ||
.type shatner,"function" | ||
.type payload,"function" | ||
|
||
shatner: | ||
jmp 1f | ||
__old_ld: | ||
.long 0 /* ld original entry point (from 0) */ | ||
__old_user: | ||
.long 0 /* location to store original user entry point (from 0) */ | ||
__inject_entry: /* entry point of injected code (from 0) */ | ||
.long 0 | ||
1: | ||
pushl $0 | ||
push %eax | ||
lea 8(%esp), %eax | ||
push %edx | ||
push %ecx | ||
call __get_pc | ||
__get_pc: | ||
pop %edx | ||
mov %edx, %ecx | ||
add $(payload_caller - __get_pc), %edx | ||
sub $(__get_pc - __old_user), %ecx | ||
push %ebx | ||
push %edi | ||
xor %edi, %edi | ||
fix_auxv: /* walk stack to find 2 NULL words (one ending argv, one ending envp) */ | ||
mov (%eax), %ebx | ||
test %ebx, %ebx | ||
jnz next_word | ||
inc %edi | ||
cmp $2, %edi | ||
je auxv_found | ||
next_word: | ||
add $4, %eax | ||
jmp fix_auxv | ||
|
||
auxv_found: /* found second NULL word, start lokking for AUX_TYPE==ENTRY (9) */ | ||
add $4, %eax | ||
next_tag: | ||
cmp $9, (%eax) | ||
je auxv_entry_tag_found | ||
add $8, %eax | ||
jmp next_tag | ||
|
||
auxv_entry_tag_found: | ||
add $4, %eax | ||
mov (%eax), %edi | ||
mov (%ecx), %ecx | ||
push %esi | ||
call __get_pc2 | ||
__get_pc2: | ||
pop %esi | ||
sub $((__get_pc2 - shatner)+52), %esi /* base address of ld in memory */ | ||
add %esi, %ecx | ||
mov %edi, (%ecx) /* save user entry */ | ||
mov %edx, (%eax) /* install new one */ | ||
|
||
resume_ld: | ||
sub $(payload_caller - __old_ld), %edx | ||
mov (%edx), %edx | ||
add %esi, %edx /* base + ld original entry */ | ||
pop %esi | ||
pop %edi | ||
pop %ebx | ||
pop %ecx | ||
mov %edx, 8(%esp) | ||
pop %edx | ||
pop %eax | ||
ret | ||
|
||
payload_caller: | ||
call real_payload_caller | ||
push $0 | ||
push %eax | ||
call __get_pc3 | ||
__get_pc3: | ||
pop %eax | ||
push %edx | ||
mov %eax, %edx | ||
sub $((__get_pc3 - shatner)+52), %eax /* base address of ld in memory */ | ||
sub $(__get_pc3 - __old_user), %edx /* user offset */ | ||
mov (%edx), %edx | ||
add %eax, %edx | ||
mov (%edx), %eax /* original user entry */ | ||
movl $0, (%edx) /* clear place */ | ||
mov %eax, 8(%esp) | ||
pop %edx | ||
pop %eax | ||
ret | ||
real_payload_caller: | ||
push %eax | ||
call __get_pc4 | ||
__get_pc4: | ||
pop %eax | ||
push %edx | ||
mov %eax, %edx | ||
add $(payload - __get_pc4), %eax | ||
sub $(__get_pc4 - __inject_entry), %edx /* injected entry offset */ | ||
mov (%edx), %edx | ||
add %edx, %eax | ||
call *%eax | ||
pop %edx | ||
pop %eax | ||
ret | ||
|
||
.align 4 | ||
payload: | ||
nop |
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,58 @@ | ||
#include <stdio.h> | ||
#include <elf.h> | ||
#include <sys/types.h> | ||
#include <sys/stat.h> | ||
#include <sys/mman.h> | ||
#include <string.h> | ||
#include <fcntl.h> | ||
|
||
#define LDNAME "/lib/ld-hook.so" | ||
|
||
int main(int argc, char **argv) | ||
{ | ||
Elf32_Ehdr *e_hdr; | ||
Elf32_Phdr *p_hdr; | ||
int fd, i; | ||
off_t fd_sz; | ||
uint32_t len, old; | ||
|
||
if (argc != 2) | ||
{ | ||
printf("usage: %s <elf>\n", argv[0]); | ||
return -1; | ||
} | ||
|
||
if ((fd = open(argv[1], O_RDWR)) == -1) | ||
{ | ||
printf("can't open file %s\n", argv[1]); | ||
return -1; | ||
} | ||
|
||
fd_sz = lseek(fd, 0, SEEK_END); | ||
lseek(fd, 0, SEEK_SET); | ||
e_hdr = (Elf32_Ehdr*)mmap(NULL, fd_sz, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); | ||
p_hdr = (Elf32_Phdr*)((uint32_t)e_hdr + e_hdr->e_phoff); | ||
|
||
len = strlen(LDNAME)+1; | ||
|
||
for (i=0 ; i<e_hdr->e_phnum ; i++, p_hdr++) | ||
if (p_hdr->p_type == PT_INTERP) | ||
{ | ||
if (p_hdr->p_filesz < len) | ||
{ | ||
printf("not enough space to fix interp name (%d)\n", p_hdr->p_filesz); | ||
return -1; | ||
} | ||
|
||
old = p_hdr->p_filesz; | ||
p_hdr->p_filesz = p_hdr->p_memsz = len; | ||
memcpy((void*)((uint32_t)e_hdr+p_hdr->p_offset), LDNAME, len-1); | ||
memset((void*)((uint32_t)e_hdr+p_hdr->p_offset+len-1), 0, old-len); | ||
|
||
/* XXX: should also fix section header ... */ | ||
} | ||
|
||
munmap((void*)e_hdr, fd_sz); | ||
close(fd); | ||
return 0; | ||
} |
Oops, something went wrong.