diff --git a/Anti-Rootkit/ARK.cpp b/Anti-Rootkit/ARK.cpp
index 2b4ed65..2dcaed6 100644
--- a/Anti-Rootkit/ARK.cpp
+++ b/Anti-Rootkit/ARK.cpp
@@ -17,6 +17,7 @@
#include "..\KernelLibrary\IoTimer.h"
#include "..\KernelLibrary\BypassAntiKernelDbg.h"
#include "..\KernelLibrary\MiniFilter.h"
+#include "..\KernelLibrary\VadHelpers.h"
// SE_IMAGE_SIGNATURE_TYPE
@@ -1419,7 +1420,10 @@ NTSTATUS AntiRootkitDeviceControl(PDEVICE_OBJECT, PIRP Irp) {
break;
}
VadData* pData = (VadData*)Irp->AssociatedIrp.SystemBuffer;
-
+ ULONG count = 0;
+ status = VadHelpers::GetVadCount(pData, &count);
+ *(ULONG*)Irp->AssociatedIrp.SystemBuffer = count;
+ len = sizeof(count);
break;
}
}
diff --git a/Anti-Rootkit/AntiRootkit.h b/Anti-Rootkit/AntiRootkit.h
index 9d56657..546d646 100644
--- a/Anti-Rootkit/AntiRootkit.h
+++ b/Anti-Rootkit/AntiRootkit.h
@@ -45,7 +45,7 @@ Typical drivers just use FILE_ANY_ACCESS and deal with the actual request in the
// 回调驱动 链接器 命令行 + -----> /integritycheck
#define ANTI_ROOTKIT_DEVICE 0x8000
-#define DRIVER_CURRENT_VERSION 0xC2
+#define DRIVER_CURRENT_VERSION 0xC3
// 用MDL锁定用户内存
diff --git a/KernelLibrary/Common.h b/KernelLibrary/Common.h
index 43c0488..1878093 100644
--- a/KernelLibrary/Common.h
+++ b/KernelLibrary/Common.h
@@ -240,13 +240,24 @@ struct PebOffsets {
};
enum class VadCountPos {
- VadCount = 0,
+ None = 0,
+ VadCount,
NumberOfVads,
NumberGenericTableElements
};
+struct BitField {
+ USHORT Position;
+ USHORT Size;
+};
+
struct MmAvlTableOffsets {
ULONG NumberGenericTableElements;
+ BitField BitField;
+};
+
+struct MmVadFlagsOffsets {
+ ULONG Protection;
};
struct VadData {
@@ -256,3 +267,10 @@ struct VadData {
ULONG Pid;
};
+struct VadInfo {
+ void* Vad;
+ ULONG Level;
+ ULONG64 StartingVpn;
+ ULONG64 EndingVpn;
+ ULONG Protection;
+};
\ No newline at end of file
diff --git a/KernelLibrary/KernelLibrary.vcxproj.filters b/KernelLibrary/KernelLibrary.vcxproj.filters
index 209e978..f64660c 100644
--- a/KernelLibrary/KernelLibrary.vcxproj.filters
+++ b/KernelLibrary/KernelLibrary.vcxproj.filters
@@ -179,7 +179,7 @@
Header Files
- Source Files
+ Header Files
@@ -301,7 +301,7 @@
Source Files
- Header Files
+ Source Files
diff --git a/KernelLibrary/KernelTimer.cpp b/KernelLibrary/KernelTimer.cpp
index 1c954ce..4254e1e 100644
--- a/KernelLibrary/KernelTimer.cpp
+++ b/KernelLibrary/KernelTimer.cpp
@@ -45,7 +45,7 @@ void KernelTimer::EnumKernelTimer(KernelTimerData* pData, DpcTimerInfo* pInfo) {
for (PLIST_ENTRY pListEntry = pListHead->Flink; pListEntry != pListHead; pListEntry = pListEntry->Flink) {
if (!MmIsAddressValid(pListEntry))
- continue;
+ break;
PKTIMER pTimer = CONTAINING_RECORD(pListEntry, KTIMER, TimerListEntry);
#ifdef _WIN64
ULONG_PTR salt = (ULONG_PTR)pTimer;
@@ -103,7 +103,7 @@ ULONG KernelTimer::GetKernelTimerCount(KernelTimerData* pData) {
for (PLIST_ENTRY pListEntry = pListHead->Flink; pListEntry != pListHead; pListEntry = pListEntry->Flink) {
if (!MmIsAddressValid(pListEntry))
- continue;
+ break;
PKTIMER pTimer = CONTAINING_RECORD(pListEntry, KTIMER, TimerListEntry);
#ifdef _WIN64
ULONG_PTR salt = (ULONG_PTR)pTimer;
diff --git a/KernelLibrary/VadHelpers.cpp b/KernelLibrary/VadHelpers.cpp
index b227e92..6e9b5a2 100644
--- a/KernelLibrary/VadHelpers.cpp
+++ b/KernelLibrary/VadHelpers.cpp
@@ -1,7 +1,7 @@
#include "pch.h"
#include "VadHelpers.h"
-NTSTATUS VadHelpers::GetVadCount(VadData* pData, PULONG pCount) {
+NTSTATUS VadHelpers::GetVadCount (VadData* pData, PULONG pCount) {
NTSTATUS status = STATUS_SUCCESS;
ULONG nVads = 0;
PEPROCESS Process = nullptr;
@@ -13,8 +13,22 @@ NTSTATUS VadHelpers::GetVadCount(VadData* pData, PULONG pCount) {
case VadCountPos::NumberGenericTableElements:
{
PUCHAR pTable = (PUCHAR)Process + pData->EprocessOffsets.VadRoot;
- PULONG pNumberGenericElements = (PULONG)((PUCHAR)pTable + pData->TableOffsets.NumberGenericTableElements);
- *pCount = *pNumberGenericElements;
+ PUCHAR pNumberGenericElements = (PUCHAR)pTable + pData->TableOffsets.NumberGenericTableElements;
+ PUCHAR readAddr = pNumberGenericElements;
+ readAddr += (pData->TableOffsets.BitField.Position / 8);
+ ULONG readSz = (pData->TableOffsets.BitField.Position % 8 + pData->TableOffsets.BitField.Size
+ + 7) / 8;
+ ULONG64 readBits;
+ ULONG64 bitCopy;
+
+ RtlCopyMemory(&readBits, readAddr, readSz);
+
+ readBits = readBits >> (pData->TableOffsets.BitField.Position % 8);
+ bitCopy = ((ULONG64)1 << pData->TableOffsets.BitField.Size);
+ bitCopy -= (ULONG64)1;
+ readBits &= bitCopy;
+
+ *pCount = readBits;
break;
}
diff --git a/PdbParser/SymbolHandler.cpp b/PdbParser/SymbolHandler.cpp
index 99a80ad..28ebc6e 100644
--- a/PdbParser/SymbolHandler.cpp
+++ b/PdbParser/SymbolHandler.cpp
@@ -206,6 +206,7 @@ DWORD SymbolHandler::GetStructMemberSize(std::string name, std::string memberNam
SymFromIndex(m_hProcess, _address, child, pMemberInfo);
if (!::strcmp(pMemberInfo->Name, memberName.c_str())) {
size = pMemberInfo->Size;
+
break;
}
}
@@ -261,4 +262,46 @@ ULONG_PTR SymbolHandler::GetSymbolAddressFromName(PCSTR name) {
auto info = symbol->GetSymbolInfo();
::SymGetSymFromName(m_hProcess, name, info);
return info->Address;
+}
+
+DWORD SymbolHandler::GetBitFieldPos(std::string name, std::string fieldName) {
+ DWORD pos = 0;
+
+ auto symbol = std::make_unique();
+ auto info = symbol->GetSymbolInfo();
+ SymGetTypeFromName(m_hProcess, _address, name.c_str(), symbol->GetSymbolInfo());
+
+ ULONG childrenCount;
+ SymGetTypeInfo(m_hProcess, _address, info->TypeIndex, TI_GET_CHILDRENCOUNT, &childrenCount);
+ TI_FINDCHILDREN_PARAMS* childrenParams = (TI_FINDCHILDREN_PARAMS*)malloc(sizeof(TI_FINDCHILDREN_PARAMS) + sizeof(ULONG) * childrenCount);
+ if (childrenParams == nullptr) {
+ return pos;
+ }
+ childrenParams->Count = childrenCount;
+ childrenParams->Start = 0;
+ PSYMBOL_INFO pMemberInfo = (PSYMBOL_INFO)malloc((sizeof(SYMBOL_INFO) +
+ MAX_SYM_NAME * sizeof(TCHAR) +
+ sizeof(ULONG64) - 1) /
+ sizeof(ULONG64));
+ if (pMemberInfo == nullptr) {
+ free(childrenParams);
+ return pos;
+ }
+ pMemberInfo->SizeOfStruct = sizeof(SYMBOL_INFO);
+ pMemberInfo->MaxNameLen = MAX_SYM_NAME;
+ SymGetTypeInfo(m_hProcess, _address, info->TypeIndex, TI_FINDCHILDREN, childrenParams);
+
+ for (ULONG i = 0; i < childrenParams->Count; i++) {
+ ULONG child = childrenParams->ChildId[i];
+ SymFromIndex(m_hProcess, _address, child, pMemberInfo);
+ if (!::strcmp(pMemberInfo->Name, fieldName.c_str())) {
+ SymGetTypeInfo(m_hProcess, _address, child, TI_GET_BITPOSITION, &pos);
+ break;
+ }
+ }
+
+ free(pMemberInfo);
+ free(childrenParams);
+
+ return pos;
}
\ No newline at end of file
diff --git a/PdbParser/SymbolHandler.h b/PdbParser/SymbolHandler.h
index 1dc9a90..b67346a 100644
--- a/PdbParser/SymbolHandler.h
+++ b/PdbParser/SymbolHandler.h
@@ -5,7 +5,6 @@
#include
#include
-
enum class ProcessAccessMask : unsigned {
Query = 0x400
};
@@ -207,6 +206,7 @@ public:
ULONG GetStructSize(std::string name);
+ DWORD GetBitFieldPos(std::string name, std::string fieldName);
private:
BOOL Callback(ULONG code, ULONG64 data);
diff --git a/WinArk/DPCTimerTable.cpp b/WinArk/DPCTimerTable.cpp
index 90e2288..341c81c 100644
--- a/WinArk/DPCTimerTable.cpp
+++ b/WinArk/DPCTimerTable.cpp
@@ -138,7 +138,7 @@ int CDpcTimerTable::ParseTableEntry(CString& s, char& mask, int& select, std::sh
void CDpcTimerTable::Refresh() {
m_Table.data.info.clear();
- ULONG memberSize = SymbolHelper::GetKernelSturctMemberSize("_KTIMER_TABLE", "TimerEntries");
+ ULONG memberSize = SymbolHelper::GetKernelStructMemberSize("_KTIMER_TABLE", "TimerEntries");
ULONG size = SymbolHelper::GetKernelStructSize("_KTIMER_TABLE_ENTRY");
KernelTimerData data;
if (size != 0) {
diff --git a/WinArk/ProcessTable.cpp b/WinArk/ProcessTable.cpp
index 0459395..ddfe8f9 100644
--- a/WinArk/ProcessTable.cpp
+++ b/WinArk/ProcessTable.cpp
@@ -2,7 +2,6 @@
#include "ProcessTable.h"
#include "FormatHelper.h"
#include "resource.h"
-#include "DriverHelper.h"
#include "ProcessModuleDlg.h"
#include "ProcessPropertiesDlg.h"
#include "ProcessThreadDlg.h"
@@ -10,6 +9,7 @@
#include "ProcessMemoryDlg.h"
#include "ProcessInlineHookDlg.h"
#include "ProcessATHookDlg.h"
+#include "SymbolHelper.h"
#pragma comment(lib,"WinSysCore")
#pragma comment(lib,"ntdll")
@@ -423,3 +423,57 @@ LRESULT CProcessTable::OnProcessEATHookScan(WORD /*wNotifyCode*/, WORD /*wID*/,
return 0;
}
+bool CProcessTable::InitVadSymbols(VadData* pData) {
+ pData->EprocessOffsets.VadRoot = SymbolHelper::GetKernelStructMemberOffset("_EPROCESS", "VadRoot");
+ if (!pData->EprocessOffsets.VadRoot) {
+ return false;
+ }
+
+ pData->VadCountPos = VadCountPos::None;
+
+ pData->TableOffsets.NumberGenericTableElements = SymbolHelper::GetKernelStructMemberOffset("_MM_AVL_TABLE", "NumberGenericTableElements");
+ if (pData->TableOffsets.NumberGenericTableElements != -1) {
+ pData->TableOffsets.BitField.Position = SymbolHelper::GetKernelBitFieldPos("_MM_AVL_TABLE", "NumberGenericTableElements");
+ pData->TableOffsets.BitField.Size = SymbolHelper::GetKernelStructMemberSize("_MM_AVL_TABLE", "NumberGenericTableElements");
+ }
+
+ pData->EprocessOffsets.VadCount = SymbolHelper::GetKernelStructMemberOffset("_EPROCESS", "VadCount");
+ pData->EprocessOffsets.NumberOfVads = SymbolHelper::GetKernelStructMemberOffset("_EPROCESS", "NumberOfVads");
+
+ if (pData->TableOffsets.NumberGenericTableElements!=-1) {
+ pData->VadCountPos = VadCountPos::NumberGenericTableElements;
+ }
+ else if (pData->EprocessOffsets.NumberOfVads!=-1) {
+ pData->VadCountPos = VadCountPos::NumberOfVads;
+ }
+ else if(pData->EprocessOffsets.VadCount!=-1){
+ pData->VadCountPos = VadCountPos::VadCount;
+ }
+
+ if (pData->VadCountPos == VadCountPos::None)
+ return false;
+
+ return true;
+}
+
+LRESULT CProcessTable::OnProcessVadInfo(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) {
+ int selected = m_Table.data.selected;
+ ATLASSERT(selected >= 0);
+ auto& process = m_Table.data.info[selected];
+
+ VadData data;
+ data.Pid = process->Id;
+ bool ok = InitVadSymbols(&data);
+ if (!ok) {
+ AtlMessageBox(*this, L"offsets get failed :(", IDS_TITLE, MB_ICONINFORMATION);
+ return 0;
+ }
+
+ ULONG vadCount = DriverHelper::GetVadCount(&data);
+ if (!vadCount) {
+ AtlMessageBox(*this, L"Vad Count equals 0 :(", IDS_TITLE, MB_ICONINFORMATION);
+ }
+
+ return 0;
+}
+
diff --git a/WinArk/ProcessTable.h b/WinArk/ProcessTable.h
index 09eba31..02a1cf2 100644
--- a/WinArk/ProcessTable.h
+++ b/WinArk/ProcessTable.h
@@ -2,6 +2,7 @@
// 因为是模板类,所以直接在这里包含
#include "Table.h"
#include "resource.h"
+#include "DriverHelper.h"
class CProcessTable
:public CTable>,
@@ -40,6 +41,7 @@ public:
COMMAND_ID_HANDLER(ID_PROCESS_MEMORY,OnProcessMemory)
COMMAND_ID_HANDLER(ID_PROCESS_INLINEHOOKSCAN,OnProcessInlineHookScan)
COMMAND_ID_HANDLER(ID_ADDRESS_TABLE_HOOKSCAN,OnProcessEATHookScan)
+ COMMAND_ID_HANDLER(ID_PROCESS_VAD_INFO,OnProcessVadInfo)
END_MSG_MAP()
CProcessTable(BarInfo& bars,TableInfo& table);
@@ -80,7 +82,9 @@ public:
LRESULT OnProcessInlineHookScan(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/);
LRESULT OnProcessSuspend(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/);
LRESULT OnProcessEATHookScan(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/);
+ LRESULT OnProcessVadInfo(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/);
+ bool InitVadSymbols(VadData* pData);
int GetRowImage(HWND, int row) const;
diff --git a/WinArk/SymbolHelper.cpp b/WinArk/SymbolHelper.cpp
index f10bb14..9a1db23 100644
--- a/WinArk/SymbolHelper.cpp
+++ b/WinArk/SymbolHelper.cpp
@@ -107,10 +107,14 @@ DWORD SymbolHelper::GetFltmgrStructMemberOffset(std::string name, std::string me
return _fltmgr.GetStructMemberOffset(name, memberName);
}
-DWORD SymbolHelper::GetKernelSturctMemberSize(std::string name, std::string memberName) {
+DWORD SymbolHelper::GetKernelStructMemberSize(std::string name, std::string memberName) {
return _kernel.GetStructMemberSize(name, memberName);
}
DWORD SymbolHelper::GetKernelStructSize(std::string name) {
return _kernel.GetStructSize(name);
}
+
+DWORD SymbolHelper::GetKernelBitFieldPos(std::string name, std::string fieldName) {
+ return _kernel.GetBitFieldPos(name, fieldName);
+}
\ No newline at end of file
diff --git a/WinArk/SymbolHelper.h b/WinArk/SymbolHelper.h
index aa2aac1..88a5edc 100644
--- a/WinArk/SymbolHelper.h
+++ b/WinArk/SymbolHelper.h
@@ -1,17 +1,22 @@
#pragma once
#include "SymbolHandler.h"
-
class SymbolHelper final{
public:
static std::unique_ptr GetSymbolFromAddress(DWORD64 address, PDWORD64 offset = nullptr);
static ULONG64 GetKernelSymbolAddressFromName(PCSTR name);
static ULONG64 GetWin32kSymbolAddressFromName(PCSTR name);
static DWORD GetKernelStructMemberOffset(std::string name, std::string memberName);
- static DWORD GetKernelSturctMemberSize(std::string name, std::string memberName);
+ static DWORD GetKernelStructMemberSize(std::string name, std::string memberName);
static DWORD GetKernelStructSize(std::string name);
static DWORD GetFltmgrStructMemberOffset(std::string name, std::string memberName);
static void Init();
+
+ struct BitField {
+ USHORT Position;
+ USHORT Size;
+ };
+ static DWORD GetKernelBitFieldPos(std::string name, std::string fieldName);
private:
static inline DWORD _win32kSize, _kernelSize;
diff --git a/WinArk/WinArk.rc b/WinArk/WinArk.rc
index e49e37e..e7b53ea 100644
--- a/WinArk/WinArk.rc
+++ b/WinArk/WinArk.rc
@@ -657,6 +657,7 @@ BEGIN
END
MENUITEM "Inline Hook Scan", ID_PROCESS_INLINEHOOKSCAN
MENUITEM "AT Hook Scan", ID_ADDRESS_TABLE_HOOKSCAN
+ MENUITEM "VAD Information", ID_PROCESS_VAD_INFO
END
POPUP "listdir"
BEGIN
diff --git a/WinArk/resource.h b/WinArk/resource.h
index b751bd2..3eb5798 100644
--- a/WinArk/resource.h
+++ b/WinArk/resource.h
@@ -370,13 +370,15 @@
#define ID_PROCESS_AT_HOOKSCAN 32963
#define ID_ADDRESS_TABLE_HOOKSCAN 32964
#define ID_KERNEL_GOTOFILELOCATION 32965
+#define ID_PROCESS_VADINFORMATION 32966
+#define ID_PROCESS_VAD_INFO 32967
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 279
-#define _APS_NEXT_COMMAND_VALUE 32966
+#define _APS_NEXT_COMMAND_VALUE 32968
#define _APS_NEXT_CONTROL_VALUE 1096
#define _APS_NEXT_SYMED_VALUE 101
#endif
diff --git a/WinSysCore/DriverHelper.cpp b/WinSysCore/DriverHelper.cpp
index c261183..de74223 100644
--- a/WinSysCore/DriverHelper.cpp
+++ b/WinSysCore/DriverHelper.cpp
@@ -589,4 +589,15 @@ bool DriverHelper::Unbypass(DWORD flag) {
DWORD bytes;
return ::DeviceIoControl(_hDevice, IOCTL_ARK_UNBYPASS_DETECT, &flag, sizeof(flag),
nullptr, 0, &bytes, nullptr);
+}
+
+ULONG DriverHelper::GetVadCount(VadData* pData) {
+ if (!OpenDevice())
+ return false;
+
+ DWORD bytes;
+ ULONG count = 0;
+ ::DeviceIoControl(_hDevice, IOCTL_ARK_GET_PROCESS_VAD_COUNT, pData, sizeof(VadData),
+ &count, sizeof(ULONG), &bytes, nullptr);
+ return count;
}
\ No newline at end of file
diff --git a/WinSysCore/DriverHelper.h b/WinSysCore/DriverHelper.h
index 85ac8b9..0e6e035 100644
--- a/WinSysCore/DriverHelper.h
+++ b/WinSysCore/DriverHelper.h
@@ -49,6 +49,7 @@ struct DriverHelper final {
static bool RemoveMiniFilter(MiniFilterData* pData, SIZE_T dataSize);
static ULONG GetKernelTimerCount(KernelTimerData* pData);
+ static ULONG GetVadCount(VadData* pData);
static bool Bypass(DWORD flag);
static bool Unbypass(DWORD flag);