一些 w10 的 NtQuerySystemInformation 问题
Problem with NtQuerySystemInformation with some w10
我正在处理外部代码,它是一款 MMORPG 游戏的反黑客软件。话虽这么说,代码在一些 Windows 10 个用户中出现崩溃或错误检测(它对 7 和 8.1 总是很好用),问题来自使用 NtQuerySystemInformation 然后比较进程句柄的函数。
感谢任何可以提供帮助或提供提示的人。
我会为你留下密码:
ProcessQuery.h
#pragma once
typedef LONG KPRIORITY;
typedef NTSTATUS(WINAPI*NTQUERYSYSTEMINFORMATION)(SYSTEM_INFORMATION_CLASS,PVOID,ULONG,PULONG);
#define STATUS_SUCCESS ((NTSTATUS)0x00000000)
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004)
#define STATUS_DATA_ERROR ((NTSTATUS)0xC000003E)
#define SystemExtendedProcessInformation ((SYSTEM_INFORMATION_CLASS)57)
#define SystemHandleInformation ((SYSTEM_INFORMATION_CLASS)16)
#define SystemExtendedHandleInformation ((SYSTEM_INFORMATION_CLASS)64)
#define SystemKernelDebuggerInformation ((SYSTEM_INFORMATION_CLASS)35)
enum THREAD_STATE
{
Running = 2,
Waiting = 5,
};
enum KWAIT_REASON
{
Executive = 0,
FreePage = 1,
PageIn = 2,
PoolAllocation = 3,
DelayExecution = 4,
Suspended = 5,
UserRequest = 6,
WrExecutive = 7,
WrFreePage = 8,
WrPageIn = 9,
WrPoolAllocation = 10,
WrDelayExecution = 11,
WrSuspended = 12,
WrUserRequest = 13,
WrEventPair = 14,
WrQueue = 15,
WrLpcReceive = 16,
WrLpcReply = 17,
WrVirtualMemory = 18,
WrPageOut = 19,
WrRendezvous = 20,
Spare2 = 21,
Spare3 = 22,
Spare4 = 23,
Spare5 = 24,
WrCalloutStack = 25,
WrKernel = 26,
WrResource = 27,
WrPushLock = 28,
WrMutex = 29,
WrQuantumEnd = 30,
WrDispatchInt = 31,
WrPreempted = 32,
WrYieldExecution = 33,
WrFastMutex = 34,
WrGuardedMutex = 35,
WrRundown = 36,
MaximumWaitReason = 37,
};
struct CLIENT_ID
{
PVOID UniqueProcess;
PVOID UniqueThread;
};
struct SYSTEM_THREAD_INFO
{
LARGE_INTEGER KernelTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER CreateTime;
ULONG WaitTime;
PVOID StartAddress;
CLIENT_ID ClientId;
KPRIORITY Priority;
LONG BasePriority;
ULONG ContextSwitches;
ULONG ThreadState;
KWAIT_REASON WaitReason;
};
struct SYSTEM_EXTENDED_THREAD_INFO
{
SYSTEM_THREAD_INFO ThreadInfo;
PVOID StackBase;
PVOID StackLimit;
PVOID Win32StartAddress;
PVOID TebAddress; // since VISTA
ULONG Reserved1;
ULONG Reserved2;
ULONG Reserved3;
};
struct SYSTEM_PROCESS_INFO
{
ULONG NextEntryOffset;
ULONG NumberOfThreads;
LARGE_INTEGER WorkingSetPrivateSize; // since VISTA
ULONG HardFaultCount; // since WIN7
ULONG NumberOfThreadsHighWatermark; // since WIN7
ULONGLONG CycleTime; // since WIN7
LARGE_INTEGER CreateTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER KernelTime;
UNICODE_STRING ImageName;
KPRIORITY BasePriority;
HANDLE UniqueProcessId;
HANDLE InheritedFromUniqueProcessId;
ULONG HandleCount;
ULONG SessionId;
ULONG_PTR UniqueProcessKey; // since VISTA (requires SystemExtendedProcessInformation)
SIZE_T PeakVirtualSize;
SIZE_T VirtualSize;
ULONG PageFaultCount;
SIZE_T PeakWorkingSetSize;
SIZE_T WorkingSetSize;
SIZE_T QuotaPeakPagedPoolUsage;
SIZE_T QuotaPagedPoolUsage;
SIZE_T QuotaPeakNonPagedPoolUsage;
SIZE_T QuotaNonPagedPoolUsage;
SIZE_T PagefileUsage;
SIZE_T PeakPagefileUsage;
SIZE_T PrivatePageCount;
LARGE_INTEGER ReadOperationCount;
LARGE_INTEGER WriteOperationCount;
LARGE_INTEGER OtherOperationCount;
LARGE_INTEGER ReadTransferCount;
LARGE_INTEGER WriteTransferCount;
LARGE_INTEGER OtherTransferCount;
SYSTEM_THREAD_INFO Threads[1];
};
struct SYSTEM_EXTENDED_PROCESS_INFO
{
ULONG NextEntryOffset;
ULONG NumberOfThreads;
LARGE_INTEGER WorkingSetPrivateSize; // since VISTA
ULONG HardFaultCount; // since WIN7
ULONG NumberOfThreadsHighWatermark; // since WIN7
ULONGLONG CycleTime; // since WIN7
LARGE_INTEGER CreateTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER KernelTime;
UNICODE_STRING ImageName;
KPRIORITY BasePriority;
HANDLE UniqueProcessId;
HANDLE InheritedFromUniqueProcessId;
ULONG HandleCount;
ULONG SessionId;
ULONG_PTR UniqueProcessKey; // since VISTA (requires SystemExtendedProcessInformation)
SIZE_T PeakVirtualSize;
SIZE_T VirtualSize;
ULONG PageFaultCount;
SIZE_T PeakWorkingSetSize;
SIZE_T WorkingSetSize;
SIZE_T QuotaPeakPagedPoolUsage;
SIZE_T QuotaPagedPoolUsage;
SIZE_T QuotaPeakNonPagedPoolUsage;
SIZE_T QuotaNonPagedPoolUsage;
SIZE_T PagefileUsage;
SIZE_T PeakPagefileUsage;
SIZE_T PrivatePageCount;
LARGE_INTEGER ReadOperationCount;
LARGE_INTEGER WriteOperationCount;
LARGE_INTEGER OtherOperationCount;
LARGE_INTEGER ReadTransferCount;
LARGE_INTEGER WriteTransferCount;
LARGE_INTEGER OtherTransferCount;
SYSTEM_EXTENDED_THREAD_INFO Threads[1];
};
struct SYSTEM_HANDLE_ENTRY_INFO
{
USHORT UniqueProcessId;
USHORT CreatorBackTraceIndex;
UCHAR ObjectTypeIndex;
UCHAR HandleAttributes;
USHORT HandleValue;
PVOID Object;
ULONG GrantedAccess;
};
struct SYSTEM_HANDLE_INFO
{
ULONG NumberOfHandles;
SYSTEM_HANDLE_ENTRY_INFO Handles[1];
};
struct SYSTEM_HANDLE_ENTRY_INFO_EX
{
PVOID Object;
ULONG UniqueProcessId;
ULONG HandleValue;
ULONG GrantedAccess;
USHORT CreatorBackTraceIndex;
USHORT ObjectTypeIndex;
ULONG HandleAttributes;
ULONG Reserved;
};
struct SYSTEM_HANDLE_INFO_EX
{
ULONG NumberOfHandles;
ULONG Reserved;
SYSTEM_HANDLE_ENTRY_INFO_EX Handles[1];
};
struct SYSTEM_KERNEL_DEBUGGER_INFO
{
BOOLEAN DebuggerEnabled;
BOOLEAN DebuggerNotPresent;
};
class CProcessQuery
{
public:
CProcessQuery();
virtual ~CProcessQuery();
void Start();
void Close();
bool Fetch(SYSTEM_INFORMATION_CLASS SysInfoClass,DWORD QuerySize);
SYSTEM_HANDLE_INFO* GetHandleInfo();
SYSTEM_HANDLE_INFO_EX* GetExtendedHandleInfo();
SYSTEM_KERNEL_DEBUGGER_INFO* GetKernelDebuggerInfo();
SYSTEM_PROCESS_INFO* GetProcessInfoByID(HANDLE ProcessId);
SYSTEM_EXTENDED_PROCESS_INFO* GetExtendedProcessInfoByID(HANDLE ProcessId);
SYSTEM_THREAD_INFO* GetThreadInfoByID(SYSTEM_PROCESS_INFO* lpSystemProcessInfo,HANDLE ThreadId);
SYSTEM_EXTENDED_THREAD_INFO* GetExtendedThreadInfoByID(SYSTEM_EXTENDED_PROCESS_INFO* lpSystemProcessInfo,HANDLE ThreadId);
public:
static NTQUERYSYSTEMINFORMATION m_NtQuerySystemInformation;
private:
BYTE* m_QueryData;
DWORD m_QuerySize;
NTSTATUS m_QueryStatus;
};
ProcessQuery.cpp:
void CProcessQuery::Start() // OK
{
this->m_QueryData = 0;
this->m_QuerySize = 0;
this->m_QueryStatus = STATUS_SUCCESS;
}
void CProcessQuery::Close() // OK
{
this->m_QueryData = ((this->m_QueryData==0)?(BYTE*)0:((HeapFree(GetProcessHeap(),0,this->m_QueryData)==0)?(BYTE*)0:(BYTE*)0));
this->m_QuerySize = 0;
this->m_QueryStatus = STATUS_SUCCESS;
}
bool CProcessQuery::Fetch(SYSTEM_INFORMATION_CLASS SysInfoClass,DWORD QuerySize) // OK
{
while(this->m_QueryData != 0 || (this->m_QueryData=(BYTE*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(this->m_QuerySize=((this->m_QuerySize<QuerySize)?QuerySize:this->m_QuerySize)))) != 0)
{
DWORD ReturnLength;
if((this->m_QueryStatus=CProcessQuery::m_NtQuerySystemInformation(SysInfoClass,this->m_QueryData,this->m_QuerySize,&ReturnLength)) == STATUS_INFO_LENGTH_MISMATCH)
{
this->m_QueryData = ((this->m_QueryData==0)?(BYTE*)0:((HeapFree(GetProcessHeap(),0,this->m_QueryData)==0)?(BYTE*)0:(BYTE*)0));
this->m_QuerySize = ReturnLength;
}
else
{
return ((this->m_QueryStatus==STATUS_SUCCESS)?1:0);
}
}
return 0;
}
SYSTEM_HANDLE_INFO* CProcessQuery::GetHandleInfo() // OK
{
return ((SYSTEM_HANDLE_INFO*)this->m_QueryData);
}
SYSTEM_HANDLE_INFO_EX* CProcessQuery::GetExtendedHandleInfo() // OK
{
return ((SYSTEM_HANDLE_INFO_EX*)this->m_QueryData);
}
SYSTEM_KERNEL_DEBUGGER_INFO* CProcessQuery::GetKernelDebuggerInfo() // OK
{
return ((SYSTEM_KERNEL_DEBUGGER_INFO*)this->m_QueryData);
}
SYSTEM_PROCESS_INFO* CProcessQuery::GetProcessInfoByID(HANDLE ProcessId) // OK
{
SYSTEM_PROCESS_INFO* lpSystemProcessInfo = (SYSTEM_PROCESS_INFO*)this->m_QueryData;
while(true)
{
if(lpSystemProcessInfo->UniqueProcessId == ProcessId)
{
return lpSystemProcessInfo;
}
if(lpSystemProcessInfo->NextEntryOffset == 0)
{
break;
}
lpSystemProcessInfo = (SYSTEM_PROCESS_INFO*)((BYTE*)lpSystemProcessInfo+lpSystemProcessInfo->NextEntryOffset);
}
return 0;
}
SYSTEM_EXTENDED_PROCESS_INFO* CProcessQuery::GetExtendedProcessInfoByID(HANDLE ProcessId) // OK
{
SYSTEM_EXTENDED_PROCESS_INFO* lpSystemProcessInfo = (SYSTEM_EXTENDED_PROCESS_INFO*)this->m_QueryData;
while(true)
{
if(lpSystemProcessInfo->UniqueProcessId == ProcessId)
{
return lpSystemProcessInfo;
}
if(lpSystemProcessInfo->NextEntryOffset == 0)
{
break;
}
lpSystemProcessInfo = (SYSTEM_EXTENDED_PROCESS_INFO*)((BYTE*)lpSystemProcessInfo+lpSystemProcessInfo->NextEntryOffset);
}
return 0;
}
SYSTEM_THREAD_INFO* CProcessQuery::GetThreadInfoByID(SYSTEM_PROCESS_INFO* lpSystemProcessInfo,HANDLE ThreadId) // OK
{
SYSTEM_THREAD_INFO* lpSystemThreadInfo = lpSystemProcessInfo->Threads;
for(DWORD n=0;n < lpSystemProcessInfo->NumberOfThreads;n++,lpSystemThreadInfo++)
{
if(lpSystemThreadInfo->ClientId.UniqueThread == ThreadId)
{
return lpSystemThreadInfo;
}
}
return 0;
}
SYSTEM_EXTENDED_THREAD_INFO* CProcessQuery::GetExtendedThreadInfoByID(SYSTEM_EXTENDED_PROCESS_INFO* lpSystemProcessInfo,HANDLE ThreadId) // OK
{
SYSTEM_EXTENDED_THREAD_INFO* lpSystemThreadInfo = lpSystemProcessInfo->Threads;
for(DWORD n=0;n < lpSystemProcessInfo->NumberOfThreads;n++,lpSystemThreadInfo++)
{
if(lpSystemThreadInfo->ThreadInfo.ClientId.UniqueThread == ThreadId)
{
return lpSystemThreadInfo;
}
}
return 0;
}
扫描功能:
bool HANDLE_PROTECTION_INIT() // OK
{
CProcessQuery ProcessQuery;
HANDLE HandleValue = OpenProcess(PROCESS_VM_READ,0,GetCurrentProcessId());
if(ProcessQuery.Fetch(SystemExtendedHandleInformation,sizeof(SYSTEM_HANDLE_INFO_EX)) != 0)
{
SYSTEM_HANDLE_INFO_EX* lpSystemHandleInfo = ProcessQuery.GetExtendedHandleInfo();
if(lpSystemHandleInfo != 0)
{
SYSTEM_HANDLE_ENTRY_INFO_EX* lpSystemHandleEntryInfo = lpSystemHandleInfo->Handles;
if(lpSystemHandleEntryInfo != 0)
{
for(DWORD n=0;n < lpSystemHandleInfo->NumberOfHandles;n++,lpSystemHandleEntryInfo++)
{
if(lpSystemHandleEntryInfo->UniqueProcessId == GetCurrentProcessId() && lpSystemHandleEntryInfo->HandleValue == ((DWORD)HandleValue))
{
HandleProtectionNumber = (DWORD)lpSystemHandleEntryInfo->ObjectTypeIndex;
HandleProtectionObject = (DWORD)lpSystemHandleEntryInfo->Object;
ProcessQuery.Close();
return 1;
}
}
}
}
}
ProcessQuery.Close();
return 0;
}
bool HANDLE_PROTECTION_SCAN() // THIS FUNCTION IS CALLED IN A THREAD EVERY 2000 MS.
{
if(gMemoryGuardSwitch == 0 || (gMemoryGuardNumber & MEMORY_GUARD_NUMBER_HANDLE) == 0)
{
return 1;
}
static CProcessQuery ProcessQuery;
std::map<DWORD,std::vector<DWORD>> HandleProtectionTable;
if(ProcessQuery.Fetch(SystemExtendedHandleInformation,sizeof(SYSTEM_HANDLE_INFO_EX)) != 0)
{
SYSTEM_HANDLE_INFO_EX* lpSystemHandleInfo = ProcessQuery.GetExtendedHandleInfo();
if(lpSystemHandleInfo != 0)
{
SYSTEM_HANDLE_ENTRY_INFO_EX* lpSystemHandleEntryInfo = lpSystemHandleInfo->Handles;
if(lpSystemHandleEntryInfo != 0)
{
for(DWORD n=0;n < lpSystemHandleInfo->NumberOfHandles;n++,lpSystemHandleEntryInfo++)
{
if(lpSystemHandleEntryInfo->UniqueProcessId != GetCurrentProcessId() && lpSystemHandleEntryInfo->ObjectTypeIndex == HandleProtectionNumber && lpSystemHandleEntryInfo->Object == ((LPVOID)HandleProtectionObject) && (lpSystemHandleEntryInfo->GrantedAccess & PROCESS_VM_WRITE) != 0)
{
std::map<DWORD,std::vector<DWORD>>::iterator it = HandleProtectionTable.find(lpSystemHandleEntryInfo->UniqueProcessId);
if(it == HandleProtectionTable.end())
{
HandleProtectionTable.insert(std::pair<DWORD,std::vector<DWORD>>(lpSystemHandleEntryInfo->UniqueProcessId,std::vector<DWORD>(1,lpSystemHandleEntryInfo->HandleValue)));
continue;
}
else
{
if(it->second.size() >= MAX_HANDLE_PROTECTION_COUNT)
{
CGDetect(CLIENT_DISCONNECT_MEMORY_DETECTION, 0, 0);
//CHClientDisconnectSend(CLIENT_DISCONNECT_MEMORY_DETECTION,0,lpSystemHandleEntryInfo->UniqueProcessId);
return 0;
}
else
{
it->second.push_back(lpSystemHandleEntryInfo->HandleValue);
continue;
}
}
}
}
}
}
}
return 1;
}
内存保护结构:
enum eMemoryGuardNumber
{
MEMORY_GUARD_NUMBER_NONE = 0,
MEMORY_GUARD_NUMBER_HANDLE = 1,
MEMORY_GUARD_NUMBER_INJECT = 2,
};
if(IsWindows10OrGreater)
{
DWORD gMemoryGuardNumber = 8;
}
else
{
DWORD gMemoryGuardNumber = 3;
}
好吧,万一对某人有用,问题是 handlecount 如果 w7 与 w10 不同...必须在 w10 中放置最多 12 才能正确使用
我正在处理外部代码,它是一款 MMORPG 游戏的反黑客软件。话虽这么说,代码在一些 Windows 10 个用户中出现崩溃或错误检测(它对 7 和 8.1 总是很好用),问题来自使用 NtQuerySystemInformation 然后比较进程句柄的函数。
感谢任何可以提供帮助或提供提示的人。 我会为你留下密码:
ProcessQuery.h
#pragma once
typedef LONG KPRIORITY;
typedef NTSTATUS(WINAPI*NTQUERYSYSTEMINFORMATION)(SYSTEM_INFORMATION_CLASS,PVOID,ULONG,PULONG);
#define STATUS_SUCCESS ((NTSTATUS)0x00000000)
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004)
#define STATUS_DATA_ERROR ((NTSTATUS)0xC000003E)
#define SystemExtendedProcessInformation ((SYSTEM_INFORMATION_CLASS)57)
#define SystemHandleInformation ((SYSTEM_INFORMATION_CLASS)16)
#define SystemExtendedHandleInformation ((SYSTEM_INFORMATION_CLASS)64)
#define SystemKernelDebuggerInformation ((SYSTEM_INFORMATION_CLASS)35)
enum THREAD_STATE
{
Running = 2,
Waiting = 5,
};
enum KWAIT_REASON
{
Executive = 0,
FreePage = 1,
PageIn = 2,
PoolAllocation = 3,
DelayExecution = 4,
Suspended = 5,
UserRequest = 6,
WrExecutive = 7,
WrFreePage = 8,
WrPageIn = 9,
WrPoolAllocation = 10,
WrDelayExecution = 11,
WrSuspended = 12,
WrUserRequest = 13,
WrEventPair = 14,
WrQueue = 15,
WrLpcReceive = 16,
WrLpcReply = 17,
WrVirtualMemory = 18,
WrPageOut = 19,
WrRendezvous = 20,
Spare2 = 21,
Spare3 = 22,
Spare4 = 23,
Spare5 = 24,
WrCalloutStack = 25,
WrKernel = 26,
WrResource = 27,
WrPushLock = 28,
WrMutex = 29,
WrQuantumEnd = 30,
WrDispatchInt = 31,
WrPreempted = 32,
WrYieldExecution = 33,
WrFastMutex = 34,
WrGuardedMutex = 35,
WrRundown = 36,
MaximumWaitReason = 37,
};
struct CLIENT_ID
{
PVOID UniqueProcess;
PVOID UniqueThread;
};
struct SYSTEM_THREAD_INFO
{
LARGE_INTEGER KernelTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER CreateTime;
ULONG WaitTime;
PVOID StartAddress;
CLIENT_ID ClientId;
KPRIORITY Priority;
LONG BasePriority;
ULONG ContextSwitches;
ULONG ThreadState;
KWAIT_REASON WaitReason;
};
struct SYSTEM_EXTENDED_THREAD_INFO
{
SYSTEM_THREAD_INFO ThreadInfo;
PVOID StackBase;
PVOID StackLimit;
PVOID Win32StartAddress;
PVOID TebAddress; // since VISTA
ULONG Reserved1;
ULONG Reserved2;
ULONG Reserved3;
};
struct SYSTEM_PROCESS_INFO
{
ULONG NextEntryOffset;
ULONG NumberOfThreads;
LARGE_INTEGER WorkingSetPrivateSize; // since VISTA
ULONG HardFaultCount; // since WIN7
ULONG NumberOfThreadsHighWatermark; // since WIN7
ULONGLONG CycleTime; // since WIN7
LARGE_INTEGER CreateTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER KernelTime;
UNICODE_STRING ImageName;
KPRIORITY BasePriority;
HANDLE UniqueProcessId;
HANDLE InheritedFromUniqueProcessId;
ULONG HandleCount;
ULONG SessionId;
ULONG_PTR UniqueProcessKey; // since VISTA (requires SystemExtendedProcessInformation)
SIZE_T PeakVirtualSize;
SIZE_T VirtualSize;
ULONG PageFaultCount;
SIZE_T PeakWorkingSetSize;
SIZE_T WorkingSetSize;
SIZE_T QuotaPeakPagedPoolUsage;
SIZE_T QuotaPagedPoolUsage;
SIZE_T QuotaPeakNonPagedPoolUsage;
SIZE_T QuotaNonPagedPoolUsage;
SIZE_T PagefileUsage;
SIZE_T PeakPagefileUsage;
SIZE_T PrivatePageCount;
LARGE_INTEGER ReadOperationCount;
LARGE_INTEGER WriteOperationCount;
LARGE_INTEGER OtherOperationCount;
LARGE_INTEGER ReadTransferCount;
LARGE_INTEGER WriteTransferCount;
LARGE_INTEGER OtherTransferCount;
SYSTEM_THREAD_INFO Threads[1];
};
struct SYSTEM_EXTENDED_PROCESS_INFO
{
ULONG NextEntryOffset;
ULONG NumberOfThreads;
LARGE_INTEGER WorkingSetPrivateSize; // since VISTA
ULONG HardFaultCount; // since WIN7
ULONG NumberOfThreadsHighWatermark; // since WIN7
ULONGLONG CycleTime; // since WIN7
LARGE_INTEGER CreateTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER KernelTime;
UNICODE_STRING ImageName;
KPRIORITY BasePriority;
HANDLE UniqueProcessId;
HANDLE InheritedFromUniqueProcessId;
ULONG HandleCount;
ULONG SessionId;
ULONG_PTR UniqueProcessKey; // since VISTA (requires SystemExtendedProcessInformation)
SIZE_T PeakVirtualSize;
SIZE_T VirtualSize;
ULONG PageFaultCount;
SIZE_T PeakWorkingSetSize;
SIZE_T WorkingSetSize;
SIZE_T QuotaPeakPagedPoolUsage;
SIZE_T QuotaPagedPoolUsage;
SIZE_T QuotaPeakNonPagedPoolUsage;
SIZE_T QuotaNonPagedPoolUsage;
SIZE_T PagefileUsage;
SIZE_T PeakPagefileUsage;
SIZE_T PrivatePageCount;
LARGE_INTEGER ReadOperationCount;
LARGE_INTEGER WriteOperationCount;
LARGE_INTEGER OtherOperationCount;
LARGE_INTEGER ReadTransferCount;
LARGE_INTEGER WriteTransferCount;
LARGE_INTEGER OtherTransferCount;
SYSTEM_EXTENDED_THREAD_INFO Threads[1];
};
struct SYSTEM_HANDLE_ENTRY_INFO
{
USHORT UniqueProcessId;
USHORT CreatorBackTraceIndex;
UCHAR ObjectTypeIndex;
UCHAR HandleAttributes;
USHORT HandleValue;
PVOID Object;
ULONG GrantedAccess;
};
struct SYSTEM_HANDLE_INFO
{
ULONG NumberOfHandles;
SYSTEM_HANDLE_ENTRY_INFO Handles[1];
};
struct SYSTEM_HANDLE_ENTRY_INFO_EX
{
PVOID Object;
ULONG UniqueProcessId;
ULONG HandleValue;
ULONG GrantedAccess;
USHORT CreatorBackTraceIndex;
USHORT ObjectTypeIndex;
ULONG HandleAttributes;
ULONG Reserved;
};
struct SYSTEM_HANDLE_INFO_EX
{
ULONG NumberOfHandles;
ULONG Reserved;
SYSTEM_HANDLE_ENTRY_INFO_EX Handles[1];
};
struct SYSTEM_KERNEL_DEBUGGER_INFO
{
BOOLEAN DebuggerEnabled;
BOOLEAN DebuggerNotPresent;
};
class CProcessQuery
{
public:
CProcessQuery();
virtual ~CProcessQuery();
void Start();
void Close();
bool Fetch(SYSTEM_INFORMATION_CLASS SysInfoClass,DWORD QuerySize);
SYSTEM_HANDLE_INFO* GetHandleInfo();
SYSTEM_HANDLE_INFO_EX* GetExtendedHandleInfo();
SYSTEM_KERNEL_DEBUGGER_INFO* GetKernelDebuggerInfo();
SYSTEM_PROCESS_INFO* GetProcessInfoByID(HANDLE ProcessId);
SYSTEM_EXTENDED_PROCESS_INFO* GetExtendedProcessInfoByID(HANDLE ProcessId);
SYSTEM_THREAD_INFO* GetThreadInfoByID(SYSTEM_PROCESS_INFO* lpSystemProcessInfo,HANDLE ThreadId);
SYSTEM_EXTENDED_THREAD_INFO* GetExtendedThreadInfoByID(SYSTEM_EXTENDED_PROCESS_INFO* lpSystemProcessInfo,HANDLE ThreadId);
public:
static NTQUERYSYSTEMINFORMATION m_NtQuerySystemInformation;
private:
BYTE* m_QueryData;
DWORD m_QuerySize;
NTSTATUS m_QueryStatus;
};
ProcessQuery.cpp:
void CProcessQuery::Start() // OK
{
this->m_QueryData = 0;
this->m_QuerySize = 0;
this->m_QueryStatus = STATUS_SUCCESS;
}
void CProcessQuery::Close() // OK
{
this->m_QueryData = ((this->m_QueryData==0)?(BYTE*)0:((HeapFree(GetProcessHeap(),0,this->m_QueryData)==0)?(BYTE*)0:(BYTE*)0));
this->m_QuerySize = 0;
this->m_QueryStatus = STATUS_SUCCESS;
}
bool CProcessQuery::Fetch(SYSTEM_INFORMATION_CLASS SysInfoClass,DWORD QuerySize) // OK
{
while(this->m_QueryData != 0 || (this->m_QueryData=(BYTE*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(this->m_QuerySize=((this->m_QuerySize<QuerySize)?QuerySize:this->m_QuerySize)))) != 0)
{
DWORD ReturnLength;
if((this->m_QueryStatus=CProcessQuery::m_NtQuerySystemInformation(SysInfoClass,this->m_QueryData,this->m_QuerySize,&ReturnLength)) == STATUS_INFO_LENGTH_MISMATCH)
{
this->m_QueryData = ((this->m_QueryData==0)?(BYTE*)0:((HeapFree(GetProcessHeap(),0,this->m_QueryData)==0)?(BYTE*)0:(BYTE*)0));
this->m_QuerySize = ReturnLength;
}
else
{
return ((this->m_QueryStatus==STATUS_SUCCESS)?1:0);
}
}
return 0;
}
SYSTEM_HANDLE_INFO* CProcessQuery::GetHandleInfo() // OK
{
return ((SYSTEM_HANDLE_INFO*)this->m_QueryData);
}
SYSTEM_HANDLE_INFO_EX* CProcessQuery::GetExtendedHandleInfo() // OK
{
return ((SYSTEM_HANDLE_INFO_EX*)this->m_QueryData);
}
SYSTEM_KERNEL_DEBUGGER_INFO* CProcessQuery::GetKernelDebuggerInfo() // OK
{
return ((SYSTEM_KERNEL_DEBUGGER_INFO*)this->m_QueryData);
}
SYSTEM_PROCESS_INFO* CProcessQuery::GetProcessInfoByID(HANDLE ProcessId) // OK
{
SYSTEM_PROCESS_INFO* lpSystemProcessInfo = (SYSTEM_PROCESS_INFO*)this->m_QueryData;
while(true)
{
if(lpSystemProcessInfo->UniqueProcessId == ProcessId)
{
return lpSystemProcessInfo;
}
if(lpSystemProcessInfo->NextEntryOffset == 0)
{
break;
}
lpSystemProcessInfo = (SYSTEM_PROCESS_INFO*)((BYTE*)lpSystemProcessInfo+lpSystemProcessInfo->NextEntryOffset);
}
return 0;
}
SYSTEM_EXTENDED_PROCESS_INFO* CProcessQuery::GetExtendedProcessInfoByID(HANDLE ProcessId) // OK
{
SYSTEM_EXTENDED_PROCESS_INFO* lpSystemProcessInfo = (SYSTEM_EXTENDED_PROCESS_INFO*)this->m_QueryData;
while(true)
{
if(lpSystemProcessInfo->UniqueProcessId == ProcessId)
{
return lpSystemProcessInfo;
}
if(lpSystemProcessInfo->NextEntryOffset == 0)
{
break;
}
lpSystemProcessInfo = (SYSTEM_EXTENDED_PROCESS_INFO*)((BYTE*)lpSystemProcessInfo+lpSystemProcessInfo->NextEntryOffset);
}
return 0;
}
SYSTEM_THREAD_INFO* CProcessQuery::GetThreadInfoByID(SYSTEM_PROCESS_INFO* lpSystemProcessInfo,HANDLE ThreadId) // OK
{
SYSTEM_THREAD_INFO* lpSystemThreadInfo = lpSystemProcessInfo->Threads;
for(DWORD n=0;n < lpSystemProcessInfo->NumberOfThreads;n++,lpSystemThreadInfo++)
{
if(lpSystemThreadInfo->ClientId.UniqueThread == ThreadId)
{
return lpSystemThreadInfo;
}
}
return 0;
}
SYSTEM_EXTENDED_THREAD_INFO* CProcessQuery::GetExtendedThreadInfoByID(SYSTEM_EXTENDED_PROCESS_INFO* lpSystemProcessInfo,HANDLE ThreadId) // OK
{
SYSTEM_EXTENDED_THREAD_INFO* lpSystemThreadInfo = lpSystemProcessInfo->Threads;
for(DWORD n=0;n < lpSystemProcessInfo->NumberOfThreads;n++,lpSystemThreadInfo++)
{
if(lpSystemThreadInfo->ThreadInfo.ClientId.UniqueThread == ThreadId)
{
return lpSystemThreadInfo;
}
}
return 0;
}
扫描功能:
bool HANDLE_PROTECTION_INIT() // OK
{
CProcessQuery ProcessQuery;
HANDLE HandleValue = OpenProcess(PROCESS_VM_READ,0,GetCurrentProcessId());
if(ProcessQuery.Fetch(SystemExtendedHandleInformation,sizeof(SYSTEM_HANDLE_INFO_EX)) != 0)
{
SYSTEM_HANDLE_INFO_EX* lpSystemHandleInfo = ProcessQuery.GetExtendedHandleInfo();
if(lpSystemHandleInfo != 0)
{
SYSTEM_HANDLE_ENTRY_INFO_EX* lpSystemHandleEntryInfo = lpSystemHandleInfo->Handles;
if(lpSystemHandleEntryInfo != 0)
{
for(DWORD n=0;n < lpSystemHandleInfo->NumberOfHandles;n++,lpSystemHandleEntryInfo++)
{
if(lpSystemHandleEntryInfo->UniqueProcessId == GetCurrentProcessId() && lpSystemHandleEntryInfo->HandleValue == ((DWORD)HandleValue))
{
HandleProtectionNumber = (DWORD)lpSystemHandleEntryInfo->ObjectTypeIndex;
HandleProtectionObject = (DWORD)lpSystemHandleEntryInfo->Object;
ProcessQuery.Close();
return 1;
}
}
}
}
}
ProcessQuery.Close();
return 0;
}
bool HANDLE_PROTECTION_SCAN() // THIS FUNCTION IS CALLED IN A THREAD EVERY 2000 MS.
{
if(gMemoryGuardSwitch == 0 || (gMemoryGuardNumber & MEMORY_GUARD_NUMBER_HANDLE) == 0)
{
return 1;
}
static CProcessQuery ProcessQuery;
std::map<DWORD,std::vector<DWORD>> HandleProtectionTable;
if(ProcessQuery.Fetch(SystemExtendedHandleInformation,sizeof(SYSTEM_HANDLE_INFO_EX)) != 0)
{
SYSTEM_HANDLE_INFO_EX* lpSystemHandleInfo = ProcessQuery.GetExtendedHandleInfo();
if(lpSystemHandleInfo != 0)
{
SYSTEM_HANDLE_ENTRY_INFO_EX* lpSystemHandleEntryInfo = lpSystemHandleInfo->Handles;
if(lpSystemHandleEntryInfo != 0)
{
for(DWORD n=0;n < lpSystemHandleInfo->NumberOfHandles;n++,lpSystemHandleEntryInfo++)
{
if(lpSystemHandleEntryInfo->UniqueProcessId != GetCurrentProcessId() && lpSystemHandleEntryInfo->ObjectTypeIndex == HandleProtectionNumber && lpSystemHandleEntryInfo->Object == ((LPVOID)HandleProtectionObject) && (lpSystemHandleEntryInfo->GrantedAccess & PROCESS_VM_WRITE) != 0)
{
std::map<DWORD,std::vector<DWORD>>::iterator it = HandleProtectionTable.find(lpSystemHandleEntryInfo->UniqueProcessId);
if(it == HandleProtectionTable.end())
{
HandleProtectionTable.insert(std::pair<DWORD,std::vector<DWORD>>(lpSystemHandleEntryInfo->UniqueProcessId,std::vector<DWORD>(1,lpSystemHandleEntryInfo->HandleValue)));
continue;
}
else
{
if(it->second.size() >= MAX_HANDLE_PROTECTION_COUNT)
{
CGDetect(CLIENT_DISCONNECT_MEMORY_DETECTION, 0, 0);
//CHClientDisconnectSend(CLIENT_DISCONNECT_MEMORY_DETECTION,0,lpSystemHandleEntryInfo->UniqueProcessId);
return 0;
}
else
{
it->second.push_back(lpSystemHandleEntryInfo->HandleValue);
continue;
}
}
}
}
}
}
}
return 1;
}
内存保护结构:
enum eMemoryGuardNumber
{
MEMORY_GUARD_NUMBER_NONE = 0,
MEMORY_GUARD_NUMBER_HANDLE = 1,
MEMORY_GUARD_NUMBER_INJECT = 2,
};
if(IsWindows10OrGreater)
{
DWORD gMemoryGuardNumber = 8;
}
else
{
DWORD gMemoryGuardNumber = 3;
}
好吧,万一对某人有用,问题是 handlecount 如果 w7 与 w10 不同...必须在 w10 中放置最多 12 才能正确使用