Skip to content

Commit

Permalink
GetModuleBase now kernel
Browse files Browse the repository at this point in the history
  • Loading branch information
ByteCorum committed Sep 18, 2024
1 parent 4edacff commit 82af2c3
Show file tree
Hide file tree
Showing 6 changed files with 253 additions and 86 deletions.
10 changes: 10 additions & 0 deletions DragonBurn-kernel/Functions.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,16 @@ NTSTATUS DriverIrpDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
//Execute IOCTL handler
switch (Stack->Parameters.DeviceIoControl.IoControlCode)
{
case IOCTL_GET_MODULE_BASE:
if (Stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(MODULE_PACK))
{
ntResult = STATUS_BUFFER_TOO_SMALL;
break;
}

ntResult = GetModuleBase((P_MODULE_PACK)Stack->Parameters.DeviceIoControl.Type3InputBuffer);
break;

case IOCTL_READ_PROCESS_MEMORY:
if (Stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(READ_PACK))
{
Expand Down
86 changes: 86 additions & 0 deletions DragonBurn-kernel/Memory.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,92 @@
#pragma once
#include "Memory.h"

// method definitions
DWORD PEBLDR_OFFSET = 0x18; // peb.ldr
DWORD PEBLDR_MEMORYLOADED_OFFSET = 0x10; // peb.ldr.InMemoryOrderModuleList
extern PVOID PsGetProcessSectionBaseAddress(PEPROCESS Process);

NTSTATUS GetModuleBase(P_MODULE_PACK ModulePack)
{
PEPROCESS Process;
KAPC_STATE APC;
NTSTATUS Status = STATUS_FAIL_CHECK;
ModulePack->baseAddress = 228;

if (!NT_SUCCESS(PsLookupProcessByProcessId((PVOID)ModulePack->pid, &Process)))
return STATUS_INVALID_PARAMETER_1;

P_MODULE_PACK ModuleList = ExAllocatePool(PagedPool, sizeof(MODULE_PACK) * 512);
if (ModuleList == NULL)
return STATUS_MEMORY_NOT_ALLOCATED;

RtlZeroMemory(ModuleList, sizeof(MODULE_PACK) * 512);

PPEB Peb = PsGetProcessPeb(Process);
if (!Peb)
return STATUS_INVALID_PARAMETER_1;

__try {
KeStackAttachProcess(Process, &APC);

UINT64 Ldr = (UINT64)Peb + PEBLDR_OFFSET;
ProbeForRead((CONST PVOID)Ldr, 8, 8);

PLIST_ENTRY ModListHead = (PLIST_ENTRY)(*(PULONG64)Ldr + PEBLDR_MEMORYLOADED_OFFSET);
ProbeForRead((CONST PVOID)ModListHead, 8, 8);

PLIST_ENTRY Module = ModListHead->Flink;

DWORD index = 0;
while (ModListHead != Module) {
LDR_DATA_TABLE_ENTRY* Module_Ldr = (LDR_DATA_TABLE_ENTRY*)(Module);

ModuleList[index].baseAddress = Module_Ldr->DllBase;
ModuleList[index].size = Module_Ldr->SizeOfImage;
RtlCopyMemory(ModuleList[index].moduleName, Module_Ldr->BaseDllName.Buffer, Module_Ldr->BaseDllName.Length);

Module = Module->Flink;
index++;
}

KeUnstackDetachProcess(&APC);

Status = STATUS_SUCCESS;
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
KeUnstackDetachProcess(&APC);
}

ModuleList[0].baseAddress += (UINT64)PsGetProcessSectionBaseAddress(Process);

WCHAR ModuleName[1024];

RtlZeroMemory(ModuleName, 1024);
wcsncpy(ModuleName, ModulePack->moduleName, 1024);

MODULE_PACK SelectedModule;
for (DWORD i = 0; i < 512; i++) {
MODULE_PACK CurrentModule = ModuleList[i];

if (_wcsicmp(CurrentModule.moduleName, ModuleName) == 0)
{
SelectedModule = CurrentModule;
break;
}
}

if (SelectedModule.baseAddress != NULL && SelectedModule.size != NULL)
{
ModulePack->baseAddress = SelectedModule.baseAddress;
}

ExFreePool(ModuleList);
ObfDereferenceObject(Process);

return Status;
}

NTSTATUS ReadProcessMemory(P_READ_PACK ReadPack)
{
if (!ReadPack)
Expand Down
36 changes: 34 additions & 2 deletions DragonBurn-kernel/Memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ typedef struct _MODULE_PACK
UINT32 pid;
UINT64 baseAddress;
SIZE_T size;
WCHAR moduleName[256];
WCHAR moduleName[1024];
} MODULE_PACK, * P_MODULE_PACK;

// Structure for writing memory to a process
Expand All @@ -27,8 +27,40 @@ typedef struct _READ_PACK
PVOID buff;
} READ_PACK, * P_READ_PACK;

typedef struct _LDR_DATA_TABLE_ENTRY
{
LIST_ENTRY64 InLoadOrderLinks;
LIST_ENTRY64 InMemoryOrderLinks;
LIST_ENTRY64 InInitializationOrderLinks;
UINT64 DllBase;
UINT64 EntryPoint;
ULONG SizeOfImage;
UNICODE_STRING FullDllName;
UNICODE_STRING BaseDllName;
ULONG Flags;
USHORT LoadCount;
USHORT TlsIndex;
PVOID SectionPointer;
ULONG CheckSum;
PVOID LoadedImports;
PVOID EntryPointActivationContext;
PVOID PatchInformation;
LIST_ENTRY64 ForwarderLinks;
LIST_ENTRY64 ServiceTagLinks;
LIST_ENTRY64 StaticLinks;
PVOID ContextInformation;
ULONG64 OriginalBase;
LARGE_INTEGER LoadTime;
} LDR_DATA_TABLE_ENTRY, * PLDR_DATA_TABLE_ENTRY;

typedef unsigned long long QWORD;
typedef unsigned short WORD;
typedef unsigned long DWORD, * PDWORD, * LPDWORD;

NTSTATUS GetModuleBase(P_MODULE_PACK);

NTSTATUS ReadProcessMemory(P_READ_PACK);

NTSTATUS WriteProcessMemory(P_WRITE_PACK);

NTSTATUS WriteProcessMemoryProtected(P_WRITE_PACK);// write virtual memory, with less restrictions, should only be used for byte patching in protected memory regions
NTSTATUS WriteProcessMemoryProtected(P_WRITE_PACK);// write virtual memory, with less restrictions, should only be used for byte patching in protected memory regions
93 changes: 61 additions & 32 deletions DragonBurn/Core/MemoryMgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,35 @@ DWORD64 MemoryMgr::TraceAddress(DWORD64 baseAddress, std::vector<DWORD> offsets)
return 0;
}

