/* Writes the current execution context to the specified file Author: illustrissimus To build with cmd.exe: > cd "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build" > vcvars64.bat > cd "C:\source" > cl.exe /nologo /D_WINDLL /Tp dll.cpp /link /DLL /out:dll.dll Advapi32.lib To run in PowerShell: PS> Add-Type -TypeDefinition @" using System; using System.Diagnostics; using System.Runtime.InteropServices; public static class Kernel32 { [DllImport("kernel32", SetLastError=true, CharSet=CharSet.Ansi)] public static extern IntPtr LoadLibrary( [MarshalAs(UnmanagedType.LPStr)]string lpFileName); } "@ PS> [Kernel32]::LoadLibrary('C:\source\dll.dll') */ #include #include #define FILENAME TEXT("C:\\Users\\Public\\PoC.txt") #define SEPARATOR TEXT("\n") /* Get the username or return NULL */ TCHAR* get_username() { DWORD buffer_len = 0; TCHAR* buffer = NULL; /* first time we fail on purpose to learn the required buffer size */ GetUserName(buffer, &buffer_len); if (buffer_len < 1 || GetLastError() != ERROR_INSUFFICIENT_BUFFER) return NULL; buffer = (TCHAR*)VirtualAlloc(NULL, buffer_len * sizeof(TCHAR), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); if (buffer == NULL) return NULL; if (!GetUserName(buffer, &buffer_len)) { VirtualFree(buffer, 0, MEM_RELEASE); return NULL; } return buffer; } /* Get the module name or return NULL */ TCHAR* get_modulename() { TCHAR* buffer = NULL; buffer = (TCHAR*)VirtualAlloc(NULL, MAX_PATH * sizeof(TCHAR), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); if (buffer == NULL) return NULL; if (!GetModuleFileName(NULL, buffer, MAX_PATH)) { VirtualFree(buffer, 0, MEM_RELEASE); return NULL; } return buffer; } void write_line(HANDLE file, TCHAR* str) { DWORD bytes_written; /* ignored */ WriteFile(file, str, (DWORD)(_tcslen(str) * sizeof(TCHAR)), &bytes_written, NULL); WriteFile(file, SEPARATOR, (DWORD)(_tcslen(SEPARATOR) * sizeof(TCHAR)), &bytes_written, NULL); } void entry() { HANDLE file; TCHAR* command_line = GetCommandLine(); /* lifetime managed by system */ RevertToSelf(); /* attempt is made, but the result ignored */ TCHAR* username = get_username(); if (username == NULL) return; TCHAR* modulename = get_modulename(); if (modulename == NULL) { VirtualFree(username, 0, MEM_RELEASE); return; } file = CreateFile(FILENAME, FILE_APPEND_DATA, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (file == INVALID_HANDLE_VALUE) { VirtualFree(username, 0, MEM_RELEASE); VirtualFree(modulename, 0, MEM_RELEASE); return; } write_line(file, command_line); write_line(file, username); write_line(file, modulename); CloseHandle(file); VirtualFree(username, 0, MEM_RELEASE); VirtualFree(modulename, 0, MEM_RELEASE); } #ifdef _WINDLL /* Entry point if DLL */ BOOL APIENTRY DllMain(HMODULE module, DWORD reason, LPVOID reserved) { switch (reason) { case DLL_PROCESS_ATTACH: entry(); break; case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; } #else /* Entry point if EXE */ int _tmain(int argc, TCHAR** argv) { entry(); return 0; } #endif