{
	"id": "cfeb1cca-1f29-4025-be16-f1b476d3eb52",
	"created_at": "2026-04-06T03:37:05.011201Z",
	"updated_at": "2026-04-10T13:11:53.224108Z",
	"deleted_at": null,
	"sha1_hash": "94b3642e4e745ec1ae585c40835357111a98ee82",
	"title": "GitHub - TheWover/donut: Generates x86, x64, or AMD64+x86 position-independent shellcode that loads .NET Assemblies, PE files, and other Windows payloads from memory and runs them with parameters",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 218596,
	"plain_text": "GitHub - TheWover/donut: Generates x86, x64, or AMD64+x86\r\nposition-independent shellcode that loads .NET Assemblies, PE\r\nfiles, and other Windows payloads from memory and runs them\r\nwith parameters\r\nBy TheWover\r\nArchived: 2026-04-06 03:15:55 UTC\r\niissssuueess 3311 ooppeenn\r\n ccoonnttrriibbuuttoorrss 21 Stars 4.5k Forks 737 lliicceennssee BBSSDD--33--CCllaauussee chat ##ddoonnuutt\r\nddoowwnnllooaaddss 6 7 k\r\n Tweet\r\nCurrent version: v1.1\r\nTable of contents\r\n1. Introduction\r\n2. How It Works\r\n3. Building\r\n4. Usage\r\n5. Subprojects\r\n6. Developing with Donut\r\n7. Questions and Discussions\r\n8. Disclaimer\r\nhttps://github.com/TheWover/donut\r\nPage 1 of 8\n\n1. Introduction\r\nDonut is a position-independent code that enables in-memory execution of VBScript, JScript, EXE, DLL files and\r\ndotNET assemblies. A module created by Donut can either be staged from a HTTP server or embedded directly in\r\nthe loader itself. The module is optionally encrypted using the Chaskey block cipher and a 128-bit randomly\r\ngenerated key. After the file is loaded and executed in memory, the original reference is erased to deter memory\r\nscanners. The generator and loader support the following features:\r\nCompression of input files with aPLib and LZNT1, Xpress, Xpress Huffman via RtlCompressBuffer.\r\nUsing entropy for API hashes and generation of strings.\r\n128-bit symmetric encryption of files.\r\nOverwriting native PE headers.\r\nStoring native PEs in MEM_IMAGE memory.\r\nPatching Antimalware Scan Interface (AMSI) and Windows Lockdown Policy (WLDP).\r\nPatching Event Tracing for Windows (ETW).\r\nPatching command line for EXE files.\r\nPatching exit-related API to avoid termination of host process.\r\nMultiple output formats: C, Ruby, Python, PowerShell, Base64, C#, Hexadecimal, and UUID string.\r\nThere are dynamic and static libraries for both Linux and Windows that can be integrated into your own projects.\r\nThere's also a python module which you can read more about in Building and using the Python extension.\r\n2. How It Works\r\nDonut contains individual loaders for each supported file type. For dotNET EXE/DLL assemblies, Donut uses the\r\nUnmanaged CLR Hosting API to load the Common Language Runtime. Once the CLR is loaded into the host\r\nprocess, a new Application Domain is created to allow for running Assemblies in disposable AppDomains. When\r\nthe AppDomain is ready, the dotNET Assembly is loaded via the AppDomain.Load_3 method. Finally, the Entry\r\nPoint for EXEs or public method for DLLs specified by the user is invoked with any additional parameters. Refer\r\nto MSDN for documentation on the Unmanaged CLR Hosting API. For a standalone example of a CLR Host,\r\nrefer to code here.\r\nVBScript and JScript files are executed using the IActiveScript interface. There's also minimal support for some\r\nof the methods provided by the Windows Script Host (wscript/cscript). For a standalone example, refer to code\r\nhere. For a more detailed description, read: In-Memory Execution of JavaScript, VBScript, JScript and XSL\r\nUnmanaged or native EXE/DLL files are executed using a custom PE loader with support for Delayed Imports,\r\nTLS and patching the command line. Only files with relocation information are supported. Read In-Memory\r\nExecution of DLL for more information.\r\nThe loader can disable AMSI and WLDP to help evade detection of malicious files executed in-memory. For more\r\ninformation, read How Red Teams Bypass AMSI and WLDP for .NET Dynamic Code. It also supports\r\ndecompression of files in memory using aPLib or the RtlDecompressBuffer API. Read Data Compression for\r\nmore information.\r\nhttps://github.com/TheWover/donut\r\nPage 2 of 8\n\nAs of v1.0, ETW is also bypassed. Like with AMSI/WLDP, this a modular system that allows you to swap out the\r\ndefault bypass with your own. The default bypass is derived from research by XPN. Read Hiding your .NET -\r\nETW for more information.\r\nBy default, the loader will overwrite the PE headers of unmanaged PEs (from the base address to\r\n`IMAGE_OPTIONAL_HEADER.SizeOfHeaders`). If no decoy module is used (module overloading), then the\r\nPE headers will be zeroed. If a decoy module is used, the PE headers of the decoy module will be used to\r\noverwrite those of the payload module. This is to deter detection by comparing the PE headers of modules in\r\nmemory with the file backing them on disk. The user may request that all PE headers be preserved in their original\r\nstate. This is helpful for scenarios when the payload module needs to access its PE headers, such as when looking\r\nup embedded PE resources.\r\nFor a detailed walkthrough using the generator and how Donut affects tradecraft, read Donut - Injecting .NET\r\nAssemblies as Shellcode. For more information about the loader, read Loading .NET Assemblies From Memory.\r\nThose who wish to know more about the internals should refer to Developer notes.\r\n3. Building\r\nThere are two types of build. If you want to debug Donut, please refer to documentation here. If not, continue\r\nreading for the release build.\r\nClone\r\nFrom a Windows command prompt or Linux terminal, clone the repository.\r\n \r\n git clone http://github.com/thewover/donut.git\r\nThe next step depends on your operating system and what compiler you decide to use. Currently, the generator and\r\nloader template for Donut can be compiled successfully with both Microsoft Visual Studio 2019 and MingGW-64.\r\nTo use the libraries in your own C/C++ project, please refer to the examples provided here.\r\nWindows\r\nTo generate the loader template, dynamic library donut.dll, the static library donut.lib and the generator donut.exe.\r\nStart an x64 Microsoft Visual Studio Developer Command Prompt, change to the directory where you cloned the\r\nDonut repository and enter the following:\r\n nmake -f Makefile.msvc\r\nTo do the same, except using MinGW-64 on Windows or Linux, change to the directory where you cloned the\r\nDonut repository and enter the following:\r\nhttps://github.com/TheWover/donut\r\nPage 3 of 8\n\nmake -f Makefile.mingw\r\nLinux\r\nTo generate the dynamic library donut.so, the static library donut.a and the generator donut. Change to the\r\ndirectory where you cloned the Donut repository and simply type make.\r\nPython Module\r\nDonut can be installed and used as a Python module. To install from source requires pip for Python3. First, ensure\r\nolder versions of donut-shellcode are not installed by issuing the following command on Linux terminal or\r\nMicrosoft Visual Studio command prompt.\r\n pip3 uninstall donut-shellcode\r\nAfter you confirm older versions are no longer installed, issue the following command.\r\n pip3 install .\r\nYou may also install Donut as a Python module by grabbing it from the PyPi repository.\r\n pip3 install donut-shellcode\r\nFor more information, please refer to Building and using the Python extension.\r\nDocker\r\nBuilding the docker container.\r\n docker build -t donut .\r\nRunning donut.\r\n docker run -it --rm -v \"${PWD}:/workdir\" donut -h\r\nSupport Tools\r\nDonut includes several other executables that may be built separately. This include \"hash.exe\",\r\n\"encrypt.exe\",\"inject.exe\", and \"inject_local.exe\". The first two are used in shellcode generation. The latter two\r\nare provided to assist with testing donut shellcode. \"inject.exe\" will inject a raw binary file (loader.bin) into a\r\nprocess by its PID or process name. \"inject_local.exe\" will inject a raw binary file into its own process.\r\nhttps://github.com/TheWover/donut\r\nPage 4 of 8\n\nTo build these support executables separately you may use the MSVC makefile. For example, to build\r\n\"inject_local.exe\" to test your donut shellcode, you may run.\r\n nmake inject_local -f Makefile.msvc\r\nReleases\r\nTags have been provided for each release version of Donut that contain the compiled executables.\r\nv0.9.3, TBD\r\nv0.9.2, Bear Claw\r\nv0.9.1, Apple Fritter\r\nv0.9.0, Initial Release\r\nCurrently, there are two other generators available.\r\nC# generator by n1xbyte\r\nGo generator by awgh\r\n4. Usage\r\nThe following table lists switches supported by the command line version of the generator.\r\nSwitch Argument Description\r\n-a arch Target architecture for loader : 1=x86, 2=amd64, 3=x86+amd64(default).\r\n-b level\r\nBehavior for bypassing AMSI/WLDP : 1=None, 2=Abort on fail, 3=Continue on\r\nfail.(default)\r\n-k headers Preserve PE headers. 1=Overwrite (default), 2=Keep all\r\n-j decoy Optional path of decoy module for Module Overloading.\r\n-c class\r\nOptional class name. (required for .NET DLL) Can also include namespace: e.g\r\nnamespace.class\r\n-d name\r\nAppDomain name to create for .NET. If entropy is enabled, one will be generated\r\nrandomly.\r\n-e level\r\nEntropy level. 1=None, 2=Generate random names, 3=Generate random names +\r\nuse symmetric encryption (default)\r\n-f format\r\nThe output format of loader saved to file. 1=Binary (default), 2=Base64, 3=C,\r\n4=Ruby, 5=Python, 6=PowerShell, 7=C#, 8=Hexadecimal\r\n-m name Optional method or function for DLL. (a method is required for .NET DLL)\r\nhttps://github.com/TheWover/donut\r\nPage 5 of 8\n\n-n name Module name for HTTP staging. If entropy is enabled, one is generated randomly.\r\n-o path\r\nSpecifies where Donut should save the loader. Default is \"loader.bin\" in the current\r\ndirectory.\r\n-p parameters\r\nOptional parameters/command line inside quotations for DLL method/function or\r\nEXE.\r\n-r version CLR runtime version. MetaHeader used by default or v4.0.30319 if none available.\r\n-s server\r\nURL for the HTTP server that will host a Donut module. Credentials may be\r\nprovided in the following format:\r\nhttps://username:password@192.168.0.1/\r\n-t\r\nRun the entrypoint of an unmanaged/native EXE as a thread and wait for thread to\r\nend.\r\n-w\r\nCommand line is passed to unmanaged DLL function in UNICODE format. (default\r\nis ANSI)\r\n-x option\r\nDetermines how the loader should exit. 1=exit thread (default), 2=exit process,\r\n3=Do not exit or cleanup and block indefinitely\r\n-y addr\r\nCreates a new thread for the loader and continues execution at an address that is an\r\noffset relative to the host process's executable. The value provided is the offset. This\r\noption supports loaders that wish to resume execution of the host process after donut\r\ncompletes execution.\r\n-z engine\r\nPack/Compress the input file. 1=None, 2=aPLib, 3=LZNT1, 4=Xpress, 5=Xpress\r\nHuffman. Currently, the last three are only supported on Windows.\r\nPayload Requirements\r\nThere are some specific requirements that your payload must meet in order for Donut to successfully load it.\r\n.NET Assemblies\r\nThe entry point method must only take strings as arguments, or take no arguments.\r\nThe entry point method must be marked as public and static.\r\nThe class containing the entry point method must be marked as public.\r\nThe Assembly must NOT be a Mixed Assembly (contain both managed and native code).\r\nAs such, the Assembly must NOT contain any Unmanaged Exports.\r\nNative EXE/DLL\r\nhttps://github.com/TheWover/donut\r\nPage 6 of 8\n\nBinaries built with Cygwin are unsupported.\r\nCygwin executables use initialization routines that expect the host process to be running from disk. If executing\r\nfrom memory, the host process will likely crash.\r\nUnmanaged DLLs\r\nA user-specified entry point method must only take a string as an argument, or take no arguments. We have\r\nprovided an example.\r\n5. Subprojects\r\nThere are four companion projects provided with donut:\r\nTool Description\r\nDemoCreateProcess\r\nA sample .NET Assembly to use in testing. Takes two command-line parameters that\r\neach specify a program to execute.\r\nDonutTest\r\nA simple C# shellcode injector to use in testing donut. The shellcode must be base64\r\nencoded and copied in as a string.\r\nModuleMonitor\r\nA proof-of-concept tool that detects CLR injection as it is done by tools such as Donut\r\nand Cobalt Strike's execute-assembly.\r\nProcessManager\r\nA Process Discovery tool that offensive operators may use to determine what to inject\r\ninto and defensive operators may use to determine what is running, what properties\r\nthose processes have, and whether or not they have the CLR loaded.\r\n6. Developing with Donut\r\nYou may want to add support for more types of payloads, change our feature set, or integrate Donut into your\r\nexisting tooling. We have provided developer documentation. Additional features are left as exercises to the\r\nreader. Our suggestions:\r\nAdd environmental keying.\r\nMake Donut polymorphic by obfuscating the loader every time shellcode is generated.\r\nIntegrate Donut as a module into your favorite RAT/C2 Framework.\r\n7. Questions and Discussion\r\nIf you have any questions or comments about Donut. Join the #Donut channel in the BloodHound Gang Slack\r\n8. Disclaimer\r\nhttps://github.com/TheWover/donut\r\nPage 7 of 8\n\nWe are not responsible for any misuse of this software or technique. Donut is provided as a demonstration of CLR\r\nInjection and in-memory loading through shellcode in order to provide red teamers a way to emulate adversaries\r\nand defenders a frame of reference for building analytics and mitigations. This inevitably runs the risk of malware\r\nauthors and threat actors misusing it. However, we believe that the net benefit outweighs the risk. Hopefully that is\r\ncorrect. In the event EDR or AV products are capable of detecting Donut via signatures or behavioral patterns, we\r\nwill not update Donut to counter signatures or detection methods. To avoid being offended, please do not ask.\r\nSource: https://github.com/TheWover/donut\r\nhttps://github.com/TheWover/donut\r\nPage 8 of 8",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"MITRE"
	],
	"origins": [
		"web"
	],
	"references": [
		"https://github.com/TheWover/donut"
	],
	"report_names": [
		"donut"
	],
	"threat_actors": [],
	"ts_created_at": 1775446625,
	"ts_updated_at": 1775826713,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/94b3642e4e745ec1ae585c40835357111a98ee82.pdf",
		"text": "https://archive.orkl.eu/94b3642e4e745ec1ae585c40835357111a98ee82.txt",
		"img": "https://archive.orkl.eu/94b3642e4e745ec1ae585c40835357111a98ee82.jpg"
	}
}