Skip to content

litemars/hARMless

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

47 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ›‘οΈ hARMless

License Platform Build Stars

An ARM64 ELF Packer/Loader for AArch64 Linux Binaries

A comprehensive security research tool that encrypts ARM64 ELF executables using multi-layer encryption and provides runtime in-memory execution without writing the original binary to disk.


Features

  • ARM64 ELF Support: Specifically designed for AArch64 Linux binaries
  • Multi-Layer Encryption: Triple encryption using AES-256, ChaCha20, and RC4
  • Memory Execution: Runtime decryption and execution entirely in memory using memfd_create
  • Code Obfuscation: Advanced obfuscation techniques for anti-analysis
  • CRC32 Verification: Integrity checking to detect tampering
  • Self-Contained: Packed binaries are completely standalone
  • Core Dump Prevention: Prevents memory dumps using setrlimit
  • Secure Memory Wiping: Multi-pass memory erasure for sensitive data
  • Direct Syscalls: Bypasses userland hooks for enhanced stealth
  • Polymorphic Loader: Every packed binary is bytewise unique β€” randomized magic, filler, padding, and symbol table scrubbing at stub-generation time

πŸš€ Quick Start

# Clone the repository
git clone https://github.com/litemars/hARMless.git
cd hARMless

# Build everything
make all

# Pack a binary
make pack INPUT=/bin/ls OUTPUT=packed_ls

# Run the packed binary
./packed_ls

πŸ“¦ Installation

Prerequisites

  • ARM64/AArch64 Linux system or cross-compilation toolchain
  • GCC for ARM64 (aarch64-linux-gnu-gcc or native)
  • Make
  • OpenSSL (libssl-dev) β€” required for AES-256 and ChaCha20 via the EVP API
  • Standard development tools (git, build-essential)

Build Steps

# 1. Clone the repository
git clone https://github.com/litemars/hARMless.git
cd hARMless

# 2. Build all components
make all

# This creates:
# - build/packer    : Binary packer
# - build/loader    : Stub loader
# - build/stubgen   : Stub generator

Cross-Compilation (x86_64 β†’ ARM64)

# Install ARM64 cross-compiler and OpenSSL
sudo apt-get install gcc-aarch64-linux-gnu libssl-dev

# Build with cross-compiler
make CC=aarch64-linux-gnu-gcc all

πŸ“– Usage

Basic Packing

# Pack an ARM64 binary
make pack INPUT=your_arm64_binary OUTPUT=packed_binary

# Alternative: Use tools directly
./build/packer your_arm64_binary packed_data
./build/stubgen ./build/loader packed_data packed_binary

Running Packed Binaries

# Simply execute the packed binary
./packed_binary

# The packed binary will:
# 1. Run anti-debug and anti-sandbox checks
# 2. Read its own embedded encrypted data
# 3. Decrypt the original ELF in memory
# 4. Verify integrity with CRC32
# 5. Create a masqueraded memfd and write the ELF into it
# 6. Delete itself from disk (unlink)
# 7. Execute directly from memory via /proc/self/fd/<memfd>

Test

# Testing using /bin/ls

make test
# Output: packed_binary: packed_ls

Technical Details

Encryption Pipeline

The packer uses a triple-layer encryption approach:

  1. AES-256-ECB: First encryption pass (OpenSSL EVP)
  2. ChaCha20: Modern stream cipher for additional security (OpenSSL EVP)
  3. RC4 Stream Cipher: Final obfuscation layer
Original Binary β†’ AES-256 β†’ ChaCha20 β†’ RC4 β†’ Packed Data

Key Generation: Cryptographically secure random keys from /dev/urandom (256 bits per layer)

In-Memory Write Paths

Three selectable methods for writing the decrypted ELF into the memfd (chosen at compile time):

Method Flag Kernel Requirement
io_uring (default) -DCOPY_WITH_IO_URING β‰₯ 5.1
mmap -DCOPY_WITH_MMAP Any
write(2) (neither flag) Any

Polymorphic Engine

Every invocation of stubgen produces a bytewise-unique packed binary, even when packing the same input:

Mutation Mechanism
Random magic 32-bit g_packed_magic patched to a fresh value from /dev/urandom; packed header is synchronized
Random filler 256-byte g_pack_polymorph array in .data overwritten with random bytes
Random padding 0–4095 bytes of random junk inserted between loader stub and payload
SC table re-keying hARMless_sc[] re-encoded with a fresh random g_sc_xor_key so syscall numbers differ in every binary
String block re-keying All 241 obfuscated string bytes in g_obf_str_block re-encoded with a fresh random g_str_xor_key
Header OTP blinding Pack header body (140 bytes) XOR'd with the first 140 bytes of g_pack_polymorph as a one-time pad
Symbol scrub .symtab/.strtab sections overwritten with random data; ELF section header fields zeroed

