diff --git a/Scylla/DllInjection.cpp b/Scylla/DllInjection.cpp index 422d97c..69d3434 100644 --- a/Scylla/DllInjection.cpp +++ b/Scylla/DllInjection.cpp @@ -1,225 +1,225 @@ #include "DllInjection.h" #include #include "Scylla.h" #include "NativeWinApi.h" #include "ProcessAccessHelp.h" #pragma comment(lib, "Psapi.lib") //#define DEBUG_COMMENTS HMODULE DllInjection::dllInjection(HANDLE hProcess, const WCHAR * filename) { LPVOID remoteMemory = 0; SIZE_T memorySize = 0; HANDLE hThread = 0; HMODULE hModule = 0; memorySize = (wcslen(filename) + 1) * sizeof(WCHAR); if (memorySize < 7) { #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"dllInjection :: memorySize invalid"); #endif return 0; } remoteMemory = VirtualAllocEx(hProcess, NULL, memorySize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); if (remoteMemory == 0) { #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"dllInjection :: VirtualAllocEx failed 0x%X", GetLastError()); #endif return 0; } if (WriteProcessMemory(hProcess, remoteMemory, filename, memorySize, &memorySize)) { hThread = startRemoteThread(hProcess,LoadLibraryW,remoteMemory); if (hThread) { WaitForSingleObject(hThread, INFINITE); #ifdef _WIN64 hModule = getModuleHandleByFilename(hProcess, filename); #else //returns only 32 bit values -> design bug by microsoft if (!GetExitCodeThread(hThread, (LPDWORD) &hModule)) { #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"dllInjection :: GetExitCodeThread failed 0x%X", GetLastError()); #endif hModule = 0; } #endif CloseHandle(hThread); } else { #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"dllInjection :: CreateRemoteThread failed 0x%X", GetLastError()); #endif } } else { #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"dllInjection :: WriteProcessMemory failed 0x%X", GetLastError()); #endif } VirtualFreeEx(hProcess, remoteMemory, 0, MEM_RELEASE); return hModule; } bool DllInjection::unloadDllInProcess(HANDLE hProcess, HMODULE hModule) { HANDLE hThread = 0; DWORD lpThreadId = 0; BOOL freeLibraryRet = 0; hThread = startRemoteThread(hProcess,FreeLibrary,hModule); if (hThread) { WaitForSingleObject(hThread, INFINITE); if (!GetExitCodeThread(hThread, (LPDWORD) &freeLibraryRet)) { #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"unloadDllInProcess :: GetExitCodeThread failed 0x%X", GetLastError()); #endif freeLibraryRet = 0; } CloseHandle(hThread); } else { #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"unloadDllInProcess :: CreateRemoteThread failed 0x%X", GetLastError()); #endif } return freeLibraryRet != 0; } HMODULE DllInjection::getModuleHandleByFilename( HANDLE hProcess, const WCHAR * filename ) { HMODULE * hMods = 0; HMODULE hModResult = 0; WCHAR target[MAX_PATH]; DWORD numHandles = ProcessAccessHelp::getModuleHandlesFromProcess(hProcess, &hMods); if (numHandles == 0) { return 0; } for (DWORD i = 0; i < numHandles; i++) { if (GetModuleFileNameExW(hProcess, hMods[i], target, _countof(target))) { if (!_wcsicmp(target, filename)) { hModResult = hMods[i]; break; } } else { #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"DllInjection::getModuleHandle :: GetModuleFileNameExW failed 0x%X", GetLastError()); #endif } } if (!hModResult) { #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"DllInjection::getModuleHandle :: Handle not found"); #endif } delete [] hMods; return hModResult; } void DllInjection::specialThreadSettings( HANDLE hThread ) { if (hThread) { if (!SetThreadPriority(hThread, THREAD_PRIORITY_TIME_CRITICAL)) { #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"specialThreadSettings :: SetThreadPriority(hThread, THREAD_PRIORITY_TIME_CRITICAL) failed 0x%X", GetLastError()); #endif } if (NativeWinApi::NtSetInformationThread) { if (NativeWinApi::NtSetInformationThread(hThread, ThreadHideFromDebugger, 0, 0) != STATUS_SUCCESS) { #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"specialThreadSettings :: NtSetInformationThread ThreadHideFromDebugger failed"); #endif } } } } HANDLE DllInjection::startRemoteThread(HANDLE hProcess, LPVOID lpStartAddress, LPVOID lpParameter) { HANDLE hThread = 0; hThread = customCreateRemoteThread(hProcess, lpStartAddress, lpParameter); if (hThread) { specialThreadSettings(hThread); ResumeThread(hThread); } return hThread; } HANDLE DllInjection::customCreateRemoteThread(HANDLE hProcess, LPVOID lpStartAddress, LPVOID lpParameter) { DWORD lpThreadId = 0; HANDLE hThread = 0; NTSTATUS ntStatus = 0; if (NativeWinApi::NtCreateThreadEx) { #define THREAD_ALL_ACCESS_VISTA_7 (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xFFFF) //for windows vista/7 - ntStatus = NativeWinApi::NtCreateThreadEx(&hThread, THREAD_ALL_ACCESS_VISTA_7, 0, hProcess, (LPTHREAD_START_ROUTINE)lpStartAddress, (LPVOID)lpParameter, TRUE, 0, 0, 0, 0); + ntStatus = NativeWinApi::NtCreateThreadEx(&hThread, THREAD_ALL_ACCESS_VISTA_7, 0, hProcess, (LPTHREAD_START_ROUTINE)lpStartAddress, (LPVOID)lpParameter, NtCreateThreadExFlagCreateSuspended|NtCreateThreadExFlagHideFromDebugger, 0, 0, 0, 0); if (NT_SUCCESS(ntStatus)) { return hThread; } else { #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"customCreateRemoteThread :: NtCreateThreadEx failed 0x%X", NativeWinApi::RtlNtStatusToDosError(ntStatus)); #endif return 0; } } else { return CreateRemoteThread(hProcess,NULL,NULL,(LPTHREAD_START_ROUTINE)lpStartAddress,lpParameter,CREATE_SUSPENDED,&lpThreadId); } } diff --git a/Scylla/NativeWinApi.h b/Scylla/NativeWinApi.h index 602cf2c..abd5987 100644 --- a/Scylla/NativeWinApi.h +++ b/Scylla/NativeWinApi.h @@ -1,287 +1,290 @@ #pragma once #include #define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L) #define STATUS_SUCCESS ((NTSTATUS)0x00000000L) #define DUPLICATE_SAME_ATTRIBUTES 0x00000004 #define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0) typedef enum _SYSTEM_INFORMATION_CLASS { SystemBasicInformation, SystemProcessorInformation, SystemPerformanceInformation, SystemTimeOfDayInformation, SystemPathInformation, SystemProcessInformation, SystemCallCountInformation, SystemDeviceInformation, SystemProcessorPerformanceInformation, SystemFlagsInformation, SystemCallTimeInformation, SystemModuleInformation, SystemLocksInformation, SystemStackTraceInformation, SystemPagedPoolInformation, SystemNonPagedPoolInformation, SystemHandleInformation, SystemObjectInformation, SystemPageFileInformation, SystemVdmInstemulInformation, SystemVdmBopInformation, SystemFileCacheInformation, SystemPoolTagInformation, SystemInterruptInformation, SystemDpcBehaviorInformation, SystemFullMemoryInformation, SystemLoadGdiDriverInformation, SystemUnloadGdiDriverInformation, SystemTimeAdjustmentInformation, SystemSummaryMemoryInformation, SystemNextEventIdInformation, SystemEventIdsInformation, SystemCrashDumpInformation, SystemExceptionInformation, SystemCrashDumpStateInformation, SystemKernelDebuggerInformation, SystemContextSwitchInformation, SystemRegistryQuotaInformation, SystemExtendServiceTableInformation, SystemPrioritySeperation, SystemPlugPlayBusInformation, SystemDockInformation, SystemPowerInformation2, SystemProcessorSpeedInformation, SystemCurrentTimeZoneInformation, SystemLookasideInformation } SYSTEM_INFORMATION_CLASS; typedef struct _IO_STATUS_BLOCK { union { NTSTATUS Status; PVOID Pointer; }; ULONG_PTR Information; } IO_STATUS_BLOCK, *PIO_STATUS_BLOCK; typedef struct _FILE_NAME_INFORMATION { // Information Classes 9 and 21 ULONG FileNameLength; WCHAR FileName[1]; } FILE_NAME_INFORMATION; typedef enum _FILE_INFORMATION_CLASS { FileNameInformation=9, } FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS; typedef struct _UNICODE_STRING { USHORT Length; USHORT MaximumLength; PWSTR Buffer; } UNICODE_STRING, *PUNICODE_STRING; typedef struct _CLIENT_ID{ HANDLE UniqueProcess; HANDLE UniqueThread; } CLIENT_ID, *PCLIENT_ID; #define InitializeObjectAttributes(p,n,a,r,s) \ { \ (p)->Length = sizeof(OBJECT_ATTRIBUTES); \ (p)->ObjectName = n; \ (p)->Attributes = a; \ (p)->RootDirectory = r; \ (p)->SecurityDescriptor = s; \ (p)->SecurityQualityOfService = NULL; \ } typedef struct _OBJECT_ATTRIBUTES { ULONG Length; PVOID RootDirectory; PUNICODE_STRING ObjectName; ULONG Attributes; PVOID SecurityDescriptor; PVOID SecurityQualityOfService; } OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES; typedef enum _OBJECT_INFORMATION_CLASS { ObjectBasicInformation, ObjectNameInformation, ObjectTypeInformation, ObjectAllInformation, ObjectDataInformation } OBJECT_INFORMATION_CLASS, *POBJECT_INFORMATION_CLASS; typedef enum _THREADINFOCLASS { ThreadBasicInformation, ThreadTimes, ThreadPriority, ThreadBasePriority, ThreadAffinityMask, ThreadImpersonationToken, ThreadDescriptorTableEntry, ThreadEnableAlignmentFaultFixup, ThreadEventPair_Reusable, ThreadQuerySetWin32StartAddress, ThreadZeroTlsCell, ThreadPerformanceCount, ThreadAmILastThread, ThreadIdealProcessor, ThreadPriorityBoost, ThreadSetTlsArrayAddress, ThreadIsIoPending, ThreadHideFromDebugger, ThreadBreakOnTermination, MaxThreadInfoClass } THREADINFOCLASS; // // Memory Information Classes for NtQueryVirtualMemory // typedef enum _MEMORY_INFORMATION_CLASS { MemoryBasicInformation, MemoryWorkingSetList, MemorySectionName, MemoryBasicVlmInformation } MEMORY_INFORMATION_CLASS; typedef enum _PROCESSINFOCLASS { ProcessBasicInformation, ProcessQuotaLimits, ProcessIoCounters, ProcessVmCounters, ProcessTimes, ProcessBasePriority, ProcessRaisePriority, ProcessDebugPort, ProcessExceptionPort, ProcessAccessToken, ProcessLdtInformation, ProcessLdtSize, ProcessDefaultHardErrorMode, ProcessIoPortHandlers, ProcessPooledUsageAndLimits, ProcessWorkingSetWatch, ProcessUserModeIOPL, ProcessEnableAlignmentFaultFixup, ProcessPriorityClass, ProcessWx86Information, ProcessHandleCount, ProcessAffinityMask, ProcessPriorityBoost, ProcessDeviceMap, ProcessSessionInformation, ProcessForegroundInformation, ProcessWow64Information, ProcessImageFileName, ProcessLUIDDeviceMapsEnabled, ProcessBreakOnTermination, ProcessDebugObjectHandle, ProcessDebugFlags, ProcessHandleTracing, ProcessIoPriority, ProcessExecuteFlags, ProcessResourceManagement, ProcessCookie, ProcessImageInformation, MaxProcessInfoClass } PROCESSINFOCLASS; typedef struct _PEB_LDR_DATA { BYTE Reserved1[8]; PVOID Reserved2[3]; LIST_ENTRY InMemoryOrderModuleList; } PEB_LDR_DATA, *PPEB_LDR_DATA; typedef struct _RTL_USER_PROCESS_PARAMETERS { BYTE Reserved1[16]; PVOID Reserved2[10]; UNICODE_STRING ImagePathName; UNICODE_STRING CommandLine; } RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS; typedef struct _PEB { BYTE Reserved1[2]; BYTE BeingDebugged; BYTE Reserved2[1]; PVOID Reserved3[2]; PPEB_LDR_DATA Ldr; PRTL_USER_PROCESS_PARAMETERS ProcessParameters; BYTE Reserved4[104]; PVOID Reserved5[52]; PVOID PostProcessInitRoutine; BYTE Reserved6[128]; PVOID Reserved7[1]; ULONG SessionId; } PEB, *PPEB; typedef struct _PROCESS_BASIC_INFORMATION { PVOID Reserved1; PPEB PebBaseAddress; PVOID Reserved2[2]; ULONG_PTR UniqueProcessId; PVOID Reserved3; } PROCESS_BASIC_INFORMATION; typedef struct _MEMORY_WORKING_SET_LIST { ULONG NumberOfPages; ULONG WorkingSetList[1]; } MEMORY_WORKING_SET_LIST, *PMEMORY_WORKING_SET_LIST; typedef struct _MEMORY_SECTION_NAME { UNICODE_STRING SectionFileName; } MEMORY_SECTION_NAME, *PMEMORY_SECTION_NAME; typedef NTSTATUS (WINAPI *def_NtTerminateProcess)(HANDLE ProcessHandle, NTSTATUS ExitStatus); typedef NTSTATUS (WINAPI *def_NtQueryObject)(HANDLE Handle,OBJECT_INFORMATION_CLASS ObjectInformationClass,PVOID ObjectInformation,ULONG ObjectInformationLength,PULONG ReturnLength); typedef NTSTATUS (WINAPI *def_NtDuplicateObject)(HANDLE SourceProcessHandle, HANDLE SourceHandle, HANDLE TargetProcessHandle, PHANDLE TargetHandle, ACCESS_MASK DesiredAccess, BOOLEAN InheritHandle, ULONG Options ); typedef NTSTATUS (WINAPI *def_NtQueryInformationFile)(HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock, PVOID FileInformation, ULONG Length, FILE_INFORMATION_CLASS FileInformationClass); typedef NTSTATUS (WINAPI *def_NtQueryInformationThread)(HANDLE ThreadHandle,THREADINFOCLASS ThreadInformationClass,PVOID ThreadInformation,ULONG ThreadInformationLength,PULONG ReturnLength); typedef NTSTATUS (WINAPI *def_NtQueryInformationProcess)(HANDLE ProcessHandle,PROCESSINFOCLASS ProcessInformationClass,PVOID ProcessInformation,ULONG ProcessInformationLength,PULONG ReturnLength); typedef NTSTATUS (WINAPI *def_NtQuerySystemInformation)(SYSTEM_INFORMATION_CLASS SystemInformationClass,PVOID SystemInformation,ULONG SystemInformationLength, PULONG ReturnLength); typedef NTSTATUS (WINAPI *def_NtQueryVirtualMemory)(HANDLE ProcessHandle, PVOID BaseAddress, MEMORY_INFORMATION_CLASS MemoryInformationClass, PVOID Buffer, ULONG Length, PULONG ResultLength); typedef NTSTATUS (WINAPI *def_NtOpenProcess)(PHANDLE ProcessHandle, ACCESS_MASK AccessMask, PVOID ObjectAttributes, PCLIENT_ID ClientId ); typedef NTSTATUS (WINAPI *def_NtOpenThread)(PHANDLE ThreadHandle,ACCESS_MASK DesiredAccess,POBJECT_ATTRIBUTES ObjectAttributes,PCLIENT_ID ClientId); typedef NTSTATUS (WINAPI *def_NtResumeThread)(HANDLE ThreadHandle, PULONG SuspendCount); typedef NTSTATUS (WINAPI *def_NtSetInformationThread)(HANDLE ThreadHandle,THREADINFOCLASS ThreadInformationClass,PVOID ThreadInformation,ULONG ThreadInformationLength); -typedef NTSTATUS (WINAPI *def_NtCreateThreadEx)(PHANDLE hThread,ACCESS_MASK DesiredAccess,LPVOID ObjectAttributes,HANDLE ProcessHandle,LPTHREAD_START_ROUTINE lpStartAddress,LPVOID lpParameter,BOOL CreateSuspended,ULONG StackZeroBits,LPVOID SizeOfStackCommit,LPVOID SizeOfStackReserve,LPVOID lpBytesBuffer); +typedef NTSTATUS (WINAPI *def_NtCreateThreadEx)(PHANDLE hThread,ACCESS_MASK DesiredAccess,LPVOID ObjectAttributes,HANDLE ProcessHandle,LPTHREAD_START_ROUTINE lpStartAddress,LPVOID lpParameter,int CreateFlags,ULONG StackZeroBits,LPVOID SizeOfStackCommit,LPVOID SizeOfStackReserve,LPVOID lpBytesBuffer); typedef NTSTATUS (WINAPI *def_NtSuspendProcess)(HANDLE ProcessHandle); typedef NTSTATUS (WINAPI *def_NtResumeProcess)(HANDLE ProcessHandle); typedef ULONG (WINAPI *def_RtlNtStatusToDosError)(NTSTATUS Status); - +//Flags from waliedassar +#define NtCreateThreadExFlagCreateSuspended 0x1 +#define NtCreateThreadExFlagSuppressDllMains 0x2 +#define NtCreateThreadExFlagHideFromDebugger 0x4 class NativeWinApi { public: static def_NtCreateThreadEx NtCreateThreadEx; static def_NtDuplicateObject NtDuplicateObject; static def_NtOpenProcess NtOpenProcess; static def_NtOpenThread NtOpenThread; static def_NtQueryObject NtQueryObject; static def_NtQueryInformationFile NtQueryInformationFile; static def_NtQueryInformationProcess NtQueryInformationProcess; static def_NtQueryInformationThread NtQueryInformationThread; static def_NtQuerySystemInformation NtQuerySystemInformation; static def_NtQueryVirtualMemory NtQueryVirtualMemory; static def_NtResumeProcess NtResumeProcess; static def_NtResumeThread NtResumeThread; static def_NtSetInformationThread NtSetInformationThread; static def_NtSuspendProcess NtSuspendProcess; static def_NtTerminateProcess NtTerminateProcess; static def_RtlNtStatusToDosError RtlNtStatusToDosError; static void initialize(); static PPEB getCurrentProcessEnvironmentBlock(); static PPEB getProcessEnvironmentBlockAddress(HANDLE processHandle); };