├── osx ├── alias.txt ├── zya │ ├── alias.txt │ ├── lib │ │ ├── todo.c │ │ ├── misc.c │ │ ├── lib.h │ │ └── lib.c │ ├── mk.sh │ └── beta.c ├── beta.c ├── loader │ ├── config.h │ ├── mke.sh │ ├── mke32.sh │ ├── mk.sh │ ├── README.txt │ ├── gelfload │ │ ├── bbuffer.h │ │ ├── elfload_dlfcn.h │ │ ├── elfnative.h │ │ ├── dlfcn.c │ │ ├── elfload_exec.h │ │ ├── elfload.h │ │ ├── bbuffer.c │ │ └── elfload.c │ ├── testlib.c │ ├── config32.h │ ├── config64.h │ ├── gnuh.c │ ├── cxa.c │ └── main.c ├── alpha.c ├── mk.sh └── testb.c ├── README.md └── linux ├── both.c ├── zya ├── lib │ ├── todo.c │ ├── misc.c │ ├── lib.h │ └── lib.c ├── mk.sh~ ├── mk.sh ├── tools │ ├── herp.py │ └── derp.py ├── beta.c~ └── beta.c ├── loader ├── mke.sh ├── mke32.sh ├── mk.sh ├── rune │ ├── mac.c │ ├── _types.h │ ├── none.c │ ├── mac-ctype.h │ ├── runetype.h │ └── runetable.c ├── cxa.c └── loader.c ├── alpha.c ├── testb.c ├── mk.sh └── beta.c /osx/alias.txt: -------------------------------------------------------------------------------- 1 | _x _y 2 | _alpha _beta 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Reexport symbols for Mach-O and ELF. 2 | -------------------------------------------------------------------------------- /osx/zya/alias.txt: -------------------------------------------------------------------------------- 1 | _zya99 _callui 2 | _zya146 _decode_insn 3 | -------------------------------------------------------------------------------- /osx/beta.c: -------------------------------------------------------------------------------- 1 | /* optional hacks here */ 2 | static int unused __attribute__((unused)); 3 | -------------------------------------------------------------------------------- /osx/loader/config.h: -------------------------------------------------------------------------------- 1 | #ifdef __LP64__ 2 | #include "config64.h" 3 | #else 4 | #include "config32.h" 5 | #endif 6 | -------------------------------------------------------------------------------- /linux/both.c: -------------------------------------------------------------------------------- 1 | int y; 2 | int x; 3 | 4 | void 5 | alpha(void) 6 | { 7 | } 8 | 9 | void 10 | beta(void) 11 | { 12 | } 13 | -------------------------------------------------------------------------------- /linux/zya/lib/todo.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | bool 4 | check_for_table_jump() 5 | { 6 | return 0; // module/jptcmn.cpp 7 | } 8 | -------------------------------------------------------------------------------- /osx/zya/lib/todo.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | bool 4 | check_for_table_jump() 5 | { 6 | return 0; // module/jptcmn.cpp 7 | } 8 | -------------------------------------------------------------------------------- /linux/zya/lib/misc.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "lib.h" 4 | 5 | bool 6 | is_refresh_requested(unsigned int mask) 7 | { 8 | return (get_dirty_infos() & mask) != 0; 9 | } 10 | -------------------------------------------------------------------------------- /osx/zya/lib/misc.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "lib.h" 4 | 5 | bool 6 | is_refresh_requested(unsigned int mask) 7 | { 8 | return (get_dirty_infos() & mask) != 0; 9 | } 10 | -------------------------------------------------------------------------------- /linux/loader/mke.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | gcc -o loader -Wall -W -pedantic -Wno-unused-function -Wno-variadic-macros -Wno-missing-field-initializers -O2 -I. -Irune -DXSYMBOL=ZYA -DXSYMBOL_SIZE=0x90 -DHAVE_MAIN loader.c cxa.c rune/mac.c -ldl 4 | -------------------------------------------------------------------------------- /linux/loader/mke32.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | gcc -o loader -m32 -Wall -W -pedantic -Wno-unused-function -Wno-variadic-macros -Wno-missing-field-initializers -O2 -I. -Irune -DXSYMBOL=ZYA -DXSYMBOL_SIZE=0x90 -DHAVE_MAIN loader.c cxa.c rune/mac.c -ldl 4 | -------------------------------------------------------------------------------- /osx/loader/mke.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | gcc -o loader -Wall -W -pedantic -Wno-unused-parameter -Wno-variadic-macros -O2 -I. -Igelfload -DXSYMBOL_SIZE=1 -DHAVE_MAIN main.c gnuh.c cxa.c gelfload/elfload.c gelfload/dlfcn.c gelfload/bbuffer.c -ldl 4 | -------------------------------------------------------------------------------- /osx/loader/mke32.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | gcc -o loader -m32 -Wall -W -pedantic -Wno-unused-parameter -Wno-variadic-macros -O2 -I. -Igelfload -DXSYMBOL_SIZE=1 -DHAVE_MAIN main.c gnuh.c cxa.c gelfload/elfload.c gelfload/dlfcn.c gelfload/bbuffer.c -ldl 4 | -------------------------------------------------------------------------------- /osx/loader/mk.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | gcc -o loader.dylib -shared -Wall -W -pedantic -Wno-unused-parameter -Wno-variadic-macros -O2 -I. -Igelfload -L. -DXSYMBOL=ZYA -DXSYMBOL_SIZE=0x90 main.c gnuh.c cxa.c gelfload/elfload.c gelfload/dlfcn.c gelfload/bbuffer.c -ldl 4 | -------------------------------------------------------------------------------- /osx/alpha.c: -------------------------------------------------------------------------------- 1 | int x = 5; 2 | 3 | int 4 | alpha(void) 5 | { 6 | x++; 7 | return 9; 8 | } 9 | 10 | #include 11 | 12 | static void __attribute__((constructor)) 13 | initme(void) 14 | { 15 | printf("here A: x: *%p = %u\n", (void *)&x, x); 16 | } 17 | -------------------------------------------------------------------------------- /linux/alpha.c: -------------------------------------------------------------------------------- 1 | int x = 5; 2 | 3 | int 4 | alpha(void) 5 | { 6 | x++; 7 | return 9; 8 | } 9 | 10 | #include 11 | 12 | static void __attribute__((constructor)) 13 | initme(void) 14 | { 15 | printf("here A: x: *%p = %u\n", (void *)&x, x); 16 | } 17 | -------------------------------------------------------------------------------- /linux/loader/mk.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | gcc -o loader.so -shared -Wall -W -pedantic -Wno-unused-function -Wno-variadic-macros -Wno-missing-field-initializers -O2 -I. -Irune -fPIC -Wl,-init=initme -Wl,-fini=finime -s -DXSYMBOL=ZYA -DXSYMBOL_SIZE=0x90 loader.c cxa.c rune/mac.c -ldl 4 | -------------------------------------------------------------------------------- /osx/loader/README.txt: -------------------------------------------------------------------------------- 1 | This is a portable runtime ELF loader. 2 | 3 | gelfload was written by Gregor Richards. 4 | https://github.com/GregorR/gelfload.git 5 | 6 | gnu_lookup() function was written by Andrey Roenko. 7 | https://flapenguin.me/2017/05/10/elf-lookup-dt-gnu-hash/ 8 | -------------------------------------------------------------------------------- /osx/loader/gelfload/bbuffer.h: -------------------------------------------------------------------------------- 1 | #ifndef BBUFFER_H 2 | #define BBUFFER_H 3 | 4 | /* Get a r/w/x binary buffer, at the given location if provided */ 5 | void *bbuffer(void *loc, size_t sz); 6 | int xbbuffer(void *loc, size_t sz); 7 | void unbbuffer(void *loc, size_t sz); 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /osx/zya/mk.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | OLD=a 4 | NEW=b 5 | 6 | gcc -o lib$NEW.dylib -shared -Wall -W -pedantic -Wno-variadic-macros -O2 -Wl,-install_name,@executable_path/lib$NEW.dylib -Wl,-reexport_library,lib$OLD.dylib -Wl,-alias_list,alias.txt -Wl,-current_version,1.0.0 -Wl,-compatibility_version,1.0.0 beta.c \ 7 | lib/lib.c \ 8 | lib/misc.c \ 9 | lib/todo.c 10 | -------------------------------------------------------------------------------- /osx/mk.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | OLD=a 4 | NEW=b 5 | 6 | gcc -o lib$OLD.dylib -shared -Wall -W -pedantic -O2 -Wl,-install_name,@executable_path/lib$OLD.dylib alpha.c 7 | 8 | gcc -o lib$NEW.dylib -shared -Wall -W -pedantic -O2 -Wl,-install_name,@executable_path/lib$NEW.dylib -Wl,-reexport_library,lib$OLD.dylib -Wl,-alias_list,alias.txt beta.c 9 | 10 | gcc -o testb -Wall -W -pedantic -O2 -L. testb.c -l$NEW 11 | -------------------------------------------------------------------------------- /osx/zya/lib/lib.h: -------------------------------------------------------------------------------- 1 | #ifndef LIB_H 2 | #define LIB_H 3 | 4 | #include 5 | #include /* size_t, NULL, etc. */ 6 | #include 7 | 8 | void *create_strlit(); /* anchor */ 9 | #define A(offset) ((uintptr_t)create_strlit + (offset) - 0x7670) 10 | 11 | int _patch_dword(uintptr_t dest, unsigned int value); 12 | 13 | #ifndef DISABLE_API 14 | 15 | #define get_dirty_infos zya323 16 | 17 | unsigned int get_dirty_infos(void); 18 | 19 | #endif 20 | #endif 21 | -------------------------------------------------------------------------------- /linux/zya/lib/lib.h: -------------------------------------------------------------------------------- 1 | #ifndef LIB_H 2 | #define LIB_H 3 | 4 | #include 5 | #include /* size_t, NULL, etc. */ 6 | #include 7 | 8 | void *create_strlit(); /* anchor */ 9 | #define A(offset) ((uintptr_t)create_strlit + (offset) - 0x3dec0) 10 | 11 | int _patch_dword(uintptr_t dest, unsigned int value); 12 | 13 | #ifndef DISABLE_API 14 | 15 | #define get_dirty_infos zya323 16 | 17 | unsigned int get_dirty_infos(void); 18 | 19 | #endif 20 | #endif 21 | -------------------------------------------------------------------------------- /osx/loader/gelfload/elfload_dlfcn.h: -------------------------------------------------------------------------------- 1 | /* dlfcn for elfload-loaded ELFs */ 2 | 3 | #ifndef ELFLOAD_DLFCN_H 4 | #define ELFLOAD_DLFCN_H 5 | 6 | extern char *elfload_dlinstdir; 7 | 8 | void *elfload_dlopen(const char *filename, int flag); 9 | char *elfload_dlerror(void); 10 | void *elfload_dlsym(void *handle, const char *symbol); 11 | int elfload_dlclose(void *handle); 12 | 13 | /* return one of these functions by their name */ 14 | void *elfload_dl(const char *fname); 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /osx/testb.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | extern int x; 4 | extern int alpha(void); 5 | 6 | extern int y; 7 | extern int beta(void); 8 | 9 | int 10 | main(void) 11 | { 12 | printf("here C: x: *%p = %u\n", (void *)&x, x); 13 | printf("here C: y: *%p = %u\n", (void *)&y, y); 14 | int a = alpha(); 15 | int b = beta(); 16 | printf("x=%d, y=%d\n", x, y); 17 | printf("a=%d, b=%d\n", a, b); 18 | y = 1; 19 | a = alpha(); 20 | b = beta(); 21 | printf("x=%d, y=%d\n", x, y); 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /linux/testb.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | extern int x; 4 | extern int alpha(void); 5 | 6 | extern int y; 7 | extern int beta(void); 8 | 9 | int 10 | main(void) 11 | { 12 | printf("here C: x: *%p = %u\n", (void *)&x, x); 13 | printf("here C: y: *%p = %u\n", (void *)&y, y); 14 | int a = alpha(); 15 | int b = beta(); 16 | printf("x=%d, y=%d\n", x, y); 17 | printf("a=%d, b=%d\n", a, b); 18 | y = 1; 19 | a = alpha(); 20 | b = beta(); 21 | printf("x=%d, y=%d\n", x, y); 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /linux/zya/mk.sh~: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | OLD=a 4 | NEW=b 5 | 6 | # rebuild 'new' so that it has COPY relocs for symbols imported from 'old' (also define needed aliases) 7 | gcc -o lib$NEW.so -shared -Wall -W -pedantic -O2 -L. -fPIE -pie -Wl,-E -nostdlib \ 8 | -Wl,--defsym=ash=zya45 \ 9 | -Wl,--defsym=batch=zya60 \ 10 | -Wl,--defsym=callui=zya99 \ 11 | -Wl,--defsym=dbg=zya144 \ 12 | -Wl,--defsym=errorexit=zya224 \ 13 | -Wl,--defsym=inf=zya597 \ 14 | -Wl,--defsym=lnar_size=zya679 \ 15 | -Wl,--defsym=ph=zya787 \ 16 | -Wl,--defsym=root_node=zya935 \ 17 | -Wl,--defsym=under_debugger=zya1094 \ 18 | -Wl,-init=initme -s beta.c -l$OLD -ldl -lc 19 | -------------------------------------------------------------------------------- /linux/mk.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # this is the original library 4 | gcc -o liba.so -shared -Wall -W -pedantic -O2 -fPIC -L. alpha.c 5 | 6 | # create a full library (symbols from A & their aliases) for the sole purpose of linking main 7 | gcc -o libb.so -shared -Wall -W -pedantic -O2 -fPIC both.c 8 | 9 | # build main with both symbols (notice nocopyreloc) 10 | gcc -o testb -Wall -W -pedantic -O2 -L. -fPIC -Wl,-z,nocopyreloc -Wl,-z,origin -Wl,-rpath,'$ORIGIN' testb.c -lb 11 | 12 | # rebuild B so that it has COPY relocs for symbols imported from A (also define needed aliases) 13 | gcc -o libb.so -shared -Wall -W -pedantic -O2 -L. -fPIE -pie -Wl,-E -Wl,--defsym=y=x beta.c -la -ldl 14 | -------------------------------------------------------------------------------- /osx/zya/beta.c: -------------------------------------------------------------------------------- 1 | static int unused __attribute__((unused)); 2 | 3 | #if 0 4 | /* 5 | * function wrapping: this is slightly different than just aliasing, because we need 6 | * to provide BOTH symbols *and* rely on the first library for backend implementation 7 | */ 8 | 9 | #include 10 | 11 | int zya936(char **a, long b); 12 | 13 | int 14 | run_plugin(char **a, long b) 15 | { 16 | if (a) { 17 | printf("%s: %s\n", __func__, a[6]); 18 | } 19 | return zya936(a, b); 20 | } 21 | 22 | const struct { 23 | void *repl; 24 | void *orig; 25 | } interposers[] __attribute__((section("__DATA, __interpose"))) = { 26 | { .repl = (void *)run_plugin, .orig = (void *)zya936 }, 27 | }; 28 | #endif 29 | -------------------------------------------------------------------------------- /linux/zya/mk.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | OLD=a 4 | MID=2 5 | NEW=b 6 | 7 | gcc -o lib$MID.so -shared -Wall -W -pedantic -Wno-variadic-macros -O2 -L. -fPIC -s lib/lib.c lib/misc.c lib/todo.c -l$OLD 8 | 9 | # rebuild 'new' so that it has COPY relocs for symbols imported from 'old' (also define needed aliases) 10 | gcc -o lib$NEW.so -shared -Wall -W -pedantic -O2 -L. -fPIE -pie -Wl,-E -nostdlib \ 11 | -Wl,--defsym=ash=zya45 \ 12 | -Wl,--defsym=batch=zya60 \ 13 | -Wl,--defsym=callui=zya99 \ 14 | -Wl,--defsym=dbg=zya144 \ 15 | -Wl,--defsym=errorexit=zya224 \ 16 | -Wl,--defsym=inf=zya597 \ 17 | -Wl,--defsym=lnar_size=zya679 \ 18 | -Wl,--defsym=ph=zya787 \ 19 | -Wl,--defsym=root_node=zya935 \ 20 | -Wl,--defsym=under_debugger=zya1094 \ 21 | -s beta.c -l$MID -l$OLD -ldl -lc 22 | -------------------------------------------------------------------------------- /osx/loader/testlib.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #ifdef __cplusplus 4 | extern "C" { 5 | #endif 6 | 7 | int exposed = 5; 8 | 9 | static void __attribute__((constructor)) 10 | initfunc(void) 11 | { 12 | printf("initialize\n"); 13 | } 14 | 15 | static void __attribute__((destructor)) 16 | termfunc(void) 17 | { 18 | printf("terminate\n"); 19 | } 20 | 21 | int 22 | square(int x) 23 | { 24 | return x * x; 25 | } 26 | 27 | int 28 | hello(char *who) 29 | { 30 | return printf("hello %s\n", who); 31 | } 32 | 33 | int 34 | plus(int x) 35 | { 36 | try { 37 | throw(1); 38 | return x + x; 39 | } catch(...) { 40 | printf("caught\n"); 41 | return -x; 42 | } 43 | } 44 | 45 | #ifdef __cplusplus 46 | } 47 | #endif 48 | -------------------------------------------------------------------------------- /osx/zya/lib/lib.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #define DISABLE_API 5 | #include "lib.h" 6 | 7 | #define IMPORT_PRIVATE(offset, alias) \ 8 | void *alias(void *a, void *b, void *c, void *d, void *e, void *f) \ 9 | { \ 10 | return ((void *(*)())A(offset))(a, b, c, d, e, f); \ 11 | } 12 | 13 | IMPORT_PRIVATE(0x009730, cfgopt_t__apply) 14 | 15 | int __attribute__((visibility("hidden"))) 16 | _patch_dword(uintptr_t dest, unsigned int value) 17 | { 18 | void *base = (void *)(dest & ~0xFFF); 19 | int rv = mprotect(base, 0x1000, PROT_READ | PROT_WRITE); 20 | if (rv == 0) { 21 | *(unsigned int *)dest = value; 22 | rv = mprotect(base, 0x1000, PROT_READ | PROT_EXEC); 23 | } 24 | return rv; 25 | } 26 | 27 | static void __attribute__((constructor)) 28 | init(void) 29 | { 30 | } 31 | -------------------------------------------------------------------------------- /linux/zya/lib/lib.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #define DISABLE_API 5 | #include "lib.h" 6 | 7 | #ifdef SIMPLE_JMP 8 | #define IMPORT_PRIVATE(offset, alias) \ 9 | void *alias(void *a, void *b, void *c, void *d, void *e, void *f) \ 10 | { \ 11 | return ((void *(*)())A(offset))(a, b, c, d, e, f); \ 12 | } 13 | #else /* IFUNC */ 14 | #define IMPORT_PRIVATE(offset, alias) \ 15 | static void *(*resolve_##alias(void))() { return (void *(*)())A(offset); } \ 16 | void *alias() __attribute__((ifunc("resolve_" #alias))); 17 | #endif /* IFUNC */ 18 | 19 | IMPORT_PRIVATE(0x042810, cfgopt_t__apply) 20 | 21 | int __attribute__((visibility("hidden"))) 22 | _patch_dword(uintptr_t dest, unsigned int value) 23 | { 24 | void *base = (void *)(dest & ~0xFFF); 25 | int rv = mprotect(base, 0x1000, PROT_READ | PROT_WRITE); 26 | if (rv == 0) { 27 | *(unsigned int *)dest = value; 28 | rv = mprotect(base, 0x1000, PROT_READ | PROT_EXEC); 29 | } 30 | return rv; 31 | } 32 | 33 | static void __attribute__((constructor)) 34 | init(void) 35 | { 36 | } 37 | -------------------------------------------------------------------------------- /linux/zya/tools/herp.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | import os 4 | import sys 5 | 6 | def O(cmd): 7 | return os.popen(cmd).read().splitlines() 8 | 9 | def U(file, where): 10 | if os.uname()[0] == 'Linux': 11 | return O("ldd -r '%s' | awk '/undefined symbol/{print $3}'" % file) 12 | else: 13 | return O("nm -m -undefined-only '%s' | awk '/\(undefined.*%s\)/{print $3}' | sort" % (file, where)) 14 | 15 | def E(files): 16 | if os.uname()[0] == 'Linux': 17 | return O("nm -D --defined-only '%s' | awk '{print $3}' | sort -u" % "' '".join(files)) 18 | else: 19 | return O("nm -defined-only '%s' | awk '{print $3}' | sort -u" % "' '".join(files)) 20 | 21 | def X(xlat): 22 | # file format is: mangled = symbol 23 | return O("awk '{print $3}' '%s'" % xlat) 24 | #with open(xlat) as f: 25 | # return f.read().splitlines() 26 | 27 | if len(sys.argv) < 3: 28 | print "usage: %s binary xlat.txt lib [lib...]" % sys.argv[0] 29 | exit(1) 30 | 31 | u = U(sys.argv[1], sys.argv[3].split('.')[0]) 32 | x = X(sys.argv[2]) 33 | e = E(sys.argv[3:]) 34 | 35 | for i in u: 36 | if not i in e and not i in x: 37 | print i 38 | -------------------------------------------------------------------------------- /osx/loader/gelfload/elfnative.h: -------------------------------------------------------------------------------- 1 | #ifndef ELFNATIVE_H 2 | #define ELFNATIVE_H 3 | 4 | #include "../config.h" 5 | #include "elfload_elf.h" 6 | 7 | #if SIZEOF_VOID_P == 4 8 | 9 | #define ElfNative_Ehdr Elf32_Ehdr 10 | #define ElfNative_Phdr Elf32_Phdr 11 | #define ElfNative_Shdr Elf32_Shdr 12 | #define ElfNative_Addr Elf32_Addr 13 | #define ElfNative_Dyn Elf32_Dyn 14 | #define ElfNative_Sym Elf32_Sym 15 | #define ElfNative_Word Elf32_Word 16 | #define ElfNative_Rel Elf32_Rel 17 | #define ElfNative_Rela Elf32_Rela 18 | 19 | #define ELFNATIVE_ST_BIND ELF32_ST_BIND 20 | #define ELFNATIVE_R_SYM ELF32_R_SYM 21 | #define ELFNATIVE_R_TYPE ELF32_R_TYPE 22 | 23 | #elif SIZEOF_VOID_P == 8 24 | 25 | #define ElfNative_Ehdr Elf64_Ehdr 26 | #define ElfNative_Phdr Elf64_Phdr 27 | #define ElfNative_Shdr Elf64_Shdr 28 | #define ElfNative_Addr Elf64_Addr 29 | #define ElfNative_Dyn Elf64_Dyn 30 | #define ElfNative_Sym Elf64_Sym 31 | #define ElfNative_Word Elf64_Word 32 | #define ElfNative_Rel Elf64_Rel 33 | #define ElfNative_Rela Elf64_Rela 34 | 35 | #define ELFNATIVE_ST_BIND ELF32_ST_BIND 36 | #define ELFNATIVE_R_SYM ELF64_R_SYM 37 | #define ELFNATIVE_R_TYPE ELF64_R_TYPE 38 | 39 | #else 40 | 41 | #error Unsupported bitwidth. 42 | 43 | #endif 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /osx/loader/config32.h: -------------------------------------------------------------------------------- 1 | /* config.h. Generated from config.h.in by configure. */ 2 | /* config.h.in. Generated from configure.ac by autoheader. */ 3 | 4 | /* Define if architecture is i386. */ 5 | #define GELFLOAD_ARCH_i386 1 6 | 7 | /* Define if architecture is x86_64. */ 8 | /* #undef GELFLOAD_ARCH_x86_64 */ 9 | 10 | /* Define to 1 if you have the header file. */ 11 | #define HAVE_DLFCN_H 1 12 | 13 | /* Defined if libdl is available. */ 14 | #define HAVE_LIBDL 1 15 | 16 | /* Define to 1 if you have the `mmap' function. */ 17 | #define HAVE_MMAP 1 18 | 19 | /* Name of package */ 20 | #define PACKAGE "gelfload" 21 | 22 | /* Define to the address where bug reports for this package should be sent. */ 23 | #define PACKAGE_BUGREPORT "cdgregorr@sourceforge.net" 24 | 25 | /* Define to the full name of this package. */ 26 | #define PACKAGE_NAME "gelfload" 27 | 28 | /* Define to the full name and version of this package. */ 29 | #define PACKAGE_STRING "gelfload 1" 30 | 31 | /* Define to the one symbol short name of this package. */ 32 | #define PACKAGE_TARNAME "gelfload" 33 | 34 | /* Define to the home page for this package. */ 35 | #define PACKAGE_URL "" 36 | 37 | /* Define to the version of this package. */ 38 | #define PACKAGE_VERSION "1" 39 | 40 | /* Install prefix */ 41 | #define PREFIX "NONE" 42 | 43 | /* The size of `void *', as computed by sizeof. */ 44 | #define SIZEOF_VOID_P 4 45 | 46 | /* Version number of package */ 47 | #define VERSION "1" 48 | -------------------------------------------------------------------------------- /osx/loader/config64.h: -------------------------------------------------------------------------------- 1 | /* config.h. Generated from config.h.in by configure. */ 2 | /* config.h.in. Generated from configure.ac by autoheader. */ 3 | 4 | /* Define if architecture is i386. */ 5 | /* #undef GELFLOAD_ARCH_i386 */ 6 | 7 | /* Define if architecture is x86_64. */ 8 | #define GELFLOAD_ARCH_x86_64 1 9 | 10 | /* Define to 1 if you have the header file. */ 11 | #define HAVE_DLFCN_H 1 12 | 13 | /* Defined if libdl is available. */ 14 | #define HAVE_LIBDL 1 15 | 16 | /* Define to 1 if you have the `mmap' function. */ 17 | #define HAVE_MMAP 1 18 | 19 | /* Name of package */ 20 | #define PACKAGE "gelfload" 21 | 22 | /* Define to the address where bug reports for this package should be sent. */ 23 | #define PACKAGE_BUGREPORT "cdgregorr@sourceforge.net" 24 | 25 | /* Define to the full name of this package. */ 26 | #define PACKAGE_NAME "gelfload" 27 | 28 | /* Define to the full name and version of this package. */ 29 | #define PACKAGE_STRING "gelfload 1" 30 | 31 | /* Define to the one symbol short name of this package. */ 32 | #define PACKAGE_TARNAME "gelfload" 33 | 34 | /* Define to the home page for this package. */ 35 | #define PACKAGE_URL "" 36 | 37 | /* Define to the version of this package. */ 38 | #define PACKAGE_VERSION "1" 39 | 40 | /* Install prefix */ 41 | #define PREFIX "NONE" 42 | 43 | /* The size of `void *', as computed by sizeof. */ 44 | #define SIZEOF_VOID_P 8 45 | 46 | /* Version number of package */ 47 | #define VERSION "1" 48 | -------------------------------------------------------------------------------- /osx/loader/gelfload/dlfcn.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "elfload.h" 5 | #include "elfload_dlfcn.h" 6 | 7 | char *elfload_dlinstdir = NULL; 8 | char *dlLastError = NULL; 9 | 10 | void *elfload_dlopen(const char *filename, int flag) 11 | { 12 | /* pretty simple, just load based on the file name */ 13 | struct ELF_File *f = loadELF(filename, elfload_dlinstdir, 0); 14 | 15 | if (f == NULL) { 16 | dlLastError = "Could not find or load file."; 17 | } 18 | 19 | return (void *) f; 20 | } 21 | 22 | char *elfload_dlerror(void) { return dlLastError; } 23 | 24 | void *elfload_dlsym(void *handle, const char *symbol) 25 | { 26 | void *sym = findELFSymbol(symbol, (struct ELF_File *) handle, -1, -1, NULL); 27 | 28 | if (sym == NULL) { 29 | dlLastError = "Symbol undefined."; 30 | } 31 | 32 | return sym; 33 | } 34 | 35 | int elfload_dlclose(void *handle) {return 0;} 36 | 37 | 38 | void *elfload_dl(const char *fname) 39 | { 40 | if (strcmp(fname, "dlopen") == 0) { 41 | return (void *) (size_t)elfload_dlopen; 42 | 43 | } else if (strcmp(fname, "dlerror") == 0) { 44 | return (void *) (size_t)elfload_dlerror; 45 | 46 | } else if (strcmp(fname, "dlsym") == 0) { 47 | return (void *) (size_t)elfload_dlsym; 48 | 49 | } else if (strcmp(fname, "dlclose") == 0) { 50 | return (void *) (size_t)elfload_dlclose; 51 | 52 | } 53 | 54 | return NULL; 55 | } 56 | -------------------------------------------------------------------------------- /osx/loader/gelfload/elfload_exec.h: -------------------------------------------------------------------------------- 1 | /* From a loader, pop off our entire stack and execute the loaded program */ 2 | 3 | /* 4 | * Copyright (c) 2007, 2012 Gregor Richards 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to 8 | * deal in the Software without restriction, including without limitation the 9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | * sell copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | * IN THE SOFTWARE. 20 | */ 21 | 22 | #include "config.h" 23 | 24 | #if GELFLOAD_ARCH_i386 25 | #define WITHSTACK_JMP(newstack, newloc) \ 26 | asm("mov %0, %%esp\n" \ 27 | "jmp *%1\n" \ 28 | : \ 29 | : "r"(newstack), "r"(newloc)); 30 | 31 | #elif GELFLOAD_ARCH_x86_64 32 | #define WITHSTACK_JMP(newstack, newloc) \ 33 | asm("mov %0, %%rsp\n" \ 34 | "jmp *%1\n" \ 35 | : \ 36 | : "r"(newstack), "r"(newloc)); 37 | 38 | #else 39 | #error No assembly code for subprocess execution known. 40 | #endif 41 | -------------------------------------------------------------------------------- /linux/beta.c: -------------------------------------------------------------------------------- 1 | extern int x; 2 | 3 | #ifdef SIMPLE_JMP 4 | #define IMPORT(import, alias) \ 5 | extern void *import(); \ 6 | void *alias() { return import(); } /* create code trampoline */ 7 | #else /* IFUNC */ 8 | #define IMPORT(import, alias) \ 9 | extern void *import(); \ 10 | static void *(*resolve_##alias(void))() { return import; } \ 11 | void *alias() __attribute__((ifunc("resolve_" #alias))); 12 | #endif /* IFUNC */ 13 | 14 | IMPORT(alpha, beta) 15 | 16 | #define _GNU_SOURCE 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #define COPY(sym) \ 23 | do { \ 24 | void *that = dlsym(RTLD_NEXT, #sym); \ 25 | /*if (that) { sym = *(typeof(sym) *)that; break; }*/ \ 26 | /*if (that) { memcpy(&sym, that, sizeof(sym)); break; }*/ \ 27 | void *this = dlsym(RTLD_DEFAULT, #sym); \ 28 | if (this && that) { \ 29 | Dl_info info; \ 30 | ElfW(Sym) *extra_info = NULL; \ 31 | int rv = dladdr1(that, &info, (void **)&extra_info, RTLD_DL_SYMENT); \ 32 | if (rv && extra_info && sizeof(sym) >= extra_info->st_size) { \ 33 | memcpy(this, that, extra_info->st_size); \ 34 | } \ 35 | } \ 36 | } while (0) 37 | 38 | static void __attribute__((constructor)) 39 | initme(void) 40 | { 41 | /* pull in x -- we need to link this with a COPY reloc to x */ 42 | printf("here B: x: *%p = %u\n", (void *)&x, x); 43 | /* however, in certain circumstances, the linker did not COPY the value. do it now 44 | * NB: if the next lib has constructors that rely on these values being != 0, we are probably fucked... 45 | */ 46 | COPY(x); 47 | } 48 | 49 | int 50 | main(void) 51 | { 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /linux/loader/rune/mac.c: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Shinichiro Hamaji. All rights reserved. 2 | // 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions 5 | // are met: 6 | // 7 | // 1. Redistributions of source code must retain the above copyright 8 | // notice, this list of conditions and the following disclaimer. 9 | // 10 | // 2. Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following 12 | // disclaimer in the documentation and/or other materials 13 | // provided with the distribution. 14 | // 15 | // THIS SOFTWARE IS PROVIDED BY Shinichiro Hamaji ``AS IS'' AND ANY 16 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18 | // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Shinichiro Hamaji OR 19 | // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 22 | // USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25 | // OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 | // SUCH DAMAGE. 27 | 28 | // Emulation for functions in Mac. 29 | 30 | #define _GNU_SOURCE 31 | #include 32 | #include 33 | 34 | typedef __darwin_rune_t rune_t; 35 | typedef int __darwin_ct_rune_t; /* ct_rune_t */ 36 | 37 | #define _INVALID_RUNE _DefaultRuneLocale.__invalid_rune 38 | 39 | #include "none.c" 40 | #include "runetable.c" 41 | 42 | int __maskrune(__darwin_ct_rune_t _c, unsigned long _f) { 43 | return _DefaultRuneLocale.__runetype[_c & 0xff] & _f; 44 | } 45 | -------------------------------------------------------------------------------- /linux/zya/beta.c~: -------------------------------------------------------------------------------- 1 | extern char zya45[408]; 2 | extern char zya60; 3 | extern void *zya99; 4 | extern long zya144; 5 | extern char zya224; 6 | extern char zya597[280]; 7 | extern int zya679; 8 | extern char zya787[144]; 9 | extern long zya935; 10 | extern char zya1094; 11 | 12 | #ifdef SIMPLE_JMP 13 | #define IMPORT(import, alias) \ 14 | extern void *import(); \ 15 | void *alias() { return import(); } /* create code trampoline */ 16 | #else /* IFUNC */ 17 | #define IMPORT(import, alias) \ 18 | extern void *import(); \ 19 | static void *(*resolve_##alias(void))() { return import; } \ 20 | void *alias() __attribute__((ifunc("resolve_" #alias))); 21 | #endif /* IFUNC */ 22 | 23 | IMPORT(zya146, decode_insn) 24 | 25 | #define _GNU_SOURCE 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #define COPY(sym) \ 32 | do { \ 33 | void *that = dlsym(RTLD_NEXT, #sym); \ 34 | if (that) { \ 35 | memcpy(&sym, that, sizeof(sym)); \ 36 | } \ 37 | } while (0) 38 | 39 | void 40 | initme(void) 41 | { 42 | /* pull in data imports */ 43 | COPY(zya45); 44 | COPY(zya60); 45 | COPY(zya99); 46 | COPY(zya144); 47 | COPY(zya224); 48 | COPY(zya597); 49 | COPY(zya679); 50 | COPY(zya787); 51 | COPY(zya935); 52 | COPY(zya1094); 53 | printf("COPY ok\n"); 54 | } 55 | 56 | void 57 | _start(void) 58 | { 59 | __builtin_trap(); 60 | } 61 | 62 | #if 0 63 | /* 64 | * function wrapping: this is slightly different than just aliasing, because we need 65 | * to provide BOTH symbols *and* rely on the first library for backend implementation 66 | */ 67 | 68 | #include 69 | 70 | int 71 | run_plugin(char **a, long b) 72 | { 73 | static unsigned long func = 0; 74 | if (!func) { 75 | func = (unsigned long)dlsym(RTLD_NEXT, "zya936"); 76 | } 77 | if (a) { 78 | printf("%s: %s\n", __func__, a[6]); 79 | } 80 | return ((typeof(run_plugin) *)func)(a, b); 81 | } 82 | int zya936(char **a, long b) __attribute__((alias("run_plugin"))); 83 | #endif 84 | -------------------------------------------------------------------------------- /linux/zya/beta.c: -------------------------------------------------------------------------------- 1 | extern char zya45[408]; 2 | extern char zya60; 3 | extern void *zya99; 4 | extern long zya144; 5 | extern char zya224; 6 | extern char zya597[280]; 7 | extern int zya679; 8 | extern char zya787[144]; 9 | extern long zya935; 10 | extern char zya1094; 11 | 12 | #ifdef SIMPLE_JMP 13 | #define IMPORT(import, alias) \ 14 | extern void *import(); \ 15 | void *alias() { return import(); } /* create code trampoline */ 16 | #else /* IFUNC */ 17 | #define IMPORT(import, alias) \ 18 | extern void *import(); \ 19 | static void *(*resolve_##alias(void))() { return import; } \ 20 | void *alias() __attribute__((ifunc("resolve_" #alias))); 21 | #endif /* IFUNC */ 22 | 23 | IMPORT(zya146, decode_insn) 24 | 25 | #define _GNU_SOURCE 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #define COPY(sym) \ 32 | do { \ 33 | void *that = dlsym(RTLD_NEXT, #sym); \ 34 | if (that) { \ 35 | memcpy(&sym, that, sizeof(sym)); \ 36 | } \ 37 | } while (0) 38 | 39 | static void __attribute__((constructor)) 40 | initme(void) 41 | { 42 | /* pull in data imports, yet this code is not executed. magic, eh? */ 43 | COPY(zya45); 44 | COPY(zya60); 45 | COPY(zya99); 46 | COPY(zya144); 47 | COPY(zya224); 48 | COPY(zya597); 49 | COPY(zya679); 50 | COPY(zya787); 51 | COPY(zya935); 52 | COPY(zya1094); 53 | __builtin_trap(); 54 | } 55 | 56 | void 57 | _start(void) 58 | { 59 | __builtin_trap(); 60 | } 61 | 62 | #if 0 63 | /* 64 | * function wrapping: this is slightly different than just aliasing, because we need 65 | * to provide BOTH symbols *and* rely on the first library for backend implementation 66 | */ 67 | 68 | #include 69 | 70 | int 71 | run_plugin(char **a, long b) 72 | { 73 | static unsigned long func = 0; 74 | if (!func) { 75 | func = (unsigned long)dlsym(RTLD_NEXT, "zya936"); 76 | } 77 | if (a) { 78 | printf("%s: %s\n", __func__, a[6]); 79 | } 80 | return ((typeof(run_plugin) *)func)(a, b); 81 | } 82 | int zya936(char **a, long b) __attribute__((alias("run_plugin"))); 83 | #endif 84 | -------------------------------------------------------------------------------- /linux/loader/cxa.c: -------------------------------------------------------------------------------- 1 | #define _GNU_SOURCE 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #define INFO(args...) //printf(args) 8 | #define ERR(args...) fprintf(stderr, args) 9 | 10 | #define EC_STR "%c%c%c%c%c%c%c%d" 11 | #define EC_VAL(x) (int)((x >> 56) & 0xFF), (int)((x >> 48) & 0xFF), (int)((x >> 40) & 0xFF), (int)((x >> 32) & 0xFF), (int)((x >> 24) & 0xFF), (int)((x >> 16) & 0xFF), (int)((x >> 8) & 0xFF), (int)(x & 0xFF) 12 | 13 | typedef void (*cxa_throw_fn)(void *thrown_exception, void *tinfo, void (*dest)(void *)); 14 | void __register_frame(const void *begin); 15 | void __register_frame_info(const void *begin, void *object); 16 | void *eh_frame __attribute__((visibility("hidden"))); 17 | 18 | /* 19 | _Unwind_Reason_Code __attribute__((visibility("hidden"))) 20 | gxx_personality_v0(int version, _Unwind_Action actions, _Unwind_Exception_Class exceptionClass, struct _Unwind_Exception *unwind_exception, struct _Unwind_Context *context) 21 | { 22 | static _Unwind_Personality_Fn func; 23 | if (!func) { 24 | func = (_Unwind_Personality_Fn)(uintptr_t)dlsym(RTLD_DEFAULT, "__gxx_personality_v0"); 25 | } 26 | _Unwind_Reason_Code rv; 27 | INFO("%s(%d, %d, "EC_STR", %p, %p)\n", __func__, version, actions, EC_VAL(exceptionClass), (void *)unwind_exception, (void *)context); 28 | rv = func(version, actions, exceptionClass, unwind_exception, context); 29 | INFO("-> %d\n", rv); 30 | return rv; 31 | } 32 | */ 33 | 34 | void __attribute__((visibility("hidden"))) 35 | cxa_throw(void *thrown_exception, void *tinfo, void (*dest)(void *)) 36 | { 37 | static cxa_throw_fn func; 38 | if (!func) { 39 | func = (cxa_throw_fn)(uintptr_t)dlsym(RTLD_DEFAULT, "__cxa_throw"); 40 | if (eh_frame) { 41 | static char object[256]; // XXX or just let __register_frame() allocate one 42 | INFO("__register_frame(%p)\n", eh_frame); 43 | __register_frame_info(eh_frame, &object); 44 | } else { 45 | ERR("__unwind_info not supported yet\n"); 46 | } 47 | } 48 | INFO("%s(%p, %p, 0x%zx)\n", __func__, thrown_exception, tinfo, (uintptr_t)dest); 49 | func(thrown_exception, tinfo, dest); 50 | } 51 | -------------------------------------------------------------------------------- /linux/loader/rune/_types.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2004, 2008, 2009 Apple Inc. All rights reserved. 3 | * 4 | * @APPLE_LICENSE_HEADER_START@ 5 | * 6 | * This file contains Original Code and/or Modifications of Original Code 7 | * as defined in and that are subject to the Apple Public Source License 8 | * Version 2.0 (the 'License'). You may not use this file except in 9 | * compliance with the License. Please obtain a copy of the License at 10 | * http://www.opensource.apple.com/apsl/ and read it before using this 11 | * file. 12 | * 13 | * The Original Code and all software distributed under the License are 14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 | * Please see the License for the specific language governing rights and 19 | * limitations under the License. 20 | * 21 | * @APPLE_LICENSE_HEADER_END@ 22 | */ 23 | 24 | #ifndef __TYPES_H_ 25 | #define __TYPES_H_ 26 | 27 | #include 28 | //#include 29 | 30 | #if __GNUC__ > 2 || __GNUC__ == 2 && __GNUC_MINOR__ >= 7 31 | #define __strfmonlike(fmtarg, firstvararg) \ 32 | __attribute__((__format__ (__strfmon__, fmtarg, firstvararg))) 33 | #define __strftimelike(fmtarg) \ 34 | __attribute__((__format__ (__strftime__, fmtarg, 0))) 35 | #else 36 | #define __strfmonlike(fmtarg, firstvararg) 37 | #define __strftimelike(fmtarg) 38 | #endif 39 | 40 | typedef int __darwin_nl_item; 41 | typedef int __darwin_wctrans_t; 42 | #ifdef __LP64__ 43 | typedef uint32_t __darwin_wctype_t; 44 | #else /* !__LP64__ */ 45 | typedef unsigned long __darwin_wctype_t; 46 | #endif /* __LP64__ */ 47 | 48 | #ifdef __WCHAR_MAX__ 49 | #define __DARWIN_WCHAR_MAX __WCHAR_MAX__ 50 | #else /* ! __WCHAR_MAX__ */ 51 | #define __DARWIN_WCHAR_MAX 0x7fffffff 52 | #endif /* __WCHAR_MAX__ */ 53 | 54 | #if __DARWIN_WCHAR_MAX > 0xffffU 55 | #define __DARWIN_WCHAR_MIN (-0x7fffffff - 1) 56 | #else 57 | #define __DARWIN_WCHAR_MIN 0 58 | #endif 59 | #define __DARWIN_WEOF ((__darwin_wint_t)-1) 60 | 61 | #ifndef _FORTIFY_SOURCE 62 | # if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && ((__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__-0) < 1050) 63 | # define _FORTIFY_SOURCE 0 64 | # else 65 | # define _FORTIFY_SOURCE 2 /* on by default */ 66 | # endif 67 | #endif 68 | 69 | #endif /* __TYPES_H_ */ 70 | -------------------------------------------------------------------------------- /osx/loader/gelfload/elfload.h: -------------------------------------------------------------------------------- 1 | #ifndef ELFLOAD_H 2 | #define ELFLOAD_H 3 | 4 | #include 5 | 6 | #include "elfnative.h" 7 | 8 | #define HOSTLIB_NOT 0 9 | #define HOSTLIB_HOST 1 10 | #define HOSTLIB_DL 2 11 | 12 | /* Basic structure for ELF files mid-load */ 13 | struct ELF_File { 14 | char *nm; 15 | 16 | /* if this is actually a host library, this is set to 1 */ 17 | char hostlib; 18 | 19 | /* the complete program, in memory */ 20 | char *prog; 21 | size_t proglen; 22 | 23 | /* same pointer, actually */ 24 | ElfNative_Ehdr *ehdr; 25 | 26 | /* the size in memory of this file */ 27 | ssize_t memsz; 28 | 29 | /* the minimum and maximum position of the loaded file, ideally */ 30 | char *min, *max; 31 | 32 | /* the actual location where this file was loaded */ 33 | char *loc; 34 | 35 | /* the offset of this file's real loaded location from its internal location */ 36 | ssize_t offset; 37 | 38 | /* the dynamic entries table */ 39 | ElfNative_Dyn *dynamic; 40 | 41 | /* the string table */ 42 | char *strtab; 43 | 44 | /* and symbol table */ 45 | ElfNative_Sym *symtab; 46 | 47 | /* with its associated hash table */ 48 | ElfNative_Word *hashtab; 49 | #define ELFFILE_NBUCKET(f) ((f)->hashtab[0]) 50 | #define ELFFILE_NCHAIN(f) ((f)->hashtab[1]) 51 | #define ELFFILE_BUCKET(f, i) ((f)->hashtab[(i) + 2]) 52 | #define ELFFILE_CHAIN(f, i) ((f)->hashtab[(i) + ELFFILE_NBUCKET(f) + 2]) 53 | 54 | #define DT_GNU_HASH 0x6ffffef5 /* GNU-style hash table. */ 55 | Elf32_Word *gnuhash; 56 | 57 | /* exceptions */ 58 | char *eh_frame; 59 | 60 | /* RW area */ 61 | char *writable; 62 | 63 | /* init/fini_array */ 64 | ElfNative_Addr *init_array; 65 | size_t init_array_sz; 66 | ElfNative_Addr *fini_array; 67 | size_t fini_array_sz; 68 | 69 | /* relocation table(s) */ 70 | ElfNative_Rel *rel; 71 | size_t relsz; 72 | ElfNative_Rela *rela; 73 | size_t relasz; 74 | void *jmprel; 75 | size_t jmprelsz; 76 | }; 77 | 78 | struct ELF_File *loadELF(const char *nm, const char *instdir, int maybe); 79 | void relocateELFs(); 80 | void relocateELF(int fileNo, struct ELF_File *f); 81 | void initELF(struct ELF_File *except); 82 | void readFile(const char *nm, const char *instdir, struct ELF_File *ef); 83 | void closeFile(struct ELF_File *ef); 84 | void unloadELFs(); 85 | void *findELFSymbol(const char *nm, struct ELF_File *onlyin, int localin, int notin, 86 | ElfNative_Sym **syminto); 87 | ElfNative_Word elf_hash(const unsigned char *name); 88 | 89 | #endif 90 | -------------------------------------------------------------------------------- /osx/loader/gnuh.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "elfload.h" 3 | #include "elfload_dlfcn.h" 4 | 5 | unsigned long 6 | gnu_hash(const char *name) 7 | { 8 | const unsigned char *uname = (const unsigned char *)name; 9 | unsigned long h = 5381; 10 | unsigned char c; 11 | while ((c = *uname++) != '\0') { 12 | h = (h << 5) + h + c; 13 | } 14 | return h & 0xffffffff; 15 | } 16 | 17 | /* Different architectures have different symbol structure size. 18 | * Those actually should be selected depending on input binary's ELFCLASS, 19 | * but for simplicity I've left them as typedefs and defines. 20 | */ 21 | #ifdef __LP64__ 22 | typedef uint64_t bloom_el_t; 23 | #define ELFCLASS_BITS 64 24 | #else 25 | typedef uint32_t bloom_el_t; 26 | #define ELFCLASS_BITS 32 27 | #endif 28 | 29 | void * 30 | gnu_lookup(const char *name, struct ELF_File *f, int inlocal, ElfNative_Sym **syminto) 31 | { 32 | const uint32_t *hashtab = f->gnuhash; 33 | const uint32_t namehash = gnu_hash(name); 34 | 35 | const uint32_t nbuckets = hashtab[0]; 36 | const uint32_t symoffset = hashtab[1]; 37 | const uint32_t bloom_size = hashtab[2]; 38 | const uint32_t bloom_shift = hashtab[3]; 39 | const bloom_el_t *bloom = (void *)&hashtab[4]; 40 | const uint32_t *buckets = (void *)&bloom[bloom_size]; 41 | const uint32_t *chain = &buckets[nbuckets]; 42 | 43 | bloom_el_t word = bloom[(namehash / ELFCLASS_BITS) % bloom_size]; 44 | bloom_el_t mask = 0 45 | | (bloom_el_t)1 << (namehash % ELFCLASS_BITS) 46 | | (bloom_el_t)1 << ((namehash >> bloom_shift) % ELFCLASS_BITS); 47 | 48 | /* If at least one bit is not set, a symbol is surely missing. */ 49 | if ((word & mask) != mask) { 50 | return NULL; 51 | } 52 | 53 | uint32_t symix = buckets[namehash % nbuckets]; 54 | if (symix < symoffset) { 55 | return NULL; 56 | } 57 | 58 | /* Loop through the chain. */ 59 | while (8) { 60 | const char *symname = f->strtab + f->symtab[symix].st_name; 61 | const uint32_t hash = chain[symix - symoffset]; 62 | 63 | if ((namehash | 1) == (hash | 1) && strcmp(name, symname) == 0) { 64 | ElfNative_Sym *sym = &(f->symtab[symix]); 65 | if ((inlocal || ELFNATIVE_ST_BIND(sym->st_info) != STB_LOCAL) && sym->st_shndx != SHN_UNDEF) { 66 | if (syminto != NULL) { 67 | *syminto = sym; 68 | } 69 | return (void *)(sym->st_value + f->offset); 70 | } 71 | return NULL; 72 | } 73 | 74 | /* Chain ends with an element with the lowest bit set to 1. */ 75 | if (hash & 1) { 76 | break; 77 | } 78 | 79 | symix++; 80 | } 81 | 82 | return NULL; 83 | } 84 | -------------------------------------------------------------------------------- /osx/loader/cxa.c: -------------------------------------------------------------------------------- 1 | #define _GNU_SOURCE 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #define INFO(args...) printf(args) 8 | #define ERR(args...) fprintf(stderr, args) 9 | 10 | #define EC_STR "%c%c%c%c%c%c%c%d" 11 | #define EC_VAL(x) (int)((x >> 56) & 0xFF), (int)((x >> 48) & 0xFF), (int)((x >> 40) & 0xFF), (int)((x >> 32) & 0xFF), (int)((x >> 24) & 0xFF), (int)((x >> 16) & 0xFF), (int)((x >> 8) & 0xFF), (int)(x & 0xFF) 12 | 13 | typedef void (*cxa_throw_fn)(void *thrown_exception, void *tinfo, void (*dest)(void *)); 14 | void __register_frame(const void *begin); 15 | void __register_frame_info(const void *begin, void *object); 16 | void *eh_frame __attribute__((visibility("hidden"))); 17 | 18 | /* 19 | _Unwind_Reason_Code __attribute__((visibility("hidden"))) 20 | gxx_personality_v0(int version, _Unwind_Action actions, _Unwind_Exception_Class exceptionClass, struct _Unwind_Exception *unwind_exception, struct _Unwind_Context *context) 21 | { 22 | static _Unwind_Personality_Fn func; 23 | if (!func) { 24 | func = (_Unwind_Personality_Fn)(uintptr_t)dlsym(RTLD_DEFAULT, "__gxx_personality_v0"); 25 | } 26 | _Unwind_Reason_Code rv; 27 | INFO("%s(%d, %d, "EC_STR", %p, %p)\n", __func__, version, actions, EC_VAL(exceptionClass), (void *)unwind_exception, (void *)context); 28 | rv = func(version, actions, exceptionClass, unwind_exception, context); 29 | INFO("-> %d\n", rv); 30 | return rv; 31 | } 32 | */ 33 | 34 | void __attribute__((visibility("hidden"))) 35 | cxa_throw(void *thrown_exception, void *tinfo, void (*dest)(void *)) 36 | { 37 | static cxa_throw_fn func; 38 | if (!func) { 39 | func = (cxa_throw_fn)(uintptr_t)dlsym(RTLD_DEFAULT, "__cxa_throw"); 40 | if (eh_frame) { 41 | #ifdef __APPLE__ 42 | // XXX this is probably wrong as hell, but know this: 43 | // XXX on Darwin __register_frame() takes a single FDE 44 | uint32_t Size, Offset; 45 | const char *P = eh_frame; 46 | do { 47 | Size = *(uint32_t *)P; 48 | if (!Size) { 49 | break; 50 | } 51 | P += 4 + Size; 52 | do { 53 | Size = *(uint32_t *)P; 54 | if (!Size) { 55 | break; 56 | } 57 | Offset = *(uint32_t *)(P + 4); 58 | if (!Offset) { 59 | break; 60 | } 61 | INFO("__register_fde(%p)\n", (void *)P); 62 | __register_frame(P); 63 | P += 4 + Size; 64 | } while (Size); 65 | } while (Size); 66 | #else 67 | static char object[256]; // XXX or just let __register_frame() allocate one 68 | INFO("__register_frame(%p)\n", eh_frame); 69 | __register_frame_info(eh_frame, &object); 70 | #endif 71 | } else { 72 | ERR("eh_frame is missing. prepare to die\n"); 73 | } 74 | } 75 | INFO("%s(%p, %p, 0x%zx)\n", __func__, thrown_exception, tinfo, (uintptr_t)dest); 76 | func(thrown_exception, tinfo, dest); 77 | } 78 | -------------------------------------------------------------------------------- /linux/loader/rune/none.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. 3 | * 4 | * @APPLE_LICENSE_HEADER_START@ 5 | * 6 | * The contents of this file constitute Original Code as defined in and 7 | * are subject to the Apple Public Source License Version 1.1 (the 8 | * "License"). You may not use this file except in compliance with the 9 | * License. Please obtain a copy of the License at 10 | * http://www.apple.com/publicsource and read it before using this file. 11 | * 12 | * This Original Code and all software distributed under the License are 13 | * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER 14 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 15 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the 17 | * License for the specific language governing rights and limitations 18 | * under the License. 19 | * 20 | * @APPLE_LICENSE_HEADER_END@ 21 | */ 22 | /* 23 | * Copyright (c) 1993 24 | * The Regents of the University of California. All rights reserved. 25 | * 26 | * This code is derived from software contributed to Berkeley by 27 | * Paul Borman at Krystal Technologies. 28 | * 29 | * Redistribution and use in source and binary forms, with or without 30 | * modification, are permitted provided that the following conditions 31 | * are met: 32 | * 1. Redistributions of source code must retain the above copyright 33 | * notice, this list of conditions and the following disclaimer. 34 | * 2. Redistributions in binary form must reproduce the above copyright 35 | * notice, this list of conditions and the following disclaimer in the 36 | * documentation and/or other materials provided with the distribution. 37 | * 3. All advertising materials mentioning features or use of this software 38 | * must display the following acknowledgement: 39 | * This product includes software developed by the University of 40 | * California, Berkeley and its contributors. 41 | * 4. Neither the name of the University nor the names of its contributors 42 | * may be used to endorse or promote products derived from this software 43 | * without specific prior written permission. 44 | * 45 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 46 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 47 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 48 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 49 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 50 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 51 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 52 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 53 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 54 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 55 | * SUCH DAMAGE. 56 | */ 57 | 58 | rune_t 59 | _none_sgetrune(string, n, result) 60 | const char *string; 61 | size_t n; 62 | char const **result; 63 | { 64 | if (n < 1) { 65 | if (result) 66 | *result = string; 67 | return(_INVALID_RUNE); 68 | } 69 | if (result) 70 | *result = string + 1; 71 | return(*string & 0xff); 72 | } 73 | 74 | int 75 | _none_sputrune(c, string, n, result) 76 | rune_t c; 77 | char *string, **result; 78 | size_t n; 79 | { 80 | if (n >= 1) { 81 | if (string) 82 | *string = c; 83 | if (result) 84 | *result = string + 1; 85 | } else if (result) 86 | *result = (char *)0; 87 | return(1); 88 | } 89 | -------------------------------------------------------------------------------- /osx/loader/gelfload/bbuffer.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "../config.h" 6 | 7 | #include "bbuffer.h" 8 | 9 | #if defined(HAVE_MMAP) 10 | #include 11 | 12 | /* mmap-based is the easiest */ 13 | void *bbuffer(void *loc, size_t sz) { 14 | void *ret; 15 | int page = getpagesize(); 16 | 17 | /* switch on fixed-ness */ 18 | if (loc) { 19 | /* make sure it's on a page boundary */ 20 | void *wantloc = loc; 21 | ssize_t offset; 22 | offset = (ssize_t) loc % page; 23 | if (offset) { 24 | sz += offset; 25 | loc = (char *)loc - offset; 26 | } 27 | 28 | ret = mmap(loc, sz, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON|MAP_FIXED, 29 | -1, 0); 30 | if (ret == loc) ret = wantloc; 31 | } else { 32 | ret = mmap(NULL, sz, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, 33 | -1, 0); 34 | } 35 | 36 | if (ret == (void *) -1) { 37 | perror("mmap"); 38 | exit(1); 39 | } 40 | 41 | return ret; 42 | } 43 | 44 | int xbbuffer(void *loc, size_t sz) 45 | { 46 | return mprotect(loc, sz, PROT_READ | PROT_EXEC); 47 | } 48 | 49 | void unbbuffer(void *loc, size_t sz) 50 | { 51 | munmap(loc, sz); 52 | } 53 | 54 | #elif defined(__WIN32) 55 | #ifndef WIN32_LEAN_AND_MEAN 56 | #define WIN32_LEAN_AND_MEAN 57 | #endif 58 | #include 59 | 60 | void *bbuffer(void *loc, size_t sz) 61 | { 62 | /* shockingly, Windows makes this far more difficult than it needs to be */ 63 | SYSTEM_INFO si; 64 | MEMORY_BASIC_INFORMATION mbi; 65 | ssize_t agrn, offset, szoffset; 66 | void *q, *ret; 67 | 68 | if (loc) { 69 | /* the complicated case */ 70 | 71 | /* get the allocation granularity */ 72 | GetSystemInfo(&si); 73 | agrn = si.dwAllocationGranularity; 74 | 75 | /* make sure it's on the allocation granularity */ 76 | offset = (ssize_t) loc % agrn; 77 | if (offset) { 78 | sz += offset; 79 | loc -= offset; 80 | } 81 | 82 | /* then make sure sz is also aligned */ 83 | szoffset = sz % agrn; 84 | if (szoffset) { 85 | sz += (agrn - szoffset); 86 | } 87 | 88 | /* free everything */ 89 | for (q = loc; q < loc + sz; q += agrn) { 90 | if (VirtualQuery(q, &mbi, agrn) >= sizeof(mbi)) { 91 | if (mbi.State != MEM_FREE) { 92 | /* get rid of it */ 93 | if (mbi.Type & MEM_IMAGE) 94 | UnmapViewOfFile(mbi.AllocationBase); 95 | VirtualFree(mbi.AllocationBase, 0, MEM_RELEASE); 96 | } 97 | } 98 | } 99 | 100 | /* finally, allocate */ 101 | ret = VirtualAlloc(loc, sz, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE); 102 | if (ret == NULL) { 103 | fprintf(stderr, "VirtualAlloc failed with error %d\n", GetLastError()); 104 | exit(1); 105 | } 106 | 107 | return ret + offset; 108 | 109 | } else { 110 | ret = VirtualAlloc(NULL, sz, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE); 111 | if (ret == NULL) { 112 | fprintf(stderr, "VirtualAlloc failed with error %d\n", GetLastError()); 113 | exit(1); 114 | } 115 | 116 | return ret; 117 | 118 | } 119 | } 120 | 121 | void unbbuffer(void *loc, size_t sz) 122 | { 123 | VirtualFree(loc, 0, MEM_RELEASE); 124 | } 125 | 126 | int xbbuffer(void *loc, size_t sz) 127 | { 128 | DWORD old; 129 | return !VirtualProtect(loc, sz, PAGE_EXECUTE_READ, &old); 130 | } 131 | 132 | #else 133 | 134 | void *bbuffer(void *loc, size_t sz) 135 | { 136 | /* worst case scenario, just malloc */ 137 | void *ret = malloc(sz); 138 | if (ret == NULL) { 139 | perror("malloc"); 140 | exit(1); 141 | } 142 | return ret; 143 | } 144 | 145 | int xbbuffer(void *loc, size_t sz) 146 | { 147 | return -1; 148 | } 149 | 150 | void unbbuffer(void *loc, size_t sz) 151 | { 152 | free(loc); 153 | } 154 | 155 | #endif 156 | -------------------------------------------------------------------------------- /linux/loader/rune/mac-ctype.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2000, 2005, 2008 Apple Inc. All rights reserved. 3 | * 4 | * @APPLE_LICENSE_HEADER_START@ 5 | * 6 | * This file contains Original Code and/or Modifications of Original Code 7 | * as defined in and that are subject to the Apple Public Source License 8 | * Version 2.0 (the 'License'). You may not use this file except in 9 | * compliance with the License. Please obtain a copy of the License at 10 | * http://www.opensource.apple.com/apsl/ and read it before using this 11 | * file. 12 | * 13 | * The Original Code and all software distributed under the License are 14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 | * Please see the License for the specific language governing rights and 19 | * limitations under the License. 20 | * 21 | * @APPLE_LICENSE_HEADER_END@ 22 | */ 23 | /* 24 | * Copyright (c) 1989, 1993 25 | * The Regents of the University of California. All rights reserved. 26 | * (c) UNIX System Laboratories, Inc. 27 | * All or some portions of this file are derived from material licensed 28 | * to the University of California by American Telephone and Telegraph 29 | * Co. or Unix System Laboratories, Inc. and are reproduced herein with 30 | * the permission of UNIX System Laboratories, Inc. 31 | * 32 | * This code is derived from software contributed to Berkeley by 33 | * Paul Borman at Krystal Technologies. 34 | * 35 | * Redistribution and use in source and binary forms, with or without 36 | * modification, are permitted provided that the following conditions 37 | * are met: 38 | * 1. Redistributions of source code must retain the above copyright 39 | * notice, this list of conditions and the following disclaimer. 40 | * 2. Redistributions in binary form must reproduce the above copyright 41 | * notice, this list of conditions and the following disclaimer in the 42 | * documentation and/or other materials provided with the distribution. 43 | * 3. All advertising materials mentioning features or use of this software 44 | * must display the following acknowledgement: 45 | * This product includes software developed by the University of 46 | * California, Berkeley and its contributors. 47 | * 4. Neither the name of the University nor the names of its contributors 48 | * may be used to endorse or promote products derived from this software 49 | * without specific prior written permission. 50 | * 51 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 52 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 53 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 54 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 55 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 56 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 57 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 58 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 59 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 60 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 61 | * SUCH DAMAGE. 62 | * 63 | * @(#)ctype.h 8.4 (Berkeley) 1/21/94 64 | */ 65 | 66 | #ifndef MAC_CTYPE_H_ 67 | #define MAC_CTYPE_H_ 68 | 69 | #define _CTYPE_A 0x00000100L /* Alpha */ 70 | #define _CTYPE_C 0x00000200L /* Control */ 71 | #define _CTYPE_D 0x00000400L /* Digit */ 72 | #define _CTYPE_G 0x00000800L /* Graph */ 73 | #define _CTYPE_L 0x00001000L /* Lower */ 74 | #define _CTYPE_P 0x00002000L /* Punct */ 75 | #define _CTYPE_S 0x00004000L /* Space */ 76 | #define _CTYPE_U 0x00008000L /* Upper */ 77 | #define _CTYPE_X 0x00010000L /* X digit */ 78 | #define _CTYPE_B 0x00020000L /* Blank */ 79 | #define _CTYPE_R 0x00040000L /* Print */ 80 | #define _CTYPE_I 0x00080000L /* Ideogram */ 81 | #define _CTYPE_T 0x00100000L /* Special */ 82 | #define _CTYPE_Q 0x00200000L /* Phonogram */ 83 | 84 | /* 85 | * Backward compatibility 86 | */ 87 | #define _A _CTYPE_A /* Alpha */ 88 | #define _C _CTYPE_C /* Control */ 89 | #define _D _CTYPE_D /* Digit */ 90 | #define _G _CTYPE_G /* Graph */ 91 | #define _L _CTYPE_L /* Lower */ 92 | #define _P _CTYPE_P /* Punct */ 93 | #define _S _CTYPE_S /* Space */ 94 | #define _U _CTYPE_U /* Upper */ 95 | #define _X _CTYPE_X /* X digit */ 96 | #define _B _CTYPE_B /* Blank */ 97 | #define _R _CTYPE_R /* Print */ 98 | #define _I _CTYPE_I /* Ideogram */ 99 | #define _T _CTYPE_T /* Special */ 100 | #define _Q _CTYPE_Q /* Phonogram */ 101 | 102 | #endif /* !MAC_CTYPE_H_ */ 103 | -------------------------------------------------------------------------------- /linux/loader/rune/runetype.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * Copyright (c) 1993 3 | * The Regents of the University of California. All rights reserved. 4 | * 5 | * This code is derived from software contributed to Berkeley by 6 | * Paul Borman at Krystal Technologies. 7 | * 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions 10 | * are met: 11 | * 1. Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 3. All advertising materials mentioning features or use of this software 17 | * must display the following acknowledgement: 18 | * This product includes software developed by the University of 19 | * California, Berkeley and its contributors. 20 | * 4. Neither the name of the University nor the names of its contributors 21 | * may be used to endorse or promote products derived from this software 22 | * without specific prior written permission. 23 | * 24 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 | * SUCH DAMAGE. 35 | * 36 | * @(#)runetype.h 8.1 (Berkeley) 6/2/93 37 | */ 38 | 39 | #ifndef _RUNETYPE_H_ 40 | #define _RUNETYPE_H_ 41 | 42 | #include <_types.h> 43 | #include 44 | 45 | typedef wchar_t __darwin_rune_t; 46 | typedef size_t __darwin_size_t; 47 | 48 | #if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) 49 | 50 | #ifndef _SIZE_T 51 | #define _SIZE_T 52 | typedef __darwin_size_t size_t; 53 | #endif 54 | 55 | #ifndef _CT_RUNE_T 56 | #define _CT_RUNE_T 57 | typedef __darwin_ct_rune_t ct_rune_t; 58 | #endif 59 | 60 | #ifndef _RUNE_T 61 | #define _RUNE_T 62 | typedef __darwin_rune_t rune_t; 63 | #endif 64 | 65 | #ifndef __cplusplus 66 | #ifndef _WCHAR_T 67 | #define _WCHAR_T 68 | typedef __darwin_wchar_t wchar_t; 69 | #endif /* _WCHAR_T */ 70 | #endif /* __cplusplus */ 71 | 72 | #ifndef _WINT_T 73 | #define _WINT_T 74 | typedef __darwin_wint_t wint_t; 75 | #endif 76 | 77 | #endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */ 78 | 79 | #define _CACHED_RUNES (1 <<8 ) /* Must be a power of 2 */ 80 | #define _CRMASK (~(_CACHED_RUNES - 1)) 81 | 82 | /* 83 | * The lower 8 bits of runetype[] contain the digit value of the rune. 84 | */ 85 | typedef struct { 86 | __darwin_rune_t __min; /* First rune of the range */ 87 | __darwin_rune_t __max; /* Last rune (inclusive) of the range */ 88 | __darwin_rune_t __map; /* What first maps to in maps */ 89 | uint32_t *__types; /* Array of types in range */ 90 | } _RuneEntry; 91 | 92 | typedef struct { 93 | int __nranges; /* Number of ranges stored */ 94 | _RuneEntry *__ranges; /* Pointer to the ranges */ 95 | } _RuneRange; 96 | 97 | typedef struct { 98 | char __name[14]; /* CHARCLASS_NAME_MAX = 14 */ 99 | uint32_t __mask; /* charclass mask */ 100 | } _RuneCharClass; 101 | 102 | typedef struct { 103 | char __magic[8]; /* Magic saying what version we are */ 104 | char __encoding[32]; /* ASCII name of this encoding */ 105 | 106 | __darwin_rune_t (*__sgetrune)(const char *, __darwin_size_t, char const **); 107 | int (*__sputrune)(__darwin_rune_t, char *, __darwin_size_t, char **); 108 | __darwin_rune_t __invalid_rune; 109 | 110 | uint32_t __runetype[_CACHED_RUNES]; 111 | __darwin_rune_t __maplower[_CACHED_RUNES]; 112 | __darwin_rune_t __mapupper[_CACHED_RUNES]; 113 | 114 | /* 115 | * The following are to deal with Runes larger than _CACHED_RUNES - 1. 116 | * Their data is actually contiguous with this structure so as to make 117 | * it easier to read/write from/to disk. 118 | */ 119 | _RuneRange __runetype_ext; 120 | _RuneRange __maplower_ext; 121 | _RuneRange __mapupper_ext; 122 | 123 | void *__variable; /* Data which depends on the encoding */ 124 | int __variable_len; /* how long that data is */ 125 | 126 | /* 127 | * extra fields to deal with arbitrary character classes 128 | */ 129 | int __ncharclasses; 130 | _RuneCharClass *__charclasses; 131 | } _RuneLocale; 132 | 133 | #define _RUNE_MAGIC_A "RuneMagA" /* Indicates version A of RuneLocale */ 134 | 135 | __BEGIN_DECLS 136 | extern _RuneLocale _DefaultRuneLocale; 137 | extern _RuneLocale *_CurrentRuneLocale; 138 | __END_DECLS 139 | 140 | #endif /* !_RUNETYPE_H_ */ 141 | -------------------------------------------------------------------------------- /osx/loader/main.c: -------------------------------------------------------------------------------- 1 | #define _GNU_SOURCE 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "elfload.h" 9 | #include "elfload_dlfcn.h" 10 | #include "elfload_exec.h" 11 | 12 | #define INFO(args...) //printf(args) 13 | #define ERR(args...) fprintf(stderr, args) 14 | 15 | #define STRINGIFY(x) #x 16 | #define STRINGIT(x) STRINGIFY(x) 17 | 18 | char XSYMBOL[XSYMBOL_SIZE]; 19 | 20 | const char * 21 | hook_libs(const char *nm) 22 | { 23 | static const char *libs[][2] = { 24 | #ifdef __APPLE__ 25 | { "librt.so.1", NULL }, 26 | { "libc.so.6", "libhost_/usr/lib/libSystem.B.dylib" }, 27 | { "libdl.so.2", "libhost_/usr/lib/libdl.dylib" }, 28 | { "libgcc_s.so.1", "libhost_/usr/lib/libgcc_s.1.dylib" }, 29 | { "libm.so.6", "libhost_/usr/lib/libm.dylib" }, 30 | { "libpthread.so.0", "libhost_/usr/lib/libpthread.dylib" }, 31 | { "libstdc++.so.6", "libhost_/usr/lib/libstdc++.6.dylib" }, 32 | { "libSomething.so", "libhost_../libSomething.dylib" }, 33 | #else 34 | { "librt.so.1", "libhost_librt.so.1" }, 35 | { "libc.so.6", "libhost_libc.so.6" }, 36 | { "libdl.so.2", "libhost_libdl.so.2" }, 37 | { "libgcc_s.so.1", "libhost_libgcc_s.so.1" }, 38 | { "libm.so.6", "libhost_libm.so.6" }, 39 | { "libpthread.so.0", "libhost_libpthread.so.0" }, 40 | { "libstdc++.so.6", "libhost_libstdc++.so.6" }, 41 | #endif 42 | { NULL, NULL } 43 | }; 44 | unsigned i; 45 | for (i = 0; libs[i][0]; i++) { 46 | if (!strcmp(nm, libs[i][0])) { 47 | return libs[i][1]; 48 | } 49 | } 50 | return nm; 51 | } 52 | 53 | #ifdef WEIRD_FUNC_CALL 54 | struct a { 55 | int rv; 56 | int tmp[2]; 57 | }; 58 | 59 | struct b { 60 | int parm[32]; 61 | }; 62 | 63 | extern int (*weirdo)(struct b b); 64 | 65 | static struct a 66 | my_weirdo(struct b b) 67 | { 68 | struct a a; 69 | // fprintf(stderr, "weirdo(0x%x, 0x%x, 0x%x, ...)", b.parm[0], b.parm[1], b.parm[2]); 70 | a.rv = -1;//weirdo(b); 71 | // fprintf(stderr, " -> 0x%x\n", a.rv); 72 | return a; /* XXX ret 4 */ 73 | } 74 | 75 | static struct a (*new_weirdo)(struct b b) = my_weirdo; 76 | #endif 77 | 78 | extern char cxa_throw[]; 79 | extern void *eh_frame; 80 | 81 | const char * 82 | hook_syms(const char *nm, void **p) 83 | { 84 | // XXX elfload_dl* API is not quite correct, because 85 | // XXX it won't call ctors/dtors but will do for now 86 | static const char *syms[][3] = { 87 | { "dlopen", NULL, (char *)(uintptr_t)elfload_dlopen }, 88 | { "dlsym", NULL, (char *)(uintptr_t)elfload_dlsym }, 89 | { "dlclose", NULL, (char *)(uintptr_t)elfload_dlclose }, 90 | { "dlerror", NULL, (char *)(uintptr_t)elfload_dlerror }, 91 | { "__cxa_throw", NULL, (char *)(uintptr_t)cxa_throw }, 92 | #ifdef __APPLE__ 93 | { "_Znwj", "_Znwm", NULL }, 94 | { "__errno_location", "__error", NULL }, 95 | #ifdef WEIRD_FUNC_CALL 96 | { "weirdo", NULL, (char *)&new_weirdo }, 97 | #endif 98 | #endif 99 | { NULL, NULL }, 100 | }; 101 | unsigned i; 102 | *p = NULL; 103 | for (i = 0; syms[i][0]; i++) { 104 | if (!strcmp(nm, syms[i][0])) { 105 | if (syms[i][2]) { 106 | *p = (void *)syms[i][2]; 107 | return NULL; 108 | } 109 | return syms[i][1]; 110 | } 111 | } 112 | return nm; 113 | } 114 | 115 | static char * 116 | build_path(void) 117 | { 118 | static char buf[4096]; 119 | Dl_info info; 120 | int rv = dladdr((void *)(uintptr_t)build_path, &info); 121 | if (rv && info.dli_fname) { 122 | size_t len; 123 | const char *p = strrchr(info.dli_fname, '.'); 124 | if (p && p > info.dli_fname && (/*p[-1] != '/' ||*/ p[1] != '/')) { 125 | len = p - info.dli_fname; 126 | } else { 127 | len = strlen(info.dli_fname); 128 | } 129 | if (len + 1 + sizeof("so") > sizeof(buf)) { 130 | return NULL; 131 | } 132 | memcpy(buf, info.dli_fname, len); 133 | buf[len++] = '.'; 134 | strcpy(buf + len, "so"); 135 | return buf; 136 | } 137 | return NULL; 138 | } 139 | 140 | void __attribute__((constructor)) 141 | initme(void) 142 | { 143 | void *sym; 144 | struct ELF_File *f; 145 | char *dir, *fil, *path = build_path(); 146 | 147 | if (!path) { 148 | return; 149 | } 150 | INFO("load: %s\n", path); 151 | 152 | fil = strrchr(path, '/'); 153 | if (!fil) { 154 | dir = ""; 155 | fil = path; 156 | } else { 157 | *fil++ = '\0'; 158 | dir = path; 159 | } 160 | 161 | elfload_dlinstdir = dir; 162 | 163 | /* load them all in */ 164 | f = loadELF(fil, dir, 0); 165 | 166 | if (!f) { 167 | ERR("Failed to load %s.\n", fil); 168 | return; 169 | } 170 | eh_frame = f->eh_frame; 171 | 172 | /* relocate them */ 173 | relocateELFs(); 174 | 175 | /* initialize .so files */ 176 | initELF(NULL); 177 | 178 | /* do our thing */ 179 | sym = elfload_dlsym(f, STRINGIT(XSYMBOL)); 180 | if (sym) { 181 | memcpy(XSYMBOL, sym, sizeof(XSYMBOL)); 182 | } 183 | 184 | INFO("base: %p\n", (void *)f->loc); 185 | } 186 | 187 | void __attribute__((destructor)) 188 | finime(void) 189 | { 190 | unloadELFs(); 191 | INFO("unload\n"); 192 | } 193 | 194 | #ifdef HAVE_MAIN 195 | int 196 | main(void) 197 | { 198 | void *sym; 199 | sym = elfload_dlsym(NULL, "square"); 200 | if (sym) { 201 | printf("square = %d\n", ((int (*)(int))(uintptr_t)sym)(3)); 202 | } 203 | sym = elfload_dlsym(NULL, "hello"); 204 | if (sym) { 205 | printf("count = %d\n", ((int (*)(char *))(uintptr_t)sym)("world")); 206 | } 207 | sym = elfload_dlsym(NULL, "exposed"); 208 | if (sym) { 209 | printf("exposed = %d\n", *(int *)sym); 210 | } 211 | sym = elfload_dlsym(NULL, "plus"); 212 | if (sym) { 213 | printf("plus = %d\n", ((int (*)(int))(uintptr_t)sym)(4)); 214 | } 215 | return 0; 216 | } 217 | #endif 218 | -------------------------------------------------------------------------------- /linux/loader/rune/runetable.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. 3 | * 4 | * @APPLE_LICENSE_HEADER_START@ 5 | * 6 | * The contents of this file constitute Original Code as defined in and 7 | * are subject to the Apple Public Source License Version 1.1 (the 8 | * "License"). You may not use this file except in compliance with the 9 | * License. Please obtain a copy of the License at 10 | * http://www.apple.com/publicsource and read it before using this file. 11 | * 12 | * This Original Code and all software distributed under the License are 13 | * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER 14 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 15 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the 17 | * License for the specific language governing rights and limitations 18 | * under the License. 19 | * 20 | * @APPLE_LICENSE_HEADER_END@ 21 | */ 22 | /* 23 | * Copyright (c) 1993 24 | * The Regents of the University of California. All rights reserved. 25 | * 26 | * This code is derived from software contributed to Berkeley by 27 | * Paul Borman at Krystal Technologies. 28 | * 29 | * Redistribution and use in source and binary forms, with or without 30 | * modification, are permitted provided that the following conditions 31 | * are met: 32 | * 1. Redistributions of source code must retain the above copyright 33 | * notice, this list of conditions and the following disclaimer. 34 | * 2. Redistributions in binary form must reproduce the above copyright 35 | * notice, this list of conditions and the following disclaimer in the 36 | * documentation and/or other materials provided with the distribution. 37 | * 3. All advertising materials mentioning features or use of this software 38 | * must display the following acknowledgement: 39 | * This product includes software developed by the University of 40 | * California, Berkeley and its contributors. 41 | * 4. Neither the name of the University nor the names of its contributors 42 | * may be used to endorse or promote products derived from this software 43 | * without specific prior written permission. 44 | * 45 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 46 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 47 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 48 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 49 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 50 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 51 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 52 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 53 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 54 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 55 | * SUCH DAMAGE. 56 | */ 57 | 58 | _RuneLocale _DefaultRuneLocale = { 59 | _RUNE_MAGIC_A, 60 | "none", 61 | _none_sgetrune, 62 | _none_sputrune, 63 | 0xFFFD, 64 | 65 | { /*00*/ _C, _C, _C, _C, 66 | _C, _C, _C, _C, 67 | /*08*/ _C, _C|_S|_B, _C|_S, _C|_S, 68 | _C|_S, _C|_S, _C, _C, 69 | /*10*/ _C, _C, _C, _C, 70 | _C, _C, _C, _C, 71 | /*18*/ _C, _C, _C, _C, 72 | _C, _C, _C, _C, 73 | /*20*/ _S|_B|_R, _P|_R|_G, _P|_R|_G, _P|_R|_G, 74 | _P|_R|_G, _P|_R|_G, _P|_R|_G, _P|_R|_G, 75 | /*28*/ _P|_R|_G, _P|_R|_G, _P|_R|_G, _P|_R|_G, 76 | _P|_R|_G, _P|_R|_G, _P|_R|_G, _P|_R|_G, 77 | /*30*/ _D|_R|_G|_X|0, _D|_R|_G|_X|1, _D|_R|_G|_X|2, _D|_R|_G|_X|3, 78 | _D|_R|_G|_X|4, _D|_R|_G|_X|5, _D|_R|_G|_X|6, _D|_R|_G|_X|7, 79 | /*38*/ _D|_R|_G|_X|8, _D|_R|_G|_X|9, _P|_R|_G, _P|_R|_G, 80 | _P|_R|_G, _P|_R|_G, _P|_R|_G, _P|_R|_G, 81 | /*40*/ _P|_R|_G, _U|_X|_R|_G|_A|10, _U|_X|_R|_G|_A|11, _U|_X|_R|_G|_A|12, 82 | _U|_X|_R|_G|_A|13, _U|_X|_R|_G|_A|14, _U|_X|_R|_G|_A|15, _U|_R|_G|_A, 83 | /*48*/ _U|_R|_G|_A, _U|_R|_G|_A, _U|_R|_G|_A, _U|_R|_G|_A, 84 | _U|_R|_G|_A, _U|_R|_G|_A, _U|_R|_G|_A, _U|_R|_G|_A, 85 | /*50*/ _U|_R|_G|_A, _U|_R|_G|_A, _U|_R|_G|_A, _U|_R|_G|_A, 86 | _U|_R|_G|_A, _U|_R|_G|_A, _U|_R|_G|_A, _U|_R|_G|_A, 87 | /*58*/ _U|_R|_G|_A, _U|_R|_G|_A, _U|_R|_G|_A, _P|_R|_G, 88 | _P|_R|_G, _P|_R|_G, _P|_R|_G, _P|_R|_G, 89 | /*60*/ _P|_R|_G, _L|_X|_R|_G|_A|10, _L|_X|_R|_G|_A|11, _L|_X|_R|_G|_A|12, 90 | _L|_X|_R|_G|_A|13, _L|_X|_R|_G|_A|14, _L|_X|_R|_G|_A|15, _L|_R|_G|_A, 91 | /*68*/ _L|_R|_G|_A, _L|_R|_G|_A, _L|_R|_G|_A, _L|_R|_G|_A, 92 | _L|_R|_G|_A, _L|_R|_G|_A, _L|_R|_G|_A, _L|_R|_G|_A, 93 | /*70*/ _L|_R|_G|_A, _L|_R|_G|_A, _L|_R|_G|_A, _L|_R|_G|_A, 94 | _L|_R|_G|_A, _L|_R|_G|_A, _L|_R|_G|_A, _L|_R|_G|_A, 95 | /*78*/ _L|_R|_G|_A, _L|_R|_G|_A, _L|_R|_G|_A, _P|_R|_G, 96 | _P|_R|_G, _P|_R|_G, _P|_R|_G, _C, 97 | }, 98 | { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 99 | 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 100 | 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 101 | 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 102 | 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 103 | 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 104 | 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 105 | 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 106 | 0x40, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 107 | 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 108 | 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 109 | 'x', 'y', 'z', 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 110 | 0x60, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 111 | 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 112 | 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 113 | 'x', 'y', 'z', 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 114 | 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 115 | 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 116 | 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 117 | 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 118 | 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 119 | 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 120 | 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 121 | 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 122 | 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 123 | 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 124 | 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 125 | 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 126 | 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 127 | 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 128 | 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 129 | 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, 130 | }, 131 | { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 132 | 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 133 | 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 134 | 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 135 | 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 136 | 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 137 | 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 138 | 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 139 | 0x40, 'A', 'B', 'C', 'D', 'E', 'F', 'G', 140 | 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 141 | 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 142 | 'X', 'Y', 'Z', 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 143 | 0x60, 'A', 'B', 'C', 'D', 'E', 'F', 'G', 144 | 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 145 | 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 146 | 'X', 'Y', 'Z', 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 147 | 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 148 | 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 149 | 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 150 | 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 151 | 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 152 | 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 153 | 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 154 | 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 155 | 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 156 | 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 157 | 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 158 | 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 159 | 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 160 | 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 161 | 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 162 | 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, 163 | }, 164 | }; 165 | -------------------------------------------------------------------------------- /osx/loader/gelfload/elfload.c: -------------------------------------------------------------------------------- 1 | #ifndef _GNU_SOURCE /* for RTLD_DEFAULT */ 2 | #define _GNU_SOURCE 1 3 | #endif 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include "bbuffer.h" 14 | 15 | #include "../config.h" 16 | 17 | #ifdef HAVE_MMAP 18 | #include 19 | #endif 20 | 21 | #ifdef HAVE_DLFCN_H 22 | #include 23 | #endif 24 | 25 | #ifdef __WIN32 26 | #ifndef WIN32_LEAN_AND_MEAN 27 | #define WIN32_LEAN_AND_MEAN 28 | #endif 29 | #include 30 | #endif 31 | 32 | #include "elfload.h" 33 | #include "elfload_dlfcn.h" 34 | 35 | const char *hook_libs(const char *); 36 | const char *hook_syms(const char *, void **); 37 | 38 | void *gnu_lookup(const char *name, struct ELF_File *f, int inlocal, ElfNative_Sym **syminto); 39 | 40 | /* An array of files currently in the process of loading */ 41 | #define MAX_ELF_FILES 255 42 | struct ELF_File elfFiles[MAX_ELF_FILES]; 43 | int elfFileCount = 0; 44 | 45 | /* The function to actually load ELF files into memory */ 46 | struct ELF_File *loadELF(const char *nm, const char *instdir, int maybe) 47 | { 48 | int i, fileNo, phdri; 49 | struct ELF_File *f; 50 | char *curphdrl; 51 | ElfNative_Phdr *curphdr; 52 | ElfNative_Dyn *curdyn; 53 | ElfNative_Shdr *sh; 54 | 55 | nm = hook_libs(nm); 56 | if (!nm) { 57 | return NULL; 58 | } 59 | 60 | /* first, make sure it's not already loaded or loading */ 61 | for (i = 0; i < elfFileCount; i++) { 62 | if (strcmp(elfFiles[i].nm, nm) == 0) return &(elfFiles[i]); 63 | } 64 | 65 | /* now start preparing to load it */ 66 | fileNo = elfFileCount; 67 | f = &(elfFiles[fileNo]); 68 | memset(f, 0, sizeof(struct ELF_File)); 69 | elfFileCount++; 70 | f->nm = strdup(nm); 71 | 72 | /* if this is a host library, circumvent all the ELF stuff and go straight for the host */ 73 | if (strncmp(nm, "libhost_", 8) == 0) { 74 | f->hostlib = HOSTLIB_HOST; 75 | #if defined(HAVE_DLFCN_H) 76 | if (strcmp(nm, "libhost_.so") == 0) { 77 | /* the entire host */ 78 | #ifdef RTLD_DEFAULT 79 | f->prog = RTLD_DEFAULT; 80 | #else 81 | f->prog = dlopen(NULL, RTLD_NOW|RTLD_GLOBAL); 82 | #endif 83 | } else { 84 | f->prog = dlopen(nm + 8, RTLD_NOW|RTLD_GLOBAL); 85 | 86 | if (f->prog == NULL) { 87 | /* try with an explicit path */ 88 | char *fullpath; 89 | fullpath = malloc(strlen(elfload_dlinstdir) + strlen(nm) + 1); 90 | if (fullpath == NULL) { 91 | perror("malloc"); 92 | exit(1); 93 | } 94 | sprintf(fullpath, "%s/%s", elfload_dlinstdir, nm + 8); 95 | f->prog = dlopen(fullpath, RTLD_NOW|RTLD_GLOBAL); 96 | free(fullpath); 97 | } 98 | 99 | if (f->prog == NULL) { 100 | fprintf(stderr, "Could not resolve host library %s: %s.\n", nm + 8, dlerror()); 101 | exit(1); 102 | } 103 | } 104 | #elif defined(__WIN32) 105 | if (strcmp(nm, "libhost_.so") == 0) { 106 | f->prog = LoadLibrary("msvcrt.dll"); 107 | } else { 108 | f->prog = LoadLibrary(nm + 8); 109 | } 110 | if (f->prog == NULL) { 111 | fprintf(stderr, "Could not resolve host library %s.\n", nm + 8); 112 | exit(1); 113 | } 114 | #else 115 | fprintf(stderr, "This version of elfload is not capable of loading the host library %s.\n", 116 | nm + 8); 117 | exit(1); 118 | #endif 119 | return f; 120 | 121 | } else if (strncmp(nm, "libloader_", 10) == 0) { 122 | /* must be provided by the loader. Only dl.0 is provided right now */ 123 | if (strcmp(nm, "libloader_dl.0") == 0) { 124 | f->hostlib = HOSTLIB_DL; 125 | 126 | } else { 127 | fprintf(stderr, "Loader lib %s unsupported.\n", nm); 128 | exit(1); 129 | 130 | } 131 | 132 | return f; 133 | } 134 | 135 | readFile(nm, instdir, f); 136 | 137 | /* make sure it's an ELF file */ 138 | f->ehdr = (ElfNative_Ehdr *) f->prog; 139 | if (memcmp(f->ehdr->e_ident, ELFMAG, SELFMAG) != 0) { 140 | if (!maybe) { 141 | fprintf(stderr, "%s does not appear to be an ELF file.\n", nm); 142 | exit(1); 143 | } else { 144 | return NULL; 145 | } 146 | } 147 | 148 | /* only native-bit supported for the moment */ 149 | if ((SIZEOF_VOID_P == 4 && f->ehdr->e_ident[EI_CLASS] != ELFCLASS32) || 150 | (SIZEOF_VOID_P == 8 && f->ehdr->e_ident[EI_CLASS] != ELFCLASS64)) { 151 | if (!maybe) { 152 | fprintf(stderr, "%s is not a %d-bit ELF file.\n", nm, SIZEOF_VOID_P * 8); 153 | exit(1); 154 | } else { 155 | return NULL; 156 | } 157 | } 158 | 159 | /* FIXME: check endianness */ 160 | 161 | /* must be an executable or .so to be loaded */ 162 | if (f->ehdr->e_type != ET_EXEC && 163 | f->ehdr->e_type != ET_DYN) { 164 | if (!maybe) { 165 | fprintf(stderr, "%s is not an executable or shared object file.\n", nm); 166 | exit(1); 167 | } else { 168 | return NULL; 169 | } 170 | } 171 | 172 | /* now go through program headers, to find the allocation space of this file */ 173 | f->min = (void *) -1; 174 | f->max = 0; 175 | curphdrl = f->prog + f->ehdr->e_phoff - f->ehdr->e_phentsize; 176 | 177 | for (phdri = 0; phdri < f->ehdr->e_phnum; phdri++) { 178 | curphdrl += f->ehdr->e_phentsize; 179 | curphdr = (ElfNative_Phdr *) curphdrl; 180 | 181 | /* perhaps check its location */ 182 | if (curphdr->p_type == PT_LOAD) { 183 | /* adjust min/max */ 184 | if ((char *) curphdr->p_vaddr < f->min) { 185 | f->min = (void *) curphdr->p_vaddr; 186 | } 187 | if ((char *) curphdr->p_vaddr + curphdr->p_memsz > f->max) { 188 | f->max = (char *) curphdr->p_vaddr + curphdr->p_memsz; 189 | } 190 | 191 | } else if (maybe && curphdr->p_type == PT_INTERP) { 192 | /* if we're only maybe-loading, check the loader */ 193 | if (strcmp((char *) (f->prog + curphdr->p_offset), "/usr/bin/gelfload-ld")) { 194 | /* wrong loader! */ 195 | return NULL; 196 | } 197 | 198 | } 199 | } 200 | 201 | /* with this size info, we can allocate the space */ 202 | f->memsz = f->max - f->min; 203 | 204 | /* if this is a binary, try to allocate it in place. elfload is addressed above 0x18000000 */ 205 | if (f->ehdr->e_type == ET_EXEC && f->max < (char *) 0x18000000) { 206 | f->loc = bbuffer(f->min, f->memsz); 207 | 208 | } else { 209 | f->loc = bbuffer(NULL, f->memsz); 210 | 211 | } 212 | memset(f->loc, 0, f->memsz); 213 | 214 | f->offset = f->loc - f->min; 215 | 216 | /* we have the space, so load it in */ 217 | curphdrl = f->prog + f->ehdr->e_phoff - f->ehdr->e_phentsize; 218 | for (phdri = 0; phdri < f->ehdr->e_phnum; phdri++) { 219 | curphdrl += f->ehdr->e_phentsize; 220 | curphdr = (ElfNative_Phdr *) curphdrl; 221 | 222 | /* perhaps load it in */ 223 | if (curphdr->p_type == PT_LOAD) { 224 | if (curphdr->p_filesz > 0) { 225 | /* OK, there's something to copy in, so do so */ 226 | memcpy((char *) curphdr->p_vaddr + f->offset, 227 | f->prog + curphdr->p_offset, 228 | curphdr->p_filesz); 229 | } 230 | 231 | if (curphdr->p_flags & PF_W) { 232 | f->writable = (char *)f->loc + (curphdr->p_vaddr & ~0xFFF); 233 | } 234 | 235 | } else if (curphdr->p_type == PT_GNU_EH_FRAME) { 236 | /* exceptions ftw */ 237 | f->eh_frame = (char *) (f->loc + curphdr->p_vaddr + curphdr->p_memsz); 238 | 239 | } else if (curphdr->p_type == PT_DYNAMIC) { 240 | /* we need this to load in dependencies, et cetera */ 241 | f->dynamic = (ElfNative_Dyn *) (f->prog + curphdr->p_offset); 242 | 243 | } 244 | } 245 | 246 | /* now go through dynamic entries, looking for basic vital info */ 247 | for (curdyn = f->dynamic; curdyn && curdyn->d_tag != DT_NULL; curdyn++) { 248 | if (curdyn->d_tag == DT_STRTAB) { 249 | f->strtab = (char *) (curdyn->d_un.d_ptr + f->offset); 250 | 251 | } else if (curdyn->d_tag == DT_SYMTAB) { 252 | f->symtab = (ElfNative_Sym *) (curdyn->d_un.d_ptr + f->offset); 253 | 254 | } else if (curdyn->d_tag == DT_HASH) { 255 | f->hashtab = (ElfNative_Word *) (curdyn->d_un.d_ptr + f->offset); 256 | 257 | } else if (curdyn->d_tag == DT_GNU_HASH) { 258 | f->gnuhash = (Elf32_Word *) (curdyn->d_un.d_ptr + f->offset); 259 | 260 | } else if (curdyn->d_tag == DT_RELA) { 261 | f->rela = (ElfNative_Rela *) (curdyn->d_un.d_ptr + f->offset); 262 | 263 | } else if (curdyn->d_tag == DT_RELASZ) { 264 | f->relasz = curdyn->d_un.d_val; 265 | 266 | } else if (curdyn->d_tag == DT_REL) { 267 | f->rel = (ElfNative_Rel *) (curdyn->d_un.d_ptr + f->offset); 268 | 269 | } else if (curdyn->d_tag == DT_RELSZ) { 270 | f->relsz = curdyn->d_un.d_val; 271 | 272 | } else if (curdyn->d_tag == DT_JMPREL) { 273 | f->jmprel = (void *) (curdyn->d_un.d_ptr + f->offset); 274 | 275 | } else if (curdyn->d_tag == DT_PLTRELSZ) { 276 | f->jmprelsz = curdyn->d_un.d_val; 277 | 278 | } 279 | } 280 | 281 | sh = (ElfNative_Shdr *)(f->prog + f->ehdr->e_shoff); 282 | for (i = 0; i < f->ehdr->e_shnum; i++) { 283 | if (sh[i].sh_type == SHT_INIT_ARRAY) { 284 | f->init_array = (ElfNative_Addr *)(f->loc + sh[i].sh_addr); 285 | f->init_array_sz = sh[i].sh_size / sizeof(ElfNative_Addr); 286 | } 287 | if (sh[i].sh_type == SHT_FINI_ARRAY) { 288 | f->fini_array = (ElfNative_Addr *)(f->loc + sh[i].sh_addr); 289 | f->fini_array_sz = sh[i].sh_size / sizeof(ElfNative_Addr); 290 | } 291 | } 292 | 293 | /* load in dependencies */ 294 | for (curdyn = f->dynamic; curdyn && curdyn->d_tag != DT_NULL; curdyn++) { 295 | if (curdyn->d_tag == DT_NEEDED) { 296 | loadELF(f->strtab + curdyn->d_un.d_val, instdir, 0); 297 | } 298 | } 299 | 300 | return f; 301 | } 302 | 303 | void relocateELFs() 304 | { 305 | int i; 306 | 307 | for (i = elfFileCount - 1; i >= 0; i--) { 308 | relocateELF(i, &(elfFiles[i])); 309 | } 310 | } 311 | 312 | void relocateELF(int fileNo, struct ELF_File *f) 313 | { 314 | /* do processor-specific relocation */ 315 | #if GELFLOAD_ARCH_i386 316 | #define REL_P ((ssize_t) (currel->r_offset + f->offset)) 317 | #define REL_S ((ssize_t) (findELFSymbol( \ 318 | f->strtab + f->symtab[ELFNATIVE_R_SYM(currel->r_info)].st_name, \ 319 | NULL, fileNo, -1, NULL))) 320 | #define REL_A (*((ssize_t *) REL_P)) 321 | #define WORD32_REL(to) REL_A = (ssize_t) (to) 322 | 323 | /* we ought to have rel and symtab defined */ 324 | if (f->rel && f->symtab) { 325 | ElfNative_Rel *currel = f->rel; 326 | for (; (char *) currel < (char *) f->rel + f->relsz; currel++) { 327 | switch (ELFNATIVE_R_TYPE(currel->r_info)) { 328 | case R_386_32: 329 | WORD32_REL(REL_S + REL_A); 330 | break; 331 | 332 | case R_386_PC32: 333 | WORD32_REL(REL_S + REL_A - REL_P); 334 | break; 335 | 336 | case R_386_COPY: 337 | { 338 | /* this is a bit more convoluted, as we need to find it in both places and copy */ 339 | ElfNative_Sym *localsym, *sosym; 340 | localsym = &(f->symtab[ELFNATIVE_R_SYM(currel->r_info)]); 341 | void *soptr = findELFSymbol( 342 | f->strtab + localsym->st_name, 343 | NULL, -1, fileNo, &sosym); 344 | 345 | /* OK, we should have both, so copy it over */ 346 | if (localsym && sosym) { 347 | memcpy((void *) (localsym->st_value + f->offset), 348 | soptr, sosym->st_size); 349 | } else { 350 | /* depend on localsym's size */ 351 | memcpy((void *) (localsym->st_value + f->offset), 352 | soptr, localsym->st_size); 353 | 354 | } 355 | 356 | break; 357 | } 358 | 359 | case R_386_GLOB_DAT: 360 | WORD32_REL(REL_S + REL_A); 361 | break; 362 | 363 | case R_386_RELATIVE: 364 | WORD32_REL(f->loc + REL_A); 365 | break; 366 | 367 | case R_386_NONE: 368 | break; 369 | 370 | default: 371 | fprintf(stderr, "Unsupported relocation %d in %s\n", ELFNATIVE_R_TYPE(currel->r_info), f->nm); 372 | } 373 | } 374 | } 375 | 376 | if (f->jmprel && f->symtab) { 377 | ElfNative_Rel *currel = (ElfNative_Rel *) f->jmprel; 378 | for (; (char *) currel < (char *) f->jmprel + f->jmprelsz; currel++) { 379 | switch (ELFNATIVE_R_TYPE(currel->r_info)) { 380 | case R_386_JMP_SLOT: 381 | WORD32_REL(REL_S); 382 | break; 383 | } 384 | } 385 | } 386 | 387 | 388 | #elif GELFLOAD_ARCH_x86_64 389 | #define REL_P ((ssize_t) (currel->r_offset + f->offset)) 390 | #define REL_S ((ssize_t) (findELFSymbol( \ 391 | f->strtab + f->symtab[ELFNATIVE_R_SYM(currel->r_info)].st_name, \ 392 | NULL, fileNo, -1, NULL))) 393 | #define REL_A (*((ssize_t *) REL_P)) 394 | #define WORD32_REL(to) REL_A = (int32_t) (to) 395 | #define WORD64_REL(to) REL_A = (ssize_t) (to) 396 | 397 | /* we ought to have rel and symtab defined */ 398 | if (f->rela && f->symtab) { 399 | ElfNative_Rela *currel = f->rela; 400 | for (; (char *) currel < (char *) f->rela + f->relasz; currel++) { 401 | switch (ELFNATIVE_R_TYPE(currel->r_info)) { 402 | case R_X86_64_64: 403 | WORD64_REL(REL_S + REL_A); 404 | break; 405 | 406 | case R_X86_64_PC32: 407 | WORD32_REL(REL_S + REL_A - REL_P); 408 | break; 409 | 410 | case R_X86_64_COPY: 411 | { 412 | /* this is a bit more convoluted, as we need to find it in both places and copy */ 413 | ElfNative_Sym *localsym, *sosym; 414 | localsym = &(f->symtab[ELFNATIVE_R_SYM(currel->r_info)]); 415 | void *soptr = findELFSymbol( 416 | f->strtab + localsym->st_name, 417 | NULL, -1, fileNo, &sosym); 418 | 419 | /* OK, we should have both, so copy it over */ 420 | if (localsym && sosym) { 421 | memcpy((void *) (localsym->st_value + f->offset), 422 | soptr, sosym->st_size); 423 | } else { 424 | /* depend on localsym's size */ 425 | memcpy((void *) (localsym->st_value + f->offset), 426 | soptr, localsym->st_size); 427 | 428 | } 429 | 430 | break; 431 | } 432 | 433 | case R_X86_64_GLOB_DAT: 434 | WORD64_REL(REL_S + REL_A); 435 | break; 436 | 437 | case R_X86_64_RELATIVE: 438 | WORD64_REL(f->loc + REL_A); 439 | break; 440 | 441 | default: 442 | fprintf(stderr, "Unsupported relocation %d in %s\n", (int) ELFNATIVE_R_TYPE(currel->r_info), f->nm); 443 | } 444 | } 445 | } 446 | 447 | if (f->jmprel && f->symtab) { 448 | ElfNative_Rela *currel = (ElfNative_Rela *) f->jmprel; 449 | for (; (char *) currel < (char *) f->jmprel + f->jmprelsz; currel++) { 450 | switch (ELFNATIVE_R_TYPE(currel->r_info)) { 451 | case R_X86_64_JUMP_SLOT: 452 | WORD64_REL(REL_S); 453 | break; 454 | 455 | default: 456 | fprintf(stderr, "Unsupported jmprel relocation %d in %s\n", (int) ELFNATIVE_R_TYPE(currel->r_info), f->nm); 457 | } 458 | } 459 | } 460 | 461 | 462 | #else 463 | #error Unsupported architecture. 464 | #endif 465 | } 466 | 467 | /* Initialize every ELF loaded /except/ for f (usually the binary) */ 468 | void initELF(struct ELF_File *except) 469 | { 470 | int i; 471 | struct ELF_File *f; 472 | ElfNative_Dyn *dyn; 473 | 474 | for (i = elfFileCount - 1; i >= 0; i--) { 475 | f = &(elfFiles[i]); 476 | if (f->loc) xbbuffer(f->loc, f->writable - f->loc); 477 | if (f == except) continue; 478 | 479 | if (f->init_array) { 480 | unsigned j; 481 | for (j = 0; j < f->init_array_sz; j++) { 482 | ((void (*)())(f->init_array[j]))(); 483 | } 484 | } 485 | 486 | /* init is in the dynamic section */ 487 | if (f->dynamic == NULL) continue; 488 | for (dyn = f->dynamic; dyn && dyn->d_tag != DT_NULL; dyn++) { 489 | if (dyn->d_tag == DT_INIT) { 490 | /* call it */ 491 | ((void(*)()) (dyn->d_un.d_ptr + f->offset))(); 492 | break; 493 | } 494 | } 495 | } 496 | } 497 | 498 | /* Find a symbol within the currently loaded ELF files 499 | * localin: The number of the current file, where STB_LOCAL symbols are OK 500 | * notin: Do not bind to symbols in this file 501 | * Either can be -1 */ 502 | void *findELFSymbolEx(const char *nm, struct ELF_File *onlyin, int localin, int notin, ElfNative_Sym **syminto) 503 | { 504 | int i; 505 | struct ELF_File *f; 506 | ElfNative_Word hash = elf_hash((unsigned char *) nm); 507 | ElfNative_Word bucket, index; 508 | ElfNative_Sym *sym; 509 | void *hostsym; 510 | if (syminto) *syminto = NULL; 511 | 512 | if (nm[0] == '\0') return NULL; 513 | 514 | for (i = 0; i < elfFileCount; i++) { 515 | if (i == notin) continue; 516 | 517 | f = &(elfFiles[i]); 518 | if (onlyin && f != onlyin) continue; 519 | 520 | /* if this is a host library, just try the host method */ 521 | if (f->hostlib == HOSTLIB_HOST) { 522 | char lsym[1024]; 523 | snprintf(lsym, 1024, "gelfload__%s", nm); 524 | 525 | #if defined(HAVE_DLFCN_H) 526 | hostsym = dlsym(f->prog, lsym); 527 | if (hostsym) return hostsym; 528 | hostsym = dlsym(f->prog, nm); 529 | if (hostsym) return hostsym; 530 | continue; 531 | #elif defined(__WIN32) 532 | char csym[1024]; 533 | int isimp = 0; 534 | 535 | /* Remove _imp__ if it's present */ 536 | if (strncmp(nm, "_imp__", 6) == 0) { 537 | isimp = 1; 538 | nm += 6; 539 | snprintf(lsym, 1024, "gelfload__%s", nm); 540 | } 541 | 542 | /* Try adding a _ first, to get the cdecl version */ 543 | snprintf(csym, 1024, "_%s", lsym); 544 | hostsym = GetProcAddress(f->prog, csym); 545 | if (hostsym == NULL) 546 | hostsym = GetProcAddress(f->prog, lsym); 547 | if (hostsym == NULL) { 548 | snprintf(csym, 1024, "_%s", nm); 549 | hostsym = GetProcAddress(f->proc, csym); 550 | } 551 | if (hostsym == NULL) 552 | hostsym = GetProcAddress(f->prog, nm); 553 | if (hostsym) { 554 | if (isimp) { 555 | /* Need a pointer to this pointer */ 556 | void **pptr = (void **) malloc(sizeof(void*)); 557 | if (pptr == NULL) { 558 | perror("malloc"); 559 | exit(1); 560 | } 561 | *pptr = hostsym; 562 | return (void *) pptr; 563 | 564 | } else { 565 | return hostsym; 566 | 567 | } 568 | } 569 | #endif 570 | continue; 571 | 572 | } else if (f->hostlib == HOSTLIB_DL) { 573 | hostsym = elfload_dl(nm); 574 | if (hostsym) return hostsym; 575 | continue; 576 | 577 | } 578 | 579 | if (f->gnuhash) { 580 | void *ptr = gnu_lookup(nm, f, i == localin, syminto); 581 | if (ptr) { 582 | return ptr; 583 | } 584 | } 585 | if (!f->hashtab) { 586 | continue; 587 | } 588 | 589 | /* figure out the bucket ... */ 590 | bucket = hash % ELFFILE_NBUCKET(f); 591 | 592 | /* then find the chain entry */ 593 | index = ELFFILE_BUCKET(f, bucket); 594 | 595 | /* and work our way through the chain */ 596 | for (; index != STN_UNDEF; index = ELFFILE_CHAIN(f, index)) { 597 | sym = &(f->symtab[index]); 598 | 599 | /* see if it's defined */ 600 | if (strcmp(f->strtab + sym->st_name, nm) == 0 && 601 | (i == localin || ELFNATIVE_ST_BIND(sym->st_info) != STB_LOCAL) && 602 | sym->st_shndx != SHN_UNDEF) { 603 | /* we found our symbol! */ 604 | if (syminto != NULL) { 605 | *syminto = sym; 606 | } 607 | return (void *) (sym->st_value + f->offset); 608 | } 609 | } 610 | } 611 | 612 | /* uh oh, not found! */ 613 | fprintf(stderr, "Symbol undefined: '%s'\n", nm); 614 | return NULL; 615 | } 616 | 617 | void *findELFSymbol(const char *nm, struct ELF_File *onlyin, int localin, int notin, ElfNative_Sym **syminto) 618 | { 619 | void *p = NULL; 620 | nm = hook_syms(nm, &p); 621 | if (p) { 622 | return p; 623 | } 624 | return findELFSymbolEx(nm, onlyin, localin, notin, syminto); 625 | } 626 | 627 | /* The standard ELF hash function */ 628 | ElfNative_Word elf_hash(const unsigned char *name) 629 | { 630 | ElfNative_Word h = 0, g; 631 | 632 | while (*name) { 633 | h = (h << 4) + *name++; 634 | if ((g = h & 0xf0000000)) 635 | h ^= g >> 24; 636 | h &= ~g; 637 | } 638 | return h; 639 | } 640 | 641 | /* A handy function to read a file or mmap it, as appropriate */ 642 | void readFile(const char *nm, const char *instdir, struct ELF_File *ef) 643 | { 644 | /* try with instdir */ 645 | char *longnm = malloc(strlen(nm) + strlen(instdir) + 18); 646 | if (longnm == NULL) { 647 | perror("malloc"); 648 | exit(1); 649 | } 650 | sprintf(longnm, "%s/%s", instdir, nm); 651 | 652 | #ifdef HAVE_MMAP 653 | { 654 | void *buf; 655 | struct stat sbuf; 656 | int fd; 657 | 658 | /* use mmap. First, open the file and get its length */ 659 | fd = open(nm, O_RDONLY); 660 | if (fd == -1) { 661 | fd = open(longnm, O_RDONLY); 662 | 663 | if (fd == -1) { 664 | perror(nm); 665 | exit(1); 666 | } 667 | } 668 | free(longnm); 669 | if (fstat(fd, &sbuf) < 0) { 670 | perror(nm); 671 | exit(1); 672 | } 673 | 674 | /* then mmap it */ 675 | buf = mmap(NULL, sbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 676 | if (buf == NULL) { 677 | perror("mmap"); 678 | exit(1); 679 | } 680 | 681 | close(fd); 682 | 683 | /* and put it in ef */ 684 | ef->prog = buf; 685 | ef->proglen = sbuf.st_size; 686 | } 687 | #else 688 | { 689 | char *buf; 690 | int bufsz, rdtotal, rd; 691 | FILE *f; 692 | 693 | /* OK, use stdio */ 694 | f = fopen(nm, "rb"); 695 | if (f == NULL) { 696 | f = fopen(longnm, "rb"); 697 | 698 | if (f == NULL) { 699 | perror(nm); 700 | exit(1); 701 | } 702 | } 703 | free(longnm); 704 | 705 | /* start with a 512-byte buffer */ 706 | bufsz = 512; 707 | buf = (char *) malloc(bufsz); 708 | if (buf == NULL) { 709 | perror("malloc"); 710 | exit(1); 711 | } 712 | 713 | /* and read in the file */ 714 | rdtotal = 0; 715 | while ((rd = fread(buf + rdtotal, 1, bufsz - rdtotal, f)) != 0) { 716 | rdtotal += rd; 717 | if (rdtotal != bufsz) { 718 | /* done reading */ 719 | break; 720 | 721 | } else { 722 | bufsz <<= 1; 723 | buf = realloc(buf, bufsz); 724 | if (buf == NULL) { 725 | perror("realloc"); 726 | exit(1); 727 | } 728 | } 729 | } 730 | if (ferror(f)) { 731 | perror(nm); 732 | exit(1); 733 | } 734 | fclose(f); 735 | 736 | /* now put it in ef */ 737 | ef->prog = buf; 738 | ef->proglen = rdtotal; 739 | } 740 | #endif 741 | } 742 | 743 | /* The finalization function for readFile */ 744 | void closeFile(struct ELF_File *ef) 745 | { 746 | #ifdef HAVE_MMAP 747 | munmap(ef->prog, ef->proglen); 748 | #else 749 | free(ef->prog); 750 | #endif 751 | } 752 | 753 | void unloadELFs() 754 | { 755 | int i; 756 | 757 | for (i = elfFileCount - 1; i >= 0; i--) { 758 | struct ELF_File *f = &(elfFiles[i]); 759 | if (f->hostlib == HOSTLIB_DL) continue; 760 | if (f->hostlib == HOSTLIB_HOST) { 761 | #if defined(HAVE_DLFCN_H) 762 | dlclose(f->prog); 763 | #elif defined(__WIN32) 764 | FreeLibrary(f->prog); 765 | #endif 766 | continue; 767 | } 768 | 769 | if (f->fini_array) { 770 | unsigned j; 771 | for (j = 0; j < f->fini_array_sz; j++) { 772 | ((void (*)())(f->fini_array[j]))(); 773 | } 774 | } 775 | 776 | if (f->dynamic) { 777 | ElfNative_Dyn *dyn; 778 | for (dyn = f->dynamic; dyn && dyn->d_tag != DT_NULL; dyn++) { 779 | if (dyn->d_tag == DT_FINI) { 780 | /* call it */ 781 | ((void(*)()) (dyn->d_un.d_ptr + f->offset))(); 782 | break; 783 | } 784 | } 785 | } 786 | 787 | unbbuffer(f->loc, f->memsz); 788 | closeFile(f); 789 | } 790 | } 791 | -------------------------------------------------------------------------------- /linux/zya/tools/derp.py: -------------------------------------------------------------------------------- 1 | import idaapi 2 | import idautils 3 | import idc 4 | 5 | alias = { 6 | 'zya844': 'qisdir', 7 | 'zya1126': 'xrefchar', 8 | 'zya665': 'leading_zero_important', 9 | 'zya827': 'qfindclose', 10 | 'zya532': 'getn_hidden_range', 11 | 'zya262': 'fopenRT', 12 | 'zya854': 'qmutex_unlock', 13 | 'zya1012': 'set_stroff_path', 14 | 'zya859': 'qsem_wait', 15 | 'zya591': 'idcv_int64', 16 | 'zya324': 'get_dtype_by_size', 17 | 'zya753': 'next_idcv_attr', 18 | 'zya773': 'pack_dq', 19 | 'zya545': 'hexplace_t__clone', 20 | 'zya204': 'enumplace_t__clone', 21 | 'zya562': 'hexplace_t__serialize', 22 | 'zya57': 'b2a_width', 23 | 'zya1039': 'simpleline_place_t__makeplace', 24 | 'zya672': 'linearray_t_ctr', 25 | 'zya936': 'run_plugin', 26 | 'zya813': 'qalloc_or_throw', 27 | 'zya397': 'get_idati', 28 | 'zya167': 'del_segm', 29 | 'zya68': 'bookmarks_t_find_index', 30 | 'zya912': 'reg_str_set', 31 | 'zya732': 'netnode_qhashfirst', 32 | 'zya982': 'set_lzero', 33 | 'zya829': 'qfindnext', 34 | 'zya644': 'is_off', 35 | 'zya915': 'reg_update_strlist', 36 | 'zya678': 'llong_scan', 37 | 'zya143': 'create_zip_linput', 38 | 'zya717': 'netnode_charshift', 39 | 'zya187': 'dstr_tinfo', 40 | 'zya833': 'qfputs', 41 | 'zya814': 'qatexit', 42 | 'zya244': 'find_extlang', 43 | 'zya49': 'attach_custom_data_format', 44 | 'zya276': 'func_item_iterator_decode_prev_insn', 45 | 'zya1114': 'vadd_extra_line', 46 | 'zya634': 'is_invsign', 47 | 'zya327': 'get_dword', 48 | 'zya29': 'alloc_type_ordinals', 49 | 'zya560': 'hexplace_t__print', 50 | 'zya589': 'idb_utf8', 51 | 'zya974': 'set_func_cmt', 52 | 'zya872': 'qstrupr', 53 | 'zya147': 'decode_preceding_insn', 54 | 'zya252': 'find_regvar', 55 | 'zya861': 'qsscanf', 56 | 'zya251': 'find_plugin', 57 | 'zya551': 'hexplace_t__enter', 58 | 'zya901': 'rebuild_nlist', 59 | 'zya293': 'get_64bit', 60 | 'zya1046': 'simpleline_place_t__toea', 61 | 'zya337': 'get_enum_cmt', 62 | 'zya07': 'add_enum_member', 63 | 'zya781': 'parse_reg_name', 64 | 'zya820': 'qerrcode', 65 | 'zya267': 'forget_problem', 66 | 'zya1095': 'unhook_from_notification_point', 67 | 'zya270': 'free_idcv', 68 | 'zya687': 'lochist_t_deregister_live', 69 | 'zya1120': 'vshow_hex', 70 | 'zya1048': 'skip_spaces', 71 | 'zya296': 'get_array_parameters', 72 | 'zya878': 'qtime64', 73 | 'zya1037': 'simpleline_place_t__id', 74 | 'zya1051': 'str2ea', 75 | 'zya106': 'check_and_create_flat_jump_table', 76 | 'zya1092': 'trim_jtable', 77 | 'zya882': 'qustrlen', 78 | 'zya99': 'callui', 79 | 'zya811': 'put_word', 80 | 'zya714': 'netnode_altadjust', 81 | 'zya40': 'apply_named_type', 82 | 'zya393': 'get_idasgn_desc', 83 | 'zya406': 'get_item_flag', 84 | 'zya840': 'qgetcwd', 85 | 'zya477': 'get_root_filename', 86 | 'zya973': 'set_frame_size', 87 | 'zya898': 'reanalyze_callers', 88 | 'zya572': 'idaplace_t__compare', 89 | 'zya213': 'enumplace_t__makeplace', 90 | 'zya657': 'is_valid_cp', 91 | 'zya929': 'reorder_dummy_names', 92 | 'zya473': 'get_radix', 93 | 'zya392': 'get_idainfo_by_type', 94 | 'zya706': 'make_name_public', 95 | 'zya573': 'idaplace_t__copyfrom', 96 | 'zya689': 'lochist_t_get', 97 | 'zya658': 'is_valid_utf8', 98 | 'zya527': 'get_word', 99 | 'zya381': 'get_func_by_frame', 100 | 'zya685': 'lochist_t_clear', 101 | 'zya921': 'register_custom_fixup', 102 | 'zya58': 'base2file', 103 | 'zya94': 'calc_prefix_color', 104 | 'zya531': 'getn_func', 105 | 'zya59': 'base64_decode', 106 | 'zya1113': 'utf8_utf16', 107 | 'zya38': 'apply_cdecl', 108 | 'zya389': 'get_hidden_range', 109 | 'zya370': 'get_fixup', 110 | 'zya146': 'decode_insn', 111 | 'zya454': 'get_ordinal_from_idb_type', 112 | 'zya653': 'is_stroff', 113 | 'zya576': 'idaplace_t__enter', 114 | 'zya593': 'idcv_string', 115 | 'zya1044': 'simpleline_place_t__rebase', 116 | 'zya491': 'get_selector_qty', 117 | 'zya395': 'get_idasgn_qty', 118 | 'zya350': 'get_enum_qty', 119 | 'zya11': 'add_idc_func', 120 | 'zya311': 'get_custom_data_type', 121 | 'zya429': 'get_name_expr', 122 | 'zya95': 'calc_reference_data', 123 | 'zya151': 'del_debug_names', 124 | 'zya1117': 'visit_patched_bytes', 125 | 'zya70': 'bookmarks_t_get_desc', 126 | 'zya910': 'reg_read_strlist', 127 | 'zya384': 'get_func_name', 128 | 'zya777': 'parse_dbgopts', 129 | 'zya402': 'get_import_module_name', 130 | 'zya1104': 'update_extra_cmt', 131 | 'zya922': 'register_loc_converter', 132 | 'zya154': 'del_enum_member', 133 | 'zya622': 'is_database_flag', 134 | 'zya237': 'find_code', 135 | 'zya419': 'get_mappings_qty', 136 | 'zya229': 'eval_idc_snippet', 137 | 'zya1034': 'simpleline_place_t__ending', 138 | 'zya160': 'del_items', 139 | 'zya819': 'qdirname', 140 | 'zya804': 'print_type', 141 | 'zya715': 'netnode_altshift', 142 | 'zya310': 'get_custom_data_formats', 143 | 'zya822': 'qexit', 144 | 'zya855': 'qrealloc', 145 | 'zya761': 'num_flag', 146 | 'zya14': 'add_qword', 147 | 'zya18': 'add_segm_ex', 148 | 'zya55': 'b2a32', 149 | 'zya905': 'reg_delete_subkey', 150 | 'zya86': 'calc_def_align', 151 | 'zya881': 'quote_cmdline_arg', 152 | 'zya594': 'ieee_realcvt', 153 | 'zya455': 'get_ordinal_qty', 154 | 'zya91': 'calc_max_item_end', 155 | 'zya513': 'get_struc_qty', 156 | 'zya119': 'clr_op_type', 157 | 'zya287': 'gen_simple_call_chart', 158 | 'zya357': 'get_file_type_name', 159 | 'zya447': 'get_nsec_stamp', 160 | 'zya312': 'get_custom_data_type_ids', 161 | 'zya646': 'is_public_name', 162 | 'zya965': 'set_enum_hidden', 163 | 'zya720': 'netnode_delblob', 164 | 'zya611': 'invalidate_visea_cache', 165 | 'zya1123': 'xrefblk_t_first_to', 166 | 'zya778': 'parse_decl', 167 | 'zya313': 'get_custom_refinfo', 168 | 'zya933': 'retrieve_custom_argloc', 169 | 'zya463': 'get_predef_insn_cmt', 170 | 'zya440': 'get_next_serial_enum_member', 171 | 'zya431': 'get_named_type', 172 | 'zya439': 'get_next_seg', 173 | 'zya774': 'pack_ds', 174 | 'zya897': 'realtoasc', 175 | 'zya654': 'is_suspop', 176 | 'zya886': 'qvsnprintf', 177 | 'zya06': 'add_enum', 178 | 'zya498': 'get_sreg_range_num', 179 | 'zya249': 'find_not_func', 180 | 'zya458': 'get_path', 181 | 'zya896': 'read_regargs', 182 | 'zya371': 'get_fixup_desc', 183 | 'zya776': 'parse_config_value', 184 | 'zya470': 'get_problem_name', 185 | 'zya1003': 'set_segm_base', 186 | 'zya129': 'create_32bit_data', 187 | 'zya994': 'set_op_type', 188 | 'zya650': 'is_spec_segm', 189 | 'zya574': 'idaplace_t__deserialize', 190 | 'zya161': 'del_mapping', 191 | 'zya946': 'serialize_tinfo', 192 | 'zya400': 'get_idp_name', 193 | 'zya1013': 'set_struc_align', 194 | 'zya1106': 'update_func', 195 | 'zya623': 'is_debugger_memory', 196 | 'zya01': 'add_cref', 197 | 'zya628': 'is_fltnum', 198 | 'zya661': 'itext', 199 | 'zya130': 'create_align', 200 | 'zya1098': 'unpack_dq', 201 | 'zya836': 'qfseek', 202 | 'zya257': 'first_idcv_attr', 203 | 'zya445': 'get_nlist_size', 204 | 'zya564': 'hexplace_t__touval', 205 | 'zya183': 'deref_idcv', 206 | 'zya497': 'get_sreg_range', 207 | 'zya489': 'get_segment_combination', 208 | 'zya471': 'get_qerrno', 209 | 'zya993': 'set_op_tinfo', 210 | 'zya176': 'del_value', 211 | 'zya51': 'auto_apply_type', 212 | 'zya958': 'set_default_dataseg', 213 | 'zya259': 'fopenA', 214 | 'zya798': 'print_decls', 215 | 'zya795': 'print_auto_state', 216 | 'zya03': 'add_dword', 217 | 'zya396': 'get_idasgn_title', 218 | 'zya597': 'inf', 219 | 'zya599': 'init_database', 220 | 'zya783': 'patch_bytes', 221 | 'zya284': 'gen_fix_fixups', 222 | 'zya369': 'get_first_serial_enum_member', 223 | 'zya220': 'enumplace_t__toea', 224 | 'zya1111': 'user2bin', 225 | 'zya217': 'enumplace_t__print', 226 | 'zya321': 'get_default_radix', 227 | 'zya488': 'get_segment_cmt', 228 | 'zya763': 'op_custfmt', 229 | 'zya479': 'get_segm_base', 230 | 'zya546': 'hexplace_t__compare', 231 | 'zya540': 'h2ti', 232 | 'zya943': 'segm_adjust_ea', 233 | 'zya916': 'regcomp', 234 | 'zya139': 'create_qflow_chart', 235 | 'zya358': 'get_fileregion_ea', 236 | 'zya418': 'get_mapping', 237 | 'zya196': 'eclose', 238 | 'zya504': 'get_strlist_options', 239 | 'zya1125': 'xrefblk_t_next_to', 240 | 'zya847': 'qlseek', 241 | 'zya849': 'qmake_full_path', 242 | 'zya903': 'reg_bin_op', 243 | 'zya112': 'clear_strlist', 244 | 'zya949': 'set_auto_state', 245 | 'zya309': 'get_custom_data_format', 246 | 'zya584': 'idaplace_t__print', 247 | 'zya82': 'calc_bg_color', 248 | 'zya1121': 'winerr', 249 | 'zya980': 'set_immd', 250 | 'zya1006': 'set_segm_name', 251 | 'zya1103': 'unregister_custom_fixup', 252 | 'zya286': 'gen_rand_buf', 253 | 'zya367': 'get_first_fixup_ea', 254 | 'zya341': 'get_enum_member', 255 | 'zya577': 'idaplace_t__generate', 256 | 'zya17': 'add_segm', 257 | 'zya556': 'hexplace_t__name', 258 | 'zya670': 'lexcompare_tinfo', 259 | 'zya209': 'enumplace_t__enter', 260 | 'zya1071': 'structplace_t__prev', 261 | 'zya676': 'linearray_t_set_place', 262 | 'zya294': 'get_aflags', 263 | 'zya824': 'qfgets', 264 | 'zya165': 'del_numbered_type', 265 | 'zya735': 'netnode_qsupstr', 266 | 'zya805': 'process_archive', 267 | 'zya486': 'get_segm_qty', 268 | 'zya372': 'get_fixup_value', 269 | 'zya266': 'for_all_extlangs', 270 | 'zya132': 'create_filename_cmt', 271 | 'zya295': 'get_alias_target', 272 | 'zya891': 'rangeset_t_has_common', 273 | 'zya54': 'auto_mark_range', 274 | 'zya00': 'add_auto_stkpnt', 275 | 'zya283': 'gen_file', 276 | 'zya317': 'get_debug_name_ea', 277 | 'zya75': 'build_anon_type_name', 278 | 'zya460': 'get_place_class_id', 279 | 'zya425': 'get_member_struc', 280 | 'zya613': 'invoke_plugin', 281 | 'zya563': 'hexplace_t__toea', 282 | 'zya180': 'delete_wrong_stkvar_ops', 283 | 'zya1022': 'set_visible_segm', 284 | 'zya547': 'hexplace_t__copyfrom', 285 | 'zya246': 'find_idc_func', 286 | 'zya500': 'get_stkvar', 287 | 'zya390': 'get_hidden_range_qty', 288 | 'zya860': 'qsnprintf', 289 | 'zya863': 'qstr2user', 290 | 'zya883': 'qvector_reserve', 291 | 'zya913': 'reg_subkey_children', 292 | 'zya723': 'netnode_getblob', 293 | 'zya386': 'get_func_qty', 294 | 'zya503': 'get_strinfo', 295 | 'zya716': 'netnode_altval', 296 | 'zya620': 'is_custfmt', 297 | 'zya210': 'enumplace_t__generate', 298 | 'zya876': 'qthread_kill', 299 | 'zya166': 'del_regvar', 300 | 'zya739': 'netnode_supdel', 301 | 'zya306': 'get_compilers', 302 | 'zya298': 'get_auto_state', 303 | 'zya837': 'qfsize', 304 | 'zya427': 'get_name_base_ea', 305 | 'zya736': 'netnode_rename', 306 | 'zya1043': 'simpleline_place_t__print', 307 | 'zya138': 'create_outctx', 308 | 'zya493': 'get_spd', 309 | 'zya612': 'invoke_callbacks', 310 | 'zya184': 'deserialize_tinfo', 311 | 'zya832': 'qfputc', 312 | 'zya225': 'eseek', 313 | 'zya258': 'flush_buffers', 314 | 'zya28': 'align_up_to_stack', 315 | 'zya1047': 'simpleline_place_t__touval', 316 | 'zya141': 'create_tinfo', 317 | 'zya550': 'hexplace_t__ending', 318 | 'zya794': 'print_argloc', 319 | 'zya391': 'get_ida_subdirs', 320 | 'zya1021': 'set_visible_func', 321 | 'zya566': 'hook_to_notification_point', 322 | 'zya281': 'gen_complex_call_chart', 323 | 'zya696': 'lochist_t_size', 324 | 'zya71': 'bookmarks_t_mark', 325 | 'zya530': 'getn_fchunk', 326 | 'zya241': 'find_defined', 327 | 'zya235': 'file2base', 328 | 'zya543': 'hexplace_t__adjust', 329 | 'zya923': 'reload_file', 330 | 'zya1059': 'structplace_t__clone', 331 | 'zya155': 'del_frame', 332 | 'zya959': 'set_default_encoding_idx', 333 | 'zya845': 'qlgetz', 334 | 'zya170': 'del_stkpnt', 335 | 'zya722': 'netnode_get_name', 336 | 'zya285': 'gen_flow_graph', 337 | 'zya289': 'generate_disasm_line', 338 | 'zya603': 'insn_add_dref', 339 | 'zya315': 'get_data_value', 340 | 'zya278': 'func_parent_iterator_set', 341 | 'zya1110': 'upload_idb', 342 | 'zya1083': 'tag_skipcode', 343 | 'zya292': 'get_32bit', 344 | 'zya703': 'make_linput', 345 | 'zya906': 'reg_delete_tree', 346 | 'zya377': 'get_frame_retsize', 347 | 'zya852': 'qmutex_free', 348 | 'zya1082': 'tag_remove', 349 | 'zya36': 'append_struct_fields', 350 | 'zya786': 'peek_auto_queue', 351 | 'zya796': 'print_cdata', 352 | 'zya775': 'pack_dw', 353 | 'zya1084': 'tag_strlen', 354 | 'zya728': 'netnode_inited', 355 | 'zya1030': 'simpleline_place_t__clone', 356 | 'zya02': 'add_dref', 357 | 'zya869': 'qstrncat', 358 | 'zya66': 'bitrange_t_inject_using_bitrange', 359 | 'zya602': 'insn_add_cref', 360 | 'zya1055': 'stristr', 361 | 'zya857': 'qsem_free', 362 | 'zya771': 'optimize_argloc', 363 | 'zya459': 'get_place_class', 364 | 'zya450': 'get_offset_expr', 365 | 'zya698': 'lock_segm', 366 | 'zya542': 'has_insn_feature', 367 | 'zya834': 'qfread', 368 | 'zya942': 'search_path', 369 | 'zya277': 'func_item_iterator_next', 370 | 'zya398': 'get_idcv_attr', 371 | 'zya303': 'get_byte', 372 | 'zya645': 'is_problem_present', 373 | 'zya729': 'netnode_kill', 374 | 'zya33': 'append_disp', 375 | 'zya605': 'insn_create_op_data', 376 | 'zya109': 'choose_named_type', 377 | 'zya110': 'cleanup_argloc', 378 | 'zya606': 'insn_create_stkvar', 379 | 'zya121': 'compact_numbered_types', 380 | 'zya437': 'get_next_hidden_range', 381 | 'zya853': 'qmutex_lock', 382 | 'zya1018': 'set_tinfo', 383 | 'zya520': 'get_tinfo_size', 384 | 'zya972': 'set_forced_operand', 385 | 'zya25': 'aes_crypt_cbc', 386 | 'zya1023': 'set_xrefpos', 387 | 'zya919': 'regfree', 388 | 'zya1094': 'under_debugger', 389 | 'zya953': 'set_compiler', 390 | 'zya517': 'get_tinfo_details', 391 | 'zya660': 'is_weak_name', 392 | 'zya1105': 'update_fpd', 393 | 'zya951': 'set_bmask_name', 394 | 'zya441': 'get_nice_colored_name', 395 | 'zya757': 'node2ea', 396 | 'zya100': 'can_be_off32', 397 | 'zya242': 'find_defjump_from_table', 398 | 'zya316': 'get_debug_name', 399 | 'zya892': 'rangeset_t_intersect', 400 | 'zya838': 'qftell', 401 | 'zya174': 'del_struc_members', 402 | 'zya955': 'set_database_flag', 403 | 'zya823': 'qfclose', 404 | 'zya909': 'reg_int_op', 405 | 'zya1020': 'set_type_alias', 406 | 'zya1041': 'simpleline_place_t__next', 407 | 'zya552': 'hexplace_t__generate', 408 | 'zya991': 'set_notcode', 409 | 'zya353': 'get_extra_cmt', 410 | 'zya192': 'dump_func_type_data', 411 | 'zya724': 'netnode_hashdel', 412 | 'zya663': 'l_compare', 413 | 'zya742': 'netnode_supfirst', 414 | 'zya664': 'launch_process', 415 | 'zya484': 'get_segm_num', 416 | 'zya219': 'enumplace_t__serialize', 417 | 'zya1035': 'simpleline_place_t__enter', 418 | 'zya137': 'create_multirange_qflow_chart', 419 | 'zya452': 'get_op_tinfo', 420 | 'zya1036': 'simpleline_place_t__generate', 421 | 'zya673': 'linearray_t_down', 422 | 'zya202': 'enumplace_t__adjust', 423 | 'zya537': 'getsysfile', 424 | 'zya918': 'regexec', 425 | 'zya924': 'remember_problem', 426 | 'zya617': 'is_bnot', 427 | 'zya1127': 'zip_deflate', 428 | 'zya1065': 'structplace_t__generate', 429 | 'zya609': 'invalidate_dbgmem_config', 430 | 'zya469': 'get_problem_desc', 431 | 'zya555': 'hexplace_t__makeplace', 432 | 'zya983': 'set_manual_insn', 433 | 'zya1058': 'structplace_t__beginning', 434 | 'zya721': 'netnode_exist', 435 | 'zya1102': 'unregister_custom_data_format', 436 | 'zya474': 'get_refinfo', 437 | 'zya158': 'del_idasgn', 438 | 'zya282': 'gen_decorate_name', 439 | 'zya268': 'format_c_number', 440 | 'zya274': 'func_has_stkframe_hole', 441 | 'zya1122': 'xrefblk_t_first_from', 442 | 'zya26': 'aes_setkey_dec', 443 | 'zya986': 'set_member_tinfo', 444 | 'zya380': 'get_func_bitness', 445 | 'zya604': 'insn_add_off_drefs', 446 | 'zya979': 'set_idcv_attr', 447 | 'zya481': 'get_segm_by_sel', 448 | 'zya1042': 'simpleline_place_t__prev', 449 | 'zya1080': 'tag_off', 450 | 'zya772': 'pack_dd', 451 | 'zya683': 'load_til_header', 452 | 'zya533': 'getn_selector', 453 | 'zya1107': 'update_hidden_range', 454 | 'zya839': 'qfwrite', 455 | 'zya911': 'reg_str_get', 456 | 'zya858': 'qsem_post', 457 | 'zya675': 'linearray_t_ending', 458 | 'zya899': 'reanalyze_function', 459 | 'zya615': 'is_auto_enabled', 460 | 'zya762': 'op_adds_xrefs', 461 | 'zya557': 'hexplace_t__next', 462 | 'zya807': 'put_bytes', 463 | 'zya713': 'nbits', 464 | 'zya485': 'get_segm_para', 465 | 'zya227': 'eval_expr_long', 466 | 'zya625': 'is_defarg', 467 | 'zya181': 'demangle', 468 | 'zya214': 'enumplace_t__name', 469 | 'zya867': 'qstrftime64', 470 | 'zya565': 'hide_name', 471 | 'zya747': 'netnode_supstr', 472 | 'zya841': 'qgetenv', 473 | 'zya741': 'netnode_supdel_range', 474 | 'zya87': 'calc_default_sizeof_ldbl', 475 | 'zya914': 'reg_subkey_exists', 476 | 'zya610': 'invalidate_dbgmem_contents', 477 | 'zya233': 'extract_name', 478 | 'zya376': 'get_frame', 479 | 'zya884': 'qvfprintf', 480 | 'zya764': 'op_enum', 481 | 'zya226': 'eval_expr', 482 | 'zya989': 'set_node_info', 483 | 'zya846': 'qlread', 484 | 'zya19': 'add_sourcefile', 485 | 'zya189': 'dto_copy_to_inf', 486 | 'zya709': 'mem2base', 487 | 'zya162': 'del_member_tinfo', 488 | 'zya718': 'netnode_charval', 489 | 'zya47': 'atoea', 490 | 'zya740': 'netnode_supdel_all', 491 | 'zya600': 'init_kernel', 492 | 'zya961': 'set_entry_forwarder', 493 | 'zya521': 'get_user_idadir', 494 | 'zya992': 'set_numbered_type', 495 | 'zya586': 'idaplace_t__serialize', 496 | 'zya507': 'get_struc', 497 | 'zya186': 'disable_flags', 498 | 'zya97': 'calc_thunk_func_target', 499 | 'zya624': 'is_debugger_on', 500 | 'zya737': 'netnode_set', 501 | 'zya1009': 'set_segment_translations', 502 | 'zya932': 'resolve_typedef', 503 | 'zya864': 'qstrdup', 504 | 'zya920': 'register_custom_data_format', 505 | 'zya83': 'calc_c_cpp_name', 506 | 'zya770': 'open_linput', 507 | 'zya08': 'add_frame', 508 | 'zya326': 'get_dtype_size', 509 | 'zya927': 'rename_encoding', 510 | 'zya607': 'internal_register_place_class', 511 | 'zya630': 'is_func_locked', 512 | 'zya42': 'apply_tinfo', 513 | 'zya335': 'get_entry_qty', 514 | 'zya98': 'call_idc_func', 515 | 'zya515': 'get_struct_operand', 516 | 'zya12': 'add_idc_gvar', 517 | 'zya866': 'qstrftime', 518 | 'zya997': 'set_processor_type', 519 | 'zya1108': 'update_segm', 520 | 'zya333': 'get_entry_name', 521 | 'zya815': 'qbasename', 522 | 'zya207': 'enumplace_t__deserialize', 523 | 'zya198': 'enable_auto', 524 | 'zya799': 'print_fpval', 525 | 'zya695': 'lochist_t_set', 526 | 'zya30': 'allocate_selector', 527 | 'zya539': 'guess_tinfo', 528 | 'zya908': 'reg_flush', 529 | 'zya330': 'get_encoding_name', 530 | 'zya260': 'fopenM', 531 | 'zya568': 'idadir', 532 | 'zya92': 'calc_number_of_children', 533 | 'zya751': 'new_til', 534 | 'zya608': 'interr', 535 | 'zya809': 'put_qword', 536 | 'zya738': 'netnode_setblob', 537 | 'zya580': 'idaplace_t__makeplace', 538 | 'zya1038': 'simpleline_place_t__leave', 539 | 'zya619': 'is_char', 540 | 'zya810': 'put_utf8_char', 541 | 'zya228': 'eval_idc_expr', 542 | 'zya399': 'get_idp_descs', 543 | 'zya05': 'add_entry', 544 | 'zya299': 'get_basic_file_type', 545 | 'zya308': 'get_current_idasgn', 546 | 'zya1050': 'split_sreg_range', 547 | 'zya1061': 'structplace_t__copyfrom', 548 | 'zya1033': 'simpleline_place_t__deserialize', 549 | 'zya831': 'qfopen', 550 | 'zya636': 'is_lzero', 551 | 'zya1109': 'update_snapshot_attributes', 552 | 'zya755': 'next_that', 553 | 'zya250': 'find_notype', 554 | 'zya328': 'get_ea_name', 555 | 'zya413': 'get_license_info', 556 | 'zya451': 'get_offset_expression', 557 | 'zya64': 'bin_search', 558 | 'zya1097': 'unpack_dd', 559 | 'zya305': 'get_cmt', 560 | 'zya182': 'demangle_name', 561 | 'zya873': 'qthread_create', 562 | 'zya1100': 'unpack_dw', 563 | 'zya677': 'linearray_t_up', 564 | 'zya662': 'jvalue_t_clear', 565 | 'zya640': 'is_miniidb', 566 | 'zya212': 'enumplace_t__leave', 567 | 'zya638': 'is_manual', 568 | 'zya356': 'get_file_ext', 569 | 'zya1128': 'qsleep', 570 | 'zya56': 'b2a64', 571 | 'zya758': 'node_iterator_goup', 572 | 'zya325': 'get_dtype_flag', 573 | 'zya917': 'regerror', 574 | 'zya416': 'get_mangled_name_type', 575 | 'zya69': 'bookmarks_t_get', 576 | 'zya126': 'convert_encoding', 577 | 'zya279': 'func_tail_iterator_set', 578 | 'zya163': 'del_named_type', 579 | 'zya995': 'set_opinfo', 580 | 'zya826': 'qfilesize', 581 | 'zya1053': 'str2reg', 582 | 'zya561': 'hexplace_t__rebase', 583 | 'zya1024': 'setup_graph_subsystem', 584 | 'zya448': 'get_numbered_type', 585 | 'zya1004': 'set_segm_class', 586 | 'zya1049': 'skip_utf8', 587 | 'zya374': 'get_flags_ex', 588 | 'zya411': 'get_last_serial_enum_member', 589 | 'zya926': 'remove_tinfo_pointer', 590 | 'zya682': 'load_nonbinary_file', 591 | 'zya240': 'find_data', 592 | 'zya195': 'eadd', 593 | 'zya32': 'append_cmt', 594 | 'zya1063': 'structplace_t__ending', 595 | 'zya667': 'lex_get_file_line', 596 | 'zya67': 'bookmarks_t_erase', 597 | 'zya387': 'get_func_ranges', 598 | 'zya490': 'get_segment_translations', 599 | 'zya1129': 'qmkdir', 600 | 'zya726': 'netnode_hashval', 601 | 'zya679': 'lnar_size', 602 | 'zya1067': 'structplace_t__leave', 603 | 'zya111': 'cleanup_name', 604 | 'zya1118': 'visit_snapshot_tree', 605 | 'zya621': 'is_database_ext', 606 | 'zya939': 'save_struc', 607 | 'zya941': 'search', 608 | 'zya442': 'get_nlist_ea', 609 | 'zya733': 'netnode_qhashnext', 610 | 'zya483': 'get_segm_name', 611 | 'zya247': 'find_imm', 612 | 'zya171': 'del_stroff_path', 613 | 'zya125': 'compile_idc_snippet', 614 | 'zya1124': 'xrefblk_t_next_from', 615 | 'zya567': 'http_request', 616 | 'zya438': 'get_next_member_idx', 617 | 'zya27': 'align_down_to_stack', 618 | 'zya354': 'get_fchunk', 619 | 'zya404': 'get_item_color', 620 | 'zya1007': 'set_segm_start', 621 | 'zya264': 'fopenWT', 622 | 'zya426': 'get_member_tinfo', 623 | 'zya544': 'hexplace_t__beginning', 624 | 'zya699': 'lookup_loc_converter', 625 | 'zya668': 'lex_get_token', 626 | 'zya690': 'lochist_t_get_current', 627 | 'zya77': 'build_range_strlist', 628 | 'zya144': 'dbg', 629 | 'zya52': 'auto_cancel', 630 | 'zya101': 'can_define_item', 631 | 'zya990': 'set_noret_insn', 632 | 'zya501': 'get_stock_tinfo', 633 | 'zya744': 'netnode_supprev', 634 | 'zya476': 'get_reg_name', 635 | 'zya817': 'qcopyfile', 636 | 'zya382': 'get_func_chunknum', 637 | 'zya118': 'clr_node_info', 638 | 'zya1040': 'simpleline_place_t__name', 639 | 'zya875': 'qthread_join', 640 | 'zya862': 'qstpncpy', 641 | 'zya208': 'enumplace_t__ending', 642 | 'zya320': 'get_default_encoding_idx', 643 | 'zya88': 'calc_file_crc32', 644 | 'zya1073': 'structplace_t__rebase', 645 | 'zya750': 'netnode_valstr', 646 | 'zya727': 'netnode_hashval_long', 647 | 'zya655': 'is_trusted_idb', 648 | 'zya870': 'qstrncpy', 649 | 'zya711': 'move_segm', 650 | 'zya15': 'add_regarg', 651 | 'zya461': 'get_plugin_options', 652 | 'zya554': 'hexplace_t__leave', 653 | 'zya175': 'del_til', 654 | 'zya347': 'get_enum_member_serial', 655 | 'zya148': 'decode_prev_insn', 656 | 'zya1062': 'structplace_t__deserialize', 657 | 'zya681': 'load_ids_module', 658 | 'zya671': 'linearray_t_beginning', 659 | 'zya588': 'idaplace_t__touval', 660 | 'zya843': 'qisabspath', 661 | 'zya482': 'get_segm_class', 662 | 'zya1115': 'validate_name', 663 | 'zya803': 'print_tinfo', 664 | 'zya743': 'netnode_supnext', 665 | 'zya300': 'get_best_fit_member', 666 | 'zya569': 'idaplace_t__adjust', 667 | 'zya581': 'idaplace_t__name', 668 | 'zya632': 'is_ident', 669 | 'zya216': 'enumplace_t__prev', 670 | 'zya1096': 'unmake_linput', 671 | 'zya601': 'init_plugins', 672 | 'zya812': 'qalloc', 673 | 'zya197': 'ecreate', 674 | 'zya802': 'print_strlit_type', 675 | 'zya519': 'get_tinfo_property', 676 | 'zya931': 'request_refresh', 677 | 'zya63': 'bf_set_key', 678 | 'zya13': 'add_mapping', 679 | 'zya394': 'get_idasgn_header_by_short_name', 680 | 'zya1088': 'term_plugins', 681 | 'zya34': 'append_func_tail', 682 | 'zya1029': 'simpleline_place_t__beginning', 683 | 'zya587': 'idaplace_t__toea', 684 | 'zya629': 'is_forced_operand', 685 | 'zya548': 'hexplace_t__deserialize', 686 | 'zya22': 'add_test_feature', 687 | 'zya648': 'is_seg', 688 | 'zya319': 'get_debugger_plugins', 689 | 'zya23': 'add_til', 690 | 'zya478': 'get_scalar_bt', 691 | 'zya1093': 'type_flag', 692 | 'zya523': 'get_view_options', 693 | 'zya686': 'lochist_t_current_index', 694 | 'zya149': 'define_stkvar', 695 | 'zya152': 'del_dref', 696 | 'zya1000': 'set_refinfo', 697 | 'zya894': 'read_config', 698 | 'zya1116': 'verror', 699 | 'zya570': 'idaplace_t__beginning', 700 | 'zya996': 'set_path', 701 | 'zya874': 'qthread_free', 702 | 'zya1005': 'set_segm_end', 703 | 'zya436': 'get_next_func_addr', 704 | 'zya322': 'get_default_reftype', 705 | 'zya96': 'calc_stkvar_struc_offset', 706 | 'zya169': 'del_sreg_range', 707 | 'zya760': 'num2str_uint64', 708 | 'zya692': 'lochist_t_jump', 709 | 'zya704': 'make_name_auto', 710 | 'zya643': 'is_numop0', 711 | 'zya20': 'add_struc', 712 | 'zya642': 'is_numop', 713 | 'zya185': 'destroy_lexer', 714 | 'zya127': 'copy_argloc', 715 | 'zya830': 'qflush', 716 | 'zya669': 'lex_init_file', 717 | 'zya492': 'get_sp_delta', 718 | 'zya877': 'qthread_same', 719 | 'zya203': 'enumplace_t__beginning', 720 | 'zya136': 'create_lexer', 721 | 'zya1031': 'simpleline_place_t__compare', 722 | 'zya385': 'get_func_num', 723 | 'zya937': 'sanitize_file_name', 724 | 'zya218': 'enumplace_t__rebase', 725 | 'zya981': 'set_item_color', 726 | 'zya117': 'clr_lzero', 727 | 'zya954': 'set_cp_validity', 728 | 'zya79': 'build_stkvar_name', 729 | 'zya614': 'is_attached_custom_data_format', 730 | 'zya255': 'find_tinfo_udt_member', 731 | 'zya10': 'add_hidden_range', 732 | 'zya977': 'set_group_selector', 733 | 'zya1075': 'structplace_t__toea', 734 | 'zya934': 'revert_byte', 735 | 'zya1076': 'structplace_t__touval', 736 | 'zya466': 'get_prev_func_addr', 737 | 'zya53': 'auto_is_ok', 738 | 'zya48': 'atos', 739 | 'zya409': 'get_last_pfxlen', 740 | 'zya159': 'del_idc_func', 741 | 'zya65': 'bitrange_t_extract_using_bitrange', 742 | 'zya784': 'patch_fixup_value', 743 | 'zya254': 'find_suspop', 744 | 'zya290': 'generate_disassembly', 745 | 'zya211': 'enumplace_t__id', 746 | 'zya748': 'netnode_supval', 747 | 'zya102': 'cfg_get_cc_parm', 748 | 'zya271': 'free_loaders_list', 749 | 'zya1001': 'set_regvar_cmt', 750 | 'zya746': 'netnode_supshift', 751 | 'zya627': 'is_enum_hidden', 752 | 'zya506': 'get_stroff_path', 753 | 'zya331': 'get_encoding_qty', 754 | 'zya269': 'format_cdata', 755 | 'zya888': 'rangeset_t_add2', 756 | 'zya72': 'bookmarks_t_size', 757 | 'zya1070': 'structplace_t__next', 758 | 'zya559': 'hexplace_t__prev', 759 | 'zya907': 'reg_exists', 760 | 'zya535': 'getnseg', 761 | 'zya104': 'change_segment_status', 762 | 'zya388': 'get_group_selector', 763 | 'zya201': 'enum_import_names', 764 | 'zya780': 'parse_json', 765 | 'zya801': 'print_operand', 766 | 'zya383': 'get_func_cmt', 767 | 'zya1054': 'strarray', 768 | 'zya534': 'getn_sreg_range', 769 | 'zya1056': 'strrpl', 770 | 'zya133': 'create_generic_linput', 771 | 'zya984': 'set_member_cmt', 772 | 'zya808': 'put_dword', 773 | 'zya730': 'netnode_lower_bound', 774 | 'zya998': 'set_purged', 775 | 'zya952': 'set_cmt', 776 | 'zya420': 'get_max_strlit_length', 777 | 'zya323': 'get_dirty_infos', 778 | 'zya511': 'get_struc_last_offset', 779 | 'zya453': 'get_opinfo', 780 | 'zya578': 'idaplace_t__id', 781 | 'zya928': 'rename_regvar', 782 | 'zya708': 'match_jpt', 783 | 'zya318': 'get_debug_names', 784 | 'zya113': 'clear_tinfo_t', 785 | 'zya585': 'idaplace_t__rebase', 786 | 'zya647': 'is_ret_insn', 787 | 'zya749': 'netnode_valobj', 788 | 'zya595': 'import_module', 789 | 'zya641': 'is_name_defined_locally', 790 | 'zya522': 'get_utf8_char', 791 | 'zya821': 'qerrstr', 792 | 'zya651': 'is_special_member', 793 | 'zya496': 'get_sreg', 794 | 'zya164': 'del_node_info', 795 | 'zya1028': 'simpleline_place_t__adjust', 796 | 'zya475': 'get_refinfo_descs', 797 | 'zya1026': 'show_auto', 798 | 'zya1027': 'show_name', 799 | 'zya1101': 'unpack_xleb128', 800 | 'zya415': 'get_loader_name_from_dll', 801 | 'zya194': 'ea2str', 802 | 'zya178': 'delete_extra_cmts', 803 | 'zya865': 'qstrerror', 804 | 'zya759': 'num2str_uint32', 805 | 'zya579': 'idaplace_t__leave', 806 | 'zya31': 'append_abi_opts', 807 | 'zya190': 'dto_init', 808 | 'zya944': 'segtype', 809 | 'zya128': 'copy_tinfo_t', 810 | 'zya693': 'lochist_t_register_live', 811 | 'zya509': 'get_struc_first_offset', 812 | 'zya725': 'netnode_hashset', 813 | 'zya1066': 'structplace_t__id', 814 | 'zya256': 'find_unknown', 815 | 'zya222': 'equal_bytes', 816 | 'zya444': 'get_nlist_name', 817 | 'zya887': 'rangeset_t_add', 818 | 'zya462': 'get_plugins', 819 | 'zya618': 'is_call_insn', 820 | 'zya108': 'choose_local_tinfo', 821 | 'zya114': 'close_linput', 822 | 'zya378': 'get_free_disk_space', 823 | 'zya880': 'qunlink', 824 | 'zya78': 'build_snapshot_tree', 825 | 'zya947': 'set_abits', 826 | 'zya957': 'set_debug_name', 827 | 'zya1057': 'structplace_t__adjust', 828 | 'zya571': 'idaplace_t__clone', 829 | 'zya904': 'reg_delete', 830 | 'zya1099': 'unpack_ds', 831 | 'zya940': 'save_tinfo', 832 | 'zya745': 'netnode_supset', 833 | 'zya691': 'lochist_t_init', 834 | 'zya273': 'func_does_return', 835 | 'zya245': 'find_func_bounds', 836 | 'zya1112': 'utf16_utf8', 837 | 'zya702': 'lreadbytes', 838 | 'zya666': 'lex_define_macro', 839 | 'zya816': 'qcalloc', 840 | 'zya707': 'make_name_weak', 841 | 'zya177': 'delete_all_xrefs_from', 842 | 'zya850': 'qmakepath', 843 | 'zya16': 'add_regvar', 844 | 'zya206': 'enumplace_t__copyfrom', 845 | 'zya188': 'dto_copy_from_inf', 846 | 'zya950': 'set_bmask_cmt', 847 | 'zya793': 'prev_visea', 848 | 'zya223': 'eread', 849 | 'zya970': 'set_file_ext', 850 | 'zya352': 'get_errdesc', 851 | 'zya518': 'get_tinfo_pdata', 852 | 'zya468': 'get_problem', 853 | 'zya430': 'get_name_value', 854 | 'zya304': 'get_bytes', 855 | 'zya1074': 'structplace_t__serialize', 856 | 'zya487': 'get_segment_alignment', 857 | 'zya935': 'root_node', 858 | 'zya590': 'idcv_float', 859 | 'zya680': 'load_binary_file', 860 | 'zya656': 'is_uname', 861 | 'zya480': 'get_segm_by_name', 862 | 'zya987': 'set_member_type', 863 | 'zya856': 'qsem_create', 864 | 'zya243': 'find_error', 865 | 'zya731': 'netnode_qgetblob', 866 | 'zya659': 'is_varsize_item', 867 | 'zya1045': 'simpleline_place_t__serialize', 868 | 'zya649': 'is_spec_ea', 869 | 'zya344': 'get_enum_member_cmt', 870 | 'zya355': 'get_fchunk_qty', 871 | 'zya598': 'inform_idc_about_debthread', 872 | 'zya215': 'enumplace_t__next', 873 | 'zya122': 'compare_arglocs', 874 | 'zya1091': 'trim', 875 | 'zya265': 'for_all_arglocs', 876 | 'zya538': 'guess_func_cc', 877 | 'zya224': 'errorexit', 878 | 'zya134': 'create_hit_counter', 879 | 'zya705': 'make_name_non_public', 880 | 'zya379': 'get_func', 881 | 'zya90': 'calc_max_align', 882 | 'zya948': 'set_array_parameters', 883 | 'zya239': 'find_custom_fixup', 884 | 'zya1064': 'structplace_t__enter', 885 | 'zya885': 'qvprintf', 886 | 'zya107': 'check_spoiled_jpt', 887 | 'zya652': 'is_stkvar', 888 | 'zya21': 'add_struc_member', 889 | 'zya1068': 'structplace_t__makeplace', 890 | 'zya1014': 'set_struc_cmt', 891 | 'zya792': 'prev_that', 892 | 'zya280': 'fwritebytes', 893 | 'zya1052': 'str2ea_ex', 894 | 'zya401': 'get_immvals', 895 | 'zya1087': 'term_kernel', 896 | 'zya956': 'set_dbgmem_source', 897 | 'zya131': 'create_data', 898 | 'zya39': 'apply_idasgn_to', 899 | 'zya1002': 'set_segm_addressing', 900 | 'zya373': 'get_fixups', 901 | 'zya261': 'fopenRB', 902 | 'zya142': 'create_xrefs_from', 903 | 'zya234': 'fc_calc_block_type', 904 | 'zya150': 'del_cref', 905 | 'zya1019': 'set_tinfo_property', 906 | 'zya403': 'get_import_module_qty', 907 | 'zya84': 'calc_crc32', 908 | 'zya1079': 'tag_advance', 909 | 'zya115': 'closing_comment', 910 | 'zya848': 'qlsize', 911 | 'zya74': 'btoa64', 912 | 'zya60': 'batch', 913 | 'zya879': 'qtmpnam', 914 | 'zya889': 'rangeset_t_contains', 915 | 'zya871': 'qstrtok', 916 | 'zya421': 'get_member', 917 | 'zya674': 'linearray_t_dtr', 918 | 'zya893': 'rangeset_t_sub', 919 | 'zya985': 'set_member_name', 920 | 'zya272': 'free_til', 921 | 'zya04': 'add_encoding', 922 | 'zya765': 'op_offset', 923 | 'zya105': 'change_storage_type', 924 | 'zya46': 'atob64', 925 | 'zya769': 'op_stroff', 926 | 'zya412': 'get_last_struc_idx', 927 | 'zya301': 'get_bmask_cmt', 928 | 'zya842': 'qgetline', 929 | 'zya536': 'getseg', 930 | 'zya410': 'get_last_seg', 931 | 'zya495': 'get_sptr', 932 | 'zya423': 'get_member_by_name', 933 | 'zya938': 'save_database', 934 | 'zya553': 'hexplace_t__id', 935 | 'zya710': 'memrev', 936 | 'zya999': 'set_qerrno', 937 | 'zya1086': 'term_database', 938 | 'zya231': 'extend_sign', 939 | 'zya232': 'extract_module_from_archive', 940 | 'zya582': 'idaplace_t__next', 941 | 'zya179': 'delete_unreferenced_stkvars', 942 | 'zya890': 'rangeset_t_find_range', 943 | 'zya359': 'get_fileregion_offset', 944 | 'zya797': 'print_charlit', 945 | 'zya930': 'replace_tabs', 946 | 'zya633': 'is_in_nlist', 947 | 'zya719': 'netnode_check', 948 | 'zya1081': 'tag_on', 949 | 'zya592': 'idcv_object', 950 | 'zya1025': 'setup_selector', 951 | 'zya467': 'get_prev_seg', 952 | 'zya825': 'qfileexist', 953 | 'zya788': 'plan_and_wait', 954 | 'zya457': 'get_original_word', 955 | 'zya43': 'apply_tinfo_to_stkarg', 956 | 'zya960': 'set_default_sreg_value', 957 | 'zya1008': 'set_segment_cmt', 958 | 'zya1032': 'simpleline_place_t__copyfrom', 959 | 'zya124': 'compile_idc_file', 960 | 'zya221': 'enumplace_t__touval', 961 | 'zya502': 'get_strid', 962 | 'zya93': 'calc_offset_base', 963 | 'zya818': 'qctime_utc', 964 | 'zya1119': 'vloader_failure', 965 | 'zya575': 'idaplace_t__ending', 966 | 'zya35': 'append_snprintf', 967 | 'zya528': 'get_xrefpos', 968 | 'zya635': 'is_loaded', 969 | 'zya828': 'qfindfirst', 970 | 'zya499': 'get_sreg_ranges_qty', 971 | 'zya193': 'ea2node', 972 | 'zya988': 'set_name', 973 | 'zya307': 'get_current_extlang', 974 | 'zya41': 'apply_once_tinfo_and_name', 975 | 'zya1060': 'structplace_t__compare', 976 | 'zya76': 'build_loaders_list', 977 | 'zya895': 'read_ioports', 978 | 'zya443': 'get_nlist_idx', 979 | 'zya583': 'idaplace_t__prev', 980 | 'zya368': 'get_first_seg', 981 | 'zya263': 'fopenWB', 982 | 'zya494': 'get_special_folder', 983 | 'zya512': 'get_struc_next_offset', 984 | 'zya422': 'get_member_by_fullname', 985 | 'zya230': 'expand_struc', 986 | 'zya925': 'remove_func_tail', 987 | 'zya787': 'ph', 988 | 'zya541': 'has_external_refs', 989 | 'zya446': 'get_node_info', 990 | 'zya81': 'build_strlist', 991 | 'zya766': 'op_offset_ex', 992 | 'zya806': 'put_byte', 993 | 'zya62': 'bf_crypt_cbc', 994 | 'zya297': 'get_auto_display', 995 | 'zya73': 'btoa32', 996 | 'zya116': 'clr_abits', 997 | 'zya339': 'get_enum_id', 998 | 'zya248': 'find_jtable_size', 999 | 'zya1069': 'structplace_t__name', 1000 | 'zya329': 'get_encoding_bpu', 1001 | 'zya700': 'lower_type', 1002 | 'zya205': 'enumplace_t__compare', 1003 | 'zya734': 'netnode_qhashstr', 1004 | 'zya50': 'auto_apply_tail', 1005 | 'zya712': 'move_segm_start', 1006 | 'zya414': 'get_loader_name', 1007 | 'zya85': 'calc_dataseg', 1008 | 'zya963': 'set_enum_cmt', 1009 | 'zya516': 'get_tinfo', 1010 | 'zya09': 'add_func_ex', 1011 | 'zya191': 'dummy_name_ea', 1012 | 'zya199': 'enable_numbered_types', 1013 | 'zya314': 'get_data_elsize', 1014 | 'zya971': 'set_fixup', 1015 | 'zya236': 'find_byte', 1016 | 'zya549': 'hexplace_t__ea2str', 1017 | 'zya835': 'qfree', 1018 | 'zya697': 'lock_func_range', 1019 | 'zya701': 'lread', 1020 | 'zya120': 'code_highlight_block', 1021 | 'zya868': 'qstrlwr', 1022 | 'zya505': 'get_strlit_contents', 1023 | 'zya694': 'lochist_t_save', 1024 | 'zya684': 'lochist_t_back', 1025 | 'zya123': 'compare_tinfo', 1026 | 'zya44': 'asctoreal', 1027 | 'zya45': 'ash', 1028 | 'zya800': 'print_idcv', 1029 | 'zya558': 'hexplace_t__out_one_item', 1030 | 'zya1072': 'structplace_t__print', 1031 | 'zya37': 'apply_callee_tinfo', 1032 | 'zya89': 'calc_idasgn_state', 1033 | 'zya631': 'is_ghost_enum', 1034 | 'zya288': 'gen_use_arg_tinfos', 1035 | 'zya756': 'next_visea', 1036 | 'zya637': 'is_main_thread', 1037 | 'zya688': 'lochist_t_fwd', 1038 | 'zya851': 'qmutex_create', 1039 | 'zya80': 'build_stkvar_xrefs', 1040 | 'zya1078': 'swap_value', 1041 | 'zya291': 'get_16bit', 1042 | } 1043 | 1044 | def do_rename(z, name, prefix, suffix): 1045 | if prefix == None: 1046 | prefix = "" 1047 | if suffix == None: 1048 | suffix = "" 1049 | z = "%s%s%s" % (prefix, z, suffix) 1050 | name = "%s%s%s" % (prefix, name, suffix) 1051 | eaaddr = LocByName(z) 1052 | if eaaddr != BADADDR: 1053 | #idc.MakeCode(eaaddr) 1054 | #idc.MakeFunction(eaaddr) 1055 | #idc.MakeNameEx(eaaddr, name, idc.SN_NOWARN) 1056 | idc.MakeNameEx(eaaddr, name, 0) 1057 | 1058 | if __name__ == "__main__": 1059 | for i in alias: 1060 | print "renaming %s -> %s" % (i, alias[i]) 1061 | name = "Z_%s" % alias[i] 1062 | do_rename(i, name, None, None) 1063 | do_rename(i, name, ".", None) 1064 | do_rename(i, name, None, "_ptr") 1065 | do_rename(i, name, None, "_0") 1066 | do_rename(i, name, "j_.", None) 1067 | -------------------------------------------------------------------------------- /linux/loader/loader.c: -------------------------------------------------------------------------------- 1 | /* 2 | * dylib loader 3 | * 4 | * Copyright (c) 2015, 2016, 2018 xerub 5 | */ 6 | 7 | #define _GNU_SOURCE 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #define STRINGIFY(x) #x 24 | #define UNDERSCORE(x) "_" STRINGIFY(x) 25 | 26 | #define INFO(args...) //printf(args) 27 | #define ERR(args...) fprintf(stderr, args) 28 | 29 | #define round_page(size) ((size + 0xFFF) & ~0xFFF) 30 | 31 | #define IS64(image) (*(uint8_t *)(image) & 1) 32 | 33 | #ifdef __LP64__ 34 | static const uint8_t kernel[] = { 35 | 0xcf, 0xfa, 0xed, 0xfe, 0x07, 0x00, 0x00, 0x01, 0x03, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00 36 | }; 37 | #else 38 | static const uint8_t kernel[] = { 39 | 0xce, 0xfa, 0xed, 0xfe, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00 40 | }; 41 | #endif 42 | 43 | /* fat ***********************************************************************/ 44 | 45 | struct macho { 46 | int fd; 47 | size_t off, end; 48 | }; 49 | 50 | static int 51 | mclose(struct macho *macho) 52 | { 53 | int rv = -1; 54 | if (macho) { 55 | rv = close(macho->fd); 56 | free(macho); 57 | } 58 | return rv; 59 | } 60 | 61 | static ssize_t 62 | mread(struct macho *macho, void *buf, size_t count, off_t offset) 63 | { 64 | size_t len; 65 | size_t off; 66 | if (!macho) { 67 | return -1; 68 | } 69 | off = offset + macho->off; 70 | if (off < macho->off) { 71 | return -1; 72 | } 73 | if (off >= macho->end) { 74 | return 0; 75 | } 76 | len = macho->end - off; 77 | if (len > count) { 78 | len = count; 79 | } 80 | return pread(macho->fd, buf, len, off); 81 | } 82 | 83 | static struct macho * 84 | mopen(const char *filename, int mode, const struct mach_header *target) 85 | { 86 | int rv; 87 | int fd; 88 | size_t size; 89 | unsigned i, n; 90 | struct stat st; 91 | struct fat_header fat_buf; 92 | struct mach_header hdr; 93 | struct macho *macho; 94 | 95 | macho = malloc(sizeof(struct macho)); 96 | if (macho == NULL) { 97 | return NULL; 98 | } 99 | 100 | fd = open(filename, mode); 101 | if (fd < 0) { 102 | free(macho); 103 | return NULL; 104 | } 105 | macho->fd = fd; 106 | 107 | rv = fstat(fd, &st); 108 | if (rv) { 109 | mclose(macho); 110 | return NULL; 111 | } 112 | 113 | size = read(fd, &fat_buf, sizeof(fat_buf)); 114 | if (size != sizeof(fat_buf)) { 115 | mclose(macho); 116 | return NULL; 117 | } 118 | 119 | if (fat_buf.magic != FAT_CIGAM) { 120 | if (fat_buf.magic == target->magic && (cpu_type_t)fat_buf.nfat_arch == target->cputype) { 121 | size = read(fd, &n, sizeof(n)); 122 | if (size == sizeof(n) && (cpu_subtype_t)n <= target->cpusubtype) { 123 | macho->off = 0; 124 | macho->end = st.st_size; 125 | return macho; 126 | } 127 | } 128 | mclose(macho); 129 | return NULL; 130 | } 131 | 132 | n = __builtin_bswap32(fat_buf.nfat_arch); 133 | for (i = 0; i < n; i++) { 134 | size_t off, end; 135 | struct fat_arch arch_buf; 136 | size = pread(fd, &arch_buf, sizeof(arch_buf), sizeof(fat_buf) + i * sizeof(arch_buf)); 137 | if (size != sizeof(arch_buf)) { 138 | break; 139 | } 140 | off = __builtin_bswap32(arch_buf.offset); 141 | end = off + __builtin_bswap32(arch_buf.size); 142 | if (end < off || (off_t)end > st.st_size) { 143 | break; 144 | } 145 | macho->off = off; 146 | macho->end = end; 147 | size = mread(macho, &hdr, sizeof(hdr), 0); 148 | if (size != sizeof(hdr)) { 149 | break; 150 | } 151 | if (hdr.magic == target->magic && hdr.cputype == target->cputype && hdr.cpusubtype <= target->cpusubtype) { 152 | return macho; 153 | } 154 | } 155 | 156 | mclose(macho); 157 | return NULL; 158 | } 159 | 160 | /* the real mccoy ************************************************************/ 161 | 162 | static long __stack_chk_guard[8] = {0, 0, 10, 255, 0, 0, 0, 0}; 163 | extern char _DefaultRuneLocale[]; 164 | static int num_ctors; 165 | static uintptr_t *ctors; 166 | static int num_dtors; 167 | static uintptr_t *dtors; 168 | static uintptr_t the_ptr; 169 | char XSYMBOL[XSYMBOL_SIZE]; 170 | 171 | static void 172 | dyld_stub_binder(void) 173 | { 174 | assert(0); 175 | } 176 | 177 | extern char cxa_throw[]; 178 | extern void *eh_frame; 179 | 180 | static uintptr_t 181 | solver(const char *symbol) 182 | { 183 | static const struct { 184 | const char *osx; 185 | const void *lin; 186 | int dynamic; 187 | } syms[] = { 188 | { "___cxa_throw", cxa_throw, 0 }, 189 | { "dyld_stub_binder", (void *)(uintptr_t)dyld_stub_binder, 0 }, 190 | { "__DefaultRuneLocale", _DefaultRuneLocale, 0 }, 191 | { "___stack_chk_guard", __stack_chk_guard, 0 }, 192 | { "___tolower", "_tolower", 1 }, 193 | { "___toupper", "_toupper", 1 }, 194 | { NULL, NULL, 0 } 195 | }; 196 | unsigned i; 197 | uintptr_t addr = 0; 198 | for (i = 0; syms[i].osx; i++) { 199 | if (!strcmp(syms[i].osx, symbol)) { 200 | if (syms[i].dynamic) { 201 | symbol = syms[i].lin; 202 | break; 203 | } 204 | addr = (uintptr_t)syms[i].lin; 205 | break; 206 | } 207 | } 208 | if (!addr) { 209 | addr = (uintptr_t)dlsym(RTLD_DEFAULT, symbol + 1); 210 | } 211 | INFO("solve: %s -> 0x%zx\n", symbol, addr); 212 | return addr; 213 | } 214 | 215 | static void 216 | preload(const char *dependency) 217 | { 218 | static const struct { 219 | const char *osx; 220 | const char *lin; 221 | } libs[] = { 222 | { "/usr/lib/libSystem.B.dylib", NULL }, 223 | { "/usr/lib/libiconv.2.dylib", NULL }, 224 | { "/usr/lib/libstdc++.6.dylib", "libstdc++.so.6" }, 225 | { "/usr/lib/libgcc_s.1.dylib", "libgcc_s.so.1" }, 226 | { NULL, NULL } 227 | }; 228 | unsigned i; 229 | INFO("dlopen(%s)", dependency); 230 | for (i = 0; libs[i].osx; i++) { 231 | if (!strcmp(libs[i].osx, dependency)) { 232 | if (libs[i].lin) { 233 | void *h = dlopen(libs[i].lin, RTLD_GLOBAL | RTLD_LAZY); 234 | INFO(" -> %s -> %p", libs[i].lin, h); 235 | (void)h; 236 | } 237 | break; 238 | } 239 | } 240 | INFO("\n"); 241 | } 242 | 243 | static uintptr_t 244 | read_uleb128(const uint8_t **q, const uint8_t *end) 245 | { 246 | const uint8_t *p = *q; 247 | uint64_t result = 0; 248 | int bit = 0; 249 | do { 250 | uint64_t slice; 251 | 252 | if (p == end) { 253 | errx(1, "malformed uleb128 extends beyond trie"); 254 | } 255 | 256 | slice = *p & 0x7f; 257 | 258 | if (bit >= 64 || slice << bit >> bit != slice) { 259 | errx(1, "uleb128 too big for 64-bits"); 260 | } else { 261 | result |= (slice << bit); 262 | bit += 7; 263 | } 264 | } while (*p++ & 0x80); 265 | *q = p; 266 | return result; 267 | } 268 | 269 | static intptr_t 270 | read_sleb128(const uint8_t **q, const uint8_t *end) 271 | { 272 | const uint8_t *p = *q; 273 | int64_t result = 0; 274 | int bit = 0; 275 | uint8_t byte; 276 | do { 277 | if (p == end) { 278 | errx(1, "malformed sleb128"); 279 | } 280 | byte = *p++; 281 | result |= ((int64_t)(byte & 0x7f)) << bit; 282 | bit += 7; 283 | } while (byte & 0x80); 284 | if (byte & 0x40) { 285 | result |= (-1LL) << bit; 286 | } 287 | *q = p; 288 | return result; 289 | } 290 | 291 | #define segActualLoadAddress(i) segments[(i) * 2] 292 | #define segActualEndAddress(i) segments[(i) * 2 + 1] 293 | 294 | static void 295 | bindAt(void *context, uintptr_t addr, uint8_t type, const char* symbolName, uint8_t symbolFlags, int64_t addend, long libraryOrdinal) 296 | { 297 | INFO("#import: 0x%zx %s\n", addr, symbolName); 298 | (void)(context && addr && type && symbolName && symbolFlags && addend && libraryOrdinal); 299 | } 300 | 301 | static void 302 | do_import(const uint8_t *buf, uint32_t bind_off, uint32_t bind_size, const uintptr_t *segments, int n, void *context, int lazy) 303 | { 304 | uint32_t i; 305 | uint8_t type = lazy; 306 | int segmentIndex = 0; 307 | uintptr_t address = segActualLoadAddress(0); 308 | uintptr_t segmentEndAddress = segActualEndAddress(0); 309 | const char* symbolName = NULL; 310 | uint8_t symboFlags = 0; 311 | long libraryOrdinal = 0; 312 | intptr_t addend = 0; 313 | uintptr_t count; 314 | uintptr_t skip; 315 | const uint8_t* const start = buf + bind_off; 316 | const uint8_t* const end = &start[bind_size]; 317 | const uint8_t* p = start; 318 | int done = 0; 319 | while ( !done && (p < end) ) { 320 | uint8_t immediate = *p & BIND_IMMEDIATE_MASK; 321 | uint8_t opcode = *p & BIND_OPCODE_MASK; 322 | ++p; 323 | switch (opcode) { 324 | case BIND_OPCODE_DONE: 325 | if (!lazy) done = 1; 326 | break; 327 | case BIND_OPCODE_SET_DYLIB_ORDINAL_IMM: 328 | libraryOrdinal = immediate; 329 | break; 330 | case BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB: 331 | libraryOrdinal = read_uleb128(&p, end); 332 | break; 333 | case BIND_OPCODE_SET_DYLIB_SPECIAL_IMM: 334 | // the special ordinals are negative numbers 335 | if ( immediate == 0 ) 336 | libraryOrdinal = 0; 337 | else { 338 | int8_t signExtended = BIND_OPCODE_MASK | immediate; 339 | libraryOrdinal = signExtended; 340 | } 341 | break; 342 | case BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM: 343 | symbolName = (char*)p; 344 | symboFlags = immediate; 345 | while (*p != '\0') 346 | ++p; 347 | ++p; 348 | break; 349 | case BIND_OPCODE_SET_TYPE_IMM: 350 | type = immediate; 351 | break; 352 | case BIND_OPCODE_SET_ADDEND_SLEB: 353 | addend = read_sleb128(&p, end); 354 | break; 355 | case BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: 356 | segmentIndex = immediate; 357 | if ( segmentIndex >= n ) 358 | errx(1, "BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB has segment %d which is too large (%d)\n", 359 | segmentIndex, n); 360 | address = segActualLoadAddress(segmentIndex) + read_uleb128(&p, end); 361 | segmentEndAddress = segActualEndAddress(segmentIndex); 362 | break; 363 | case BIND_OPCODE_ADD_ADDR_ULEB: 364 | address += read_uleb128(&p, end); 365 | break; 366 | case BIND_OPCODE_DO_BIND: 367 | if ( address >= segmentEndAddress ) 368 | errx(1, "throwBadBindingAddress(0x%zx, 0x%zx, %d, %p, %p, %p);", address, segmentEndAddress, segmentIndex, start, end, p); 369 | bindAt(context, address, type, symbolName, symboFlags, addend, libraryOrdinal); 370 | address += sizeof(intptr_t); 371 | break; 372 | case BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB: 373 | if ( address >= segmentEndAddress ) 374 | errx(1, "throwBadBindingAddress(0x%zx, 0x%zx, %d, %p, %p, %p);", address, segmentEndAddress, segmentIndex, start, end, p); 375 | bindAt(context, address, type, symbolName, symboFlags, addend, libraryOrdinal); 376 | address += read_uleb128(&p, end) + sizeof(intptr_t); 377 | break; 378 | case BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED: 379 | if ( address >= segmentEndAddress ) 380 | errx(1, "throwBadBindingAddress(0x%zx, 0x%zx, %d, %p, %p, %p);", address, segmentEndAddress, segmentIndex, start, end, p); 381 | bindAt(context, address, type, symbolName, symboFlags, addend, libraryOrdinal); 382 | address += immediate*sizeof(intptr_t) + sizeof(intptr_t); 383 | break; 384 | case BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB: 385 | count = read_uleb128(&p, end); 386 | skip = read_uleb128(&p, end); 387 | for (i=0; i < count; ++i) { 388 | if ( address >= segmentEndAddress ) 389 | errx(1, "throwBadBindingAddress(0x%zx, 0x%zx, %d, %p, %p, %p);", address, segmentEndAddress, segmentIndex, start, end, p); 390 | bindAt(context, address, type, symbolName, symboFlags, addend, libraryOrdinal); 391 | address += skip + sizeof(intptr_t); 392 | } 393 | break; 394 | default: 395 | errx(1, "bad bind opcode %d in bind info", *p); 396 | } 397 | } 398 | } 399 | 400 | static void 401 | rebaseAt(void *context, uintptr_t addr, uintptr_t slide, uint8_t type) 402 | { 403 | *(uintptr_t *)addr += slide; 404 | (void)(context && type); 405 | } 406 | 407 | static void 408 | do_rebase(const uint8_t *buf, uint32_t rebase_off, uint32_t rebase_size, const uintptr_t *segments, int n, void *context) 409 | { 410 | unsigned fgTotalRebaseFixups = 0; 411 | const uintptr_t slide = *(uintptr_t *)context; 412 | const uint8_t* const start = buf + rebase_off; 413 | const uint8_t* const end = &start[rebase_size]; 414 | const uint8_t* p = start; 415 | 416 | uint8_t type = 0; 417 | int segmentIndex = 0; 418 | uintptr_t address = segActualLoadAddress(0); 419 | uintptr_t segmentEndAddress = segActualEndAddress(0); 420 | uintptr_t count; 421 | uintptr_t skip; 422 | int done = 0; 423 | while ( !done && (p < end) ) { 424 | uint8_t immediate = *p & REBASE_IMMEDIATE_MASK; 425 | uint8_t opcode = *p & REBASE_OPCODE_MASK; 426 | ++p; 427 | switch (opcode) { 428 | case REBASE_OPCODE_DONE: 429 | done = 1; 430 | break; 431 | case REBASE_OPCODE_SET_TYPE_IMM: 432 | type = immediate; 433 | break; 434 | case REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: 435 | segmentIndex = immediate; 436 | if ( segmentIndex >= n ) 437 | errx(1, "REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB has segment %d which is too large (0..%d)", 438 | segmentIndex, n-1); 439 | address = segActualLoadAddress(segmentIndex) + read_uleb128(&p, end); 440 | segmentEndAddress = segActualEndAddress(segmentIndex); 441 | break; 442 | case REBASE_OPCODE_ADD_ADDR_ULEB: 443 | address += read_uleb128(&p, end); 444 | break; 445 | case REBASE_OPCODE_ADD_ADDR_IMM_SCALED: 446 | address += immediate*sizeof(uintptr_t); 447 | break; 448 | case REBASE_OPCODE_DO_REBASE_IMM_TIMES: 449 | for (int i=0; i < immediate; ++i) { 450 | if ( address >= segmentEndAddress ) 451 | errx(1, "throwBadBindingAddress(0x%zx, 0x%zx, %d, %p, %p, %p);", address, segmentEndAddress, segmentIndex, start, end, p); 452 | rebaseAt(context, address, slide, type); 453 | address += sizeof(uintptr_t); 454 | } 455 | fgTotalRebaseFixups += immediate; 456 | break; 457 | case REBASE_OPCODE_DO_REBASE_ULEB_TIMES: 458 | count = read_uleb128(&p, end); 459 | for (uint32_t i=0; i < count; ++i) { 460 | if ( address >= segmentEndAddress ) 461 | errx(1, "throwBadBindingAddress(0x%zx, 0x%zx, %d, %p, %p, %p);", address, segmentEndAddress, segmentIndex, start, end, p); 462 | rebaseAt(context, address, slide, type); 463 | address += sizeof(uintptr_t); 464 | } 465 | fgTotalRebaseFixups += count; 466 | break; 467 | case REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB: 468 | if ( address >= segmentEndAddress ) 469 | errx(1, "throwBadBindingAddress(0x%zx, 0x%zx, %d, %p, %p, %p);", address, segmentEndAddress, segmentIndex, start, end, p); 470 | rebaseAt(context, address, slide, type); 471 | address += read_uleb128(&p, end) + sizeof(uintptr_t); 472 | ++fgTotalRebaseFixups; 473 | break; 474 | case REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB: 475 | count = read_uleb128(&p, end); 476 | skip = read_uleb128(&p, end); 477 | for (uint32_t i=0; i < count; ++i) { 478 | if ( address >= segmentEndAddress ) 479 | errx(1, "throwBadBindingAddress(0x%zx, 0x%zx, %d, %p, %p, %p);", address, segmentEndAddress, segmentIndex, start, end, p); 480 | rebaseAt(context, address, slide, type); 481 | address += skip + sizeof(uintptr_t); 482 | } 483 | fgTotalRebaseFixups += count; 484 | break; 485 | default: 486 | errx(1, "bad rebase opcode %d", *p); 487 | } 488 | } 489 | } 490 | 491 | #undef segActualEndAddress 492 | #undef segActualLoadAddress 493 | 494 | static void 495 | exportAt(void *context, uintptr_t address, uint64_t other, const char *importName, const char *symbolName) 496 | { 497 | assert(importName == NULL); 498 | INFO("#public(0x%zx) %s\n", *(uintptr_t *)context + address, symbolName); 499 | (void)(context && address && other && symbolName); 500 | } 501 | 502 | static void 503 | processExportNode(const uint8_t *const start, const uint8_t *p, const uint8_t* const end, char *cummulativeString, int curStrOffset, void *context) 504 | { 505 | if (p >= end) { 506 | errx(1, "malformed trie, node past end"); 507 | } 508 | const uint8_t terminalSize = read_uleb128(&p, end); 509 | const uint8_t *children = p + terminalSize; 510 | if (terminalSize != 0) { 511 | /*uintptr_t nodeOffset = p - start;*/ 512 | const char *name = strdup(cummulativeString); 513 | uint64_t address; 514 | uint64_t flags = read_uleb128(&p, end); 515 | uint64_t other; 516 | const char *importName; 517 | 518 | if (flags & EXPORT_SYMBOL_FLAGS_REEXPORT) { 519 | address = 0; 520 | other = read_uleb128(&p, end); 521 | importName = (char*)p; 522 | } else { 523 | address = read_uleb128(&p, end); 524 | if (flags & EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER) { 525 | other = read_uleb128(&p, end); 526 | } else { 527 | other = 0; 528 | } 529 | importName = NULL; 530 | } 531 | exportAt(context, address, other, importName, name); 532 | free((char *)name); 533 | } 534 | 535 | const uint8_t childrenCount = *children++; 536 | const uint8_t *s = children; 537 | uint8_t i; 538 | for (i = 0; i < childrenCount; ++i) { 539 | int edgeStrLen = 0; 540 | while (*s != '\0') { 541 | cummulativeString[curStrOffset + edgeStrLen] = *s++; 542 | ++edgeStrLen; 543 | } 544 | cummulativeString[curStrOffset + edgeStrLen] = *s++; 545 | uint32_t childNodeOffset = read_uleb128(&s, end); 546 | if (childNodeOffset == 0) { 547 | errx(1, "malformed trie, childNodeOffset==0"); 548 | } 549 | processExportNode(start, start + childNodeOffset, end, cummulativeString, curStrOffset + edgeStrLen, context); 550 | } 551 | } 552 | 553 | static void 554 | do_export(const unsigned char *p, off_t sz, uint32_t export_off, uint32_t export_size, void *context) 555 | { 556 | const unsigned char *q = p + export_off; 557 | const unsigned char *end = q + export_size; 558 | char *cummulativeString; 559 | if (q == end) { 560 | return; 561 | } 562 | cummulativeString = malloc(end - q); 563 | if (!cummulativeString) { 564 | errx(1, "out of memory"); 565 | } 566 | processExportNode(q, q, end, cummulativeString, 0, context); 567 | free(cummulativeString); 568 | (void)sz; 569 | } 570 | 571 | static uint8_t * 572 | load_kext(const char *filename, uintptr_t *dest, size_t *sz) 573 | { 574 | int rv; 575 | struct macho *macho; 576 | uint8_t *buf; 577 | uint8_t p[0x1000]; 578 | size_t size, offset; 579 | struct symtab_command *ksym = NULL; 580 | struct dysymtab_command *kdys = NULL; 581 | struct dyld_info_command *kdic = NULL; 582 | uintptr_t segments[2 * 16]; 583 | unsigned num_segments = 0; 584 | size_t linkdelta = 0; 585 | uintptr_t writable = 0; 586 | int is64 = 0; 587 | unsigned i, j, k; 588 | const struct mach_header *hdr; 589 | const uint8_t *q; 590 | size_t hdrsz; 591 | 592 | *sz = 0; 593 | *dest = 0; 594 | 595 | /* since I'm not going to rewrite a full dyld-like code, I'm gonna make some assumptions: 596 | * segments (including LINKEDIT) come in order 597 | * sections are nicely laid down inside segments 598 | * after segments come the other commands: SYMTAB, DYSYMTAB 599 | * symbols, relocations are inside LINKEDIT 600 | */ 601 | 602 | macho = mopen(filename, O_RDONLY, (struct mach_header *)kernel); 603 | if (!macho) { 604 | ERR("%s: not found\n", filename); 605 | return NULL; 606 | } 607 | 608 | size = mread(macho, p, sizeof(p), 0); 609 | if (size != sizeof(p)) { 610 | ERR("%s: bad mach-o\n", filename); 611 | mclose(macho); 612 | return NULL; 613 | } 614 | 615 | /* parse header, calculate total in-memory size */ 616 | 617 | hdr = (struct mach_header *)p; 618 | q = p + sizeof(struct mach_header); 619 | 620 | if (IS64(p)) { 621 | is64 = 4; 622 | } 623 | q += is64; 624 | 625 | hdrsz = q - p + hdr->sizeofcmds; 626 | if (hdrsz > sizeof(p)) { 627 | ERR("%s: internal error\n", filename); 628 | mclose(macho); 629 | return NULL; 630 | } 631 | 632 | size = 0; 633 | for (i = 0; i < hdr->ncmds; i++) { 634 | const struct load_command *cmd = (struct load_command *)q; 635 | if (cmd->cmd == LC_SEGMENT) { 636 | struct segment_command *seg = (struct segment_command *)q; 637 | seg->vmsize = round_page(seg->vmsize); 638 | size += seg->vmsize; 639 | } 640 | if (cmd->cmd == LC_SEGMENT_64) { 641 | struct segment_command_64 *seg = (struct segment_command_64 *)q; 642 | seg->vmsize = round_page(seg->vmsize); 643 | size += seg->vmsize; 644 | } 645 | if (cmd->cmd == LC_LOAD_DYLIB) { 646 | struct dylib_command *dyl = (struct dylib_command *)q; 647 | preload((char *)q + dyl->dylib.name.offset); 648 | } 649 | q = q + cmd->cmdsize; 650 | } 651 | 652 | rv = posix_memalign((void **)&buf, 0x1000, size); 653 | if (rv) { 654 | ERR("%s: out of memory\n", filename); 655 | mclose(macho); 656 | return NULL; 657 | } 658 | memset(buf, 0, size); /* XXX take care of S_ZEROFILL */ 659 | *dest = (uintptr_t)buf; 660 | 661 | /* read segments in, calculate linkedit delta */ 662 | 663 | q = p + sizeof(struct mach_header) + is64; 664 | 665 | offset = 0; 666 | for (i = 0; i < hdr->ncmds; i++) { 667 | const struct load_command *cmd = (struct load_command *)q; 668 | if (cmd->cmd == LC_SEGMENT) { 669 | struct segment_command *seg = (struct segment_command *)q; 670 | struct section *sec = (struct section *)(seg + 1); 671 | if (!strcmp(seg->segname, "__LINKEDIT")) { 672 | linkdelta = offset - seg->fileoff; 673 | } 674 | if (seg->filesize > seg->vmsize) { 675 | seg->filesize = seg->vmsize; 676 | } 677 | seg->vmaddr += *dest; 678 | for (j = 0; j < seg->nsects; j++) { 679 | sec[j].addr += *dest; 680 | assert(sec->reloff == 0 && sec->nreloc == 0); 681 | if (!strncmp(sec[j].sectname, "__mod_init_func", 16)) { 682 | ctors = (uintptr_t *)(uintptr_t)sec[j].addr; 683 | num_ctors = sec[j].size / sizeof(void *); 684 | } 685 | if (!strncmp(sec[j].sectname, "__mod_term_func", 16)) { 686 | dtors = (uintptr_t *)(uintptr_t)sec[j].addr; 687 | num_dtors = sec[j].size / sizeof(void *); 688 | } 689 | if (!strncmp(sec[j].sectname, "__eh_frame", 16)) { 690 | eh_frame = (void *)(uintptr_t)sec[j].addr; 691 | } 692 | } 693 | size = mread(macho, buf + offset, seg->filesize, seg->fileoff); 694 | assert(size == seg->filesize); 695 | seg->fileoff = offset; 696 | if ((seg->initprot & 2) && !writable) { 697 | writable = offset; 698 | } 699 | assert(num_segments < 16); 700 | segments[num_segments * 2 + 0] = seg->vmaddr; 701 | segments[num_segments * 2 + 1] = seg->vmaddr + seg->vmsize; 702 | num_segments++; 703 | offset += seg->vmsize; 704 | } 705 | if (cmd->cmd == LC_SEGMENT_64) { 706 | struct segment_command_64 *seg = (struct segment_command_64 *)q; 707 | struct section_64 *sec = (struct section_64 *)(seg + 1); 708 | if (!strcmp(seg->segname, "__LINKEDIT")) { 709 | linkdelta = offset - seg->fileoff; 710 | } 711 | if (seg->filesize > seg->vmsize) { 712 | seg->filesize = seg->vmsize; 713 | } 714 | seg->vmaddr += *dest; 715 | for (j = 0; j < seg->nsects; j++) { 716 | sec[j].addr += *dest; 717 | assert(sec->reloff == 0 && sec->nreloc == 0); 718 | if (!strncmp(sec[j].sectname, "__mod_init_func", 16)) { 719 | ctors = (uintptr_t *)(uintptr_t)sec[j].addr; 720 | num_ctors = sec[j].size / sizeof(void *); 721 | } 722 | if (!strncmp(sec[j].sectname, "__mod_term_func", 16)) { 723 | dtors = (uintptr_t *)(uintptr_t)sec[j].addr; 724 | num_dtors = sec[j].size / sizeof(void *); 725 | } 726 | if (!strncmp(sec[j].sectname, "__eh_frame", 16)) { 727 | eh_frame = (void *)(uintptr_t)sec[j].addr; 728 | } 729 | } 730 | size = mread(macho, buf + offset, seg->filesize, seg->fileoff); 731 | assert(size == seg->filesize); 732 | seg->fileoff = offset; 733 | if ((seg->initprot & 2) && !writable) { 734 | writable = offset; 735 | } 736 | assert(num_segments < 16); 737 | segments[num_segments * 2 + 0] = seg->vmaddr; 738 | segments[num_segments * 2 + 1] = seg->vmaddr + seg->vmsize; 739 | num_segments++; 740 | offset += seg->vmsize; 741 | } 742 | q = q + cmd->cmdsize; 743 | } 744 | 745 | mclose(macho); 746 | 747 | /* fix header */ 748 | 749 | memcpy(buf, p, hdrsz); 750 | 751 | /* solve imports, spot relocs */ 752 | 753 | q = buf + sizeof(struct mach_header) + is64; 754 | 755 | #define SLIDE(x) do { if (x) x += linkdelta; } while (0) 756 | for (i = 0; i < hdr->ncmds; i++) { 757 | const struct load_command *cmd = (struct load_command *)q; 758 | if (cmd->cmd == LC_SYMTAB) { 759 | struct symtab_command *sym = (struct symtab_command *)q; 760 | ksym = sym; 761 | SLIDE(sym->symoff); 762 | SLIDE(sym->stroff); 763 | if (is64) { 764 | struct nlist_64 *s = (struct nlist_64 *)(buf + sym->symoff); 765 | for (k = 0; k < sym->nsyms; k++) { 766 | if (s[k].n_type & N_STAB) { 767 | continue; 768 | } 769 | if ((s[k].n_type & N_EXT) && GET_LIBRARY_ORDINAL(s[k].n_desc) > 0 && s[k].n_value == 0) { 770 | s[k].n_value = solver((char *)buf + sym->stroff + s[k].n_un.n_strx); 771 | continue; 772 | } 773 | s[k].n_value += *dest; 774 | } 775 | } else { 776 | struct nlist *s = (struct nlist *)(buf + sym->symoff); 777 | for (k = 0; k < sym->nsyms; k++) { 778 | if (s[k].n_type & N_STAB) { 779 | continue; 780 | } 781 | if ((s[k].n_type & N_EXT) && GET_LIBRARY_ORDINAL(s[k].n_desc) > 0 && s[k].n_value == 0) { 782 | s[k].n_value = solver((char *)buf + sym->stroff + s[k].n_un.n_strx); 783 | continue; 784 | } 785 | s[k].n_value += *dest; 786 | } 787 | } 788 | } 789 | if (cmd->cmd == LC_DYSYMTAB) { 790 | struct dysymtab_command *dys = (struct dysymtab_command *)q; 791 | kdys = dys; 792 | SLIDE(dys->tocoff); 793 | SLIDE(dys->modtaboff); 794 | SLIDE(dys->extrefsymoff); 795 | SLIDE(dys->indirectsymoff); 796 | SLIDE(dys->extreloff); 797 | SLIDE(dys->locreloff); 798 | } 799 | if (cmd->cmd == LC_DYLD_INFO_ONLY) { 800 | struct dyld_info_command *dic = (struct dyld_info_command *)q; 801 | kdic = dic; 802 | SLIDE(dic->rebase_off); 803 | SLIDE(dic->bind_off); 804 | SLIDE(dic->weak_bind_off); 805 | SLIDE(dic->lazy_bind_off); 806 | SLIDE(dic->export_off); 807 | } 808 | q = q + cmd->cmdsize; 809 | } 810 | #undef SLIDE 811 | 812 | /*if (kdic) { 813 | if (kdic->bind_off) { 814 | do_import(buf, kdic->bind_off, kdic->bind_size, segments, num_segments, dest, 0); 815 | } 816 | if (kdic->weak_bind_off) { 817 | assert(0); 818 | } 819 | if (kdic->lazy_bind_off) { 820 | do_import(buf, kdic->lazy_bind_off, kdic->lazy_bind_size, segments, num_segments, dest, BIND_TYPE_POINTER); 821 | } 822 | if (kdic->export_off) { 823 | do_export(buf, size, kdic->export_off, kdic->export_size, dest); 824 | } 825 | }*/ 826 | 827 | /* apply relocs */ 828 | 829 | if (kdic && kdic->rebase_off) { 830 | do_rebase(buf, kdic->rebase_off, kdic->rebase_size, segments, num_segments, dest); 831 | } else 832 | if (kdys && kdys->locreloff) { 833 | const struct relocation_info *r = (struct relocation_info *)(buf + kdys->locreloff); 834 | if (is64) { 835 | for (k = 0; k < kdys->nlocrel; k++, r++) { 836 | if ( 837 | #if 1 /* XXX horrible hack to reduce size */ 838 | (((uint32_t *)r)[1] >> 24) != 6 839 | #else 840 | r->r_pcrel || r->r_length != 3 || r->r_extern || r->r_type > GENERIC_RELOC_VANILLA 841 | #endif 842 | ) { 843 | assert(0); 844 | } 845 | if (r->r_address & R_SCATTERED) { 846 | assert(0); 847 | } 848 | *(uint64_t *)(buf + r->r_address + writable) += *dest; 849 | } 850 | } else { 851 | for (k = 0; k < kdys->nlocrel; k++, r++) { 852 | if ( 853 | #if 1 /* XXX horrible hack to reduce size */ 854 | (((uint32_t *)r)[1] >> 24) != 4 855 | #else 856 | r->r_pcrel || r->r_length != 2 || r->r_extern || r->r_type > GENERIC_RELOC_VANILLA 857 | #endif 858 | ) { 859 | assert(0); 860 | } 861 | if (r->r_address & R_SCATTERED) { 862 | assert(0); 863 | } 864 | *(uint32_t *)(buf + r->r_address + writable) += *dest; 865 | } 866 | } 867 | } 868 | 869 | /* apply externs */ 870 | 871 | if (kdys && kdys->extreloff && ksym->symoff) { 872 | const struct relocation_info *r = (struct relocation_info *)(buf + kdys->extreloff); 873 | if (is64) { 874 | const struct nlist_64 *s = (struct nlist_64 *)(buf + ksym->symoff); 875 | for (k = 0; k < kdys->nextrel; k++, r++) { 876 | assert(!r->r_pcrel && r->r_length == 3 && r->r_extern && r->r_type == GENERIC_RELOC_VANILLA); 877 | INFO("extern %d: 0x%zx = %s\n", r->r_symbolnum, r->r_address + writable, (char *)buf + ksym->stroff + s[r->r_symbolnum].n_un.n_strx); 878 | *(uint64_t *)(buf + r->r_address + writable) = s[r->r_symbolnum].n_value; 879 | } 880 | } else { 881 | const struct nlist *s = (struct nlist *)(buf + ksym->symoff); 882 | for (k = 0; k < kdys->nextrel; k++, r++) { 883 | assert(!r->r_pcrel && r->r_length == 2 && r->r_extern && r->r_type == GENERIC_RELOC_VANILLA); 884 | INFO("extern %d: 0x%zx = %s\n", r->r_symbolnum, r->r_address + writable, (char *)buf + ksym->stroff + s[r->r_symbolnum].n_un.n_strx); 885 | *(uint32_t *)(buf + r->r_address + writable) = s[r->r_symbolnum].n_value; 886 | } 887 | } 888 | } 889 | 890 | /* indirect symbols */ 891 | 892 | q = buf + sizeof(struct mach_header) + is64; 893 | for (i = 0; i < hdr->ncmds; i++) { 894 | const struct load_command *cmd = (struct load_command *)q; 895 | if (cmd->cmd == LC_SEGMENT) { 896 | struct segment_command *seg = (struct segment_command *)q; 897 | struct section *sec = (struct section *)(seg + 1); 898 | for (j = 0; j < seg->nsects; j++) { 899 | if ((sec[j].flags & SECTION_TYPE) == S_LAZY_SYMBOL_POINTERS || 900 | (sec[j].flags & SECTION_TYPE) == S_NON_LAZY_SYMBOL_POINTERS) { 901 | const struct nlist *s = (struct nlist *)(buf + ksym->symoff); 902 | unsigned stride = sizeof(void *); 903 | unsigned count = sec[j].size / stride; 904 | unsigned k, n = sec[j].reserved1; 905 | for (k = 0; k < count && n + k < kdys->nindirectsyms; k++) { 906 | unsigned int z = ((unsigned *)(buf + kdys->indirectsymoff))[k + n]; 907 | if (z & INDIRECT_SYMBOL_ABS) { 908 | continue; 909 | } 910 | if (z & INDIRECT_SYMBOL_LOCAL) { 911 | *(uint32_t *)((uintptr_t)sec[j].addr + k * stride) += *dest; 912 | continue; 913 | } 914 | INFO("indirect %d: 0x%x = %s\n", z, s[z].n_value, (char *)buf + ksym->stroff + s[z].n_un.n_strx); 915 | *(uint32_t *)((uintptr_t)sec[j].addr + k * stride) = s[z].n_value; 916 | } 917 | } 918 | } 919 | } 920 | if (cmd->cmd == LC_SEGMENT_64) { 921 | struct segment_command_64 *seg = (struct segment_command_64 *)q; 922 | struct section_64 *sec = (struct section_64 *)(seg + 1); 923 | for (j = 0; j < seg->nsects; j++) { 924 | if ((sec[j].flags & SECTION_TYPE) == S_LAZY_SYMBOL_POINTERS || 925 | (sec[j].flags & SECTION_TYPE) == S_NON_LAZY_SYMBOL_POINTERS) { 926 | const struct nlist_64 *s = (struct nlist_64 *)(buf + ksym->symoff); 927 | unsigned stride = sizeof(void *); 928 | unsigned count = sec[j].size / stride; 929 | unsigned k, n = sec[j].reserved1; 930 | for (k = 0; k < count && n + k < kdys->nindirectsyms; k++) { 931 | unsigned int z = ((unsigned *)(buf + kdys->indirectsymoff))[k + n]; 932 | if (z & INDIRECT_SYMBOL_ABS) { 933 | continue; 934 | } 935 | if (z & INDIRECT_SYMBOL_LOCAL) { 936 | *(uint64_t *)((uintptr_t)sec[j].addr + k * stride) += *dest; 937 | continue; 938 | } 939 | INFO("indirect %d: 0x%lx = %s\n", z, s[z].n_value, (char *)buf + ksym->stroff + s[z].n_un.n_strx); 940 | *(uint64_t *)(sec[j].addr + k * stride) = s[z].n_value; 941 | } 942 | } 943 | } 944 | } 945 | q = q + cmd->cmdsize; 946 | } 947 | 948 | /* imported (should be solved already) */ 949 | 950 | if (kdys && kdys->nundefsym && ksym->symoff) { 951 | if (is64) { 952 | const struct nlist_64 *s = (struct nlist_64 *)(buf + ksym->symoff); 953 | for (k = 0; k < kdys->nundefsym; k++) { 954 | if (s[k + kdys->iundefsym].n_value == 0) { 955 | ERR("%s: unresolved symbol %s\n", filename, (char *)buf + ksym->stroff + s[k + kdys->iundefsym].n_un.n_strx); 956 | free(buf); 957 | return NULL; 958 | } 959 | } 960 | } else { 961 | const struct nlist *s = (struct nlist *)(buf + ksym->symoff); 962 | for (k = 0; k < kdys->nundefsym; k++) { 963 | if (s[k + kdys->iundefsym].n_value == 0) { 964 | ERR("%s: unresolved symbol %s\n", filename, (char *)buf + ksym->stroff + s[k + kdys->iundefsym].n_un.n_strx); 965 | free(buf); 966 | return NULL; 967 | } 968 | } 969 | } 970 | } 971 | 972 | /* exported */ 973 | 974 | if (kdys && kdys->nextdefsym && ksym->symoff) { 975 | if (is64) { 976 | const struct nlist_64 *s = (struct nlist_64 *)(buf + ksym->symoff); 977 | for (k = 0; k < kdys->nextdefsym; k++) { 978 | INFO("public(0x%lx) %s\n", s[k + kdys->iextdefsym].n_value, (char *)buf + ksym->stroff + s[k + kdys->iextdefsym].n_un.n_strx); 979 | if (!strcmp(UNDERSCORE(XSYMBOL), (char *)buf + ksym->stroff + s[k + kdys->iextdefsym].n_un.n_strx)) { 980 | the_ptr = s[k + kdys->iextdefsym].n_value; 981 | } 982 | } 983 | } else { 984 | const struct nlist *s = (struct nlist *)(buf + ksym->symoff); 985 | for (k = 0; k < kdys->nextdefsym; k++) { 986 | INFO("public(0x%x) %s\n", s[k + kdys->iextdefsym].n_value, (char *)buf + ksym->stroff + s[k + kdys->iextdefsym].n_un.n_strx); 987 | if (!strcmp(UNDERSCORE(XSYMBOL), (char *)buf + ksym->stroff + s[k + kdys->iextdefsym].n_un.n_strx)) { 988 | the_ptr = s[k + kdys->iextdefsym].n_value; 989 | } 990 | } 991 | } 992 | } 993 | 994 | if (kdys) { 995 | kdys->nlocrel = 0; /* XXX nuke relocs */ 996 | kdys->nextrel = 0; /* XXX nuke exts */ 997 | } 998 | 999 | rv = mprotect(buf, writable, PROT_READ | PROT_EXEC); 1000 | if (rv) { 1001 | ERR("%s: map error\n", filename); 1002 | free(buf); 1003 | return NULL; 1004 | } 1005 | 1006 | *sz = offset; 1007 | return buf; 1008 | } 1009 | 1010 | static const char * 1011 | build_path(void) 1012 | { 1013 | static char buf[4096]; 1014 | Dl_info info; 1015 | int rv = dladdr((void *)(uintptr_t)build_path, &info); 1016 | if (rv && info.dli_fname) { 1017 | size_t len; 1018 | const char *p = strrchr(info.dli_fname, '.'); 1019 | if (p && p > info.dli_fname) { 1020 | len = p - info.dli_fname; 1021 | } else { 1022 | len = strlen(info.dli_fname); 1023 | } 1024 | if (len + 1 + sizeof("dylib") > sizeof(buf)) { 1025 | return NULL; 1026 | } 1027 | memcpy(buf, info.dli_fname, len); 1028 | buf[len++] = '.'; 1029 | strcpy(buf + len, "dylib"); 1030 | return buf; 1031 | } 1032 | return NULL; 1033 | } 1034 | 1035 | void 1036 | initme(void) 1037 | { 1038 | const char *path; 1039 | uint8_t *buf; 1040 | uintptr_t dest = 0; 1041 | size_t sz = 0; 1042 | path = build_path(); 1043 | if (!path) { 1044 | return; 1045 | } 1046 | INFO("load: %s\n", path); 1047 | buf = load_kext(path, &dest, &sz); 1048 | if (!buf) { 1049 | num_dtors = 0; 1050 | return; 1051 | } 1052 | INFO("base: %p\n", (void *)buf); 1053 | while (num_ctors-- > 0) { 1054 | uintptr_t func = (uintptr_t)*ctors++; 1055 | INFO("ctor: 0x%zx\n", func); 1056 | ((void (*)())func)(); 1057 | } 1058 | if (the_ptr) { 1059 | memcpy(XSYMBOL, (void *)the_ptr, sizeof(XSYMBOL)); 1060 | } else { 1061 | ERR("symbol %s not found\n", UNDERSCORE(XSYMBOL)); 1062 | } 1063 | } 1064 | 1065 | void 1066 | finime(void) 1067 | { 1068 | // XXX actual destruction is done by __cxa_atexit 1069 | while (num_dtors-- > 0) { 1070 | uintptr_t func = (uintptr_t)*dtors++; 1071 | INFO("dtor: 0x%zx\n", func); 1072 | ((void (*)())func)(); 1073 | } 1074 | } 1075 | 1076 | #ifdef HAVE_MAIN 1077 | int 1078 | main(void) 1079 | { 1080 | initme(); 1081 | printf("%x\n", *XSYMBOL); 1082 | finime(); 1083 | return 0; 1084 | } 1085 | #endif 1086 | --------------------------------------------------------------------------------