Can get the count of vad

This commit is contained in:
BeneficialCode
2022-12-11 11:34:27 +08:00
parent 6f4c01ae06
commit abe307ae5f
17 changed files with 178 additions and 17 deletions
+5 -1
View File
@@ -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;
}
}
+1 -1
View File
@@ -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锁定用户内存
+19 -1
View File
@@ -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;
};
+2 -2
View File
@@ -179,7 +179,7 @@
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="VadHelpers.h">
<Filter>Source Files</Filter>
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
@@ -301,7 +301,7 @@
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="VadHelpers.cpp">
<Filter>Header Files</Filter>
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
+2 -2
View File
@@ -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;
+17 -3
View File
@@ -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;
}
+43
View File
@@ -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<SymbolInfo>();
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;
}
+1 -1
View File
@@ -5,7 +5,6 @@
#include <list>
#include <DbgHelp.h>
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);
+1 -1
View File
@@ -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) {
+55 -1
View File
@@ -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;
}
+4
View File
@@ -2,6 +2,7 @@
// 因为是模板类,所以直接在这里包含
#include "Table.h"
#include "resource.h"
#include "DriverHelper.h"
class CProcessTable
:public CTable<std::shared_ptr<WinSys::ProcessInfo>>,
@@ -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;
+5 -1
View File
@@ -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);
}
+7 -2
View File
@@ -1,17 +1,22 @@
#pragma once
#include "SymbolHandler.h"
class SymbolHelper final{
public:
static std::unique_ptr<SymbolInfo> 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;
+1
View File
@@ -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
+3 -1
View File
@@ -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
+11
View File
@@ -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;
}
+1
View File
@@ -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);