#ifndef FUNCCRYPT_H #define FUNCCRYPT_H 1 #include #include #if !defined(__GNUC__) || !defined(__GNUC_MINOR__) #error "This is only verified to work with a GCC compiler!" #endif /* Force GCC struct for MingW compilers and pack them, * which means the struct is 1-byte aligned. */ #define GCC_PACKED __attribute__((packed, gcc_struct)) typedef struct crypt_header { uint64_t key; uint8_t crpyted; uint32_t marker; uint64_t func_body[0]; } GCC_PACKED crypt_header; typedef enum crypt_return { CRET_ERROR /* Neither prologue marker nor epilogue marker found. */, CRET_PROLOGUE /* prologue marker found */, CRET_EPILOGUE /* epilogue marker found */, CRET_CHECK /* all pre (en|de)cryption checks successful */, CRET_OK /* (en|de)cryption succeeded */ } crypt_return; #define CRYPT_FUNC_MAXSIZ 0x100 #define CRYPT_FUNC(fn) \ crypt_func((void *)fn) #define CRYPT_PROLOGUE(fn) \ crypt_return __cr; \ { \ __cr = CRYPT_FUNC(fn); \ if (__cr != CRET_OK) \ asm volatile goto("jmp %l0 \n" \ : : : : cr_epilogue); \ asm volatile goto("jmp %l0 \n" \ : : : : cr_prologue); \ asm volatile( \ ".byte " \ /* key: */ "0x00, 0x00, 0x00, 0x00," \ "0x00, 0x00, 0x00, 0x00," \ /* crypted: */ "0x00," \ /* marker: */ "0xDE, 0xC0, 0xDE, 0xC0; \n" \ ); \ } \ cr_prologue: { #define CRYPT_EPILOGUE(fn) \ } { \ asm volatile goto("jmp %l0 \n" \ : : : : cr_epilogue); \ asm volatile( \ ".byte " \ /* Insert encryption pad, so we can find the end marker, * while the function body is encrypted. * (XOR 64 bit encryption == 8 byte) */ \ "0x00, 0x00, 0x00, 0x00," \ "0x00, 0x00, 0x00, 0x00," \ /* marker: */ "0xFE, 0xCA, 0xFE, 0xCA; \n" \ ); \ } \ cr_epilogue: \ CRYPT_FUNC(fn); #define CRYPT_FNDEF(name, ...) \ void name( __VA_ARGS__ ) { \ CRYPT_PROLOGUE( name ); #define CRYPT_FNEND(name) \ CRYPT_EPILOGUE(name); \ } extern const char *crypt_strs[]; extern void printHexBuf(uint8_t *buf, size_t siz, size_t chars_per_line); extern crypt_return crypt_func(void *fn_start); #endif