The result: no two packed outputs share the same byte pattern, defeating static hash-based signatures.

XOR-Obfuscated Syscall Table

Syscall numbers are stored in a volatile array (hARMless_sc[]) XOR-encoded with the key 0xDEADBEEF at compile time. At stub-generation time, stubgen re-encodes the entire table with a fresh random key written into g_sc_xor_key, so syscall numbers differ in every packed binary. They are decoded inline at each call site via hARMless_sc[i] ^ g_sc_xor_key, preventing static analysis tools from recovering syscall identifiers.

XOR-Obfuscated String Block

All anti-debug and process-masquerade strings (tool names, hypervisor signatures, env var names, process titles) are stored in a single contiguous g_obf_str_block[] array, XOR-encoded with g_str_xor_key. At stub-generation time, stubgen re-encodes the entire block with a fresh random byte key, making every binary's string patterns unique and independent of one another.

Memory Safety

  • Secure Wiping: 3-pass overwrite (zeros, ones, random) with volatile access to prevent compiler optimization
  • No Disk Writes: Original binary never touches filesystem
  • Self-Deletion: Loader calls unlink() on itself before executing the payload
  • ASLR Compatible: Position-independent code; random address slot reserved via mmap(NULL) before execution

Security Features

Core Dump Prevention

setrlimit(RLIMIT_CORE, &(struct rlimit){0, 0});

Ensures sensitive memory is never written to disk, even during crashes.

Integrity Verification

CRC32 checksums detect any tampering with:

  • Encrypted payload
  • Decryption keys
  • Loader code

Anti-Analysis

  • No debug symbols: Stripped binaries; section header table zeroed at stub-generation time
  • Obfuscated control flow: Reduces reverse engineering surface
  • Obfuscated syscall numbers: Stored XOR'd with 0xDEADBEEF, decoded at each call site
  • Direct syscalls: Evades LD_PRELOAD and EDR hooks
  • Noise delays: CPU-bound xorshift loops seeded from the ASLR stack address; cannot be skipped by sandbox time-acceleration and emit no recognizable timing syscall
  • Process context probes: getpid, getppid, and prctl(PR_GET_NAME) woven between critical operations; results used in a runtime condition to avoid trivial dead-code elimination by an analyst
  • In-memory execution: No /tmp artifacts

Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    Original Binary                      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                     β”‚
                     β–Ό
         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
         β”‚   Packer (packer.c)   β”‚
         β”‚  - Read ELF           β”‚
         β”‚  - Generate keys      β”‚
         β”‚  - Triple encrypt     β”‚
         β”‚  - Compute CRC32      β”‚
         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                     β”‚
                     β–Ό
         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
         β”‚  Packed Data File     β”‚
         β”‚  [encrypted payload]  β”‚
         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                     β”‚
                     β–Ό
         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
         β”‚ Stub Generator        β”‚
         β”‚ (stubgen.c)           β”‚
         β”‚  - Patch magic/filler β”‚
         β”‚  - Scrub symbols      β”‚
         β”‚  - Insert padding     β”‚
         β”‚  - Append payload     β”‚
         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                     β”‚
                     β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚              Packed Binary (Output)                    β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”‚
β”‚  β”‚ Loader Stub (loader.c)                       β”‚      β”‚
β”‚  β”‚  - Anti-debug / anti-sandbox checks          β”‚      β”‚
β”‚  β”‚  - Decrypt (RC4 β†’ ChaCha20 β†’ AES-256)        β”‚      β”‚
β”‚  β”‚  - Verify CRC32                              β”‚      β”‚
β”‚  β”‚  - Create masqueraded memfd                  β”‚      β”‚
β”‚  β”‚  - Unlink self                               β”‚      β”‚
β”‚  β”‚  - Execute via /proc/self/fd/<N>             β”‚      β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜      β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”‚
β”‚  β”‚ [random padding] Encrypted Payload + Header  β”‚      β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                     β”‚
                     β–Ό
         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
         β”‚   Runtime Execution   β”‚
         β”‚  (in-memory only)     β”‚
         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

🀝 Contributing

Contributions are welcome! Please see CONTRIBUTING.md for guidelines.


⚠️ Legal Notice: This tool is intended for:

  • Authorized penetration testing
  • Security research and education
  • Red team operations
  • Malware analysis

Unauthorized use is prohibited and may be illegal.


πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.