From 676b3837ce4b73de93248e1ad1ace47446b1186d Mon Sep 17 00:00:00 2001 From: lhodges1 Date: Thu, 17 Aug 2023 18:45:50 +1000 Subject: [PATCH] e --- ac.sln | 26 +++++ driver/common.h | 11 ++ driver/driver.c | 56 ++++++++++ driver/driver.h | 11 ++ driver/driver.inf | 77 ++++++++++++++ driver/driver.vcxproj | 129 +++++++++++++++++++++++ driver/driver.vcxproj.filters | 45 ++++++++ driver/ioctl.c | 32 ++++++ driver/ioctl.h | 23 ++++ user/km/driver.cpp | 6 ++ user/km/driver.h | 22 ++++ user/km/kmanager.cpp | 7 ++ user/km/kmanager.h | 20 ++++ user/km/kprotection.cpp | 0 user/km/kprotection.h | 1 - user/main.cpp | 64 +++++++++--- user/{um => }/threadpool.cpp | 10 +- user/{um => }/threadpool.h | 2 +- user/um/imports.cpp | 4 + user/um/imports.h | 3 + user/um/manager.cpp | 23 ---- user/um/module.cpp | 1 - user/um/module.h | 8 -- user/um/process.cpp | 168 ++++++++++++++++++++++++++---- user/um/process.h | 15 +-- user/um/umanager.cpp | 42 ++++++++ user/um/{manager.h => umanager.h} | 14 +-- user/user.vcxproj | 22 ++-- user/user.vcxproj.filters | 16 +-- 29 files changed, 751 insertions(+), 107 deletions(-) create mode 100644 driver/common.h create mode 100644 driver/driver.c create mode 100644 driver/driver.h create mode 100644 driver/driver.inf create mode 100644 driver/driver.vcxproj create mode 100644 driver/driver.vcxproj.filters create mode 100644 driver/ioctl.c create mode 100644 driver/ioctl.h create mode 100644 user/km/driver.cpp create mode 100644 user/km/driver.h create mode 100644 user/km/kmanager.cpp create mode 100644 user/km/kmanager.h delete mode 100644 user/km/kprotection.cpp delete mode 100644 user/km/kprotection.h rename user/{um => }/threadpool.cpp (91%) rename user/{um => }/threadpool.h (97%) delete mode 100644 user/um/manager.cpp delete mode 100644 user/um/module.cpp delete mode 100644 user/um/module.h create mode 100644 user/um/umanager.cpp rename user/um/{manager.h => umanager.h} (66%) diff --git a/ac.sln b/ac.sln index a7afab8..68a2c31 100644 --- a/ac.sln +++ b/ac.sln @@ -5,22 +5,48 @@ VisualStudioVersion = 17.5.33502.453 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "user", "user\user.vcxproj", "{3C8194C7-9F20-4FF8-8C4C-B26C3D053611}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "driver", "driver\driver.vcxproj", "{0AE83EC6-DDEA-4EDE-B1B2-1B2AB1E8BB54}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|ARM64 = Debug|ARM64 Debug|x64 = Debug|x64 Debug|x86 = Debug|x86 + Release|ARM64 = Release|ARM64 Release|x64 = Release|x64 Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution + {3C8194C7-9F20-4FF8-8C4C-B26C3D053611}.Debug|ARM64.ActiveCfg = Debug|x64 + {3C8194C7-9F20-4FF8-8C4C-B26C3D053611}.Debug|ARM64.Build.0 = Debug|x64 {3C8194C7-9F20-4FF8-8C4C-B26C3D053611}.Debug|x64.ActiveCfg = Debug|x64 {3C8194C7-9F20-4FF8-8C4C-B26C3D053611}.Debug|x64.Build.0 = Debug|x64 {3C8194C7-9F20-4FF8-8C4C-B26C3D053611}.Debug|x86.ActiveCfg = Debug|Win32 {3C8194C7-9F20-4FF8-8C4C-B26C3D053611}.Debug|x86.Build.0 = Debug|Win32 + {3C8194C7-9F20-4FF8-8C4C-B26C3D053611}.Release|ARM64.ActiveCfg = Release|x64 + {3C8194C7-9F20-4FF8-8C4C-B26C3D053611}.Release|ARM64.Build.0 = Release|x64 {3C8194C7-9F20-4FF8-8C4C-B26C3D053611}.Release|x64.ActiveCfg = Release|x64 {3C8194C7-9F20-4FF8-8C4C-B26C3D053611}.Release|x64.Build.0 = Release|x64 {3C8194C7-9F20-4FF8-8C4C-B26C3D053611}.Release|x86.ActiveCfg = Release|Win32 {3C8194C7-9F20-4FF8-8C4C-B26C3D053611}.Release|x86.Build.0 = Release|Win32 + {0AE83EC6-DDEA-4EDE-B1B2-1B2AB1E8BB54}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {0AE83EC6-DDEA-4EDE-B1B2-1B2AB1E8BB54}.Debug|ARM64.Build.0 = Debug|ARM64 + {0AE83EC6-DDEA-4EDE-B1B2-1B2AB1E8BB54}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {0AE83EC6-DDEA-4EDE-B1B2-1B2AB1E8BB54}.Debug|x64.ActiveCfg = Debug|x64 + {0AE83EC6-DDEA-4EDE-B1B2-1B2AB1E8BB54}.Debug|x64.Build.0 = Debug|x64 + {0AE83EC6-DDEA-4EDE-B1B2-1B2AB1E8BB54}.Debug|x64.Deploy.0 = Debug|x64 + {0AE83EC6-DDEA-4EDE-B1B2-1B2AB1E8BB54}.Debug|x86.ActiveCfg = Debug|x64 + {0AE83EC6-DDEA-4EDE-B1B2-1B2AB1E8BB54}.Debug|x86.Build.0 = Debug|x64 + {0AE83EC6-DDEA-4EDE-B1B2-1B2AB1E8BB54}.Debug|x86.Deploy.0 = Debug|x64 + {0AE83EC6-DDEA-4EDE-B1B2-1B2AB1E8BB54}.Release|ARM64.ActiveCfg = Release|ARM64 + {0AE83EC6-DDEA-4EDE-B1B2-1B2AB1E8BB54}.Release|ARM64.Build.0 = Release|ARM64 + {0AE83EC6-DDEA-4EDE-B1B2-1B2AB1E8BB54}.Release|ARM64.Deploy.0 = Release|ARM64 + {0AE83EC6-DDEA-4EDE-B1B2-1B2AB1E8BB54}.Release|x64.ActiveCfg = Release|x64 + {0AE83EC6-DDEA-4EDE-B1B2-1B2AB1E8BB54}.Release|x64.Build.0 = Release|x64 + {0AE83EC6-DDEA-4EDE-B1B2-1B2AB1E8BB54}.Release|x64.Deploy.0 = Release|x64 + {0AE83EC6-DDEA-4EDE-B1B2-1B2AB1E8BB54}.Release|x86.ActiveCfg = Release|x64 + {0AE83EC6-DDEA-4EDE-B1B2-1B2AB1E8BB54}.Release|x86.Build.0 = Release|x64 + {0AE83EC6-DDEA-4EDE-B1B2-1B2AB1E8BB54}.Release|x86.Deploy.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/driver/common.h b/driver/common.h new file mode 100644 index 0000000..d81d04c --- /dev/null +++ b/driver/common.h @@ -0,0 +1,11 @@ +#ifndef COMMON_H +#define COMMON_H + +#include +#include +#include + +#define DEBUG_LOG(fmt, ...) DbgPrintEx(DPFLTR_IHVDRIVER_ID, 0, "[+] " fmt "\n", ##__VA_ARGS__) +#define DEBUG_ERROR(fmt, ...) DbgPrintEx(DPFLTR_IHVDRIVER_ID, 0, "[-] " fmt "\n", ##__VA_ARGS__) + +#endif diff --git a/driver/driver.c b/driver/driver.c new file mode 100644 index 0000000..c9d4cf2 --- /dev/null +++ b/driver/driver.c @@ -0,0 +1,56 @@ +#include "driver.h" + +#include "common.h" +#include "ioctl.h" + +VOID DriverUnload( + _In_ PDRIVER_OBJECT DriverObject +) +{ + IoDeleteSymbolicLink( &DEVICE_SYMBOLIC_LINK ); + IoDeleteDevice( &DriverObject->DeviceObject ); +} + +NTSTATUS DriverEntry( + _In_ PDRIVER_OBJECT DriverObject, + _In_ PUNICODE_STRING RegistryPath +) +{ + UNREFERENCED_PARAMETER( RegistryPath ); + + NTSTATUS status; + + status = IoCreateDevice( + DriverObject, + NULL, + &DEVICE_NAME, + FILE_DEVICE_UNKNOWN, + FILE_DEVICE_SECURE_OPEN, + FALSE, + &DriverObject->DeviceObject + ); + + if ( !NT_SUCCESS( status ) ) + return STATUS_FAILED_DRIVER_ENTRY; + + status = IoCreateSymbolicLink( + &DEVICE_SYMBOLIC_LINK, + &DEVICE_NAME + ); + + if ( !NT_SUCCESS( status ) ) + { + IoDeleteDevice( &DriverObject->DeviceObject ); + return STATUS_FAILED_DRIVER_ENTRY; + } + + DriverObject->MajorFunction[ IRP_MJ_CREATE ] = DeviceCreate; + DriverObject->MajorFunction[ IRP_MJ_CLOSE ] = DeviceClose; + DriverObject->MajorFunction[ IRP_MJ_DEVICE_CONTROL ] = DeviceControl; + DriverObject->DriverUnload = DriverUnload; + + DEBUG_LOG( "DonnaAC Driver Entry Complete" ); + + return status; +} + diff --git a/driver/driver.h b/driver/driver.h new file mode 100644 index 0000000..754a5d9 --- /dev/null +++ b/driver/driver.h @@ -0,0 +1,11 @@ +#ifndef DRIVER_H +#define DRIVER_H + +#include +#include +#include + +UNICODE_STRING DEVICE_NAME = RTL_CONSTANT_STRING( L"\\Device\\DonnaAC" ); +UNICODE_STRING DEVICE_SYMBOLIC_LINK = RTL_CONSTANT_STRING( L"\\??\\DonnaAC" ); + +#endif \ No newline at end of file diff --git a/driver/driver.inf b/driver/driver.inf new file mode 100644 index 0000000..1915bc0 --- /dev/null +++ b/driver/driver.inf @@ -0,0 +1,77 @@ +; +; driver.inf +; + +[Version] +Signature="$WINDOWS NT$" +Class=System ; TODO: specify appropriate Class +ClassGuid={4d36e97d-e325-11ce-bfc1-08002be10318} ; TODO: specify appropriate ClassGuid +Provider=%ManufacturerName% +CatalogFile=driver.cat +DriverVer= ; TODO: set DriverVer in stampinf property pages +PnpLockdown=1 + +[DestinationDirs] +DefaultDestDir = 12 +driver_Device_CoInstaller_CopyFiles = 11 + +[SourceDisksNames] +1 = %DiskName%,,,"" + +[SourceDisksFiles] +driver.sys = 1,, +WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll=1 ; make sure the number matches with SourceDisksNames + +;***************************************** +; Install Section +;***************************************** + +[Manufacturer] +%ManufacturerName%=Standard,NT$ARCH$ + +[Standard.NT$ARCH$] +%driver.DeviceDesc%=driver_Device, Root\driver ; TODO: edit hw-id + +[driver_Device.NT] +CopyFiles=Drivers_Dir + +[Drivers_Dir] +driver.sys + +;-------------- Service installation +[driver_Device.NT.Services] +AddService = driver,%SPSVCINST_ASSOCSERVICE%, driver_Service_Inst + +; -------------- driver driver install sections +[driver_Service_Inst] +DisplayName = %driver.SVCDESC% +ServiceType = 1 ; SERVICE_KERNEL_DRIVER +StartType = 3 ; SERVICE_DEMAND_START +ErrorControl = 1 ; SERVICE_ERROR_NORMAL +ServiceBinary = %12%\driver.sys + +; +;--- driver_Device Coinstaller installation ------ +; + +[driver_Device.NT.CoInstallers] +AddReg=driver_Device_CoInstaller_AddReg +CopyFiles=driver_Device_CoInstaller_CopyFiles + +[driver_Device_CoInstaller_AddReg] +HKR,,CoInstallers32,0x00010000, "WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll,WdfCoInstaller" + +[driver_Device_CoInstaller_CopyFiles] +WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll + +[driver_Device.NT.Wdf] +KmdfService = driver, driver_wdfsect +[driver_wdfsect] +KmdfLibraryVersion = $KMDFVERSION$ + +[Strings] +SPSVCINST_ASSOCSERVICE= 0x00000002 +ManufacturerName="" ;TODO: Replace with your manufacturer name +DiskName = "driver Installation Disk" +driver.DeviceDesc = "driver Device" +driver.SVCDESC = "driver Service" diff --git a/driver/driver.vcxproj b/driver/driver.vcxproj new file mode 100644 index 0000000..18e7e52 --- /dev/null +++ b/driver/driver.vcxproj @@ -0,0 +1,129 @@ + + + + + Debug + x64 + + + Release + x64 + + + Debug + ARM64 + + + Release + ARM64 + + + + {0AE83EC6-DDEA-4EDE-B1B2-1B2AB1E8BB54} + {1bc93793-694f-48fe-9372-81e2b05556fd} + v4.5 + 12.0 + Debug + x64 + driver + + + + Windows10 + true + WindowsKernelModeDriver10.0 + Driver + KMDF + Universal + false + + + Windows10 + false + WindowsKernelModeDriver10.0 + Driver + KMDF + Universal + false + + + Windows10 + true + WindowsKernelModeDriver10.0 + Driver + KMDF + Universal + + + Windows10 + false + WindowsKernelModeDriver10.0 + Driver + KMDF + Universal + + + + + + + + + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + + sha256 + + + false + + + + + sha256 + + + false + + + + + sha256 + + + + + sha256 + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/driver/driver.vcxproj.filters b/driver/driver.vcxproj.filters new file mode 100644 index 0000000..31417a7 --- /dev/null +++ b/driver/driver.vcxproj.filters @@ -0,0 +1,45 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + {8E41214B-6785-4CFE-B992-037D68949A14} + inf;inv;inx;mof;mc; + + + + + Driver Files + + + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/driver/ioctl.c b/driver/ioctl.c new file mode 100644 index 0000000..6f2c207 --- /dev/null +++ b/driver/ioctl.c @@ -0,0 +1,32 @@ +#include "ioctl.h" + +#include "common.h" + +NTSTATUS DeviceControl( + _In_ PDRIVER_OBJECT DriverObject, + _In_ PIRP Irp +) +{ + DEBUG_LOG( "Handle opened to DonnaAC" ); + IoCompleteRequest( Irp, IO_NO_INCREMENT ); + return Irp->IoStatus.Status; +} + +NTSTATUS DeviceClose( + _In_ PDEVICE_OBJECT DeviceObject, + _In_ PIRP Irp +) +{ + DEBUG_LOG( "Handle closed to DonnaAC" ); + IoCompleteRequest( Irp, IO_NO_INCREMENT ); + return Irp->IoStatus.Status; +} + +NTSTATUS DeviceCreate( + _In_ PDEVICE_OBJECT DeviceObject, + _In_ PIRP Irp +) +{ + IoCompleteRequest( Irp, IO_NO_INCREMENT ); + return Irp->IoStatus.Status; +} \ No newline at end of file diff --git a/driver/ioctl.h b/driver/ioctl.h new file mode 100644 index 0000000..434bed9 --- /dev/null +++ b/driver/ioctl.h @@ -0,0 +1,23 @@ +#ifndef IOCTL_H +#define IOCTL_H + +#include +#include +#include + +NTSTATUS DeviceControl( + _In_ PDRIVER_OBJECT DriverObject, + _In_ PIRP Irp +); + +NTSTATUS DeviceClose( + _In_ PDEVICE_OBJECT DeviceObject, + _In_ PIRP Irp +); + +NTSTATUS DeviceCreate( + _In_ PDEVICE_OBJECT DeviceObject, + _In_ PIRP Irp +); + +#endif \ No newline at end of file diff --git a/user/km/driver.cpp b/user/km/driver.cpp new file mode 100644 index 0000000..f551e03 --- /dev/null +++ b/user/km/driver.cpp @@ -0,0 +1,6 @@ +#include "driver.h" + +kernelmode::Driver::Driver(LPCWSTR DriverName) +{ + this->driver_name = DriverName; +} diff --git a/user/km/driver.h b/user/km/driver.h new file mode 100644 index 0000000..08d3b44 --- /dev/null +++ b/user/km/driver.h @@ -0,0 +1,22 @@ +#ifndef DRIVER_H +#define DRIVER_H + +#include + +#include "../threadpool.h" + +namespace kernelmode +{ + class Driver + { + HANDLE driver_handle; + LPCWSTR driver_name; + public: + + std::shared_ptr thread_pool; + + Driver(LPCWSTR DriverName); + }; +} + +#endif diff --git a/user/km/kmanager.cpp b/user/km/kmanager.cpp new file mode 100644 index 0000000..a96a042 --- /dev/null +++ b/user/km/kmanager.cpp @@ -0,0 +1,7 @@ +#include "kmanager.h" + +kernelmode::KManager::KManager( LPCWSTR DriverName, std::shared_ptr ThreadPool ) +{ + this->driver_interface = std::make_unique(DriverName); + this->thread_pool = ThreadPool; +} diff --git a/user/km/kmanager.h b/user/km/kmanager.h new file mode 100644 index 0000000..a875470 --- /dev/null +++ b/user/km/kmanager.h @@ -0,0 +1,20 @@ +#ifndef KMANAGER_H +#define KMANAGER_H + +#include + +#include "..\threadpool.h" +#include "driver.h" + +namespace kernelmode +{ + class KManager + { + std::unique_ptr driver_interface; + std::shared_ptr thread_pool; + public: + KManager( LPCWSTR DriverName, std::shared_ptr ThreadPool ); + }; +} + +#endif \ No newline at end of file diff --git a/user/km/kprotection.cpp b/user/km/kprotection.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/user/km/kprotection.h b/user/km/kprotection.h deleted file mode 100644 index 6f70f09..0000000 --- a/user/km/kprotection.h +++ /dev/null @@ -1 +0,0 @@ -#pragma once diff --git a/user/main.cpp b/user/main.cpp index 1e900fa..817be76 100644 --- a/user/main.cpp +++ b/user/main.cpp @@ -4,28 +4,64 @@ #include "common.h" -#include "../user/um/threadpool.h" -#include "../user/um/manager.h" +#include "threadpool.h" -void TestFunction() +#include "../user/um/umanager.h" +#include "../user/km/kmanager.h" + +DWORD WINAPI Init(HINSTANCE hinstDLL) { + AllocConsole(); + FILE* file; + freopen_s( &file, "CONOUT$", "w", stdout ); + freopen_s( &file, "CONIN$", "r", stdin ); + std::this_thread::sleep_for( std::chrono::seconds( 1 ) ); + + std::shared_ptr thread_pool = std::make_shared( 4 ); + + usermode::UManager umanager( thread_pool ); + //kernelmode::KManager kmanager( L"DonnaAC", thread_pool); + umanager.ValidateProcessModules(); + + while ( !GetAsyncKeyState( VK_DELETE ) ) + { + std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); + } + + fclose( stdout ); + fclose( stdin ); + FreeConsole(); + + FreeLibraryAndExitThread( hinstDLL, 0); + return 0; } -int main(int argc, char* argv[]) +BOOL WINAPI DllMain( + HINSTANCE hinstDLL, // handle to DLL module + DWORD fdwReason, // reason for calling function + LPVOID lpvReserved ) // reserved { - //if ( argc == 1 ) - //{ - // LOG_INFO( "No target process passed, terminating" ); - // return ERROR; - //} + // Perform actions based on the reason for calling. + switch ( fdwReason ) + { + case DLL_PROCESS_ATTACH: - usermode::Manager manager( "notepad.exe" ); - manager.ValidateProcessThreads(); + DisableThreadLibraryCalls( hinstDLL ); + const auto thread = CreateThread( + nullptr, + 0, + reinterpret_cast< LPTHREAD_START_ROUTINE >( Init ), + hinstDLL, + 0, + nullptr + ); - while ( 1 ) - { + if ( thread ) + CloseHandle( thread ); - } + break; + } + return TRUE; // Successful DLL_PROCESS_ATTACH. } \ No newline at end of file diff --git a/user/um/threadpool.cpp b/user/threadpool.cpp similarity index 91% rename from user/um/threadpool.cpp rename to user/threadpool.cpp index bcb4a7a..dbd587b 100644 --- a/user/um/threadpool.cpp +++ b/user/threadpool.cpp @@ -4,7 +4,7 @@ * This is the idle loop each thread will be running until a job is ready * for execution */ -void usermode::ThreadPool::ThreadLoop() +void global::ThreadPool::ThreadLoop() { while ( true ) { @@ -42,7 +42,7 @@ void usermode::ThreadPool::ThreadLoop() } } -usermode::ThreadPool::ThreadPool(int ThreadCount) +global::ThreadPool::ThreadPool(int ThreadCount) { this->thread_count = ThreadCount; this->should_terminate = false; @@ -54,7 +54,7 @@ usermode::ThreadPool::ThreadPool(int ThreadCount) } } -void usermode::ThreadPool::QueueJob( const std::function& job ) +void global::ThreadPool::QueueJob( const std::function& job ) { /* push a job into our job queue safely by holding our queue lock */ std::unique_lock lock( this->queue_mutex ); @@ -63,7 +63,7 @@ void usermode::ThreadPool::QueueJob( const std::function& job ) mutex_condition.notify_one(); } -void usermode::ThreadPool::Stop() +void global::ThreadPool::Stop() { /* safely set our termination flag to true */ std::unique_lock lock( this->queue_mutex ); @@ -76,7 +76,7 @@ void usermode::ThreadPool::Stop() threads.clear(); } -bool usermode::ThreadPool::Busy() +bool global::ThreadPool::Busy() { /* allows us to wait for when the job queue is empty allowing us to safely call the destructor */ std::unique_lock lock( this->queue_mutex ); diff --git a/user/um/threadpool.h b/user/threadpool.h similarity index 97% rename from user/um/threadpool.h rename to user/threadpool.h index 90b2d8b..af7f8c4 100644 --- a/user/um/threadpool.h +++ b/user/threadpool.h @@ -6,7 +6,7 @@ #include #include -namespace usermode +namespace global { /* * This ThreadPool class is a simple threadpool implementation that will allow us diff --git a/user/um/imports.cpp b/user/um/imports.cpp index c804b6a..e0bf0e5 100644 --- a/user/um/imports.cpp +++ b/user/um/imports.cpp @@ -9,15 +9,19 @@ usermode::Imports::Imports() this->ImportMap[ "NtQueryInformationThread" ] = NtQueryInformationThread; std::map::iterator it; + for ( it = this->ImportMap.begin(); it != this->ImportMap.end(); it++ ) { HMODULE module_handle = GetModuleHandle( L"ntdll.dll" ); + if ( !module_handle ) { LOG_ERROR( "GetModuleHandle failed with status code 0x%x", GetLastError() ); return; } + it->second = GetProcAddress( module_handle, it->first.c_str()); + if ( !it->second ) { LOG_ERROR( "GetProcAddress failed with status code 0x%x", GetLastError() ); diff --git a/user/um/imports.h b/user/um/imports.h index 2541a5e..fc04c67 100644 --- a/user/um/imports.h +++ b/user/um/imports.h @@ -14,7 +14,10 @@ namespace usermode { public: std::map ImportMap; + void* NtQueryInformationThread; + void* NtQueryVirtualMemory; + Imports(); }; } diff --git a/user/um/manager.cpp b/user/um/manager.cpp deleted file mode 100644 index 8c10470..0000000 --- a/user/um/manager.cpp +++ /dev/null @@ -1,23 +0,0 @@ -#include "manager.h" - -#include "../common.h" -#include "process.h" -#include "../um/imports.h" - -#include - -usermode::Manager::Manager( std::string ProcessName ) -{ - this->process_name = ProcessName; - this->process = std::make_unique( 4, ProcessName ); -} - -usermode::Manager::~Manager() -{ - -} - -void usermode::Manager::ValidateProcessThreads() -{ - this->process->thread_pool->QueueJob( [ this ]() {this->process->ValidateProcessThreads(); } ); -} diff --git a/user/um/module.cpp b/user/um/module.cpp deleted file mode 100644 index 8ec530e..0000000 --- a/user/um/module.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "module.h" \ No newline at end of file diff --git a/user/um/module.h b/user/um/module.h deleted file mode 100644 index 0ce55ce..0000000 --- a/user/um/module.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef MODULE_H -#define MODULE_H - -#include - - - -#endif \ No newline at end of file diff --git a/user/um/process.cpp b/user/um/process.cpp index dd75792..5d47bf5 100644 --- a/user/um/process.cpp +++ b/user/um/process.cpp @@ -2,30 +2,16 @@ #include "../common.h" #include "../um/imports.h" +#include "memory.h" +#include #include -usermode::Process::Process( int ThreadCount, std::string ProcessName ) +usermode::Process::Process() { - this->process_name = ProcessName; - this->thread_pool = std::make_unique( ThreadCount ); - this->process_handle = GetHandleToProcessGivenName( ProcessName ); + this->process_handle = GetCurrentProcess(); + this->process_id = GetCurrentProcessId(); this->function_imports = std::make_unique(); - - if ( this->process_handle == INVALID_HANDLE_VALUE ) - { - this->thread_pool->Stop(); - throw std::invalid_argument("Failed to initiate process class handle with error"); - } -} - -usermode::Process::~Process() -{ - /* Wait for our jobs to be finished, then safely stop our pool */ - while ( true ) - { - if ( this->thread_pool->Busy() == FALSE ) { this->thread_pool->Stop(); } - } } void usermode::Process::ValidateProcessThreads() @@ -112,7 +98,7 @@ std::vector usermode::Process::GetProcessThreadsStartAddresses() * of the module. A simple way to check if a thread is a valid thread, however there are ways around * this check so it is not a perfect solution. */ -bool usermode::Process::CheckIfAddressLiesWithinValidProcessModule( UINT64 Address, bool* result ) +bool usermode::Process::CheckIfAddressLiesWithinValidProcessModule( UINT64 Address, bool* Result ) { HANDLE process_modules_handle; MODULEENTRY32 module_entry; @@ -145,14 +131,14 @@ bool usermode::Process::CheckIfAddressLiesWithinValidProcessModule( UINT64 Addre { LOG_INFO( "found valid module LOL" ); CloseHandle( process_modules_handle ); - *result = true; + *Result = true; return true; } } while ( Module32Next( process_modules_handle, &module_entry ) ); CloseHandle( process_modules_handle ); - *result = false; + *Result = false; return true; } @@ -204,7 +190,6 @@ HANDLE usermode::Process::GetHandleToProcessGivenName( std::string ProcessName ) { LOG_INFO( "Found target process" ); CloseHandle( process_snapshot_handle ); - this->process_id = process_entry.th32ProcessID; return process_handle; } @@ -213,3 +198,140 @@ HANDLE usermode::Process::GetHandleToProcessGivenName( std::string ProcessName ) CloseHandle( process_snapshot_handle ); return INVALID_HANDLE_VALUE; } + +bool usermode::Process::GetProcessBaseAddress( UINT64* Result ) +{ + HANDLE process_modules_handle; + MODULEENTRY32 module_entry; + + process_modules_handle = CreateToolhelp32Snapshot( TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, this->process_id ); + + if ( process_modules_handle == INVALID_HANDLE_VALUE ) + { + LOG_ERROR( "CreateToolHelp32Snapshot with TH32CS_SNAPMODULE failed with status 0x%x", GetLastError() ); + return false; + } + + module_entry.dwSize = sizeof( MODULEENTRY32 ); + + if ( !Module32First( process_modules_handle, &module_entry ) ) + { + LOG_ERROR( "Module32First failed with status 0x%x", GetLastError() ); + CloseHandle( process_modules_handle ); + return false; + } + + *Result = (UINT64)module_entry.modBaseAddr; + CloseHandle( process_modules_handle ); + return true; +} + +void usermode::Process::ScanProcessMemory() +{ + MEMORY_BASIC_INFORMATION memory_info = { 0 }; + UINT64 base_address; + + if ( !GetProcessBaseAddress( &base_address ) ) + { + LOG_ERROR( "Failed to get process base address with status 0x%x", GetLastError() ); + return; + } + + while ( VirtualQueryEx( + this->process_handle, + ( PVOID )base_address, + &memory_info, + sizeof( MEMORY_BASIC_INFORMATION )) + ) + { + this->CheckPageProtection( &memory_info ); + this->PatternScanRegion(base_address, &memory_info); + + base_address += memory_info.RegionSize; + } +} + +void usermode::Process::PatternScanRegion( UINT64 Address, MEMORY_BASIC_INFORMATION* Page ) +{ + +} + +void usermode::Process::CheckPageProtection( MEMORY_BASIC_INFORMATION* Page ) +{ + /* MEM_IMAGE indicates the pages are mapped into view of an image section */ + if ( Page->Type == MEM_IMAGE ) + return; + + if ( Page->AllocationProtect & PAGE_EXECUTE || + Page->AllocationProtect & PAGE_EXECUTE_READ || + Page->AllocationProtect & PAGE_EXECUTE_READWRITE || + Page->AllocationProtect & PAGE_EXECUTE_WRITECOPY + ) + { + // report area or smth + } +} + +void usermode::Process::VerifyLoadedModuleChecksums() +{ + HANDLE process_modules_handle; + MODULEENTRY32 module_entry; + PVOID mapped_image; + DWORD in_memory_header_sum; + DWORD in_memory_check_sum; + DWORD disk_header_sum; + DWORD disk_check_sum; + DWORD result; + + process_modules_handle = CreateToolhelp32Snapshot( TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, this->process_id ); + + if ( process_modules_handle == INVALID_HANDLE_VALUE ) + { + LOG_ERROR( "CreateToolHelp32Snapshot with TH32CS_SNAPMODULE failed with status 0x%x", GetLastError() ); + return; + } + + module_entry.dwSize = sizeof( MODULEENTRY32 ); + + if ( !Module32First( process_modules_handle, &module_entry ) ) + { + LOG_ERROR( "Module32First failed with status 0x%x", GetLastError() ); + return; + } + + do + { + /* compute checksum for the in memory module */ + mapped_image = CheckSumMappedFile( + module_entry.modBaseAddr, + module_entry.modBaseSize, + &in_memory_header_sum, + &in_memory_check_sum + ); + + if ( !mapped_image ) + { + LOG_ERROR( "CheckSumMappedFile failed with status 0x%x", GetLastError() ); + goto end; + } + + /* computer the checksum for the module on disk */ + result = MapFileAndCheckSum( + (PCWSTR)module_entry.szExePath, + &disk_header_sum, + &disk_check_sum + ); + + if ( result != CHECKSUM_SUCCESS ) + { + LOG_ERROR( "MapFileAndCheckSum failed with status 0x%x", GetLastError() ); + goto end; + } + + LOG_INFO( "in memory checksum: %x, disk checksum: %x", in_memory_check_sum, disk_check_sum ); + + } while ( Module32Next( process_modules_handle, &module_entry ) ); + +end: + CloseHandle( process_modules_handle ); +} \ No newline at end of file diff --git a/user/um/process.h b/user/um/process.h index fb1bd76..f79375a 100644 --- a/user/um/process.h +++ b/user/um/process.h @@ -6,7 +6,7 @@ #include #include -#include "../um/threadpool.h" +#include "../threadpool.h" #include "../um/imports.h" #define ThreadQuerySetWin32StartAddress 9 @@ -23,22 +23,23 @@ namespace usermode { HANDLE process_handle; DWORD process_id; - std::string process_name; std::mutex mutex; std::unique_ptr function_imports; HANDLE GetHandleToProcessGivenName( std::string ProcessName ); std::vector GetProcessThreadsStartAddresses(); - bool CheckIfAddressLiesWithinValidProcessModule( UINT64 Address, bool* result ); + bool CheckIfAddressLiesWithinValidProcessModule( UINT64 Address, bool* Result ); + bool GetProcessBaseAddress( UINT64* Result ); + void CheckPageProtection( MEMORY_BASIC_INFORMATION* Page ); + void PatternScanRegion( UINT64 Address, MEMORY_BASIC_INFORMATION* Page ); public: - std::unique_ptr thread_pool; - - Process( int ThreadCount, std::string ProcessName ); - ~Process(); + Process(); void ValidateProcessThreads(); + void ScanProcessMemory(); + void VerifyLoadedModuleChecksums(); }; } diff --git a/user/um/umanager.cpp b/user/um/umanager.cpp new file mode 100644 index 0000000..22446ed --- /dev/null +++ b/user/um/umanager.cpp @@ -0,0 +1,42 @@ +#include "umanager.h" + +#include "../common.h" +#include "process.h" +#include "../um/imports.h" + +#include + +usermode::UManager::UManager( std::shared_ptr ThreadPool ) +{ + this->thread_pool = ThreadPool; + this->process = std::make_unique(); +} + +usermode::UManager::~UManager() +{ + /* Wait for our jobs to be finished, then safely stop our pool */ + while ( true ) + { + if ( this->thread_pool->Busy() == FALSE ) + { + this->thread_pool->Stop(); + break; + } + } +} + +void usermode::UManager::ValidateProcessThreads() +{ + this->thread_pool->QueueJob( [ this ]() {this->process->ValidateProcessThreads(); } ); +} + +void usermode::UManager::ValidateProcessMemory() +{ + this->thread_pool->QueueJob( [ this ]() {this->process->ScanProcessMemory(); } ); +} + +void usermode::UManager::ValidateProcessModules() +{ + this->thread_pool->QueueJob( [ this ]() {this->process->VerifyLoadedModuleChecksums(); } ); +} + diff --git a/user/um/manager.h b/user/um/umanager.h similarity index 66% rename from user/um/manager.h rename to user/um/umanager.h index fa2ebed..3f1ddf0 100644 --- a/user/um/manager.h +++ b/user/um/umanager.h @@ -1,5 +1,5 @@ -#ifndef MANAGER_H -#define MANAGER_H +#ifndef UMANAGER_H +#define UMANAGER_H #include #include @@ -17,16 +17,18 @@ namespace usermode * class and the threadpool class to allow a single thread (or multiple) to easily run * the core business logic of running tasks in a certain order. */ - class Manager + class UManager { - std::string process_name; std::unique_ptr process; + std::shared_ptr thread_pool; public: - Manager( std::string ProcessName ); - ~Manager(); + UManager( std::shared_ptr ThreadPool ); + ~UManager(); void ValidateProcessThreads(); + void ValidateProcessMemory(); + void ValidateProcessModules(); }; } diff --git a/user/user.vcxproj b/user/user.vcxproj index 4e7dd27..b43e81c 100644 --- a/user/user.vcxproj +++ b/user/user.vcxproj @@ -40,13 +40,13 @@ Unicode - Application + DynamicLibrary true v143 Unicode - Application + DynamicLibrary false v143 true @@ -108,6 +108,7 @@ Console true + Imagehlp.lib;%(AdditionalDependencies) @@ -124,25 +125,26 @@ true true true + Imagehlp.lib;%(AdditionalDependencies) - + + - - - + + - + + - - - + + diff --git a/user/user.vcxproj.filters b/user/user.vcxproj.filters index b63bc4e..6009898 100644 --- a/user/user.vcxproj.filters +++ b/user/user.vcxproj.filters @@ -18,22 +18,22 @@ Source Files - + Source Files - + Source Files Source Files - + Source Files Source Files - + Source Files @@ -41,22 +41,22 @@ Header Files - + Header Files - + Header Files Header Files - + Header Files Header Files - + Header Files