Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| eb87fee622 | |||
| 1c8e593127 | |||
| 4634e0a6db | |||
| 91a213d460 | |||
| feeab2f00f | |||
| 698c55a49f |
@@ -71,6 +71,7 @@
|
||||
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
|
||||
<ConfigurationType>Driver</ConfigurationType>
|
||||
<DriverType>WDM</DriverType>
|
||||
<Driver_SpectreMitigation>Spectre</Driver_SpectreMitigation>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
|
||||
<TargetVersion>Windows10</TargetVersion>
|
||||
@@ -136,6 +137,9 @@
|
||||
<Link>
|
||||
<AdditionalOptions>/INTEGRITYCHECK %(AdditionalOptions)</AdditionalOptions>
|
||||
</Link>
|
||||
<ClCompile>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<FilesToPackage Include="$(TargetPath)" />
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
#include "create_thread_callback.h"
|
||||
#include "protect_filter.h"
|
||||
#include "kernel_function.h"
|
||||
|
||||
#pragma warning(disable : 4309)
|
||||
#pragma warning(disable : 4838)
|
||||
|
||||
namespace thread_notify_routine
|
||||
{
|
||||
@@ -49,14 +53,49 @@ namespace thread_notify_routine
|
||||
}
|
||||
}
|
||||
|
||||
auto get_beep_trampoline_ptr() -> uintptr_t
|
||||
{
|
||||
uintptr_t trampoline_ptr = NULL;
|
||||
|
||||
auto beep = kernel_function::GetKernelModule("beep.sys");
|
||||
auto nt_header = reinterpret_cast<PIMAGE_NT_HEADERS>(beep + reinterpret_cast<PIMAGE_DOS_HEADER>(beep)->e_lfanew);
|
||||
auto file_header = &nt_header->FileHeader;
|
||||
|
||||
auto section_header = IMAGE_FIRST_SECTION(nt_header);
|
||||
for (size_t i = 0; i < file_header->NumberOfSections; i++)
|
||||
{
|
||||
if (!strcmp((char*)section_header[i].Name, ".text"))
|
||||
{
|
||||
trampoline_ptr = ((beep + section_header[i].VirtualAddress) + section_header[i].Misc.VirtualSize);
|
||||
}
|
||||
}
|
||||
return trampoline_ptr;
|
||||
}
|
||||
|
||||
auto create_thread_routine() -> NTSTATUS
|
||||
{
|
||||
return PsSetCreateThreadNotifyRoutine(thread_notify_routine);
|
||||
auto trampoline_ptr = get_beep_trampoline_ptr();
|
||||
if (trampoline_ptr)
|
||||
{
|
||||
char jmprax[] = { 0x48, 0xB8, 0xA0, 0x9A, 0xD5, 0x3E, 0xFE, 0x7F, 0x00, 0x00, 0xFF, 0xE0 };
|
||||
//mov rax,thread_notify_routine
|
||||
//jmp rax
|
||||
*(uintptr_t*)&jmprax[2] = (uintptr_t)thread_notify_routine;
|
||||
kernel_function::MmMDLPagesCopy((PVOID)trampoline_ptr, &jmprax, sizeof(jmprax), 0x0000002, KernelMode);
|
||||
|
||||
|
||||
return PsSetCreateThreadNotifyRoutine((PCREATE_PROCESS_NOTIFY_ROUTINE)trampoline_ptr);
|
||||
}
|
||||
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
auto unload_thread_routine() -> NTSTATUS
|
||||
{
|
||||
return PsRemoveCreateThreadNotifyRoutine(thread_notify_routine);
|
||||
auto trampoline_ptr = get_beep_trampoline_ptr();
|
||||
return PsRemoveCreateThreadNotifyRoutine((PCREATE_PROCESS_NOTIFY_ROUTINE)trampoline_ptr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -4,32 +4,29 @@
|
||||
#include "load_Image_callback.h"
|
||||
#include "protect_filter.h"
|
||||
#include "process_func.h"
|
||||
|
||||
#include "kernel_function.h"
|
||||
EXTERN_C NTSTATUS DriverEntry(PDRIVER_OBJECT drv_obj, PUNICODE_STRING)
|
||||
{
|
||||
if (drv_obj)
|
||||
{
|
||||
drv_obj->DriverUnload = [](PDRIVER_OBJECT)
|
||||
{
|
||||
ob_call_back::uninstall_ob_callback();
|
||||
thread_notify_routine::unload_thread_routine();
|
||||
load_image_notify_routine::remove_image_load_notify_routine();
|
||||
|
||||
|
||||
//process_function::eprocess_protect_process_off(4732);
|
||||
//load_image_notify_routine::remove_image_load_notify_routine();
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
kernel_api::kernel_api_init();
|
||||
|
||||
protect_filter::Init();
|
||||
|
||||
//protect_filter::add_list(6644, 0);
|
||||
protect_filter::add_list(10492, 0);
|
||||
DbgPrintEx(77, 0, "[+]ob_reg_callback status:%x\n", ob_call_back::register_ob_reg_callback());
|
||||
DbgPrintEx(77, 0, "[+]create_thread_routine status:%x\n", thread_notify_routine::create_thread_routine());
|
||||
|
||||
|
||||
//process_function::eprocess_protect_process_on(4732);
|
||||
|
||||
|
||||
ob_call_back::register_ob_reg_callback();
|
||||
thread_notify_routine::create_thread_routine();
|
||||
load_image_notify_routine::create_image_load_notify_routine();
|
||||
//NtQueryVirtualMemory
|
||||
//load_image_notify_routine::create_image_load_notify_routine();
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
@@ -11,9 +11,14 @@ namespace kernel_api
|
||||
RtlInitUnicodeString(&unFuncName, L"ZwQuerySystemInformation");
|
||||
imported.nt_querysystem_information = (ULONG64)MmGetSystemRoutineAddress(&unFuncName);
|
||||
|
||||
|
||||
RtlInitUnicodeString(&unFuncName, L"PsGetProcessImageFileName");
|
||||
imported.ps_getprocessimage_filname = (ULONG64)MmGetSystemRoutineAddress(&unFuncName);
|
||||
|
||||
RtlInitUnicodeString(&unFuncName, L"PsGetProcessId");
|
||||
imported.ps_getprocess_id = (ULONG64)MmGetSystemRoutineAddress(&unFuncName);
|
||||
|
||||
RtlInitUnicodeString(&unFuncName, L"SeLocateProcessImageName");
|
||||
imported.se_locateprocess_imagename = (ULONG64)MmGetSystemRoutineAddress(&unFuncName);
|
||||
}
|
||||
|
||||
NTSTATUS ntquerysysteminformation(ULONG SystemInformationClass, PVOID SystemInformation, ULONG SystemInformationLength, PULONG ReturnLength)
|
||||
@@ -28,6 +33,14 @@ namespace kernel_api
|
||||
(imported.ps_getprocessimage_filname)(Process);
|
||||
}
|
||||
|
||||
HANDLE psgetprocessid(PEPROCESS process)
|
||||
{
|
||||
return reinterpret_cast<HANDLE(*)(PEPROCESS)>(imported.ps_getprocess_id)(process);
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS selocate_process_imagename(PEPROCESS Process, PUNICODE_STRING* pImageFileName)
|
||||
{
|
||||
return reinterpret_cast<NTSTATUS(*)(PEPROCESS, PUNICODE_STRING*)>
|
||||
(imported.se_locateprocess_imagename)(Process, pImageFileName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,8 @@ struct imported_
|
||||
ULONG64 io_getcurrent_process;
|
||||
ULONG64 mm_copy_memory;
|
||||
ULONG64 ps_getprocess_section_baseaddress;
|
||||
ULONG64 ps_getprocess_id;
|
||||
ULONG64 se_locateprocess_imagename;
|
||||
};
|
||||
|
||||
namespace kernel_api
|
||||
@@ -32,4 +34,8 @@ namespace kernel_api
|
||||
|
||||
UCHAR* psgetprocessimagefilname(PEPROCESS Process);
|
||||
|
||||
HANDLE psgetprocessid(PEPROCESS process);
|
||||
|
||||
NTSTATUS selocate_process_imagename(PEPROCESS Process, PUNICODE_STRING* pImageFileName);
|
||||
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
#include "kernel_function.h"
|
||||
#include "kernel_api.h"
|
||||
|
||||
#include "utils.h"
|
||||
#pragma warning(disable : 4309)
|
||||
#pragma warning(disable : 4838)
|
||||
namespace kernel_function
|
||||
{
|
||||
PEPROCESS process{ 0 };
|
||||
@@ -66,5 +68,106 @@ namespace kernel_function
|
||||
return base;
|
||||
}
|
||||
|
||||
auto MmMDLPagesCopy(IN PVOID Address, PVOID Buff, SIZE_T Size, BYTE Type, CHAR AccessMode) -> NTSTATUS
|
||||
{
|
||||
PMDL pMDL = IoAllocateMdl(Address, (ULONG)Size, FALSE, FALSE, NULL);
|
||||
if (!pMDL) return STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
__try
|
||||
{
|
||||
MmProbeAndLockPages(pMDL, AccessMode, IoReadAccess);
|
||||
}
|
||||
__except (EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
IoFreeMdl(pMDL);
|
||||
return STATUS_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
PVOID NewAddress = MmMapLockedPagesSpecifyCache(pMDL, KernelMode, MmNonCached, NULL, 0, NormalPagePriority);
|
||||
if (!NewAddress)
|
||||
{
|
||||
MmUnlockPages(pMDL);
|
||||
IoFreeMdl(pMDL);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
if (Type == 0x0000001)
|
||||
RtlCopyMemory(Buff, NewAddress, Size);
|
||||
if (Type == 0x0000002)
|
||||
RtlCopyMemory(NewAddress, Buff, Size);
|
||||
|
||||
|
||||
MmUnmapLockedPages(NewAddress, pMDL);
|
||||
MmUnlockPages(pMDL);
|
||||
IoFreeMdl(pMDL);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
auto GetMmverifyCallBackFlags() -> uintptr_t
|
||||
{
|
||||
uintptr_t pfunc_address = NULL;
|
||||
auto version = utils::GetVersion();
|
||||
if (version.dwBuildNumber == 7600 || version.dwBuildNumber == 7601)
|
||||
{
|
||||
auto pfunc_extport_address = reinterpret_cast<unsigned char*>(utils::kernel_get_expotr_func(L"ObRegisterCallbacks"));
|
||||
for (size_t i = 0; i < 0x256; i++)
|
||||
{
|
||||
if (pfunc_extport_address[i] == 0x74 && pfunc_extport_address[i + 1] == 0x09)
|
||||
{
|
||||
pfunc_address = (uintptr_t)(*(long*)(&pfunc_extport_address[i + 3]) + &pfunc_extport_address[i + 7]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
auto pfunc_extport_address = reinterpret_cast<unsigned char*>(utils::kernel_get_expotr_func(L"PsSetCreateThreadNotifyRoutineEx"));
|
||||
for (size_t i = 0; i < 0x256; i++)
|
||||
{
|
||||
if (pfunc_extport_address[i] == 0xE8)
|
||||
{
|
||||
pfunc_address = (uintptr_t)(*(long*)(&pfunc_extport_address[i + 1]) + &pfunc_extport_address[i + 5]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return pfunc_address;
|
||||
}
|
||||
|
||||
//ÆÁ±Î0xC0000022LL´íÎó
|
||||
auto Mack_MmVerifyCallBackFlags(BYTE** orgin_byte) -> BOOL
|
||||
{
|
||||
uintptr_t pfunc_address = GetMmverifyCallBackFlags();
|
||||
if (!pfunc_address)
|
||||
return FALSE;
|
||||
|
||||
//xor,rax,rax
|
||||
//mov rax,1
|
||||
//ret
|
||||
char shellcode[] = { 0x31, 0xC0, 0xB8, 0x01, 0x00 ,0x00, 0x00,0xC3 };
|
||||
|
||||
memcpy(orgin_byte, (CONST void*)pfunc_address, sizeof(shellcode));
|
||||
|
||||
auto status = MmMDLPagesCopy((PVOID)pfunc_address, &shellcode, sizeof(shellcode), 0x0000002, KernelMode);
|
||||
if (!NT_SUCCESS(status))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
auto Orgin_MmVerifyCallBackFlags(BYTE* orgin_byte) -> BOOL
|
||||
{
|
||||
uintptr_t pfunc_address = GetMmverifyCallBackFlags();
|
||||
if (!pfunc_address)
|
||||
return FALSE;
|
||||
|
||||
auto status = MmMDLPagesCopy((PVOID)pfunc_address, orgin_byte, sizeof(orgin_byte), 0x0000002, KernelMode);
|
||||
if (!NT_SUCCESS(status))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
namespace kernel_function
|
||||
{
|
||||
|
||||
typedef enum _SYSTEM_INFORMATION_CLASS {
|
||||
SystemBasicInformation = 0,
|
||||
SystemPerformanceInformation = 2,
|
||||
@@ -43,7 +42,11 @@ namespace kernel_function
|
||||
|
||||
auto GetKernelModule(CONST CHAR* Module)->uintptr_t;
|
||||
|
||||
auto MmMDLPagesCopy(IN PVOID Address, PVOID Buff, SIZE_T Size, BYTE Type, CHAR AccessMode)->NTSTATUS;
|
||||
|
||||
auto GetMmverifyCallBackFlags()->uintptr_t;
|
||||
|
||||
auto Mack_MmVerifyCallBackFlags(BYTE** orgin_byte)->BOOL;
|
||||
|
||||
auto Orgin_MmVerifyCallBackFlags(BYTE* orgin_byte)->BOOL;
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "ob_reg_callback.h"
|
||||
#include "protect_filter.h"
|
||||
#include "kernel_function.h"
|
||||
|
||||
void* reg_ob_callback_handle;
|
||||
|
||||
@@ -22,13 +23,15 @@ auto ob_call_back::register_ob_reg_callback() -> NTSTATUS
|
||||
auto ob_callback = [](_In_ PVOID RegistrationContext,
|
||||
_In_ POB_PRE_OPERATION_INFORMATION pOperationInformation) -> OB_PREOP_CALLBACK_STATUS
|
||||
{
|
||||
UNREFERENCED_PARAMETER(pOperationInformation);
|
||||
UNREFERENCED_PARAMETER(RegistrationContext);
|
||||
auto dwPid = PsGetProcessId(reinterpret_cast<PEPROCESS>(pOperationInformation->Object));
|
||||
|
||||
auto dwPid = kernel_api::psgetprocessid(reinterpret_cast<PEPROCESS>(pOperationInformation->Object));
|
||||
|
||||
auto operation_eprocess = PsGetCurrentProcess();
|
||||
|
||||
PUNICODE_STRING image_file_name{ 0 };
|
||||
auto status = SeLocateProcessImageName(operation_eprocess, &image_file_name);
|
||||
auto status = kernel_api::selocate_process_imagename(operation_eprocess, &image_file_name);
|
||||
if (NT_SUCCESS(status))
|
||||
{
|
||||
if(is_allow_process(image_file_name))
|
||||
@@ -36,8 +39,8 @@ auto ob_call_back::register_ob_reg_callback() -> NTSTATUS
|
||||
|
||||
if (protect_filter::is_protect_pid(HandleToLong(dwPid), nullptr))
|
||||
{
|
||||
pOperationInformation->Parameters->DuplicateHandleInformation.DesiredAccess = 0;
|
||||
pOperationInformation->Parameters->DuplicateHandleInformation.OriginalDesiredAccess = 0;
|
||||
//pOperationInformation->Parameters->DuplicateHandleInformation.DesiredAccess = 0;
|
||||
//pOperationInformation->Parameters->DuplicateHandleInformation.OriginalDesiredAccess = 0;
|
||||
}
|
||||
}
|
||||
end:
|
||||
@@ -64,8 +67,11 @@ auto ob_call_back::register_ob_reg_callback() -> NTSTATUS
|
||||
//方式2 : 注册两个ObRegisterCallbacks 层分别在xx的上方和下方 等xx抹了之后 抹回去
|
||||
//方式3 :Pte hook Obp
|
||||
//方式4 :遍历CallbacksList替换或修改Pre Post函数
|
||||
|
||||
BYTE* orgin_byte = nullptr;
|
||||
kernel_function::Mack_MmVerifyCallBackFlags(&orgin_byte);
|
||||
status = ObRegisterCallbacks(&obReg, ®_ob_callback_handle);
|
||||
kernel_function::Orgin_MmVerifyCallBackFlags((BYTE*)&orgin_byte);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
@@ -56,6 +56,13 @@ namespace utils
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto kernel_get_expotr_func(wchar_t* func_name)-> uintptr_t
|
||||
{
|
||||
UNICODE_STRING unicode_func_name{ 0 };
|
||||
RtlInitUnicodeString(&unicode_func_name, func_name);
|
||||
return (uintptr_t)MmGetSystemRoutineAddress(&unicode_func_name);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -7,8 +7,7 @@ namespace utils
|
||||
|
||||
auto FindSectionsCode(unsigned long long Base, const char* pattern, const char* mask, const char* name) -> ULONG64;
|
||||
|
||||
|
||||
|
||||
auto kernel_get_expotr_func(wchar_t* func_name) -> uintptr_t;
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user