daisvke/woody-woodpacker

GitHub: daisvke/woody-woodpacker

Stars: 0 | Forks: 0

# **woody-woodpacker** ## **Table of Contents** * [Overview](#overview) * [Execution Flow](#execution-flow) * [Runtime Behavior](#runtime-behavior) * [ELF 64-bit File Structure](#elf-64-bit-file-structure) * [Injection Mechanism](#injection-mechanism) * [Stub Patch System](#stub-patch-system) * [Entry Point Redirection](#entry-point-redirection) * [Encryption System](#encryption-system) * [Commands](#commands) * [Debug Tools](#debug-tools) # **Overview** This project implements a **64-bit ELF packer with runtime unpacking capabilities**. It transforms an ELF binary into a new executable (`woody`) that embeds: * an encrypted copy of the original executable segment * a custom unpacking stub injected into the binary At runtime, the stub reconstructs the original program in memory and transfers execution back to it, preserving identical behavior while modifying only the binary representation. # **Execution Flow** Original ELF → Parse ELF headers & program headers → Locate executable PT_LOAD segment → Extract segment (includes .text region) → Encrypt payload (XOR + additive cipher) → Inject stub into executable segment region (padding or shifting mode) → Patch stub with metadata (offsets, sizes, key) → Modify ELF entry point (e_entry → stub) → Generate "woody" Runtime: → Kernel loads ELF → Execution starts in stub → Stub decrypts payload in memory → Restores original code → Prints: ....WOODY..... → Jumps to original entry point → Original program executes # **Runtime Behavior** At execution time, a packed `/bin/whoami` behaves as follows: ....WOODY..... username Except for the printed string, the final behavior remains strictly identical to the original binary. # **ELF 64-bit File Structure** +----------------------------------------------------+ | ELF Header | | (64 bytes, ELF64_Ehdr structure) | +----------------------------------------------------+ | Program Header Table | | (Variable size, ELF64_Phdr entries) | | describes memory-mapped segments | +----------------------------------------------------+ | Text Section | | (Executable code inside PT_LOAD segment) | +----------------------------------------------------+ | Data Section | | (Initialized data inside PT_LOAD segment) | +----------------------------------------------------+ | Symbol Table Section | | (ELF64_Sym entries) | +----------------------------------------------------+ | String Table Section | | ("name1\0name2\0...") | +----------------------------------------------------+ | Section Header Table (optional) | | (ELF64_Shdr entries) | +----------------------------------------------------+ # **Injection Mechanism** The stub is injected into the **executable PT_LOAD segment**, which typically contains: * `.text` * executable data pages * padding between segments It is not restricted to `.text` only, but placed inside the **executable memory-mapped region**. ## **1. Padding Injection (preferred mode)** Used when sufficient space exists inside the executable segment. Condition: sizeof_stub ≤ padding_size Where: padding_size = next_segment.p_offset - injection_offset Behavior: * stub is written directly into existing padding * no ELF relocation required * no structural modification of headers [ PT_LOAD (code + .text) | padding | STUB ] ## **2. Shifting Injection (fallback mode)** Used when padding is insufficient or explicitly required. ### Step 1 — Extend segment size p_filesz += sizeof_stub; p_memsz += sizeof_stub; ### Step 2 — Relocate ELF structures All headers after injection are updated: * program headers offsets shifted * section headers offsets shifted * ELF section header table offset updated ### Step 3 — Rebuild binary layout [ original ELF ] [ STUB inserted ] [ shifted ELF data ] # **Stub Patch System** The injected stub is patched with runtime metadata: ww_t_patch patch; This includes: * offset from stub to original entry point * `.text` section offset relative to stub * `.text` size * segment relocation offsets Layout inside binary: [ STUB ........ PATCH ........ KEY ] # **Entry Point Redirection** The ELF entry point is modified: e_entry = injection_addr; Result: Before: entry → main() After: entry → stub → main() # **Encryption System** ## XOR Cipher * symmetric encryption * same function used for encryption and decryption ## Additive Layer Applied before XOR: byte → +offset → XOR → encrypted encrypted → XOR → -offset → original # **Commands** ## Basic usage make # Build project ./woody_woodpacker [OPTIONS] # Make and run the packer with the default options, then run the packed binary, all with valgrind make run # Example: run the packer with verbose mode, padding injection mode, then run the binary ./woody_woodpacker /bin/ls -i=p -v && ./woody ## Options ### Verbose mode Displays detailed information about: * ELF parsing * injection offsets * padding analysis * relocation operations * stub patch values -v --verbose ### Injection mode: padding Attempts to inject stub into existing executable segment padding. -i=p --injection-type=padding * safest mode * no ELF restructuring * requires enough free space ### Injection mode: shift Forces structural modification of ELF when padding is insufficient or explicitly selected. -i=s --injection-type=shift * rewrites ELF layout * shifts headers and segments * guarantees injection success # **Debug tools** readelf -l [filename] # Check program headers of the file readelf -S [filename] # Check section headers hexdump -C [filename] # Check the file in hex format vimdiff [filename 1] [filename 2] # Check the difference between two files # Extract the .text section from code.o objcopy --dump-section .text=code-raw code.o # Print the loaded file content in hex format at address 0x401040 gdb ./woody run (or r) x/16xw 0x401040 # Add breakpoint at relative address 11ad if base address is 0x4011ad b *0x4011ad # Produce a trace trap that stops the execution at the position (useful when debugging) int3 # **Bonus ideas**
标签:客户端加密