/* * Restore original one from SHC obfuscated/compiled binary. * - bushi.csk@gmail * * $ gcc -Os -Wall -shared -fPIC -pthread -ldl -nostdlib -s -o unshc.so unshc.c * $ LD_PRELOAD=./unshc.so ./test.sh.x */ #define _GNU_SOURCE #include #include #include #include #include #include #pragma GCC visibility push(hidden) #define __init __attribute__((constructor)) #define __visible __attribute__((visibility("default"))) static void autolock_unlock(pthread_mutex_t **mutex) { pthread_mutex_unlock(*mutex); } #define __autounlock __attribute__((cleanup(autolock_unlock))) #define __name_autolock(_name) autolock_ ##_name #define AUTOLOCK_LOCK(_name) \ __autounlock pthread_mutex_t *l_##_name = &__name_autolock(_name); \ pthread_mutex_lock(l_##_name); #define H_SYM(_ret, _func, _arg...) \ static pthread_mutex_t __name_autolock(_func) = PTHREAD_MUTEX_INITIALIZER; \ static _ret (*org_ ##_func)(_arg); \ static void __init hook_ ##_func(void) \ { org_ ##_func = dlsym(RTLD_NEXT, #_func); } \ _ret __visible _func(_arg) #define H_ORG(_func) org_ ## _func /* against with shc-3.9.3 */ H_SYM(int, execvp, const char *f, char *const *arg) { AUTOLOCK_LOCK(execvp); if (3[arg] && !strcmp(3[arg], getenv("_")) && getenv("unshc")) { const char *p = 2[arg]; for (; ' ' == 0[p]; p++); write(fileno(stdout), p, strlen(p)); exit(1); } putenv("unshc="__FILE__); return H_ORG(execvp(f, arg)); }