mirror of
https://github.com/tmpest127/enc_pic_str
synced 2026-06-08 17:51:05 +00:00
main
Encrypted PIC String
Usage
Run the obfuscator on a C file:
enc_pic_str -i input.c -o output.c
It turns this:
puts(pic_str("Hello, World!"));
Into this:
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.
Build
Arch Linux
sudo pacman -S go clang llvm lld mingw-w64-gcc make
Debian/Ubuntu
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.
Languages
Go
71.6%
C
17.4%
Makefile
11%