> For the complete documentation index, see [llms.txt](https://malwaresourcecode.com/home/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://malwaresourcecode.com/home/my-projects/proof-of-concepts/nonamed-mutation-engine.md).

# NoNamed Mutation Engine

Previously on social media I discussed my work on a Polymorphic Mutation Engine, my implementation of it (known as encryption-based Polymorphism), and the general traits and features my code base possesses. This write-up will be a technical explanation of my code. It assumes you're familiar with some of the information present.

***

### Dependencies and compilation&#x20;

NoNamed contains no dependencies, omit NTDLL which is a requirement for binaries to work on Windows. NoNamed does load OLE32.DLL and VBSCRIPT.DLL for a brief moment to initialize COM components for the VBS payload demonstration. Everything else is manually reconstructed and built into the binary. This is not necessary for a proof-of-concept, but I enjoy the challenge. Sorry.

<table><thead><tr><th width="150">Library</th><th width="264">Function</th><th>Custom Implementation</th></tr></thead><tbody><tr><td>ucrtbase.dll</td><td>memset (ZeroMemory)</td><td>ZeroMemory2</td></tr><tr><td>ucrtbase.dll</td><td>wcslen</td><td>StringLengthW</td></tr><tr><td>ucrtbase.dll</td><td>strcmp</td><td>StringCompareA</td></tr><tr><td>kernel32.dll</td><td>CopyMemory</td><td>CopyMemoryEx</td></tr><tr><td>ucrtbase.dll</td><td>wcscat</td><td>StringConcatW</td></tr><tr><td>ucrtbase.dll</td><td>wcscopy</td><td>StringCopyW</td></tr><tr><td>kernel32.dll</td><td>MultiByteToWideChar</td><td>CharStringToWCharString</td></tr><tr><td>ucrtbase.dll</td><td>itoa</td><td>Uint32ToWcharString</td></tr><tr><td>ole32.dll</td><td>CoCreateInstance</td><td>RtlCreateVbsEngine</td></tr><tr><td>ucrtbase.dll</td><td>memcmp</td><td>MemoryCompare</td></tr><tr><td>ucrtbase.dll</td><td>rand</td><td>GetRandomIntegerKsecDDObject</td></tr><tr><td>kernel32.dll</td><td>GetProcAddress</td><td>ImportFunction</td></tr><tr><td>bcrypt.dll</td><td>BCryptOpenAlgorithmProvider</td><td>ChaChaInitializeContext</td></tr><tr><td>bcrypt.dll</td><td>BCryptBuffer</td><td>ChaChaBuffer</td></tr></tbody></table>

NoNamed mutates the .psdata section of the binary. Hence, it is specified to the compiler in the IDE for the creation of .psdata. The initial build of .psdata is the raw byes of a simple VBS script.

```
#pragma comment(linker, "/SECTION:.psdata,RW")
#pragma comment(linker, "/INCLUDE:PsObject")
#pragma section(".psdata", read)

extern "C" __declspec(allocate(".psdata"))
BYTE PsObject[] =
{
    0x4D, 0x73, 0x67, 0x42, 0x6F, 0x78, 0x20, 0x22,
    0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x66, 0x72,
    0x6F, 0x6D, 0x20, 0x69, 0x6E, 0x20, 0x2D, 0x20,
    0x6D, 0x65, 0x6D, 0x6F, 0x72, 0x79, 0x20, 0x56,
    0x42, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x22,
    0x00
};//MsgBox "Hello from in - memory VBScript"
```

Additionally, to avoid the creation of a UI and a console Window, the subsystem to set to Windows, no default libraries are specified, and the entry point is modified to ensure the compiler doesn't insert security features which would introduce bloat to our application. Yes, this is generally dangerous. This is not best practices for general software develop. This is initially stripped to ensure the binary is as minimal as possible.

```
#pragma comment(linker, "/SUBSYSTEM:WINDOWS")
#pragma comment(linker, "/NODEFAULTLIB")
#pragma comment(linker, "/ENTRY:EntryPoint")
```

### NoNamed flow overview

```
+---------+
|  Start  |
+---------+
     |
     v
+----------------------------------+
| InitializeApiTable               |
| (resolve NT APIs)                |
|                                  |
| NtAllocateVirtualMemory          |
| NtFreeVirtualMemory              |
| NtClose                          |
| NtOpenFile                       |
| NtDeviceIoControlFile            |
| NtFsControlFile                  |
| NtWaitForSingleObject            |
| NtQueryInformationFile           |
| NtReadFile                       |
| NtCreateFile                     |
| NtSetInformationFile             |
| NtWriteFile                      |
| LdrLoadDll                       |
| LdrUnloadDll                     |
+----------------------------------+
     |
     v
+----------------------------------+
| InitializeMemoryManagementSystem |
+----------------------------------+
     |
     v
+----------------------------------+
| ChaChaInitializeContext          |
+----------------------------------+
     |
     v
+---------------------------------------------------+
| InitializeSelfObject                              |
|                                                   |
| - Get own file path                               |
| - Get NTFS File ID                                |
| - Read self into memory                           |
| - Generate random number via \Device\KsecDD       |
+---------------------------------------------------+
     |
     v
+----------------------------------+
| Read .psdata section             |
+----------------------------------+
     |
     v
+--------------------------------------------------+
| Fnv1a64(.psdata) == 0xAB34B590F66696C1 ?         |
+--------------------------------------------------+
        | YES (first stage)           | NO (second stage)
        v                             v
+---------------------------+   +---------------------------+
| Mutate executable         |   | Mutate executable         |
|                           |   |                           |
| Self delete               |   | Execute VBS from .psdata  |
|                           |   |                           |
|                           |   | Self delete               |
+---------------------------+   +---------------------------+
        |                             |
        +-------------+---------------+
                      |
                      v
                 +---------+
                 |  End    |
                 +---------+
```

### **InitializeApiTable** and **InitializeMemoryManagementSystem**:

Initialize API Table is fairly self-explanatory. NoNamed contains a structure of various NTDLL functionality required for this binary to operate. When the binary begins it programmatically walks the in-memory NTDLL Export Address Table and retrieves a pointer to any functionality required. A flaw in this implementation is it does not verify the first FLINK is NTDLL. In the instance it is replaced with an EDR and/or AV instance (hooking) it will fail. This does not perform indirect or direct SYSCALLs.

The API table contains a general usage variable (DWORD) at the base of the API table which is reserved for general usage (acting like RAX, omit it does not handle returns). To ensure all APIs were successfully loaded it verifies the pointers are valid by storing them in a temporary "VerificationTable" and iterates through them with an initial offset of size DWORD to skip past the GeneralUsage variable. GeneralUsage was intentionally placed at the base of the API table for this reason.

Note RtlAllocateHeap is not present. All memory is handled with a custom memory management system using NtAllocateVirtualMemory. I am in essence using an elementary heap manager. I am using the [Arena algorithm](https://github.com/tsoding/arena). The primary difference is my implementation is stripped to the metaphorical bone because it does not require much heap usage. If you're curious [read more here](https://medium.com/@sgn00/high-performance-memory-management-arena-allocators-c685c81ee338).

### **ChaChaInitializeContext**:

ChaChaInitializeContext is a manual implementation of the ChaCha encryption algorithm. I am not a cryptographer. Nothing in this is extraordinarily novel. I manually introduced it into my code base to avoid external dependencies.