DWORD64 MemoryMgr::GetModuleBase(const wchar_t* moduleName)
{
if (kernelDriver != nullptr && ProcessID != 0)
{
MODULE_PACK ModulePack;
DWORD64 address = 0;
ModulePack.pid = ProcessID;
ModulePack.baseAddress = address;
RtlZeroMemory(ModulePack.moduleName, 1024);
wcsncpy(ModulePack.moduleName, moduleName, 1024);

BOOL result = DeviceIoControl(kernelDriver,
IOCTL_GET_MODULE_BASE,
&ModulePack,
sizeof(ModulePack),
&ModulePack,
sizeof(ModulePack),
nullptr,
nullptr);

if (result == TRUE)
return ModulePack.baseAddress;
else
return 0;
}
else
return 0;
}

DWORD MemoryMgr::GetProcessID(const wchar_t* processName)
{
DWORD processId = 0;
Expand Down Expand Up @@ -98,35 +127,35 @@ DWORD MemoryMgr::GetProcessID(const wchar_t* processName)
return processId;
}

DWORD64 MemoryMgr::GetModuleBase(const DWORD pid, const wchar_t* moduleName) {
DWORD64 moduleBase = 0;

// Snap-shot of process' modules (dlls).
HANDLE snapShot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, pid);
if (snapShot == INVALID_HANDLE_VALUE)
return moduleBase;

MODULEENTRY32W entry = {};
entry.dwSize = sizeof(decltype(entry));

if (Module32FirstW(snapShot, &entry) == TRUE)
{
if (wcsstr(moduleName, entry.szModule) != nullptr)
moduleBase = reinterpret_cast<DWORD64>(entry.modBaseAddr);

else
{
while (Module32NextW(snapShot, &entry) == TRUE)
{
if (wcsstr(moduleName, entry.szModule) != nullptr)
{
moduleBase = reinterpret_cast<DWORD64>(entry.modBaseAddr);
break;
}
}
}
}

CloseHandle(snapShot);
return moduleBase;
}
//DWORD64 MemoryMgr::GetModuleBase(const DWORD pid, const wchar_t* moduleName) {
// DWORD64 moduleBase = 0;
//
// // Snap-shot of process' modules (dlls).
// HANDLE snapShot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, pid);
// if (snapShot == INVALID_HANDLE_VALUE)
// return moduleBase;
//
// MODULEENTRY32W entry = {};
// entry.dwSize = sizeof(decltype(entry));
//
// if (Module32FirstW(snapShot, &entry) == TRUE)
// {
// if (wcsstr(moduleName, entry.szModule) != nullptr)
// moduleBase = reinterpret_cast<DWORD64>(entry.modBaseAddr);
//
// else
// {
// while (Module32NextW(snapShot, &entry) == TRUE)
// {
// if (wcsstr(moduleName, entry.szModule) != nullptr)
// {
// moduleBase = reinterpret_cast<DWORD64>(entry.modBaseAddr);
// break;
// }
// }
// }
// }
//
// CloseHandle(snapShot);
// return moduleBase;
//}
110 changes: 60 additions & 50 deletions DragonBurn/Core/MemoryMgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <vector>

