vk-candpython/pyelfpacker
GitHub: vk-candpython/pyelfpacker
PyELFPacker 是一款用 Python 编写的 Linux ELF 二进制混淆打包器,通过压缩、加密、多态代码生成和无文件执行技术,将可执行文件转化为高度防护且难以分析的「幽灵」二进制。
Stars: 1 | Forks: 0
# 👾 pyelfpacker
[elf2 ...]
```
**示例:**
```
python3 pyelfpacker.py --obf --debug /bin/ls
```
**输出:**
```
(C) Vladislav Khudash, 2026
(P) GitHub: https://github.com/vk-candpython/pyelfpacker
(!) Only for x64 Linux
(Usage): python3 pyelfpacker.py [elf2 ...]
[ OK ]: architecture is valid (x86_64)
[ OK ]: using compiler(/usr/bin/gcc)
[ OK ]: using flag(OBFUSCATION)
[ OK ]: using flag(ANTI-DEBUG)
[ OK ]: make build dir(./_mk_pyelfpacker-...)
[ INFO ]: Start processing -> /bin/ls
[ INFO ]: building ELF(./pyelfpacker-ls)
[ INFO ]: compressing: {--------------------} 100% (DONE)
[ OK ]: compressed: (142144 -> 87514) bytes | saved: 54630 bytes (38.4%)
[ INFO ]: encrypting: {--------------------} 100% (DONE)
[ BUILD ]: file(./_mk_pyelfpacker-.../link.ld)
[ BUILD ]: file(./_mk_pyelfpacker-.../payload.bin)
[ BUILD ]: file(./_mk_pyelfpacker-.../loader.c)
[ BUILD ]: file(./_mk_pyelfpacker-.../elfstrip)
[ OK ]: compiled ................. (DONE)
[ OK ]: stripped ................. (DONE)
[ INFO ]: time ................. (2.15s)
[ OK ]: outfile(./pyelfpacker-ls, 88234 bytes)
[ OK ]: building completed ELF(./pyelfpacker-ls)
[ INFO ]: End processing -> /bin/ls
[ OK ]: cleanup build dir(./_mk_pyelfpacker-...)
```
## ⚙️ 深入技术分析
### SYSCALL 宏(一个通用宏)
一个统一的宏处理加载器中的每一个系统调用。每次展开都会注入 11 条随机垃圾语句(当启用 `--obf` 时)。系统调用通过 `call` 跳转到一个 trampoline 函数来实现,该函数在 `syscall` 指令前后均包含随机无效代码。根据 x86_64 ABI 的规定,会破坏 `rcx` 和 `r11` 寄存器。
### 系统调用 Trampoline
一个可见性为 `.hidden` 的专用静态函数包含实际的 `syscall` 指令,被随机无效 ASM 代码包围。这将所有系统调用集中在一个混淆的关卡中。
### RLE 解压缩(运行时)
解压缩器逐个字节处理加密的 payload。每个字节首先通过 `DEC` 宏解密,然后被解释为重复运行(设置 0x80 标志)或文字运行。输出以 4 KB 的块为单位写入密封的内存文件描述符。
### DEC 宏(解密单个字节)
加密函数的逆向操作:减去 `(y ^ 0xA5)`,向右旋转 3 位,与派生密钥和状态进行 XOR。状态 `g` 通过非线性反馈函数更新:`g = (b ^ ((y << 1) ^ (i >> 1))) & 0xFF`。
### ANTIDEBUG 宏
字符串 `/proc/self/status` 在二进制文件中是加密的。该宏在运行时将其解密,打开文件,并搜索混淆过的 `TracerPid:` 模式(每个字符都与不同的密钥进行 XOR)。返回 TracerPid 值:0 = 干净,>0 = 检测到调试器。所有缓冲区在返回前都会被安全地清零。
### 无文件执行
payload 被直接解密并解压到通过 `memfd_create` 创建的内存文件描述符中。随后该 fd 使用 `F_SEAL_ALL` 进行密封,以防止在通过 `execveat` 结合 `AT_EMPTY_PATH` 执行之前被修改。
### ZEROS 宏(安全擦除内存)
在反向(DF=1)使用 `rep stosq` 将敏感缓冲区清零。反向操作使内存取证恢复变得更加困难。
### 无效代码注入模式
在构建时,25 种以上的基础 ASM 模式与 10 个寄存器组合,生成了 150 多种独特的无效代码组合。此外,C 代码中也在每行有意义的代码之间穿插了随机语句。
### 构建器优化
| 优化 | 实现 |
|--------------|----------------|
| **Memoryviews** | 零拷贝切片,无中间分配 |
| **预分配缓冲区** | 精确计算 RLE 输出大小 |
| **MADV_SEQUENTIAL** | 提示内核进行顺序访问 |
| **分块 I/O** | 大文件使用 4 KB 分块 |
| **预编译 SSTRIP** | 作为 bytes 嵌入,每次会话只写入一次 |
| **单次压缩** | RLE 在一次过程中完成压缩 |
| **原地加密** | XOR 直接修改缓冲区 |
| **GC 控制** | `gc.disable()` + 手动 `gc.collect()` |
| **彩色输出缓存** | 记忆化的 ANSI 颜色代码 |
## 📁 输出
```
original_elf → pyelfpacker-original_elf
```
**输出二进制文件属性:**
- 剥离了所有符号和 section headers
- 在类似 `.rodata` 的 section 中包含加密的 payload
- 完全在内存中执行
- 不在磁盘上留下任何痕迹(二进制文件本身除外)
- 体积通常比原文件**小 30-60%**
## ⚠️ 要求
| 要求 | 版本 | 备注 |
|-------------|---------|-------|
| **Python** | 3.6+ | 构建器必需 |
| **MUSL-GCC** | 任意 | 推荐(输出体积更小) |
| **GCC** | 任意 | 备选 |
| **Linux Kernel** | 3.17+ | 用于 `memfd_create` |
| **Linux Kernel** | 3.19+ | 用于 `execveat` |
| **架构** | x86_64 | 仅限 64 位 |
## 🔧 故障排除
| 问题 | 解决方案 |
|-------|----------|
| `Cannot determine architecture` | 仅支持 x86_64 |
| `No suitable compiler found` | 安装 `musl-tools` 或 `gcc` |
| `compilation failed` | 检查编译器;如果 MUSL 失败,请尝试 GCC |
| `execveat: Function not implemented` | Kernel < 3.19 |
| `memfd_create: Function not implemented` Kernel < 3.17 |
| 混淆后的二进制文件发生段错误 | 原文件可能需要动态库 |
| `gdb` 仍然可以附加 | 使用 `PR_SET_PTRACER` + TracerPid |
| 二进制文件体积增加 | 对于非常小的二进制文件来说是正常的 |
| `--vm` 标志无效 | 反虚拟机是占位符(存根) |
# Русский
## 📋 概览
**PyELFPacker** — мощный инструмент для обфускации и упаковки ELF‑бинарников, превращающий стандартные исполняемые файлы Linux в сильно защищённые, саморасшифровывающиеся программы с бесфайловым выполнением. Написан на Python, использует кастомный C‑стаб, RLE‑сжатие, потоковый XOR‑шифр и встроенный `sstrip` для создания «призрачных» бинарников без заголовков секций.
### 是什么让它如此独特?
| Компонент | Реализация |
|-----------|------------|
| **Однопроходное RLE‑сжатие** | Побайтовое кодирование с флагом 0x80 – типичное сжатие 30–60% |
| **Потоковый XOR‑шифр** | Ключ 16–128 байт + соль + обратная связь – каждый байт зависит от предыдущих |
| **Полиморфный C‑стаб** | Случайные имена из 129‑символьного алфавита (латиница + кириллица + украинский) |
| **Впрыск мёртвого кода** | 150+ комбинаторных ASM‑паттернов + случайный мусор в C (включается через `--obf`) |
| **Встроенный SSTRIP** | Предскомпилированный бинарник `sstrip` встроен в Python‑скрипт – удаляет заголовки секций |
| **Полиглот‑сигнатуры** | 27 различных заголовков форматов файлов |
| **Бесфайловое выполнение** | `memfd_create` + `execveat` с `AT_EMPTY_PATH` – нулевой след на диске |
| **Анти‑отладка & Анти‑VM** | Проверка TracerPid, `PR_SET_PTRACER`, `PR_SET_DUMPABLE`, mlockall (анти‑VM заглушка) |
| **Защита памяти** | mlockall + F_SEAL_ALL – предотвращает свопинг и модификацию памяти |
| **Оптимизированный билдер** | Memoryviews, предварительно выделенные буферы, однопроходное сжатие, контроль GC |
## ✨ 功能特性
### 基础保护
| Возможность | Описание |
|-------------|----------|
| 🗜️ **RLE‑сжатие** | Побайтовое RLE с флагом 0x80, типичное сжатие 30–60% |
| 🔐 **Потоковый XOR‑шифр** | Соль + мутация ключа с обратной связью – нелинейное шифрование |
| 🎲 **Полиморфная заглушка** | Случайные имена из 129‑символьного алфавита (латиница + кириллица + украинский) |
| 📝 **Впрыск мёртвого ASM** | 25+ паттернов + комбинации с 10 регистрами = 150+ вариантов |
| 🔧 **Впрыск мёртвого C** | Случайный мусор в макросе SYSCALL, ANTIDEBUG и теле загрузчика |
### 编译和链接
| Возможность | Описание |
|-------------|----------|
| 🏗️ **Автовыбор MUSL/GCC** | Предпочитает MUSL (меньший размер), откат к GCC |
| 📦 **Кастомный линкер‑скрипт** | Случайный базовый адрес, сбрасывает все неиспользуемые секции |
| 🚫 **Флаги компилятора** | `-Os -static-pie -fomit-frame-pointer -fno-stack-protector -Wl,--strip-all` |
| 🧹 **SSTRIP** | Встроенный `sstrip` – полное удаление заголовков секций, ломает `objdump`, `readelf`, `gdb` |
### 运行时保护
| Возможность | Описание |
|-------------|----------|
| 💾 **Бесфайловое выполнение** | `memfd_create` → запись → seal → `execveat` с `AT_EMPTY_PATH` |
| 🛡️ **Анти‑отладка** | Парсинг `/proc/self/status` для `TracerPid` (строка зашифрована в бинарнике) |
| 🔒 **Блокировка PTRACE** | `prctl(PR_SET_PTRACER, 0)` – только потомки могут трассировать |
| 🚫 **Запрет новых привилегий** | `prctl(PR_SET_NO_NEW_PRIVS, 1)` |
| 📵 **Запрет core‑дампов** | `prctl(PR_SET_DUMPABLE, 0)` |
| 🔐 **Блокировка памяти** | `mlockall(MCL_ALL)` |
| 🔏 **Запечатанный memory FD** | `fcntl(F_ADD_SEALS, F_SEALS_ALL)` |
| 🛡️ **Анти‑VM** | Заглушка; может быть расширена (пока не реализована) |
## 🔒 完整的保护 pipeline
*(См. английскую версию для подробной диаграммы)*
## 🚀 快速开始
```
git clone https://github.com/vk-candpython/pyelfpacker.git
cd pyelfpacker
python3 pyelfpacker.py --obf --debug /bin/ls
./pyelfpacker-ls
```
## ⚙️ 深入的技术分析
### SYSCALL 宏(一个用于所有)
Единый унифицированный макрос обрабатывает каждый системный вызов в загрузчике. Каждое раскрытие впрыскивает 11 случайных мусорных инструкций (при включённом `--obf`). Системный вызов делается через `call` к функции‑трамплину, которая содержит случайный мёртвый код до и после инструкции `syscall`.
### RLE 解压(在运行时)
Распаковщик обрабатывает зашифрованные данные побайтово. Каждый байт сначала расшифровывается через макрос `DEC`, затем интерпретируется как повторяющаяся серия (флаг 0x80) или литеральная серия. Вывод пишется чанками по 4 КБ в запечатанный файловый дескриптор в памяти.
### DEC 宏(解密单个字节)
Обратная функция шифрования: вычитание `(y ^ 0xA5)`, поворот вправо на 3, XOR с производным ключом и состоянием. Состояние `g` обновляется нелинейной функцией с обратной связью: `g = (b ^ ((y << 1) ^ (i >> 1))) & 0xFF`.
### ANTIDEBUG 宏
Строка `/proc/self/status` зашифрована в бинарнике. Макрос расшифровывает её во время выполнения, открывает файл и ищет обфусцированный паттерн `TracerPid:` (каждый символ XOR с разными ключами). Возвращает значение TracerPid: 0 = чисто, >0 = обнаружен отладчик. Все буферы безопасно затираются перед возвратом.
### 无文件执行
Полезная нагрузка расшифровывается и распаковывается напрямую в файловый дескриптор в памяти, созданный через `memfd_create`. Затем fd запечатывается с `F_SEAL_ALL` для предотвращения любых модификаций перед выполнением через `execveat` с `AT_EMPTY_PATH`.
### ZEROS 宏(安全擦除内存)
Использует `rep stosq` в обратном направлении (DF=1) для затирания чувствительных буферов. Обратное направление усложняет восстановление memory forensics.
### builder 优化
| Оптимизация | Реализация |
|-------------|------------|
| **Memoryviews** | Zero‑copy слайсинг |
| **Предвыделенные буферы** | Точный расчёт размера для RLE |
| **MADV_SEQUENTIAL** | Подсказка ядру о последовательном доступе |
| **Чанковый I/O** | Блоки по 4 КБ для больших файлов |
| **Предскомпилированный SSTRIP** | Встроен как байты, записывается один раз |
| **Однопроходное сжатие** | RLE сжимает за один проход |
| **Шифрование на месте** | XOR модифицирует буфер напрямую |
| **Контроль GC** | `gc.disable()` + ручной `gc.collect()` |
| **Кеширование цветов** | Мемоизация ANSI‑кодов |
## 📁 结果
```
оригинальный_elf → pyelfpacker-оригинальный_elf
```
## ⚠️ 要求
| Требование | Версия | Примечания |
|------------|--------|------------|
| **Python** | 3.6+ | Для билдера |
| **MUSL-GCC** | Любая | Рекомендуется |
| **GCC** | Любая | Запасной |
| **Ядро Linux** | 3.17+ | Для `memfd_create` |
| **Ядро Linux** | 3.19+ | Для `execveat` |
| **Архитектура** | x86_64 | Только 64‑бит |
## 🔧 故障排除
| Проблема | Решение |
|----------|---------|
| `Cannot determine architecture` | Только x86_64 |
| `No suitable compiler found` | Установи `musl-tools` или `gcc` |
| `compilation failed` | Проверь компилятор |
| `execveat: Function not implemented` | Ядро < 3.19 |
| `memfd_create: Function not implemented` | Ядро < 3.17 |
| Обфусцированный бинарник падает | Оригинал может требовать динамические библиотеки |
| `gdb` всё ещё цепляется | Используй `PR_SET_PTRACER` + TracerPid |
| Размер бинарника увеличился | Нормально для очень маленьких бинарников |
| Флаг `--vm` не работает | Анти‑VM — заглушка (пока не реализована) |
[](https://www.linux.org/)
[](https://www.python.org/)
[](LICENSE)
*军用级 ELF 混淆 — 压缩、加密、多态、无文件执行*
## 📖 目录 | Оглавление
- [English](#english)
- [📋 概述](#-overview)
- [✨ 功能](#-features)
- [🔒 完整保护流水线](#-complete-protection-pipeline)
- [🚀 快速开始](#-quick-start)
- [⚙️ 深入技术分析](#️-deep-technical-analysis)
- [📁 输出](#-output)
- [⚠️ 要求](#️-requirements)
- [🔧 故障排除](#-troubleshooting)
- [Русский](#русский)
- [📋 Обзор](#-обзор)
- [✨ Возможности](#-возможности)
- [🔒 Полный конвейер защиты](#-полный-конвейер-защиты)
- [🚀 Быстрый старт](#-быстрый-старт)
- [⚙️ Глубокий технический анализ](#️-глубокий-технический-анализ)
- [📁 Результат](#-результат)
- [⚠️ Требования](#️-требования)
- [🔧 Устранение неполадок](#-устранение-неполадок)
# English
## 📋 概述
**PyELFPacker** — 是一款强大的 ELF 二进制文件混淆和打包工具,可将标准的 Linux 可执行文件转换为受严格保护且具备无文件执行能力的自解密二进制文件。它使用 Python 编写,利用自定义的 C stub、RLE 压缩、XOR 流密码和内置的 `sstrip` 来生成高度精简的“幽灵”二进制文件。
### 是什么让它如此独特?
| 组件 | 实现 |
|-----------|----------------|
| **单次 RLE 压缩** | 带 0x80 标志的字节级行程编码 —— 通常可减小 30-60% 的体积 |
| **XOR 流密码** | 16-128 字节密钥 + salt + 反馈机制 —— 每个字节都依赖于前一个状态 |
| **多态 C Stub** | 每次构建均从 129 字符的字母表(拉丁 + 西里尔 + 乌克兰语)中随机生成标识符名称 |
| **无效代码注入** | 150 多种组合 ASM 模式 + 随机 C 垃圾语句(通过 `--obf` 启用) |
| **内置 SSTRIP** | 预编译的 `sstrip` 二进制文件嵌入在 Python 脚本中 —— 移除 section headers |
| **Polyglot 特征** | 向链接器脚本中注入了 27 种不同的文件格式头 |
| **无文件执行** | `memfd_create` + `execveat` 结合 `AT_EMPTY_PATH` —— 零磁盘痕迹 |
| **反调试与反虚拟机** | TracerPid 检查、`PR_SET_PTRACER`、`PR_SET_DUMPABLE`、mlockall(反虚拟机为占位符) |
| **内存保护** | mlockall + F_SEAL_ALL —— 防止交换和内存修改 |
| **高度优化的构建器** | Memoryviews、预分配缓冲区、单次压缩、GC 控制 |
## ✨ 功能
### 核心保护
| 功能 | 描述 |
|---------|-------------|
| 🗜️ **RLE 压缩** | 带 0x80 重复标志的字节级 RLE,通常减小 30-60% |
| 🔐 **XOR 流密码** | Salt + 密钥变异及反馈 —— 非线性加密 |
| 🎲 **多态 Stub** | 从 129 字符的字母表(拉丁 + 西里尔 + 乌克兰语)中随机选取的函数/变量名 |
| 📝 **无效 ASM 注入** | 25 种以上的模式(nop、pause、clc、xor、lea、push/pop 等)+ 寄存器组合 |
| 🔧 **无效 C 代码注入** | 在 SYSCALL 宏、ANTIDEBUG 和加载器主体中注入随机垃圾语句 |
### 编译与链接
| 功能 | 描述 |
|---------|-------------|
| 🏗️ **MUSL/GCC 自动检测** | 优先使用 MUSL(输出体积更小),回退到 GCC |
| 📦 **自定义链接器脚本** | 随机基地址(0x400000 + random*0x1000),丢弃未使用的 section |
| 🚫 **编译器标志** | `-Os -static-pie -fomit-frame-pointer -fno-stack-protector -Wl,--strip-all` |
| 🧹 **SSTRIP** | 内置 `sstrip` —— 完全移除 section headers,破坏 `objdump`、`readelf`、`gdb` |
### 运行时保护
| 功能 | 描述 |
|---------|-------------|
| 💾 **无文件执行** | `memfd_create` → 写入 → seal → `execveat` 结合 `AT_EMPTY_PATH` |
| 🛡️ **反调试** | 解析 `/proc/self/status` 查找 `TracerPid`(二进制文件中的混淆字符串) |
| 🔒 **PTRACE 阻止** | `prctl(PR_SET_PTRACER, 0)` —— 仅允许子进程 ptrace |
| 🚫 **禁止新权限** | `prctl(PR_SET_NO_NEW_PRIVS, 1)` —— 防止 setuid 提权 |
| 📵 **禁止 Core Dumps** | `prctl(PR_SET_DUMPABLE, 0)` —— 阻止 gcore 和 coredumps |
| 🔐 **内存锁定** | `mlockall(MCL_ALL)` —— 防止交换到磁盘 |
| 🔏 **密封的内存 FD** | `fcntl(F_ADD_SEALS, F_SEALS_ALL)` —— 防止在 exec 前被修改 |
| 🛡️ **反虚拟机** | 占位符;可扩展(目前仅为存根) |
### Polyglot 特征(27 种格式)
| 特征 | 格式 |
|-----------|--------|
| `\x7FELF` | ELF (原生) |
| `MZ` + `PE` | Windows PE |
| `\x89PNG` | PNG 图像 |
| `%PDF` | PDF 文档 |
| `PK\x03\x04` | ZIP 归档 |
| `\x1F\x8B` | GZIP |
| `\xFD\x37\x7A\x58\x5A` | XZ/LZMA |
| `\x21\x3C\x61\x72\x63\x68\x3E` | AR 归档 |
| `\xCA\xFE\xBA\xBE` | Mach-O (32 位) |
| `\xCF\xFA\xED\xFE` | Mach-O (64 位) |
| `#!/bin/bash` | Shell 脚本 |
| `UPX!` | UPX 打包器 |
| `\xFF\xD8\xFF\xE0` | JPEG |
| `BM` | BMP |
| `ID3` | MP3 |
| `ftypisom` | MP4 |
| `SQLite format 3` | SQLite |
| `\xD0\xCF\x11\xE0` | MS Office |
| `\x00\x61\x73\x6D` | WebAssembly |
| `\xFE\xED\xFA\xCE` | Mach-O (32 位, 备用) |
| `\xBE\xBA\xFE\xCA` | Java Class |
| `\x99\x01` | DOS COM |
| `\x00\x01\x00\x00` | TrueType 字体 |
| `> 1))) & 0xFF
├── Operations: XOR → rotate left 3 → add (y ^ 0xA5)
└── /proc/self/status string also encrypted
PHASE 4: POLYMORPHIC LOADER GENERATION
├── Random identifiers: 4-254 chars, 129‑char alphabet
├── Obfuscated constants: XORed and shifted syscall numbers
├── Random dead code: 150+ ASM patterns, 11 junk per SYSCALL macro
└── Unique linker script: random base address + random polyglot signature
PHASE 5: C COMPILATION
├── Compiler: MUSL (preferred) or GCC
├── 20+ aggressive compiler flags for size and stealth
└── Custom linker script with discarded sections
PHASE 6: SSTRIP
├── Embedded pre‑compiled SSTRIP binary (~13 KB)
├── Truncates section header table
└── Result: "ghost" ELF — runs but has no visible sections
```
## 🚀 快速开始
### 📥 下载
```
git clone https://github.com/vk-candpython/pyelfpacker.git
cd pyelfpacker
```
### 📦 要求
```
# 安装 MUSL(推荐用于更小的输出)
sudo apt install musl-tools # Debian/Ubuntu
sudo pacman -S musl # Arch
# 或使用 GCC(自动检测)
sudo apt install gcc
```
### 🏃 用法
```
python3 pyelfpacker.py [--obf] [--debug] [--vm]
**[⬆ 返回顶部](#-pyelfpacker)**
*针对 Linux 的 ELF 混淆*
标签:ELF加壳, Raspberry Pi, 二进制混淆, 内存执行