@@ -1724,6 +1724,140 @@ extern "C" {
1724
1724
ULONG_PTR pTemp = 0 ;
1725
1725
};
1726
1726
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
+
1727
1861
/*
1728
1862
SuGetSystemTokenCopy函数获取一个当前会话SYSTEM用户令牌的副本。
1729
1863
The SuGetSystemTokenCopy function obtains a copy of current session SYSTEM
@@ -1739,21 +1873,16 @@ extern "C" {
1739
1873
NTSTATUS status = STATUS_SUCCESS;
1740
1874
DWORD dwWinLogonPID = (DWORD)-1 ;
1741
1875
DWORD dwSessionID = (DWORD)-1 ;
1742
- PSYSTEM_PROCESS_INFORMATION pSPI = nullptr ;
1743
1876
HANDLE hProcessToken = nullptr ;
1744
1877
1745
1878
do
1746
1879
{
1747
- // 初始化进程遍历
1748
- CSuProcessSnapshot Snapshot (&status);
1749
- if (!NT_SUCCESS (status)) break ;
1750
-
1751
1880
// 获取当前进程令牌会话ID
1752
1881
status = SuGetCurrentProcessSessionID (&dwSessionID);
1753
1882
if (!NT_SUCCESS (status)) break ;
1754
1883
1755
1884
// 遍历进程寻找winlogon进程并获取PID
1756
- while (Snapshot. Next (&pSPI ))
1885
+ for ( auto pSPI : CM2EnumProcess (&status ))
1757
1886
{
1758
1887
if (pSPI->SessionId != dwSessionID) continue ;
1759
1888
if (pSPI->ImageName .Buffer == nullptr ) continue ;
@@ -1765,6 +1894,9 @@ extern "C" {
1765
1894
}
1766
1895
}
1767
1896
1897
+ // 如果初始化进程遍历失败,则返回错误
1898
+ if (!NT_SUCCESS (status)) break ;
1899
+
1768
1900
// 如果没找到进程,则返回错误
1769
1901
if (dwWinLogonPID == -1 )
1770
1902
{
0 commit comments