Generic Shell Script Compiler with Enhanced Security & Auditing
Empowering Developers โข Securing Shell Scripts โข Open Source Passion
Shc takes a script, which is specified on the command line, and produces C source code. The generated source code is then compiled and linked to produce a stripped binary executable.
Insight:
shcitself is not a compiler such ascc. It rather encodes and encrypts a shell script and generates C source code with an added expiration capability. It then uses the system compiler to compile a stripped binary which behaves exactly like the original script. Upon execution, the compiled binary will decrypt and execute the code with the shell-coption.
Note: The compiled binary will still be dependent on the shell specified in the first line of the shell code (i.e. shebang #!/bin/sh), thus shc does not create completely independent binaries.
First, clone the repository and ensure you have the necessary packages for compiling:
# Clone the repository
git clone https://github.com/alsyundawy/shc.git
cd shc
# Install dependencies
sudo apt-get update
sudo apt-get install build-essential automake autoconf libtool
Then, compile and install from the source:
./autogen.sh
./configure
make
sudo make install
(Note: If make fails due to automakeโs version, ensure you have run ./autogen.sh before running the commands.)
sudo apt-get install shc
sudo add-apt-repository ppa:alsyundawy/ppa
sudo apt-get update
sudo apt-get install shc
Prefer Pre-compiled Binaries? Download a compiled binary package from the Releases Page and copy the
shcbinary to/usr/binandshc.1to/usr/share/man/man1.
# General Usage
shc [options]
# Compile a script into a binary
shc -f script.sh -o binary
# Untraceable binary (prevents strace, ptrace, etc.)
shc -U -f script.sh -o binary
# Untraceable binary, no root required (only sh scripts, no parameters)
shc -H -f script.sh -o binary
-HThis flag is currently in an experimental state and may not work on all systems. This flag only works for the default shell. For example, if you compile a bash script with the -H flag, the resulting executable will only work on systems where the default shell is bash. You may change the default shell, which generally is /bin/sh (often a symlink to bash or dash).
โ ๏ธ Notice: -H does not work with positional parameters (yet).
To run the test suite, simply use:
./configure
make
make test
Temporary directories are generated in ${TMPDIR:-/tmp}/shc.SHELL.OPT.XXXXXX (caps are replaced according to the test). When a test succeeds, the directory is removed; if it fails, it is kept to help with debugging.
Clean up test outputs manually with:
rm -rf ${TMPDIR:-/tmp}/shc.*
_SC_ARG_MAX system configuration parameter limits the length of the arguments to the exec function. With standard options, this limits the maximum length of the runnable script of shc. However, you can now use the -P option which uses a pipe to circumvent this limitation.โ CHECK YOUR RESULTS CAREFULLY BEFORE USING โ
By HARRY DS ALSYUNDAWY - ALSYUNDAWY IT SOLUTION
tcsh and rc test failures in test/ttest.sh by updating csh/tcsh shell pattern matching and handling rc positional arguments for -p option.version_credits[] array in src/shc.c with tab indentation and joined split string literals in RTC[] array to eliminate compiler warnings.generate.yml workflow trigger typo (workflow_dispatch), autotools filter check, and added git diff check before git commit.pre-commit.yml workflow logToCheckStyle required out parameter and pythonLocation context reference..pre-commit-config.yaml to exclude config/ directory from beautysh/codespell, exclude test/ from cppcheck, and filter cpplint multiline comment/int warnings.pyproject.toml codespell ignore-words-list with domain words (ttest, indx, forceing) and added sscanf field width limits to test/scratch.c.upload-artifact path pattern (/tmp/shc.*/*) and added if-no-files-found: ignore to .github/workflows/ci.yml.mdeweerd/logToCheckStyle and dorny/paths-filter) to full commit SHAs to resolve CodeQL actions/unpinned-tag security alert.README.md badge section: added Ko-fi, QRIS, styled PayPal, GitHub sponsor badges, and replaced deprecated Travis CI badge with GitHub Actions CI badge.cppcheck notices in src/shc.c by adding const qualifiers to pointer parameters (eval_shell, read_script, prnt_bytes, prnt_array), renaming local opts variable, reducing cnt variable scope, removing redundant continue/assignment, and adding inline suppressions for RC4 indx loops.src/shc.c: added explicit (char *) / (char **) casts to malloc/realloc, declared file as const char *, fixed const pointer discarding in eval_shell, updated prnt_bytes to accept const void *, initialized struct argv_builder fields, and joined split string literals in RTC[].-Wall -Wextra -Wpedantic -Wshadow -Wconversion -Wunreachable-code -Wuninitialized -Wstrict-prototypes) and IDE diagnostics in src/shc.c: initialized expdate=0, removed unreachable break statements after exit(0), removed unreachable return 1 in main(), refactored eval_shell() to use line_len and matches with %zus specifiers, added explicit sign and float conversion casts in random generators (rand_mod, noise, prnt_array), and added cppcheck suppressions.Original Credit to @alsyundawy
4.0.9-Hardened-Audit-2026 across configure.ac, src/shc.c, README.md, and ChangeLog.-Wformat-nonliteral compiler warning in eval_shell() by wrapping sscanf() with #pragma GCC diagnostic push/ignored/pop guards.__attribute__((unused)) annotation to original_author struct declaration to fix -Wunused-const-variable compiler warning.version_credits[] array in src/shc.c to include email <alsyundawy@gmail.com> and website https://alsyundawy.com.License entry into version_credits[] array and aligned all field labels to 19 characters for perfect colon (:) alignment in shc -V output.Original Credit to @alsyundawy
-V and --version options in src/shc.c to print version and exit, keeping POSIX getopt(3) compatibility without getopt_long.shc -V and --version output to include original author, provider/maintainer, core collaborator, SHC contributors, repository URL, and audit hardening credit.-P/-p pipe runtime by replacing predictable /tmp FIFO names with mkdtemp(3)-backed private temporary directories.open(2), closed descriptors, unlinked FIFO, and removed private temp directory after pipe delivery.snprintf(NULL, 0, ...) allocation to prevent truncation.SKIP_OPTS parsing in test/ttest.sh so empty option is not skipped when SKIP_OPTS is unset.PATH_MAX fallback and feature macro guards for mkdtemp(3), putenv(3), setenv(3), and strict builds in src/shc.c.5.0.8-Hardened-Audit-2026 in configure.ac, src/shc.c, README.md, docs/CHANGELOG.md, docs/DOCNOTE.md.configure.ac.src/Makefile.am.README.md, docs/CHANGELOG.md, docs/DOCNOTE.md to match ChangeLog collaboration notes.Original Credit to @alsyundawy
-P/-p pipe mode by replacing predictable /tmp/%08x FIFO names with mkdtemp(3) private temporary directories.open(2), closed the descriptor, unlinked the FIFO, and removed the private temp directory.test/ttest.sh SKIP_OPTS logic so the default empty option is not skipped accidentally when SKIP_OPTS is unset.char cmd[256] pipe command formatting with dynamically sized snprintf(NULL, 0, ...) allocation to avoid silent truncation.PATH_MAX fallback for stricter compiler/libc compatibility.configure.ac and internal source version to 4.0.4-Hardened-Audit-2026.src/Makefile.am with -Wpedantic and -Wformat=2.Original Credit to @alsyundawy
fork() + execvp() argv vectors for compiler and strip paths.chmod command with chmod(2) to avoid shell expansion and command parsing exposure./tmp/shc_x_<pid>.c and /tmp/shc_x_<pid>.so generation from -H runtime.-H runtime buffer overflow in parent process-name reading with bounded fread() and explicit null termination.fread() error handling in script loader so read failures are not silently treated as EOF.CC, CFLAGS, LDFLAGS, and STRIP while preserving existing environment variable behavior.Makefile.am.-H execution path.ChangeLog and README.md change notes by adding entries in the existing project format only.Original Credit to @alsyundawy
ksh88, ksh93, mksh, pdksh, fish, nu, pwsh, powershell, yash, osh, elvish.#!/usr/bin/env wrapper interpretation with complex parameter chaining.sscanf truncated whitespace-separated shebang options (e.g., env -S bash -e).execvp wrappers causing abnormal behavior on env and sh variants.test/match.set -eu) across all POSIX payload testing scripts (test/match, test/pru.sh).set -Eeuo pipefail) & safe IFS parsing in test/ttest.sh.mktemp template vulnerabilities in test/ttest.sh to prevent predictable temp directories.test/ttest.sh.set -e) in autogen.sh.src/shc.c (removed unused headers, fixed array string missing comma, improved conditional statements).'4.0.3 (Hardened Audit Edition - 15 Jun 2026)'.configure.ac to version 4.0.3-Hardened-Audit-2026.shc.c causing sh: 1: %s: not found error during -H hardened compilation.SKIP_OPTS support to test/ttest.sh; set SKIP_OPTS=-H in CI sanitize job to skip -H tests that are fundamentally incompatible with ASAN LD_PRELOAD injection.Original Credit to @alsyundawy
-P, -p), with $0 forging (big scripts, perl, python) @fabio-brugnara.ash dependency @dviererbe #167-2 to use mmap2 @csersoft #132<> @learnpassword #148Original Credit to @mdeweerd
We welcome your open-source passion! If you want to make pull requests, please target the master branch. The default branch is release, which should contain clean package files ready to be used.
If you want to edit the manual, please edit the man.md file. The CI flow will automatically generate the other manual files from it.
You can also generate these locally with the following commands (requires pandoc):
pandoc -s man.md -t man -o shc.1
# Also run this command to generate the HTML manual
pandoc -s man.md -t html -o man.html
If you change anything related to autotools, ./autogen.sh should be run to regenerate the derived files. Again, the CI flow will generate these automatically.
(You may need to pull after a push because of the changes committed by CI.)
This project is a hardened and heavily audited iteration built upon the incredible foundational work of neurobin. Huge thanks to the original author and the contributors of the neurobin/shc repository.
Developed with โค๏ธ & Passion by Open Source Community