Skip to content
This repository was archived by the owner on Jan 28, 2022. It is now read-only.

Commit 73f1443

Browse files
committed
添加 CM2EnumProcess 迭代器
1 parent 26c7c28 commit 73f1443

File tree

2 files changed

+140
-7
lines changed

2 files changed

+140
-7
lines changed

Changelog.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
M2-SDK 修订日志(简体中文)
22
M2-SDK Changelog (Simplified Chinese)
33
===============================================================================
4-
M2-SDK 1.3 (2017-05-28)
4+
M2-SDK 1.3 (2017-06-02)
55
- 修复解决方案文件
66
- 添加 SuGetCurrentProcessSessionID 函数
7+
- 添加 CM2EnumProcess 迭代器
78

89
M2-SDK 1.2 (2017-04-28)
910
- M2.PHNT.msg 改名为 M2.Windows.PHNTPermission.msg

M2.NSudo.h

Lines changed: 138 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1724,6 +1724,140 @@ extern "C" {
17241724
ULONG_PTR pTemp = 0;
17251725
};
17261726

1727+
1728+
#if _MSC_VER >= 1200
1729+
#pragma warning(push)
1730+
#pragma warning(disable:4355) // "this": 用于基成员初始值设定项列表
1731+
#endif
1732+
1733+
/*
1734+
进程列表遍历迭代器
1735+
Iterator for enumerate the process list
1736+
1737+
用法 Usage
1738+
for (auto pSPI : CM2EnumProcess(status)) { }
1739+
1740+
status 是初始化遍历返回值(可选)
1741+
status is the return value for initialization (Optional)
1742+
*/
1743+
class CM2EnumProcess
1744+
{
1745+
public:
1746+
class CM2EnumProcessIterator
1747+
{
1748+
private:
1749+
CM2EnumProcess* m_EnumProcess;
1750+
1751+
public:
1752+
FORCEINLINE CM2EnumProcessIterator(
1753+
_In_ CM2EnumProcess* FindFile) :
1754+
m_EnumProcess(FindFile)
1755+
{
1756+
1757+
}
1758+
1759+
FORCEINLINE ~CM2EnumProcessIterator()
1760+
{
1761+
1762+
}
1763+
1764+
FORCEINLINE void operator++()
1765+
{
1766+
// 如果pSPI和下个结构偏移都存在,则继续循环,否则清零
1767+
if (m_EnumProcess->pSPI && m_EnumProcess->pSPI->NextEntryOffset)
1768+
{
1769+
ULONG_PTR NextSPI = reinterpret_cast<ULONG_PTR>(m_EnumProcess->pSPI);
1770+
NextSPI += m_EnumProcess->pSPI->NextEntryOffset;
1771+
m_EnumProcess->pSPI = reinterpret_cast<PSYSTEM_PROCESS_INFORMATION>(NextSPI);
1772+
}
1773+
else
1774+
{
1775+
m_EnumProcess->pSPI = nullptr;
1776+
}
1777+
}
1778+
1779+
// 根据迭代器循环特性,使用不等于操作符遍历目录
1780+
FORCEINLINE bool operator!=(const CM2EnumProcessIterator& Item)
1781+
{
1782+
UNREFERENCED_PARAMETER(Item);
1783+
return (m_EnumProcess->pSPI != nullptr);
1784+
}
1785+
1786+
FORCEINLINE PSYSTEM_PROCESS_INFORMATION operator*()
1787+
{
1788+
return m_EnumProcess->pSPI;
1789+
}
1790+
};
1791+
1792+
private:
1793+
CM2EnumProcessIterator Iterator;
1794+
PVOID lpBuffer;
1795+
PSYSTEM_PROCESS_INFORMATION pSPI;
1796+
1797+
public:
1798+
// 初始化文件遍历, 不内联考虑到大量使用本迭代器时实现函数复用以节约空间
1799+
DECLSPEC_NOINLINE CM2EnumProcess(
1800+
_Out_ NTSTATUS* InitStatus = nullptr) :
1801+
Iterator(this),
1802+
lpBuffer(nullptr),
1803+
pSPI(nullptr)
1804+
1805+
{
1806+
NTSTATUS status = STATUS_SUCCESS;
1807+
DWORD dwLength = 0;
1808+
1809+
do
1810+
{
1811+
// 获取进程信息大小
1812+
status = NtQuerySystemInformation(
1813+
SystemProcessInformation,
1814+
nullptr,
1815+
0,
1816+
&dwLength);
1817+
if (status != STATUS_INFO_LENGTH_MISMATCH) break;
1818+
1819+
// 为令牌信息分配内存,如果失败则返回
1820+
status = M2HeapAlloc(
1821+
dwLength,
1822+
lpBuffer);
1823+
if (!NT_SUCCESS(status)) break;
1824+
1825+
// 获取进程信息
1826+
status = NtQuerySystemInformation(
1827+
SystemProcessInformation,
1828+
lpBuffer,
1829+
dwLength,
1830+
&dwLength);
1831+
if (!NT_SUCCESS(status)) break;
1832+
1833+
// 设置遍历开始地址
1834+
pSPI = reinterpret_cast<PSYSTEM_PROCESS_INFORMATION>(lpBuffer);
1835+
1836+
} while (false);
1837+
1838+
if (InitStatus) *InitStatus = status;
1839+
}
1840+
1841+
FORCEINLINE ~CM2EnumProcess()
1842+
{
1843+
if (lpBuffer) M2HeapFree(lpBuffer);
1844+
}
1845+
1846+
FORCEINLINE CM2EnumProcessIterator& begin()
1847+
{
1848+
return Iterator;
1849+
}
1850+
1851+
FORCEINLINE CM2EnumProcessIterator& end()
1852+
{
1853+
return Iterator;
1854+
}
1855+
};
1856+
1857+
#if _MSC_VER >= 1200
1858+
#pragma warning(pop)
1859+
#endif
1860+
17271861
/*
17281862
SuGetSystemTokenCopy函数获取一个当前会话SYSTEM用户令牌的副本。
17291863
The SuGetSystemTokenCopy function obtains a copy of current session SYSTEM
@@ -1739,21 +1873,16 @@ extern "C" {
17391873
NTSTATUS status = STATUS_SUCCESS;
17401874
DWORD dwWinLogonPID = (DWORD)-1;
17411875
DWORD dwSessionID = (DWORD)-1;
1742-
PSYSTEM_PROCESS_INFORMATION pSPI = nullptr;
17431876
HANDLE hProcessToken = nullptr;
17441877

17451878
do
17461879
{
1747-
// 初始化进程遍历
1748-
CSuProcessSnapshot Snapshot(&status);
1749-
if (!NT_SUCCESS(status)) break;
1750-
17511880
// 获取当前进程令牌会话ID
17521881
status = SuGetCurrentProcessSessionID(&dwSessionID);
17531882
if (!NT_SUCCESS(status)) break;
17541883

17551884
// 遍历进程寻找winlogon进程并获取PID
1756-
while (Snapshot.Next(&pSPI))
1885+
for (auto pSPI : CM2EnumProcess(&status))
17571886
{
17581887
if (pSPI->SessionId != dwSessionID) continue;
17591888
if (pSPI->ImageName.Buffer == nullptr) continue;
@@ -1765,6 +1894,9 @@ extern "C" {
17651894
}
17661895
}
17671896

1897+
// 如果初始化进程遍历失败,则返回错误
1898+
if (!NT_SUCCESS(status)) break;
1899+
17681900
// 如果没找到进程,则返回错误
17691901
if (dwWinLogonPID == -1)
17701902
{

0 commit comments

Comments
 (0)