├── screenshots ├── 1.gif ├── 1.png ├── 2.gif └── 2.png ├── .idea ├── .gitignore ├── modules.xml ├── vcs.xml └── Shellcodev.iml ├── Shellcodev ├── read.cpp ├── main.cpp ├── loop.cpp ├── inject.cpp ├── str.cpp ├── str.h ├── repl.h ├── Shellcodev.vcxproj.filters ├── init.cpp ├── Shellcodev.vcxproj ├── print.cpp ├── eval.cpp ├── command.cpp └── color.hpp ├── license ├── .gitattributes ├── README.md ├── Shellcodev.sln └── .gitignore /screenshots/1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XaFF-XaFF/Shellcodev/HEAD/screenshots/1.gif -------------------------------------------------------------------------------- /screenshots/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XaFF-XaFF/Shellcodev/HEAD/screenshots/1.png -------------------------------------------------------------------------------- /screenshots/2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XaFF-XaFF/Shellcodev/HEAD/screenshots/2.gif -------------------------------------------------------------------------------- /screenshots/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XaFF-XaFF/Shellcodev/HEAD/screenshots/2.png -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Editor-based HTTP Client requests 5 | /httpRequests/ 6 | # Datasource local storage ignored files 7 | /dataSources/ 8 | /dataSources.local.xml 9 | -------------------------------------------------------------------------------- /Shellcodev/read.cpp: -------------------------------------------------------------------------------- 1 | #include "repl.h" 2 | 3 | 4 | std::string shelldev_read() 5 | { 6 | std::string command; 7 | 8 | std::cout << ">>> "; 9 | std::getline(std::cin, command); 10 | 11 | trim(command); 12 | 13 | return command; 14 | } -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/Shellcodev.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Shellcodev/main.cpp: -------------------------------------------------------------------------------- 1 | #include "repl.h" 2 | 3 | static shell_t sh = { 0 }; 4 | 5 | BOOL CALLBACK winrepl_exit(DWORD dwCtrlCode) 6 | { 7 | DebugActiveProcessStop(sh.procInfo.dwProcessId); 8 | ExitProcess(0); 9 | } 10 | 11 | int main(int argc, char *argv[]) 12 | { 13 | SetConsoleCtrlHandler(winrepl_exit, TRUE); 14 | 15 | std::cout << "Shellcodev v2.2 by XaFF based on WinREPL\n"; 16 | std::cout << "Input assembly instructions, or \".help\" for a list of commands.\n" << std::endl; 17 | 18 | while (TRUE) 19 | { 20 | if (!shelldev_loop(&sh)) 21 | break; 22 | } 23 | 24 | return 0; 25 | } -------------------------------------------------------------------------------- /Shellcodev/loop.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | #include "repl.h" 6 | 7 | static std::vector assemblies; 8 | 9 | BOOL shelldev_loop(shell_t *sh) 10 | { 11 | if (!shelldev_init(sh)) 12 | return FALSE; 13 | 14 | shelldev_print_pids(sh); 15 | shelldev_print_registers(sh); 16 | 17 | while (TRUE) 18 | { 19 | std::string command = shelldev_read(); 20 | 21 | if (command.size() == 0) 22 | continue; 23 | 24 | if (!shelldev_eval(sh, command, &assemblies)) 25 | { 26 | shelldev_print_errors("An unrecoverable error occurred, resetting environment!"); 27 | break; 28 | } 29 | } 30 | 31 | return TRUE; 32 | } -------------------------------------------------------------------------------- /Shellcodev/inject.cpp: -------------------------------------------------------------------------------- 1 | #include "repl.h" 2 | 3 | static std::vector get_shellcode(std::vector* assemblies) 4 | { 5 | std::vector bytes; 6 | 7 | for (asm_t assembly : *assemblies) 8 | bytes.insert(bytes.end(), assembly.bytes.begin(), assembly.bytes.end()); 9 | 10 | return bytes; 11 | } 12 | 13 | BOOL shelldev_inject_shellcode(std::vector* assemblies, std::string pid) 14 | { 15 | DWORD PID = std::stoi(pid); 16 | shelldev_print_good("Injecting shellcode into %d", PID); 17 | 18 | std::vector bytes = get_shellcode(assemblies); 19 | 20 | HANDLE processHandle; 21 | HANDLE remoteThread; 22 | PVOID remoteBuffer; 23 | 24 | processHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PID); 25 | remoteBuffer = VirtualAllocEx(processHandle, NULL, bytes.size(), (MEM_RESERVE | MEM_COMMIT), PAGE_EXECUTE_READWRITE); 26 | WriteProcessMemory(processHandle, remoteBuffer, bytes.data(), bytes.size(), NULL); 27 | remoteThread = CreateRemoteThread(processHandle, NULL, 0, (LPTHREAD_START_ROUTINE)remoteBuffer, NULL, 0, NULL); 28 | CloseHandle(processHandle); 29 | 30 | return TRUE; 31 | } -------------------------------------------------------------------------------- /license: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 XaFF 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Shellcodev/str.cpp: -------------------------------------------------------------------------------- 1 | #include "str.h" 2 | 3 | 4 | void ltrim(std::string &s) 5 | { 6 | s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](int ch) { 7 | return !std::isspace(ch); 8 | })); 9 | } 10 | 11 | // trim from end (in place) 12 | void rtrim(std::string &s) 13 | { 14 | s.erase(std::find_if(s.rbegin(), s.rend(), [](int ch) { 15 | return !std::isspace(ch); 16 | }).base(), s.end()); 17 | } 18 | 19 | void trim(std::string &s) 20 | { 21 | ltrim(s); 22 | rtrim(s); 23 | } 24 | 25 | std::vector split(const std::string &str, const std::string &delim) 26 | { 27 | const auto delim_pos = str.find(delim); 28 | 29 | //std::string two = delim + delim; 30 | //std::replace(str.begin(), str.end(), two, delim); 31 | 32 | if (delim_pos == std::string::npos) 33 | return{ str }; 34 | 35 | std::vector ret{ str.substr(0, delim_pos) }; 36 | auto tail = split(str.substr(delim_pos + delim.size(), std::string::npos), delim); 37 | 38 | ret.insert(ret.end(), tail.begin(), tail.end()); 39 | 40 | return ret; 41 | } 42 | 43 | std::string join(const std::vector &elements, const std::string &separator) 44 | { 45 | if (!elements.empty()) 46 | { 47 | std::stringstream ss; 48 | auto it = elements.cbegin(); 49 | while (true) 50 | { 51 | ss << *it++; 52 | if (it != elements.cend()) 53 | ss << separator; 54 | else 55 | return ss.str(); 56 | } 57 | } 58 | return ""; 59 | } 60 | 61 | bool is_number(const std::string& s) 62 | { 63 | std::string::const_iterator it = s.begin(); 64 | while (it != s.end() && std::isdigit(*it)) ++it; 65 | return !s.empty() && it == s.end(); 66 | } -------------------------------------------------------------------------------- /Shellcodev/str.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | void ltrim(std::string &s); 11 | void rtrim(std::string &s); 12 | void trim(std::string &s); 13 | bool is_number(const std::string& s); 14 | 15 | std::vector split(const std::string &str, const std::string &delim); 16 | std::string join(const std::vector &elements, const std::string &separator); 17 | 18 | template 19 | static void separate(std::string & input) 20 | { 21 | for (auto it = input.begin(); (num + 1) <= std::distance(it, input.end()); ++it) 22 | { 23 | std::advance(it, num); 24 | it = input.insert(it, separator); 25 | } 26 | } 27 | 28 | static unsigned char hex_char_to_byte(char Input) 29 | { 30 | return 31 | ((Input >= 'a') && (Input <= 'f')) 32 | ? (Input - 87) 33 | : ((Input >= 'A') && (Input <= 'F')) 34 | ? (Input - 55) 35 | : ((Input >= '0') && (Input <= '9')) 36 | ? (Input - 48) 37 | : 0;//throw std::exception{}; 38 | } 39 | 40 | /* Position the characters into the appropriate nibble */ 41 | static unsigned char transform_hex_to_byte(char High, char Low) 42 | { 43 | return (hex_char_to_byte(High) << 4) | (hex_char_to_byte(Low)); 44 | } 45 | 46 | template 47 | static std::string from_hex(InputIterator first, InputIterator last) 48 | { 49 | std::ostringstream oss; 50 | 51 | while (first != last) 52 | { 53 | char highValue = *first++; 54 | if (highValue == ' ') 55 | continue; 56 | 57 | if (first == last) 58 | break; 59 | 60 | char lowValue = *first++; 61 | 62 | //char ch = (hex_to_byte::high(highValue) | hex_to_byte::low(lowValue)); 63 | unsigned char ch = transform_hex_to_byte(highValue, lowValue); 64 | oss << ch; 65 | } 66 | 67 | return oss.str(); 68 | } -------------------------------------------------------------------------------- /Shellcodev/repl.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include 6 | 7 | #include "str.h" 8 | 9 | #define WINREPL_INIT_MEM_SIZE 0x10000 10 | 11 | extern BOOL xorNulls; 12 | 13 | typedef struct _shell_context_t { 14 | PROCESS_INFORMATION procInfo; 15 | LPVOID lpStartAddress; 16 | SIZE_T nMemSize; 17 | CONTEXT prev; 18 | CONTEXT curr; 19 | } shell_t; 20 | 21 | typedef struct _asm_context_t { 22 | std::string instruction; 23 | std::vector bytes; 24 | int size; 25 | } asm_t; 26 | 27 | typedef struct _parser_context_t { 28 | std::string instruction; 29 | BOOL xored; 30 | } _str_parser_t; 31 | 32 | BOOL shelldev_init(shell_t* sh); 33 | BOOL shelldev_loop(shell_t* sh); 34 | 35 | std::string shelldev_read(); 36 | 37 | BOOL shelldev_eval(shell_t* sh, std::string command, std::vector* assemblies); 38 | BOOL shelldev_write_shellcode(shell_t* sh, unsigned char* encode, size_t size); 39 | void shelldev_debug_shellcode(shell_t* sh); 40 | 41 | std::vector shelldev_parse_string(std::string value); 42 | BOOL shelldev_run_shellcode(shell_t* sh, std::vector* assemblies); 43 | BOOL shelldev_run_shellcode(shell_t* sh, std::string assembly, std::vector* assemblies); 44 | BOOL shelldev_run_command(shell_t* sh, std::string command, std::vector* assemblies); 45 | BOOL shelldev_assemble_loop(std::vector* assemblies, std::vector& data, size_t address); 46 | 47 | void shelldev_print_pids(shell_t* sh); 48 | void shelldev_print_registers(shell_t* sh); 49 | void shelldev_print_registers_all(shell_t* sh); 50 | void shelldev_print_assembly(unsigned char* encode, size_t size); 51 | void shelldev_print_bytes(unsigned char* addr, int len, unsigned long long start_addr = 0); 52 | void shelldev_print_good(const char* format, ...); 53 | void shelldev_print_errors(const char* format, ...); 54 | 55 | BOOL shelldev_inject_shellcode(std::vector* assemblies, std::string pid); -------------------------------------------------------------------------------- /Shellcodev/Shellcodev.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Header Files 20 | 21 | 22 | Header Files 23 | 24 | 25 | Header Files 26 | 27 | 28 | 29 | 30 | Source Files 31 | 32 | 33 | Source Files 34 | 35 | 36 | Source Files 37 | 38 | 39 | Source Files 40 | 41 | 42 | Source Files 43 | 44 | 45 | Source Files 46 | 47 | 48 | Source Files 49 | 50 | 51 | Source Files 52 | 53 | 54 | Source Files 55 | 56 | 57 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Shellcodev 2 | Shellcodev is a tool designed to help and automate the process of shellcode creation. 3 | 4 | [![Test](https://img.shields.io/badge/Tested-x86-brightgreen?style=flat-square)]() [![Test](https://img.shields.io/badge/Tested-x64-brightgreen?style=flat-square)]() [![Release](https://img.shields.io/badge/Release-v2.2-blue?style=flat-square)](https://github.com/XaFF-XaFF/Shellcodev/releases/tag/v2.2.1) 5 | 6 | ![1](https://raw.githubusercontent.com/XaFF-XaFF/Shellcodev/master/screenshots/1.png?raw=true) 7 | 8 | ## Attribution 9 | This project is based on [WinREPL](https://github.com/XaFF-XaFF/WinREPL) by zerosum0x0 10 | 11 | ### Commands 12 | 13 | ``` 14 | .help Show this help screen. 15 | .registers Show more detailed register info. 16 | .list Show list of previously executed assembly instructions. 17 | .edit line Edit specified line in list. 18 | .del line Delete specified line from list. 19 | .xor e/d/status Enable, disable or show status of nullbyte xoring. 20 | .read addr size Read from a memory address. 21 | .write addr hexdata Write to a memory address. 22 | .toshell format Convert list to selected shellcode format. Available formats: c, cs, raw 23 | .inject pid Test shellcode by injecting it into the process. Works currently only on x86! 24 | .allocate size Allocate a memory buffer. 25 | .loadlibrary path Load a DLL into the process. 26 | .kernel32 func Get address of a kernel32 export. 27 | .shellcode hexdata Execute raw shellcode. 28 | .peb Loads PEB into accumulator. 29 | .reset Start a new environment. 30 | .quit Exit the program. 31 | ``` 32 | 33 | ### Added features 34 | 35 | All the instructions provided by user are now stored. User is now able to list, edit and delete instructions which makes 36 | shellcodes much easier to modify. Everything is in real-time, so any changes made in list also changes the register values. 37 | 38 | #### Listing 39 | ![2](https://raw.githubusercontent.com/XaFF-XaFF/Shellcodev/master/screenshots/2.png?raw=true) 40 | 41 | #### String snippets 42 | 43 | 44 | #### Nullbyte handling 45 | 46 | 47 | ### Goal features 48 | 49 | - **Done:** ~~String converter: String provided by user will be automatically converted to hex and encoded with little endian. In case of nullbytes, they 50 | will be removed by encrypting data with xor.~~ 51 | - **Done:** ~~Shellcode runner: User will be able to test shellcode by injecting it into the process.~~ 52 | - **Done:** ~~More formats~~. 53 | - **Done:** ~~Make nullbyte obfuscation optional~~ 54 | - Loop support 55 | 56 | ### References 57 | Libraries used to assemble instructions: 58 | - [AsmJit](https://github.com/asmjit/asmjit) 59 | - [AsmTK](https://github.com/asmjit/asmtk) 60 | -------------------------------------------------------------------------------- /Shellcodev/init.cpp: -------------------------------------------------------------------------------- 1 | #include "repl.h" 2 | 3 | static BOOL winrepl_create_debuggee(shell_t *sh) 4 | { 5 | STARTUPINFO si = { 0 }; 6 | TCHAR fileName[MAX_PATH] = { 0 }; 7 | 8 | GetModuleFileName(NULL, fileName, MAX_PATH); 9 | 10 | si.dwFlags = STARTF_USESHOWWINDOW; 11 | si.wShowWindow = SW_HIDE; // already 0 12 | si.cb = sizeof(si); 13 | 14 | if (!CreateProcess( 15 | fileName, 16 | NULL, 17 | NULL, 18 | NULL, 19 | FALSE, 20 | DEBUG_ONLY_THIS_PROCESS, 21 | NULL, 22 | NULL, 23 | &si, 24 | &sh->procInfo 25 | )) 26 | { 27 | return FALSE; 28 | } 29 | 30 | // workaround for a bug on startup (Windows 8.1 x64), SetThreadContext would fail for some reason 31 | CloseHandle(sh->procInfo.hThread); 32 | if (!(sh->procInfo.hThread = OpenThread( 33 | THREAD_SET_CONTEXT | THREAD_GET_CONTEXT | THREAD_QUERY_INFORMATION, 34 | FALSE, 35 | sh->procInfo.dwThreadId 36 | ))) 37 | { 38 | return FALSE; 39 | } 40 | 41 | // swallow initial debug events 42 | while (TRUE) 43 | { 44 | DEBUG_EVENT dbg = { 0 }; 45 | if (!WaitForDebugEvent(&dbg, 1000)) 46 | break; 47 | 48 | if (dbg.dwDebugEventCode == CREATE_PROCESS_DEBUG_EVENT) 49 | CloseHandle(dbg.u.CreateProcessInfo.hFile); 50 | 51 | if (dbg.dwDebugEventCode == LOAD_DLL_DEBUG_EVENT) 52 | { 53 | if (dbg.u.LoadDll.hFile) 54 | CloseHandle(dbg.u.LoadDll.hFile); 55 | } 56 | 57 | if (dbg.dwDebugEventCode == EXCEPTION_DEBUG_EVENT && 58 | dbg.dwThreadId == sh->procInfo.dwThreadId) 59 | break; 60 | 61 | ContinueDebugEvent(dbg.dwProcessId, dbg.dwThreadId, DBG_CONTINUE); 62 | } 63 | 64 | return TRUE; 65 | } 66 | 67 | static BOOL winrepl_alloc_mem(shell_t *sh) 68 | { 69 | if (sh->nMemSize == 0) 70 | sh->nMemSize = WINREPL_INIT_MEM_SIZE; 71 | 72 | sh->lpStartAddress = VirtualAllocEx( 73 | sh->procInfo.hProcess, 74 | NULL, 75 | sh->nMemSize, 76 | MEM_COMMIT, 77 | PAGE_EXECUTE_READ); 78 | 79 | return sh->lpStartAddress != NULL; 80 | } 81 | 82 | static BOOL winrepl_reset_context(shell_t *sh) 83 | { 84 | CONTEXT ctx = { 0 }; 85 | ctx.ContextFlags = CONTEXT_ALL; 86 | 87 | if (!GetThreadContext(sh->procInfo.hThread, &ctx)) 88 | return FALSE; 89 | 90 | #ifdef _M_X64 91 | ctx.Rip = (DWORD64)sh->lpStartAddress; 92 | 93 | ctx.Rax = 0; 94 | ctx.Rbx = 0; 95 | ctx.Rcx = 0; 96 | ctx.Rdx = 0; 97 | 98 | ctx.Rsi = 0; 99 | ctx.Rdi = 0; 100 | ctx.Rbp = 0; 101 | 102 | ctx.R8 = 0; 103 | ctx.R9 = 0; 104 | ctx.R10 = 0; 105 | ctx.R11 = 0; 106 | ctx.R12 = 0; 107 | ctx.R13 = 0; 108 | ctx.R14 = 0; 109 | ctx.R15 = 0; 110 | 111 | ctx.EFlags = 0; 112 | #elif defined(_M_IX86) 113 | ctx.Eip = (DWORD)sh->lpStartAddress; 114 | 115 | ctx.Eax = 0; 116 | ctx.Ebx = 0; 117 | ctx.Ecx = 0; 118 | ctx.Edx = 0; 119 | 120 | ctx.Esi = 0; 121 | ctx.Edi = 0; 122 | ctx.Ebp = 0; 123 | 124 | ctx.EFlags = 0; 125 | #elif defined(_M_ARM) 126 | // todo: ARM? 127 | return FALSE; 128 | #else 129 | return FALSE; 130 | #endif 131 | 132 | sh->prev = ctx; 133 | sh->curr = ctx; 134 | 135 | return SetThreadContext(sh->procInfo.hThread, &ctx); 136 | } 137 | 138 | BOOL shelldev_init(shell_t *sh) 139 | { 140 | if (!winrepl_create_debuggee(sh)) 141 | return FALSE; 142 | 143 | if (!winrepl_alloc_mem(sh)) 144 | return FALSE; 145 | 146 | if (!winrepl_reset_context(sh)) 147 | return FALSE; 148 | 149 | return TRUE; 150 | } -------------------------------------------------------------------------------- /Shellcodev.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.3.32901.215 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "asmtk", "asmtk\build_vs2022_x86\asmtk.vcxproj", "{8BEBE135-54E1-30EB-9CE8-432B756956CA}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "asmjit", "asmjit\build_vs2022_x86\asmjit.vcxproj", "{57E360DB-BAB4-3C8F-B324-2294D7C36CF1}" 9 | EndProject 10 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Shellcodev", "Shellcodev\Shellcodev.vcxproj", "{460A5496-23BB-4310-B45D-12D13745007B}" 11 | EndProject 12 | Global 13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 14 | Debug|x64 = Debug|x64 15 | Debug|x86 = Debug|x86 16 | MinSizeRel|x64 = MinSizeRel|x64 17 | MinSizeRel|x86 = MinSizeRel|x86 18 | Release|x64 = Release|x64 19 | Release|x86 = Release|x86 20 | RelWithDebInfo|x64 = RelWithDebInfo|x64 21 | RelWithDebInfo|x86 = RelWithDebInfo|x86 22 | EndGlobalSection 23 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 24 | {8BEBE135-54E1-30EB-9CE8-432B756956CA}.Debug|x64.ActiveCfg = Debug|Win32 25 | {8BEBE135-54E1-30EB-9CE8-432B756956CA}.Debug|x64.Build.0 = Debug|Win32 26 | {8BEBE135-54E1-30EB-9CE8-432B756956CA}.Debug|x86.ActiveCfg = Debug|Win32 27 | {8BEBE135-54E1-30EB-9CE8-432B756956CA}.Debug|x86.Build.0 = Debug|Win32 28 | {8BEBE135-54E1-30EB-9CE8-432B756956CA}.MinSizeRel|x64.ActiveCfg = MinSizeRel|Win32 29 | {8BEBE135-54E1-30EB-9CE8-432B756956CA}.MinSizeRel|x64.Build.0 = MinSizeRel|Win32 30 | {8BEBE135-54E1-30EB-9CE8-432B756956CA}.MinSizeRel|x86.ActiveCfg = MinSizeRel|Win32 31 | {8BEBE135-54E1-30EB-9CE8-432B756956CA}.MinSizeRel|x86.Build.0 = MinSizeRel|Win32 32 | {8BEBE135-54E1-30EB-9CE8-432B756956CA}.Release|x64.ActiveCfg = Release|Win32 33 | {8BEBE135-54E1-30EB-9CE8-432B756956CA}.Release|x64.Build.0 = Release|Win32 34 | {8BEBE135-54E1-30EB-9CE8-432B756956CA}.Release|x86.ActiveCfg = Release|Win32 35 | {8BEBE135-54E1-30EB-9CE8-432B756956CA}.Release|x86.Build.0 = Release|Win32 36 | {8BEBE135-54E1-30EB-9CE8-432B756956CA}.RelWithDebInfo|x64.ActiveCfg = RelWithDebInfo|Win32 37 | {8BEBE135-54E1-30EB-9CE8-432B756956CA}.RelWithDebInfo|x64.Build.0 = RelWithDebInfo|Win32 38 | {8BEBE135-54E1-30EB-9CE8-432B756956CA}.RelWithDebInfo|x86.ActiveCfg = RelWithDebInfo|Win32 39 | {8BEBE135-54E1-30EB-9CE8-432B756956CA}.RelWithDebInfo|x86.Build.0 = RelWithDebInfo|Win32 40 | {57E360DB-BAB4-3C8F-B324-2294D7C36CF1}.Debug|x64.ActiveCfg = Debug|Win32 41 | {57E360DB-BAB4-3C8F-B324-2294D7C36CF1}.Debug|x64.Build.0 = Debug|Win32 42 | {57E360DB-BAB4-3C8F-B324-2294D7C36CF1}.Debug|x86.ActiveCfg = Debug|Win32 43 | {57E360DB-BAB4-3C8F-B324-2294D7C36CF1}.Debug|x86.Build.0 = Debug|Win32 44 | {57E360DB-BAB4-3C8F-B324-2294D7C36CF1}.MinSizeRel|x64.ActiveCfg = MinSizeRel|Win32 45 | {57E360DB-BAB4-3C8F-B324-2294D7C36CF1}.MinSizeRel|x64.Build.0 = MinSizeRel|Win32 46 | {57E360DB-BAB4-3C8F-B324-2294D7C36CF1}.MinSizeRel|x86.ActiveCfg = MinSizeRel|Win32 47 | {57E360DB-BAB4-3C8F-B324-2294D7C36CF1}.MinSizeRel|x86.Build.0 = MinSizeRel|Win32 48 | {57E360DB-BAB4-3C8F-B324-2294D7C36CF1}.Release|x64.ActiveCfg = Release|Win32 49 | {57E360DB-BAB4-3C8F-B324-2294D7C36CF1}.Release|x64.Build.0 = Release|Win32 50 | {57E360DB-BAB4-3C8F-B324-2294D7C36CF1}.Release|x86.ActiveCfg = Release|Win32 51 | {57E360DB-BAB4-3C8F-B324-2294D7C36CF1}.Release|x86.Build.0 = Release|Win32 52 | {57E360DB-BAB4-3C8F-B324-2294D7C36CF1}.RelWithDebInfo|x64.ActiveCfg = RelWithDebInfo|Win32 53 | {57E360DB-BAB4-3C8F-B324-2294D7C36CF1}.RelWithDebInfo|x64.Build.0 = RelWithDebInfo|Win32 54 | {57E360DB-BAB4-3C8F-B324-2294D7C36CF1}.RelWithDebInfo|x86.ActiveCfg = RelWithDebInfo|Win32 55 | {57E360DB-BAB4-3C8F-B324-2294D7C36CF1}.RelWithDebInfo|x86.Build.0 = RelWithDebInfo|Win32 56 | {460A5496-23BB-4310-B45D-12D13745007B}.Debug|x64.ActiveCfg = Debug|x64 57 | {460A5496-23BB-4310-B45D-12D13745007B}.Debug|x64.Build.0 = Debug|x64 58 | {460A5496-23BB-4310-B45D-12D13745007B}.Debug|x86.ActiveCfg = Debug|Win32 59 | {460A5496-23BB-4310-B45D-12D13745007B}.Debug|x86.Build.0 = Debug|Win32 60 | {460A5496-23BB-4310-B45D-12D13745007B}.MinSizeRel|x64.ActiveCfg = Debug|x64 61 | {460A5496-23BB-4310-B45D-12D13745007B}.MinSizeRel|x64.Build.0 = Debug|x64 62 | {460A5496-23BB-4310-B45D-12D13745007B}.MinSizeRel|x86.ActiveCfg = Debug|Win32 63 | {460A5496-23BB-4310-B45D-12D13745007B}.MinSizeRel|x86.Build.0 = Debug|Win32 64 | {460A5496-23BB-4310-B45D-12D13745007B}.Release|x64.ActiveCfg = Release|x64 65 | {460A5496-23BB-4310-B45D-12D13745007B}.Release|x64.Build.0 = Release|x64 66 | {460A5496-23BB-4310-B45D-12D13745007B}.Release|x86.ActiveCfg = Release|Win32 67 | {460A5496-23BB-4310-B45D-12D13745007B}.Release|x86.Build.0 = Release|Win32 68 | {460A5496-23BB-4310-B45D-12D13745007B}.RelWithDebInfo|x64.ActiveCfg = Release|x64 69 | {460A5496-23BB-4310-B45D-12D13745007B}.RelWithDebInfo|x64.Build.0 = Release|x64 70 | {460A5496-23BB-4310-B45D-12D13745007B}.RelWithDebInfo|x86.ActiveCfg = Release|Win32 71 | {460A5496-23BB-4310-B45D-12D13745007B}.RelWithDebInfo|x86.Build.0 = Release|Win32 72 | EndGlobalSection 73 | GlobalSection(SolutionProperties) = preSolution 74 | HideSolutionNode = FALSE 75 | EndGlobalSection 76 | GlobalSection(ExtensibilityGlobals) = postSolution 77 | SolutionGuid = {4CE168A3-0152-4135-A7C4-40D14BE27588} 78 | EndGlobalSection 79 | EndGlobal 80 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Mono auto generated files 17 | mono_crash.* 18 | 19 | # Build results 20 | [Dd]ebug/ 21 | [Dd]ebugPublic/ 22 | [Rr]elease/ 23 | [Rr]eleases/ 24 | x64/ 25 | x86/ 26 | [Ww][Ii][Nn]32/ 27 | [Aa][Rr][Mm]/ 28 | [Aa][Rr][Mm]64/ 29 | bld/ 30 | [Bb]in/ 31 | [Oo]bj/ 32 | [Oo]ut/ 33 | [Ll]og/ 34 | [Ll]ogs/ 35 | 36 | # Visual Studio 2015/2017 cache/options directory 37 | .vs/ 38 | # Uncomment if you have tasks that create the project's static files in wwwroot 39 | #wwwroot/ 40 | 41 | # Visual Studio 2017 auto generated files 42 | Generated\ Files/ 43 | 44 | # MSTest test Results 45 | [Tt]est[Rr]esult*/ 46 | [Bb]uild[Ll]og.* 47 | 48 | # NUnit 49 | *.VisualState.xml 50 | TestResult.xml 51 | nunit-*.xml 52 | 53 | # Build Results of an ATL Project 54 | [Dd]ebugPS/ 55 | [Rr]eleasePS/ 56 | dlldata.c 57 | 58 | # Benchmark Results 59 | BenchmarkDotNet.Artifacts/ 60 | 61 | # .NET Core 62 | project.lock.json 63 | project.fragment.lock.json 64 | artifacts/ 65 | 66 | # ASP.NET Scaffolding 67 | ScaffoldingReadMe.txt 68 | 69 | # StyleCop 70 | StyleCopReport.xml 71 | 72 | # Files built by Visual Studio 73 | *_i.c 74 | *_p.c 75 | *_h.h 76 | *.ilk 77 | *.meta 78 | *.obj 79 | *.iobj 80 | *.pch 81 | *.pdb 82 | *.ipdb 83 | *.pgc 84 | *.pgd 85 | *.rsp 86 | *.sbr 87 | *.tlb 88 | *.tli 89 | *.tlh 90 | *.tmp 91 | *.tmp_proj 92 | *_wpftmp.csproj 93 | *.log 94 | *.vspscc 95 | *.vssscc 96 | .builds 97 | *.pidb 98 | *.svclog 99 | *.scc 100 | 101 | # Chutzpah Test files 102 | _Chutzpah* 103 | 104 | # Visual C++ cache files 105 | ipch/ 106 | *.aps 107 | *.ncb 108 | *.opendb 109 | *.opensdf 110 | *.sdf 111 | *.cachefile 112 | *.VC.db 113 | *.VC.VC.opendb 114 | 115 | # Visual Studio profiler 116 | *.psess 117 | *.vsp 118 | *.vspx 119 | *.sap 120 | 121 | # Visual Studio Trace Files 122 | *.e2e 123 | 124 | # TFS 2012 Local Workspace 125 | $tf/ 126 | 127 | # Guidance Automation Toolkit 128 | *.gpState 129 | 130 | # ReSharper is a .NET coding add-in 131 | _ReSharper*/ 132 | *.[Rr]e[Ss]harper 133 | *.DotSettings.user 134 | 135 | # TeamCity is a build add-in 136 | _TeamCity* 137 | 138 | # DotCover is a Code Coverage Tool 139 | *.dotCover 140 | 141 | # AxoCover is a Code Coverage Tool 142 | .axoCover/* 143 | !.axoCover/settings.json 144 | 145 | # Coverlet is a free, cross platform Code Coverage Tool 146 | coverage*.json 147 | coverage*.xml 148 | coverage*.info 149 | 150 | # Visual Studio code coverage results 151 | *.coverage 152 | *.coveragexml 153 | 154 | # NCrunch 155 | _NCrunch_* 156 | .*crunch*.local.xml 157 | nCrunchTemp_* 158 | 159 | # MightyMoose 160 | *.mm.* 161 | AutoTest.Net/ 162 | 163 | # Web workbench (sass) 164 | .sass-cache/ 165 | 166 | # Installshield output folder 167 | [Ee]xpress/ 168 | 169 | # DocProject is a documentation generator add-in 170 | DocProject/buildhelp/ 171 | DocProject/Help/*.HxT 172 | DocProject/Help/*.HxC 173 | DocProject/Help/*.hhc 174 | DocProject/Help/*.hhk 175 | DocProject/Help/*.hhp 176 | DocProject/Help/Html2 177 | DocProject/Help/html 178 | 179 | # Click-Once directory 180 | publish/ 181 | 182 | # Publish Web Output 183 | *.[Pp]ublish.xml 184 | *.azurePubxml 185 | # Note: Comment the next line if you want to checkin your web deploy settings, 186 | # but database connection strings (with potential passwords) will be unencrypted 187 | *.pubxml 188 | *.publishproj 189 | 190 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 191 | # checkin your Azure Web App publish settings, but sensitive information contained 192 | # in these scripts will be unencrypted 193 | PublishScripts/ 194 | 195 | # NuGet Packages 196 | *.nupkg 197 | # NuGet Symbol Packages 198 | *.snupkg 199 | # The packages folder can be ignored because of Package Restore 200 | **/[Pp]ackages/* 201 | # except build/, which is used as an MSBuild target. 202 | !**/[Pp]ackages/build/ 203 | # Uncomment if necessary however generally it will be regenerated when needed 204 | #!**/[Pp]ackages/repositories.config 205 | # NuGet v3's project.json files produces more ignorable files 206 | *.nuget.props 207 | *.nuget.targets 208 | 209 | # Microsoft Azure Build Output 210 | csx/ 211 | *.build.csdef 212 | 213 | # Microsoft Azure Emulator 214 | ecf/ 215 | rcf/ 216 | 217 | # Windows Store app package directories and files 218 | AppPackages/ 219 | BundleArtifacts/ 220 | Package.StoreAssociation.xml 221 | _pkginfo.txt 222 | *.appx 223 | *.appxbundle 224 | *.appxupload 225 | 226 | # Visual Studio cache files 227 | # files ending in .cache can be ignored 228 | *.[Cc]ache 229 | # but keep track of directories ending in .cache 230 | !?*.[Cc]ache/ 231 | 232 | # Others 233 | ClientBin/ 234 | ~$* 235 | *~ 236 | *.dbmdl 237 | *.dbproj.schemaview 238 | *.jfm 239 | *.pfx 240 | *.publishsettings 241 | orleans.codegen.cs 242 | 243 | # Including strong name files can present a security risk 244 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 245 | #*.snk 246 | 247 | # Since there are multiple workflows, uncomment next line to ignore bower_components 248 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 249 | #bower_components/ 250 | 251 | # RIA/Silverlight projects 252 | Generated_Code/ 253 | 254 | # Backup & report files from converting an old project file 255 | # to a newer Visual Studio version. Backup files are not needed, 256 | # because we have git ;-) 257 | _UpgradeReport_Files/ 258 | Backup*/ 259 | UpgradeLog*.XML 260 | UpgradeLog*.htm 261 | ServiceFabricBackup/ 262 | *.rptproj.bak 263 | 264 | # SQL Server files 265 | *.mdf 266 | *.ldf 267 | *.ndf 268 | 269 | # Business Intelligence projects 270 | *.rdl.data 271 | *.bim.layout 272 | *.bim_*.settings 273 | *.rptproj.rsuser 274 | *- [Bb]ackup.rdl 275 | *- [Bb]ackup ([0-9]).rdl 276 | *- [Bb]ackup ([0-9][0-9]).rdl 277 | 278 | # Microsoft Fakes 279 | FakesAssemblies/ 280 | 281 | # GhostDoc plugin setting file 282 | *.GhostDoc.xml 283 | 284 | # Node.js Tools for Visual Studio 285 | .ntvs_analysis.dat 286 | node_modules/ 287 | 288 | # Visual Studio 6 build log 289 | *.plg 290 | 291 | # Visual Studio 6 workspace options file 292 | *.opt 293 | 294 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 295 | *.vbw 296 | 297 | # Visual Studio LightSwitch build output 298 | **/*.HTMLClient/GeneratedArtifacts 299 | **/*.DesktopClient/GeneratedArtifacts 300 | **/*.DesktopClient/ModelManifest.xml 301 | **/*.Server/GeneratedArtifacts 302 | **/*.Server/ModelManifest.xml 303 | _Pvt_Extensions 304 | 305 | # Paket dependency manager 306 | .paket/paket.exe 307 | paket-files/ 308 | 309 | # FAKE - F# Make 310 | .fake/ 311 | 312 | # CodeRush personal settings 313 | .cr/personal 314 | 315 | # Python Tools for Visual Studio (PTVS) 316 | __pycache__/ 317 | *.pyc 318 | 319 | # Cake - Uncomment if you are using it 320 | # tools/** 321 | # !tools/packages.config 322 | 323 | # Tabs Studio 324 | *.tss 325 | 326 | # Telerik's JustMock configuration file 327 | *.jmconfig 328 | 329 | # BizTalk build output 330 | *.btp.cs 331 | *.btm.cs 332 | *.odx.cs 333 | *.xsd.cs 334 | 335 | # OpenCover UI analysis results 336 | OpenCover/ 337 | 338 | # Azure Stream Analytics local run output 339 | ASALocalRun/ 340 | 341 | # MSBuild Binary and Structured Log 342 | *.binlog 343 | 344 | # NVidia Nsight GPU debugger configuration file 345 | *.nvuser 346 | 347 | # MFractors (Xamarin productivity tool) working folder 348 | .mfractor/ 349 | 350 | # Local History for Visual Studio 351 | .localhistory/ 352 | 353 | # BeatPulse healthcheck temp database 354 | healthchecksdb 355 | 356 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 357 | MigrationBackup/ 358 | 359 | # Ionide (cross platform F# VS Code tools) working folder 360 | .ionide/ 361 | 362 | # Fody - auto-generated XML schema 363 | FodyWeavers.xsd -------------------------------------------------------------------------------- /Shellcodev/Shellcodev.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 16.0 39 | Win32Proj 40 | {460a5496-23bb-4310-b45d-12d13745007b} 41 | Shellcodev 42 | 10.0 43 | 44 | 45 | 46 | Application 47 | true 48 | v143 49 | Unicode 50 | 51 | 52 | Application 53 | false 54 | v143 55 | true 56 | Unicode 57 | 58 | 59 | Application 60 | true 61 | v143 62 | Unicode 63 | 64 | 65 | Application 66 | false 67 | v143 68 | true 69 | Unicode 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | Level3 92 | true 93 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 94 | true 95 | Default 96 | true 97 | $(SolutionDir)asmtk\src;$(SolutionDir)asmjit\src;%(AdditionalIncludeDirectories) 98 | 99 | 100 | Console 101 | true 102 | $(SolutionDir)asmtk\build_vs2022_x86\Debug;$(SolutionDir)asmjit\build_vs2022_x86\Debug;%(AdditionalLibraryDirectories) 103 | asmjit.lib;asmtk.lib;%(AdditionalDependencies) 104 | 105 | 106 | 107 | 108 | Level3 109 | true 110 | true 111 | true 112 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 113 | true 114 | 115 | 116 | Console 117 | true 118 | true 119 | true 120 | 121 | 122 | 123 | 124 | Level3 125 | true 126 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 127 | true 128 | $(SolutionDir)asmtk\src;$(SolutionDir)asmjit\src;%(AdditionalIncludeDirectories) 129 | true 130 | 131 | 132 | Console 133 | true 134 | $(SolutionDir)asmjit\build_vs2022_x64\Debug;$(SolutionDir)asmtk\build_vs2022_x64\Debug;%(AdditionalLibraryDirectories) 135 | asmjit.lib;asmtk.lib;%(AdditionalDependencies) 136 | 137 | 138 | 139 | 140 | Level3 141 | true 142 | true 143 | true 144 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 145 | true 146 | 147 | 148 | Console 149 | true 150 | true 151 | true 152 | 153 | 154 | 155 | 156 | 157 | -------------------------------------------------------------------------------- /Shellcodev/print.cpp: -------------------------------------------------------------------------------- 1 | #include "repl.h" 2 | #include 3 | 4 | 5 | static inline BOOL check_bit(DWORD var, char pos) 6 | { 7 | return !!((var) & (1 << (pos))); 8 | } 9 | 10 | static void winrepl_reset_console_color() 11 | { 12 | static HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); 13 | SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); 14 | } 15 | 16 | static void winrepl_print_console_color(WORD attributes, const char *format, ...) 17 | { 18 | static HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); 19 | 20 | if (attributes != 0) 21 | SetConsoleTextAttribute(hConsole, attributes); 22 | 23 | va_list argptr; 24 | va_start(argptr, format); 25 | vfprintf(stderr, format, argptr); 26 | va_end(argptr); 27 | 28 | winrepl_reset_console_color(); 29 | } 30 | 31 | 32 | static void winrepl_print_register_32(const char *reg, DWORD64 value, DWORD64 prev) 33 | { 34 | winrepl_print_console_color(FOREGROUND_GREEN | FOREGROUND_INTENSITY, "%s: ", reg); 35 | 36 | WORD color = (prev == value) ? 0 : FOREGROUND_RED | FOREGROUND_INTENSITY; 37 | winrepl_print_console_color(color, "%08llx ", value); 38 | } 39 | 40 | static void winrepl_print_register_64(const char *reg, DWORD64 value, DWORD64 prev) 41 | { 42 | winrepl_print_console_color(FOREGROUND_GREEN | FOREGROUND_INTENSITY, "%s: ", reg); 43 | 44 | WORD color = (prev == value) ? 0 : FOREGROUND_RED | FOREGROUND_INTENSITY; 45 | winrepl_print_console_color(color, "%016llx ", value); 46 | } 47 | 48 | 49 | static void winrepl_print_register_flag(const char *flag, BOOL value, BOOL prev) 50 | { 51 | winrepl_print_console_color(FOREGROUND_BLUE | FOREGROUND_GREEN, "%s: ", flag); 52 | 53 | WORD color = (prev == value) ? 0 : FOREGROUND_RED | FOREGROUND_INTENSITY; 54 | winrepl_print_console_color(color, "%d ", value); 55 | } 56 | 57 | #ifdef _M_X64 58 | static void winrepl_print_register_xmm(const char *reg, M128A value, M128A prev) 59 | { 60 | 61 | winrepl_print_console_color(FOREGROUND_GREEN | FOREGROUND_INTENSITY, "%s: ", reg); 62 | 63 | printf("{ "); 64 | WORD color = (prev.High == value.High) ? 0 : FOREGROUND_RED | FOREGROUND_INTENSITY; 65 | winrepl_print_console_color(color, "%10.10e", value.High); 66 | 67 | printf(", "); 68 | 69 | color = (prev.Low == value.Low) ? 0 : FOREGROUND_RED | FOREGROUND_INTENSITY; 70 | winrepl_print_console_color(color, "%10.10e", value.Low); 71 | 72 | 73 | printf(" }\t"); 74 | 75 | color = (prev.High == value.High) ? 0 : FOREGROUND_RED | FOREGROUND_INTENSITY; 76 | winrepl_print_console_color(color, "%016llx", value.High); 77 | 78 | color = (prev.Low == value.Low) ? 0 : FOREGROUND_RED | FOREGROUND_INTENSITY; 79 | winrepl_print_console_color(color, "%016llx", value.Low); 80 | 81 | printf("\n"); 82 | 83 | } 84 | #elif defined(_M_IX86) 85 | // ?????????????? 86 | static void winrepl_print_register_xmm(const char *reg, int a, int b) 87 | {} 88 | #else 89 | // ?!!!!!!!!! 90 | static void winrepl_print_register_xmm(const char *reg, int a, int b) 91 | {} 92 | #endif 93 | 94 | 95 | void shelldev_print_errors(const char *format, ...) 96 | { 97 | static HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); 98 | 99 | winrepl_print_console_color(FOREGROUND_RED | FOREGROUND_INTENSITY, "%s", "[-] "); 100 | 101 | va_list argptr; 102 | va_start(argptr, format); 103 | vfprintf(stderr, format, argptr); 104 | va_end(argptr); 105 | 106 | DWORD dwErr = GetLastError(); 107 | if (dwErr != 0) 108 | printf(" (errno: %d)", dwErr); 109 | 110 | printf("\n"); 111 | } 112 | 113 | void shelldev_print_bytes(unsigned char *addr, int len, unsigned long long start_addr) 114 | { 115 | int i; 116 | unsigned char buff[17]; 117 | unsigned char *pc = (unsigned char*)addr; 118 | 119 | for (i = 0; i < len; i++) 120 | { 121 | if ((i % 16) == 0) 122 | { 123 | if (i != 0) 124 | printf(" %s\n", buff); 125 | 126 | printf(" %04llx ", start_addr + i); 127 | } 128 | 129 | printf(" %02x", pc[i]); 130 | 131 | if ((pc[i] < 0x20) || (pc[i] > 0x7e)) 132 | buff[i % 16] = '.'; 133 | else 134 | buff[i % 16] = pc[i]; 135 | buff[(i % 16) + 1] = '\0'; 136 | } 137 | 138 | while ((i % 16) != 0) 139 | { 140 | printf(" "); 141 | ++i; 142 | } 143 | 144 | printf(" %s\n", buff); 145 | } 146 | 147 | void shelldev_print_good(const char *format, ...) 148 | { 149 | winrepl_print_console_color(FOREGROUND_GREEN | FOREGROUND_INTENSITY, "%s", "[+] "); 150 | va_list argptr; 151 | va_start(argptr, format); 152 | vfprintf(stderr, format, argptr); 153 | va_end(argptr); 154 | printf("\n"); 155 | } 156 | 157 | void shelldev_print_registers(shell_t *sh) 158 | { 159 | CONTEXT ctx = { 0 }; 160 | ctx.ContextFlags = CONTEXT_ALL; 161 | 162 | GetThreadContext(sh->procInfo.hThread, &ctx); 163 | 164 | #ifdef _M_X64 165 | winrepl_print_register_64("rax", ctx.Rax, sh->prev.Rax); 166 | winrepl_print_register_64("rbx", ctx.Rbx, sh->prev.Rbx); 167 | winrepl_print_register_64("rcx", ctx.Rcx, sh->prev.Rcx); 168 | winrepl_print_register_64("rdx", ctx.Rdx, sh->prev.Rdx); 169 | printf("\n"); 170 | 171 | winrepl_print_register_64("r8 ", ctx.R8, sh->prev.R8); 172 | winrepl_print_register_64("r9 ", ctx.R9, sh->prev.R9); 173 | winrepl_print_register_64("r10", ctx.R10, sh->prev.R10); 174 | winrepl_print_register_64("r11", ctx.R11, sh->prev.R11); 175 | printf("\n"); 176 | 177 | winrepl_print_register_64("r12", ctx.R12, sh->prev.R12); 178 | winrepl_print_register_64("r13", ctx.R13, sh->prev.R13); 179 | winrepl_print_register_64("r14", ctx.R14, sh->prev.R14); 180 | winrepl_print_register_64("r15", ctx.R15, sh->prev.R15); 181 | printf("\n"); 182 | 183 | 184 | winrepl_print_register_64("rsi", ctx.Rsi, sh->prev.Rsi); 185 | winrepl_print_register_64("rdi", ctx.Rdi, sh->prev.Rdi); 186 | printf("\n"); 187 | 188 | winrepl_print_register_64("rip", ctx.Rip, sh->prev.Rip); 189 | winrepl_print_register_64("rsp", ctx.Rsp, sh->prev.Rsp); 190 | winrepl_print_register_64("rbp", ctx.Rbp, sh->prev.Rbp); 191 | printf("\n"); 192 | #elif defined(_M_IX86) 193 | winrepl_print_register_32("eax", ctx.Eax, sh->prev.Eax); 194 | winrepl_print_register_32("ebx", ctx.Ebx, sh->prev.Ebx); 195 | winrepl_print_register_32("ecx", ctx.Ecx, sh->prev.Ecx); 196 | winrepl_print_register_32("edx", ctx.Edx, sh->prev.Edx); 197 | printf("\n"); 198 | 199 | winrepl_print_register_32("esi", ctx.Esi, sh->prev.Esi); 200 | winrepl_print_register_32("edi", ctx.Edi, sh->prev.Edi); 201 | printf("\n"); 202 | 203 | winrepl_print_register_32("eip", ctx.Eip, sh->prev.Eip); 204 | winrepl_print_register_32("esp", ctx.Esp, sh->prev.Esp); 205 | winrepl_print_register_32("ebp", ctx.Ebp, sh->prev.Ebp); 206 | printf("\n"); 207 | #endif 208 | 209 | #if defined(_M_X64) || defined(_M_IX86) 210 | printf("flags: %08x ", ctx.EFlags); 211 | 212 | winrepl_print_register_flag("CF", check_bit(ctx.EFlags, 0), check_bit(sh->prev.EFlags, 0)); 213 | winrepl_print_register_flag("PF", check_bit(ctx.EFlags, 2), check_bit(sh->prev.EFlags, 2)); 214 | winrepl_print_register_flag("AF", check_bit(ctx.EFlags, 3), check_bit(sh->prev.EFlags, 3)); 215 | winrepl_print_register_flag("ZF", check_bit(ctx.EFlags, 6), check_bit(sh->prev.EFlags, 6)); 216 | winrepl_print_register_flag("SF", check_bit(ctx.EFlags, 7), check_bit(sh->prev.EFlags, 7)); 217 | winrepl_print_register_flag("DF", check_bit(ctx.EFlags, 10), check_bit(sh->prev.EFlags, 10)); 218 | winrepl_print_register_flag("OF", check_bit(ctx.EFlags, 11), check_bit(sh->prev.EFlags, 11)); 219 | 220 | /* 221 | 222 | printf("cf: %d, ", check_bit(ctx.EFlags, 0)); 223 | printf("pf: %d, ", check_bit(ctx.EFlags, 2)); 224 | printf("af: %d, ", check_bit(ctx.EFlags, 4)); 225 | printf("zf: %d, ", check_bit(ctx.EFlags, 6)); 226 | printf("sf: %d, ", check_bit(ctx.EFlags, 7)); 227 | printf("df: %d, ", check_bit(ctx.EFlags, 10)); 228 | printf("of: %d]", check_bit(ctx.EFlags, 11)); 229 | */ 230 | printf("\n"); 231 | #endif 232 | } 233 | 234 | void shelldev_print_registers_all(shell_t *sh) 235 | { 236 | CONTEXT ctx = { 0 }; 237 | ctx.ContextFlags = CONTEXT_ALL; 238 | 239 | GetThreadContext(sh->procInfo.hThread, &ctx); 240 | 241 | #ifdef _M_X64 242 | winrepl_print_register_xmm("xmm0 ", ctx.Xmm0, sh->prev.Xmm0); 243 | winrepl_print_register_xmm("xmm1 ", ctx.Xmm1, sh->prev.Xmm1); 244 | winrepl_print_register_xmm("xmm2 ", ctx.Xmm2, sh->prev.Xmm2); 245 | winrepl_print_register_xmm("xmm3 ", ctx.Xmm3, sh->prev.Xmm3); 246 | winrepl_print_register_xmm("xmm4 ", ctx.Xmm4, sh->prev.Xmm4); 247 | winrepl_print_register_xmm("xmm5 ", ctx.Xmm5, sh->prev.Xmm5); 248 | winrepl_print_register_xmm("xmm6 ", ctx.Xmm6, sh->prev.Xmm6); 249 | winrepl_print_register_xmm("xmm7 ", ctx.Xmm7, sh->prev.Xmm7); 250 | winrepl_print_register_xmm("xmm8 ", ctx.Xmm8, sh->prev.Xmm8); 251 | winrepl_print_register_xmm("xmm9 ", ctx.Xmm9, sh->prev.Xmm9); 252 | winrepl_print_register_xmm("xmm10", ctx.Xmm10, sh->prev.Xmm10); 253 | winrepl_print_register_xmm("xmm11", ctx.Xmm11, sh->prev.Xmm11); 254 | winrepl_print_register_xmm("xmm12", ctx.Xmm12, sh->prev.Xmm12); 255 | winrepl_print_register_xmm("xmm13", ctx.Xmm13, sh->prev.Xmm13); 256 | winrepl_print_register_xmm("xmm14", ctx.Xmm14, sh->prev.Xmm14); 257 | winrepl_print_register_xmm("xmm15", ctx.Xmm15, sh->prev.Xmm15); 258 | #endif 259 | 260 | shelldev_print_registers(sh); 261 | } 262 | 263 | void shelldev_print_pids(shell_t *sh) 264 | { 265 | DWORD dwPPID = GetCurrentProcessId(); 266 | DWORD dwPTID = GetCurrentThreadId(); 267 | DWORD dwCPID = sh->procInfo.dwProcessId; 268 | DWORD dwCTID = sh->procInfo.dwThreadId; 269 | printf("PPID: %d\tPTID: %d\tCPID: %d\tCTID: %d\n", dwPPID, dwPTID, dwCPID, dwCTID); 270 | } -------------------------------------------------------------------------------- /Shellcodev/eval.cpp: -------------------------------------------------------------------------------- 1 | #undef min 2 | #undef max 3 | #include 4 | #include 5 | #include 6 | #include "repl.h" 7 | 8 | static std::string get_register(std::string instruction) 9 | { 10 | std::string reg; 11 | for (int i = 4; i < instruction.size(); i++) 12 | if (instruction[i] == ',') 13 | break; 14 | else reg += instruction[i]; 15 | 16 | return reg; 17 | } 18 | 19 | static inline unsigned int value(char c) 20 | { 21 | if (c >= '0' && c <= '9') { return c - '0'; } 22 | if (c >= 'a' && c <= 'f') { return c - 'a' + 10; } 23 | if (c >= 'A' && c <= 'F') { return c - 'A' + 10; } 24 | return -1; 25 | } 26 | 27 | std::string str_xor(std::string const& s1, std::string const& s2) 28 | { 29 | static char const alphabet[] = "0123456789abcdef"; 30 | 31 | std::string result; 32 | result.reserve(s1.length()); 33 | 34 | for (std::size_t i = 0; i != s1.length(); ++i) 35 | { 36 | unsigned int v = value(s1[i]) ^ value(s2[i]); 37 | 38 | result.push_back(alphabet[v]); 39 | } 40 | 41 | return result; 42 | } 43 | 44 | std::vector shelldev_parse_string(std::string reg, std::string value) // Currently only works on x86! 45 | { 46 | std::string key = "11111111"; 47 | 48 | std::vector stringParts; 49 | for (size_t i = 0; i < value.size(); i += 4) 50 | stringParts.push_back(value.substr(i, 4)); 51 | 52 | std::vector hex; 53 | for (std::string part : stringParts) 54 | { 55 | std::stringstream ss; 56 | for (int i = part.size() - 1; i >= 0; i--) 57 | ss << std::hex << static_cast(part[i]); 58 | 59 | hex.push_back(ss.str()); 60 | } 61 | 62 | if(xorNulls == TRUE) 63 | for (int i = 0; i < hex.size(); i++) 64 | if (hex[i].size() < 8) 65 | for (int j = 0; j < (8 - hex[i].size()); j++) 66 | hex[i].insert(0, "00"); 67 | 68 | std::vector<_str_parser_t> parsers; 69 | for (int i = 0; i < hex.size(); i++) 70 | { 71 | _str_parser_t parser; 72 | if (xorNulls == TRUE && hex[i].find("0") != std::string::npos) 73 | { 74 | parser.instruction = str_xor(hex[i], key); 75 | parser.xored = TRUE; 76 | parsers.push_back(parser); 77 | } 78 | else 79 | { 80 | parser.instruction = hex[i]; 81 | parser.xored = FALSE; 82 | parsers.push_back(parser); 83 | } 84 | } 85 | 86 | std::vector instructions; 87 | for (int i = parsers.size() - 1; i >= 0; i--) 88 | { 89 | if (parsers[i].xored) 90 | { 91 | instructions.push_back("mov " + reg + ", 0x" + parsers[i].instruction); 92 | instructions.push_back("xor " + reg + ", 0x" + key); 93 | instructions.push_back("push " + reg); 94 | } 95 | else 96 | { 97 | instructions.push_back("push 0x" + parsers[i].instruction); 98 | } 99 | } 100 | 101 | #ifdef _M_X64 102 | instructions.push_back("mov " + reg + ", rsp"); 103 | #elif defined(_M_IX86) 104 | instructions.push_back("mov " + reg + ", esp"); 105 | #endif 106 | 107 | return instructions; 108 | } 109 | 110 | static void shelldev_fix_rip(shell_t* sh) 111 | { 112 | // fix RIP because of \xcc 113 | CONTEXT ctx = { 0 }; 114 | ctx.ContextFlags = CONTEXT_ALL; 115 | GetThreadContext(sh->procInfo.hThread, &ctx); 116 | 117 | #ifdef _M_X64 118 | ctx.Rip = ctx.Rip - 1; 119 | #elif defined(_M_IX86) 120 | ctx.Eip = ctx.Eip - 1; 121 | #endif 122 | SetThreadContext(sh->procInfo.hThread, &ctx); 123 | } 124 | 125 | BOOL shelldev_write_shellcode(shell_t* sh, unsigned char* encode, size_t size) 126 | { 127 | DWORD dwOldProtect = 0; 128 | SIZE_T nBytes; 129 | CONTEXT ctx = { 0 }; 130 | 131 | shelldev_print_assembly(encode, size); 132 | 133 | ctx.ContextFlags = CONTEXT_ALL; 134 | if (!GetThreadContext(sh->procInfo.hThread, &ctx)) 135 | return FALSE; 136 | 137 | 138 | #ifdef _M_X64 139 | LPVOID addr = (LPVOID)ctx.Rip; 140 | #elif defined(_M_IX86) 141 | LPVOID addr = (LPVOID)ctx.Eip; 142 | #endif 143 | 144 | if (!VirtualProtectEx(sh->procInfo.hProcess, (LPVOID)addr, size + 1, PAGE_READWRITE, &dwOldProtect)) 145 | return FALSE; 146 | 147 | if (!WriteProcessMemory(sh->procInfo.hProcess, (LPVOID)addr, (LPCVOID)encode, size, &nBytes)) 148 | return FALSE; 149 | 150 | if (!WriteProcessMemory(sh->procInfo.hProcess, (LPVOID)((LPBYTE)addr + size), (LPCVOID)"\xcc", 1, &nBytes)) 151 | return FALSE; 152 | 153 | if (!VirtualProtectEx(sh->procInfo.hProcess, (LPVOID)addr, size + 1, dwOldProtect, &dwOldProtect)) 154 | return FALSE; 155 | 156 | FlushInstructionCache(sh->procInfo.hProcess, (LPCVOID)addr, size + 1); 157 | 158 | return TRUE; 159 | } 160 | 161 | void shelldev_debug_shellcode(shell_t* sh) 162 | { 163 | BOOL go = TRUE; 164 | while (go) 165 | { 166 | ContinueDebugEvent(sh->procInfo.dwProcessId, sh->procInfo.dwThreadId, DBG_CONTINUE); 167 | 168 | DEBUG_EVENT dbg = { 0 }; 169 | if (!WaitForDebugEvent(&dbg, INFINITE)) 170 | break; 171 | 172 | if (dbg.dwThreadId != sh->procInfo.dwThreadId) 173 | { 174 | ContinueDebugEvent(dbg.dwProcessId, dbg.dwThreadId, DBG_CONTINUE); 175 | continue; 176 | } 177 | 178 | if (dbg.dwDebugEventCode == EXCEPTION_DEBUG_EVENT && dbg.dwThreadId == sh->procInfo.dwThreadId) 179 | { 180 | go = FALSE; 181 | 182 | switch (dbg.u.Exception.ExceptionRecord.ExceptionCode) 183 | { 184 | case EXCEPTION_ACCESS_VIOLATION: 185 | break; 186 | 187 | case EXCEPTION_PRIV_INSTRUCTION: 188 | break; 189 | 190 | case EXCEPTION_BREAKPOINT: 191 | break; 192 | default: 193 | break; 194 | } 195 | } 196 | 197 | if (dbg.dwDebugEventCode == LOAD_DLL_DEBUG_EVENT) 198 | { 199 | if (dbg.u.LoadDll.hFile) 200 | CloseHandle(dbg.u.LoadDll.hFile); 201 | } 202 | } 203 | 204 | shelldev_fix_rip(sh); 205 | 206 | CONTEXT ctx = { 0 }; 207 | ctx.ContextFlags = CONTEXT_ALL; 208 | GetThreadContext(sh->procInfo.hThread, &ctx); 209 | 210 | memcpy(&sh->prev, &sh->curr, sizeof(CONTEXT)); 211 | memcpy(&sh->curr, &ctx, sizeof(CONTEXT)); 212 | } 213 | 214 | static BOOL shelldev_assemble(const char* instruction, std::vector& data, size_t address) 215 | { 216 | using namespace asmjit; 217 | using namespace asmtk; 218 | 219 | // Setup CodeInfo 220 | JitRuntime jr; 221 | 222 | // Setup CodeHolder 223 | CodeHolder code; 224 | Error err = code.init(jr.environment()); 225 | if (err != kErrorOk) 226 | { 227 | printf("ERROR: %s\n", DebugUtils::errorAsString(err)); 228 | return FALSE; 229 | } 230 | 231 | // Attach an assembler to the CodeHolder. 232 | x86::Assembler a(&code); 233 | 234 | // Create AsmParser that will emit to X86Assembler. 235 | AsmParser p(&a); 236 | 237 | // Parse some assembly. 238 | err = p.parse(instruction); 239 | 240 | // Error handling 241 | if (err != kErrorOk) 242 | { 243 | printf("ERROR: %s (instruction: \"%s\")\n", DebugUtils::errorAsString(err), instruction); 244 | return FALSE; 245 | } 246 | 247 | // If we are done, you must detach the Assembler from CodeHolder or sync 248 | // it, so its internal state and position is synced with CodeHolder. 249 | code.detach(&a); 250 | 251 | // Now you can print the code, which is stored in the first section (.text). 252 | CodeBuffer& buffer = code.sectionById(0)->buffer(); 253 | for (size_t i = 0; i < buffer.size(); i++) 254 | data.push_back(buffer.data()[i]); 255 | 256 | return TRUE; 257 | } 258 | 259 | static BOOL shelldev_jump(asmjit::Label loop, asmjit::x86::Assembler* a, std::string instruction) 260 | { 261 | // Jump instruction checker 262 | std::string jump; 263 | for (int i = 0; i < instruction.size(); i++) 264 | if (instruction[i] != ' ') 265 | jump += instruction[i]; 266 | else break; 267 | 268 | if (jump == "jmp") 269 | a->jmp(loop); 270 | else if (jump == "je") 271 | a->je(loop); 272 | else if (jump == "jz") 273 | a->jz(loop); 274 | else if (jump == "jne") 275 | a->jne(loop); 276 | else if (jump == "jnz") 277 | a->jnz(loop); 278 | else if (jump == "jg") 279 | a->jg(loop); 280 | else if (jump == "jnle") 281 | a->jnle(loop); 282 | else if (jump == "jge") 283 | a->jge(loop); 284 | else if (jump == "jnl") 285 | a->jnl(loop); 286 | else if (jump == "jl") 287 | a->jl(loop); 288 | else if (jump == "jnge") 289 | a->jnge(loop); 290 | else if (jump == "jle") 291 | a->jle(loop); 292 | else if (jump == "jng") 293 | a->jng(loop); 294 | else if (jump == "ja") 295 | a->ja(loop); 296 | else if (jump == "jnbe") 297 | a->jnbe(loop); 298 | else if (jump == "jae") 299 | a->jae(loop); 300 | else if (jump == "jnb") 301 | a->jnb(loop); 302 | // Add more options 303 | else 304 | return FALSE; 305 | 306 | return TRUE; 307 | } 308 | 309 | // If jump instruction detected, reassemble everything 310 | BOOL shelldev_assemble_loop(std::vector* assemblies, std::vector& data, size_t address) 311 | { 312 | using namespace asmjit; 313 | using namespace asmtk; 314 | 315 | struct Loop 316 | { 317 | std::string name; 318 | Label label; 319 | }; 320 | 321 | // Setup CodeInfo 322 | JitRuntime jr; 323 | 324 | // Setup CodeHolder 325 | CodeHolder code; 326 | Error err = code.init(jr.environment()); 327 | if (err != kErrorOk) 328 | { 329 | printf("ERROR: %s\n", DebugUtils::errorAsString(err)); 330 | return FALSE; 331 | } 332 | 333 | // Attach an assembler to the CodeHolder. 334 | x86::Assembler a(&code); 335 | 336 | std::vector loops; 337 | AsmParser p(&a); 338 | 339 | for (int i = 0; i < assemblies->size(); i++) 340 | { 341 | std::string instruction = assemblies->at(i).instruction; 342 | 343 | if (instruction[instruction.size() - 1] == ':') 344 | { 345 | Loop loop; 346 | loop.name = instruction.erase(instruction.size() - 1, 1); // Remove : from label 347 | loop.label = a.newLabel(); 348 | 349 | a.bind(loop.label); 350 | loops.push_back(loop); 351 | } 352 | else if (instruction[0] == 'j') 353 | { 354 | std::string labelName; 355 | for (int i = instruction.size() - 1; i >= 0; i--) 356 | { 357 | if (instruction[i] != ' ') 358 | labelName += instruction[i]; 359 | else break; 360 | } 361 | 362 | std::reverse(labelName.begin(), labelName.end()); 363 | 364 | Label label; 365 | for (int i = 0; i < loops.size(); i++) 366 | if (loops.at(i).name == labelName) 367 | label = loops.at(i).label; 368 | 369 | if (!shelldev_jump(label, &a, instruction)) 370 | return FALSE; 371 | } 372 | else 373 | { 374 | err = p.parse(instruction.c_str()); 375 | } 376 | } 377 | 378 | code.detach(&a); 379 | 380 | // Now you can print the code, which is stored in the first section (.text). 381 | CodeBuffer& buffer = code.sectionById(0)->buffer(); 382 | for (size_t i = 0; i < buffer.size(); i++) 383 | data.push_back(buffer.data()[i]); 384 | 385 | return TRUE; 386 | } 387 | 388 | BOOL shelldev_run_shellcode(shell_t* sh, std::vector* assemblies) 389 | { 390 | #ifdef _M_X64 391 | size_t addr = sh->curr.Rip; 392 | #elif defined(_M_IX86) 393 | size_t addr = sh->curr.Eip; 394 | #endif 395 | 396 | for (int i = 0; i < assemblies->capacity(); i++) 397 | { 398 | if (assemblies->at(i).size == 0) 399 | i++; 400 | 401 | std::vector data; 402 | if (!shelldev_assemble(assemblies->at(i).instruction.c_str(), data, addr + data.size())) 403 | return TRUE; 404 | 405 | assemblies->at(i).bytes = data; 406 | assemblies->at(i).size = sizeof(data); 407 | 408 | if (!shelldev_write_shellcode(sh, data.data(), data.size())) 409 | return FALSE; 410 | 411 | shelldev_debug_shellcode(sh); 412 | } 413 | 414 | shelldev_print_registers(sh); 415 | 416 | return TRUE; 417 | } 418 | 419 | BOOL shelldev_run_shellcode(shell_t* sh, std::string assembly, std::vector* assemblies) 420 | { 421 | std::vector instructions = split(assembly, ";"); 422 | std::vector data; 423 | 424 | #ifdef _M_X64 425 | size_t addr = sh->curr.Rip; 426 | #elif defined(_M_IX86) 427 | size_t addr = sh->curr.Eip; 428 | #endif 429 | 430 | for (int i = 0; i < instructions.size(); i++) 431 | { 432 | std::vector itms = split(instructions[i], "\""); 433 | for (std::vector::iterator it = itms.begin() + 1; it != itms.end(); it += 2) 434 | { 435 | std::string reg = get_register(instructions[i]); 436 | std::vector parse = shelldev_parse_string(reg, *it); 437 | 438 | instructions.insert(instructions.end(), parse.begin(), parse.end()); 439 | instructions.erase(instructions.begin() + i); 440 | } 441 | } 442 | 443 | for (std::string& instruction : instructions) 444 | { 445 | std::vector temp; 446 | 447 | if(instruction[instruction.size() - 1] != ':') 448 | if (!shelldev_assemble(instruction.c_str(), temp, addr + temp.size())) 449 | return FALSE; 450 | 451 | asm_t a; 452 | a.instruction = instruction; 453 | a.bytes = temp; 454 | a.size = sizeof(temp); 455 | 456 | assemblies->push_back(a); 457 | data.insert(data.end(), temp.begin(), temp.end()); 458 | } 459 | 460 | if (!shelldev_write_shellcode(sh, data.data(), data.size())) 461 | return FALSE; 462 | 463 | shelldev_debug_shellcode(sh); 464 | 465 | shelldev_print_registers(sh); 466 | 467 | return TRUE; 468 | } 469 | 470 | BOOL shelldev_loop_eval(std::string jump, shell_t* sh, std::vector* assemblies) 471 | { 472 | #ifdef _M_X64 473 | size_t addr = sh->curr.Rip; 474 | #elif defined(_M_IX86) 475 | size_t addr = sh->curr.Eip; 476 | #endif 477 | 478 | std::vector data; 479 | 480 | asm_t asmt; 481 | asmt.instruction = jump; 482 | 483 | assemblies->push_back(asmt); 484 | 485 | if (!shelldev_assemble_loop(assemblies, data, addr + data.size())) 486 | return FALSE; 487 | 488 | // assemblies->at(assemblies->size() - 1).bytes; 489 | 490 | if (!shelldev_write_shellcode(sh, data.data(), data.size())) 491 | return FALSE; 492 | 493 | shelldev_debug_shellcode(sh); 494 | 495 | shelldev_print_registers(sh); 496 | 497 | 498 | return TRUE; 499 | } 500 | 501 | BOOL shelldev_eval(shell_t* sh, std::string command, std::vector* assemblies) 502 | { 503 | try 504 | { 505 | if (command.at(0) == '.') 506 | return shelldev_run_command(sh, command, assemblies); 507 | else if (command.at(0) == 'j') 508 | return shelldev_loop_eval(command, sh, assemblies); 509 | 510 | return shelldev_run_shellcode(sh, command, assemblies); 511 | } 512 | catch (...) 513 | { 514 | shelldev_print_errors("An unhandled C++ exception occurred."); 515 | } 516 | 517 | return TRUE; 518 | } -------------------------------------------------------------------------------- /Shellcodev/command.cpp: -------------------------------------------------------------------------------- 1 | #include "repl.h" 2 | #include "color.hpp" 3 | 4 | BOOL xorNulls; 5 | 6 | // Helper vectors for selecting random registers in .rsf 7 | // TODO: Add those of XMM registers to x64 that are non-mutable by any flag conditions (especially by CF and ZF) 8 | std::vector gregs_x64{ "rax", "rbx", "rcx", "rdx", "r8", "r9", "r10", "r11", "r12"}; 9 | std::vector gregs_x32{ "eax", "ebx", "ecx", "edx"}; 10 | 11 | void shelldev_print_assembly(unsigned char* encode, size_t size) 12 | { 13 | printf("assembled (%zu bytes): ", size); 14 | 15 | for (size_t i = 0; i < size; ++i) 16 | if (encode[i] == 0x0) 17 | //std::cout << std::hex << dye::light_red("0x") << dye::light_red(static_cast(encode[i])) << " "; 18 | std::cout << std::hex << dye::light_red("0x00") << " "; 19 | else 20 | //std::cout << std::hex << "0x" << static_cast(encode[i]) << " "; 21 | // SUGGESTION: The above can also be used in .toshell with hex cast but I am not sure if it won't break int-based size extraction of bytearray 22 | printf("0x%x, ", encode[i]); 23 | 24 | printf("\n"); 25 | } 26 | 27 | static BOOL shelldev_command_kernel32(shell_t* sh, std::vector parts) 28 | { 29 | do 30 | { 31 | if (parts.size() != 1) 32 | { 33 | shelldev_print_errors("Usage: .kernel32 "); 34 | break; 35 | } 36 | 37 | HMODULE kernel32 = GetModuleHandleA("kernel32.dll"); 38 | FARPROC addr = GetProcAddress(kernel32, parts[0].c_str()); 39 | 40 | if (!addr) 41 | { 42 | shelldev_print_errors("Unable to find that export!"); 43 | break; 44 | } 45 | 46 | shelldev_print_good("Kernel32.dll at %p, export located at %p", (LPVOID)kernel32, (LPVOID)addr); 47 | 48 | } while (0); 49 | 50 | return TRUE; 51 | } 52 | 53 | static BOOL shelldev_command_load(shell_t* sh, std::vector parts) 54 | { 55 | if (parts.size() == 0 || parts.size() > 2) 56 | { 57 | shelldev_print_errors("Usage: .load * | *Optional"); 58 | return TRUE; 59 | } 60 | 61 | HMODULE dll = LoadLibraryA(parts[0].c_str()); 62 | FARPROC addr = nullptr; 63 | if(parts.size() == 2) 64 | addr = GetProcAddress(dll, parts[1].c_str()); 65 | 66 | if (parts.size() == 2 && !addr) 67 | { 68 | shelldev_print_errors("Unable to find that export!"); 69 | return TRUE; 70 | } 71 | 72 | shelldev_print_good("%s at %p, export located at %p", parts[0].c_str(), (LPVOID)dll, (LPVOID)addr); 73 | 74 | return TRUE; 75 | } 76 | 77 | 78 | static BOOL shelldev_command_shellcode(shell_t* sh, std::vector parts) 79 | { 80 | do 81 | { 82 | std::string fixed = join(parts, ""); 83 | std::string bin_str = from_hex(std::begin(fixed), std::end(fixed)); 84 | std::vector bytes(std::begin(bin_str), std::end(bin_str)); 85 | 86 | if (bytes.size() == 0) 87 | { 88 | shelldev_print_errors("Usage: .shellcode hexdata"); 89 | break; 90 | } 91 | 92 | if (!shelldev_write_shellcode(sh, &bytes[0], bytes.size())) 93 | { 94 | shelldev_print_errors("Unable to allocate shellcode!"); 95 | return TRUE; 96 | } 97 | 98 | shelldev_debug_shellcode(sh); 99 | shelldev_print_registers(sh); 100 | 101 | } while (0); 102 | 103 | return TRUE; 104 | } 105 | 106 | static BOOL shelldev_command_peb(shell_t* sh, std::vector parts, std::vector* assemblies) 107 | { 108 | std::string instructions; 109 | #ifdef _M_X64 110 | // xor eax, eax 111 | // mov rax, gs:[eax+0x60] 112 | // unsigned char bytes[] = { 0x31, 0xc0, 0x65, 0x48, 0x8b, 0x40, 0x60 }; 113 | instructions = "xor eax, eax;mov rax, gs:[eax+0x60]"; 114 | #elif defined(_M_IX86) 115 | // xor eax, eax 116 | // mov eax, fs:[eax+0x30] 117 | // unsigned char bytes[] = { 0x31, 0xC0, 0x64, 0x8B, 0x40, 0x30 }; 118 | instructions = "xor eax, eax;mov eax, fs:[eax+0x30]"; 119 | #endif 120 | 121 | shelldev_run_shellcode(sh, instructions, assemblies); 122 | 123 | return TRUE; 124 | } 125 | 126 | 127 | static BOOL shelldev_command_abort(shell_t* sh, std::vector* assemblies) 128 | { 129 | // TODO: I will add loop binder and unbinder so that below works + add exit routine 130 | std::string instructions; 131 | #ifdef _M_X64 132 | instructions = "push rbx; xor rbx, rbx; cmp rax, rbx; jne exitlogic; pop rbx; exitlogic:"; 133 | #elif defined(_M_IX86) 134 | instructions = "push ebx; xor ebx, ebx; cmp eax, ebx; jne exitlogic; pop ebx; exitlogic:"; 135 | #endif 136 | 137 | shelldev_run_shellcode(sh, instructions, assemblies); 138 | 139 | return TRUE; 140 | } 141 | 142 | static BOOL shelldev_command_allocate(shell_t* sh, std::vector parts) 143 | { 144 | do 145 | { 146 | if (parts.size() != 1) 147 | { 148 | shelldev_print_errors("Usage: .alloc size"); 149 | break; 150 | } 151 | 152 | size_t size = atol(parts[0].c_str()); 153 | 154 | if (size == 0) 155 | { 156 | shelldev_print_errors("Usage: .alloc size"); 157 | break; 158 | } 159 | 160 | LPVOID addr = VirtualAllocEx( 161 | sh->procInfo.hProcess, 162 | NULL, 163 | size, 164 | MEM_COMMIT, 165 | PAGE_EXECUTE_READWRITE 166 | ); 167 | 168 | if (!addr) 169 | { 170 | shelldev_print_errors("Unable to allocate memory!"); 171 | break; 172 | } 173 | 174 | shelldev_print_good("Allocated RWX memory at %p (size: %d)", addr, size); 175 | } while (0); 176 | 177 | return TRUE; 178 | } 179 | 180 | static BOOL shelldev_command_write(shell_t* sh, std::vector parts) 181 | { 182 | 183 | do 184 | { 185 | if (parts.size() < 2) 186 | { 187 | shelldev_print_errors("Usage: .write addr hexdata"); 188 | break; 189 | } 190 | 191 | 192 | unsigned long long x = 0; 193 | std::istringstream iss(parts[0]); 194 | iss >> std::hex >> x; 195 | parts.erase(parts.begin()); 196 | 197 | std::string fixed = join(parts, ""); 198 | //separate<2, ' '>(fixed); 199 | std::string bin_str = from_hex(std::begin(fixed), std::end(fixed)); 200 | std::vector bytes(std::begin(bin_str), std::end(bin_str)); 201 | 202 | if (x == 0 || bytes.size() == 0) 203 | { 204 | shelldev_print_errors("Usage: .write addr hexdata"); 205 | break; 206 | } 207 | 208 | SIZE_T nBytes; 209 | 210 | if (!WriteProcessMemory( 211 | sh->procInfo.hProcess, 212 | (LPVOID)x, 213 | &bytes[0], 214 | bytes.size(), 215 | &nBytes 216 | )) 217 | { 218 | shelldev_print_errors("Unable to write hex data!"); 219 | break; 220 | } 221 | 222 | shelldev_print_good("Wrote %d bytes to %p", nBytes, (LPVOID)x); 223 | shelldev_print_bytes(&bytes[0], (int)bytes.size(), x); 224 | 225 | } while (0); 226 | 227 | 228 | return TRUE; 229 | } 230 | 231 | static BOOL shelldev_command_read(shell_t* sh, std::vector parts) 232 | { 233 | do 234 | { 235 | if (parts.size() != 2) 236 | { 237 | shelldev_print_errors("Usage: .read addr size"); 238 | break; 239 | } 240 | 241 | size_t size = atol(parts[1].c_str()); 242 | 243 | unsigned long long x = 0; 244 | std::istringstream iss(parts[0]); 245 | iss >> std::hex >> x; 246 | 247 | if (size == 0 || x == 0) 248 | { 249 | shelldev_print_errors("Usage: .read addr size"); 250 | break; 251 | } 252 | 253 | std::vector bytes; 254 | bytes.reserve(size); 255 | 256 | SIZE_T nBytes; 257 | 258 | if (!ReadProcessMemory( 259 | sh->procInfo.hProcess, 260 | (LPCVOID)x, 261 | &bytes[0], 262 | size, 263 | &nBytes 264 | )) 265 | { 266 | shelldev_print_errors("Unable to read from address: %p!", (LPVOID)x); 267 | break; 268 | } 269 | 270 | shelldev_print_bytes(&bytes[0], (int)nBytes, x); 271 | 272 | } while (0); 273 | 274 | return TRUE; 275 | } 276 | 277 | static BOOL shelldev_command_loadlibrary(shell_t* sh, std::vector parts) 278 | { 279 | do 280 | { 281 | if (parts.size() < 1) 282 | { 283 | shelldev_print_errors("The path is missing!"); 284 | break; 285 | } 286 | 287 | std::string dll = join(parts, ""); 288 | 289 | LPVOID pStr = VirtualAllocEx( 290 | sh->procInfo.hProcess, 291 | NULL, 292 | dll.length() + 1, 293 | MEM_COMMIT, 294 | PAGE_READWRITE); 295 | 296 | if (!pStr) 297 | { 298 | shelldev_print_errors("Unable to allocate DLL path!"); 299 | break; 300 | } 301 | 302 | SIZE_T nBytes; 303 | 304 | if (!WriteProcessMemory( 305 | sh->procInfo.hProcess, 306 | pStr, 307 | &dll[0], 308 | dll.length() + 1, 309 | &nBytes 310 | )) 311 | { 312 | shelldev_print_errors("Unable to write DLL path!"); 313 | break; 314 | } 315 | 316 | DWORD dwThreadId; 317 | 318 | HANDLE hThread = CreateRemoteThread( 319 | sh->procInfo.hProcess, 320 | NULL, 321 | 0, 322 | (LPTHREAD_START_ROUTINE)LoadLibraryA, 323 | pStr, 324 | 0, 325 | &dwThreadId); 326 | 327 | if (hThread == INVALID_HANDLE_VALUE) 328 | { 329 | shelldev_print_errors("Failed to call LoadLibraryA()."); 330 | break; 331 | } 332 | 333 | shelldev_print_good("LoadLibraryA() called for %s!", dll.c_str()); 334 | 335 | } while (0); 336 | 337 | return TRUE; 338 | } 339 | 340 | BOOL shelldev_command_registers(shell_t* sh, std::vector parts) 341 | { 342 | shelldev_print_registers_all(sh); 343 | return TRUE; 344 | } 345 | 346 | static BOOL shelldev_command_reset_assemblies(std::vector* assemblies) 347 | { 348 | shelldev_print_good("Resetting the assemblies"); 349 | assemblies->clear(); 350 | return TRUE; 351 | } 352 | 353 | static BOOL shelldev_command_reset(shell_t* sh) 354 | { 355 | shelldev_print_good("Resetting the environment"); 356 | TerminateProcess(sh->procInfo.hProcess, 0); 357 | DebugActiveProcessStop(sh->procInfo.dwProcessId); 358 | return TRUE; 359 | } 360 | 361 | static BOOL shelldev_command_fixip(shell_t* sh) 362 | { 363 | shelldev_print_good("Trying to fix the instruction pointer"); 364 | CONTEXT ctx = { 0 }; 365 | ctx.ContextFlags = CONTEXT_ALL; 366 | GetThreadContext(sh->procInfo.hThread, &ctx); 367 | 368 | #ifdef _M_X64 369 | ctx.Rip = ctx.Rip - 1; 370 | #elif defined(_M_IX86) 371 | ctx.Eip = ctx.Eip - 1; 372 | #endif 373 | SetThreadContext(sh->procInfo.hThread, &ctx); 374 | return TRUE; 375 | } 376 | 377 | static BOOL shelldev_list(std::vector* assemblies) 378 | { 379 | int count = 0; 380 | for (asm_t assembly : *assemblies) 381 | { 382 | std::cout << std::dec << dye::light_green(count) << ".\t"; 383 | std::cout << assembly.instruction; 384 | 385 | for (int i = 0; i < (24 - assembly.instruction.size()); i++) 386 | std::cout << " "; 387 | 388 | std::cout << dye::light_green("|\t"); 389 | 390 | for (unsigned char byte : assembly.bytes) 391 | if (byte == 0x0) 392 | std::cout << std::hex << dye::red("0x") << dye::red(static_cast(byte)) << " "; 393 | else 394 | std::cout << std::hex << "0x" << static_cast(byte) << " "; 395 | 396 | std::cout << std::endl; 397 | count++; 398 | } 399 | 400 | if (count == 0) { 401 | shelldev_print_errors("No instructions inserted"); 402 | } 403 | 404 | return TRUE; 405 | } 406 | 407 | static BOOL shelldev_edit(shell_t* sh, std::vector* assemblies, std::vector parts) 408 | { 409 | if (!is_number(parts[0])) 410 | return FALSE; 411 | 412 | std::cout << "Editing line: " << dye::light_green(parts[0]) << std::endl; 413 | std::cout << "Editing instruction: " << dye::light_green(assemblies->at(std::stoi(parts[0])).instruction) << std::endl; 414 | std::cout << "Type '-' to quit editing" << std::endl; 415 | 416 | std::string input = shelldev_read(); 417 | if (input == "-") 418 | return TRUE; 419 | 420 | assemblies->at(std::stoi(parts[0])).instruction = input; 421 | 422 | if (!shelldev_run_shellcode(sh, assemblies)) 423 | return FALSE; 424 | 425 | return TRUE; 426 | } 427 | 428 | static BOOL shelldev_swap(shell_t* sh, std::vector* assemblies, std::vector parts) 429 | { 430 | if (parts.size() != 2) { 431 | shelldev_print_errors("Usage: .swap "); 432 | return FALSE; 433 | } 434 | 435 | if (!is_number(parts[0])) { 436 | return FALSE; 437 | } 438 | 439 | if (!is_number(parts[1])) { 440 | return FALSE; 441 | } 442 | 443 | std::string src_instr = assemblies->at(std::stoi(parts[0])).instruction; 444 | std::string dst_instr = assemblies->at(std::stoi(parts[1])).instruction; 445 | 446 | std::cout << "[*] " << dye::light_purple(src_instr)<< " <-> " << dye::purple_on_black(src_instr) << std::endl; 447 | 448 | assemblies->at(std::stoi(parts[0])).instruction = dst_instr; 449 | assemblies->at(std::stoi(parts[1])).instruction = src_instr; 450 | 451 | if (!shelldev_run_shellcode(sh, assemblies)) { 452 | return FALSE; 453 | } 454 | 455 | 456 | return TRUE; 457 | } 458 | 459 | static BOOL shelldev_toshell(shell_t* sh, std::vector* assemblies, std::vector parts) 460 | { 461 | #ifdef _M_X64 462 | size_t addr = sh->curr.Rip; 463 | #elif defined(_M_IX86) 464 | size_t addr = sh->curr.Eip; 465 | #endif 466 | 467 | std::vector data; 468 | 469 | if (!shelldev_assemble_loop(assemblies, data, addr + data.size())) 470 | return FALSE; 471 | 472 | printf("\n"); 473 | if (parts[0] == "c") 474 | { 475 | int count = 0; 476 | 477 | std::cout << "unsigned char shellcode[] = {" << std::endl; 478 | for (int i = 0; i < data.size(); i++) 479 | { 480 | if (count != 0 && count % 12 == 0) 481 | printf("\n"); 482 | else if (i == data.size() - 1) 483 | printf("0x%02x ", data.at(i)); 484 | else 485 | printf("0x%02x, ", data.at(i)); 486 | 487 | count++; 488 | } 489 | std::cout << "};" << std::endl; 490 | } 491 | else if (parts[0] == "cs") 492 | { 493 | int count = 0; 494 | 495 | std::cout << "byte[] shellcode = {" << std::endl; 496 | for (int i = 0; i < data.size(); i++) 497 | { 498 | if (count != 0 && count % 12 == 0) 499 | printf("\n"); 500 | else if (i == data.size() - 1) 501 | printf("0x%02x ", data.at(i)); 502 | else 503 | printf("0x%02x, ", data.at(i)); 504 | 505 | count++; 506 | } 507 | std::cout << "};" << std::endl; 508 | } 509 | else if (parts[0] == "py") 510 | { 511 | std::cout << "shellcode = (b\""; 512 | for (int i = 0; i < data.size(); i++) 513 | { 514 | printf("\\x%02x", data.at(i)); 515 | } 516 | std::cout << "\")" << std::endl; 517 | } 518 | else if (parts[0] == "raw") 519 | { 520 | for (int i = 0; i < data.size(); i++) 521 | { 522 | printf("%02X", data.at(i)); 523 | } 524 | printf("\n"); 525 | } 526 | printf("\n"); 527 | 528 | return TRUE; 529 | } 530 | 531 | static BOOL shelldev_command_delete(shell_t* sh, std::vector* assemblies, std::vector parts) 532 | { 533 | assemblies->erase(assemblies->begin() + std::stoi(parts[0])); 534 | 535 | shelldev_run_shellcode(sh, assemblies); 536 | 537 | return TRUE; 538 | } 539 | 540 | static BOOL shelldev_command_insert(shell_t* sh, std::vector* assemblies, std::vector parts) 541 | { 542 | if (!is_number(parts[0])) 543 | { 544 | shelldev_print_errors("Please specify index after which insertion should happen"); 545 | return FALSE; 546 | } 547 | int base_insert_idx = std::stoi(parts[0]); 548 | 549 | std::cout << "Inserting at position: " << dye::light_green(std::stoi(parts[0]) + 1) << std::endl; 550 | std::cout << "Type '-' to quit editing" << std::endl; 551 | 552 | std::string input = shelldev_read(); 553 | if (input == "-") { 554 | return TRUE; 555 | } 556 | 557 | asm_t temp; 558 | temp.instruction = input; 559 | assemblies->insert(assemblies->begin() + base_insert_idx, temp); 560 | 561 | base_insert_idx += 1; 562 | 563 | shelldev_run_shellcode(sh, assemblies); 564 | 565 | return TRUE; 566 | } 567 | 568 | static BOOL shelldev_xoring() 569 | { 570 | if (xorNulls) { 571 | xorNulls = FALSE; 572 | std::cout << "Xoring is " << dye::red("disabled") << std::endl; 573 | } 574 | else { 575 | xorNulls = TRUE; 576 | std::cout << "Xoring is " << dye::green("enabled") << std::endl; 577 | } 578 | return TRUE; 579 | } 580 | 581 | static BOOL shelldev_command_stackframe(shell_t* sh, std::vector* assemblies) 582 | { 583 | #ifdef _M_X64 584 | std::string instructions = "push rbp;mov rbp, rsp"; 585 | #elif defined(_M_IX86) 586 | std::string instructions = "push ebp;mov ebp, esp"; 587 | #endif 588 | shelldev_run_shellcode(sh, instructions, assemblies); 589 | 590 | return TRUE; 591 | } 592 | 593 | //TODO: Finish counting up difference between pushes and pops and appending a proper number of pops 594 | static BOOL shelldev_command_stackreset(shell_t* sh, std::vector* assemblies) 595 | { 596 | /* int numpush = 0; 597 | int numpop = 0; 598 | std::srand(std::time(0)); 599 | #ifdef _M_X64 600 | int randpos = std::rand() % gregs_x64.size(); 601 | std::string randreg = gregs_x64[randpos]; 602 | #elif defined(_M_IX86) 603 | int randpos = std::rand() % gregs_x32.size(); 604 | std::string randreg = gregs_x32[randpos]; 605 | #endif 606 | std::string popsled = ""; 607 | sprintf("push %s", randreg); 608 | for (asm_t assembly : *assemblies) { 609 | std::string first_mnemonic = split(assembly.instruction, " ")[0]; 610 | if ( first_mnemonic == "push" ) { 611 | numpop += 1; 612 | popsled += std::format(";pop %s", randreg); 613 | } 614 | } 615 | 616 | shelldev_print_good("Resetting stack using %d POP instructions to register %s", numpop, randreg); 617 | shelldev_run_shellcode(sh, popsled, assemblies); 618 | */ 619 | return TRUE; 620 | } 621 | 622 | static BOOL shelldev_command_clearstackframe(shell_t* sh, std::vector* assemblies) 623 | { 624 | std::srand(std::time(0)); 625 | std::string instructions = ""; 626 | int randbool = std::rand() % 2; 627 | if (randbool) { 628 | #ifdef _M_X64 629 | instructions = "mov rsp, rbp; pop rbp"; 630 | #elif defined(_M_IX86) 631 | instructions = "mov esp, ebp; pop ebp"; 632 | #endif 633 | } else { 634 | instructions = "ret"; 635 | } 636 | shelldev_run_shellcode(sh, instructions, assemblies); 637 | 638 | return TRUE; 639 | } 640 | 641 | static BOOL winrepl_command_help() 642 | { 643 | std::cout << ".help\t\t\tShow this help screen." << std::endl; 644 | std::cout << ".registers\t\tShow more detailed register info" << std::endl; 645 | std::cout << ".list\t\t\tShow list of previously executed assembly instructions" << std::endl; 646 | std::cout << ".ins \t\tInsert instructions after index" << std::endl; 647 | std::cout << ".edit \t\tEdit specified line in list" << std::endl; 648 | std::cout << ".rem \t\tRemove a specified instruction" << std::endl; 649 | std::cout << ".del \t\tDelete specified line from list" << std::endl; 650 | std::cout << ".xor\t\t\tEnable or disable and show status of nullbyte xoring" << std::endl; 651 | std::cout << ".nsf\t\t\tEstablish new stackframe" << std::endl; 652 | std::cout << ".csf\t\t\tClear stackframe and load previous frame" << std::endl; 653 | std::cout << ".rsf\t\t\tFully reset stack by ensuring equivalent number of LIFO operations" << std::endl; 654 | std::cout << ".read \tRead from a memory address" << std::endl; 655 | std::cout << ".swap \tSwap source with destination lines" << std::endl; 656 | std::cout << ".write \tWrite to a memory address" << std::endl; 657 | std::cout << ".toshell \tConvert list to selected shellcode format. Available formats: c, cs, raw, py" << std::endl; 658 | std::cout << ".inject \t\tTest shellcode by injecting it into the process. Works currently only on x86!" << std::endl; 659 | std::cout << ".alloc \t\tAllocate a memory buffer" << std::endl; 660 | std::cout << ".loadlibrary \tLoad a DLL into the process" << std::endl; 661 | std::cout << ".kernel32 \tGet address of a kernel32 export" << std::endl; 662 | std::cout << ".load *\tGet address of a specified export. *Optional" << std::endl; 663 | std::cout << ".shellcode \tExecute raw shellcode" << std::endl; 664 | std::cout << ".peb\t\t\tLoads PEB into accumulator" << std::endl; 665 | std::cout << ".fixip\t\t\tFix instruction pointer when 0xCC or 0xC3 is encountered" << std::endl; 666 | std::cout << ".reset\t\t\tStart a new environment" << std::endl; 667 | std::cout << ".abort\t\t\tInsert logic check and quit if AX != 0" << std::endl; 668 | std::cout << ".quit\t\t\tExit the program" << std::endl; 669 | 670 | return TRUE; 671 | } 672 | 673 | 674 | BOOL shelldev_run_command(shell_t* sh, std::string command, std::vector* assemblies) 675 | { 676 | std::vector parts = split(command, " "); 677 | std::string mainCmd = parts[0]; 678 | parts.erase(parts.begin()); 679 | 680 | if (mainCmd == ".registers") 681 | return shelldev_command_registers(sh, parts); 682 | else if (mainCmd == ".list") 683 | return shelldev_list(assemblies); 684 | else if (mainCmd == ".edit") 685 | return shelldev_edit(sh, assemblies, parts); 686 | else if (mainCmd == ".swap") 687 | return shelldev_swap(sh, assemblies, parts); 688 | else if (mainCmd == ".toshell") 689 | return shelldev_toshell(sh, assemblies, parts); 690 | else if (mainCmd == ".inject") 691 | return shelldev_inject_shellcode(assemblies, parts[0]); 692 | else if (mainCmd == ".read") 693 | return shelldev_command_read(sh, parts); 694 | else if (mainCmd == ".nsf") 695 | return shelldev_command_stackframe(sh, assemblies); 696 | else if (mainCmd == ".csf") 697 | return shelldev_command_clearstackframe(sh, assemblies); 698 | else if (mainCmd == ".rsf") 699 | return shelldev_command_stackreset(sh, assemblies); 700 | else if (mainCmd == ".del") 701 | return shelldev_command_delete(sh, assemblies, parts); 702 | else if (mainCmd == ".ins") 703 | return shelldev_command_insert(sh, assemblies, parts); 704 | else if (mainCmd == ".abort") 705 | return shelldev_command_abort(sh, assemblies); 706 | else if (mainCmd == ".xor") 707 | return shelldev_xoring(); 708 | else if (mainCmd == ".write") 709 | return shelldev_command_write(sh, parts); 710 | else if (mainCmd == ".fixip") 711 | return shelldev_command_fixip(sh); 712 | else if (mainCmd == ".alloc") 713 | return shelldev_command_allocate(sh, parts); 714 | else if (mainCmd == ".loadlibrary") 715 | return shelldev_command_loadlibrary(sh, parts); 716 | else if (mainCmd == ".kernel32") 717 | return shelldev_command_kernel32(sh, parts); 718 | else if (mainCmd == ".load") 719 | return shelldev_command_load(sh, parts); 720 | else if (mainCmd == ".reset") 721 | return (shelldev_command_reset_assemblies(assemblies) && shelldev_command_reset(sh)); 722 | else if (mainCmd == ".shellcode") 723 | return shelldev_command_shellcode(sh, parts); 724 | else if (mainCmd == ".peb") 725 | return shelldev_command_peb(sh, parts, assemblies); 726 | else if (mainCmd == ".quit" || mainCmd == ".exit") 727 | ExitProcess(0); 728 | else 729 | { 730 | if (mainCmd != ".help") 731 | shelldev_print_errors("Command not found!"); 732 | return winrepl_command_help(); 733 | } 734 | 735 | return TRUE; 736 | } -------------------------------------------------------------------------------- /Shellcodev/color.hpp: -------------------------------------------------------------------------------- 1 | #ifndef COLOR_HPP 2 | #define COLOR_HPP 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | namespace hue 14 | { 15 | constexpr int DEFAULT_COLOR = 7; 16 | constexpr int BAD_COLOR = -256; 17 | 18 | const std::map CODES = { 19 | {"black", 0}, {"k", 0}, 20 | {"blue", 1}, {"b", 1}, 21 | {"green", 2}, {"g", 2}, 22 | {"aqua", 3}, {"a", 3}, 23 | {"red", 4}, {"r", 4}, 24 | {"purple", 5}, {"p", 5}, 25 | {"yellow", 6}, {"y", 6}, 26 | {"white", 7}, {"w", 7}, 27 | {"grey", 8}, {"e", 8}, 28 | {"light blue", 9}, {"lb", 9}, 29 | {"light green", 10}, {"lg", 10}, 30 | {"light aqua", 11}, {"la", 11}, 31 | {"light red", 12}, {"lr", 12}, 32 | {"light purple", 13}, {"lp", 13}, 33 | {"light yellow", 14}, {"ly", 14}, 34 | {"bright white", 15}, {"bw", 15} 35 | }; 36 | 37 | const std::map NAMES = { 38 | { 0, "black"}, 39 | { 1, "blue"}, 40 | { 2, "green"}, 41 | { 3, "aqua"}, 42 | { 4, "red"}, 43 | { 5, "purple"}, 44 | { 6, "yellow"}, 45 | { 7, "white"}, 46 | { 8, "grey"}, 47 | { 9, "light blue"}, 48 | {10, "light green"}, 49 | {11, "light aqua"}, 50 | {12, "light red"}, 51 | {13, "light purple"}, 52 | {14, "light yellow"}, 53 | {15, "bright white"} 54 | }; 55 | 56 | inline bool is_good(int c) 57 | { 58 | return 0 <= c && c < 256; 59 | } 60 | 61 | inline int itoc(int c) 62 | { 63 | return is_good(c) ? c : BAD_COLOR; 64 | } 65 | 66 | inline int itoc(int a, int b) 67 | { 68 | return itoc(a + b * 16); 69 | } 70 | 71 | // std::string to color 72 | int stoc(std::string a) 73 | { 74 | // convert s to lowercase, and format variants like "light_blue" 75 | std::transform(a.begin(), a.end(), a.begin(), [](char c) 76 | { 77 | if ('A' <= c && c <= 'Z') 78 | c = c - 'A' + 'a'; 79 | else if (c == '_' || c == '-') 80 | c = ' '; 81 | return c; 82 | }); 83 | 84 | // operator[] on std::map is non-const, use std::map::at instead 85 | return (CODES.find(a) != CODES.end()) ? CODES.at(a) : BAD_COLOR; 86 | } 87 | 88 | int stoc(std::string a, std::string b) 89 | { 90 | return itoc(stoc(a), stoc(b)); 91 | } 92 | 93 | std::string ctos(int c) 94 | { 95 | return (0 <= c && c < 256) ? 96 | "(text) " + NAMES.at(c % 16) + " + " + 97 | "(background) " + NAMES.at(c / 16) : 98 | "BAD COLOR"; 99 | } 100 | 101 | int get() 102 | { 103 | CONSOLE_SCREEN_BUFFER_INFO i; 104 | return GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &i) ? 105 | i.wAttributes : BAD_COLOR; 106 | } 107 | 108 | int get_text() 109 | { 110 | return (get() != BAD_COLOR) ? get() % 16 : BAD_COLOR; 111 | } 112 | 113 | int get_background() 114 | { 115 | return (get() != BAD_COLOR) ? get() / 16 : BAD_COLOR; 116 | } 117 | 118 | void set(int c) 119 | { 120 | if (is_good(c)) 121 | SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), c); 122 | } 123 | 124 | void set(int a, int b) 125 | { 126 | set(a + b * 16); 127 | } 128 | 129 | void set(std::string a, std::string b) 130 | { 131 | set(stoc(a) + stoc(b) * 16); 132 | } 133 | 134 | void set_text(std::string a) 135 | { 136 | set(stoc(a), get_background()); 137 | } 138 | 139 | void set_background(std::string b) 140 | { 141 | set(get_text(), stoc(b)); 142 | } 143 | 144 | void reset() 145 | { 146 | set(DEFAULT_COLOR); 147 | } 148 | 149 | int invert(int c) 150 | { 151 | if (is_good(c)) { 152 | int a = c % 16; 153 | int b = c / 16; 154 | return b + a * 16; 155 | } 156 | else 157 | return BAD_COLOR; 158 | } 159 | 160 | std::ostream& reset(std::ostream& os) { reset(); return os; } 161 | std::ostream& black(std::ostream& os) { set_text("k"); return os; } 162 | std::ostream& blue(std::ostream& os) { set_text("b"); return os; } 163 | std::ostream& green(std::ostream& os) { set_text("g"); return os; } 164 | std::ostream& aqua(std::ostream& os) { set_text("a"); return os; } 165 | std::ostream& red(std::ostream& os) { set_text("r"); return os; } 166 | std::ostream& purple(std::ostream& os) { set_text("p"); return os; } 167 | std::ostream& yellow(std::ostream& os) { set_text("y"); return os; } 168 | std::ostream& white(std::ostream& os) { set_text("w"); return os; } 169 | std::ostream& grey(std::ostream& os) { set_text("e"); return os; } 170 | std::ostream& light_blue(std::ostream& os) { set_text("lb"); return os; } 171 | std::ostream& light_green(std::ostream& os) { set_text("lg"); return os; } 172 | std::ostream& light_aqua(std::ostream& os) { set_text("la"); return os; } 173 | std::ostream& light_red(std::ostream& os) { set_text("lr"); return os; } 174 | std::ostream& light_purple(std::ostream& os) { set_text("lp"); return os; } 175 | std::ostream& light_yellow(std::ostream& os) { set_text("ly"); return os; } 176 | std::ostream& bright_white(std::ostream& os) { set_text("bw"); return os; } 177 | std::ostream& on_black(std::ostream& os) { set_background("k"); return os; } 178 | std::ostream& on_blue(std::ostream& os) { set_background("b"); return os; } 179 | std::ostream& on_green(std::ostream& os) { set_background("g"); return os; } 180 | std::ostream& on_aqua(std::ostream& os) { set_background("a"); return os; } 181 | std::ostream& on_red(std::ostream& os) { set_background("r"); return os; } 182 | std::ostream& on_purple(std::ostream& os) { set_background("p"); return os; } 183 | std::ostream& on_yellow(std::ostream& os) { set_background("y"); return os; } 184 | std::ostream& on_white(std::ostream& os) { set_background("w"); return os; } 185 | std::ostream& on_grey(std::ostream& os) { set_background("e"); return os; } 186 | std::ostream& on_light_blue(std::ostream& os) { set_background("lb"); return os; } 187 | std::ostream& on_light_green(std::ostream& os) { set_background("lg"); return os; } 188 | std::ostream& on_light_aqua(std::ostream& os) { set_background("la"); return os; } 189 | std::ostream& on_light_red(std::ostream& os) { set_background("lr"); return os; } 190 | std::ostream& on_light_purple(std::ostream& os) { set_background("lp"); return os; } 191 | std::ostream& on_light_yellow(std::ostream& os) { set_background("ly"); return os; } 192 | std::ostream& on_bright_white(std::ostream& os) { set_background("bw"); return os; } 193 | std::ostream& black_on_black(std::ostream& os) { set("k", "k"); return os; } 194 | std::ostream& black_on_blue(std::ostream& os) { set("k", "b"); return os; } 195 | std::ostream& black_on_green(std::ostream& os) { set("k", "g"); return os; } 196 | std::ostream& black_on_aqua(std::ostream& os) { set("k", "a"); return os; } 197 | std::ostream& black_on_red(std::ostream& os) { set("k", "r"); return os; } 198 | std::ostream& black_on_purple(std::ostream& os) { set("k", "p"); return os; } 199 | std::ostream& black_on_yellow(std::ostream& os) { set("k", "y"); return os; } 200 | std::ostream& black_on_white(std::ostream& os) { set("k", "w"); return os; } 201 | std::ostream& black_on_grey(std::ostream& os) { set("k", "e"); return os; } 202 | std::ostream& black_on_light_blue(std::ostream& os) { set("k", "lb"); return os; } 203 | std::ostream& black_on_light_green(std::ostream& os) { set("k", "lg"); return os; } 204 | std::ostream& black_on_light_aqua(std::ostream& os) { set("k", "la"); return os; } 205 | std::ostream& black_on_light_red(std::ostream& os) { set("k", "lr"); return os; } 206 | std::ostream& black_on_light_purple(std::ostream& os) { set("k", "lp"); return os; } 207 | std::ostream& black_on_light_yellow(std::ostream& os) { set("k", "ly"); return os; } 208 | std::ostream& black_on_bright_white(std::ostream& os) { set("k", "bw"); return os; } 209 | std::ostream& blue_on_black(std::ostream& os) { set("b", "k"); return os; } 210 | std::ostream& blue_on_blue(std::ostream& os) { set("b", "b"); return os; } 211 | std::ostream& blue_on_green(std::ostream& os) { set("b", "g"); return os; } 212 | std::ostream& blue_on_aqua(std::ostream& os) { set("b", "a"); return os; } 213 | std::ostream& blue_on_red(std::ostream& os) { set("b", "r"); return os; } 214 | std::ostream& blue_on_purple(std::ostream& os) { set("b", "p"); return os; } 215 | std::ostream& blue_on_yellow(std::ostream& os) { set("b", "y"); return os; } 216 | std::ostream& blue_on_white(std::ostream& os) { set("b", "w"); return os; } 217 | std::ostream& blue_on_grey(std::ostream& os) { set("b", "e"); return os; } 218 | std::ostream& blue_on_light_blue(std::ostream& os) { set("b", "lb"); return os; } 219 | std::ostream& blue_on_light_green(std::ostream& os) { set("b", "lg"); return os; } 220 | std::ostream& blue_on_light_aqua(std::ostream& os) { set("b", "la"); return os; } 221 | std::ostream& blue_on_light_red(std::ostream& os) { set("b", "lr"); return os; } 222 | std::ostream& blue_on_light_purple(std::ostream& os) { set("b", "lp"); return os; } 223 | std::ostream& blue_on_light_yellow(std::ostream& os) { set("b", "ly"); return os; } 224 | std::ostream& blue_on_bright_white(std::ostream& os) { set("b", "bw"); return os; } 225 | std::ostream& green_on_black(std::ostream& os) { set("g", "k"); return os; } 226 | std::ostream& green_on_blue(std::ostream& os) { set("g", "b"); return os; } 227 | std::ostream& green_on_green(std::ostream& os) { set("g", "g"); return os; } 228 | std::ostream& green_on_aqua(std::ostream& os) { set("g", "a"); return os; } 229 | std::ostream& green_on_red(std::ostream& os) { set("g", "r"); return os; } 230 | std::ostream& green_on_purple(std::ostream& os) { set("g", "p"); return os; } 231 | std::ostream& green_on_yellow(std::ostream& os) { set("g", "y"); return os; } 232 | std::ostream& green_on_white(std::ostream& os) { set("g", "w"); return os; } 233 | std::ostream& green_on_grey(std::ostream& os) { set("g", "e"); return os; } 234 | std::ostream& green_on_light_blue(std::ostream& os) { set("g", "lb"); return os; } 235 | std::ostream& green_on_light_green(std::ostream& os) { set("g", "lg"); return os; } 236 | std::ostream& green_on_light_aqua(std::ostream& os) { set("g", "la"); return os; } 237 | std::ostream& green_on_light_red(std::ostream& os) { set("g", "lr"); return os; } 238 | std::ostream& green_on_light_purple(std::ostream& os) { set("g", "lp"); return os; } 239 | std::ostream& green_on_light_yellow(std::ostream& os) { set("g", "ly"); return os; } 240 | std::ostream& green_on_bright_white(std::ostream& os) { set("g", "bw"); return os; } 241 | std::ostream& aqua_on_black(std::ostream& os) { set("a", "k"); return os; } 242 | std::ostream& aqua_on_blue(std::ostream& os) { set("a", "b"); return os; } 243 | std::ostream& aqua_on_green(std::ostream& os) { set("a", "g"); return os; } 244 | std::ostream& aqua_on_aqua(std::ostream& os) { set("a", "a"); return os; } 245 | std::ostream& aqua_on_red(std::ostream& os) { set("a", "r"); return os; } 246 | std::ostream& aqua_on_purple(std::ostream& os) { set("a", "p"); return os; } 247 | std::ostream& aqua_on_yellow(std::ostream& os) { set("a", "y"); return os; } 248 | std::ostream& aqua_on_white(std::ostream& os) { set("a", "w"); return os; } 249 | std::ostream& aqua_on_grey(std::ostream& os) { set("a", "e"); return os; } 250 | std::ostream& aqua_on_light_blue(std::ostream& os) { set("a", "lb"); return os; } 251 | std::ostream& aqua_on_light_green(std::ostream& os) { set("a", "lg"); return os; } 252 | std::ostream& aqua_on_light_aqua(std::ostream& os) { set("a", "la"); return os; } 253 | std::ostream& aqua_on_light_red(std::ostream& os) { set("a", "lr"); return os; } 254 | std::ostream& aqua_on_light_purple(std::ostream& os) { set("a", "lp"); return os; } 255 | std::ostream& aqua_on_light_yellow(std::ostream& os) { set("a", "ly"); return os; } 256 | std::ostream& aqua_on_bright_white(std::ostream& os) { set("a", "bw"); return os; } 257 | std::ostream& red_on_black(std::ostream& os) { set("r", "k"); return os; } 258 | std::ostream& red_on_blue(std::ostream& os) { set("r", "b"); return os; } 259 | std::ostream& red_on_green(std::ostream& os) { set("r", "g"); return os; } 260 | std::ostream& red_on_aqua(std::ostream& os) { set("r", "a"); return os; } 261 | std::ostream& red_on_red(std::ostream& os) { set("r", "r"); return os; } 262 | std::ostream& red_on_purple(std::ostream& os) { set("r", "p"); return os; } 263 | std::ostream& red_on_yellow(std::ostream& os) { set("r", "y"); return os; } 264 | std::ostream& red_on_white(std::ostream& os) { set("r", "w"); return os; } 265 | std::ostream& red_on_grey(std::ostream& os) { set("r", "e"); return os; } 266 | std::ostream& red_on_light_blue(std::ostream& os) { set("r", "lb"); return os; } 267 | std::ostream& red_on_light_green(std::ostream& os) { set("r", "lg"); return os; } 268 | std::ostream& red_on_light_aqua(std::ostream& os) { set("r", "la"); return os; } 269 | std::ostream& red_on_light_red(std::ostream& os) { set("r", "lr"); return os; } 270 | std::ostream& red_on_light_purple(std::ostream& os) { set("r", "lp"); return os; } 271 | std::ostream& red_on_light_yellow(std::ostream& os) { set("r", "ly"); return os; } 272 | std::ostream& red_on_bright_white(std::ostream& os) { set("r", "bw"); return os; } 273 | std::ostream& purple_on_black(std::ostream& os) { set("p", "k"); return os; } 274 | std::ostream& purple_on_blue(std::ostream& os) { set("p", "b"); return os; } 275 | std::ostream& purple_on_green(std::ostream& os) { set("p", "g"); return os; } 276 | std::ostream& purple_on_aqua(std::ostream& os) { set("p", "a"); return os; } 277 | std::ostream& purple_on_red(std::ostream& os) { set("p", "r"); return os; } 278 | std::ostream& purple_on_purple(std::ostream& os) { set("p", "p"); return os; } 279 | std::ostream& purple_on_yellow(std::ostream& os) { set("p", "y"); return os; } 280 | std::ostream& purple_on_white(std::ostream& os) { set("p", "w"); return os; } 281 | std::ostream& purple_on_grey(std::ostream& os) { set("p", "e"); return os; } 282 | std::ostream& purple_on_light_blue(std::ostream& os) { set("p", "lb"); return os; } 283 | std::ostream& purple_on_light_green(std::ostream& os) { set("p", "lg"); return os; } 284 | std::ostream& purple_on_light_aqua(std::ostream& os) { set("p", "la"); return os; } 285 | std::ostream& purple_on_light_red(std::ostream& os) { set("p", "lr"); return os; } 286 | std::ostream& purple_on_light_purple(std::ostream& os) { set("p", "lp"); return os; } 287 | std::ostream& purple_on_light_yellow(std::ostream& os) { set("p", "ly"); return os; } 288 | std::ostream& purple_on_bright_white(std::ostream& os) { set("p", "bw"); return os; } 289 | std::ostream& yellow_on_black(std::ostream& os) { set("y", "k"); return os; } 290 | std::ostream& yellow_on_blue(std::ostream& os) { set("y", "b"); return os; } 291 | std::ostream& yellow_on_green(std::ostream& os) { set("y", "g"); return os; } 292 | std::ostream& yellow_on_aqua(std::ostream& os) { set("y", "a"); return os; } 293 | std::ostream& yellow_on_red(std::ostream& os) { set("y", "r"); return os; } 294 | std::ostream& yellow_on_purple(std::ostream& os) { set("y", "p"); return os; } 295 | std::ostream& yellow_on_yellow(std::ostream& os) { set("y", "y"); return os; } 296 | std::ostream& yellow_on_white(std::ostream& os) { set("y", "w"); return os; } 297 | std::ostream& yellow_on_grey(std::ostream& os) { set("y", "e"); return os; } 298 | std::ostream& yellow_on_light_blue(std::ostream& os) { set("y", "lb"); return os; } 299 | std::ostream& yellow_on_light_green(std::ostream& os) { set("y", "lg"); return os; } 300 | std::ostream& yellow_on_light_aqua(std::ostream& os) { set("y", "la"); return os; } 301 | std::ostream& yellow_on_light_red(std::ostream& os) { set("y", "lr"); return os; } 302 | std::ostream& yellow_on_light_purple(std::ostream& os) { set("y", "lp"); return os; } 303 | std::ostream& yellow_on_light_yellow(std::ostream& os) { set("y", "ly"); return os; } 304 | std::ostream& yellow_on_bright_white(std::ostream& os) { set("y", "bw"); return os; } 305 | std::ostream& white_on_black(std::ostream& os) { set("w", "k"); return os; } 306 | std::ostream& white_on_blue(std::ostream& os) { set("w", "b"); return os; } 307 | std::ostream& white_on_green(std::ostream& os) { set("w", "g"); return os; } 308 | std::ostream& white_on_aqua(std::ostream& os) { set("w", "a"); return os; } 309 | std::ostream& white_on_red(std::ostream& os) { set("w", "r"); return os; } 310 | std::ostream& white_on_purple(std::ostream& os) { set("w", "p"); return os; } 311 | std::ostream& white_on_yellow(std::ostream& os) { set("w", "y"); return os; } 312 | std::ostream& white_on_white(std::ostream& os) { set("w", "w"); return os; } 313 | std::ostream& white_on_grey(std::ostream& os) { set("w", "e"); return os; } 314 | std::ostream& white_on_light_blue(std::ostream& os) { set("w", "lb"); return os; } 315 | std::ostream& white_on_light_green(std::ostream& os) { set("w", "lg"); return os; } 316 | std::ostream& white_on_light_aqua(std::ostream& os) { set("w", "la"); return os; } 317 | std::ostream& white_on_light_red(std::ostream& os) { set("w", "lr"); return os; } 318 | std::ostream& white_on_light_purple(std::ostream& os) { set("w", "lp"); return os; } 319 | std::ostream& white_on_light_yellow(std::ostream& os) { set("w", "ly"); return os; } 320 | std::ostream& white_on_bright_white(std::ostream& os) { set("w", "bw"); return os; } 321 | std::ostream& grey_on_black(std::ostream& os) { set("e", "k"); return os; } 322 | std::ostream& grey_on_blue(std::ostream& os) { set("e", "b"); return os; } 323 | std::ostream& grey_on_green(std::ostream& os) { set("e", "g"); return os; } 324 | std::ostream& grey_on_aqua(std::ostream& os) { set("e", "a"); return os; } 325 | std::ostream& grey_on_red(std::ostream& os) { set("e", "r"); return os; } 326 | std::ostream& grey_on_purple(std::ostream& os) { set("e", "p"); return os; } 327 | std::ostream& grey_on_yellow(std::ostream& os) { set("e", "y"); return os; } 328 | std::ostream& grey_on_white(std::ostream& os) { set("e", "w"); return os; } 329 | std::ostream& grey_on_grey(std::ostream& os) { set("e", "e"); return os; } 330 | std::ostream& grey_on_light_blue(std::ostream& os) { set("e", "lb"); return os; } 331 | std::ostream& grey_on_light_green(std::ostream& os) { set("e", "lg"); return os; } 332 | std::ostream& grey_on_light_aqua(std::ostream& os) { set("e", "la"); return os; } 333 | std::ostream& grey_on_light_red(std::ostream& os) { set("e", "lr"); return os; } 334 | std::ostream& grey_on_light_purple(std::ostream& os) { set("e", "lp"); return os; } 335 | std::ostream& grey_on_light_yellow(std::ostream& os) { set("e", "ly"); return os; } 336 | std::ostream& grey_on_bright_white(std::ostream& os) { set("e", "bw"); return os; } 337 | std::ostream& light_blue_on_black(std::ostream& os) { set("lb", "k"); return os; } 338 | std::ostream& light_blue_on_blue(std::ostream& os) { set("lb", "b"); return os; } 339 | std::ostream& light_blue_on_green(std::ostream& os) { set("lb", "g"); return os; } 340 | std::ostream& light_blue_on_aqua(std::ostream& os) { set("lb", "a"); return os; } 341 | std::ostream& light_blue_on_red(std::ostream& os) { set("lb", "r"); return os; } 342 | std::ostream& light_blue_on_purple(std::ostream& os) { set("lb", "p"); return os; } 343 | std::ostream& light_blue_on_yellow(std::ostream& os) { set("lb", "y"); return os; } 344 | std::ostream& light_blue_on_white(std::ostream& os) { set("lb", "w"); return os; } 345 | std::ostream& light_blue_on_grey(std::ostream& os) { set("lb", "e"); return os; } 346 | std::ostream& light_blue_on_light_blue(std::ostream& os) { set("lb", "lb"); return os; } 347 | std::ostream& light_blue_on_light_green(std::ostream& os) { set("lb", "lg"); return os; } 348 | std::ostream& light_blue_on_light_aqua(std::ostream& os) { set("lb", "la"); return os; } 349 | std::ostream& light_blue_on_light_red(std::ostream& os) { set("lb", "lr"); return os; } 350 | std::ostream& light_blue_on_light_purple(std::ostream& os) { set("lb", "lp"); return os; } 351 | std::ostream& light_blue_on_light_yellow(std::ostream& os) { set("lb", "ly"); return os; } 352 | std::ostream& light_blue_on_bright_white(std::ostream& os) { set("lb", "bw"); return os; } 353 | std::ostream& light_green_on_black(std::ostream& os) { set("lg", "k"); return os; } 354 | std::ostream& light_green_on_blue(std::ostream& os) { set("lg", "b"); return os; } 355 | std::ostream& light_green_on_green(std::ostream& os) { set("lg", "g"); return os; } 356 | std::ostream& light_green_on_aqua(std::ostream& os) { set("lg", "a"); return os; } 357 | std::ostream& light_green_on_red(std::ostream& os) { set("lg", "r"); return os; } 358 | std::ostream& light_green_on_purple(std::ostream& os) { set("lg", "p"); return os; } 359 | std::ostream& light_green_on_yellow(std::ostream& os) { set("lg", "y"); return os; } 360 | std::ostream& light_green_on_white(std::ostream& os) { set("lg", "w"); return os; } 361 | std::ostream& light_green_on_grey(std::ostream& os) { set("lg", "e"); return os; } 362 | std::ostream& light_green_on_light_blue(std::ostream& os) { set("lg", "lb"); return os; } 363 | std::ostream& light_green_on_light_green(std::ostream& os) { set("lg", "lg"); return os; } 364 | std::ostream& light_green_on_light_aqua(std::ostream& os) { set("lg", "la"); return os; } 365 | std::ostream& light_green_on_light_red(std::ostream& os) { set("lg", "lr"); return os; } 366 | std::ostream& light_green_on_light_purple(std::ostream& os) { set("lg", "lp"); return os; } 367 | std::ostream& light_green_on_light_yellow(std::ostream& os) { set("lg", "ly"); return os; } 368 | std::ostream& light_green_on_bright_white(std::ostream& os) { set("lg", "bw"); return os; } 369 | std::ostream& light_aqua_on_black(std::ostream& os) { set("la", "k"); return os; } 370 | std::ostream& light_aqua_on_blue(std::ostream& os) { set("la", "b"); return os; } 371 | std::ostream& light_aqua_on_green(std::ostream& os) { set("la", "g"); return os; } 372 | std::ostream& light_aqua_on_aqua(std::ostream& os) { set("la", "a"); return os; } 373 | std::ostream& light_aqua_on_red(std::ostream& os) { set("la", "r"); return os; } 374 | std::ostream& light_aqua_on_purple(std::ostream& os) { set("la", "p"); return os; } 375 | std::ostream& light_aqua_on_yellow(std::ostream& os) { set("la", "y"); return os; } 376 | std::ostream& light_aqua_on_white(std::ostream& os) { set("la", "w"); return os; } 377 | std::ostream& light_aqua_on_grey(std::ostream& os) { set("la", "e"); return os; } 378 | std::ostream& light_aqua_on_light_blue(std::ostream& os) { set("la", "lb"); return os; } 379 | std::ostream& light_aqua_on_light_green(std::ostream& os) { set("la", "lg"); return os; } 380 | std::ostream& light_aqua_on_light_aqua(std::ostream& os) { set("la", "la"); return os; } 381 | std::ostream& light_aqua_on_light_red(std::ostream& os) { set("la", "lr"); return os; } 382 | std::ostream& light_aqua_on_light_purple(std::ostream& os) { set("la", "lp"); return os; } 383 | std::ostream& light_aqua_on_light_yellow(std::ostream& os) { set("la", "ly"); return os; } 384 | std::ostream& light_aqua_on_bright_white(std::ostream& os) { set("la", "bw"); return os; } 385 | std::ostream& light_red_on_black(std::ostream& os) { set("lr", "k"); return os; } 386 | std::ostream& light_red_on_blue(std::ostream& os) { set("lr", "b"); return os; } 387 | std::ostream& light_red_on_green(std::ostream& os) { set("lr", "g"); return os; } 388 | std::ostream& light_red_on_aqua(std::ostream& os) { set("lr", "a"); return os; } 389 | std::ostream& light_red_on_red(std::ostream& os) { set("lr", "r"); return os; } 390 | std::ostream& light_red_on_purple(std::ostream& os) { set("lr", "p"); return os; } 391 | std::ostream& light_red_on_yellow(std::ostream& os) { set("lr", "y"); return os; } 392 | std::ostream& light_red_on_white(std::ostream& os) { set("lr", "w"); return os; } 393 | std::ostream& light_red_on_grey(std::ostream& os) { set("lr", "e"); return os; } 394 | std::ostream& light_red_on_light_blue(std::ostream& os) { set("lr", "lb"); return os; } 395 | std::ostream& light_red_on_light_green(std::ostream& os) { set("lr", "lg"); return os; } 396 | std::ostream& light_red_on_light_aqua(std::ostream& os) { set("lr", "la"); return os; } 397 | std::ostream& light_red_on_light_red(std::ostream& os) { set("lr", "lr"); return os; } 398 | std::ostream& light_red_on_light_purple(std::ostream& os) { set("lr", "lp"); return os; } 399 | std::ostream& light_red_on_light_yellow(std::ostream& os) { set("lr", "ly"); return os; } 400 | std::ostream& light_red_on_bright_white(std::ostream& os) { set("lr", "bw"); return os; } 401 | std::ostream& light_purple_on_black(std::ostream& os) { set("lp", "k"); return os; } 402 | std::ostream& light_purple_on_blue(std::ostream& os) { set("lp", "b"); return os; } 403 | std::ostream& light_purple_on_green(std::ostream& os) { set("lp", "g"); return os; } 404 | std::ostream& light_purple_on_aqua(std::ostream& os) { set("lp", "a"); return os; } 405 | std::ostream& light_purple_on_red(std::ostream& os) { set("lp", "r"); return os; } 406 | std::ostream& light_purple_on_purple(std::ostream& os) { set("lp", "p"); return os; } 407 | std::ostream& light_purple_on_yellow(std::ostream& os) { set("lp", "y"); return os; } 408 | std::ostream& light_purple_on_white(std::ostream& os) { set("lp", "w"); return os; } 409 | std::ostream& light_purple_on_grey(std::ostream& os) { set("lp", "e"); return os; } 410 | std::ostream& light_purple_on_light_blue(std::ostream& os) { set("lp", "lb"); return os; } 411 | std::ostream& light_purple_on_light_green(std::ostream& os) { set("lp", "lg"); return os; } 412 | std::ostream& light_purple_on_light_aqua(std::ostream& os) { set("lp", "la"); return os; } 413 | std::ostream& light_purple_on_light_red(std::ostream& os) { set("lp", "lr"); return os; } 414 | std::ostream& light_purple_on_light_purple(std::ostream& os) { set("lp", "lp"); return os; } 415 | std::ostream& light_purple_on_light_yellow(std::ostream& os) { set("lp", "ly"); return os; } 416 | std::ostream& light_purple_on_bright_white(std::ostream& os) { set("lp", "bw"); return os; } 417 | std::ostream& light_yellow_on_black(std::ostream& os) { set("ly", "k"); return os; } 418 | std::ostream& light_yellow_on_blue(std::ostream& os) { set("ly", "b"); return os; } 419 | std::ostream& light_yellow_on_green(std::ostream& os) { set("ly", "g"); return os; } 420 | std::ostream& light_yellow_on_aqua(std::ostream& os) { set("ly", "a"); return os; } 421 | std::ostream& light_yellow_on_red(std::ostream& os) { set("ly", "r"); return os; } 422 | std::ostream& light_yellow_on_purple(std::ostream& os) { set("ly", "p"); return os; } 423 | std::ostream& light_yellow_on_yellow(std::ostream& os) { set("ly", "y"); return os; } 424 | std::ostream& light_yellow_on_white(std::ostream& os) { set("ly", "w"); return os; } 425 | std::ostream& light_yellow_on_grey(std::ostream& os) { set("ly", "e"); return os; } 426 | std::ostream& light_yellow_on_light_blue(std::ostream& os) { set("ly", "lb"); return os; } 427 | std::ostream& light_yellow_on_light_green(std::ostream& os) { set("ly", "lg"); return os; } 428 | std::ostream& light_yellow_on_light_aqua(std::ostream& os) { set("ly", "la"); return os; } 429 | std::ostream& light_yellow_on_light_red(std::ostream& os) { set("ly", "lr"); return os; } 430 | std::ostream& light_yellow_on_light_purple(std::ostream& os) { set("ly", "lp"); return os; } 431 | std::ostream& light_yellow_on_light_yellow(std::ostream& os) { set("ly", "ly"); return os; } 432 | std::ostream& light_yellow_on_bright_white(std::ostream& os) { set("ly", "bw"); return os; } 433 | std::ostream& bright_white_on_black(std::ostream& os) { set("bw", "k"); return os; } 434 | std::ostream& bright_white_on_blue(std::ostream& os) { set("bw", "b"); return os; } 435 | std::ostream& bright_white_on_green(std::ostream& os) { set("bw", "g"); return os; } 436 | std::ostream& bright_white_on_aqua(std::ostream& os) { set("bw", "a"); return os; } 437 | std::ostream& bright_white_on_red(std::ostream& os) { set("bw", "r"); return os; } 438 | std::ostream& bright_white_on_purple(std::ostream& os) { set("bw", "p"); return os; } 439 | std::ostream& bright_white_on_yellow(std::ostream& os) { set("bw", "y"); return os; } 440 | std::ostream& bright_white_on_white(std::ostream& os) { set("bw", "w"); return os; } 441 | std::ostream& bright_white_on_grey(std::ostream& os) { set("bw", "e"); return os; } 442 | std::ostream& bright_white_on_light_blue(std::ostream& os) { set("bw", "lb"); return os; } 443 | std::ostream& bright_white_on_light_green(std::ostream& os) { set("bw", "lg"); return os; } 444 | std::ostream& bright_white_on_light_aqua(std::ostream& os) { set("bw", "la"); return os; } 445 | std::ostream& bright_white_on_light_red(std::ostream& os) { set("bw", "lr"); return os; } 446 | std::ostream& bright_white_on_light_purple(std::ostream& os) { set("bw", "lp"); return os; } 447 | std::ostream& bright_white_on_light_yellow(std::ostream& os) { set("bw", "ly"); return os; } 448 | std::ostream& bright_white_on_bright_white(std::ostream& os) { set("bw", "bw"); return os; } 449 | } 450 | 451 | 452 | namespace dye 453 | { 454 | template 455 | using bar = typename std::conditional::value, std::string, T>::type; 456 | 457 | template class colorful; 458 | template class item; 459 | 460 | template 461 | class colorful : private std::list> 462 | { 463 | public: 464 | using std::list>::list; 465 | 466 | colorful& operator+=(const colorful& rhs) 467 | { 468 | this->insert(this->end(), rhs.begin(), rhs.end()); 469 | return *this; 470 | } 471 | 472 | colorful& operator+=(colorful&& rhs) 473 | { 474 | this->splice(this->end(), std::move(rhs)); 475 | return *this; 476 | } 477 | 478 | colorful& operator+=(T t) 479 | { 480 | this->push_back(std::move(t)); 481 | return *this; 482 | } 483 | 484 | void push_front(T t) 485 | { 486 | this->std::list>::push_front(item(std::move(t))); 487 | } 488 | 489 | void push_back(T t) 490 | { 491 | this->std::list>::push_back(item(std::move(t))); 492 | } 493 | 494 | colorful& invert() 495 | { 496 | for (auto& elem : *this) 497 | elem.invert(); 498 | return *this; 499 | } 500 | 501 | template 502 | friend std::ostream& operator<<(std::ostream&, const colorful&); 503 | 504 | template 505 | friend colorful invert(colorful col); 506 | }; 507 | 508 | template 509 | colorful operator+(colorful lhs, colorful rhs) 510 | { 511 | colorful res(std::move(lhs)); 512 | return res += rhs; 513 | } 514 | 515 | template 516 | colorful operator+(colorful lhs, std::string rhs) 517 | { 518 | colorful res(std::move(lhs)); 519 | res.push_back(std::move(rhs)); 520 | return res; 521 | } 522 | 523 | template 524 | colorful operator+(const std::string& lhs, colorful rhs) 525 | { 526 | colorful res(std::move(rhs)); 527 | res.push_front(std::move(lhs)); 528 | return res; 529 | } 530 | 531 | template 532 | std::ostream& operator<<(std::ostream& os, const colorful& colorful) 533 | { 534 | for (const auto& elem : colorful) 535 | os << elem; 536 | return os; 537 | } 538 | 539 | template 540 | colorful invert(colorful col) 541 | { 542 | colorful res(std::move(col)); 543 | for (auto& elem : res) 544 | elem.invert(); 545 | return res; 546 | } 547 | 548 | template 549 | class item 550 | { 551 | T thing; 552 | int color; 553 | 554 | public: 555 | item(T t) : thing(std::move(t)), color(hue::get()) {} 556 | item(T t, int a) : thing(std::move(t)), color(hue::itoc(a)) {} 557 | item(T t, int a, int b) : thing(std::move(t)), color(hue::itoc(a, b)) {} 558 | item(T t, std::string a) : thing(std::move(t)), color(hue::stoc(a)) {} 559 | item(T t, std::string a, std::string b) : thing(std::move(t)), color(hue::stoc(a, b)) {} 560 | 561 | item& invert() 562 | { 563 | color = hue::invert(color); 564 | return *this; 565 | } 566 | 567 | template 568 | friend class colorful; 569 | 570 | template 571 | friend std::ostream& operator<<(std::ostream&, const item&); 572 | }; 573 | 574 | template 575 | std::ostream& operator<<(std::ostream& os, const item& it) 576 | { 577 | hue::set(it.color); 578 | os << it.thing; 579 | hue::reset(); 580 | return os; 581 | } 582 | 583 | template using R = colorful>; 584 | template using S = item>; 585 | 586 | template R colorize(T t, std::string a) { return R { S(t, a) }; } 587 | template R vanilla(T t) { return R { S(t) }; } 588 | template R black(T t) { return R { S(t, "k") }; } 589 | template R blue(T t) { return R { S(t, "b") }; } 590 | template R green(T t) { return R { S(t, "g") }; } 591 | template R aqua(T t) { return R { S(t, "a") }; } 592 | template R red(T t) { return R { S(t, "r") }; } 593 | template R purple(T t) { return R { S(t, "p") }; } 594 | template R yellow(T t) { return R { S(t, "y") }; } 595 | template R white(T t) { return R { S(t, "w") }; } 596 | template R grey(T t) { return R { S(t, "e") }; } 597 | template R light_blue(T t) { return R { S(t, "lb") }; } 598 | template R light_green(T t) { return R { S(t, "lg") }; } 599 | template R light_aqua(T t) { return R { S(t, "la") }; } 600 | template R light_red(T t) { return R { S(t, "lr") }; } 601 | template R light_purple(T t) { return R { S(t, "lp") }; } 602 | template R light_yellow(T t) { return R { S(t, "ly") }; } 603 | template R bright_white(T t) { return R { S(t, "bw") }; } 604 | template R on_black(T t) { return R { S(t, "k", "k") }; } 605 | template R on_blue(T t) { return R { S(t, "k", "b") }; } 606 | template R on_green(T t) { return R { S(t, "k", "g") }; } 607 | template R on_aqua(T t) { return R { S(t, "k", "a") }; } 608 | template R on_red(T t) { return R { S(t, "k", "r") }; } 609 | template R on_purple(T t) { return R { S(t, "k", "p") }; } 610 | template R on_yellow(T t) { return R { S(t, "k", "y") }; } 611 | template R on_white(T t) { return R { S(t, "k", "w") }; } 612 | template R on_grey(T t) { return R { S(t, "k", "e") }; } 613 | template R on_light_blue(T t) { return R { S(t, "k", "lb") }; } 614 | template R on_light_green(T t) { return R { S(t, "k", "lg") }; } 615 | template R on_light_aqua(T t) { return R { S(t, "k", "la") }; } 616 | template R on_light_red(T t) { return R { S(t, "k", "lr") }; } 617 | template R on_light_purple(T t) { return R { S(t, "k", "lp") }; } 618 | template R on_light_yellow(T t) { return R { S(t, "k", "ly") }; } 619 | template R on_bright_white(T t) { return R { S(t, "k", "bw") }; } 620 | template R black_on_black(T t) { return R { S(t, "k", "k") }; } 621 | template R black_on_blue(T t) { return R { S(t, "k", "b") }; } 622 | template R black_on_green(T t) { return R { S(t, "k", "g") }; } 623 | template R black_on_aqua(T t) { return R { S(t, "k", "a") }; } 624 | template R black_on_red(T t) { return R { S(t, "k", "r") }; } 625 | template R black_on_purple(T t) { return R { S(t, "k", "p") }; } 626 | template R black_on_yellow(T t) { return R { S(t, "k", "y") }; } 627 | template R black_on_white(T t) { return R { S(t, "k", "w") }; } 628 | template R black_on_grey(T t) { return R { S(t, "k", "e") }; } 629 | template R black_on_light_blue(T t) { return R { S(t, "k", "lb") }; } 630 | template R black_on_light_green(T t) { return R { S(t, "k", "lg") }; } 631 | template R black_on_light_aqua(T t) { return R { S(t, "k", "la") }; } 632 | template R black_on_light_red(T t) { return R { S(t, "k", "lr") }; } 633 | template R black_on_light_purple(T t) { return R { S(t, "k", "lp") }; } 634 | template R black_on_light_yellow(T t) { return R { S(t, "k", "ly") }; } 635 | template R black_on_bright_white(T t) { return R { S(t, "k", "bw") }; } 636 | template R blue_on_black(T t) { return R { S(t, "b", "k") }; } 637 | template R blue_on_blue(T t) { return R { S(t, "b", "b") }; } 638 | template R blue_on_green(T t) { return R { S(t, "b", "g") }; } 639 | template R blue_on_aqua(T t) { return R { S(t, "b", "a") }; } 640 | template R blue_on_red(T t) { return R { S(t, "b", "r") }; } 641 | template R blue_on_purple(T t) { return R { S(t, "b", "p") }; } 642 | template R blue_on_yellow(T t) { return R { S(t, "b", "y") }; } 643 | template R blue_on_white(T t) { return R { S(t, "b", "w") }; } 644 | template R blue_on_grey(T t) { return R { S(t, "b", "e") }; } 645 | template R blue_on_light_blue(T t) { return R { S(t, "b", "lb") }; } 646 | template R blue_on_light_green(T t) { return R { S(t, "b", "lg") }; } 647 | template R blue_on_light_aqua(T t) { return R { S(t, "b", "la") }; } 648 | template R blue_on_light_red(T t) { return R { S(t, "b", "lr") }; } 649 | template R blue_on_light_purple(T t) { return R { S(t, "b", "lp") }; } 650 | template R blue_on_light_yellow(T t) { return R { S(t, "b", "ly") }; } 651 | template R blue_on_bright_white(T t) { return R { S(t, "b", "bw") }; } 652 | template R green_on_black(T t) { return R { S(t, "g", "k") }; } 653 | template R green_on_blue(T t) { return R { S(t, "g", "b") }; } 654 | template R green_on_green(T t) { return R { S(t, "g", "g") }; } 655 | template R green_on_aqua(T t) { return R { S(t, "g", "a") }; } 656 | template R green_on_red(T t) { return R { S(t, "g", "r") }; } 657 | template R green_on_purple(T t) { return R { S(t, "g", "p") }; } 658 | template R green_on_yellow(T t) { return R { S(t, "g", "y") }; } 659 | template R green_on_white(T t) { return R { S(t, "g", "w") }; } 660 | template R green_on_grey(T t) { return R { S(t, "g", "e") }; } 661 | template R green_on_light_blue(T t) { return R { S(t, "g", "lb") }; } 662 | template R green_on_light_green(T t) { return R { S(t, "g", "lg") }; } 663 | template R green_on_light_aqua(T t) { return R { S(t, "g", "la") }; } 664 | template R green_on_light_red(T t) { return R { S(t, "g", "lr") }; } 665 | template R green_on_light_purple(T t) { return R { S(t, "g", "lp") }; } 666 | template R green_on_light_yellow(T t) { return R { S(t, "g", "ly") }; } 667 | template R green_on_bright_white(T t) { return R { S(t, "g", "bw") }; } 668 | template R aqua_on_black(T t) { return R { S(t, "a", "k") }; } 669 | template R aqua_on_blue(T t) { return R { S(t, "a", "b") }; } 670 | template R aqua_on_green(T t) { return R { S(t, "a", "g") }; } 671 | template R aqua_on_aqua(T t) { return R { S(t, "a", "a") }; } 672 | template R aqua_on_red(T t) { return R { S(t, "a", "r") }; } 673 | template R aqua_on_purple(T t) { return R { S(t, "a", "p") }; } 674 | template R aqua_on_yellow(T t) { return R { S(t, "a", "y") }; } 675 | template R aqua_on_white(T t) { return R { S(t, "a", "w") }; } 676 | template R aqua_on_grey(T t) { return R { S(t, "a", "e") }; } 677 | template R aqua_on_light_blue(T t) { return R { S(t, "a", "lb") }; } 678 | template R aqua_on_light_green(T t) { return R { S(t, "a", "lg") }; } 679 | template R aqua_on_light_aqua(T t) { return R { S(t, "a", "la") }; } 680 | template R aqua_on_light_red(T t) { return R { S(t, "a", "lr") }; } 681 | template R aqua_on_light_purple(T t) { return R { S(t, "a", "lp") }; } 682 | template R aqua_on_light_yellow(T t) { return R { S(t, "a", "ly") }; } 683 | template R aqua_on_bright_white(T t) { return R { S(t, "a", "bw") }; } 684 | template R red_on_black(T t) { return R { S(t, "r", "k") }; } 685 | template R red_on_blue(T t) { return R { S(t, "r", "b") }; } 686 | template R red_on_green(T t) { return R { S(t, "r", "g") }; } 687 | template R red_on_aqua(T t) { return R { S(t, "r", "a") }; } 688 | template R red_on_red(T t) { return R { S(t, "r", "r") }; } 689 | template R red_on_purple(T t) { return R { S(t, "r", "p") }; } 690 | template R red_on_yellow(T t) { return R { S(t, "r", "y") }; } 691 | template R red_on_white(T t) { return R { S(t, "r", "w") }; } 692 | template R red_on_grey(T t) { return R { S(t, "r", "e") }; } 693 | template R red_on_light_blue(T t) { return R { S(t, "r", "lb") }; } 694 | template R red_on_light_green(T t) { return R { S(t, "r", "lg") }; } 695 | template R red_on_light_aqua(T t) { return R { S(t, "r", "la") }; } 696 | template R red_on_light_red(T t) { return R { S(t, "r", "lr") }; } 697 | template R red_on_light_purple(T t) { return R { S(t, "r", "lp") }; } 698 | template R red_on_light_yellow(T t) { return R { S(t, "r", "ly") }; } 699 | template R red_on_bright_white(T t) { return R { S(t, "r", "bw") }; } 700 | template R purple_on_black(T t) { return R { S(t, "p", "k") }; } 701 | template R purple_on_blue(T t) { return R { S(t, "p", "b") }; } 702 | template R purple_on_green(T t) { return R { S(t, "p", "g") }; } 703 | template R purple_on_aqua(T t) { return R { S(t, "p", "a") }; } 704 | template R purple_on_red(T t) { return R { S(t, "p", "r") }; } 705 | template R purple_on_purple(T t) { return R { S(t, "p", "p") }; } 706 | template R purple_on_yellow(T t) { return R { S(t, "p", "y") }; } 707 | template R purple_on_white(T t) { return R { S(t, "p", "w") }; } 708 | template R purple_on_grey(T t) { return R { S(t, "p", "e") }; } 709 | template R purple_on_light_blue(T t) { return R { S(t, "p", "lb") }; } 710 | template R purple_on_light_green(T t) { return R { S(t, "p", "lg") }; } 711 | template R purple_on_light_aqua(T t) { return R { S(t, "p", "la") }; } 712 | template R purple_on_light_red(T t) { return R { S(t, "p", "lr") }; } 713 | template R purple_on_light_purple(T t) { return R { S(t, "p", "lp") }; } 714 | template R purple_on_light_yellow(T t) { return R { S(t, "p", "ly") }; } 715 | template R purple_on_bright_white(T t) { return R { S(t, "p", "bw") }; } 716 | template R yellow_on_black(T t) { return R { S(t, "y", "k") }; } 717 | template R yellow_on_blue(T t) { return R { S(t, "y", "b") }; } 718 | template R yellow_on_green(T t) { return R { S(t, "y", "g") }; } 719 | template R yellow_on_aqua(T t) { return R { S(t, "y", "a") }; } 720 | template R yellow_on_red(T t) { return R { S(t, "y", "r") }; } 721 | template R yellow_on_purple(T t) { return R { S(t, "y", "p") }; } 722 | template R yellow_on_yellow(T t) { return R { S(t, "y", "y") }; } 723 | template R yellow_on_white(T t) { return R { S(t, "y", "w") }; } 724 | template R yellow_on_grey(T t) { return R { S(t, "y", "e") }; } 725 | template R yellow_on_light_blue(T t) { return R { S(t, "y", "lb") }; } 726 | template R yellow_on_light_green(T t) { return R { S(t, "y", "lg") }; } 727 | template R yellow_on_light_aqua(T t) { return R { S(t, "y", "la") }; } 728 | template R yellow_on_light_red(T t) { return R { S(t, "y", "lr") }; } 729 | template R yellow_on_light_purple(T t) { return R { S(t, "y", "lp") }; } 730 | template R yellow_on_light_yellow(T t) { return R { S(t, "y", "ly") }; } 731 | template R yellow_on_bright_white(T t) { return R { S(t, "y", "bw") }; } 732 | template R white_on_black(T t) { return R { S(t, "w", "k") }; } 733 | template R white_on_blue(T t) { return R { S(t, "w", "b") }; } 734 | template R white_on_green(T t) { return R { S(t, "w", "g") }; } 735 | template R white_on_aqua(T t) { return R { S(t, "w", "a") }; } 736 | template R white_on_red(T t) { return R { S(t, "w", "r") }; } 737 | template R white_on_purple(T t) { return R { S(t, "w", "p") }; } 738 | template R white_on_yellow(T t) { return R { S(t, "w", "y") }; } 739 | template R white_on_white(T t) { return R { S(t, "w", "w") }; } 740 | template R white_on_grey(T t) { return R { S(t, "w", "e") }; } 741 | template R white_on_light_blue(T t) { return R { S(t, "w", "lb") }; } 742 | template R white_on_light_green(T t) { return R { S(t, "w", "lg") }; } 743 | template R white_on_light_aqua(T t) { return R { S(t, "w", "la") }; } 744 | template R white_on_light_red(T t) { return R { S(t, "w", "lr") }; } 745 | template R white_on_light_purple(T t) { return R { S(t, "w", "lp") }; } 746 | template R white_on_light_yellow(T t) { return R { S(t, "w", "ly") }; } 747 | template R white_on_bright_white(T t) { return R { S(t, "w", "bw") }; } 748 | template R grey_on_black(T t) { return R { S(t, "e", "k") }; } 749 | template R grey_on_blue(T t) { return R { S(t, "e", "b") }; } 750 | template R grey_on_green(T t) { return R { S(t, "e", "g") }; } 751 | template R grey_on_aqua(T t) { return R { S(t, "e", "a") }; } 752 | template R grey_on_red(T t) { return R { S(t, "e", "r") }; } 753 | template R grey_on_purple(T t) { return R { S(t, "e", "p") }; } 754 | template R grey_on_yellow(T t) { return R { S(t, "e", "y") }; } 755 | template R grey_on_white(T t) { return R { S(t, "e", "w") }; } 756 | template R grey_on_grey(T t) { return R { S(t, "e", "e") }; } 757 | template R grey_on_light_blue(T t) { return R { S(t, "e", "lb") }; } 758 | template R grey_on_light_green(T t) { return R { S(t, "e", "lg") }; } 759 | template R grey_on_light_aqua(T t) { return R { S(t, "e", "la") }; } 760 | template R grey_on_light_red(T t) { return R { S(t, "e", "lr") }; } 761 | template R grey_on_light_purple(T t) { return R { S(t, "e", "lp") }; } 762 | template R grey_on_light_yellow(T t) { return R { S(t, "e", "ly") }; } 763 | template R grey_on_bright_white(T t) { return R { S(t, "e", "bw") }; } 764 | template R light_blue_on_black(T t) { return R { S(t, "lb", "k") }; } 765 | template R light_blue_on_blue(T t) { return R { S(t, "lb", "b") }; } 766 | template R light_blue_on_green(T t) { return R { S(t, "lb", "g") }; } 767 | template R light_blue_on_aqua(T t) { return R { S(t, "lb", "a") }; } 768 | template R light_blue_on_red(T t) { return R { S(t, "lb", "r") }; } 769 | template R light_blue_on_purple(T t) { return R { S(t, "lb", "p") }; } 770 | template R light_blue_on_yellow(T t) { return R { S(t, "lb", "y") }; } 771 | template R light_blue_on_white(T t) { return R { S(t, "lb", "w") }; } 772 | template R light_blue_on_grey(T t) { return R { S(t, "lb", "e") }; } 773 | template R light_blue_on_light_blue(T t) { return R { S(t, "lb", "lb") }; } 774 | template R light_blue_on_light_green(T t) { return R { S(t, "lb", "lg") }; } 775 | template R light_blue_on_light_aqua(T t) { return R { S(t, "lb", "la") }; } 776 | template R light_blue_on_light_red(T t) { return R { S(t, "lb", "lr") }; } 777 | template R light_blue_on_light_purple(T t) { return R { S(t, "lb", "lp") }; } 778 | template R light_blue_on_light_yellow(T t) { return R { S(t, "lb", "ly") }; } 779 | template R light_blue_on_bright_white(T t) { return R { S(t, "lb", "bw") }; } 780 | template R light_green_on_black(T t) { return R { S(t, "lg", "k") }; } 781 | template R light_green_on_blue(T t) { return R { S(t, "lg", "b") }; } 782 | template R light_green_on_green(T t) { return R { S(t, "lg", "g") }; } 783 | template R light_green_on_aqua(T t) { return R { S(t, "lg", "a") }; } 784 | template R light_green_on_red(T t) { return R { S(t, "lg", "r") }; } 785 | template R light_green_on_purple(T t) { return R { S(t, "lg", "p") }; } 786 | template R light_green_on_yellow(T t) { return R { S(t, "lg", "y") }; } 787 | template R light_green_on_white(T t) { return R { S(t, "lg", "w") }; } 788 | template R light_green_on_grey(T t) { return R { S(t, "lg", "e") }; } 789 | template R light_green_on_light_blue(T t) { return R { S(t, "lg", "lb") }; } 790 | template R light_green_on_light_green(T t) { return R { S(t, "lg", "lg") }; } 791 | template R light_green_on_light_aqua(T t) { return R { S(t, "lg", "la") }; } 792 | template R light_green_on_light_red(T t) { return R { S(t, "lg", "lr") }; } 793 | template R light_green_on_light_purple(T t) { return R { S(t, "lg", "lp") }; } 794 | template R light_green_on_light_yellow(T t) { return R { S(t, "lg", "ly") }; } 795 | template R light_green_on_bright_white(T t) { return R { S(t, "lg", "bw") }; } 796 | template R light_aqua_on_black(T t) { return R { S(t, "la", "k") }; } 797 | template R light_aqua_on_blue(T t) { return R { S(t, "la", "b") }; } 798 | template R light_aqua_on_green(T t) { return R { S(t, "la", "g") }; } 799 | template R light_aqua_on_aqua(T t) { return R { S(t, "la", "a") }; } 800 | template R light_aqua_on_red(T t) { return R { S(t, "la", "r") }; } 801 | template R light_aqua_on_purple(T t) { return R { S(t, "la", "p") }; } 802 | template R light_aqua_on_yellow(T t) { return R { S(t, "la", "y") }; } 803 | template R light_aqua_on_white(T t) { return R { S(t, "la", "w") }; } 804 | template R light_aqua_on_grey(T t) { return R { S(t, "la", "e") }; } 805 | template R light_aqua_on_light_blue(T t) { return R { S(t, "la", "lb") }; } 806 | template R light_aqua_on_light_green(T t) { return R { S(t, "la", "lg") }; } 807 | template R light_aqua_on_light_aqua(T t) { return R { S(t, "la", "la") }; } 808 | template R light_aqua_on_light_red(T t) { return R { S(t, "la", "lr") }; } 809 | template R light_aqua_on_light_purple(T t) { return R { S(t, "la", "lp") }; } 810 | template R light_aqua_on_light_yellow(T t) { return R { S(t, "la", "ly") }; } 811 | template R light_aqua_on_bright_white(T t) { return R { S(t, "la", "bw") }; } 812 | template R light_red_on_black(T t) { return R { S(t, "lr", "k") }; } 813 | template R light_red_on_blue(T t) { return R { S(t, "lr", "b") }; } 814 | template R light_red_on_green(T t) { return R { S(t, "lr", "g") }; } 815 | template R light_red_on_aqua(T t) { return R { S(t, "lr", "a") }; } 816 | template R light_red_on_red(T t) { return R { S(t, "lr", "r") }; } 817 | template R light_red_on_purple(T t) { return R { S(t, "lr", "p") }; } 818 | template R light_red_on_yellow(T t) { return R { S(t, "lr", "y") }; } 819 | template R light_red_on_white(T t) { return R { S(t, "lr", "w") }; } 820 | template R light_red_on_grey(T t) { return R { S(t, "lr", "e") }; } 821 | template R light_red_on_light_blue(T t) { return R { S(t, "lr", "lb") }; } 822 | template R light_red_on_light_green(T t) { return R { S(t, "lr", "lg") }; } 823 | template R light_red_on_light_aqua(T t) { return R { S(t, "lr", "la") }; } 824 | template R light_red_on_light_red(T t) { return R { S(t, "lr", "lr") }; } 825 | template R light_red_on_light_purple(T t) { return R { S(t, "lr", "lp") }; } 826 | template R light_red_on_light_yellow(T t) { return R { S(t, "lr", "ly") }; } 827 | template R light_red_on_bright_white(T t) { return R { S(t, "lr", "bw") }; } 828 | template R light_purple_on_black(T t) { return R { S(t, "lp", "k") }; } 829 | template R light_purple_on_blue(T t) { return R { S(t, "lp", "b") }; } 830 | template R light_purple_on_green(T t) { return R { S(t, "lp", "g") }; } 831 | template R light_purple_on_aqua(T t) { return R { S(t, "lp", "a") }; } 832 | template R light_purple_on_red(T t) { return R { S(t, "lp", "r") }; } 833 | template R light_purple_on_purple(T t) { return R { S(t, "lp", "p") }; } 834 | template R light_purple_on_yellow(T t) { return R { S(t, "lp", "y") }; } 835 | template R light_purple_on_white(T t) { return R { S(t, "lp", "w") }; } 836 | template R light_purple_on_grey(T t) { return R { S(t, "lp", "e") }; } 837 | template R light_purple_on_light_blue(T t) { return R { S(t, "lp", "lb") }; } 838 | template R light_purple_on_light_green(T t) { return R { S(t, "lp", "lg") }; } 839 | template R light_purple_on_light_aqua(T t) { return R { S(t, "lp", "la") }; } 840 | template R light_purple_on_light_red(T t) { return R { S(t, "lp", "lr") }; } 841 | template R light_purple_on_light_purple(T t) { return R { S(t, "lp", "lp") }; } 842 | template R light_purple_on_light_yellow(T t) { return R { S(t, "lp", "ly") }; } 843 | template R light_purple_on_bright_white(T t) { return R { S(t, "lp", "bw") }; } 844 | template R light_yellow_on_black(T t) { return R { S(t, "ly", "k") }; } 845 | template R light_yellow_on_blue(T t) { return R { S(t, "ly", "b") }; } 846 | template R light_yellow_on_green(T t) { return R { S(t, "ly", "g") }; } 847 | template R light_yellow_on_aqua(T t) { return R { S(t, "ly", "a") }; } 848 | template R light_yellow_on_red(T t) { return R { S(t, "ly", "r") }; } 849 | template R light_yellow_on_purple(T t) { return R { S(t, "ly", "p") }; } 850 | template R light_yellow_on_yellow(T t) { return R { S(t, "ly", "y") }; } 851 | template R light_yellow_on_white(T t) { return R { S(t, "ly", "w") }; } 852 | template R light_yellow_on_grey(T t) { return R { S(t, "ly", "e") }; } 853 | template R light_yellow_on_light_blue(T t) { return R { S(t, "ly", "lb") }; } 854 | template R light_yellow_on_light_green(T t) { return R { S(t, "ly", "lg") }; } 855 | template R light_yellow_on_light_aqua(T t) { return R { S(t, "ly", "la") }; } 856 | template R light_yellow_on_light_red(T t) { return R { S(t, "ly", "lr") }; } 857 | template R light_yellow_on_light_purple(T t) { return R { S(t, "ly", "lp") }; } 858 | template R light_yellow_on_light_yellow(T t) { return R { S(t, "ly", "ly") }; } 859 | template R light_yellow_on_bright_white(T t) { return R { S(t, "ly", "bw") }; } 860 | template R bright_white_on_black(T t) { return R { S(t, "bw", "k") }; } 861 | template R bright_white_on_blue(T t) { return R { S(t, "bw", "b") }; } 862 | template R bright_white_on_green(T t) { return R { S(t, "bw", "g") }; } 863 | template R bright_white_on_aqua(T t) { return R { S(t, "bw", "a") }; } 864 | template R bright_white_on_red(T t) { return R { S(t, "bw", "r") }; } 865 | template R bright_white_on_purple(T t) { return R { S(t, "bw", "p") }; } 866 | template R bright_white_on_yellow(T t) { return R { S(t, "bw", "y") }; } 867 | template R bright_white_on_white(T t) { return R { S(t, "bw", "w") }; } 868 | template R bright_white_on_grey(T t) { return R { S(t, "bw", "e") }; } 869 | template R bright_white_on_light_blue(T t) { return R { S(t, "bw", "lb") }; } 870 | template R bright_white_on_light_green(T t) { return R { S(t, "bw", "lg") }; } 871 | template R bright_white_on_light_aqua(T t) { return R { S(t, "bw", "la") }; } 872 | template R bright_white_on_light_red(T t) { return R { S(t, "bw", "lr") }; } 873 | template R bright_white_on_light_purple(T t) { return R { S(t, "bw", "lp") }; } 874 | template R bright_white_on_light_yellow(T t) { return R { S(t, "bw", "ly") }; } 875 | template R bright_white_on_bright_white(T t) { return R { S(t, "bw", "bw") }; } 876 | } 877 | 878 | #endif --------------------------------------------------------------------------------