#define DRAGON_DEVICE 0x8000
#define IOCTL_GET_MODULE_BASE CTL_CODE(DRAGON_DEVICE, 0x4462, METHOD_NEITHER, FILE_ANY_ACCESS)
#define IOCTL_READ_PROCESS_MEMORY CTL_CODE(DRAGON_DEVICE, 0x4472, METHOD_NEITHER, FILE_ANY_ACCESS)
#define IOCTL_WRITE_PROCESS_MEMORY CTL_CODE(DRAGON_DEVICE, 0x4482, METHOD_NEITHER, FILE_ANY_ACCESS)
#define IOCTL_WRITE_PROCESS_MEMORY_PROTECTED CTL_CODE(DRAGON_DEVICE, 0x4492, METHOD_NEITHER, FILE_ANY_ACCESS)
Expand Down Expand Up @@ -48,65 +49,74 @@ class MemoryMgr
return false;
}

template <typename WriteType>
bool WriteMemory(DWORD64 address, WriteType& value, SIZE_T size = sizeof(WriteType))
{
if (kernelDriver != INVALID_HANDLE_VALUE && ProcessID != 0)
{
WRITE_PACK WritePack;
WritePack.pid = ProcessID;
WritePack.address = reinterpret_cast<PVOID>(address);
WritePack.buff = const_cast<void*>(value);
WritePack.size = size;

BOOL result = DeviceIoControl(kernelDriver,
IOCTL_WRITE_PROCESS_MEMORY,
&WritePack,
sizeof(WritePack),
nullptr,
0,
nullptr,
nullptr);

return result == TRUE;
}
return false;
}

template <typename WriteType>
bool WriteMemoryProtected(DWORD64 address, WriteType& value, SIZE_T size = sizeof(WriteType))
{
if (kernelDriver != INVALID_HANDLE_VALUE && ProcessID != 0)
{
WRITE_PACK WritePack;
WritePack.pid = ProcessID;
WritePack.address = reinterpret_cast<PVOID>(address);
WritePack.buff = const_cast<void*>(value);
WritePack.size = size;

BOOL result = DeviceIoControl(kernelDriver,
IOCTL_WRITE_PROCESS_MEMORY_PROTECTED,
&WritePack,
sizeof(WritePack),
nullptr,
0,
nullptr,
nullptr);

return result == TRUE;
}
return false;
}
//template <typename WriteType>
//bool WriteMemory(DWORD64 address, WriteType& value, SIZE_T size = sizeof(WriteType))
//{
// if (kernelDriver != INVALID_HANDLE_VALUE && ProcessID != 0)
// {
// WRITE_PACK WritePack;
// WritePack.pid = ProcessID;
// WritePack.address = reinterpret_cast<PVOID>(address);
// WritePack.buff = const_cast<void*>(value);
// WritePack.size = size;

// BOOL result = DeviceIoControl(kernelDriver,
// IOCTL_WRITE_PROCESS_MEMORY,
// &WritePack,
// sizeof(WritePack),
// nullptr,
// 0,
// nullptr,
// nullptr);

// return result == TRUE;
// }
// return false;
//}

//template <typename WriteType>
//bool WriteMemoryProtected(DWORD64 address, WriteType& value, SIZE_T size = sizeof(WriteType))
//{
// if (kernelDriver != INVALID_HANDLE_VALUE && ProcessID != 0)
// {
// WRITE_PACK WritePack;
// WritePack.pid = ProcessID;
// WritePack.address = reinterpret_cast<PVOID>(address);
// WritePack.buff = const_cast<void*>(value);
// WritePack.size = size;

// BOOL result = DeviceIoControl(kernelDriver,
// IOCTL_WRITE_PROCESS_MEMORY_PROTECTED,
// &WritePack,
// sizeof(WritePack),
// nullptr,
// 0,
// nullptr,
// nullptr);

// return result == TRUE;
// }
// return false;
//}

DWORD64 TraceAddress(DWORD64, std::vector<DWORD>);
DWORD64 GetModuleBase(const wchar_t*);

static DWORD GetProcessID(const wchar_t*);
static DWORD64 GetModuleBase(const DWORD, const wchar_t*);
//static DWORD64 GetModuleBase(const DWORD, const wchar_t*);

private:
DWORD ProcessID;
HANDLE kernelDriver;

// Structure for getting module address base
typedef struct _MODULE_PACK {
UINT32 pid;
UINT64 baseAddress;
SIZE_T size;
WCHAR moduleName[1024];
} MODULE_PACK, * P_MODULE_PACK;

// Structure for writing memory to a process
typedef struct _WRITE_PACK {
UINT32 pid;
Expand Down
Loading

0 comments on commit 82af2c3

Please sign in to comment.