Added DomitoMemorySearchPattern
This commit is contained in:
parent
0d9cc19fbd
commit
1113a23f19
@ -10,7 +10,7 @@ __drv_allocatesMem(Mem)
|
||||
PVOID
|
||||
NTAPI
|
||||
EVT_DOMITO_ALLOCATE_ROUTINE(
|
||||
_In_ SIZE_T ByteSize
|
||||
_In_ SIZE_T ByteSize
|
||||
);
|
||||
typedef EVT_DOMITO_ALLOCATE_ROUTINE* PFN_DOMITO_ALLOCATE_ROUTINE;
|
||||
|
||||
@ -24,9 +24,9 @@ _IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
EXTERN_C
|
||||
NTSTATUS
|
||||
DomitoFindDriverBaseAddress(
|
||||
_In_ STRING ModuleName,
|
||||
_In_ PFN_DOMITO_ALLOCATE_ROUTINE Allocator,
|
||||
_Inout_opt_ PVOID * ModuleBase
|
||||
_In_ STRING ModuleName,
|
||||
_In_ PFN_DOMITO_ALLOCATE_ROUTINE Allocator,
|
||||
_Inout_opt_ PVOID * ModuleBase
|
||||
);
|
||||
|
||||
//
|
||||
@ -38,7 +38,23 @@ _IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
EXTERN_C
|
||||
NTSTATUS
|
||||
DomitoFindExportedFunctionAddress(
|
||||
_In_ PVOID ModuleBase,
|
||||
_In_ STRING FunctionName,
|
||||
_Inout_opt_ PVOID * FunctionAddress
|
||||
_In_ PVOID ModuleBase,
|
||||
_In_ STRING FunctionName,
|
||||
_Inout_opt_ PVOID * FunctionAddress
|
||||
);
|
||||
|
||||
//
|
||||
// Scans a provided buffer for a memory pattern
|
||||
//
|
||||
_Success_(return == STATUS_SUCCESS)
|
||||
_Must_inspect_result_
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
NTSTATUS
|
||||
DomitoMemorySearchPattern(
|
||||
_In_ PCUCHAR pcPattern,
|
||||
_In_ UCHAR uWildcard,
|
||||
_In_ SIZE_T puLen,
|
||||
_In_ PVOID pcBase,
|
||||
_In_ SIZE_T puSize,
|
||||
_Outptr_result_maybenull_ PVOID* ppMatch
|
||||
);
|
||||
|
330
src/Domito.cpp
330
src/Domito.cpp
@ -7,63 +7,63 @@
|
||||
// Structure representing a loaded module
|
||||
typedef struct _SYSTEM_MODULE_INFORMATION_ENTRY
|
||||
{
|
||||
PVOID Unknown1;
|
||||
PVOID Unknown2;
|
||||
PVOID Base;
|
||||
ULONG Size;
|
||||
ULONG Flags;
|
||||
USHORT Index;
|
||||
USHORT NameLength;
|
||||
USHORT LoadCount;
|
||||
USHORT PathLength;
|
||||
CHAR ImageName[256];
|
||||
PVOID Unknown1;
|
||||
PVOID Unknown2;
|
||||
PVOID Base;
|
||||
ULONG Size;
|
||||
ULONG Flags;
|
||||
USHORT Index;
|
||||
USHORT NameLength;
|
||||
USHORT LoadCount;
|
||||
USHORT PathLength;
|
||||
CHAR ImageName[256];
|
||||
} SYSTEM_MODULE_INFORMATION_ENTRY, * PSYSTEM_MODULE_INFORMATION_ENTRY;
|
||||
|
||||
// Structure representing the loaded module information
|
||||
typedef struct _SYSTEM_MODULE_INFORMATION
|
||||
{
|
||||
ULONG Count;
|
||||
SYSTEM_MODULE_INFORMATION_ENTRY Module[ANYSIZE_ARRAY];
|
||||
ULONG Count;
|
||||
SYSTEM_MODULE_INFORMATION_ENTRY Module[ANYSIZE_ARRAY];
|
||||
} SYSTEM_MODULE_INFORMATION, * PSYSTEM_MODULE_INFORMATION;
|
||||
|
||||
// Function prototype for ZwQuerySystemInformation
|
||||
NTSYSAPI NTSTATUS NTAPI ZwQuerySystemInformation(
|
||||
ULONG SystemInformationClass,
|
||||
PVOID SystemInformation,
|
||||
ULONG SystemInformationLength,
|
||||
PULONG ReturnLength
|
||||
ULONG SystemInformationClass,
|
||||
PVOID SystemInformation,
|
||||
ULONG SystemInformationLength,
|
||||
PULONG ReturnLength
|
||||
);
|
||||
|
||||
typedef struct _LDR_DATA_TABLE_ENTRY
|
||||
{
|
||||
LIST_ENTRY64 InLoadOrderLinks;
|
||||
PVOID ExceptionTable;
|
||||
ULONG ExceptionTableSize;
|
||||
PVOID GpValue;
|
||||
PVOID NonPagedDebugInfo;
|
||||
PVOID ImageBase;
|
||||
PVOID EntryPoint;
|
||||
ULONG SizeOfImage;
|
||||
UNICODE_STRING FullImageName;
|
||||
UNICODE_STRING BaseImageName;
|
||||
ULONG Flags;
|
||||
USHORT LoadCount;
|
||||
USHORT TlsIndex;
|
||||
LIST_ENTRY64 HashLinks;
|
||||
PVOID SectionPointer;
|
||||
ULONG CheckSum;
|
||||
ULONG TimeDateStamp;
|
||||
PVOID LoadedImports;
|
||||
PVOID EntryPointActivationContext;
|
||||
PVOID PatchInformation;
|
||||
LIST_ENTRY64 InLoadOrderLinks;
|
||||
PVOID ExceptionTable;
|
||||
ULONG ExceptionTableSize;
|
||||
PVOID GpValue;
|
||||
PVOID NonPagedDebugInfo;
|
||||
PVOID ImageBase;
|
||||
PVOID EntryPoint;
|
||||
ULONG SizeOfImage;
|
||||
UNICODE_STRING FullImageName;
|
||||
UNICODE_STRING BaseImageName;
|
||||
ULONG Flags;
|
||||
USHORT LoadCount;
|
||||
USHORT TlsIndex;
|
||||
LIST_ENTRY64 HashLinks;
|
||||
PVOID SectionPointer;
|
||||
ULONG CheckSum;
|
||||
ULONG TimeDateStamp;
|
||||
PVOID LoadedImports;
|
||||
PVOID EntryPointActivationContext;
|
||||
PVOID PatchInformation;
|
||||
} LDR_DATA_TABLE_ENTRY, * PLDR_DATA_TABLE_ENTRY;
|
||||
|
||||
typedef PVOID(NTAPI* t_RtlImageDirectoryEntryToData)(
|
||||
IN PVOID Base,
|
||||
IN BOOLEAN MappedAsImage,
|
||||
IN USHORT DirectoryEntry,
|
||||
OUT PULONG Size
|
||||
);
|
||||
IN PVOID Base,
|
||||
IN BOOLEAN MappedAsImage,
|
||||
IN USHORT DirectoryEntry,
|
||||
OUT PULONG Size
|
||||
);
|
||||
|
||||
|
||||
_Success_(return == STATUS_SUCCESS)
|
||||
@ -71,76 +71,76 @@ _Must_inspect_result_
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
NTSTATUS
|
||||
DomitoFindDriverBaseAddress(
|
||||
_In_ STRING ModuleName,
|
||||
_In_ PFN_DOMITO_ALLOCATE_ROUTINE Allocator,
|
||||
_Inout_opt_ PVOID * ModuleBase
|
||||
_In_ STRING ModuleName,
|
||||
_In_ PFN_DOMITO_ALLOCATE_ROUTINE Allocator,
|
||||
_Inout_opt_ PVOID * ModuleBase
|
||||
)
|
||||
{
|
||||
ULONG bufferSize = 0;
|
||||
PSYSTEM_MODULE_INFORMATION moduleInfo = NULL;
|
||||
ULONG bufferSize = 0;
|
||||
PSYSTEM_MODULE_INFORMATION moduleInfo = NULL;
|
||||
|
||||
const ULONG SystemModuleInformation = 11;
|
||||
const ULONG SystemModuleInformation = 11;
|
||||
|
||||
// Query the required buffer size for module information
|
||||
NTSTATUS status = ZwQuerySystemInformation(
|
||||
SystemModuleInformation,
|
||||
&bufferSize,
|
||||
0,
|
||||
&bufferSize
|
||||
);
|
||||
// Query the required buffer size for module information
|
||||
NTSTATUS status = ZwQuerySystemInformation(
|
||||
SystemModuleInformation,
|
||||
&bufferSize,
|
||||
0,
|
||||
&bufferSize
|
||||
);
|
||||
|
||||
if (status != STATUS_INFO_LENGTH_MISMATCH)
|
||||
{
|
||||
return status;
|
||||
}
|
||||
if (status != STATUS_INFO_LENGTH_MISMATCH)
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
// Allocate memory for the module information
|
||||
moduleInfo = (PSYSTEM_MODULE_INFORMATION)Allocator(
|
||||
bufferSize
|
||||
);
|
||||
// Allocate memory for the module information
|
||||
moduleInfo = (PSYSTEM_MODULE_INFORMATION)Allocator(
|
||||
bufferSize
|
||||
);
|
||||
|
||||
if (moduleInfo == NULL)
|
||||
{
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
if (moduleInfo == NULL)
|
||||
{
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
// Retrieve the module information
|
||||
status = ZwQuerySystemInformation(
|
||||
SystemModuleInformation,
|
||||
moduleInfo,
|
||||
bufferSize,
|
||||
NULL
|
||||
);
|
||||
// Retrieve the module information
|
||||
status = ZwQuerySystemInformation(
|
||||
SystemModuleInformation,
|
||||
moduleInfo,
|
||||
bufferSize,
|
||||
NULL
|
||||
);
|
||||
|
||||
if (!NT_SUCCESS(status))
|
||||
{
|
||||
ExFreePool(moduleInfo);
|
||||
return status;
|
||||
}
|
||||
if (!NT_SUCCESS(status))
|
||||
{
|
||||
ExFreePool(moduleInfo);
|
||||
return status;
|
||||
}
|
||||
|
||||
STRING currentImageName;
|
||||
STRING currentImageName;
|
||||
|
||||
status = STATUS_NOT_FOUND;
|
||||
// Iterate through the loaded modules and find the desired module
|
||||
for (ULONG i = 0; i < moduleInfo->Count; i++)
|
||||
{
|
||||
RtlInitAnsiString(¤tImageName, moduleInfo->Module[i].ImageName);
|
||||
status = STATUS_NOT_FOUND;
|
||||
// Iterate through the loaded modules and find the desired module
|
||||
for (ULONG i = 0; i < moduleInfo->Count; i++)
|
||||
{
|
||||
RtlInitAnsiString(¤tImageName, moduleInfo->Module[i].ImageName);
|
||||
|
||||
if (0 == RtlCompareString(&ModuleName, ¤tImageName, TRUE))
|
||||
{
|
||||
// Found the module, store the base address
|
||||
if (ModuleBase)
|
||||
{
|
||||
status = STATUS_SUCCESS;
|
||||
*ModuleBase = moduleInfo->Module[i].Base;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (0 == RtlCompareString(&ModuleName, ¤tImageName, TRUE))
|
||||
{
|
||||
// Found the module, store the base address
|
||||
if (ModuleBase)
|
||||
{
|
||||
status = STATUS_SUCCESS;
|
||||
*ModuleBase = moduleInfo->Module[i].Base;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ExFreePool(moduleInfo);
|
||||
ExFreePool(moduleInfo);
|
||||
|
||||
return status;
|
||||
return status;
|
||||
}
|
||||
|
||||
_Success_(return == STATUS_SUCCESS)
|
||||
@ -148,64 +148,108 @@ _Must_inspect_result_
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
NTSTATUS
|
||||
DomitoFindExportedFunctionAddress(
|
||||
_In_ PVOID ModuleBase,
|
||||
_In_ STRING FunctionName,
|
||||
_Inout_opt_ PVOID * FunctionAddress
|
||||
_In_ PVOID ModuleBase,
|
||||
_In_ STRING FunctionName,
|
||||
_Inout_opt_ PVOID * FunctionAddress
|
||||
)
|
||||
{
|
||||
NTSTATUS status = STATUS_NOT_FOUND;
|
||||
ULONG exportSize;
|
||||
NTSTATUS status = STATUS_NOT_FOUND;
|
||||
ULONG exportSize;
|
||||
|
||||
DECLARE_CONST_UNICODE_STRING(routineName, L"RtlImageDirectoryEntryToData");
|
||||
DECLARE_CONST_UNICODE_STRING(routineName, L"RtlImageDirectoryEntryToData");
|
||||
|
||||
const t_RtlImageDirectoryEntryToData fp_RtlImageDirectoryEntryToData =
|
||||
(t_RtlImageDirectoryEntryToData)MmGetSystemRoutineAddress((PUNICODE_STRING)&routineName);
|
||||
const t_RtlImageDirectoryEntryToData fp_RtlImageDirectoryEntryToData =
|
||||
(t_RtlImageDirectoryEntryToData)MmGetSystemRoutineAddress((PUNICODE_STRING)&routineName);
|
||||
|
||||
if (fp_RtlImageDirectoryEntryToData == NULL)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
if (fp_RtlImageDirectoryEntryToData == NULL)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
// Retrieve the export directory information
|
||||
const PIMAGE_EXPORT_DIRECTORY exportDirectory = (PIMAGE_EXPORT_DIRECTORY)fp_RtlImageDirectoryEntryToData(
|
||||
ModuleBase,
|
||||
TRUE,
|
||||
IMAGE_DIRECTORY_ENTRY_EXPORT,
|
||||
&exportSize
|
||||
);
|
||||
// Retrieve the export directory information
|
||||
const PIMAGE_EXPORT_DIRECTORY exportDirectory = (PIMAGE_EXPORT_DIRECTORY)fp_RtlImageDirectoryEntryToData(
|
||||
ModuleBase,
|
||||
TRUE,
|
||||
IMAGE_DIRECTORY_ENTRY_EXPORT,
|
||||
&exportSize
|
||||
);
|
||||
|
||||
if (exportDirectory == NULL)
|
||||
{
|
||||
return STATUS_INVALID_IMAGE_FORMAT;
|
||||
}
|
||||
if (exportDirectory == NULL)
|
||||
{
|
||||
return STATUS_INVALID_IMAGE_FORMAT;
|
||||
}
|
||||
|
||||
STRING currentFunctionName;
|
||||
STRING currentFunctionName;
|
||||
|
||||
const PULONG functionAddresses = (PULONG)((ULONG_PTR)ModuleBase + exportDirectory->AddressOfFunctions);
|
||||
const PULONG functionNames = (PULONG)((ULONG_PTR)ModuleBase + exportDirectory->AddressOfNames);
|
||||
const PUSHORT functionOrdinals = (PUSHORT)((ULONG_PTR)ModuleBase + exportDirectory->AddressOfNameOrdinals);
|
||||
const PULONG functionAddresses = (PULONG)((ULONG_PTR)ModuleBase + exportDirectory->AddressOfFunctions);
|
||||
const PULONG functionNames = (PULONG)((ULONG_PTR)ModuleBase + exportDirectory->AddressOfNames);
|
||||
const PUSHORT functionOrdinals = (PUSHORT)((ULONG_PTR)ModuleBase + exportDirectory->AddressOfNameOrdinals);
|
||||
|
||||
for (ULONG i = 0; i < exportDirectory->NumberOfNames; i++)
|
||||
{
|
||||
const char* functionName = (const char*)((ULONG_PTR)ModuleBase + functionNames[i]);
|
||||
const USHORT functionOrdinal = functionOrdinals[i];
|
||||
UNREFERENCED_PARAMETER(functionOrdinal);
|
||||
for (ULONG i = 0; i < exportDirectory->NumberOfNames; i++)
|
||||
{
|
||||
const char* functionName = (const char*)((ULONG_PTR)ModuleBase + functionNames[i]);
|
||||
const USHORT functionOrdinal = functionOrdinals[i];
|
||||
UNREFERENCED_PARAMETER(functionOrdinal);
|
||||
|
||||
const ULONG functionRva = functionAddresses[i];
|
||||
const PVOID functionAddress = (PVOID)((ULONG_PTR)ModuleBase + functionRva);
|
||||
const ULONG functionRva = functionAddresses[i];
|
||||
const PVOID functionAddress = (PVOID)((ULONG_PTR)ModuleBase + functionRva);
|
||||
|
||||
RtlInitAnsiString(¤tFunctionName, functionName);
|
||||
RtlInitAnsiString(¤tFunctionName, functionName);
|
||||
|
||||
if (0 == RtlCompareString(&FunctionName, ¤tFunctionName, TRUE))
|
||||
{
|
||||
if (FunctionAddress)
|
||||
{
|
||||
status = STATUS_SUCCESS;
|
||||
*FunctionAddress = functionAddress;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (0 == RtlCompareString(&FunctionName, ¤tFunctionName, TRUE))
|
||||
{
|
||||
if (FunctionAddress)
|
||||
{
|
||||
status = STATUS_SUCCESS;
|
||||
*FunctionAddress = functionAddress;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
return status;
|
||||
}
|
||||
|
||||
_Success_(return == STATUS_SUCCESS)
|
||||
_Must_inspect_result_
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
NTSTATUS
|
||||
DomitoMemorySearchPattern(
|
||||
_In_ PCUCHAR pcPattern,
|
||||
_In_ UCHAR uWildcard,
|
||||
_In_ SIZE_T puLen,
|
||||
_In_ PVOID pcBase,
|
||||
_In_ SIZE_T puSize,
|
||||
_Outptr_result_maybenull_ PVOID * ppMatch
|
||||
)
|
||||
{
|
||||
ASSERT(ppMatch != NULL && pcPattern != NULL && pcBase != NULL);
|
||||
|
||||
if (ppMatch == NULL || pcPattern == NULL || pcBase == NULL)
|
||||
{
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
*ppMatch = NULL;
|
||||
|
||||
for (SIZE_T i = 0; i < puSize - puLen; i++)
|
||||
{
|
||||
BOOLEAN found = TRUE;
|
||||
for (SIZE_T j = 0; j < puLen; j++)
|
||||
{
|
||||
if (pcPattern[j] != uWildcard && pcPattern[j] != ((PCUCHAR)pcBase)[i + j])
|
||||
{
|
||||
found = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found)
|
||||
{
|
||||
*ppMatch = (PUCHAR)pcBase + i;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
return STATUS_NOT_FOUND;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user