我装Win8后,就在那个任务管理器发现一个奇怪的东西“操作系统上下文”,实话不懂这个啥意思,不过貌似挺有趣的,就逆了一下,发现是NtQueryInformationProcess然后从PEB里面拿的,于是又Google了一下,发现国外已经有人折腾出来了,于是把各种结论转换成代码,如下:
Private Const ID_WIN8_CONTEXT = "{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" Private Const ID_WIN7_CONTEXT = "{35138b9a-5d96-fbd-8e2d-a2440225f93a}" Private Const ID_VISTA_CONTEXT = "{e2011457-1546-43c5-a5fe-008deee3d3f0}" Private Const ID_XP_CONTEXT = "{beb1b341-6837-4c83-8366-2b451e7ce69b}" Private Type GUID Data1 As Long Data2 As Integer Data3 As Integer Data4(7) As Byte End Type Private Declare Function GetModuleHandleW& Lib "kernel32" (ByVal lpModuleName&) Private Declare Function GetProcAddress& Lib "kernel32" (ByVal hModule&, ByVal lpProcName$) Private Declare Function OpenProcess& Lib "kernel32" (ByVal dwDesiredAccess&, ByVal bInheritHandle As Boolean, ByVal dwProcessId&) Private Declare Function ReadProcessMemory& Lib "kernel32" (ByVal hProcess&, ByVal lpBaseAddress&, ByVal lpBuffer&, ByVal nSize&, ByRef lpNumberOfBytesRead&) Private Declare Function NtQueryInformationProcess& Lib "ntdll" (ByVal ProcessHandle&, ByVal ProcessInformationClass&, ByVal ProcessInformation&, ByVal ProcessInformationLength&, ByRef ReturnLength&) Private Declare Function CloseHandle& Lib "kernel32" (ByVal hObject&) Private Function IsWindows8() As Boolean IsWindows8 = CBool(GetProcAddress(GetModuleHandleW(StrPtr("kernel32.dll")), "GetPackageFullName")) End Function Private Function GetProcessPeb&(ByVal hProcess&) Dim pbi&(5) If NtQueryInformationProcess(hProcess, 0, VarPtr(pbi(0)), 24, 0) = 0 Then GetProcessPeb = pbi(1) End Function Private Function ReadShimOrContextDataPointer&(ByVal hProcess&) Dim pDataOffset& pDataOffset = IIf(IsWindows8, &H1E8, &H238) Dim pPointer& ReadProcessMemory hProcess, GetProcessPeb(hProcess) + pDataOffset, VarPtr(pPointer), 4, 0 ReadShimOrContextDataPointer = pPointer End Function Private Sub ReadOsContextUUID(ByVal hProcess&, ByVal lpPointer&, ByVal pID&) Dim pDataOffset& pDataOffset = IIf(IsWindows8, &H7F8, &H20) ReadProcessMemory hProcess, lpPointer + pDataOffset, pID, 16, 0 End Sub Private Function QueryOsContextStringByUUID(UUID As GUID) Select Case UUID.Data1 Case &H4A2F28E3: QueryOsContextStringByUUID = "Windows 8" Case &H35138B9A: QueryOsContextStringByUUID = "Windows 7" Case &HE2011457: QueryOsContextStringByUUID = "Windows Vista" Case &HBEB1B341: QueryOsContextStringByUUID = "Windows XP" Case Else: QueryOsContextStringByUUID = "[Unknown]" End Select End Function Private Sub Form_Load() Dim hProcess&, uid As GUID hProcess = OpenProcess(2035711, False, 2660)'//改成你的PID ReadOsContextUUID hProcess, ReadShimOrContextDataPointer(hProcess), VarPtr(uid) MsgBox QueryOsContextStringByUUID(uid) CloseHandle hProcess End Sub
理论上在Win7也能获取到上下文。