From 314cd2b862941c666040ad5425c883ff2d1d2dbe Mon Sep 17 00:00:00 2001 From: hakril Date: Sat, 18 Jan 2025 18:08:20 +0100 Subject: [PATCH] More arm exploration of api responses --- .../definitions/functions/sysinfo.txt | 8 ++ .../definitions/structures/system_info.txt | 19 ++++ docs/source/winfuncs_generated.rst | 50 ++++++--- docs/source/winstructs_generated.rst | 61 ++++++++++ tests/test_syswow.py | 7 ++ windows/generated_def/meta.py | 5 + windows/generated_def/winfuncs.py | 10 ++ windows/generated_def/winstructs.py | 106 ++++++++++++++++++ windows/utils/winutils.py | 8 ++ windows/winproxy/apis/kernel32.py | 8 ++ 10 files changed, 268 insertions(+), 14 deletions(-) diff --git a/ctypes_generation/definitions/functions/sysinfo.txt b/ctypes_generation/definitions/functions/sysinfo.txt index dc3ed30..e76183e 100644 --- a/ctypes_generation/definitions/functions/sysinfo.txt +++ b/ctypes_generation/definitions/functions/sysinfo.txt @@ -59,4 +59,12 @@ BOOL LookupAccountNameW( LPWSTR ReferencedDomainName, LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse +); + +PVOID GetNativeSystemInfo( + [out] LPSYSTEM_INFO lpSystemInfo +); + +PVOID GetSystemInfo( + [out] LPSYSTEM_INFO lpSystemInfo ); \ No newline at end of file diff --git a/ctypes_generation/definitions/structures/system_info.txt b/ctypes_generation/definitions/structures/system_info.txt index 53d8570..3516d6d 100644 --- a/ctypes_generation/definitions/structures/system_info.txt +++ b/ctypes_generation/definitions/structures/system_info.txt @@ -67,3 +67,22 @@ typedef enum _COMPUTER_NAME_FORMAT { ComputerNamePhysicalDnsFullyQualified, ComputerNameMax } COMPUTER_NAME_FORMAT; + +typedef struct _SYSTEM_INFO { + union { + DWORD dwOemId; + struct { + WORD wProcessorArchitecture; + WORD wReserved; + } DUMMYSTRUCTNAME; + } DUMMYUNIONNAME; + DWORD dwPageSize; + LPVOID lpMinimumApplicationAddress; + LPVOID lpMaximumApplicationAddress; + DWORD_PTR dwActiveProcessorMask; + DWORD dwNumberOfProcessors; + DWORD dwProcessorType; + DWORD dwAllocationGranularity; + WORD wProcessorLevel; + WORD wProcessorRevision; +} SYSTEM_INFO, *LPSYSTEM_INFO; \ No newline at end of file diff --git a/docs/source/winfuncs_generated.rst b/docs/source/winfuncs_generated.rst index bc279ee..2a6706f 100644 --- a/docs/source/winfuncs_generated.rst +++ b/docs/source/winfuncs_generated.rst @@ -1214,6 +1214,42 @@ Functions .. function:: LookupAccountNameW(lpSystemName, lpAccountName, Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse) +.. function:: GetNativeSystemInfo(lpSystemInfo) + +.. function:: GetSystemInfo(lpSystemInfo) + +.. function:: IsWow64Process(hProcess, Wow64Process) + +.. function:: IsWow64Process2(hProcess, pProcessMachine, pNativeMachine) + +.. function:: IsWow64GuestMachineSupported(WowGuestMachine, MachineIsSupported) + +.. function:: GetSystemWow64DirectoryA(lpBuffer, uSize) + +.. function:: GetSystemWow64DirectoryW(lpBuffer, uSize) + +.. function:: GetSystemWow64Directory2A(lpBuffer, uSize, ImageFileMachineType) + +.. function:: GetSystemWow64Directory2W(lpBuffer, uSize, ImageFileMachineType) + +.. function:: Wow64DisableWow64FsRedirection(OldValue) + +.. function:: Wow64EnableWow64FsRedirection(Wow64FsEnableRedirection) + +.. function:: Wow64RevertWow64FsRedirection(OlValue) + +.. function:: Wow64GetThreadContext(hThread, lpContext) + +.. function:: Wow64SetThreadContext(hThread, lpContext) + +.. function:: Wow64SetThreadDefaultGuestMachine(Machine) + +.. function:: Wow64SuspendThread(hThread) + +.. function:: NtWow64ReadVirtualMemory64(hProcess, lpBaseAddress, lpBuffer, nSize, lpNumberOfBytesRead) + +.. function:: NtWow64WriteVirtualMemory64(hProcess, lpBaseAddress, lpBuffer, nSize, lpNumberOfBytesWritten) + .. function:: FileTimeToSystemTime(lpFileTime, lpSystemTime) .. function:: SystemTimeToFileTime(lpSystemTime, lpFileTime) @@ -1370,12 +1406,8 @@ Functions .. function:: ReadProcessMemory(hProcess, lpBaseAddress, lpBuffer, nSize, lpNumberOfBytesRead) -.. function:: NtWow64ReadVirtualMemory64(hProcess, lpBaseAddress, lpBuffer, nSize, lpNumberOfBytesRead) - .. function:: WriteProcessMemory(hProcess, lpBaseAddress, lpBuffer, nSize, lpNumberOfBytesWritten) -.. function:: NtWow64WriteVirtualMemory64(hProcess, lpBaseAddress, lpBuffer, nSize, lpNumberOfBytesWritten) - .. function:: GetCurrentProcess() .. function:: CreateFileA(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile) @@ -1468,14 +1500,6 @@ Functions .. function:: DeviceIoControl(hDevice, dwIoControlCode, lpInBuffer, nInBufferSize, lpOutBuffer, nOutBufferSize, lpBytesReturned, lpOverlapped) -.. function:: Wow64DisableWow64FsRedirection(OldValue) - -.. function:: Wow64RevertWow64FsRedirection(OldValue) - -.. function:: Wow64EnableWow64FsRedirection(Wow64FsEnableRedirection) - -.. function:: Wow64GetThreadContext(hThread, lpContext) - .. function:: SetConsoleCtrlHandler(HandlerRoutine, Add) .. function:: GlobalAlloc(uFlags, dwBytes) @@ -1530,8 +1554,6 @@ Functions .. function:: GetProcessId(Process) -.. function:: Wow64SetThreadContext(hThread, lpContext) - .. function:: GetMappedFileNameW(hProcess, lpv, lpFilename, nSize) .. function:: GetMappedFileNameA(hProcess, lpv, lpFilename, nSize) diff --git a/docs/source/winstructs_generated.rst b/docs/source/winstructs_generated.rst index 9abcbe3..86e7fb2 100644 --- a/docs/source/winstructs_generated.rst +++ b/docs/source/winstructs_generated.rst @@ -25769,6 +25769,67 @@ _EXPLICIT_ACCESS_W :class:`TRUSTEE_W` +_SYSTEM_INFO +'''''''''''' +.. class:: LPSYSTEM_INFO + + Pointer to :class:`_SYSTEM_INFO` + +.. class:: SYSTEM_INFO + + Alias for :class:`_SYSTEM_INFO` + +.. class:: _SYSTEM_INFO + + .. attribute:: DUMMYUNIONNAME + + :class:`_ANON__SYSTEM_INFO_SUB_UNION_1` + + + .. attribute:: dwPageSize + + :class:`DWORD` + + + .. attribute:: lpMinimumApplicationAddress + + :class:`LPVOID` + + + .. attribute:: lpMaximumApplicationAddress + + :class:`LPVOID` + + + .. attribute:: dwActiveProcessorMask + + :class:`DWORD_PTR` + + + .. attribute:: dwNumberOfProcessors + + :class:`DWORD` + + + .. attribute:: dwProcessorType + + :class:`DWORD` + + + .. attribute:: dwAllocationGranularity + + :class:`DWORD` + + + .. attribute:: wProcessorLevel + + :class:`WORD` + + + .. attribute:: wProcessorRevision + + :class:`WORD` + _TIME_ZONE_INFORMATION '''''''''''''''''''''' .. class:: LPTIME_ZONE_INFORMATION diff --git a/tests/test_syswow.py b/tests/test_syswow.py index c19c809..3e614af 100644 --- a/tests/test_syswow.py +++ b/tests/test_syswow.py @@ -22,6 +22,13 @@ def test_print_syswow_state(): print(f"{env['PROCESSOR_ARCHITECTURE']=}") print(f"{env.get('PROCESSOR_ARCHITEW6432')=}") + print("") + print("GetSystemInfo") + windows.utils.sprint(windows.utils.get_system_info(native=False), name="SystemInfo") + print("") + print("GetNativeSystemInfo") + windows.utils.sprint(windows.utils.get_system_info(native=True), name="NativeSystemInfo") + @process_syswow_only class TestSyswowCurrentProcess(object): def test_exec_syswow(self): diff --git a/windows/generated_def/meta.py b/windows/generated_def/meta.py index 30b6a0a..dcb35c4 100644 --- a/windows/generated_def/meta.py +++ b/windows/generated_def/meta.py @@ -12641,6 +12641,7 @@ structs = {'ACCESS_ALLOWED_ACE', 'LPSTARTUPINFOEXW', 'LPSTARTUPINFOW', 'LPSYSTEMTIME', +'LPSYSTEM_INFO', 'LPTHREADENTRY32', 'LPTIME_ZONE_INFORMATION', 'LPTLIBATTR', @@ -13459,6 +13460,7 @@ structs = {'ACCESS_ALLOWED_ACE', 'SYSTEM_HANDLE64', 'SYSTEM_HANDLE_INFORMATION', 'SYSTEM_HANDLE_INFORMATION64', +'SYSTEM_INFO', 'SYSTEM_MANDATORY_LABEL_ACE', 'SYSTEM_MODULE32', 'SYSTEM_MODULE64', @@ -14038,6 +14040,7 @@ structs = {'ACCESS_ALLOWED_ACE', '_SYSTEM_HANDLE64', '_SYSTEM_HANDLE_INFORMATION', '_SYSTEM_HANDLE_INFORMATION64', +'_SYSTEM_INFO', '_SYSTEM_MANDATORY_LABEL_ACE', '_SYSTEM_MODULE32', '_SYSTEM_MODULE64', @@ -14803,6 +14806,7 @@ functions = {'AccessCheck', 'GetModuleHandleW', 'GetNamedSecurityInfoA', 'GetNamedSecurityInfoW', +'GetNativeSystemInfo', 'GetNumberOfEventLogRecords', 'GetOverlappedResult', 'GetParent', @@ -14839,6 +14843,7 @@ functions = {'AccessCheck', 'GetSidSubAuthorityCount', 'GetStdHandle', 'GetStringConditionFromBinary', +'GetSystemInfo', 'GetSystemMetrics', 'GetSystemTime', 'GetSystemTimeAsFileTime', diff --git a/windows/generated_def/winfuncs.py b/windows/generated_def/winfuncs.py index e98da0c..79e8135 100644 --- a/windows/generated_def/winfuncs.py +++ b/windows/generated_def/winfuncs.py @@ -3030,6 +3030,16 @@ LookupAccountNameAParams = ((1, 'lpSystemName'), (1, 'lpAccountName'), (1, 'Sid' LookupAccountNameWPrototype = WINFUNCTYPE(BOOL, LPCWSTR, LPCWSTR, PSID, LPDWORD, LPWSTR, LPDWORD, PSID_NAME_USE) LookupAccountNameWParams = ((1, 'lpSystemName'), (1, 'lpAccountName'), (1, 'Sid'), (1, 'cbSid'), (1, 'ReferencedDomainName'), (1, 'cchReferencedDomainName'), (1, 'peUse')) +#def GetNativeSystemInfo(lpSystemInfo): +# return GetNativeSystemInfo.ctypes_function(lpSystemInfo) +GetNativeSystemInfoPrototype = WINFUNCTYPE(PVOID, LPSYSTEM_INFO) +GetNativeSystemInfoParams = ((1, 'lpSystemInfo'),) + +#def GetSystemInfo(lpSystemInfo): +# return GetSystemInfo.ctypes_function(lpSystemInfo) +GetSystemInfoPrototype = WINFUNCTYPE(PVOID, LPSYSTEM_INFO) +GetSystemInfoParams = ((1, 'lpSystemInfo'),) + #def IsWow64Process(hProcess, Wow64Process): # return IsWow64Process.ctypes_function(hProcess, Wow64Process) IsWow64ProcessPrototype = WINFUNCTYPE(BOOL, HANDLE, PBOOL) diff --git a/windows/generated_def/winstructs.py b/windows/generated_def/winstructs.py index 90a373a..49179ca 100644 --- a/windows/generated_def/winstructs.py +++ b/windows/generated_def/winstructs.py @@ -11227,6 +11227,112 @@ EXPLICIT_ACCESS_W = _EXPLICIT_ACCESS_W PEXPLICIT_ACCESSW = POINTER(_EXPLICIT_ACCESS_W) PEXPLICIT_ACCESS_W = POINTER(_EXPLICIT_ACCESS_W) +ComputerNameNetBIOS = EnumValue("_COMPUTER_NAME_FORMAT", "ComputerNameNetBIOS", 0x0) +ComputerNameDnsHostname = EnumValue("_COMPUTER_NAME_FORMAT", "ComputerNameDnsHostname", 0x1) +ComputerNameDnsDomain = EnumValue("_COMPUTER_NAME_FORMAT", "ComputerNameDnsDomain", 0x2) +ComputerNameDnsFullyQualified = EnumValue("_COMPUTER_NAME_FORMAT", "ComputerNameDnsFullyQualified", 0x3) +ComputerNamePhysicalNetBIOS = EnumValue("_COMPUTER_NAME_FORMAT", "ComputerNamePhysicalNetBIOS", 0x4) +ComputerNamePhysicalDnsHostname = EnumValue("_COMPUTER_NAME_FORMAT", "ComputerNamePhysicalDnsHostname", 0x5) +ComputerNamePhysicalDnsDomain = EnumValue("_COMPUTER_NAME_FORMAT", "ComputerNamePhysicalDnsDomain", 0x6) +ComputerNamePhysicalDnsFullyQualified = EnumValue("_COMPUTER_NAME_FORMAT", "ComputerNamePhysicalDnsFullyQualified", 0x7) +ComputerNameMax = EnumValue("_COMPUTER_NAME_FORMAT", "ComputerNameMax", 0x8) +class _COMPUTER_NAME_FORMAT(EnumType): + values = [ComputerNameNetBIOS, ComputerNameDnsHostname, ComputerNameDnsDomain, ComputerNameDnsFullyQualified, ComputerNamePhysicalNetBIOS, ComputerNamePhysicalDnsHostname, ComputerNamePhysicalDnsDomain, ComputerNamePhysicalDnsFullyQualified, ComputerNameMax] + mapper = FlagMapper(*values) +COMPUTER_NAME_FORMAT = _COMPUTER_NAME_FORMAT + + +class _SYSTEM_PROCESS_INFORMATION(Structure): + _fields_ = [ + ("NextEntryOffset", ULONG), + ("NumberOfThreads", ULONG), + ("Reserved1", BYTE * (24)), + ("CreateTime", LARGE_INTEGER), + ("UserTime", LARGE_INTEGER), + ("KernelTime", LARGE_INTEGER), + ("ImageName", UNICODE_STRING), + ("BasePriority", LONG), + ("UniqueProcessId", HANDLE), + ("InheritedFromUniqueProcessId", PVOID), + ("HandleCount", ULONG), + ("Reserved4", BYTE * (4)), + ("Reserved5", PVOID * (1)), + ("PeakVirtualSize", PVOID), + ("VirtualSize", PVOID), + ("PageFaultCount", PVOID), + ("PeakWorkingSetSize", PVOID), + ("WorkingSetSize", PVOID), + ("QuotaPeakPagedPoolUsage", PVOID), + ("QuotaPagedPoolUsage", PVOID), + ("QuotaPeakNonPagedPoolUsage", PVOID), + ("QuotaNonPagedPoolUsage", PVOID), + ("PagefileUsage", PVOID), + ("PeakPagefileUsage", SIZE_T), + ("PrivatePageCount", SIZE_T), + ("Reserved6", LARGE_INTEGER * (6)), + ] +PSYSTEM_PROCESS_INFORMATION = POINTER(_SYSTEM_PROCESS_INFORMATION) +SYSTEM_PROCESS_INFORMATION = _SYSTEM_PROCESS_INFORMATION + +class _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION(Structure): + _fields_ = [ + ("IdleTime", LARGE_INTEGER), + ("KernelTime", LARGE_INTEGER), + ("UserTime", LARGE_INTEGER), + ("Reserved1", LARGE_INTEGER * (2)), + ("Reserved2", ULONG), + ] +PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION = POINTER(_SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) +SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION = _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION + +class _SYSTEM_REGISTRY_QUOTA_INFORMATION(Structure): + _fields_ = [ + ("RegistryQuotaAllowed", ULONG), + ("RegistryQuotaUsed", ULONG), + ("Reserved1", PVOID), + ] +PSYSTEM_REGISTRY_QUOTA_INFORMATION = POINTER(_SYSTEM_REGISTRY_QUOTA_INFORMATION) +SYSTEM_REGISTRY_QUOTA_INFORMATION = _SYSTEM_REGISTRY_QUOTA_INFORMATION + +class _SYSTEM_BASIC_INFORMATION(Structure): + _fields_ = [ + ("Reserved1", BYTE * (24)), + ("Reserved2", PVOID * (4)), + ("NumberOfProcessors", CHAR), + ] +PSYSTEM_BASIC_INFORMATION = POINTER(_SYSTEM_BASIC_INFORMATION) +SYSTEM_BASIC_INFORMATION = _SYSTEM_BASIC_INFORMATION + +class _ANON__ANON__SYSTEM_INFO_SUB_UNION_1_SUB_STRUCTURE_1(Structure): + _fields_ = [ + ("wProcessorArchitecture", WORD), + ("wReserved", WORD), + ] + +class _ANON__SYSTEM_INFO_SUB_UNION_1(Union): + _anonymous_ = ("DUMMYSTRUCTNAME",) + _fields_ = [ + ("dwOemId", DWORD), + ("DUMMYSTRUCTNAME", _ANON__ANON__SYSTEM_INFO_SUB_UNION_1_SUB_STRUCTURE_1), + ] + +class _SYSTEM_INFO(Structure): + _anonymous_ = ("DUMMYUNIONNAME",) + _fields_ = [ + ("DUMMYUNIONNAME", _ANON__SYSTEM_INFO_SUB_UNION_1), + ("dwPageSize", DWORD), + ("lpMinimumApplicationAddress", LPVOID), + ("lpMaximumApplicationAddress", LPVOID), + ("dwActiveProcessorMask", DWORD_PTR), + ("dwNumberOfProcessors", DWORD), + ("dwProcessorType", DWORD), + ("dwAllocationGranularity", DWORD), + ("wProcessorLevel", WORD), + ("wProcessorRevision", WORD), + ] +LPSYSTEM_INFO = POINTER(_SYSTEM_INFO) +SYSTEM_INFO = _SYSTEM_INFO + class _TIME_ZONE_INFORMATION(Structure): _fields_ = [ ("Bias", LONG), diff --git a/windows/utils/winutils.py b/windows/utils/winutils.py index 1d28e81..1220333 100644 --- a/windows/utils/winutils.py +++ b/windows/utils/winutils.py @@ -552,6 +552,14 @@ def create_file(name, access=gdef.GENERIC_READ, share=gdef.FILE_SHARE_READ, secu # addr = windows.winproxy.MapViewOfFile(h, dwDesiredAccess=FILE_MAP_READ, dwNumberOfBytesToMap=1) # return addr +def get_system_info(native=False): + res = gdef.SYSTEM_INFO() + if native: + windows.winproxy.GetNativeSystemInfo(res) + else: + windows.winproxy.GetSystemInfo(res) + return res + def decompress_buffer(buffer, comptype=gdef.COMPRESSION_FORMAT_LZNT1, uncompress_size=None): if uncompress_size is None: uncompress_size = len(buffer) * 10 diff --git a/windows/winproxy/apis/kernel32.py b/windows/winproxy/apis/kernel32.py index 93178a2..9623981 100644 --- a/windows/winproxy/apis/kernel32.py +++ b/windows/winproxy/apis/kernel32.py @@ -407,6 +407,14 @@ def GetWindowsDirectoryW(lpBuffer, uSize=None): def GetProductInfo(dwOSMajorVersion, dwOSMinorVersion, dwSpMajorVersion, dwSpMinorVersion, pdwReturnedProductType): return GetProductInfo.ctypes_function(dwOSMajorVersion, dwOSMinorVersion, dwSpMajorVersion, dwSpMinorVersion, pdwReturnedProductType) +@Kernel32Proxy(error_check=no_error_check) +def GetNativeSystemInfo(lpSystemInfo): + return GetNativeSystemInfo.ctypes_function(lpSystemInfo) + +@Kernel32Proxy(error_check=no_error_check) +def GetSystemInfo(lpSystemInfo): + return GetSystemInfo.ctypes_function(lpSystemInfo) + ## Io @Kernel32Proxy()