diff --git a/README.md b/README.md index 955616f..0d749d5 100644 --- a/README.md +++ b/README.md @@ -12,11 +12,11 @@ cc example.sh.c -O2 -o example The generated C code is ```example.sh.c```, which is the original file name followed by ```.c```. For programs used in production environments, it is recommended to add the parameter ```-s``` or use the ```strip``` command after compilation to remove the symbol table in the executable program, increasing the difficulty of disassembly and reverse engineering. -I have tried the tools ```shc``` and ```shellcrypt```, which can compile shell scripts into executable programs. The main problems are: -- The ```shc``` command actually calls the ```sh -c``` command. The source code can be seen through the ```ps -ef``` command. The length of the shell script cannot exceed ARG_ MAX . -- ```Shellcrypt``` does not support external parameter input, and the encryption algorithm is relatively simple. The generated executable program can be decrypted by XORing with ```0x000C``` to obtain the source code. +I have tried the tools ```shc```, which can compile shell scripts into executable programs. The main problems are: -In addition to solving the problems of the above two tools, ```shellc``` also adds code obfuscation, randomly generating effective character position calculation functions, random character encryption, and debugging to increase the complexity of disassembly and reverse engineering. +The ```shc``` command actually calls the ```sh -c``` command. The source code can be seen through the ```ps -ef``` command. The length of the shell script cannot exceed ARG_MAX . + +Shellc not only solves the problems that exist in ```shc```, ```shellc``` also adds code obfuscation, randomly generating effective character position calculation functions, random character encryption, and debugging to increase the complexity of disassembly and reverse engineering.If further difficulty is required, professional tools such as ```obfuscator-llvm``` can be used to further obfuscate the generated C code. Version 1.0 or above not only support shell, but also other scripting languages, which can completely replace ```shc```. At present, the program has practical applications in ```AIX```, ```UNIX```, ```Linux``` environments. It is recommended to conduct comprehensive testing on the compiled program to prevent production failures. @@ -76,6 +76,10 @@ macOS 13|lldb|NO ### History +- v1.02 2024-06-06 + + Removing macro definitions from generated code makes it easier for professional tools to generate more complex and confusing code + - v1.01 2024-06-02 Remove special handling of FreeBSD @@ -107,5 +111,4 @@ macOS 13|lldb|NO - v0.1 2023-12-01 Initial version - - + \ No newline at end of file diff --git a/shellc.c b/shellc.c index fed8313..9bf1948 100644 --- a/shellc.c +++ b/shellc.c @@ -5,7 +5,7 @@ * Author: ChenZhongChao * E-Mail: nbczc@163.com * Date: 2023-12-25 - * Version: 1.01 + * Version: 1.0 * Github: https://github.com/chenzhch/shellc.git * Gitee: https://gitee.com/chenzhch/shellc.git */ @@ -250,8 +250,27 @@ static const char *fourth_safe[] = { " fprintf(stderr, \"Error: Command %s not found\\n\", command);", " return(1);", " }", + " free(name);" " if (argc > 1) {", - " fputs(\"__shellc_main__() { \", pipe);", + " srand(time(0));", + " length = rand() % 9 + 16;", + " name = malloc((size_t) length);", + " memset(name, 0, length);", + " for (i = 0; i < length - 1; i++) {", + " switch(rand() % 3) {", + " case 0:", + " sprintf(name + i, \"%c\", rand() % 26 + 65);", + " break;", + " case 1:", + " sprintf(name + i, \"%c\", rand() % 26 + 97);", + " break;", + " default:", + " sprintf(name + i, \"%c\", 95);", + " break;", + " }", + " }", + " fputs(name, pipe);", + " fputs(\"() { \", pipe);", " }", 0 }; @@ -272,9 +291,8 @@ static const char *fifth[] = { " }", " args[j] = 0;", " if ((pid = fork()) == 0) {", - " write_script(file[1]);", - " close(file[1]);", " close(file[0]);", + " write_script(file[1]);", " return(0);", " } else if (pid < 0) {", " perror(\"Failed to fork\");", @@ -292,7 +310,10 @@ static const char *fifth[] = { static const char *fifth_safe[] = { " write_script(pipe);", " if (argc > 1) {", - " fputs(\" } ; __shellc_main__ \", pipe);", + " fputs(\" } ; \", pipe);", + " fputs(name, pipe);", + " free(name);", + " fputc(' ', pipe);", " }", " for(i = 1; i < argc; i++) {", " fputs(\" \\\"\", pipe);", @@ -581,7 +602,7 @@ int main(int argc, char **argv) } } if (input_flag != 1 || command_flag != 1 || fix_flag > 1 || trace_flag > 1 || safe_flag > 1) { - fprintf(stderr, "Usage1: %s command inputfile [-t] [-s] [-f fix-argv0]\n", argv[0]); + fprintf(stderr, "Usage: %s command inputfile [-t] [-s] [-f fix-argv0]\n", argv[0]); return(1); } @@ -728,19 +749,19 @@ int main(int argc, char **argv) fprintf(out, "#include \n"); } - /*Macro definitions are generated based on the calculation path*/ + /*Calculation path function*/ for (i = 0; i < 32; i++) { j = 0; while (route[i][j] != 0) { if(j == 0){ - fprintf(out, "#define F%d(a, b) (\\\n", i + 1); + fprintf(out, "long f%d(long a, long b) \n{\n return (\n", i + 1); } memset(str, 0, (size_t) sizeof(str)); macro(route[i][j], x[i][j], y[i][j], str); - fprintf(out, " %s%s\\\n", j == 0 ? " ":" +", str); + fprintf(out, " %s%s\n", j == 0 ? " ":" +", str); j++; } - fprintf(out, ")\n\n"); + fprintf(out, " );\n}\n\n"); } /*Character mask calculation function*/ @@ -748,23 +769,15 @@ int main(int argc, char **argv) j = 0; while (algorithm[i][j] != 0) { if(j == 0){ - fprintf(out, "#define F%d(a, b) labs(\\\n", 32 + i + 1); + fprintf(out, "long f%d(long a, long b) \n{\n return labs(\n", 32 + i + 1); } - fprintf(out, " %s(%s%c%s)\\\n", j == 0 ? " ":" +", number[i][j * 2], algorithm[i][j], number[i][j * 2 + 1]); + fprintf(out, " %s(%s%c%s)\n", j == 0 ? " ":" +", number[i][j * 2], algorithm[i][j], number[i][j * 2 + 1]); j++; } - fprintf(out, ")\n\n"); + fprintf(out, " );\n}\n\n"); } - - /*Generate a call function*/ - for (i = 0; i < 64; i++) { - fprintf(out, "long f%d(long a, long b)\n", i + 1); - fprintf(out, "{\n"); - fprintf(out, " return(F%d(a, b));\n", i + 1); - fprintf(out, "}\n\n"); - } - - fprintf(out, "static const char *command = \"%s\";\n", command); + + fprintf(out, "static const char *command = \"%s\";\n\n", command); /*Write to the data section*/ fprintf(out, "static const char *data[] = {\n"); diff --git "a/\350\257\264\346\230\216.md" "b/\350\257\264\346\230\216.md" index b86c57b..f54190d 100644 --- "a/\350\257\264\346\230\216.md" +++ "b/\350\257\264\346\230\216.md" @@ -12,11 +12,12 @@ cc example.sh.c -O2 -o example 生成的C代码是 ```example.sh.c```,即原始文件名后加```.c```。 对于生产环境中使用的程序,建议在编译时添加参数```-s```或编译后用```strip```命令, 以删除可执行程序中的符号表,增加了反汇编和逆向工程的难度。 -本人试用了可以将shell脚本编译成可执行程序的工具```shc``` 和 ```shellcrypt```,存在的主要问题是: -- ```shc``` 实际调用的是```sh -c``` 命令,通过```ps -ef``` 命令就能看到源码。shell脚本长度不能超过ARG_MAX值。 -- ```shellcrypt```不支持外部参数输入,加密算法相对简单。生成的可执行程序可以通过与```0x000C```进行异或解密来获得源代码。 +本人试用了可以将shell脚本编译成可执行程序的工具```shc```,存在的主要问题是: -shellc除了解决上述这两工具存在的问题外,还增加了代码混淆、随机生成有效字符位置计算函数、随机字符加密、反调试等增加反汇编逆向复杂度。 +```shc``` 实际调用的是```sh -c``` 命令,通过```ps -ef``` 命令就能看到源码。shell脚本长度不能超过ARG_MAX值。 + +shellc除了解决```shc```存在的问题外,还增加了代码混淆、随机生成有效字符位置计算函数、随机字符加密、反调试等增加反汇编逆向复杂度。 +如果需要进一步增加逆向难度,还可使用```obfuscator-llvm```等专业工具对生成后的C代码进一步进行混淆。 1.0及以上版本除了支持shell外,还支持其他脚本语言,可以完全替代```shc```。 目前,该程序已在```AIX```、```UNIX```、 ```Linux``` 环境中具有实际应用。建议对编译后的程序进行全面测试,以防止生产故障。 @@ -49,7 +50,7 @@ shellc除了解决上述这两工具存在的问题外,还增加了代码混 - 参数0修复 - 支持```BASH```、```FISH```、```ZSH```、```PERL```、```PYTHON```、```JAVASCRIPT```、```LUA```、```RUBY```修复。 + 支持```BASH```、 ```FISH```、```ZSH```、```PERL```、```PYTHON```、```JAVASCRIPT```、```LUA```、```RUBY```修复。 除了内置的修复类型,还可使用自定义文件修复。自定义文件格式:```?```表示参数0值,换行必须明确使用```\n```,双引号需加转义符```\```。参考```test/fix.txt```。 @@ -75,9 +76,13 @@ macOS 13|lldb|不支持 ### 修改记录 +- v1.02 2024-06-06 + + 删除生代码中的宏定义便于专业工具生成更复杂的混淆代码 + - v1.01 2024-06-02 - 删除FreeBSD特殊处理 + 删除对FreeBSD特殊处理 - v1.0 2024-06-01