mirror of
https://github.com/BeneficialCode/WinArk.git
synced 2026-10-17 04:40:35 +08:00
Can get the count of vad
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
@@ -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;
|
||||
};
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user