Files
tmpest127-enc_pic_str/README.md
T
2026-01-29 14:33:44 +04:00

1.9 KiB

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.