Projects

Unofficial StarTech PEXHDCAP60L capture card patched driver with high CPU usage fix


Created on 2024-01-04 by Tuxality, last modified on 2024-01-04

This is an unofficial patched driver for the infamous "100% CPU usage" issue of the StarTech PEXDCAP60L PCIe capture card driver. PEXHDCAP60L is a feature rich capture card, a clone of the famous Micomsoft SC-512N1-L/DVI. Sadly user-space portion of the drivers from Yuan consist of a feature that changes power settings which results in 100% CPU usage even when your computer is running idle with no computational tasks being done in the background.

▼ Stock card photo ▼





▼ Driver reverse engineering ▼



After driver disassembly and quick check it turned out that only user-space modules are affected, most notably filter device part of the driver so it is possible to disable previously mentioned functionality in order to prevent CPU high usage issue on newer systems. Following functions from the powrprof.dll are used for manipulating power scheme by the driver:

➡ DWORD PowerSetActiveScheme(HKEY UserRootPowerKey, const GUID* SchemeGuid)
➡ DWORD PowerGetActiveScheme(HKEY UserRootPowerKey, GUID** ActivePolicyGuid)
➡ DWORD PowerEnumerate(HKEY RootPowerKey, const GUID* SchemeGuid, const GUID* SubGroupOfPowerSettingsGuid, POWER_DATA_ACCESSOR AccessFlags, ULONG Index, UCHAR* Buffer, DWORD* BufferSize)
➡ DWORD PowerReadACValueIndex(HKEY RootPowerKey, const GUID* SchemeGuid, const GUID* SubGroupOfPowerSettingsGuid, const GUID* PowerSettingGuid, LPDWORD AcValueIndex)
➡ DWORD PowerReadDCValueIndex(HKEY RootPowerKey, const GUID* SchemeGuid, const GUID* SubGroupOfPowerSettingsGuid, const GUID* PowerSettingGuid, LPDWORD DcValueIndex)
➡ DWORD PowerReadACValue(HKEY RootPowerKey, const GUID* SchemeGuid, const GUID* SubGroupOfPowerSettingsGuid, const GUID* PowerSettingGuid, PULONG Type, LPBYTE Buffer, LPDWORD BufferSize)
➡ DWORD PowerReadDCValue(HKEY RootPowerKey, const GUID* SchemeGuid, const GUID* SubGroupOfPowerSettingsGuid, const GUID* PowerSettingGuid, PULONG Type, PUCHAR Buffer, LPDWORD BufferSize)
➡ DWORD PowerReadFriendlyName(HKEY RootPowerKey, const GUID* SchemeGuid, const GUID* SubGroupOfPowerSettingsGuid, const GUID* PowerSettingGuid, PUCHAR Buffer, LPDWORD BufferSize)
➡ DWORD PowerWriteACValueIndex(HKEY RootPowerKey, const GUID* SchemeGuid, const GUID* SubGroupOfPowerSettingsGuid, const GUID* PowerSettingGuid, DWORD AcValueIndex)
➡ DWORD PowerWriteDCValueIndex(HKEY RootPowerKey, const GUID* SchemeGuid, const GUID* SubGroupOfPowerSettingsGuid, const GUID* PowerSettingGuid, DWORD DcValueIndex)
➡ BOOLEAN GetActivePwrScheme(PUINT puiID)
➡ BOOLEAN ReadProcessorPwrScheme(UINT uiID, PMACHINE_PROCESSOR_POWER_POLICY pMachineProcessorPowerPolicy)
➡ BOOLEAN WriteProcessorPwrScheme(UINT uiID, PMACHINE_PROCESSOR_POWER_POLICY pMachineProcessorPowerPolicy)
➡ BOOLEAN SetActivePwrScheme(UINT uiID, PGLOBAL_POWER_POLICY pGlobalPowerPolicy, PPOWER_POLICY pPowerPolicy)


In order to fix the issue changes to both SA7160.C64.AX and SA7160.C86.AX need to be done, for this task I've used excellent Ghidra tool from NSA.

Patched driver contains following changes applied in SA7160.C64.AX:

➡ Replaced 8 bytes at offset 0x35e5 i.e. 84 c0 0f 84 99 00 00 00 into 90 90 e9 9a 00 00 00 90

It means that original portion of the code below quoted one will not execute and jump to the label will be always done compared to the original code path:

1800041e5 84 c0 TEST AL,AL 1800041e5 90 NOP 1800041e6 90 NOP1800041e7 0f 84 99 JZ LAB_180004286 1800041e7 e9 9a 00 JMP LAB_180004286 00 00 00 00 00
Above change allows to skip calls to the WriteProcessorPwrScheme and SetActivePwrScheme functions in x64 variant of the driver to be exact.

➡ Changed PowrProf.dll to PowrNope.dll around code that performs LoadLibrary call

18000a21a 0f 82 de JC LAB_18000a3fe 01 00 0018000a220 48 8b cf MOV param_1,RDI18000a223 e8 7a 71 CALL thunk_FUN_1800033a0 undefined thunk_FUN_1800033a0(longlong param_1) ff ff18000a228 48 8d 0d LEA tblPtr,[s_PowrProf.dll_1800472d8] = "PowrProf.dll" 18000a228 48 8d 0d LEA param_1,[s_PowrNope.dll_1800472d8] = "PowrNope.dll" a9 d0 03 00 a9 d0 03 0018000a22f ff 15 83 CALL qword ptr [->KERNEL32.DLL::LoadLibraryA] = 0006f046 46 06 0018000a235 48 89 87 MOV qword ptr [RDI + 0x108],RAX 08 01 00 0018000a23c 48 85 c0 TEST RAX,RAX18000a23f 0f 84 d8 JZ LAB_18000a41d 01 00 00
Above change allows to skip further GetProcAddress calls to get function pointers from the PowrProf.dll library in x64 variant of the driver. Due to the library not being available during LoadLibrary call, all function pointers are zeroed and not used in further code path.

Similarly, following changes were applied to the patched driver for the SA7160.C86.AX:

➡ Replaced 8 bytes at offset 0x3288 i.e. 84 c0 0f 84 81 00 00 00 into 90 90 e9 82 00 00 00 90

It means that original portion of the code below quoted one will not execute and jump to the label will be always done compared to the original code path:

10003e88 84 c0 TEST AL,AL 10003e88 90 NOP 10003e89 90 NOP10003e8a 0f 84 81 JZ LAB_10003f11 10003e8a e9 82 00 JMP LAB_10003f11 00 00 00 00 00
Above change allows to similarly skip calls to the WriteProcessorPwrScheme and SetActivePwrScheme functions in x86 variant of the driver to be exact.

➡ Changed PowrProf.dll to PowrNope.dll around code that performs LoadLibrary call

100096a6 0f 82 8e JC LAB_1000983a 01 00 00100096ac 8b ce MOV this,ESI100096ae e8 84 7e CALL thunk_FUN_10003330 undefined thunk_FUN_10003330(int param_1) ff ff100096b3 68 a4 fb PUSH s_PowrProf.dll_1003fba4 = "PowrProf.dll" 100096b3 68 a4 fb PUSH s_PowrNope.dll_1003fba4 = "PowrNope.dll" 03 10 03 10100096b8 ff 15 a4 CALL dword ptr [->KERNEL32.DLL::LoadLibraryA] = 00051916 14 05 10100096be 89 86 d0 MOV dword ptr [ESI + 0xd0],EAX 00 00 00100096c4 3b c7 CMP EAX,EDI100096c6 0f 84 85 JZ LAB_10009851 01 00 00
Above change allows to skip further GetProcAddress calls to get function pointers from the PowrProf.dll library in x86 variant of the driver. Similarly to the x64 variant, due to the library not being available during LoadLibrary call, all function pointers are zeroed and not used in further code path.

▼ Patched driver release ▼



Driver package for both x64 and x86 architectures with patch applied can be found below. Please make sure to check the installation instruction section for further information!

Download:
🔽 Unofficial patched PEXHDCAP60L driver version 1.1.0.172 for x64/x86, release A1

Driver content SHA256 checksum comparison:

Original Patched0e25afc6f2c17e08afc91f7717b3669cb4de6f77dd62b78674b09e0d59e4aa3c DPInst.exe 0e25afc6f2c17e08afc91f7717b3669cb4de6f77dd62b78674b09e0d59e4aa3c DPInst_x64.exee12bf594f98a878da912d7a70743cc486238eac645a4b8e603cae8feecbde549 DPInst.exe e12bf594f98a878da912d7a70743cc486238eac645a4b8e603cae8feecbde549 DPInst_x86.exef8c64aa6989b9568c8325c880cd58e181fd7a17d84334e3a092251ea6701e2b4 SA7160.C64.AX a23419bbda5dea6aefa15f33f3aef19b30b7214126225e0f1bf00450d7122d95 SA7160.C64.AXdbc1f7ac6c62c2891b8c77c614ca22adb41a85d7055405739398f0a26c4b4c0a SA7160.C86.AX 4a49fa261208a81dde7719cacbadbf06439ea1925dd3b3031780eb0b625e974f SA7160.C86.AX7ae2e8be8c943ccd2739948bbf980b1515debe2039ec1a538a8fd3115e2b1a6d SA7160.CAT 7ae2e8be8c943ccd2739948bbf980b1515debe2039ec1a538a8fd3115e2b1a6d SA7160.CAT81e5fc307c31117a58de1bc3086d3b45b16ae2f818551365d789c87066af9145 SA7160.INF 81e5fc307c31117a58de1bc3086d3b45b16ae2f818551365d789c87066af9145 SA7160.INFc183ba15eefb6af151b12adacb87f368b672efedc9349505e63db21da9d086a7 SA7160.X64.AX c183ba15eefb6af151b12adacb87f368b672efedc9349505e63db21da9d086a7 SA7160.X64.AXbe338a6c49ceb80ad256cd7edeedc4490cee3fa0d328228df147931dde59659f SA7160.X64.SYS be338a6c49ceb80ad256cd7edeedc4490cee3fa0d328228df147931dde59659f SA7160.X64.SYSb2638effa03b50f4a621c0bb8f7087995867553afb0712e3de25a508bbb71ea3 SA7160.X86.AX b2638effa03b50f4a621c0bb8f7087995867553afb0712e3de25a508bbb71ea3 SA7160.X86.AX4ea3f7621b6e8153a9e60091883bee5911c6f781e2446c54bc67c1ebb2bd26ff SA7160.X86.SYS 4ea3f7621b6e8153a9e60091883bee5911c6f781e2446c54bc67c1ebb2bd26ff SA7160.X86.SYS073d0d2624dbc31f00bc7bb0f3f95b73f0d57501335078771111ac10275c1180 dpinst.xml 073d0d2624dbc31f00bc7bb0f3f95b73f0d57501335078771111ac10275c1180 dpinst.xml
Please note that the patched driver has both 32 and 64 directories merged into one driver package containing resources for both architectures.

▼ Patched driver installation instruction ▼



While patch fixes the issue by avoiding altering power scheme in the driver, it will not fix your high CPU usage issue if configuration has been already altered by using broken version of the driver. In this case please apply driver on a clean Windows installation or make sure that the previous driver is fully uninstalled so it won't be installed automatically!

If driver was previously installed and high CPU usage issue remains, please make sure that system was fully rebooted after uninstallation then use following commands with administrator privileges to alter the power scheme:

powercfg /setacvalueindex SCHEME_CURRENT SUB_PROCESSOR IDLEDISABLE 0powercfg /setactive SCHEME_CURRENT
After applying commands perform full reboot then check if issue still persist in Task manager. If everything works properly, proceed to patched driver installation, if not then well - you are out of luck, consider reinstalling system. That's Windows for ya.

Driver can be installed with use of DPInst_x64.exe or DPInst_x86.exe depending on architecture before plugging in PEXDCAP60L card into the system. Otherwise, one can install it manually via Device Manager after plugging in the card by prodiving path to the extracted content of the modified driver package. Please keep in mind that modification partially breaks driver signature as two files are now not signed after the change, however those are user space binaries not kernel space ones so driver should install just fine without disabling driver signature enforcement. At least that was the case of my Microsoft Windows 10 IoT Enterprise LTSB 2016 release. Please use it at your own risk as with any modded drivers especially in terms of anti-cheat systems when playing online games, you have been warned!

If everything is installed correctly your system should have proper low CPU usage during idle, assuming that there are no third party applications or services running in the background, as shown below:



In order to make sure that patched driver was installed you can check driver signature in Device Manager. First open devmgmt.msc and select one of the PEXDCAP60L devices from the Sound, video and game controllers category:



Then right click on the device entry, select Properties and navigate to the Driver tab. Patched driver version 1.1.0.172 originally from Yuan dated 30/03/2017 should be installed as shown below:



Click Driver Details and check if signature is not available for all instances of the SA7160.C64.AX and SA7160.C86.AX files:

      

Please note that driver was tested only on Fujitsu Futro S940 with official PCIe riser running so-called Microsoft Windows 10 IoT Enterprise LTSB 2016 edition i.e. version from the long term servicing branch as shown below:



I cannot guarantee that it will work on other operating systems such as newer versions of Microsoft Windows 10 as well as different hardware configurations, so please use it at your own risk.

▼ Random notes ▼



PEXHDCAP60L does not work in Dell Wyse 5070 Extended with PCIe riser. It ends up with "This device cannot start" code 10. Issue is not related to my patched driver as it doesn't work on original one too. Works just fine in Fujitsu Futro S940 with official Fujitsu D3318 PCIe riser though which I can personally recommend.

Click to list all projects...