Seregon/Hermes

Hermes/Dyforge is a program written in c++ allows you to inject a dll that can analyze all processes in a program, can be used for mod and reverse engeneering

C/3.8 KB/No license
DyMain/dll_main.cpp
Hermes / DyMain / dll_main.cpp
1#include "DyMain.h"
2#include "WebServer/WebServer.h"
3#include "SharedMemoryLayout.h"
4#include <windows.h>
5#include <iostream>
6#include <string>
7#include <memory>
8#include <mutex>
9#include <aclapi.h>
10#include <sddl.h>
11#include <stdexcept>
12#include <sstream>
13#include <fstream>
14#include <chrono>
15#include <iomanip>
16#include <tlhelp32.h>
17#include <psapi.h>
18#include <detours.h>
19#include <thread>
20#include <winsock2.h>
21#include <ws2tcpip.h>
22#include <algorithm>
23#include <mongoose.h>
24 
25// Definizioni Mongoose
26#define MG_EV_HTTP_MSG 1
27#define MG_WS_OP_TEXT 1
28 
29// Funzioni Mongoose
30static inline struct mg_str mg_http_get_header_value(const struct mg_http_message* hm, const char* name) {
31 struct mg_str result = {NULL, 0};
32 // Implementazione robusta per ottenere l'header
33 for (int i = 0; i < MG_MAX_HTTP_HEADERS; i++) {
34 if (hm->headers[i].name.len == 0) break; // Fine degli headers
35 if (mg_strcmp(hm->headers[i].name, mg_str(name)) == 0) {
36 result = hm->headers[i].value;
37 break;
38 }
39 }
40 return result;
41}
42 
43static inline int mg_http_get_var_value(const struct mg_http_message* hm, const char* name, char* buf, size_t len) {
44 struct mg_str v = mg_http_get_header_value(hm, name);
45 if (v.len > 0) {
46 if (v.len >= len) return -1;
47 memcpy(buf, v.buf, v.len);
48 buf[v.len] = '\0';
49 return (int)v.len;
50 }
51 return -1;
52}
53 
54static inline int mg_websocket_send(struct mg_connection* c, const void* data, size_t len, int op) {
55 // Implementazione robusta per inviare un messaggio WebSocket
56 size_t i, j;
57 size_t header_len = 2;
58 size_t frame_len = len;
59 uint8_t header[10]; // WebSocket frame header
60 
61 header[0] = (uint8_t)(op | 0x80); // FIN + opcode
62
63 if (len < 126) {
64 header[1] = (uint8_t)len;
65 } else if (len < 65536) {
66 header[1] = 126;
67 header[2] = (uint8_t)(len >> 8);
68 header[3] = (uint8_t)(len & 0xff);
69 header_len = 4;
70 } else {
71 header[1] = 127;
72 for (i = 0; i < 8; i++) {
73 header[2 + i] = (uint8_t)((len >> ((7 - i) * 8)) & 0xff);
74 }
75 header_len = 10;
76 }
77 
78 // Invia l'header
79 for (i = 0; i < header_len; i++) {
80 if (mg_io_send(c, &header[i], 1) != 1) return -1;
81 }
82 
83 // Invia i dati
84 const uint8_t* p = (const uint8_t*)data;
85 for (j = 0; j < frame_len; j++) {
86 if (mg_io_send(c, &p[j], 1) != 1) return -1;
87 }
88 
89 return (int)(header_len + frame_len);
90}
91 
92// PEB structures
93typedef struct _UNICODE_STRING {
94 USHORT Length;
95 USHORT MaximumLength;
96 PWSTR Buffer;
97} UNICODE_STRING, *PUNICODE_STRING;
98 
99typedef struct _PEB_LDR_DATA {
100 ULONG Length;
101 BYTE Initialized;
102 PVOID SsHandle;
103 LIST_ENTRY InLoadOrderModuleList;
104 LIST_ENTRY InMemoryOrderModuleList;
105 LIST_ENTRY InInitializationOrderModuleList;
106} PEB_LDR_DATA, *PPEB_LDR_DATA;
107 
108typedef struct _LDR_DATA_TABLE_ENTRY {
109 LIST_ENTRY InLoadOrderLinks;
110 LIST_ENTRY InMemoryOrderLinks;
111 LIST_ENTRY InInitializationOrderLinks;
112 PVOID DllBase;
113 PVOID EntryPoint;
114 ULONG SizeOfImage;
115 UNICODE_STRING FullDllName;
116 UNICODE_STRING BaseDllName;
117} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
118 
119typedef struct _PEB {
120 BYTE Reserved1[2];
121 BYTE BeingDebugged;
122 BYTE Reserved2[1];
123 PVOID Reserved3[2];
124 PPEB_LDR_DATA Ldr;
125 // ... other fields omitted for brevity
126} PEB, *PPEB;
127 
128// Global variables
129namespace {
130 HANDLE g_SharedMemory = NULL;
131 void* g_MappedMemory = NULL;
132 std::mutex g_Mutex;
133 bool g_Initialized = false;
134 HANDLE g_CommandThread = NULL;
135}
136 
137// Global state
138static HMODULE g_hModule = NULL;
139static bool g_initialized = false;
140static HANDLE g_sharedMemory = NULL;
141static void* g_sharedMemoryPtr = NULL;
142static std::ofstream g_logFile;
143 
144// Implementation of exported functions
145extern "C" {
146 bool Initialize() {
147 try {
148 std::lock_guard<std::mutex> lock(g_Mutex);
149
150 if (g_Initialized) {
151 std::cout << "Already initialized" << std::endl;
152 return true;
153 }
154 
155 DWORD error = 0;
156 std::cout << "Initializing shared memory..." << std::endl;
157 if (!DyMain::SharedMemory::CreateSharedMemory()) {
158 error = GetLastError();
159 std::cout << "Failed to create shared memory. Error: " << error << std::endl;
160 return false;
161 }
162 
163 std::cout << "Starting command thread..." << std::endl;
164 g_CommandThread = CreateThread(NULL, 0,
165 (LPTHREAD_START_ROUTINE)DyMain::SharedMemory::ProcessCommands,
166 NULL, 0, NULL);
167 
168 if (!g_CommandThread) {
169 error = GetLastError();
170 std::cout << "Failed to create command thread. Error: " << error << std::endl;
171 DyMain::SharedMemory::CloseSharedMemory();
172 return false;
173 }
174 
175 std::cout << "Injecting hooks..." << std::endl;
176 if (!DyMain::SharedMemory::InjectHooks()) {
177 std::cout << "Failed to inject hooks" << std::endl;
178 DyMain::SharedMemory::CloseSharedMemory();
179 return false;
180 }
181 
182 g_Initialized = true;
183 std::cout << "Initialization completed successfully" << std::endl;
184 return true;
185 }
186 catch (const std::exception& e) {
187 std::cout << "Exception during initialization: " << e.what() << std::endl;
188 return false;
189 }
190 }
191 
192 void Cleanup() {
193 std::lock_guard<std::mutex> lock(g_Mutex);
194
195 if (!g_Initialized) {
196 return;
197 }
198 
199 DyMain::SharedMemory::RemoveHooks();
200
201 if (g_CommandThread) {
202 TerminateThread(g_CommandThread, 0);
203 CloseHandle(g_CommandThread);
204 g_CommandThread = NULL;
205 }
206 
207 DyMain::SharedMemory::CloseSharedMemory();
208 g_Initialized = false;
209 }
210 
211 bool WriteCommand(const char* command, size_t length) {
212 if (!g_Initialized || !g_MappedMemory || !command || length == 0) {
213 return false;
214 }
215 
216 std::lock_guard<std::mutex> lock(g_Mutex);
217
218 if (length > DyMain::SharedMemory::COMMAND_BUFFER_SIZE) {
219 return false;
220 }
221 
222 char* cmdBuffer = static_cast<char*>(g_MappedMemory) + DyMain::SharedMemory::HEADER_SIZE;
223 memcpy(cmdBuffer, command, length);
224 cmdBuffer[length] = '\0';
225 return true;
226 }
227 
228 bool ReadState(char* buffer, size_t bufferSize, size_t* bytesRead) {
229 if (!g_Initialized || !g_MappedMemory || !buffer || !bytesRead) {
230 return false;
231 }
232 
233 std::lock_guard<std::mutex> lock(g_Mutex);
234
235 char* stateBuffer = static_cast<char*>(g_MappedMemory) +
236 DyMain::SharedMemory::HEADER_SIZE +
237 DyMain::SharedMemory::COMMAND_BUFFER_SIZE;
238 
239 size_t stateLength = strlen(stateBuffer);
240 if (stateLength == 0) {
241 *bytesRead = 0;
242 return true;
243 }
244 
245 if (bufferSize < stateLength + 1) {
246 return false;
247 }
248 
249 memcpy(buffer, stateBuffer, stateLength);
250 buffer[stateLength] = '\0';
251 *bytesRead = stateLength;
252 return true;
253 }
254}
255 
256// Implementation of internal functions
257namespace DyMain::SharedMemory {
258 bool CreateSharedMemory() {
259 // Create security attributes with explicit permissions for all users
260 SECURITY_ATTRIBUTES sa;
261 SECURITY_DESCRIPTOR sd;
262 PSECURITY_DESCRIPTOR pSD = NULL;
263 PACL pACL = NULL;
264 EXPLICIT_ACCESS ea;
265 PSID pEveryoneSID = NULL;
266 SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY;
267
268 // Create a well-known SID for the Everyone group
269 if(!AllocateAndInitializeSid(&SIDAuthWorld, 1,
270 SECURITY_WORLD_RID,
271 0, 0, 0, 0, 0, 0, 0,
272 &pEveryoneSID)) {
273 return false;
274 }
275
276 // Initialize an EXPLICIT_ACCESS structure for an ACE
277 ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS));
278 ea.grfAccessPermissions = GENERIC_ALL;
279 ea.grfAccessMode = SET_ACCESS;
280 ea.grfInheritance = NO_INHERITANCE;
281 ea.Trustee.TrusteeForm = TRUSTEE_IS_SID;
282 ea.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
283 ea.Trustee.ptstrName = (LPTSTR)pEveryoneSID;
284
285 // Create a new ACL that contains the new ACEs
286 DWORD dwRes = SetEntriesInAcl(1, &ea, NULL, &pACL);
287 if (ERROR_SUCCESS != dwRes) {
288 FreeSid(pEveryoneSID);
289 return false;
290 }
291
292 // Initialize a security descriptor
293 pSD = (PSECURITY_DESCRIPTOR)LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);
294 if (NULL == pSD) {
295 FreeSid(pEveryoneSID);
296 LocalFree(pACL);
297 return false;
298 }
299
300 if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION)) {
301 FreeSid(pEveryoneSID);
302 LocalFree(pACL);
303 LocalFree(pSD);
304 return false;
305 }
306
307 // Add the ACL to the security descriptor
308 if (!SetSecurityDescriptorDacl(pSD, TRUE, pACL, FALSE)) {
309 FreeSid(pEveryoneSID);
310 LocalFree(pACL);
311 LocalFree(pSD);
312 return false;
313 }
314
315 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
316 sa.lpSecurityDescriptor = pSD;
317 sa.bInheritHandle = FALSE;
318
319 // Create the shared memory with the security attributes
320 g_SharedMemory = CreateFileMappingA(
321 INVALID_HANDLE_VALUE,
322 &sa,
323 PAGE_READWRITE,
324 0,
325 SharedMemoryLayout::TOTAL_SIZE,
326 "GTAVCoopSharedMem"
327 );
328
329 // Cleanup security descriptor resources
330 FreeSid(pEveryoneSID);
331 LocalFree(pACL);
332 LocalFree(pSD);
333
334 if (!g_SharedMemory) {
335 DWORD error = GetLastError();
336 std::cout << "Failed to create shared memory mapping. Error: " << error << std::endl;
337 return false;
338 }
339
340 g_MappedMemory = MapViewOfFile(
341 g_SharedMemory,
342 FILE_MAP_ALL_ACCESS,
343 0,
344 0,
345 SharedMemoryLayout::TOTAL_SIZE
346 );
347
348 if (!g_MappedMemory) {
349 DWORD error = GetLastError();
350 std::cout << "Failed to map view of file. Error: " << error << std::endl;
351 CloseHandle(g_SharedMemory);
352 g_SharedMemory = NULL;
353 return false;
354 }
355
356 // Initialize memory
357 memset(g_MappedMemory, 0, SharedMemoryLayout::TOTAL_SIZE);
358 return true;
359 }
360 
361 void CloseSharedMemory() {
362 if (g_MappedMemory) {
363 UnmapViewOfFile(g_MappedMemory);
364 g_MappedMemory = NULL;
365 }
366 
367 if (g_SharedMemory) {
368 CloseHandle(g_SharedMemory);
369 g_SharedMemory = NULL;
370 }
371 }
372 
373 DWORD WINAPI ProcessCommands(LPVOID lpParam) {
374 while (true) {
375 if (!g_MappedMemory) {
376 Sleep(100);
377 continue;
378 }
379 
380 char* cmdBuffer = static_cast<char*>(g_MappedMemory) + SharedMemoryLayout::HEADER_SIZE;
381 if (cmdBuffer[0] != '\0') {
382 std::string command(cmdBuffer);
383 // Processa il comando qui
384 cmdBuffer[0] = '\0'; // Reset del buffer
385 }
386 Sleep(10);
387 }
388 return 0;
389 }
390 
391 bool InjectHooks() {
392 // Implementazione base degli hook
393 return true;
394 }
395 
396 void RemoveHooks() {
397 // Implementazione base della rimozione degli hook
398 }
399}
400 
401// Core System
402bool DyMain::StartDyMain(HMODULE hModule) {
403 if (g_initialized) {
404 return true;
405 }
406
407 try {
408 g_hModule = hModule;
409
410 // Initialize logging
411 g_logFile.open("DyMain.log", std::ios::app);
412 if (!g_logFile.is_open()) {
413 throw std::runtime_error("Failed to open log file");
414 }
415
416 // Initialize shared memory
417 g_sharedMemory = CreateFileMappingA(
418 INVALID_HANDLE_VALUE,
419 NULL,
420 PAGE_READWRITE,
421 0,
422 SharedMemoryLayout::TOTAL_SIZE,
423 "DyMainSharedMemory"
424 );
425
426 if (!g_sharedMemory) {
427 throw std::runtime_error("Failed to create shared memory");
428 }
429
430 g_sharedMemoryPtr = MapViewOfFile(
431 g_sharedMemory,
432 FILE_MAP_ALL_ACCESS,
433 0,
434 0,
435 SharedMemoryLayout::TOTAL_SIZE
436 );
437
438 if (!g_sharedMemoryPtr) {
439 CloseHandle(g_sharedMemory);
440 throw std::runtime_error("Failed to map shared memory");
441 }
442
443 // Initialize injection
444 if (!Injection::InitializeInjection(hModule)) {
445 throw std::runtime_error("Failed to initialize injection");
446 }
447
448 // Start web server
449 if (!WebServer::StartWebServer(8080)) {
450 throw std::runtime_error("Failed to start web server");
451 }
452
453 g_initialized = true;
454 Utils::Logger::LogInfo("DyMain started successfully");
455 return true;
456 }
457 catch (const std::exception& e) {
458 Utils::Logger::LogError(std::string("Failed to start DyMain: ") + e.what());
459 return false;
460 }
461}
462 
463void DyMain::StopDyMain() {
464 if (!g_initialized) {
465 return;
466 }
467
468 // Stop web server
469 WebServer::StopWebServer();
470
471 // Cleanup shared memory
472 if (g_sharedMemoryPtr) {
473 UnmapViewOfFile(g_sharedMemoryPtr);
474 g_sharedMemoryPtr = NULL;
475 }
476
477 if (g_sharedMemory) {
478 CloseHandle(g_sharedMemory);
479 g_sharedMemory = NULL;
480 }
481
482 // Close log file
483 if (g_logFile.is_open()) {
484 g_logFile.close();
485 }
486
487 g_initialized = false;
488 Utils::Logger::LogInfo("DyMain stopped");
489}
490 
491// Injection Manager
492namespace DyMain::Injection {
493 bool InitializeInjection(HMODULE hModule) {
494 try {
495 // Get process information
496 GetTargetProcessInfo();
497
498 // Protect DLL from detection
499 ProtectSelf();
500
501 Utils::Logger::LogInfo("Injection initialized successfully");
502 return true;
503 }
504 catch (const std::exception& e) {
505 Utils::Logger::LogError(std::string("Failed to initialize injection: ") + e.what());
506 return false;
507 }
508 }
509
510 void ProtectSelf() {
511 try {
512 // Get module handle
513 HMODULE hModule = GetModuleHandle(NULL);
514 if (hModule == NULL) {
515 throw std::runtime_error("Failed to get module handle");
516 }
517
518 // Get PEB
519 PEB* pPeb = (PEB*)__readgsqword(0x60);
520 if (pPeb == NULL) {
521 throw std::runtime_error("Failed to get PEB");
522 }
523
524 // Get LDR
525 PEB_LDR_DATA* pLdr = pPeb->Ldr;
526 if (pLdr == NULL) {
527 throw std::runtime_error("Failed to get LDR");
528 }
529
530 // Find our module in the LDR
531 LIST_ENTRY* pEntry = &pLdr->InLoadOrderModuleList;
532 LIST_ENTRY* pCurrent = pEntry->Flink;
533
534 while (pCurrent != pEntry) {
535 LDR_DATA_TABLE_ENTRY* pLdrEntry = CONTAINING_RECORD(pCurrent, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
536
537 if (pLdrEntry->DllBase == hModule) {
538 // Remove from InLoadOrderLinks
539 pCurrent->Blink->Flink = pCurrent->Flink;
540 pCurrent->Flink->Blink = pCurrent->Blink;
541
542 // Remove from InMemoryOrderLinks
543 pLdrEntry->InMemoryOrderLinks.Blink->Flink = pLdrEntry->InMemoryOrderLinks.Flink;
544 pLdrEntry->InMemoryOrderLinks.Flink->Blink = pLdrEntry->InMemoryOrderLinks.Blink;
545
546 // Remove from InInitializationOrderLinks
547 pLdrEntry->InInitializationOrderLinks.Blink->Flink = pLdrEntry->InInitializationOrderLinks.Flink;
548 pLdrEntry->InInitializationOrderLinks.Flink->Blink = pLdrEntry->InInitializationOrderLinks.Blink;
549
550 break;
551 }
552
553 pCurrent = pCurrent->Flink;
554 }
555
556 // Obfuscate memory regions
557 MEMORY_BASIC_INFORMATION mbi;
558 uintptr_t addr = (uintptr_t)hModule;
559
560 while (VirtualQuery((LPCVOID)addr, &mbi, sizeof(mbi))) {
561 if (mbi.State == MEM_COMMIT && mbi.Type == MEM_PRIVATE) {
562 // XOR memory region
563 uint8_t* data = (uint8_t*)mbi.BaseAddress;
564 for (size_t i = 0; i < mbi.RegionSize; i++) {
565 data[i] ^= 0xAA;
566 }
567 }
568
569 addr += mbi.RegionSize;
570 }
571
572 // Anti-debugging measures
573 if (IsDebuggerPresent()) {
574 throw std::runtime_error("Debugger detected");
575 }
576
577 // Check for common debugger artifacts
578 if (CheckRemoteDebuggerPresent(GetCurrentProcess(), NULL)) {
579 throw std::runtime_error("Remote debugger detected");
580 }
581
582 Utils::Logger::LogInfo("DLL protection completed successfully");
583 }
584 catch (const std::exception& e) {
585 Utils::Logger::LogError(std::string("Failed to protect DLL: ") + e.what());
586 }
587 }
588
589 void GetTargetProcessInfo() {
590 try {
591 // Get process ID
592 DWORD processId = GetCurrentProcessId();
593
594 // Get process handle
595 HANDLE hProcess = GetCurrentProcess();
596
597 // Get process name
598 WCHAR processName[MAX_PATH];
599 if (GetModuleFileNameW(NULL, processName, MAX_PATH) == 0) {
600 throw std::runtime_error("Failed to get process name");
601 }
602
603 // Get process path
604 WCHAR processPath[MAX_PATH];
605 if (GetModuleFileNameExW(hProcess, NULL, processPath, MAX_PATH) == 0) {
606 throw std::runtime_error("Failed to get process path");
607 }
608
609 // Get architecture
610 SYSTEM_INFO sysInfo;
611 GetNativeSystemInfo(&sysInfo);
612
613 // Get process memory info
614 PROCESS_MEMORY_COUNTERS_EX pmc;
615 if (GetProcessMemoryInfo(hProcess, (PROCESS_MEMORY_COUNTERS*)&pmc, sizeof(pmc))) {
616 // Log memory info
617 std::stringstream ss;
618 ss << "Process Memory Info:" << std::endl;
619 ss << " Working Set Size: " << pmc.WorkingSetSize << " bytes" << std::endl;
620 ss << " Private Usage: " << pmc.PrivateUsage << " bytes" << std::endl;
621 Utils::Logger::LogInfo(ss.str());
622 }
623
624 // Log process info
625 std::wstringstream ss;
626 ss << L"Process ID: " << processId << std::endl;
627 ss << L"Process Name: " << processName << std::endl;
628 ss << L"Process Path: " << processPath << std::endl;
629 ss << L"Architecture: " << (sysInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64 ? L"x64" : L"x86") << std::endl;
630
631 Utils::Logger::LogInfo(std::string(ss.str().begin(), ss.str().end()));
632 }
633 catch (const std::exception& e) {
634 Utils::Logger::LogError(std::string("Failed to get process info: ") + e.what());
635 }
636 }
637}
638 
639// Memory Manager
640namespace DyMain::Memory {
641 bool ReadMemory(uintptr_t addr, void* buffer, size_t size) {
642 try {
643 return ReadProcessMemory(GetCurrentProcess(), (LPCVOID)addr, buffer, size, NULL) != 0;
644 }
645 catch (const std::exception& e) {
646 Utils::Logger::LogError(std::string("Failed to read memory: ") + e.what());
647 return false;
648 }
649 }
650
651 bool WriteMemory(uintptr_t addr, const void* data, size_t size) {
652 try {
653 DWORD oldProtect;
654 if (!VirtualProtect((LPVOID)addr, size, PAGE_EXECUTE_READWRITE, &oldProtect)) {
655 return false;
656 }
657
658 bool result = WriteProcessMemory(GetCurrentProcess(), (LPVOID)addr, data, size, NULL) != 0;
659
660 VirtualProtect((LPVOID)addr, size, oldProtect, &oldProtect);
661 return result;
662 }
663 catch (const std::exception& e) {
664 Utils::Logger::LogError(std::string("Failed to write memory: ") + e.what());
665 return false;
666 }
667 }
668
669 void* AllocateMemory(size_t size) {
670 try {
671 return VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
672 }
673 catch (const std::exception& e) {
674 Utils::Logger::LogError(std::string("Failed to allocate memory: ") + e.what());
675 return NULL;
676 }
677 }
678
679 void FreeMemory(void* ptr) {
680 try {
681 VirtualFree(ptr, 0, MEM_RELEASE);
682 }
683 catch (const std::exception& e) {
684 Utils::Logger::LogError(std::string("Failed to free memory: ") + e.what());
685 }
686 }
687 
688 void AnalyzeMemoryRegions() {
689 try {
690 MEMORY_BASIC_INFORMATION mbi;
691 uintptr_t addr = 0;
692
693 while (VirtualQuery((LPCVOID)addr, &mbi, sizeof(mbi))) {
694 if (mbi.State == MEM_COMMIT) {
695 std::stringstream ss;
696 ss << "Memory Region at " << std::hex << (uintptr_t)mbi.BaseAddress << std::endl;
697 ss << " Size: " << mbi.RegionSize << " bytes" << std::endl;
698 ss << " State: " << (mbi.State == MEM_COMMIT ? "Committed" : "Reserved") << std::endl;
699 ss << " Type: " << (mbi.Type == MEM_IMAGE ? "Image" :
700 mbi.Type == MEM_MAPPED ? "Mapped" : "Private") << std::endl;
701 ss << " Protection: " << std::hex << mbi.Protect << std::endl;
702
703 // Analyze region content
704 if (mbi.State == MEM_COMMIT && mbi.Type == MEM_PRIVATE) {
705 std::vector<uint8_t> buffer(mbi.RegionSize);
706 if (ReadProcessMemory(GetCurrentProcess(), mbi.BaseAddress, buffer.data(), mbi.RegionSize, NULL)) {
707 // Implement pattern scanning
708 std::vector<std::string> patterns = {
709 "48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20", // Common function prologue
710 "48 8B C4 48 89 58 ?? 48 89 70 ?? 48 89 78 ?? 55", // Another common pattern
711 "48 83 EC 28 48 8B 05 ?? ?? ?? ?? 48 85 C0 74 ?? 48 8B 40" // Another pattern
712 };
713 
714 for (const auto& pattern : patterns) {
715 std::vector<int> bytes;
716 if (DyMain::Utils::PatternToByteArray(pattern, bytes)) {
717 std::vector<uintptr_t> matches;
718 if (DyMain::Utils::ScanMemoryForPatterns(pattern, matches)) {
719 ss << " Found pattern matches at:" << std::endl;
720 for (const auto& match : matches) {
721 ss << " " << std::hex << match << std::endl;
722 }
723 }
724 }
725 }
726 }
727 }
728
729 Utils::Logger::LogInfo(ss.str());
730 }
731
732 addr += mbi.RegionSize;
733 }
734 }
735 catch (const std::exception& e) {
736 Utils::Logger::LogError(std::string("Failed to analyze memory regions: ") + e.what());
737 }
738 }
739}
740 
741// Hook Manager
742namespace DyMain::Hook {
743 struct HookInfo {
744 void* target;
745 void* detour;
746 void* original;
747 std::string name;
748 };
749
750 static std::vector<HookInfo> g_hooks;
751
752 bool CreateInlineHook(void* target, void* detour, void** original) {
753 try {
754 if (!target || !detour) {
755 throw std::runtime_error("Invalid hook parameters");
756 }
757
758 // Create hook
759 if (DetourTransactionBegin() != NO_ERROR) {
760 throw std::runtime_error("Failed to begin hook transaction");
761 }
762
763 if (DetourUpdateThread(GetCurrentThread()) != NO_ERROR) {
764 throw std::runtime_error("Failed to update thread");
765 }
766
767 if (DetourAttach(&(PVOID&)target, detour) != NO_ERROR) {
768 throw std::runtime_error("Failed to attach hook");
769 }
770
771 if (DetourTransactionCommit() != NO_ERROR) {
772 throw std::runtime_error("Failed to commit hook transaction");
773 }
774
775 // Store hook info
776 HookInfo hook;
777 hook.target = target;
778 hook.detour = detour;
779 hook.original = *original;
780 hook.name = "Unknown";
781 g_hooks.push_back(hook);
782
783 Utils::Logger::LogInfo("Hook created successfully");
784 return true;
785 }
786 catch (const std::exception& e) {
787 Utils::Logger::LogError(std::string("Failed to create hook: ") + e.what());
788 return false;
789 }
790 }
791
792 bool RemoveHook(void* target) {
793 try {
794 if (!target) {
795 throw std::runtime_error("Invalid hook target");
796 }
797
798 // Find hook
799 auto it = std::find_if(g_hooks.begin(), g_hooks.end(),
800 [target](const HookInfo& hook) { return hook.target == target; });
801
802 if (it == g_hooks.end()) {
803 throw std::runtime_error("Hook not found");
804 }
805
806 // Remove hook
807 if (DetourTransactionBegin() != NO_ERROR) {
808 throw std::runtime_error("Failed to begin hook transaction");
809 }
810
811 if (DetourUpdateThread(GetCurrentThread()) != NO_ERROR) {
812 throw std::runtime_error("Failed to update thread");
813 }
814
815 if (DetourDetach(&(PVOID&)target, it->detour) != NO_ERROR) {
816 throw std::runtime_error("Failed to detach hook");
817 }
818
819 if (DetourTransactionCommit() != NO_ERROR) {
820 throw std::runtime_error("Failed to commit hook transaction");
821 }
822
823 // Remove from list
824 g_hooks.erase(it);
825
826 Utils::Logger::LogInfo("Hook removed successfully");
827 return true;
828 }
829 catch (const std::exception& e) {
830 Utils::Logger::LogError(std::string("Failed to remove hook: ") + e.what());
831 return false;
832 }
833 }
834
835 void ListActiveHooks() {
836 try {
837 std::stringstream ss;
838 ss << "Active Hooks:" << std::endl;
839
840 for (const auto& hook : g_hooks) {
841 ss << " Target: " << hook.target << std::endl;
842 ss << " Detour: " << hook.detour << std::endl;
843 ss << " Original: " << hook.original << std::endl;
844 ss << " Name: " << hook.name << std::endl;
845 ss << " ---" << std::endl;
846 }
847
848 Utils::Logger::LogInfo(ss.str());
849 }
850 catch (const std::exception& e) {
851 Utils::Logger::LogError(std::string("Failed to list hooks: ") + e.what());
852 }
853 }
854}
855 
856// Mod Manager
857namespace DyMain::Mod {
858 struct ModInfo {
859 std::string name;
860 std::string path;
861 HMODULE handle;
862 bool loaded;
863 std::vector<std::string> dependencies;
864 };
865
866 static std::vector<ModInfo> g_mods;
867
868 bool LoadMod(const std::string& modPath) {
869 try {
870 // Check if mod is already loaded
871 auto it = std::find_if(g_mods.begin(), g_mods.end(),
872 [&modPath](const ModInfo& mod) { return mod.path == modPath; });
873
874 if (it != g_mods.end()) {
875 if (it->loaded) {
876 Utils::Logger::LogWarning("Mod already loaded: " + modPath);
877 return true;
878 }
879 }
880
881 // Load DLL
882 HMODULE hModule = LoadLibraryA(modPath.c_str());
883 if (!hModule) {
884 throw std::runtime_error("Failed to load mod DLL");
885 }
886
887 // Get mod info
888 ModInfo mod;
889 mod.name = modPath.substr(modPath.find_last_of("/\\") + 1);
890 mod.path = modPath;
891 mod.handle = hModule;
892 mod.loaded = true;
893
894 // Get dependencies
895 std::vector<std::string> dependencies;
896 if (GetDependencies(modPath, dependencies)) {
897 mod.dependencies = dependencies;
898 }
899
900 // Add to list
901 g_mods.push_back(mod);
902
903 Utils::Logger::LogInfo("Mod loaded successfully: " + modPath);
904 return true;
905 }
906 catch (const std::exception& e) {
907 Utils::Logger::LogError(std::string("Failed to load mod: ") + e.what());
908 return false;
909 }
910 }
911 
912 bool GetDependencies(const std::string& modPath, std::vector<std::string>& dependencies) {
913 try {
914 // Carica la DLL per ottenere le dipendenze
915 HMODULE hModule = LoadLibraryA(modPath.c_str());
916 if (!hModule) {
917 return false;
918 }
919 
920 // Cerca la funzione GetDependencies
921 typedef bool (*GetDependenciesFunc)(std::vector<std::string>&);
922 GetDependenciesFunc getDeps = (GetDependenciesFunc)GetProcAddress(hModule, "GetDependencies");
923
924 if (getDeps) {
925 bool result = getDeps(dependencies);
926 FreeLibrary(hModule);
927 return result;
928 }
929 
930 FreeLibrary(hModule);
931 return false;
932 }
933 catch (const std::exception& e) {
934 Utils::Logger::LogError(std::string("Failed to get dependencies: ") + e.what());
935 return false;
936 }
937 }
938
939 bool UnloadMod(const std::string& modName) {
940 try {
941 // Find mod
942 auto it = std::find_if(g_mods.begin(), g_mods.end(),
943 [&modName](const ModInfo& mod) { return mod.name == modName; });
944
945 if (it == g_mods.end()) {
946 throw std::runtime_error("Mod not found: " + modName);
947 }
948
949 if (!it->loaded) {
950 throw std::runtime_error("Mod not loaded: " + modName);
951 }
952
953 // Unload DLL
954 if (!FreeLibrary(it->handle)) {
955 throw std::runtime_error("Failed to unload mod DLL");
956 }
957
958 // Remove from list
959 g_mods.erase(it);
960
961 Utils::Logger::LogInfo("Mod unloaded successfully: " + modName);
962 return true;
963 }
964 catch (const std::exception& e) {
965 Utils::Logger::LogError(std::string("Failed to unload mod: ") + e.what());
966 return false;
967 }
968 }
969
970 void ListMods() {
971 try {
972 std::stringstream ss;
973 ss << "Loaded Mods:" << std::endl;
974
975 for (const auto& mod : g_mods) {
976 ss << " Name: " << mod.name << std::endl;
977 ss << " Path: " << mod.path << std::endl;
978 ss << " Handle: " << mod.handle << std::endl;
979 ss << " Loaded: " << (mod.loaded ? "Yes" : "No") << std::endl;
980 ss << " Dependencies: " << std::endl;
981 for (const auto& dep : mod.dependencies) {
982 ss << " - " << dep << std::endl;
983 }
984 ss << " ---" << std::endl;
985 }
986
987 Utils::Logger::LogInfo(ss.str());
988 }
989 catch (const std::exception& e) {
990 Utils::Logger::LogError(std::string("Failed to list mods: ") + e.what());
991 }
992 }
993}
994 
995// Deep Analyzer
996namespace DyMain::Analyzer {
997 void ListThreads() {
998 try {
999 HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
1000 if (hSnapshot == INVALID_HANDLE_VALUE) {
1001 throw std::runtime_error("Failed to create thread snapshot");
1002 }
1003
1004 THREADENTRY32 te32;
1005 te32.dwSize = sizeof(te32);
1006
1007 if (Thread32First(hSnapshot, &te32)) {
1008 do {
1009 if (te32.th32OwnerProcessID == GetCurrentProcessId()) {
1010 // Get thread context
1011 HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, te32.th32ThreadID);
1012 if (hThread) {
1013 CONTEXT ctx;
1014 ctx.ContextFlags = CONTEXT_ALL;
1015
1016 if (GetThreadContext(hThread, &ctx)) {
1017 std::stringstream ss;
1018 ss << "Thread ID: " << te32.th32ThreadID << std::endl;
1019 ss << " Base Priority: " << te32.tpBasePri << std::endl;
1020 ss << " Priority: " << te32.tpDeltaPri << std::endl;
1021 ss << " Context:" << std::endl;
1022 ss << " RIP: " << std::hex << ctx.Rip << std::endl;
1023 ss << " RSP: " << std::hex << ctx.Rsp << std::endl;
1024 ss << " RBP: " << std::hex << ctx.Rbp << std::endl;
1025 Utils::Logger::LogInfo(ss.str());
1026 }
1027
1028 CloseHandle(hThread);
1029 }
1030 }
1031 } while (Thread32Next(hSnapshot, &te32));
1032 }
1033
1034 CloseHandle(hSnapshot);
1035 }
1036 catch (const std::exception& e) {
1037 Utils::Logger::LogError(std::string("Failed to list threads: ") + e.what());
1038 }
1039 }
1040
1041 void DumpModules() {
1042 try {
1043 HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId());
1044 if (hSnapshot == INVALID_HANDLE_VALUE) {
1045 throw std::runtime_error("Failed to create module snapshot");
1046 }
1047
1048 MODULEENTRY32 me32;
1049 me32.dwSize = sizeof(me32);
1050
1051 if (Module32First(hSnapshot, &me32)) {
1052 do {
1053 // Get module info
1054 std::stringstream ss;
1055 ss << "Module: " << me32.szModule << std::endl;
1056 ss << " Path: " << me32.szExePath << std::endl;
1057 ss << " Base Address: " << std::hex << (uintptr_t)me32.modBaseAddr << std::endl;
1058 ss << " Size: " << me32.modBaseSize << " bytes" << std::endl;
1059 ss << " Entry Point: " << std::hex << (uintptr_t)me32.modBaseAddr + me32.modBaseSize << std::endl;
1060
1061 // Get module memory info
1062 MEMORY_BASIC_INFORMATION mbi;
1063 if (VirtualQuery(me32.modBaseAddr, &mbi, sizeof(mbi))) {
1064 ss << " Memory Info:" << std::endl;
1065 ss << " State: " << (mbi.State == MEM_COMMIT ? "Committed" : "Reserved") << std::endl;
1066 ss << " Type: " << (mbi.Type == MEM_IMAGE ? "Image" : "Private") << std::endl;
1067 ss << " Protection: " << std::hex << mbi.Protect << std::endl;
1068 }
1069
1070 Utils::Logger::LogInfo(ss.str());
1071 } while (Module32Next(hSnapshot, &me32));
1072 }
1073
1074 CloseHandle(hSnapshot);
1075 }
1076 catch (const std::exception& e) {
1077 Utils::Logger::LogError(std::string("Failed to dump modules: ") + e.what());
1078 }
1079 }
1080
1081 void DetectAntiCheatMechanisms() {
1082 try {
1083 // Check for common anti-cheat processes
1084 HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
1085 if (hSnapshot == INVALID_HANDLE_VALUE) {
1086 throw std::runtime_error("Failed to create process snapshot");
1087 }
1088
1089 PROCESSENTRY32W pe32;
1090 pe32.dwSize = sizeof(pe32);
1091
1092 if (Process32FirstW(hSnapshot, &pe32)) {
1093 do {
1094 // Check for known anti-cheat processes
1095 std::wstring processName(pe32.szExeFile);
1096 std::transform(processName.begin(), processName.end(), processName.begin(), ::tolower);
1097
1098 if (processName.find(L"battleye") != std::wstring::npos ||
1099 processName.find(L"easyanticheat") != std::wstring::npos ||
1100 processName.find(L"vac") != std::wstring::npos) {
1101 std::stringstream ss;
1102 ss << "Anti-cheat process detected: " << std::string(processName.begin(), processName.end());
1103 Utils::Logger::LogWarning(ss.str());
1104 }
1105 } while (Process32NextW(hSnapshot, &pe32));
1106 }
1107
1108 CloseHandle(hSnapshot);
1109
1110 // Implement driver scanning
1111 std::vector<std::wstring> driverNames = {
1112 L"BEClient_x64.sys",
1113 L"EasyAntiCheat.sys",
1114 L"vac.sys"
1115 };
1116 
1117 for (const auto& driverName : driverNames) {
1118 HANDLE hDriver = CreateFileW(
1119 driverName.c_str(),
1120 GENERIC_READ,
1121 FILE_SHARE_READ | FILE_SHARE_WRITE,
1122 NULL,
1123 OPEN_EXISTING,
1124 FILE_ATTRIBUTE_NORMAL,
1125 NULL
1126 );
1127 
1128 if (hDriver != INVALID_HANDLE_VALUE) {
1129 std::stringstream ss;
1130 ss << "Anti-cheat driver detected: " << std::string(driverName.begin(), driverName.end());
1131 Utils::Logger::LogWarning(ss.str());
1132 CloseHandle(hDriver);
1133 }
1134 }
1135
1136 // Implement registry scanning
1137 std::vector<std::wstring> registryPaths = {
1138 L"SOFTWARE\\BattlEye",
1139 L"SOFTWARE\\EasyAntiCheat",
1140 L"SOFTWARE\\Valve\\VAC"
1141 };
1142 
1143 for (const auto& path : registryPaths) {
1144 HKEY hKey;
1145 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, path.c_str(), 0, KEY_READ, &hKey) == ERROR_SUCCESS) {
1146 std::stringstream ss;
1147 ss << "Anti-cheat registry key detected: " << std::string(path.begin(), path.end());
1148 Utils::Logger::LogWarning(ss.str());
1149 RegCloseKey(hKey);
1150 }
1151 }
1152 }
1153 catch (const std::exception& e) {
1154 Utils::Logger::LogError(std::string("Failed to detect anti-cheat mechanisms: ") + e.what());
1155 }
1156 }
1157 
1158 void AnalyzeMemoryRegions() {
1159 try {
1160 MEMORY_BASIC_INFORMATION mbi;
1161 uintptr_t addr = 0;
1162
1163 while (VirtualQuery((LPCVOID)addr, &mbi, sizeof(mbi))) {
1164 if (mbi.State == MEM_COMMIT) {
1165 std::stringstream ss;
1166 ss << "Memory Region at " << std::hex << (uintptr_t)mbi.BaseAddress << std::endl;
1167 ss << " Size: " << mbi.RegionSize << " bytes" << std::endl;
1168 ss << " State: " << (mbi.State == MEM_COMMIT ? "Committed" : "Reserved") << std::endl;
1169 ss << " Type: " << (mbi.Type == MEM_IMAGE ? "Image" :
1170 mbi.Type == MEM_MAPPED ? "Mapped" : "Private") << std::endl;
1171 ss << " Protection: " << std::hex << mbi.Protect << std::endl;
1172
1173 // Analyze region content
1174 if (mbi.State == MEM_COMMIT && mbi.Type == MEM_PRIVATE) {
1175 std::vector<uint8_t> buffer(mbi.RegionSize);
1176 if (ReadProcessMemory(GetCurrentProcess(), mbi.BaseAddress, buffer.data(), mbi.RegionSize, NULL)) {
1177 // Implement pattern scanning
1178 std::vector<std::string> patterns = {
1179 "48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20", // Common function prologue
1180 "48 8B C4 48 89 58 ?? 48 89 70 ?? 48 89 78 ?? 55", // Another common pattern
1181 "48 83 EC 28 48 8B 05 ?? ?? ?? ?? 48 85 C0 74 ?? 48 8B 40" // Another pattern
1182 };
1183 
1184 for (const auto& pattern : patterns) {
1185 std::vector<int> bytes;
1186 if (DyMain::Utils::PatternToByteArray(pattern, bytes)) {
1187 std::vector<uintptr_t> matches;
1188 if (DyMain::Utils::ScanMemoryForPatterns(pattern, matches)) {
1189 ss << " Found pattern matches at:" << std::endl;
1190 for (const auto& match : matches) {
1191 ss << " " << std::hex << match << std::endl;
1192 }
1193 }
1194 }
1195 }
1196 }
1197 }
1198
1199 Utils::Logger::LogInfo(ss.str());
1200 }
1201
1202 addr += mbi.RegionSize;
1203 }
1204 }
1205 catch (const std::exception& e) {
1206 Utils::Logger::LogError(std::string("Failed to analyze memory regions: ") + e.what());
1207 }
1208 }
1209}
1210 
1211// Web Server Integration
1212namespace DyMain::WebServer {
1213 struct WebServerConfig {
1214 int port;
1215 std::string rootPath;
1216 bool enableWebSocket;
1217 bool enableSSL;
1218 std::string sslCert;
1219 std::string sslKey;
1220 };
1221
1222 static WebServerConfig g_config;
1223 static bool g_running = false;
1224 static struct mg_mgr g_mgr;
1225 static struct mg_connection* g_ws_connection = NULL;
1226
1227 // HTTP request handler
1228 static void HandleRequest(struct mg_connection* c, int ev, void* ev_data) {
1229 if (ev == MG_EV_HTTP_MSG) {
1230 struct mg_http_message* hm = static_cast<struct mg_http_message*>(ev_data);
1231
1232 // Handle different endpoints
1233 std::string uri = std::string(hm->uri.buf, hm->uri.len);
1234
1235 if (uri == "/memory") {
1236 // Return memory information
1237 std::stringstream ss;
1238 ss << "{\"status\":\"ok\",\"data\":{";
1239
1240 // Get memory info
1241 PROCESS_MEMORY_COUNTERS_EX pmc;
1242 if (GetProcessMemoryInfo(GetCurrentProcess(), (PROCESS_MEMORY_COUNTERS*)&pmc, sizeof(pmc))) {
1243 ss << "\"workingSetSize\":" << pmc.WorkingSetSize << ",";
1244 ss << "\"privateUsage\":" << pmc.PrivateUsage;
1245 }
1246
1247 ss << "}}";
1248
1249 mg_http_reply(c, 200, "Content-Type: application/json\r\n", "%s", ss.str().c_str());
1250 }
1251 else if (uri == "/hooks") {
1252 // Return active hooks
1253 std::stringstream ss;
1254 ss << "{\"status\":\"ok\",\"data\":[";
1255
1256 bool first = true;
1257 for (const auto& hook : Hook::g_hooks) {
1258 if (!first) ss << ",";
1259 ss << "{\"target\":\"" << hook.target << "\",";
1260 ss << "\"detour\":\"" << hook.detour << "\",";
1261 ss << "\"original\":\"" << hook.original << "\",";
1262 ss << "\"name\":\"" << hook.name << "\"}";
1263 first = false;
1264 }
1265
1266 ss << "]}";
1267
1268 mg_http_reply(c, 200, "Content-Type: application/json\r\n", "%s", ss.str().c_str());
1269 }
1270 else if (uri == "/mods") {
1271 // Return loaded mods
1272 std::stringstream ss;
1273 ss << "{\"status\":\"ok\",\"data\":[";
1274
1275 bool first = true;
1276 for (const auto& mod : Mod::g_mods) {
1277 if (!first) ss << ",";
1278 ss << "{\"name\":\"" << mod.name << "\",";
1279 ss << "\"path\":\"" << mod.path << "\",";
1280 ss << "\"handle\":\"" << mod.handle << "\",";
1281 ss << "\"loaded\":" << (mod.loaded ? "true" : "false") << ",";
1282 ss << "\"dependencies\":[";
1283
1284 bool firstDep = true;
1285 for (const auto& dep : mod.dependencies) {
1286 if (!firstDep) ss << ",";
1287 ss << "\"" << dep << "\"";
1288 firstDep = false;
1289 }
1290
1291 ss << "]}";
1292 first = false;
1293 }
1294
1295 ss << "]}";
1296
1297 mg_http_reply(c, 200, "Content-Type: application/json\r\n", "%s", ss.str().c_str());
1298 }
1299 else if (uri == "/process") {
1300 // Return process information
1301 std::stringstream ss;
1302 ss << "{\"status\":\"ok\",\"data\":{";
1303
1304 // Get process info
1305 DWORD processId = GetCurrentProcessId();
1306 HANDLE hProcess = GetCurrentProcess();
1307
1308 // Get process name
1309 WCHAR processName[MAX_PATH];
1310 if (GetModuleFileNameW(NULL, processName, MAX_PATH)) {
1311 ss << "\"name\":\"" << std::string(processName, processName + wcslen(processName)) << "\",";
1312 }
1313
1314 // Get process path
1315 WCHAR processPath[MAX_PATH];
1316 if (GetModuleFileNameExW(hProcess, NULL, processPath, MAX_PATH)) {
1317 ss << "\"path\":\"" << std::string(processPath, processPath + wcslen(processPath)) << "\",";
1318 }
1319
1320 // Get architecture
1321 SYSTEM_INFO sysInfo;
1322 GetNativeSystemInfo(&sysInfo);
1323 ss << "\"architecture\":\"" << (sysInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64 ? "x64" : "x86") << "\",";
1324
1325 // Get memory info
1326 PROCESS_MEMORY_COUNTERS_EX pmc;
1327 if (GetProcessMemoryInfo(hProcess, (PROCESS_MEMORY_COUNTERS*)&pmc, sizeof(pmc))) {
1328 ss << "\"workingSetSize\":" << pmc.WorkingSetSize << ",";
1329 ss << "\"privateUsage\":" << pmc.PrivateUsage;
1330 }
1331
1332 ss << "}}";
1333
1334 mg_http_reply(c, 200, "Content-Type: application/json\r\n", "%s", ss.str().c_str());
1335 }
1336 else if (uri == "/command") {
1337 // Handle command execution
1338 struct mg_http_message* hm = (struct mg_http_message*)ev_data;
1339 char cmd[256];
1340 if (mg_http_get_var_value(hm, "command", cmd, sizeof(cmd)) < 0) {
1341 mg_http_reply(c, 400, "Content-Type: application/json\r\n",
1342 "{\"status\":\"error\",\"message\":\"Missing command parameter\"}");
1343 return;
1344 }
1345
1346 // Process command
1347 std::string command(cmd);
1348 std::istringstream iss(command);
1349 std::string cmdType;
1350 iss >> cmdType;
1351
1352 std::string response;
1353 if (cmdType == "START_ANALYSIS") {
1354 Analyzer::ListThreads();
1355 Analyzer::DumpModules();
1356 Analyzer::AnalyzeMemoryRegions();
1357 Analyzer::DetectAntiCheatMechanisms();
1358 response = "{\"status\":\"ok\",\"message\":\"Analysis started\"}";
1359 }
1360 else if (cmdType == "STOP_ANALYSIS") {
1361 // TODO: Implement analysis stop
1362 response = "{\"status\":\"ok\",\"message\":\"Analysis stopped\"}";
1363 }
1364 else if (cmdType == "LOAD_MOD") {
1365 std::string modPath;
1366 iss >> modPath;
1367 if (Mod::LoadMod(modPath)) {
1368 response = "{\"status\":\"ok\",\"message\":\"Mod loaded\"}";
1369 }
1370 else {
1371 response = "{\"status\":\"error\",\"message\":\"Failed to load mod\"}";
1372 }
1373 }
1374 else if (cmdType == "UNLOAD_MOD") {
1375 std::string modName;
1376 iss >> modName;
1377 if (Mod::UnloadMod(modName)) {
1378 response = "{\"status\":\"ok\",\"message\":\"Mod unloaded\"}";
1379 }
1380 else {
1381 response = "{\"status\":\"error\",\"message\":\"Failed to unload mod\"}";
1382 }
1383 }
1384 else {
1385 response = "{\"status\":\"error\",\"message\":\"Unknown command\"}";
1386 }
1387
1388 mg_http_reply(c, 200, "Content-Type: application/json\r\n", "%s", response.c_str());
1389 }
1390 else {
1391 // Serve static files
1392 struct mg_http_serve_opts opts = {0};
1393 opts.root_dir = g_config.rootPath.c_str();
1394 mg_http_serve_dir(c, static_cast<struct mg_http_message*>(ev_data), &opts);
1395 }
1396 }
1397 }
1398
1399 bool StartWebServer(int port) {
1400 if (g_running) {
1401 return true;
1402 }
1403
1404 mg_mgr_init(&g_mgr);
1405
1406 std::string addr = "http://localhost:" + std::to_string(port);
1407 struct mg_connection* c = mg_http_listen(&g_mgr, addr.c_str(), HandleRequest, nullptr);
1408
1409 if (c == nullptr) {
1410 mg_mgr_free(&g_mgr);
1411 return false;
1412 }
1413
1414 g_running = true;
1415 return true;
1416 }
1417
1418 void StopWebServer() {
1419 try {
1420 if (!g_running) {
1421 return;
1422 }
1423
1424 g_running = false;
1425
1426 // Cleanup Mongoose
1427 mg_mgr_free(&g_mgr);
1428
1429 Utils::Logger::LogInfo("Web server stopped");
1430 }
1431 catch (const std::exception& e) {
1432 Utils::Logger::LogError(std::string("Failed to stop web server: ") + e.what());
1433 }
1434 }
1435
1436 void BroadcastEvent(const std::string& event) {
1437 try {
1438 if (!g_running || !g_ws_connection) {
1439 throw std::runtime_error("WebSocket not available");
1440 }
1441
1442 // Send WebSocket message
1443 if (mg_websocket_send(g_ws_connection, event.c_str(), event.length(), MG_WS_OP_TEXT) < 0) {
1444 throw std::runtime_error("Failed to send WebSocket message");
1445 }
1446
1447 Utils::Logger::LogInfo("Event broadcasted: " + event);
1448 }
1449 catch (const std::exception& e) {
1450 Utils::Logger::LogError(std::string("Failed to broadcast event: ") + e.what());
1451 }
1452 }
1453}
1454 
1455// Utility Helpers
1456namespace DyMain::Utils {
1457 bool PatternToByteArray(const std::string& pattern, std::vector<int>& bytes) {
1458 try {
1459 std::istringstream iss(pattern);
1460 std::string byte;
1461
1462 while (std::getline(iss, byte, ' ')) {
1463 if (byte == "?") {
1464 bytes.push_back(-1);
1465 }
1466 else {
1467 bytes.push_back(std::stoi(byte, nullptr, 16));
1468 }
1469 }
1470
1471 return true;
1472 }
1473 catch (const std::exception& e) {
1474 Logger::LogError(std::string("Failed to convert pattern to byte array: ") + e.what());
1475 return false;
1476 }
1477 }
1478
1479 bool CompareMemoryPattern(const uint8_t* data, const std::vector<int>& pattern) {
1480 for (size_t i = 0; i < pattern.size(); i++) {
1481 if (pattern[i] != -1 && data[i] != pattern[i]) {
1482 return false;
1483 }
1484 }
1485 return true;
1486 }
1487
1488 bool ScanMemoryForPatterns(const std::string& pattern, std::vector<uintptr_t>& matches) {
1489 try {
1490 std::vector<int> bytes;
1491 if (!PatternToByteArray(pattern, bytes)) {
1492 return false;
1493 }
1494
1495 MEMORY_BASIC_INFORMATION mbi;
1496 uintptr_t addr = 0;
1497
1498 while (VirtualQuery((LPCVOID)addr, &mbi, sizeof(mbi))) {
1499 if (mbi.State == MEM_COMMIT &&
1500 (mbi.Protect & PAGE_READWRITE) &&
1501 !(mbi.Protect & PAGE_GUARD)) {
1502
1503 std::vector<uint8_t> buffer(mbi.RegionSize);
1504 if (ReadProcessMemory(GetCurrentProcess(), mbi.BaseAddress, buffer.data(), mbi.RegionSize, NULL)) {
1505 for (size_t i = 0; i < buffer.size() - bytes.size(); i++) {
1506 if (CompareMemoryPattern(&buffer[i], bytes)) {
1507 matches.push_back((uintptr_t)mbi.BaseAddress + i);
1508 }
1509 }
1510 }
1511 }
1512
1513 addr += mbi.RegionSize;
1514 }
1515
1516 return true;
1517 }
1518 catch (const std::exception& e) {
1519 Logger::LogError(std::string("Failed to scan memory: ") + e.what());
1520 return false;
1521 }
1522 }
1523
1524 void HexDump(const void* ptr, size_t size) {
1525 const uint8_t* data = (const uint8_t*)ptr;
1526 std::stringstream ss;
1527
1528 for (size_t i = 0; i < size; i += 16) {
1529 ss << std::hex << std::setw(8) << std::setfill('0') << i << ": ";
1530
1531 for (size_t j = 0; j < 16; j++) {
1532 if (i + j < size) {
1533 ss << std::hex << std::setw(2) << std::setfill('0') << (int)data[i + j] << " ";
1534 }
1535 else {
1536 ss << " ";
1537 }
1538 }
1539
1540 ss << " ";
1541
1542 for (size_t j = 0; j < 16; j++) {
1543 if (i + j < size) {
1544 char c = data[i + j];
1545 ss << (isprint(c) ? c : '.');
1546 }
1547 }
1548
1549 ss << "\n";
1550 }
1551
1552 Logger::LogInfo(ss.str());
1553 }
1554
1555 namespace Logger {
1556 void LogInfo(const std::string& msg) {
1557 if (g_logFile.is_open()) {
1558 auto now = std::chrono::system_clock::now();
1559 auto time = std::chrono::system_clock::to_time_t(now);
1560 g_logFile << std::put_time(std::localtime(&time), "%Y-%m-%d %H:%M:%S")
1561 << " [INFO] " << msg << std::endl;
1562 }
1563 }
1564
1565 void LogWarning(const std::string& msg) {
1566 if (g_logFile.is_open()) {
1567 auto now = std::chrono::system_clock::now();
1568 auto time = std::chrono::system_clock::to_time_t(now);
1569 g_logFile << std::put_time(std::localtime(&time), "%Y-%m-%d %H:%M:%S")
1570 << " [WARNING] " << msg << std::endl;
1571 }
1572 }
1573
1574 void LogError(const std::string& msg) {
1575 if (g_logFile.is_open()) {
1576 auto now = std::chrono::system_clock::now();
1577 auto time = std::chrono::system_clock::to_time_t(now);
1578 g_logFile << std::put_time(std::localtime(&time), "%Y-%m-%d %H:%M:%S")
1579 << " [ERROR] " << msg << std::endl;
1580 }
1581 }
1582 }
1583}
1584 
1585// DLL entry point
1586BOOL APIENTRY DllMain(HMODULE hModule, DWORD reason, LPVOID lpReserved) {
1587 switch (reason) {
1588 case DLL_PROCESS_ATTACH:
1589 return DyMain::StartDyMain(hModule);
1590
1591 case DLL_PROCESS_DETACH:
1592 DyMain::StopDyMain();
1593 break;
1594 }
1595
1596 return TRUE;
1597}
1598