# Encrypted PIC String ## Usage Run the obfuscator on a C file: ```bash enc_pic_str -i input.c -o output.c ``` It turns this: ```c puts(pic_str("Hello, World!")); ``` Into this: ```c puts(((const char *)(({ struct _str_struct_1 { char buf[14]; } _str_inst_1; unsigned char *_data_ptr; volatile unsigned long long _key_val; volatile unsigned long _len = 13; __asm__ volatile( "jmp skip_str_%=\n" "str_data_%=:\n" ".byte 0x9c, 0xc5, 0xc6, 0xef, 0xf5, 0x27, 0xe5, 0xbd, 0xbb, 0xd2, 0xc6, 0xe7, 0xbb\n" "str_key_%=:\n" ".quad 0xeac50b9a83aaa0d4\n" "skip_str_%=:\n" "lea str_data_%=(%%rip), %0\n" "movq str_key_%=(%%rip), %1\n" : "=r"(_data_ptr), "=r"(_key_val) : :); for (volatile unsigned long _i = 0; _i < _len; _i++) { volatile unsigned char _key_byte = (_key_val >> ((_i % 8) * 8)) & 0xFF; _str_inst_1.buf[_i] = _data_ptr[_i] ^ _key_byte; } _str_inst_1.buf[13] = 0; _str_inst_1; }).buf))); ``` This approach allows encrypted strings to be stored in the `.text` section and decoded at runtime. The method reasoning and other methods are described in the accompanying blog post: https://tmpest.dev/enc_pic_str.html Note that there are some cases where using the `pic_str` function may be unsafe. Please refer to `pic_str.h` in this repository for details and always conduct your own testing. For a good template for bare bones PIC/shellcode, see [`enc_pic_str/examples/04-advanced-peb`](examples/04-advanced-peb). ## Build ### Arch Linux ```bash sudo pacman -S go clang llvm lld mingw-w64-gcc make ``` ### Debian/Ubuntu ```bash sudo apt update sudo apt install golang clang llvm lld mingw-w64 make ``` After installing the dependencies, run `make` to build the project. Independent makefiles also exist in the example directory. ## Disclaimer This was vibe coded but method itself has been used and tested.