-
Notifications
You must be signed in to change notification settings - Fork 13
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 a59a316
Showing
36 changed files
with
1,843 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 @@ | ||
/* $Id: args2.c,v 1.2 2014/02/12 17:48:03 bediger Exp $ */ | ||
#include <stdio.h> | ||
int | ||
main(int ac, char **av) | ||
{ | ||
int i; | ||
printf("argc at %p\n", &ac); | ||
printf("argv[0] at %p\n", &av[0]); | ||
printf("argc %d\n", ac); | ||
for (i = 0; i < ac; ++i) | ||
printf("%d: \"%s\"\n", i, av[i]); | ||
return 0; | ||
} |
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,169 @@ | ||
#include <libstatic/libstatic.h> | ||
|
||
#include <elf.h> | ||
#include <sys/types.h> | ||
#include <sys/stat.h> | ||
|
||
#include <ulexec.h> | ||
|
||
#include <libstatic/crt.h> | ||
|
||
#define JMP_ADDR(x) asm("\tjmp *%0\n" :: "r" (x)) | ||
#define SET_STACK(x) asm("\tmovq %0, %%rsp\n" :: "r"(x)) | ||
|
||
void | ||
print_maps(void) | ||
{ | ||
char rbuf[1024]; | ||
int fd, cc; | ||
|
||
fd = linux_open("/proc/self/maps", 0, 0); | ||
while (0 < (cc = linux_read(fd, rbuf, sizeof(rbuf)))) | ||
linux_write(1, rbuf, cc); | ||
linux_close(fd); | ||
} | ||
|
||
void c_main(int ac, char **av, char **env) | ||
{ | ||
char *file_to_map = av[3]; | ||
char *file_to_unmap = av[2]; | ||
int how_to_map = 0; | ||
void *mapped; | ||
void *entry_point; | ||
struct stat sb; | ||
Elf64_Ehdr *elf_ehdr, *ldso_ehdr; | ||
struct saved_block *argvb, *envb, *elfauxvb; | ||
int trim_args; | ||
void *stack_bottom; | ||
unsigned long empty[32768]; | ||
|
||
empty[0] = 1; | ||
|
||
if (NULL == strstr(av[1], "dyn_unmap_run")) | ||
{ | ||
file_to_map = av[1]; | ||
file_to_unmap = NULL; | ||
how_to_map = 1; | ||
trim_args = 1; | ||
} else { | ||
file_to_map = av[2]; | ||
file_to_unmap = av[0]; | ||
how_to_map = 0; | ||
trim_args = 2; | ||
} | ||
|
||
if (file_to_unmap) | ||
unmap(file_to_unmap); | ||
|
||
mapped = map_file(file_to_map); | ||
elf_ehdr = (Elf64_Ehdr *)mapped; | ||
|
||
entry_point = load_elf(mapped, how_to_map, &elf_ehdr, &ldso_ehdr); | ||
|
||
linux_munmap(mapped, sb.st_size); | ||
|
||
argvb = save_argv(ac - trim_args, &av[trim_args]); | ||
envb = save_argv(0, env); | ||
elfauxvb = save_elfauxv(env); | ||
|
||
stack_bottom = stack_setup(argvb, envb, elfauxvb, elf_ehdr, ldso_ehdr); | ||
|
||
SET_STACK(stack_bottom); | ||
JMP_ADDR(entry_point); | ||
} | ||
|
||
void | ||
error_msg(char *msg) | ||
{ | ||
char buf[32]; | ||
print_string(1, msg); | ||
print_string(1, " "); | ||
to_decimal(errno, buf); | ||
print_string(1, buf); | ||
print_string(1, "\n"); | ||
} | ||
|
||
void | ||
print_address(char *phrase, void *address) | ||
{ | ||
char buf[256]; | ||
to_hex((unsigned long)address, buf); | ||
print_string(1, phrase); | ||
print_string(1, " 0x"); | ||
print_string(1, buf); | ||
print_string(1, "\n"); | ||
} | ||
|
||
void | ||
unmap(char *progname) | ||
{ | ||
char buf[1024], *p; | ||
char rbuf[2048]; | ||
int cc, fd; | ||
|
||
fd = linux_open("/proc/self/maps", 0, 0); | ||
|
||
p = &buf[0]; | ||
|
||
while (0 < (cc = linux_read(fd, rbuf, sizeof(rbuf)))) | ||
{ | ||
int i; | ||
|
||
for (i = 0; i < cc; ++i) | ||
{ | ||
int c = rbuf[i]; | ||
|
||
if ('\n' != c) | ||
*p++ = c; | ||
else { | ||
*p = '\0'; | ||
/* When a line from /proc/self/maps shows up as having been | ||
* mapped in from this running program, ld.so or libc, unmap it. | ||
* This will keep the exec'd program's address space a lot | ||
* cleaner. But even a 32-bit address space can hold 2 copies | ||
* of glibc without ill effects, so you don't really have to | ||
* munmap() anything other than the program calling ul_exec() */ | ||
if (strstr(buf, progname) || strstr(buf, "libdl") || strstr(buf, "/usr/lib/ld-") | ||
|| strstr(buf, "/lib64/ld-") || strstr(buf, "libc")) | ||
{ | ||
char *u; | ||
char *first, *second; | ||
unsigned long low, high; | ||
|
||
u = strchr(buf, ' '); | ||
*u = '\0'; | ||
|
||
first = buf; | ||
|
||
second = strchr(first, '-'); | ||
*second = '\0'; | ||
++second; | ||
|
||
low = strtoul(first, NULL, 0x10); | ||
high = strtoul(second, NULL, 0x10); | ||
|
||
linux_munmap((void *)low, high-low); | ||
} | ||
|
||
p = &buf[0]; | ||
} | ||
} | ||
} | ||
|
||
linux_close(fd); | ||
} | ||
|
||
/* | ||
void * | ||
memcpy(void *dest, const void *src, unsigned long n) | ||
{ | ||
unsigned long i; | ||
unsigned char *d = (unsigned char *)dest; | ||
unsigned char *s = (unsigned char *)src; | ||
for (i = 0; i < n; ++i) | ||
d[i] = s[i]; | ||
return dest; | ||
} | ||
*/ |
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,156 @@ | ||
/* $Id: elfauxv.c,v 1.2 2014/02/12 17:48:03 bediger Exp $ */ | ||
#include <libstatic/libstatic.h> | ||
#include <elf.h> | ||
|
||
#include <libstatic/crt.h> | ||
|
||
typedef unsigned long uint64_t; | ||
#define BUFSIZ 1024 | ||
char *printable_aux_type(uint64_t a_val); | ||
|
||
void | ||
print_data( | ||
int i, void *auxvp, | ||
int a_type, unsigned long a_val | ||
) | ||
{ | ||
print_long(1, (unsigned long)i); | ||
print_string(1, " "); | ||
print_hex(1, (unsigned long)auxvp); | ||
print_string(1, " a_type "); | ||
print_long(1, (unsigned long)a_type); | ||
print_string(1, ", "); | ||
print_string(1, printable_aux_type(a_type)); | ||
print_string(1, ": a_un.a_val "); | ||
print_hex(1, a_val); | ||
print_string(1, "\n"); | ||
|
||
/* | ||
printf("%d %p a_type %lu, %s: a_un.a_val 0x%lx\n", | ||
i, auxvp, | ||
auxvp->a_type, printable_aux_type(auxvp->a_type), | ||
auxvp->a_un.a_val); | ||
*/ | ||
} | ||
|
||
char * | ||
printable_aux_type(uint64_t a_val) | ||
{ | ||
char *r = "Unknown"; | ||
switch (a_val) | ||
{ | ||
case AT_NULL: r = "End of vector"; break; | ||
case AT_IGNORE: r = "Entry should be ignored"; break; | ||
case AT_EXECFD: r = "File descriptor of program"; break; | ||
case AT_PHDR: r = "Program headers for program"; break; | ||
case AT_PHENT: r = "Size of program header entry"; break; | ||
case AT_PHNUM: r = "Number of program headers"; break; | ||
case AT_PAGESZ: r = "System page size"; break; | ||
case AT_BASE: r = "Base address of interpreter"; break; | ||
case AT_FLAGS: r = "Flags"; break; | ||
case AT_ENTRY: r = "Entry point of program"; break; | ||
case AT_NOTELF: r = "Program is not ELF"; break; | ||
case AT_UID: r = "Real uid"; break; | ||
case AT_EUID: r = "Effective uid"; break; | ||
case AT_GID: r = "Real gid"; break; | ||
case AT_EGID: r = "Effective gid"; break; | ||
case AT_CLKTCK: r = "Frequency of times()"; break; | ||
case AT_PLATFORM: r = "String identifying platform. "; break; | ||
case AT_HWCAP: r = "Machine dependent hints about processor capabilities. "; break; | ||
case AT_FPUCW: r = "Used FPU control word. "; break; | ||
case AT_DCACHEBSIZE: r = "Data cache block size. "; break; | ||
case AT_ICACHEBSIZE: r = "Instruction cache block size. "; break; | ||
case AT_UCACHEBSIZE: r = "Unified cache block size. "; break; | ||
case AT_IGNOREPPC: r = "Entry should be ignored. "; break; | ||
case AT_SECURE: r = "Boolean, was exec setuid-like? "; break; | ||
/* The following ifdefs exist because apparently glibc starting | ||
* defining new auxillary types */ | ||
#ifdef AT_BASE_PLATFORM | ||
case AT_BASE_PLATFORM: r= "String identifying real platforms."; break; | ||
#endif | ||
#ifdef AT_RANDOM | ||
case AT_RANDOM: r = "Address of 16 random bytes. "; break; | ||
#endif | ||
#ifdef AT_EXECFN | ||
case AT_EXECFN: r = "Filename of executable. "; break; | ||
#endif | ||
case AT_SYSINFO: r = "Address of VDSO"; break; | ||
case AT_SYSINFO_EHDR: r = "AT_SYSINFO_EHDR"; break; | ||
#ifdef AT_L1I_CACHESHAPE | ||
case AT_L1I_CACHESHAPE: r = "AT_L1I_CACHESHAPE"; break; | ||
case AT_L1D_CACHESHAPE: r = "AT_L1D_CACHESHAPE"; break; | ||
case AT_L2_CACHESHAPE: r = "AT_L2_CACHESHAPE"; break; | ||
case AT_L3_CACHESHAPE: r = "AT_L3_CACHESHAPE"; break; | ||
#endif | ||
} | ||
return r; | ||
} | ||
|
||
void | ||
print_maps(void) | ||
{ | ||
char rbuf[BUFSIZ]; | ||
int fd, cc; | ||
|
||
fd = linux_open("/proc/self/maps", 0, 0); | ||
while (0 < (cc = linux_read(fd, rbuf, sizeof(rbuf)))) | ||
linux_write(1, rbuf, cc); | ||
linux_close(fd); | ||
} | ||
|
||
void | ||
c_main(int ac, char **av, char **envp) | ||
{ | ||
int i; | ||
unsigned long *p; | ||
Elf64_auxv_t *auxvp; | ||
|
||
print_maps(); | ||
|
||
print_string(1, "ac "); | ||
print_long(1, ac); | ||
print_string(1, "\n"); | ||
|
||
print_string(1, "av[0] holds "); | ||
print_hex(1, (unsigned long)av[0]); | ||
print_string(1, "\n"); | ||
|
||
print_string(1, "envp[0] holds "); | ||
print_hex(1, (unsigned long)envp[0]); | ||
print_string(1, "\n"); | ||
|
||
p = (unsigned long *)&envp[0]; | ||
|
||
while (*p != 0) | ||
++p; | ||
|
||
print_string(1, "First NULL 8-byte word at "); | ||
print_hex(1, (unsigned long)p); | ||
print_string(1, "\n"); | ||
|
||
|
||
for (i = 0, | ||
auxvp = (Elf64_auxv_t *)(p + 1); | ||
auxvp->a_type != AT_NULL; | ||
++auxvp, ++i | ||
) { | ||
char *str; | ||
|
||
print_data(i, auxvp, auxvp->a_type, auxvp->a_un.a_val); | ||
|
||
switch (auxvp->a_type) | ||
{ | ||
case AT_PLATFORM: | ||
#ifdef AT_EXECFN | ||
case AT_EXECFN: | ||
#endif | ||
str = (char *)auxvp->a_un.a_val; | ||
print_string(1, "\t\""); | ||
print_string(1, str); | ||
print_string(1, "\"\n"); | ||
break; | ||
} | ||
} | ||
|
||
linux_exit(0); | ||
} |
Oops, something went wrong.