Open In App

shc Command in Linux

Last Updated : 21 Aug, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

SHC is a Shell Script Compiler (SHC) that directly converts the shell script into executable binaries. The main purpose of the shc is to protect the shell script against accidental changes, hide source code, and prevent future modifications. shc takes the shell script specified in the command line followed by the -f option and produces the source code of the script which is in C language format. The generated source code is then compiled and linked to produce an executable. The compiled binary is still dependent on the shell specified in the shebang line (i.e. #! /bin/sh). It won’t be able to create completely independent binaries.  In this article, we shall see about shc and the various command line options. 

Pre-requisite

shc command is not pre-installed but it can be downloaded from the repositories in most of the Linux distributions.

For Ubuntu/Debian:

sudo apt-get install shc

For CentOS/Fedora:

sudo yum install shc

For Red Hat (version > 8)

sudo dnf install shc

Commands & Options

Usage:

shc 
Help Section of Shc command

Help Section of Shc command

Script:

Let’s write a simple shell script for adding two numbers which would be used as an example in the upcoming sections,

#!/bin/bash
a=10
b=20
sum=$(($a + $b))
echo "Sum is $sum"

1. Create executable

Use the -f option, to mention the path of the shell script which needs to be converted into the executable. 

Syntax:

shc -f <script>

Example:

shc -f sum.sh

Once the script is compiled it produces 2 files, one is hello.sh.x.c which is in the C format of the script and the other one is hello.sh.x which is in the binary format. shc is not a compiler like GCC, rather it encodes, encrypts the shell script, and generates the source code in C language. shc then uses the compiler installed in the system to compile the source code to produce the binary which behaves exactly like the script. Using shc any kind of shell script can be compiled, provided valid options like -i, -x, and -l are supplied while compiling. Please refer to how to create binary from shell script for more detailed information.

Listing files

Listing files

sum.sh is the original shell script which is unencrypted.

file sum.sh
Cheking sum.sh is unencrypted or not

Checking sum.sh is unencrypted or not

sum.sh.x.c is the source code of the script in C format.

file sum.sh.c
Checking file format of sum.sh.x.c

Checking the file format of the sum.sh.x.c

sum.sh.x is the encrypted shell script in binary format.

file sum.sh.x
sum.sh.x is encrypted and is in binary format

sum.sh.x is encrypted and is in binary format

Let’s try to run the script along with binary,

Running script

Running script

Here, executing the script (bash sum.sh) and the binary (./sum.sh.x) both give the same output.

2. Name the executable

Use -o option, to name the executable.

Syntax:

shc -f <script> -o <executable_name>

Example:

shc -f sum.sh -o sum
Naming the executable

Naming the executable 

By default, shc name the executable as script_name.sh.x . If the user wants to give a different name for it, the -o option can be used while compiling the script. From the above screenshot, the executable got named a sum.

3. Set Expiration Date

Use the -e option to set an expiration date for the script.

Syntax:

shc -e <date> -f <script_name>

Example:

shc -e 11/2/2023 -f sum.sh
Seting expiration date

Seting expiration date

Here, the current date is Feb 12 and we have set the expiration date for the script on Feb 11th. If someone tries to execute the script after Feb 11th, they will get a default expiration message as “Please contact your provider”. This option provides more security to the binary shared among users.

4. Set a Custom Expiration Message

Use the -m option to customize the expiration message.

Syntax:

shc -e <date> -m <message> -f <script_name>

Example:

shc -e 11/2/2023 -m "Contact administrator for the latest version of the script" -f sum.sh
Setting a custom expiration message

Setting a custom expiration message

If the user wants to override the default custom message, the -m option can be used. Once the script is compiled with this option, upon expiry user can view the customized message set.

5. Distribute Binary

Use the -r option to create redistributable encrypted shell scripts.

Syntax:

shc -rf <script_name>

Example:

shc -rf sum.sh

Binaries are compiled for a specific computing environment and the binaries generated in one environment might not run properly in another environment. By default, the binaries created by shc cannot be distributed to another system i.e. when the binary is shared or copied to another server, it will not run properly.

Step 1: To understand this more, let’s create a binary using “shc -f sum.sh” and copy it to a remote server.

shc -f sum.sh
binary copied to remote server

binary copied to remote server

When the binary is executed in the remote server, it doesn’t run and gives some junk value.

./sum.sh.x
Executing binary

Executing binary

Step 2: Now create a redistributable binary using the following command.

shc -rf sum.sh
Creating redistributable binary

Creating redistributable binary

Now, running the redistributable binary gives the correct output in a remote server,

Running the binary file

Running the binary file

7. Disable Tracing

Use -U option, to compile an untraceable binary.

Syntax:

shc -Uf <script_name>

Example:

shc -Uf sum.sh

When the binary is created from shc, the user can trace it to find the system calls used. It can be traced by using strace, ptrace, and truss command line utilities. If the user doesn’t want to trace the binaries, then -U option can be used.

Tracing to find system calls

Tracing to find system calls

When the script is compiled with -U option and traced using the strace utility, the “operation not permitted error” is thrown (at the bottom of the screenshot).

8. Verbose Compilation

Use the -v option, to enable verbose.

Syntax:

shc -vf <script_name>

Example:

shc -vf sum.sh
Enabling Vebrbose output

Enabling Verbose output

Enabling verbose while compiling gives a more detailed picture of what is happening in the back end when the script is compiled. 

Conclusion

Thus, shc offers great protection for the script against accidental changes by converting them into highly specialized C source code and then translating them to binary. Along with it provides quite a few good handy options to set expiration dates, customize the expiration message, name the executable, create distributive binaries, etc.



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads