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);