├── CVE-2024-30804 ├── AsInsHelp32.sys ├── AsInsHelp64.sys ├── CVE-2024-30804.exe ├── README.md └── result.png ├── CVE-2024-33218 ├── AsUpIO64.sys └── README.md ├── CVE-2024-33219 ├── AsIO64.sys └── README.md ├── CVE-2024-33220 ├── AsIO3_64.sys └── README.md ├── CVE-2024-33221 ├── AsusBSItf.sys └── README.md ├── CVE-2024-33222 ├── README.md └── rtkio64.sys ├── CVE-2024-33223 ├── IOMap64.sys └── README.md ├── CVE-2024-33224 ├── README.md └── rtkio64.sys ├── CVE-2024-33225 ├── README.md └── RTKVHD64.sys ├── CVE-2024-33226 ├── Access64.sys └── README.md ├── CVE-2024-33227 ├── README.md └── ddcdrv.sys ├── CVE-2024-33228 ├── README.md └── segwindrvx64.sys └── README.md /CVE-2024-30804/AsInsHelp32.sys: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DriverHunter/Win-Driver-EXP/21726ae8475c10c893ae35f2b744dee8d7390057/CVE-2024-30804/AsInsHelp32.sys -------------------------------------------------------------------------------- /CVE-2024-30804/AsInsHelp64.sys: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DriverHunter/Win-Driver-EXP/21726ae8475c10c893ae35f2b744dee8d7390057/CVE-2024-30804/AsInsHelp64.sys -------------------------------------------------------------------------------- /CVE-2024-30804/CVE-2024-30804.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DriverHunter/Win-Driver-EXP/21726ae8475c10c893ae35f2b744dee8d7390057/CVE-2024-30804/CVE-2024-30804.exe -------------------------------------------------------------------------------- /CVE-2024-30804/README.md: -------------------------------------------------------------------------------- 1 | # Vulnerable Driver AsInsHelp64.sys in ASUS Fan_Xpert 2 | 3 | --- 4 | 5 | ASUS Fan_Xper is used to control the fan speed. Many vulnerability exits in it's driver AsInsHelp64.sys Before version 10013, which allows low-privileged users to map arbitrary physical memory, read and write arbitary i/o port via specially crafted IOCTL requests. This can be exploited for privilege escalation, code execution under high privileges, and information disclosure. These signed drivers can also be used to bypass the Microsoft driver-signing policy to deploy malicious code. 6 | 7 | Using AsInsHelp64.sys as example, AsInsHelp32.sys is also similar. 8 | 9 | ## version 10 | 11 | 10013 12 | 13 | ## Vulnerability causes 14 | 15 | AsInsHelp64.sys provides the functionality of mapping physical memory and In/Out I/O ports, but it does not restrict the privileges of the caller, resulting in low-privileged users being able to call the driver and execute corresponding functions through DeviceIoControl. 16 | 17 | ~~~c 18 | __int64 __fastcall sub_116F0(__int64 a1, __int64 a2) // ioctler 19 | { 20 | char is32bitprocess; // si 21 | __int64 v5; // rdx 22 | int v6; // ebx 23 | char v7; // al 24 | unsigned int v8; // eax 25 | void *v9; // rdx 26 | __int64 v10; // rax 27 | 28 | is32bitprocess = IoIs32bitProcess((PIRP)a2); 29 | *(_QWORD *)(a2 + 56) = 0i64; 30 | v5 = *(_QWORD *)(a2 + 184); 31 | v6 = -1073741822; 32 | v7 = *(_BYTE *)v5; 33 | if ( !*(_BYTE *)v5 || v7 == 2 ) 34 | { 35 | v6 = 0; 36 | goto LABEL_28; 37 | } 38 | if ( v7 != 14 ) 39 | goto LABEL_28; 40 | v8 = *(_DWORD *)(v5 + 24); 41 | if ( v8 > 0xA0406408 ) 42 | { 43 | if ( v8 == 0xA040A440 || v8 == 0xA040A444 || v8 == 0xA040A448 ) 44 | v6 = sub_11110(a2, v5, is32bitprocess); // out arbitary I/O port 45 | goto LABEL_28; 46 | } 47 | switch ( v8 ) 48 | { 49 | case 0xA0406408: 50 | LABEL_10: 51 | v6 = sub_11000(a2, v5); // in arbitary I/O port 52 | break; 53 | case 0xA040244C: 54 | v6 = sub_112F0(a1, a2, *(_QWORD *)(a2 + 184), is32bitprocess);// map physical address 55 | if ( v6 < 0 ) 56 | { 57 | *(_DWORD *)(a2 + 48) = -1073741811; 58 | } 59 | else 60 | { 61 | v10 = 8i64; 62 | if ( is32bitprocess ) 63 | v10 = 4i64; 64 | *(_QWORD *)(a2 + 56) = v10; 65 | } 66 | break; 67 | case 0xA0402450: 68 | if ( is32bitprocess ) 69 | { 70 | if ( *(_DWORD *)(v5 + 16) >= 4u ) 71 | { 72 | v9 = (void *)**(unsigned int **)(a2 + 24); 73 | LABEL_14: 74 | v6 = ZwUnmapViewOfSection((HANDLE)0xFFFFFFFFFFFFFFFFi64, v9); 75 | break; 76 | } 77 | } 78 | else if ( *(_DWORD *)(v5 + 16) >= 8u ) 79 | { 80 | v9 = **(void ***)(a2 + 24); 81 | goto LABEL_14; 82 | } 83 | v6 = -1073741670; 84 | break; 85 | case 0xA0406400: 86 | case 0xA0406404: 87 | goto LABEL_10; 88 | } 89 | LABEL_28: 90 | *(_DWORD *)(a2 + 48) = v6; 91 | IofCompleteRequest((PIRP)a2, 0); 92 | return (unsigned int)v6; 93 | } 94 | ~~~ 95 | 96 | ### IOCTL 0xA040244C 97 | 98 | This IOCTL code triggers the mapping of physical memory. The composition of the input buffer is as follows. 99 | 100 | ~~~c 101 | #pragma pack (1) 102 | typedef struct { 103 | ULONG64 junk1; 104 | ULONG64 section_offset; // The physical address you want to map. 105 | DWORD junk2; 106 | DWORD view_size; // How many bytes 107 | } AsInsHelp64_Map_Inputbuffer; 108 | #pragma pack() 109 | ~~~ 110 | 111 | The memory mapping is eventually completed by calling ZwMapViewOfSection. 112 | 113 | ~~~c 114 | __int64 __fastcall sub_112F0(__int64 a1, __int64 a2, __int64 a3, bool is32bitprocess) 115 | { 116 | PHYSICAL_ADDRESS *v5; // rdi 117 | _DWORD *v6; // r13 118 | NTSTATUS v7; // ebx 119 | HANDLE v8; // rcx 120 | _DWORD *v9; // r14 121 | DWORD v10; // ecx 122 | DWORD LowPart; // eax 123 | void *SectionHandle; // [rsp+50h] [rbp-D8h] BYREF 124 | ULONG AddressSpace; // [rsp+58h] [rbp-D0h] BYREF 125 | LARGE_INTEGER TranslatedAddress; // [rsp+60h] [rbp-C8h] BYREF 126 | union _LARGE_INTEGER SectionOffset; // [rsp+68h] [rbp-C0h] BYREF 127 | HANDLE Handle; // [rsp+70h] [rbp-B8h] BYREF 128 | ULONG_PTR ViewSize; // [rsp+78h] [rbp-B0h] BYREF 129 | PHYSICAL_ADDRESS BusAddress; // [rsp+80h] [rbp-A8h] BYREF 130 | PVOID Object; // [rsp+88h] [rbp-A0h] BYREF 131 | PVOID v21; // [rsp+90h] [rbp-98h] BYREF 132 | ULONG v22; // [rsp+98h] [rbp-90h] BYREF 133 | PVOID BaseAddress; // [rsp+A0h] [rbp-88h] BYREF 134 | struct _OBJECT_ATTRIBUTES ObjectAttributes; // [rsp+A8h] [rbp-80h] BYREF 135 | struct _UNICODE_STRING DestinationString; // [rsp+D8h] [rbp-50h] BYREF 136 | 137 | v5 = *(PHYSICAL_ADDRESS **)(a2 + 24); 138 | AddressSpace = v5[2].LowPart; 139 | v22 = AddressSpace; 140 | Handle = 0i64; 141 | v21 = 0i64; 142 | LODWORD(SectionHandle) = 0; 143 | LODWORD(Object) = 0; 144 | if ( is32bitprocess ) 145 | { 146 | v6 = v5; 147 | if ( *(_DWORD *)(a3 + 16) < 0x18u || *(_DWORD *)(a3 + 8) < 4u ) 148 | { 149 | v7 = 0xC000009A; 150 | goto LABEL_5; 151 | } 152 | v9 = v21; 153 | } 154 | else 155 | { 156 | v9 = v5; 157 | if ( *(_DWORD *)(a3 + 16) < 0x18u || *(_DWORD *)(a3 + 8) < 8u ) 158 | return (unsigned int)-1073741670; 159 | v6 = v21; 160 | } 161 | RtlInitUnicodeString(&DestinationString, L"\\Device\\PhysicalMemory"); 162 | ObjectAttributes.Length = 48; 163 | ObjectAttributes.RootDirectory = 0i64; 164 | ObjectAttributes.Attributes = 64; 165 | ObjectAttributes.ObjectName = &DestinationString; 166 | ObjectAttributes.SecurityDescriptor = 0i64; 167 | ObjectAttributes.SecurityQualityOfService = 0i64; 168 | if ( is32bitprocess ) 169 | { 170 | v7 = ZwOpenSection(&SectionHandle, 0xF001Fu, &ObjectAttributes); 171 | if ( v7 < 0 ) 172 | goto LABEL_5; 173 | v7 = ObReferenceObjectByHandle((HANDLE)(int)SectionHandle, 0xF001Fu, 0i64, 0, &Object, 0i64); 174 | if ( v7 < 0 ) 175 | goto LABEL_5; 176 | } 177 | else 178 | { 179 | v7 = ZwOpenSection(&Handle, 0xF001Fu, &ObjectAttributes); 180 | if ( v7 < 0 ) 181 | goto LABEL_32; 182 | v7 = ObReferenceObjectByHandle(Handle, 0xF001Fu, 0i64, 0, &v21, 0i64); 183 | if ( v7 < 0 ) 184 | goto LABEL_32; 185 | } 186 | BusAddress.QuadPart = v5[1].QuadPart + v5[2].HighPart + (unsigned int)(unsigned __int16)v5[1].LowPart; 187 | if ( !HalTranslateBusAddress((INTERFACE_TYPE)v5->LowPart, v5->HighPart, v5[1], &AddressSpace, &TranslatedAddress) 188 | || !HalTranslateBusAddress((INTERFACE_TYPE)v5->LowPart, v5->HighPart, BusAddress, &v22, &BusAddress) 189 | || (v10 = BusAddress.LowPart - TranslatedAddress.LowPart, 190 | ViewSize = BusAddress.QuadPart - TranslatedAddress.QuadPart, 191 | BusAddress.LowPart == TranslatedAddress.LowPart) ) 192 | { 193 | v7 = 0xC0000001; 194 | goto LABEL_5; 195 | } 196 | if ( AddressSpace ) 197 | { 198 | LowPart = TranslatedAddress.LowPart; 199 | if ( is32bitprocess ) 200 | { 201 | *v6 = TranslatedAddress.LowPart; 202 | v7 = 0; 203 | goto LABEL_5; 204 | } 205 | goto LABEL_30; 206 | } 207 | SectionOffset = TranslatedAddress; 208 | if ( !is32bitprocess ) 209 | { 210 | BaseAddress = 0i64; 211 | v7 = ZwMapViewOfSection( 212 | Handle, // rcx 213 | (HANDLE)0xFFFFFFFFFFFFFFFFi64, // rdx 214 | &BaseAddress, // r8 215 | 0i64, // r9 216 | v10, // commitsize==viewsize rsp+20 217 | &SectionOffset, // sectionoffset = inputbuffer 0x8-0xf 218 | &ViewSize, // rsp+30 219 | ViewShare, // rsp+38 220 | 0, // rsp+40 221 | 0x204u); // rsp+48 222 | if ( v7 >= 0 ) 223 | { 224 | LowPart = TranslatedAddress.LowPart + (_DWORD)BaseAddress - SectionOffset.LowPart; 225 | LABEL_30: 226 | *v9 = LowPart; 227 | v7 = 0; 228 | goto LABEL_5; 229 | } 230 | LABEL_32: 231 | v8 = Handle; 232 | if ( Handle ) 233 | goto LABEL_33; 234 | return (unsigned int)v7; 235 | } 236 | HIDWORD(SectionHandle) = 0; 237 | v7 = ZwMapViewOfSection( 238 | (HANDLE)(int)SectionHandle, 239 | (HANDLE)0xFFFFFFFFFFFFFFFFi64, 240 | (void **)((char *)&SectionHandle + 4), 241 | 0i64, 242 | v10, 243 | &SectionOffset, 244 | &ViewSize, 245 | ViewShare, 246 | 0, 247 | 0x204u); 248 | if ( v7 >= 0 ) 249 | { 250 | HIDWORD(SectionHandle) += TranslatedAddress.LowPart - SectionOffset.LowPart; 251 | *v6 = HIDWORD(SectionHandle); 252 | v7 = 0; 253 | } 254 | LABEL_5: 255 | if ( !is32bitprocess ) 256 | goto LABEL_32; 257 | if ( (_DWORD)SectionHandle ) 258 | { 259 | v8 = (HANDLE)(int)SectionHandle; 260 | LABEL_33: 261 | ZwClose(v8); 262 | } 263 | return (unsigned int)v7; 264 | } 265 | ~~~ 266 | 267 | ### IOCTL 0xA0406400(in byte), 0xA0406404(in word), 0xA0406408(in dword) 268 | 269 | This code triggers reading from an I/O port. The composition of the input buffer is as follows. 270 | 271 | ~~~c 272 | #pragma pack (1) 273 | typedef struct { 274 | DWORD port // target port 275 | } AsInsHelp64_In_Inputbuffer; 276 | #pragma pack() 277 | ~~~ 278 | 279 | The I/O port reading is eventually completed in function below. 280 | 281 | ```c 282 | __int64 __fastcall sub_11000(__int64 a1, __int64 a2) 283 | { 284 | int v3; // ebx 285 | _WORD *v4; // rdi 286 | ULONG v5; // esi 287 | unsigned __int32 v6; // eax 288 | unsigned __int16 v7; // ax 289 | unsigned __int8 v8; // al 290 | ULONG AddressSpace; // [rsp+30h] [rbp-48h] BYREF 291 | PHYSICAL_ADDRESS BusAddress; // [rsp+38h] [rbp-40h] BYREF 292 | 293 | v3 = *(_DWORD *)(a2 + 24); 294 | v4 = *(_WORD **)(a1 + 24); 295 | switch ( v3 ) 296 | { 297 | case 0xA0406400: 298 | v5 = 1; 299 | break; 300 | case 0xA0406404: 301 | v5 = 2; 302 | break; 303 | case 0xA0406408: 304 | v5 = 4; 305 | break; 306 | default: 307 | v5 = AddressSpace; 308 | break; 309 | } 310 | BusAddress.QuadPart = *(unsigned int *)v4; 311 | AddressSpace = 1; 312 | HalTranslateBusAddress(Isa, 0, BusAddress, &AddressSpace, &BusAddress); 313 | if ( AddressSpace == 1 ) 314 | { 315 | if ( v3 != 0xA0406400 ) 316 | { 317 | if ( v3 == 0xA0406404 ) 318 | { 319 | v7 = __inword(BusAddress.LowPart); 320 | *v4 = v7; 321 | } 322 | else if ( v3 == 0xA0406408 ) 323 | { 324 | v6 = __indword(BusAddress.LowPart); 325 | *(_DWORD *)v4 = v6; 326 | } 327 | goto LABEL_22; 328 | } 329 | v8 = __inbyte(BusAddress.LowPart); 330 | LABEL_21: 331 | *(_BYTE *)v4 = v8; 332 | goto LABEL_22; 333 | } 334 | switch ( v3 ) 335 | { 336 | case 0xA0406400: 337 | v8 = *(_BYTE *)BusAddress.LowPart; 338 | goto LABEL_21; 339 | case 0xA0406404: 340 | *v4 = *(_WORD *)BusAddress.LowPart; 341 | break; 342 | case 0xA0406408: 343 | *(_DWORD *)v4 = *(_DWORD *)BusAddress.LowPart; 344 | break; 345 | } 346 | LABEL_22: 347 | *(_QWORD *)(a1 + 56) = v5; 348 | return 0i64; 349 | } 350 | ``` 351 | 352 | 353 | 354 | ### IOCTL 0xA040A440 (out byte), 0xA040A444(out word) , 0xA040A448 (out dword) 355 | 356 | This code triggers reading from an I/O port. The composition of the input buffer is as follows. 357 | 358 | ~~~c 359 | DWORDLONG inputbuffer= (DWORD64)data << 32 | port; 360 | ~~~ 361 | 362 | The I/O port reading is eventually completed in function below. 363 | 364 | ```c 365 | __int64 __fastcall sub_11110(__int64 a1, __int64 a2, char is32bitprocess) 366 | { 367 | int v4; // r12d 368 | _DWORD *v5; // rdi 369 | unsigned int v6; // eax 370 | unsigned __int8 *v7; // rdi 371 | DWORD *QuadPart; // rbx 372 | unsigned int *v9; // rbx 373 | ULONG AddressSpace; // [rsp+30h] [rbp-38h] BYREF 374 | PHYSICAL_ADDRESS BusAddress; // [rsp+38h] [rbp-30h] BYREF 375 | 376 | v4 = *(_DWORD *)(a2 + 24); 377 | if ( is32bitprocess ) 378 | { 379 | v5 = *(_DWORD **)(a1 + 24); 380 | v6 = *v5; 381 | v7 = (unsigned __int8 *)(v5 + 1); 382 | QuadPart = (DWORD *)BusAddress.QuadPart; 383 | } 384 | else 385 | { 386 | v9 = *(unsigned int **)(a1 + 24); 387 | v6 = *v9; 388 | QuadPart = v9 + 1; 389 | v7 = (unsigned __int8 *)BusAddress.QuadPart; 390 | } 391 | BusAddress.QuadPart = v6; 392 | AddressSpace = 1; 393 | HalTranslateBusAddress(Isa, 0, (PHYSICAL_ADDRESS)v6, &AddressSpace, &BusAddress); 394 | if ( AddressSpace != 1 ) 395 | { 396 | switch ( v4 ) 397 | { 398 | case 0xA040A440: 399 | if ( is32bitprocess ) 400 | { 401 | *(_BYTE *)BusAddress.LowPart = *v7; 402 | _mm_sfence(); 403 | return 0i64; 404 | } 405 | LOBYTE(BusAddress.LowPart) = *(_BYTE *)QuadPart; 406 | _mm_sfence(); 407 | return 0i64; 408 | case 0xA040A444: 409 | if ( is32bitprocess ) 410 | *(_WORD *)BusAddress.LowPart = *(_WORD *)v7; 411 | else 412 | LOWORD(BusAddress.LowPart) = *(_WORD *)QuadPart; 413 | break; 414 | case 0xA040A448: 415 | if ( is32bitprocess ) 416 | *(_DWORD *)BusAddress.LowPart = *(_DWORD *)v7; 417 | else 418 | BusAddress.LowPart = *QuadPart; 419 | break; 420 | default: 421 | return 0i64; 422 | } 423 | _mm_sfence(); 424 | return 0i64; 425 | } 426 | switch ( v4 ) 427 | { 428 | case 0xA040A440: 429 | if ( is32bitprocess ) 430 | __outbyte(BusAddress.LowPart, *v7); 431 | else 432 | __outbyte((unsigned __int16)&BusAddress, *(_BYTE *)QuadPart); 433 | return 0i64; 434 | case 0xA040A444: 435 | if ( is32bitprocess ) 436 | __outword(BusAddress.LowPart, *(_WORD *)v7); 437 | else 438 | __outword((unsigned __int16)&BusAddress, *(_WORD *)QuadPart); 439 | return 0i64; 440 | case 0xA040A448: 441 | if ( is32bitprocess ) 442 | __outdword(BusAddress.LowPart, *(_DWORD *)v7); 443 | else 444 | __outdword((unsigned __int16)&BusAddress, *QuadPart); 445 | return 0i64; 446 | default: 447 | return 0i64; 448 | } 449 | } 450 | ``` 451 | 452 | ## Vulnerability reproduce 453 | 454 | Load AsInsHelp64.sys and run CVE-2024-30804.exe 455 | 456 | 457 | 458 | ![image-result](result.png) 459 | -------------------------------------------------------------------------------- /CVE-2024-30804/result.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DriverHunter/Win-Driver-EXP/21726ae8475c10c893ae35f2b744dee8d7390057/CVE-2024-30804/result.png -------------------------------------------------------------------------------- /CVE-2024-33218/AsUpIO64.sys: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DriverHunter/Win-Driver-EXP/21726ae8475c10c893ae35f2b744dee8d7390057/CVE-2024-33218/AsUpIO64.sys -------------------------------------------------------------------------------- /CVE-2024-33218/README.md: -------------------------------------------------------------------------------- 1 | # Vulnerable Driver AsUpIO64.sys in ASUS USB 3.0 Boost Storage Driver 5.30.20.0 2 | 3 | --- 4 | 5 | Many vulnerability exits in driver AsUpIO64.sys, which allows low-privileged users to map arbitrary physical memory, read and write arbitary i/o port and even read/write arbitary MSR via specially crafted IOCTL requests . This can be exploited for privilege escalation, code execution under high privileges, and information disclosure. These signed drivers can also be used to bypass the Microsoft driver-signing policy to deploy malicious code. 6 | 7 | 8 | 9 | ## version 10 | 11 | 5.30.20.0 12 | 13 | ## Vulnerability causes 14 | 15 | AsUpIO64.sys provides the functionality of mapping physical memory and read/write I/O ports and arbitrary read/write MSR, but it does not restrict the privileges of the caller, resulting in low-privileged users being able to call the driver and execute corresponding functions through DeviceIoControl. 16 | 17 | ~~~c 18 | __int64 __fastcall ioctler(__int64 a1, IRP *a2) 19 | { 20 | BOOLEAN is32bitprocess; // si 21 | struct _IO_STACK_LOCATION *CurrentStackLocation; // rdx 22 | NTSTATUS v6; // ebx 23 | UCHAR MajorFunction; // al 24 | unsigned int LowPart; // eax 25 | void *Type; // rdx 26 | __int64 v10; // rax 27 | struct _IRP *MasterIrp; // rbx 28 | PVOID ContiguousMemory; // rax 29 | __int64 v14; // [rsp+20h] [rbp-38h] 30 | 31 | is32bitprocess = IoIs32bitProcess(a2); 32 | a2->IoStatus.Information = 0i64; 33 | CurrentStackLocation = a2->Tail.Overlay.CurrentStackLocation; 34 | v6 = -1073741822; 35 | MajorFunction = CurrentStackLocation->MajorFunction; 36 | if ( !CurrentStackLocation->MajorFunction || MajorFunction == 2 ) 37 | { 38 | LABEL_41: 39 | v6 = 0; 40 | goto LABEL_42; 41 | } 42 | if ( MajorFunction != 14 ) 43 | goto LABEL_42; 44 | LowPart = CurrentStackLocation->Parameters.Read.ByteOffset.LowPart; 45 | if ( LowPart > 0xA040A45C ) 46 | { 47 | switch ( LowPart ) 48 | { 49 | case 0xA040A460: 50 | v6 = ((__int64 (__fastcall *)(IRP *))sub_110B0)(a2); 51 | if ( v6 >= 0 ) 52 | a2->IoStatus.Information = 8i64; 53 | break; 54 | case 0xA040A464: 55 | v6 = ((__int64 (__fastcall *)(IRP *))sub_111C0)(a2); 56 | if ( v6 >= 0 ) 57 | a2->IoStatus.Information = 4i64; 58 | break; 59 | case 0xA040A480: 60 | goto LABEL_35; 61 | case 0xA040A488: 62 | MasterIrp = a2->AssociatedIrp.MasterIrp; 63 | ContiguousMemory = MmAllocateContiguousMemory( 64 | *(unsigned int *)&MasterIrp->Type, 65 | (PHYSICAL_ADDRESS)0xFFFFFFFFi64); 66 | HIDWORD(v14) = (_DWORD)ContiguousMemory; 67 | LODWORD(v14) = MmGetPhysicalAddress(ContiguousMemory).LowPart; 68 | *(_QWORD *)&MasterIrp->Type = v14; 69 | a2->IoStatus.Information = 8i64; 70 | goto LABEL_41; 71 | case 0xA040A48C: 72 | goto LABEL_41; 73 | case 0xA040A540: 74 | case 0xA040A544: 75 | case 0xA040A548: 76 | v6 = sub_11A20((__int64)a2, (__int64)CurrentStackLocation, is32bitprocess); 77 | break; 78 | default: 79 | goto LABEL_42; 80 | } 81 | goto LABEL_42; 82 | } 83 | if ( LowPart == 0xA040A45C ) 84 | { 85 | v6 = ((__int64 (__fastcall *)(IRP *))wrmsr_func)(a2);// read write arbitary msr primitive 86 | if ( v6 >= 0 ) 87 | a2->IoStatus.Information = 8i64; 88 | goto LABEL_42; 89 | } 90 | if ( LowPart > 0xA0406408 ) 91 | { 92 | if ( LowPart == 0xA0406458 ) 93 | { 94 | v6 = readmsr_func((__int64)a2);//rdmsr primitive 95 | if ( v6 >= 0 ) 96 | a2->IoStatus.Information = 8i64; 97 | } 98 | else if ( LowPart == 0xA040A440 || LowPart == 0xA040A444 || LowPart == 0xA040A448 ) 99 | { 100 | v6 = sub_11470((__int64)a2, (__int64)CurrentStackLocation, is32bitprocess);// out primitive 101 | } 102 | goto LABEL_42; 103 | } 104 | switch ( LowPart ) 105 | { 106 | case 0xA0406408: 107 | LABEL_12: 108 | v6 = ((__int64 (__fastcall *)(IRP *, struct _IO_STACK_LOCATION *, _QWORD))in_func)(// in primitive 109 | a2, 110 | CurrentStackLocation, 111 | is32bitprocess); 112 | break; 113 | case 0xA040244C: 114 | LABEL_35: 115 | v6 = sub_11620(a1, (__int64)a2, (__int64)a2->Tail.Overlay.CurrentStackLocation, is32bitprocess);// zwmapviewofsection primitive 116 | if ( v6 < 0 ) 117 | { 118 | a2->IoStatus.Status = -1073741811; 119 | } 120 | else 121 | { 122 | v10 = 8i64; 123 | if ( is32bitprocess ) 124 | v10 = 4i64; 125 | a2->IoStatus.Information = v10; 126 | } 127 | break; 128 | case 0xA0402450: 129 | if ( is32bitprocess ) 130 | { 131 | if ( CurrentStackLocation->Parameters.Create.Options >= 4 ) 132 | { 133 | Type = (void *)a2->AssociatedIrp.MasterIrp->Type; 134 | LABEL_16: 135 | v6 = ZwUnmapViewOfSection((HANDLE)0xFFFFFFFFFFFFFFFFi64, Type); 136 | break; 137 | } 138 | } 139 | else if ( CurrentStackLocation->Parameters.Create.Options >= 8 ) 140 | { 141 | Type = *(void **)a2->AssociatedIrp.MasterIrp; 142 | goto LABEL_16; 143 | } 144 | v6 = -1073741670; 145 | break; 146 | case 0xA0406400: 147 | case 0xA0406404: 148 | goto LABEL_12; 149 | } 150 | LABEL_42: 151 | a2->IoStatus.Status = v6; 152 | IofCompleteRequest(a2, 0); 153 | return (unsigned int)v6; 154 | } 155 | ~~~ 156 | 157 | ### IOCTL 0xA040A45C 158 | 159 | This IOCTL code triggers the read/write operation on MSR. 160 | 161 | ~~~c 162 | __int64 __fastcall sub_11120(__int64 a1, __int64 a2) 163 | { 164 | unsigned int *v3; // rax 165 | unsigned int v4; // r8d 166 | unsigned __int64 v5; // rax 167 | _DWORD *v6; // rcx 168 | 169 | v3 = *(unsigned int **)(a1 + 0x18); 170 | if ( *(_DWORD *)(a2 + 0x10) != 12 || *(_DWORD *)(a2 + 8) < 8u ) 171 | return 0xC000000Di64; 172 | v4 = *v3; 173 | __writemsr(*v3, v3[1]); 174 | v5 = __readmsr(v4); 175 | v6 = *(_DWORD **)(a1 + 0x18); 176 | *v6 = HIDWORD(v5); 177 | v6[1] = v5; 178 | *(_QWORD *)(a1 + 56) = 8i64; 179 | return 0i64; 180 | } 181 | ~~~ 182 | 183 | 184 | 185 | ### IOCTL 0xA0406458 186 | 187 | This IOCTL code triggers the read operation on MSR. 188 | 189 | ~~~c 190 | __int64 __fastcall sub_11070(__int64 a1) 191 | { 192 | **(_QWORD **)(a1 + 24) = __readmsr(**(_DWORD **)(a1 + 24)); 193 | *(_QWORD *)(a1 + 56) = 8i64; 194 | return 0i64; 195 | } 196 | ~~~ 197 | 198 | 199 | 200 | 201 | 202 | ### IOCTL 0xA040A440 (out byte), 0xA040A444 (out word), 0xA040A448 (out dword) 203 | 204 | This code triggers port out operation. The operation is eventually completed in function below. 205 | 206 | ```c 207 | __int64 __fastcall sub_11470(__int64 a1, __int64 a2, char a3) 208 | { 209 | int v4; // r12d 210 | unsigned int v5; // edx 211 | unsigned __int8 *v6; // rdi 212 | unsigned __int8 *QuadPart; // rbx 213 | ULONG v8; // eax 214 | unsigned int v10; // eax 215 | ULONG AddressSpace; // [rsp+30h] [rbp-48h] BYREF 216 | PHYSICAL_ADDRESS BusAddress; // [rsp+38h] [rbp-40h] BYREF 217 | 218 | v4 = *(_DWORD *)(a2 + 24); 219 | v5 = *(_DWORD *)(a2 + 16); 220 | if ( a3 ) 221 | { 222 | v6 = *(unsigned __int8 **)(a1 + 24); 223 | QuadPart = (unsigned __int8 *)BusAddress.QuadPart; 224 | } 225 | else 226 | { 227 | QuadPart = *(unsigned __int8 **)(a1 + 24); 228 | v6 = (unsigned __int8 *)BusAddress.QuadPart; 229 | } 230 | switch ( v4 ) 231 | { 232 | case 0xA040A440: 233 | v8 = 1; 234 | break; 235 | case 0xA040A444: 236 | v8 = 2; 237 | break; 238 | case 0xA040A448: 239 | v8 = 4; 240 | break; 241 | default: 242 | v8 = AddressSpace; 243 | break; 244 | } 245 | if ( v5 < (unsigned __int64)v8 + 4 ) 246 | return 0xC000000Di64; 247 | if ( a3 ) 248 | { 249 | v10 = *(_DWORD *)v6; 250 | v6 += 4; 251 | } 252 | else 253 | { 254 | v10 = *(_DWORD *)QuadPart; 255 | QuadPart += 4; 256 | } 257 | BusAddress.QuadPart = v10; 258 | AddressSpace = 1; 259 | HalTranslateBusAddress(Isa, 0, (PHYSICAL_ADDRESS)v10, &AddressSpace, &BusAddress); 260 | if ( AddressSpace == 1 ) 261 | { 262 | switch ( v4 ) 263 | { 264 | case 0xA040A440: 265 | if ( a3 ) 266 | __outbyte(BusAddress.LowPart, *v6); 267 | else 268 | __outbyte((unsigned __int16)&BusAddress, *QuadPart); 269 | break; 270 | case 0xA040A444: 271 | if ( a3 ) 272 | __outword(BusAddress.LowPart, *(_WORD *)v6); 273 | else 274 | __outword((unsigned __int16)&BusAddress, *(_WORD *)QuadPart); 275 | break; 276 | case 0xA040A448: 277 | if ( a3 ) 278 | __outdword(BusAddress.LowPart, *(_DWORD *)v6); 279 | else 280 | __outdword((unsigned __int16)&BusAddress, *(_DWORD *)QuadPart); 281 | break; 282 | } 283 | return 0i64; 284 | } 285 | switch ( v4 ) 286 | { 287 | case -1606376384: 288 | if ( a3 ) 289 | *(_BYTE *)BusAddress.LowPart = *v6; 290 | else 291 | LOBYTE(BusAddress.LowPart) = *QuadPart; 292 | goto LABEL_41; 293 | case -1606376380: 294 | if ( a3 ) 295 | *(_WORD *)BusAddress.LowPart = *(_WORD *)v6; 296 | else 297 | LOWORD(BusAddress.LowPart) = *(_WORD *)QuadPart; 298 | goto LABEL_41; 299 | case -1606376376: 300 | if ( a3 ) 301 | *(_DWORD *)BusAddress.LowPart = *(_DWORD *)v6; 302 | else 303 | BusAddress.LowPart = *(_DWORD *)QuadPart; 304 | LABEL_41: 305 | _mm_sfence(); 306 | break; 307 | } 308 | return 0i64; 309 | } 310 | ``` 311 | 312 | 313 | 314 | ### IOCTL 0xA0406400(in byte), 0xA0406404(in word) , 0xA0406408(in dword) 315 | 316 | This code triggers port in operation. The operation is eventually completed in function below. 317 | 318 | ```c 319 | __int64 __fastcall sub_112C0(__int64 a1, _DWORD *a2) 320 | { 321 | int v3; // ebx 322 | _BYTE *v4; // rdi 323 | ULONG v5; // esi 324 | unsigned __int32 v6; // eax 325 | unsigned __int16 v8; // ax 326 | unsigned __int8 v9; // al 327 | ULONG AddressSpace; // [rsp+30h] [rbp-48h] BYREF 328 | PHYSICAL_ADDRESS BusAddress; // [rsp+38h] [rbp-40h] BYREF 329 | 330 | v3 = a2[6]; 331 | v4 = *(_BYTE **)(a1 + 24); 332 | switch ( v3 ) 333 | { 334 | case 0xA0406400: 335 | v5 = 1; 336 | break; 337 | case 0xA0406404: 338 | v5 = 2; 339 | break; 340 | case 0xA0406408: 341 | v5 = 4; 342 | break; 343 | default: 344 | v5 = AddressSpace; 345 | break; 346 | } 347 | if ( a2[4] != 4 || a2[2] < v5 ) 348 | return 3221225485i64; 349 | BusAddress.QuadPart = *(unsigned int *)v4; 350 | AddressSpace = 1; 351 | HalTranslateBusAddress(Isa, 0, BusAddress, &AddressSpace, &BusAddress); 352 | if ( AddressSpace == 1 ) 353 | { 354 | switch ( v3 ) 355 | { 356 | case 0xA0406400: 357 | v9 = __inbyte(BusAddress.LowPart); 358 | *v4 = v9; 359 | *(_QWORD *)(a1 + 56) = v5; 360 | return 0i64; 361 | case 0xA0406404: 362 | v8 = __inword(BusAddress.LowPart); 363 | *(_WORD *)v4 = v8; 364 | *(_QWORD *)(a1 + 56) = v5; 365 | return 0i64; 366 | case 0xA0406408: 367 | v6 = __indword(BusAddress.LowPart); 368 | *(_DWORD *)v4 = v6; 369 | *(_QWORD *)(a1 + 56) = v5; 370 | return 0i64; 371 | } 372 | } 373 | else 374 | { 375 | switch ( v3 ) 376 | { 377 | case -1606392832: 378 | *v4 = *(_BYTE *)BusAddress.LowPart; 379 | break; 380 | case -1606392828: 381 | *(_WORD *)v4 = *(_WORD *)BusAddress.LowPart; 382 | *(_QWORD *)(a1 + 56) = v5; 383 | return 0i64; 384 | case -1606392824: 385 | *(_DWORD *)v4 = *(_DWORD *)BusAddress.LowPart; 386 | *(_QWORD *)(a1 + 56) = v5; 387 | return 0i64; 388 | } 389 | } 390 | *(_QWORD *)(a1 + 56) = v5; 391 | return 0i64; 392 | } 393 | ``` 394 | 395 | ### IOCTL 0xA040244C 396 | 397 | This code triggers memory map operation. The operation is eventually completed in function below. 398 | 399 | ```c 400 | __int64 __fastcall sub_11620(__int64 a1, __int64 a2, __int64 a3, char is32bitprocess) 401 | { 402 | __int64 v5; // rdi 403 | _DWORD *v6; // r13 404 | NTSTATUS v7; // ebx 405 | HANDLE v8; // rcx 406 | _DWORD *v9; // r14 407 | DWORD v10; // ecx 408 | DWORD LowPart; // eax 409 | void *SectionHandle; // [rsp+50h] [rbp-D8h] BYREF 410 | ULONG AddressSpace; // [rsp+58h] [rbp-D0h] BYREF 411 | LARGE_INTEGER TranslatedAddress; // [rsp+60h] [rbp-C8h] BYREF 412 | union _LARGE_INTEGER SectionOffset; // [rsp+68h] [rbp-C0h] BYREF 413 | HANDLE Handle; // [rsp+70h] [rbp-B8h] BYREF 414 | ULONG_PTR ViewSize; // [rsp+78h] [rbp-B0h] BYREF 415 | PHYSICAL_ADDRESS BusAddress; // [rsp+80h] [rbp-A8h] BYREF 416 | PVOID Object; // [rsp+88h] [rbp-A0h] BYREF 417 | PVOID v21; // [rsp+90h] [rbp-98h] BYREF 418 | ULONG v22; // [rsp+98h] [rbp-90h] BYREF 419 | PVOID BaseAddress; // [rsp+A0h] [rbp-88h] BYREF 420 | struct _OBJECT_ATTRIBUTES ObjectAttributes; // [rsp+A8h] [rbp-80h] BYREF 421 | struct _UNICODE_STRING DestinationString; // [rsp+D8h] [rbp-50h] BYREF 422 | 423 | Handle = 0i64; 424 | v21 = 0i64; 425 | LODWORD(SectionHandle) = 0; 426 | LODWORD(Object) = 0; 427 | v5 = *(_QWORD *)(a2 + 24); 428 | if ( is32bitprocess ) 429 | { 430 | v6 = *(_DWORD **)(a2 + 24); 431 | if ( *(_DWORD *)(a3 + 16) < 0x18u || *(_DWORD *)(a3 + 8) < 4u ) 432 | { 433 | v7 = -1073741670; 434 | goto LABEL_5; 435 | } 436 | v9 = v21; 437 | } 438 | else 439 | { 440 | v9 = *(_DWORD **)(a2 + 24); 441 | if ( *(_DWORD *)(a3 + 16) < 0x18u || *(_DWORD *)(a3 + 8) < 8u ) 442 | return (unsigned int)-1073741670; 443 | v6 = v21; 444 | } 445 | AddressSpace = *(_DWORD *)(v5 + 16); 446 | v22 = AddressSpace; 447 | RtlInitUnicodeString(&DestinationString, L"\\Device\\PhysicalMemory"); 448 | ObjectAttributes.Length = 48; 449 | ObjectAttributes.RootDirectory = 0i64; 450 | ObjectAttributes.Attributes = 64; 451 | ObjectAttributes.ObjectName = &DestinationString; 452 | ObjectAttributes.SecurityDescriptor = 0i64; 453 | ObjectAttributes.SecurityQualityOfService = 0i64; 454 | if ( is32bitprocess ) 455 | { 456 | v7 = ZwOpenSection(&SectionHandle, 0xF001Fu, &ObjectAttributes); 457 | if ( v7 < 0 ) 458 | goto LABEL_5; 459 | v7 = ObReferenceObjectByHandle((HANDLE)(int)SectionHandle, 0xF001Fu, 0i64, 0, &Object, 0i64); 460 | if ( v7 < 0 ) 461 | goto LABEL_5; 462 | } 463 | else 464 | { 465 | v7 = ZwOpenSection(&Handle, 0xF001Fu, &ObjectAttributes); 466 | if ( v7 < 0 ) 467 | goto LABEL_32; 468 | v7 = ObReferenceObjectByHandle(Handle, 0xF001Fu, 0i64, 0, &v21, 0i64); 469 | if ( v7 < 0 ) 470 | goto LABEL_32; 471 | } 472 | BusAddress.QuadPart = *(_QWORD *)(v5 + 8) + *(_DWORD *)(v5 + 20) + (unsigned int)(unsigned __int16)*(_DWORD *)(v5 + 8); 473 | if ( !HalTranslateBusAddress( 474 | *(INTERFACE_TYPE *)v5, 475 | *(_DWORD *)(v5 + 4), 476 | *(PHYSICAL_ADDRESS *)(v5 + 8), 477 | &AddressSpace, 478 | &TranslatedAddress) 479 | || !HalTranslateBusAddress(*(INTERFACE_TYPE *)v5, *(_DWORD *)(v5 + 4), BusAddress, &v22, &BusAddress) 480 | || (v10 = BusAddress.LowPart - TranslatedAddress.LowPart, 481 | ViewSize = BusAddress.QuadPart - TranslatedAddress.QuadPart, 482 | BusAddress.LowPart == TranslatedAddress.LowPart) ) 483 | { 484 | v7 = -1073741823; 485 | goto LABEL_5; 486 | } 487 | if ( AddressSpace ) 488 | { 489 | LowPart = TranslatedAddress.LowPart; 490 | if ( is32bitprocess ) 491 | { 492 | *v6 = TranslatedAddress.LowPart; 493 | v7 = 0; 494 | goto LABEL_5; 495 | } 496 | goto LABEL_30; 497 | } 498 | SectionOffset = TranslatedAddress; 499 | if ( !is32bitprocess ) 500 | { 501 | BaseAddress = 0i64; 502 | v7 = ZwMapViewOfSection( 503 | Handle, 504 | (HANDLE)0xFFFFFFFFFFFFFFFFi64, 505 | &BaseAddress, 506 | 0i64, 507 | v10, 508 | &SectionOffset, 509 | &ViewSize, 510 | ViewShare, 511 | 0, 512 | 4u); 513 | if ( v7 >= 0 ) 514 | { 515 | LowPart = TranslatedAddress.LowPart + (_DWORD)BaseAddress - SectionOffset.LowPart; 516 | LABEL_30: 517 | *v9 = LowPart; 518 | v7 = 0; 519 | goto LABEL_5; 520 | } 521 | LABEL_32: 522 | v8 = Handle; 523 | if ( Handle ) 524 | goto LABEL_33; 525 | return (unsigned int)v7; 526 | } 527 | HIDWORD(SectionHandle) = 0; 528 | v7 = ZwMapViewOfSection( 529 | (HANDLE)(int)SectionHandle, 530 | (HANDLE)0xFFFFFFFFFFFFFFFFi64, 531 | (void **)((char *)&SectionHandle + 4), 532 | 0i64, 533 | v10, 534 | &SectionOffset, 535 | &ViewSize, 536 | ViewShare, 537 | 0, 538 | 4u); 539 | if ( v7 >= 0 ) 540 | { 541 | HIDWORD(SectionHandle) += TranslatedAddress.LowPart - SectionOffset.LowPart; 542 | *v6 = HIDWORD(SectionHandle); 543 | v7 = 0; 544 | } 545 | LABEL_5: 546 | if ( !is32bitprocess ) 547 | goto LABEL_32; 548 | if ( (_DWORD)SectionHandle ) 549 | { 550 | v8 = (HANDLE)(int)SectionHandle; 551 | LABEL_33: 552 | ZwClose(v8); 553 | } 554 | return (unsigned int)v7; 555 | } 556 | ``` 557 | 558 | -------------------------------------------------------------------------------- /CVE-2024-33219/AsIO64.sys: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DriverHunter/Win-Driver-EXP/21726ae8475c10c893ae35f2b744dee8d7390057/CVE-2024-33219/AsIO64.sys -------------------------------------------------------------------------------- /CVE-2024-33219/README.md: -------------------------------------------------------------------------------- 1 | # Vulnerable Driver AsIO64.sys in ASUS SABERTOOTH X99 Driver v1.0.1.0 2 | 3 | --- 4 | 5 | Many vulnerability exits in driver AsIO64.sys, which allows low-privileged users to map arbitrary physical memory, read and write arbitary i/o port and even read/write arbitary MSR via specially crafted IOCTL requests . This can be exploited for privilege escalation, code execution under high privileges, and information disclosure. These signed drivers can also be used to bypass the Microsoft driver-signing policy to deploy malicious code. 6 | 7 | 8 | 9 | ## version 10 | 11 | 1.0.1.0 12 | 13 | ## Vulnerability causes 14 | 15 | AsIO64.sys provides the functionality of mapping physical memory and read/write I/O ports and arbitrary read/write MSR, but it does not restrict the privileges of the caller, resulting in low-privileged users being able to call the driver and execute corresponding functions through DeviceIoControl. 16 | 17 | ~~~c 18 | __int64 __fastcall sub_119A0(__int64 a1, IRP *a2)//ioctler 19 | { 20 | BOOLEAN v4; // si 21 | struct _IO_STACK_LOCATION *CurrentStackLocation; // rdx 22 | NTSTATUS v6; // ebx 23 | UCHAR MajorFunction; // al 24 | unsigned int LowPart; // eax 25 | void *Type; // rdx 26 | ULONG_PTR v10; // rax 27 | struct _IRP *MasterIrp; // rbx 28 | PVOID ContiguousMemory; // rax 29 | __int64 v14; // [rsp+20h] [rbp-38h] 30 | 31 | v4 = IoIs32bitProcess(a2); 32 | a2->IoStatus.Information = 0i64; 33 | CurrentStackLocation = a2->Tail.Overlay.CurrentStackLocation; 34 | v6 = -1073741822; 35 | MajorFunction = CurrentStackLocation->MajorFunction; 36 | if ( !CurrentStackLocation->MajorFunction || MajorFunction == 2 ) 37 | { 38 | LABEL_38: 39 | v6 = 0; 40 | goto LABEL_39; 41 | } 42 | if ( MajorFunction != 14 ) 43 | goto LABEL_39; 44 | LowPart = CurrentStackLocation->Parameters.Read.ByteOffset.LowPart; 45 | if ( LowPart > 0xA040A444 ) 46 | { 47 | switch ( LowPart ) 48 | { 49 | case 0xA040A448: 50 | goto LABEL_22; 51 | case 0xA040A45C: 52 | v6 = sub_110B0((__int64)a2, (__int64)CurrentStackLocation);// wrmsr 53 | if ( v6 >= 0 ) 54 | a2->IoStatus.Information = 8i64; 55 | break; 56 | case 0xA040A460: 57 | v6 = sub_11040((__int64)a2, (__int64)CurrentStackLocation);// rdmsr 58 | if ( v6 >= 0 ) 59 | a2->IoStatus.Information = 8i64; 60 | break; 61 | case 0xA040A464: 62 | v6 = sub_11160(a2); 63 | if ( v6 >= 0 ) 64 | a2->IoStatus.Information = 4i64; 65 | break; 66 | case 0xA040A480: 67 | goto LABEL_32; 68 | case 0xA040A488: 69 | MasterIrp = a2->AssociatedIrp.MasterIrp; 70 | ContiguousMemory = MmAllocateContiguousMemory( 71 | *(unsigned int *)&MasterIrp->Type, 72 | (PHYSICAL_ADDRESS)0xFFFFFFFFi64); 73 | HIDWORD(v14) = (_DWORD)ContiguousMemory; 74 | LODWORD(v14) = MmGetPhysicalAddress(ContiguousMemory).LowPart; 75 | *(_QWORD *)&MasterIrp->Type = v14; 76 | a2->IoStatus.Information = 8i64; 77 | goto LABEL_38; 78 | case 0xA040A48C: 79 | goto LABEL_38; 80 | default: 81 | goto LABEL_39; 82 | } 83 | goto LABEL_39; 84 | } 85 | if ( LowPart == 0xA040A444 ) 86 | { 87 | LABEL_22: 88 | v6 = sub_11410(a2, CurrentStackLocation, v4);// out primitive 89 | goto LABEL_39; 90 | } 91 | if ( LowPart > 0xA0406404 ) 92 | { 93 | if ( LowPart == -1606392824 ) 94 | goto LABEL_11; 95 | if ( LowPart == -1606392744 ) 96 | { 97 | v6 = sub_11000(a2); 98 | if ( v6 >= 0 ) 99 | a2->IoStatus.Information = 8i64; 100 | goto LABEL_39; 101 | } 102 | if ( LowPart != -1606376384 ) 103 | goto LABEL_39; 104 | goto LABEL_22; 105 | } 106 | switch ( LowPart ) 107 | { 108 | case 0xA0406404: 109 | LABEL_11: 110 | v6 = sub_11260(a2, CurrentStackLocation, v4);// in primitive 111 | break; 112 | case 0xA040244C: 113 | LABEL_32: 114 | v6 = sub_115C0(a1, a2, a2->Tail.Overlay.CurrentStackLocation, v4);// map primitive 115 | if ( v6 < 0 ) 116 | { 117 | a2->IoStatus.Status = -1073741811; 118 | } 119 | else 120 | { 121 | v10 = 8i64; 122 | if ( v4 ) 123 | v10 = 4i64; 124 | a2->IoStatus.Information = v10; 125 | } 126 | break; 127 | case 0xA0402450: 128 | if ( v4 ) 129 | { 130 | if ( CurrentStackLocation->Parameters.Create.Options >= 4 ) 131 | { 132 | Type = (void *)a2->AssociatedIrp.MasterIrp->Type; 133 | LABEL_15: 134 | v6 = ZwUnmapViewOfSection((HANDLE)0xFFFFFFFFFFFFFFFFi64, Type); 135 | break; 136 | } 137 | } 138 | else if ( CurrentStackLocation->Parameters.Create.Options >= 8 ) 139 | { 140 | Type = *(void **)a2->AssociatedIrp.MasterIrp; 141 | goto LABEL_15; 142 | } 143 | v6 = -1073741670; 144 | break; 145 | case 0xA0406400: 146 | goto LABEL_11; 147 | } 148 | LABEL_39: 149 | a2->IoStatus.Status = v6; 150 | IofCompleteRequest(a2, 0); 151 | return (unsigned int)v6; 152 | } 153 | ~~~ 154 | 155 | ### IOCTL 0xA040A45C 156 | 157 | This IOCTL code triggers the write operation on MSR. 158 | 159 | ~~~c 160 | __int64 __fastcall sub_110B0(__int64 a1, __int64 a2) 161 | { 162 | unsigned int *v3; // rcx 163 | unsigned int v4; // eax 164 | unsigned __int64 v5; // rdx 165 | unsigned int v6; // ecx 166 | 167 | v3 = *(unsigned int **)(a1 + 24); 168 | if ( *(_DWORD *)(a2 + 16) != 12 || *(_DWORD *)(a2 + 8) < 8u ) 169 | return 3221225485i64; 170 | v4 = v3[1]; 171 | v5 = (v4 + ((unsigned __int64)v3[2] << 32)) >> 32; 172 | v6 = *v3; 173 | __writemsr(v6, __PAIR64__(v5, v4)); 174 | **(_QWORD **)(a1 + 24) = __readmsr(v6); 175 | *(_QWORD *)(a1 + 56) = 8i64; 176 | return 0i64; 177 | } 178 | ~~~ 179 | 180 | 181 | 182 | ### IOCTL 0xA040A460 183 | 184 | This IOCTL code triggers the read operation on MSR. 185 | 186 | ~~~c 187 | __int64 __fastcall sub_11040(__int64 a1, __int64 a2) 188 | { 189 | _DWORD *v2; // r10 190 | unsigned __int64 v3; // r8 191 | 192 | v2 = *(_DWORD **)(a1 + 24); 193 | if ( *(_DWORD *)(a2 + 16) != 4 || *(_DWORD *)(a2 + 8) < 4u ) 194 | return 3221225485i64; 195 | v3 = __readmsr(0x2Du) >> 32; 196 | __writemsr(0x2Du, (unsigned int)*v2 + (v3 << 32)); 197 | *v2 = v3; 198 | *(_QWORD *)(a1 + 56) = 4i64; 199 | return 0i64; 200 | } 201 | ~~~ 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | ### IOCTL 0xA040A440(out byte), 0xA040A444(out word), 0xA040A448(out dword) 210 | 211 | This code triggers port out operation. The operation is eventually completed in function below. 212 | 213 | ```c 214 | __int64 __fastcall sub_11410(__int64 a1, __int64 a2, char a3) 215 | { 216 | int v4; // r12d 217 | unsigned int v5; // edx 218 | unsigned __int8 *v6; // rdi 219 | unsigned __int8 *QuadPart; // rbx 220 | ULONG v8; // eax 221 | unsigned int v10; // eax 222 | ULONG AddressSpace; // [rsp+30h] [rbp-48h] BYREF 223 | PHYSICAL_ADDRESS BusAddress; // [rsp+38h] [rbp-40h] BYREF 224 | 225 | v4 = *(_DWORD *)(a2 + 24); 226 | v5 = *(_DWORD *)(a2 + 16); 227 | if ( a3 ) 228 | { 229 | v6 = *(unsigned __int8 **)(a1 + 24); 230 | QuadPart = (unsigned __int8 *)BusAddress.QuadPart; 231 | } 232 | else 233 | { 234 | QuadPart = *(unsigned __int8 **)(a1 + 24); 235 | v6 = (unsigned __int8 *)BusAddress.QuadPart; 236 | } 237 | switch ( v4 ) 238 | { 239 | case 0xA040A440: 240 | v8 = 1; 241 | break; 242 | case 0xA040A444: 243 | v8 = 2; 244 | break; 245 | case 0xA040A448: 246 | v8 = 4; 247 | break; 248 | default: 249 | v8 = AddressSpace; 250 | break; 251 | } 252 | if ( v5 < (unsigned __int64)v8 + 4 ) 253 | return 3221225485i64; 254 | if ( a3 ) 255 | { 256 | v10 = *(_DWORD *)v6; 257 | v6 += 4; 258 | } 259 | else 260 | { 261 | v10 = *(_DWORD *)QuadPart; 262 | QuadPart += 4; 263 | } 264 | BusAddress.QuadPart = v10; 265 | AddressSpace = 1; 266 | HalTranslateBusAddress(Isa, 0, (PHYSICAL_ADDRESS)v10, &AddressSpace, &BusAddress); 267 | if ( AddressSpace == 1 ) 268 | { 269 | switch ( v4 ) 270 | { 271 | case 0xA040A440: 272 | if ( a3 ) 273 | __outbyte(BusAddress.LowPart, *v6); 274 | else 275 | __outbyte((unsigned __int16)&BusAddress, *QuadPart); 276 | break; 277 | case 0xA040A444: 278 | if ( a3 ) 279 | __outword(BusAddress.LowPart, *(_WORD *)v6); 280 | else 281 | __outword((unsigned __int16)&BusAddress, *(_WORD *)QuadPart); 282 | break; 283 | case 0xA040A448: 284 | if ( a3 ) 285 | __outdword(BusAddress.LowPart, *(_DWORD *)v6); 286 | else 287 | __outdword((unsigned __int16)&BusAddress, *(_DWORD *)QuadPart); 288 | break; 289 | } 290 | return 0i64; 291 | } 292 | switch ( v4 ) 293 | { 294 | case 0xA040A440: 295 | if ( a3 ) 296 | *(_BYTE *)BusAddress.LowPart = *v6; 297 | else 298 | LOBYTE(BusAddress.LowPart) = *QuadPart; 299 | goto LABEL_41; 300 | case 0xA040A444: 301 | if ( a3 ) 302 | *(_WORD *)BusAddress.LowPart = *(_WORD *)v6; 303 | else 304 | LOWORD(BusAddress.LowPart) = *(_WORD *)QuadPart; 305 | goto LABEL_41; 306 | case 0xA040A448: 307 | if ( a3 ) 308 | *(_DWORD *)BusAddress.LowPart = *(_DWORD *)v6; 309 | else 310 | BusAddress.LowPart = *(_DWORD *)QuadPart; 311 | LABEL_41: 312 | _mm_sfence(); 313 | break; 314 | } 315 | return 0i64; 316 | } 317 | ``` 318 | 319 | 320 | 321 | ### IOCTL 0xA0406400(in byte), 0xA0406404(in word) , 0xA0406408(in dword) 322 | 323 | This code triggers port in operation. The operation is eventually completed in function below. 324 | 325 | ```c 326 | __int64 __fastcall sub_11260(__int64 a1, _DWORD *a2) 327 | { 328 | int v3; // ebx 329 | _BYTE *v4; // rdi 330 | ULONG v5; // esi 331 | unsigned __int32 v6; // eax 332 | unsigned __int16 v8; // ax 333 | unsigned __int8 v9; // al 334 | ULONG AddressSpace; // [rsp+30h] [rbp-48h] BYREF 335 | PHYSICAL_ADDRESS BusAddress; // [rsp+38h] [rbp-40h] BYREF 336 | 337 | v3 = a2[6]; 338 | v4 = *(_BYTE **)(a1 + 24); 339 | switch ( v3 ) 340 | { 341 | case 0xA0406400: 342 | v5 = 1; 343 | break; 344 | case 0xA0406404: 345 | v5 = 2; 346 | break; 347 | case 0xA0406408: 348 | v5 = 4; 349 | break; 350 | default: 351 | v5 = AddressSpace; 352 | break; 353 | } 354 | if ( a2[4] != 4 || a2[2] < v5 ) 355 | return 3221225485i64; 356 | BusAddress.QuadPart = *(unsigned int *)v4; 357 | AddressSpace = 1; 358 | HalTranslateBusAddress(Isa, 0, BusAddress, &AddressSpace, &BusAddress); 359 | if ( AddressSpace == 1 ) 360 | { 361 | switch ( v3 ) 362 | { 363 | case 0xA0406400: 364 | v9 = __inbyte(BusAddress.LowPart); 365 | *v4 = v9; 366 | *(_QWORD *)(a1 + 56) = v5; 367 | return 0i64; 368 | case 0xA0406404: 369 | v8 = __inword(BusAddress.LowPart); 370 | *(_WORD *)v4 = v8; 371 | *(_QWORD *)(a1 + 56) = v5; 372 | return 0i64; 373 | case 0xA0406408: 374 | v6 = __indword(BusAddress.LowPart); 375 | *(_DWORD *)v4 = v6; 376 | *(_QWORD *)(a1 + 56) = v5; 377 | return 0i64; 378 | } 379 | } 380 | else 381 | { 382 | switch ( v3 ) 383 | { 384 | case 0xA0406400: 385 | *v4 = *(_BYTE *)BusAddress.LowPart; 386 | break; 387 | case 0xA0406404: 388 | *(_WORD *)v4 = *(_WORD *)BusAddress.LowPart; 389 | *(_QWORD *)(a1 + 56) = v5; 390 | return 0i64; 391 | case 0xA0406408: 392 | *(_DWORD *)v4 = *(_DWORD *)BusAddress.LowPart; 393 | *(_QWORD *)(a1 + 56) = v5; 394 | return 0i64; 395 | } 396 | } 397 | *(_QWORD *)(a1 + 56) = v5; 398 | return 0i64; 399 | } 400 | ``` 401 | 402 | 403 | 404 | ### IOCTL 0xA040244C 405 | 406 | This code triggers memory map operation. The operation is eventually completed in function below. 407 | 408 | ```c 409 | __int64 __fastcall sub_115C0(__int64 a1, __int64 a2, __int64 a3, char a4) 410 | { 411 | __int64 v5; // rdi 412 | _DWORD *v6; // r13 413 | NTSTATUS v7; // ebx 414 | void *v8; // rcx 415 | _DWORD *v10; // r14 416 | LARGE_INTEGER v11; // rax 417 | DWORD v12; // ecx 418 | DWORD LowPart; // eax 419 | LARGE_INTEGER TranslatedAddress; // [rsp+50h] [rbp-D8h] BYREF 420 | ULONG AddressSpace; // [rsp+58h] [rbp-D0h] BYREF 421 | union _LARGE_INTEGER SectionOffset; // [rsp+60h] [rbp-C8h] BYREF 422 | void *SectionHandle; // [rsp+68h] [rbp-C0h] BYREF 423 | HANDLE Handle; // [rsp+70h] [rbp-B8h] BYREF 424 | PHYSICAL_ADDRESS BusAddress; // [rsp+78h] [rbp-B0h] BYREF 425 | PVOID BaseAddress; // [rsp+80h] [rbp-A8h] BYREF 426 | ULONG_PTR ViewSize; // [rsp+88h] [rbp-A0h] BYREF 427 | PVOID v22; // [rsp+90h] [rbp-98h] BYREF 428 | ULONG v23; // [rsp+98h] [rbp-90h] BYREF 429 | PVOID v24; // [rsp+A0h] [rbp-88h] BYREF 430 | PVOID Object; // [rsp+A8h] [rbp-80h] BYREF 431 | struct _OBJECT_ATTRIBUTES ObjectAttributes; // [rsp+B0h] [rbp-78h] BYREF 432 | struct _UNICODE_STRING DestinationString; // [rsp+E0h] [rbp-48h] BYREF 433 | 434 | Handle = 0i64; 435 | v22 = 0i64; 436 | SectionHandle = 0i64; 437 | Object = 0i64; 438 | v5 = *(_QWORD *)(a2 + 24); 439 | if ( a4 ) 440 | { 441 | v6 = *(_DWORD **)(a2 + 24); 442 | if ( *(_DWORD *)(a3 + 16) < 0x18u || *(_DWORD *)(a3 + 8) < 4u ) 443 | { 444 | v7 = -1073741670; 445 | goto LABEL_5; 446 | } 447 | v10 = v22; 448 | } 449 | else 450 | { 451 | v10 = *(_DWORD **)(a2 + 24); 452 | if ( *(_DWORD *)(a3 + 16) < 0x18u || *(_DWORD *)(a3 + 8) < 8u ) 453 | return (unsigned int)-1073741670; 454 | v6 = v22; 455 | } 456 | AddressSpace = *(_DWORD *)(v5 + 16); 457 | v23 = AddressSpace; 458 | RtlInitUnicodeString(&DestinationString, L"\\Device\\PhysicalMemory"); 459 | ObjectAttributes.Length = 48; 460 | ObjectAttributes.RootDirectory = 0i64; 461 | ObjectAttributes.Attributes = 576; 462 | ObjectAttributes.ObjectName = &DestinationString; 463 | ObjectAttributes.SecurityDescriptor = 0i64; 464 | ObjectAttributes.SecurityQualityOfService = 0i64; 465 | if ( a4 ) 466 | { 467 | v7 = ZwOpenSection(&SectionHandle, 0xF001Fu, &ObjectAttributes); 468 | if ( v7 < 0 ) 469 | goto LABEL_5; 470 | v7 = ObReferenceObjectByHandle(SectionHandle, 0xF001Fu, 0i64, 0, &Object, 0i64); 471 | if ( v7 < 0 ) 472 | goto LABEL_5; 473 | } 474 | else 475 | { 476 | v7 = ZwOpenSection(&Handle, 0xF001Fu, &ObjectAttributes); 477 | if ( v7 < 0 ) 478 | goto LABEL_6; 479 | v7 = ObReferenceObjectByHandle(Handle, 0xF001Fu, 0i64, 0, &v22, 0i64); 480 | if ( v7 < 0 ) 481 | goto LABEL_6; 482 | } 483 | BusAddress.QuadPart = *(_QWORD *)(v5 + 8) + *(_DWORD *)(v5 + 20) + (unsigned int)(unsigned __int16)*(_DWORD *)(v5 + 8); 484 | if ( HalTranslateBusAddress( 485 | *(INTERFACE_TYPE *)v5, 486 | *(_DWORD *)(v5 + 4), 487 | *(PHYSICAL_ADDRESS *)(v5 + 8), 488 | &AddressSpace, 489 | &TranslatedAddress) 490 | && HalTranslateBusAddress(*(INTERFACE_TYPE *)v5, *(_DWORD *)(v5 + 4), BusAddress, &v23, &BusAddress) ) 491 | { 492 | v11 = TranslatedAddress; 493 | } 494 | else 495 | { 496 | v11 = *(LARGE_INTEGER *)(v5 + 8); 497 | TranslatedAddress = v11; 498 | } 499 | v12 = BusAddress.LowPart - v11.LowPart; 500 | ViewSize = BusAddress.QuadPart - v11.QuadPart; 501 | if ( BusAddress.LowPart == v11.LowPart ) 502 | { 503 | v7 = -1073741823; 504 | goto LABEL_5; 505 | } 506 | if ( AddressSpace ) 507 | { 508 | LowPart = TranslatedAddress.LowPart; 509 | if ( a4 ) 510 | { 511 | *v6 = TranslatedAddress.LowPart; 512 | v7 = 0; 513 | goto LABEL_5; 514 | } 515 | goto LABEL_34; 516 | } 517 | SectionOffset = v11; 518 | if ( a4 ) 519 | { 520 | BaseAddress = 0i64; 521 | v7 = ZwMapViewOfSection( 522 | SectionHandle, 523 | (HANDLE)0xFFFFFFFFFFFFFFFFi64, 524 | &BaseAddress, 525 | 0i64, 526 | v12, 527 | &SectionOffset, 528 | &ViewSize, 529 | ViewShare, 530 | 0, 531 | 4u); 532 | if ( v7 >= 0 ) 533 | { 534 | LODWORD(BaseAddress) = TranslatedAddress.LowPart - SectionOffset.LowPart + (_DWORD)BaseAddress; 535 | *v6 = (_DWORD)BaseAddress; 536 | v7 = 0; 537 | } 538 | LABEL_5: 539 | v8 = SectionHandle; 540 | if ( a4 ) 541 | goto LABEL_7; 542 | goto LABEL_6; 543 | } 544 | v24 = 0i64; 545 | v7 = ZwMapViewOfSection( 546 | Handle, 547 | (HANDLE)0xFFFFFFFFFFFFFFFFi64, 548 | &v24, 549 | 0i64, 550 | v12, 551 | &SectionOffset, 552 | &ViewSize, 553 | ViewShare, 554 | 0, 555 | 4u); 556 | if ( v7 >= 0 ) 557 | { 558 | LowPart = TranslatedAddress.LowPart + (_DWORD)v24 - SectionOffset.LowPart; 559 | LABEL_34: 560 | *v10 = LowPart; 561 | v7 = 0; 562 | goto LABEL_5; 563 | } 564 | LABEL_6: 565 | v8 = Handle; 566 | LABEL_7: 567 | if ( v8 ) 568 | ZwClose(v8); 569 | return (unsigned int)v7; 570 | } 571 | ``` 572 | 573 | 574 | 575 | -------------------------------------------------------------------------------- /CVE-2024-33220/AsIO3_64.sys: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DriverHunter/Win-Driver-EXP/21726ae8475c10c893ae35f2b744dee8d7390057/CVE-2024-33220/AsIO3_64.sys -------------------------------------------------------------------------------- /CVE-2024-33220/README.md: -------------------------------------------------------------------------------- 1 | # Vulnerable Driver AslO3_64.sys in ASUS AISuite3 v3.03.36 3.03.36 2 | 3 | --- 4 | 5 | Many vulnerability exits in driver AslO3_64.sys, which allows low-privileged users to map arbitrary physical memory, read and write arbitary i/o port and even read/write arbitary MSR via specially crafted IOCTL requests . This can be exploited for privilege escalation, code execution under high privileges, and information disclosure. These signed drivers can also be used to bypass the Microsoft driver-signing policy to deploy malicious code. 6 | 7 | 8 | 9 | ## version 10 | 11 | 3.03.36 12 | 13 | ## Vulnerability causes 14 | 15 | AslO3_64.sys provides the functionality of mapping physical memory and read/write I/O ports and arbitrary read/write MSR, but it does not restrict the privileges of the caller, resulting in low-privileged users being able to call the driver and execute corresponding functions through DeviceIoControl. 16 | 17 | ~~~c 18 | __int64 __fastcall sub_140001930(PDEVICE_OBJECT DeviceObject, PIRP Irp) 19 | { 20 | __int64 v4; // rcx 21 | __int64 v5; // r9 22 | int v6; // r14d 23 | struct _IO_STACK_LOCATION *CurrentStackLocation; // rdx 24 | void **DeviceExtension; // rdi 25 | struct _IRP *MasterIrp; // r12 26 | unsigned int Options; // r13d 27 | __int64 Length; // r8 28 | signed int Status; // esi 29 | UCHAR MajorFunction; // al 30 | unsigned int LowPart; // ecx 31 | struct _IRP *v15; // r8 32 | unsigned __int16 MdlAddress; // dx 33 | struct _IRP *v17; // rdx 34 | char v18; // al 35 | unsigned __int8 v19; // al 36 | unsigned __int16 v20; // dx 37 | unsigned int MdlAddress_high; // eax 38 | unsigned __int16 v22; // dx 39 | char v23; // al 40 | unsigned __int32 v24; // eax 41 | unsigned __int32 v25; // eax 42 | unsigned __int16 v26; // dx 43 | struct _IRP *v27; // r8 44 | char v28; // al 45 | char Type; // al 46 | unsigned __int32 v30; // eax 47 | struct _IRP *v31; // r8 48 | struct _IRP *v32; // r8 49 | unsigned __int16 v33; // cx 50 | _BYTE *v34; // r9 51 | unsigned __int8 v35; // al 52 | struct _IRP *v36; // r8 53 | unsigned __int16 v37; // cx 54 | _BYTE *v38; // r9 55 | unsigned __int8 v39; // al 56 | struct _IRP *v40; // rcx 57 | unsigned __int16 v41; // dx 58 | __int64 v42; // r8 59 | unsigned __int32 v43; // eax 60 | struct _IRP *v44; // rbx 61 | ULONG v45; // edx 62 | ULONG v46; // r9d 63 | char v47; // al 64 | int Flags_low; // eax 65 | struct _IRP *v49; // r12 66 | ULONG BusDataByOffset; // eax 67 | int Type_low; // edx 68 | void *v52; // rcx 69 | SIZE_T Flags; // rax 70 | SIZE_T v54; // rdi 71 | __int64 result; // rax 72 | struct _IRP *v56; // rdi 73 | ULONG_PTR v57; // rbx 74 | unsigned int v58; // ebx 75 | unsigned int v59; // ebx 76 | struct _IRP *v60; // r10 77 | __int64 v61; // r8 78 | NTSTATUS v62; // eax 79 | struct _IRP *v63; // r10 80 | __int64 v64; // r8 81 | unsigned __int16 v65; // bx 82 | int v66; // eax 83 | PVOID ContiguousMemory; // rax 84 | __int64 v68; // rdi 85 | DWORD v69; // ebx 86 | _QWORD *PoolWithTag; // rax 87 | __int64 v71; // rcx 88 | int v72; // eax 89 | PKEVENT v73; // rax 90 | struct _UNICODE_STRING Buffer; // [rsp+30h] [rbp-88h] BYREF 91 | __int64 v75; // [rsp+40h] [rbp-78h] 92 | int v76; // [rsp+48h] [rbp-70h] 93 | __int16 v77[2]; // [rsp+50h] [rbp-68h] BYREF 94 | unsigned int v78; // [rsp+54h] [rbp-64h] 95 | char v79; // [rsp+58h] [rbp-60h] 96 | __m128i v80; // [rsp+60h] [rbp-58h] BYREF 97 | HANDLE Handle[2]; // [rsp+70h] [rbp-48h] 98 | PVOID Flink; // [rsp+80h] [rbp-38h] BYREF 99 | 100 | *(_QWORD *)&Buffer.Length = Irp; 101 | LOBYTE(v5) = IoIs32bitProcess(Irp); 102 | v6 = 0; 103 | Irp->IoStatus.Information = 0i64; 104 | CurrentStackLocation = Irp->Tail.Overlay.CurrentStackLocation; 105 | DeviceExtension = (void **)DeviceObject->DeviceExtension; 106 | MasterIrp = Irp->AssociatedIrp.MasterIrp; 107 | Options = CurrentStackLocation->Parameters.Create.Options; 108 | Length = CurrentStackLocation->Parameters.Read.Length; 109 | Status = -1073741822; 110 | MajorFunction = CurrentStackLocation->MajorFunction; 111 | if ( !CurrentStackLocation->MajorFunction ) 112 | { 113 | if ( !DeviceExtension[6] ) 114 | { 115 | RtlInitUnicodeString(&Buffer, L"\\BaseNamedObjects\\WaitForIoAccess"); 116 | v73 = IoCreateSynchronizationEvent(&Buffer, DeviceExtension + 6); 117 | DeviceExtension[5] = v73; 118 | if ( !v73 ) 119 | { 120 | IoDeleteDevice(DeviceObject); 121 | return 3221225473i64; 122 | } 123 | } 124 | if ( !(unsigned __int8)sub_140002F54(v4, CurrentStackLocation, Length, v5) ) 125 | { 126 | Status = 0; 127 | if ( (int)sub_140003218() < 0 ) 128 | Status = -1073741790; 129 | goto LABEL_193; 130 | } 131 | sub_140002BA4(); 132 | goto LABEL_192; 133 | } 134 | if ( MajorFunction == 2 ) 135 | { 136 | v62 = sub_140003AF4(v4, CurrentStackLocation, Length, v5); 137 | goto LABEL_169; 138 | } 139 | if ( MajorFunction != 14 ) 140 | goto LABEL_193; 141 | LowPart = CurrentStackLocation->Parameters.Read.ByteOffset.LowPart; 142 | if ( LowPart > 0xA0402014 ) 143 | { 144 | if ( LowPart > 0xA040A45C ) 145 | { 146 | if ( LowPart != -1606376352 ) 147 | { 148 | if ( LowPart == -1606376348 ) 149 | { 150 | v72 = sub_1400016B4(Irp, CurrentStackLocation, Length, v5); 151 | goto LABEL_180; 152 | } 153 | if ( LowPart == 0xA040A480 ) // map primitive 154 | { 155 | LABEL_174: 156 | if ( !(_BYTE)v5 ) 157 | { 158 | if ( Options == 40 ) 159 | { 160 | v80 = *(__m128i *)&MasterIrp->Type; 161 | *(_OWORD *)Handle = *(_OWORD *)&MasterIrp->Flags; 162 | Flink = MasterIrp->ThreadListEntry.Flink; 163 | Status = ((__int64 (__usercall *)@(PHYSICAL_ADDRESS@, PVOID *))sub_140003538)( 164 | (PHYSICAL_ADDRESS)_mm_srli_si128(v80, 8).m128i_i64[0], 165 | &Flink); 166 | if ( Status >= 0 ) 167 | { 168 | *(__m128i *)&MasterIrp->Type = v80; 169 | *(_OWORD *)&MasterIrp->Flags = *(_OWORD *)Handle; 170 | MasterIrp->ThreadListEntry.Flink = (struct _LIST_ENTRY *)Flink; 171 | Irp->IoStatus.Information = 40i64; 172 | } 173 | goto LABEL_193; 174 | } 175 | goto LABEL_154; 176 | } 177 | v72 = sub_140003268((__int64)DeviceObject, (__int64)Irp, (__int64)Irp->Tail.Overlay.CurrentStackLocation, v5); 178 | LABEL_180: 179 | Status = v72; 180 | if ( v72 >= 0 ) 181 | Irp->IoStatus.Information = 4i64; 182 | goto LABEL_193; 183 | } 184 | if ( LowPart == -1606376312 ) 185 | { 186 | if ( *(_DWORD *)&MasterIrp->Type > 0x8000000u ) 187 | goto LABEL_154; 188 | ContiguousMemory = MmAllocateContiguousMemory( 189 | *(unsigned int *)&MasterIrp->Type, 190 | (PHYSICAL_ADDRESS)0xFFFFFFFFi64); 191 | v68 = (unsigned int)ContiguousMemory; 192 | *(_DWORD *)(&Buffer.MaximumLength + 1) = (_DWORD)ContiguousMemory; 193 | v69 = MmGetPhysicalAddress(ContiguousMemory).LowPart; 194 | *(_DWORD *)&Buffer.Length = v69; 195 | PoolWithTag = ExAllocatePoolWithTag(PagedPool, 0x20ui64, 0x705052u); 196 | PoolWithTag[2] = v68; 197 | PoolWithTag[3] = v69; 198 | v71 = qword_1400093F0; 199 | if ( *(__int64 **)(qword_1400093F0 + 8) != &qword_1400093F0 ) 200 | __fastfail(3u); 201 | *PoolWithTag = qword_1400093F0; 202 | PoolWithTag[1] = &qword_1400093F0; 203 | *(_QWORD *)(v71 + 8) = PoolWithTag; 204 | qword_1400093F0 = (__int64)PoolWithTag; 205 | *(_QWORD *)&MasterIrp->Type = *(_QWORD *)&Buffer.Length; 206 | Irp->IoStatus.Information = 8i64; 207 | } 208 | else if ( LowPart != 0xA040A48C ) 209 | { 210 | if ( LowPart == 0xA040A490 ) 211 | { 212 | v62 = ((__int64 (__fastcall *)(PIRP, struct _IO_STACK_LOCATION *, __int64, __int64))sub_140003AB0)( 213 | Irp, 214 | CurrentStackLocation, 215 | Length, 216 | v5); 217 | } 218 | else 219 | { 220 | if ( ((LowPart + 1606376128) & 0xFFFFFFF3) != 0 || LowPart == -1606376116 ) 221 | goto LABEL_193; 222 | LOBYTE(Length) = v5; 223 | v62 = sub_140002918(Irp, CurrentStackLocation, Length); 224 | } 225 | goto LABEL_169; 226 | } 227 | LABEL_192: 228 | Status = 0; 229 | goto LABEL_193; 230 | } 231 | v66 = ((__int64 (__fastcall *)(PIRP, struct _IO_STACK_LOCATION *, __int64, __int64))sub_140003B4C)( 232 | Irp, 233 | CurrentStackLocation, 234 | Length, 235 | v5); 236 | } 237 | else if ( LowPart == 0xA040A45C ) 238 | { 239 | v66 = sub_140003DE8((__int64)Irp, (__int64)CurrentStackLocation, Length, v5); 240 | } 241 | else 242 | { 243 | if ( LowPart <= 0xA0406408 ) 244 | { 245 | if ( LowPart == 0xA0406408 ) 246 | { 247 | LABEL_129: 248 | LOBYTE(Length) = v5; 249 | v62 = ((__int64 (__fastcall *)(PIRP, struct _IO_STACK_LOCATION *, __int64))sub_140002654)(// in primitive 250 | Irp, 251 | CurrentStackLocation, 252 | Length); 253 | goto LABEL_169; 254 | } 255 | if ( LowPart == -1606410216 ) 256 | { 257 | Status = 0; 258 | KeWaitForSingleObject(DeviceExtension[5], Executive, 0, 0, 0i64); 259 | v63 = Irp->AssociatedIrp.MasterIrp; 260 | LOBYTE(v64) = v63->Type; 261 | if ( ((LOBYTE(v63->Type) - 1) & 0xFC) == 0 && (_BYTE)v64 != 3 && Options >= 0x23 ) 262 | { 263 | sub_1400010F0( 264 | *(CSHORT *)((char *)&v63->Type + 1), 265 | *(_DWORD *)((char *)&v63->Size + 1), 266 | v64, 267 | (unsigned int *)((char *)&v63->Size + 5)); 268 | Irp->IoStatus.Information = 35i64; 269 | goto LABEL_92; 270 | } 271 | goto LABEL_91; 272 | } 273 | if ( LowPart != 0xA040244C ) 274 | { 275 | if ( LowPart != 0xA0402450 ) 276 | { 277 | if ( ((LowPart + 0x5FBF9C00) & 0xFFFFFFFB) != 0 ) 278 | goto LABEL_193; 279 | goto LABEL_129; 280 | } 281 | if ( (_BYTE)v5 ) 282 | { 283 | if ( Options < 4 ) 284 | { 285 | Status = 0xC000009A; 286 | goto LABEL_193; 287 | } 288 | v62 = ZwUnmapViewOfSection((HANDLE)0xFFFFFFFFFFFFFFFFi64, (PVOID)*(unsigned int *)&MasterIrp->Type); 289 | LABEL_169: 290 | Status = v62; 291 | goto LABEL_193; 292 | } 293 | if ( Options ) 294 | { 295 | sub_140007380( 296 | &v80, 297 | (unsigned __int64)Irp->AssociatedIrp.MasterIrp, 298 | CurrentStackLocation->Parameters.Create.Options); 299 | v62 = sub_140003BA8(Handle[0]); 300 | goto LABEL_169; 301 | } 302 | LABEL_154: 303 | Status = -1073741811; 304 | goto LABEL_193; 305 | } 306 | goto LABEL_174; 307 | } 308 | if ( LowPart != 0xA0406458 ) 309 | { 310 | if ( ((LowPart + 0x5FBF5BC0) & 0xFFFFFFF3) != 0 || LowPart == 0xA040A44C ) 311 | goto LABEL_193; 312 | if ( (_BYTE)v5 ) 313 | { 314 | LOBYTE(Length) = v5; 315 | v62 = sub_140002774((__int64)Irp, (__int64)CurrentStackLocation, Length);// out primitive 316 | goto LABEL_169; 317 | } 318 | if ( !Options ) 319 | goto LABEL_154; 320 | sub_140007380( 321 | (__m128i *)v77, 322 | (unsigned __int64)Irp->AssociatedIrp.MasterIrp, 323 | CurrentStackLocation->Parameters.Create.Options); 324 | v65 = v77[0]; 325 | if ( (unsigned int)sub_14000130C((unsigned __int16)v77[0]) ) 326 | return 3221225506i64; 327 | switch ( v79 ) 328 | { 329 | case 1: 330 | __outbyte(v65, v78); 331 | break; 332 | case 2: 333 | __outword(v65, v78); 334 | break; 335 | case 4: 336 | __outdword(v65, v78); 337 | break; 338 | } 339 | goto LABEL_192; 340 | } 341 | v66 = sub_1400039D0((__int64)Irp, (__int64)CurrentStackLocation, Length, v5); 342 | } 343 | Status = v66; 344 | if ( v66 >= 0 ) 345 | Irp->IoStatus.Information = 8i64; 346 | goto LABEL_193; 347 | } 348 | if ( LowPart == -1606410220 ) 349 | { 350 | Status = 0; 351 | KeWaitForSingleObject(DeviceExtension[5], Executive, 0, 0, 0i64); 352 | v60 = Irp->AssociatedIrp.MasterIrp; 353 | LOBYTE(v61) = v60->Type; 354 | if ( ((LOBYTE(v60->Type) - 1) & 0xFC) == 0 && (_BYTE)v61 != 3 && Options >= 0x23 ) 355 | { 356 | Buffer = *(struct _UNICODE_STRING *)((char *)&v60->Size + 5); 357 | v75 = *(_QWORD *)((char *)&v60->Flags + 7); 358 | v76 = *(_DWORD *)((char *)&v60->AssociatedIrp.SystemBuffer + 7); 359 | ((void (__fastcall *)(_QWORD, _QWORD, __int64, struct _UNICODE_STRING *))sub_140001000)(// out primitive 360 | *(unsigned __int16 *)((char *)&v60->Type + 1), 361 | *(unsigned int *)((char *)&v60->Size + 1), 362 | v61, 363 | &Buffer); 364 | goto LABEL_92; 365 | } 366 | goto LABEL_91; 367 | } 368 | if ( LowPart <= 0xA0400F80 ) 369 | { 370 | if ( LowPart == -1606414464 ) 371 | { 372 | sub_140004264(Irp, Options, Length, v5); 373 | } 374 | else 375 | { 376 | if ( LowPart <= 0xA0400F6C ) 377 | { 378 | switch ( LowPart ) 379 | { 380 | case 0xA0400F6C: 381 | Status = 0; 382 | KeWaitForSingleObject(DeviceExtension[5], Executive, 0, 0, 0i64); 383 | v31 = Irp->AssociatedIrp.MasterIrp; 384 | if ( LOBYTE(v31->Type) != 1 ) 385 | goto LABEL_91; 386 | __outbyte((unsigned __int16)v31->MdlAddress, BYTE2(v31->MdlAddress)); 387 | v19 = BYTE2(v31->Flags); 388 | v20 = LOWORD(v31->MdlAddress) + 1; 389 | goto LABEL_19; 390 | case 0xA0400F58: 391 | Status = 0; 392 | KeWaitForSingleObject(DeviceExtension[5], Executive, 0, 0, 0i64); 393 | v15 = Irp->AssociatedIrp.MasterIrp; 394 | __outdword(0xCF8u, *(_DWORD *)(&v15->Size + 1)); 395 | Type = v15->Type; 396 | if ( LOBYTE(v15->Type) == 1 ) 397 | { 398 | v24 = __indword(0xCFCu); 399 | goto LABEL_39; 400 | } 401 | if ( Type == 2 ) 402 | { 403 | v25 = __indword(0xCFCu); 404 | goto LABEL_42; 405 | } 406 | if ( Type != 4 ) 407 | goto LABEL_91; 408 | v26 = 3324; 409 | break; 410 | case 0xA0400F5C: 411 | Status = 0; 412 | KeWaitForSingleObject(DeviceExtension[5], Executive, 0, 0, 0i64); 413 | v27 = Irp->AssociatedIrp.MasterIrp; 414 | __outdword(0xCF8u, *(_DWORD *)(&v27->Size + 1)); 415 | v22 = 3324; 416 | __indword(0xCFCu); 417 | v28 = v27->Type; 418 | if ( LOBYTE(v27->Type) == 1 || v28 == 2 ) 419 | { 420 | MdlAddress_high = 0; 421 | } 422 | else 423 | { 424 | if ( v28 != 4 ) 425 | goto LABEL_91; 426 | MdlAddress_high = HIDWORD(v27->MdlAddress); 427 | } 428 | goto LABEL_36; 429 | case 0xA0400F60: 430 | Status = 0; 431 | KeWaitForSingleObject(DeviceExtension[5], Executive, 0, 0, 0i64); 432 | v15 = Irp->AssociatedIrp.MasterIrp; 433 | v23 = v15->Type; 434 | if ( LOBYTE(v15->Type) == 1 ) 435 | { 436 | MdlAddress = (unsigned __int16)v15->MdlAddress; 437 | goto LABEL_26; 438 | } 439 | if ( v23 == 2 ) 440 | { 441 | LOWORD(v25) = __inword((unsigned __int16)v15->MdlAddress);// in word 442 | LABEL_42: 443 | LOWORD(v15->Flags) = v25; 444 | goto LABEL_46; 445 | } 446 | if ( v23 != 4 ) 447 | goto LABEL_91; 448 | v26 = (unsigned __int16)v15->MdlAddress; 449 | break; 450 | case 0xA0400F64: 451 | Status = 0; 452 | KeWaitForSingleObject(DeviceExtension[5], Executive, 0, 0, 0i64); 453 | v17 = Irp->AssociatedIrp.MasterIrp; 454 | v18 = v17->Type; 455 | if ( LOBYTE(v17->Type) == 1 ) 456 | { 457 | v19 = BYTE2(v17->Flags); 458 | v20 = (unsigned __int16)v17->MdlAddress; 459 | LABEL_19: 460 | __outbyte(v20, v19); 461 | LABEL_92: 462 | KeSetEvent((PRKEVENT)DeviceExtension[5], 0, 0); 463 | goto LABEL_193; 464 | } 465 | if ( v18 == 2 ) 466 | { 467 | __outword((unsigned __int16)v17->MdlAddress, v17->Flags); 468 | goto LABEL_92; 469 | } 470 | if ( v18 != 4 ) 471 | goto LABEL_91; 472 | MdlAddress_high = HIDWORD(v17->MdlAddress); 473 | v22 = (unsigned __int16)v17->MdlAddress; 474 | LABEL_36: 475 | __outdword(v22, MdlAddress_high); 476 | goto LABEL_92; 477 | case 0xA0400F68: 478 | Status = 0; 479 | KeWaitForSingleObject(DeviceExtension[5], Executive, 0, 0, 0i64); 480 | v15 = Irp->AssociatedIrp.MasterIrp; 481 | if ( LOBYTE(v15->Type) == 1 ) 482 | { 483 | __outbyte((unsigned __int16)v15->MdlAddress, BYTE2(v15->MdlAddress)); 484 | MdlAddress = LOWORD(v15->MdlAddress) + 1; 485 | LABEL_26: 486 | LOBYTE(v24) = __inbyte(MdlAddress); 487 | LABEL_39: 488 | BYTE2(v15->Flags) = v24; 489 | LABEL_46: 490 | Irp->IoStatus.Information = 20i64; 491 | goto LABEL_92; 492 | } 493 | LABEL_91: 494 | Status = -1073741811; 495 | goto LABEL_92; 496 | default: 497 | LABEL_193: 498 | Irp->IoStatus.Status = Status; 499 | IofCompleteRequest(Irp, 0); 500 | return (unsigned int)Status; 501 | } 502 | v30 = __indword(v26); 503 | HIDWORD(v15->MdlAddress) = v30; 504 | goto LABEL_46; 505 | } 506 | switch ( LowPart ) 507 | { 508 | case 0xA0400F70: 509 | Status = 0; 510 | KeWaitForSingleObject(DeviceExtension[5], Executive, 0, 0, 0i64); 511 | v40 = Irp->AssociatedIrp.MasterIrp; 512 | v41 = (unsigned __int16)v40->MdlAddress; 513 | if ( v41 <= 0x200u ) 514 | { 515 | if ( v41 ) 516 | { 517 | v42 = 0i64; 518 | do 519 | { 520 | __outdword(0xCF8u, *(_DWORD *)&v40->Type); 521 | v43 = __indword(0xCFCu); 522 | *(_DWORD *)((char *)&v40->MdlAddress + v42 + 2) = v43; 523 | *(_DWORD *)&v40->Type += 4; 524 | Irp->IoStatus.Information = 524i64; 525 | v6 += 4; 526 | v42 += 4i64; 527 | } 528 | while ( v6 < LOWORD(v40->MdlAddress) ); 529 | } 530 | goto LABEL_92; 531 | } 532 | goto LABEL_91; 533 | case 0xA0400F74: 534 | Status = 0; 535 | KeWaitForSingleObject(DeviceExtension[5], Executive, 0, 0, 0i64); 536 | v36 = Irp->AssociatedIrp.MasterIrp; 537 | v37 = (unsigned __int16)v36->MdlAddress; 538 | if ( v37 <= 0x200u ) 539 | { 540 | if ( v37 ) 541 | { 542 | v38 = (char *)&v36->MdlAddress + 2; 543 | do 544 | { 545 | v39 = __inbyte(*(&v36->Size + 1)); 546 | *v38 = v39; 547 | ++*(&v36->Size + 1); 548 | Irp->IoStatus.Information = 524i64; 549 | ++v6; 550 | ++v38; 551 | } 552 | while ( v6 < LOWORD(v36->MdlAddress) ); 553 | } 554 | goto LABEL_92; 555 | } 556 | goto LABEL_91; 557 | case 0xA0400F78: 558 | Status = 0; 559 | KeWaitForSingleObject(DeviceExtension[5], Executive, 0, 0, 0i64); 560 | v32 = Irp->AssociatedIrp.MasterIrp; 561 | v33 = (unsigned __int16)v32->MdlAddress; 562 | if ( v33 <= 0x200u && v33 ) 563 | { 564 | v34 = (char *)&v32->MdlAddress + 2; 565 | do 566 | { 567 | __outbyte(*(&v32->Size + 1), *((_BYTE *)&v32->Size + 4)); 568 | v35 = __inbyte(*(&v32->Size + 1) + 1); 569 | *v34 = v35; 570 | ++*((_BYTE *)&v32->Size + 4); 571 | Irp->IoStatus.Information = 524i64; 572 | ++v6; 573 | ++v34; 574 | } 575 | while ( v6 < LOWORD(v32->MdlAddress) ); 576 | } 577 | goto LABEL_92; 578 | } 579 | if ( LowPart != -1606414468 ) 580 | goto LABEL_193; 581 | sub_140004158(Irp, Options, Length, v5); 582 | } 583 | LABEL_54: 584 | Status = Irp->IoStatus.Status; 585 | goto LABEL_193; 586 | } 587 | switch ( LowPart ) 588 | { 589 | case 0xA0400F84: 590 | sub_140003FEC(Irp, Options, Length, v5); 591 | goto LABEL_54; 592 | case 0xA0400F88: 593 | v59 = *(_DWORD *)&MasterIrp->Type; 594 | Status = (unsigned int)((__int64 (__fastcall *)(_QWORD, struct _IO_STACK_LOCATION *, __int64, __int64))sub_14000138C)( 595 | *(unsigned int *)&MasterIrp->Type, 596 | CurrentStackLocation, 597 | Length, 598 | v5) != 0 599 | ? 0xC0000022 600 | : 0; 601 | MasterIrp->MdlAddress = (PMDL)__readmsr(v59);// rdmsr 602 | Irp->IoStatus.Information = 16i64; 603 | goto LABEL_193; 604 | case 0xA0400F8C: 605 | v58 = *(_DWORD *)&MasterIrp->Type; 606 | Status = (unsigned int)((__int64 (__fastcall *)(_QWORD, struct _IO_STACK_LOCATION *, __int64, __int64))sub_14000138C)( 607 | *(unsigned int *)&MasterIrp->Type, 608 | CurrentStackLocation, 609 | Length, 610 | v5) != 0 611 | ? 0xC0000022 612 | : 0; 613 | __writemsr(v58, (unsigned __int64)MasterIrp->MdlAddress);// wrmsr 614 | goto LABEL_193; 615 | } 616 | if ( LowPart != 0xA0400F90 ) 617 | { 618 | if ( LowPart == 0xA0400F94 ) 619 | { 620 | Status = 0; 621 | if ( Options == 0x1020 ) 622 | v52 = MasterIrp->AssociatedIrp.MasterIrp; 623 | else 624 | v52 = MasterIrp->ThreadListEntry.Flink; 625 | MmFreeContiguousMemory(v52); 626 | goto LABEL_193; 627 | } 628 | if ( LowPart == -1606410240 ) 629 | { 630 | Status = 0; 631 | KeWaitForSingleObject(DeviceExtension[5], Executive, 0, 0, 0i64); 632 | v49 = Irp->AssociatedIrp.MasterIrp; 633 | *(_DWORD *)&Buffer.Length = 0; 634 | BusDataByOffset = HalGetBusDataByOffset( 635 | PCIConfiguration, 636 | *((unsigned __int8 *)&v49->Size + 4), 637 | (*(_DWORD *)(&v49->Size + 1) & 0x700 | (*(_DWORD *)(&v49->Size + 1) >> 8) & 0xF8u) >> 3, 638 | &Buffer, 639 | (unsigned __int8)*(_DWORD *)(&v49->Size + 1), 640 | LOBYTE(v49->Type)); 641 | Type_low = LOBYTE(v49->Type); 642 | if ( BusDataByOffset != Type_low ) 643 | { 644 | *(_DWORD *)&Buffer.Length = -1; 645 | LOBYTE(Type_low) = v49->Type; 646 | } 647 | switch ( (_BYTE)Type_low ) 648 | { 649 | case 1: 650 | BYTE2(v49->Flags) = Buffer.Length; 651 | break; 652 | case 2: 653 | LOWORD(v49->Flags) = Buffer.Length; 654 | break; 655 | case 4: 656 | HIDWORD(v49->MdlAddress) = *(_DWORD *)&Buffer.Length; 657 | break; 658 | default: 659 | Status = 0xC000000D; 660 | break; 661 | } 662 | goto LABEL_46; 663 | } 664 | if ( LowPart != 0xA0402004 ) 665 | { 666 | if ( LowPart != 0xA040200C ) 667 | { 668 | if ( LowPart == 0xA0402010 ) 669 | { 670 | Status = sub_140003FB8(MasterIrp->MdlAddress); 671 | Irp->IoStatus.Information = 0i64; 672 | } 673 | goto LABEL_193; 674 | } 675 | sub_1400040C4(Irp, Options, Length, v5); 676 | goto LABEL_54; 677 | } 678 | Status = 0; 679 | KeWaitForSingleObject(DeviceExtension[5], Executive, 0, 0, 0i64); 680 | v44 = Irp->AssociatedIrp.MasterIrp; 681 | *(_DWORD *)&Buffer.Length = 0; 682 | v45 = *((unsigned __int8 *)&v44->Size + 4); 683 | v46 = (unsigned __int8)*(_DWORD *)(&v44->Size + 1); 684 | v47 = v44->Type; 685 | if ( LOBYTE(v44->Type) == 1 ) 686 | { 687 | Flags_low = BYTE2(v44->Flags); 688 | } 689 | else if ( v47 == 2 ) 690 | { 691 | Flags_low = LOWORD(v44->Flags); 692 | } 693 | else 694 | { 695 | if ( v47 != 4 ) 696 | { 697 | Status = -1073741811; 698 | LABEL_90: 699 | if ( HalSetBusDataByOffset( 700 | PCIConfiguration, 701 | v45, 702 | (*(_DWORD *)(&v44->Size + 1) & 0x700 | (*(_DWORD *)(&v44->Size + 1) >> 8) & 0xF8u) >> 3, 703 | &Buffer, 704 | v46, 705 | LOBYTE(v44->Type)) == LOBYTE(v44->Type) ) 706 | goto LABEL_46; 707 | goto LABEL_91; 708 | } 709 | Flags_low = HIDWORD(v44->MdlAddress); 710 | } 711 | *(_DWORD *)&Buffer.Length = Flags_low; 712 | goto LABEL_90; 713 | } 714 | Status = 0; 715 | Flags = MasterIrp->Flags; 716 | if ( Options == 4128 ) 717 | MasterIrp->AssociatedIrp.MasterIrp = 0i64; 718 | else 719 | MasterIrp->ThreadListEntry.Flink = 0i64; 720 | v54 = Flags; 721 | DbgPrint("[AsIO3]: XXXXXXXX alloc mem size is 0x%lx bytes !", Flags); 722 | result = (__int64)MmAllocateContiguousMemory(v54, (PHYSICAL_ADDRESS)0xFFFFFFFFi64); 723 | v56 = (struct _IRP *)result; 724 | if ( result ) 725 | { 726 | v57 = 4128i64; 727 | if ( Options == 4128 ) 728 | { 729 | DbgPrint("[AsIO3]: XXXXXXXX address is 0x%lx !", *(&MasterIrp->Flags + 1)); 730 | *(&MasterIrp->Flags + 1) = MmGetPhysicalAddress(v56).LowPart; 731 | MasterIrp->AssociatedIrp.MasterIrp = v56; 732 | } 733 | else 734 | { 735 | DbgPrint("[AsIO3]: XXXXXXXX address is 0x%lx !", MasterIrp->AssociatedIrp.MasterIrp); 736 | MasterIrp->AssociatedIrp.MasterIrp = (struct _IRP *)MmGetPhysicalAddress(v56).LowPart; 737 | MasterIrp->ThreadListEntry.Flink = (struct _LIST_ENTRY *)v56; 738 | v57 = 4136i64; 739 | } 740 | Irp->IoStatus.Information = v57; 741 | goto LABEL_193; 742 | } 743 | return result; 744 | } 745 | /* Orphan comments: 746 | in word 747 | */ 748 | ~~~ 749 | 750 | ### IOCTL 0xA040A480 751 | 752 | This IOCTL code triggers arbitrary physical memory map operation in function sub_140003268. 753 | 754 | ~~~c 755 | __int64 __fastcall sub_140003268(__int64 a1, __int64 a2, __int64 a3, char a4) 756 | { 757 | PHYSICAL_ADDRESS *v4; // rdi 758 | HANDLE v5; // rcx 759 | void *v6; // rax 760 | DWORD *v7; // r15 761 | unsigned int v8; // edx 762 | DWORD *v9; // r12 763 | NTSTATUS v11; // ebx 764 | LARGE_INTEGER v12; // rbx 765 | DWORD v13; // edi 766 | union _LARGE_INTEGER SectionOffset; // [rsp+58h] [rbp-59h] BYREF 767 | LARGE_INTEGER TranslatedAddress; // [rsp+60h] [rbp-51h] BYREF 768 | void *SectionHandle; // [rsp+68h] [rbp-49h] BYREF 769 | HANDLE Handle; // [rsp+70h] [rbp-41h] BYREF 770 | ULONG v19; // [rsp+78h] [rbp-39h] BYREF 771 | LARGE_INTEGER BusAddress; // [rsp+80h] [rbp-31h] BYREF 772 | PVOID BaseAddress; // [rsp+88h] [rbp-29h] BYREF 773 | ULONG_PTR ViewSize; // [rsp+90h] [rbp-21h] BYREF 774 | PVOID v23; // [rsp+98h] [rbp-19h] BYREF 775 | PVOID Object; // [rsp+A0h] [rbp-11h] BYREF 776 | PVOID v25; // [rsp+A8h] [rbp-9h] BYREF 777 | struct _OBJECT_ATTRIBUTES ObjectAttributes; // [rsp+B0h] [rbp-1h] BYREF 778 | struct _UNICODE_STRING DestinationString; // [rsp+E0h] [rbp+2Fh] BYREF 779 | ULONG AddressSpace; // [rsp+130h] [rbp+7Fh] BYREF 780 | 781 | v4 = *(PHYSICAL_ADDRESS **)(a2 + 24); 782 | v5 = 0i64; 783 | v25 = 0i64; 784 | v6 = 0i64; 785 | Object = 0i64; 786 | v7 = 0i64; 787 | v8 = *(_DWORD *)(a3 + 16); 788 | v9 = 0i64; 789 | Handle = 0i64; 790 | SectionHandle = 0i64; 791 | if ( a4 ) 792 | { 793 | v9 = (DWORD *)v4; 794 | if ( v8 < 0x18 || *(_DWORD *)(a3 + 8) < 4u ) 795 | { 796 | v11 = -1073741670; 797 | goto LABEL_33; 798 | } 799 | } 800 | else 801 | { 802 | v7 = (DWORD *)v4; 803 | if ( v8 < 0x18 || *(_DWORD *)(a3 + 8) < 8u ) 804 | { 805 | v11 = -1073741670; 806 | LABEL_37: 807 | if ( v5 ) 808 | goto LABEL_38; 809 | return (unsigned int)v11; 810 | } 811 | } 812 | AddressSpace = v4[2].LowPart; 813 | v19 = AddressSpace; 814 | RtlInitUnicodeString(&DestinationString, L"\\Device\\PhysicalMemory"); 815 | ObjectAttributes.RootDirectory = 0i64; 816 | ObjectAttributes.ObjectName = &DestinationString; 817 | ObjectAttributes.Length = 48; 818 | ObjectAttributes.Attributes = 576; 819 | *(_OWORD *)&ObjectAttributes.SecurityDescriptor = 0i64; 820 | if ( a4 ) 821 | { 822 | v11 = ZwOpenSection(&SectionHandle, 0xF001Fu, &ObjectAttributes); 823 | if ( v11 < 0 ) 824 | goto LABEL_32; 825 | v11 = ObReferenceObjectByHandle(SectionHandle, 0xF001Fu, 0i64, 0, &Object, 0i64); 826 | if ( v11 < 0 ) 827 | goto LABEL_32; 828 | } 829 | else 830 | { 831 | v11 = ZwOpenSection(&Handle, 0xF001Fu, &ObjectAttributes); 832 | if ( v11 < 0 ) 833 | goto LABEL_35; 834 | v11 = ObReferenceObjectByHandle(Handle, 0xF001Fu, 0i64, 0, &v25, 0i64); 835 | if ( v11 < 0 ) 836 | goto LABEL_35; 837 | } 838 | BusAddress.QuadPart = v4[1].QuadPart + v4[2].HighPart + (unsigned int)(unsigned __int16)v4[1].LowPart; 839 | if ( HalTranslateBusAddress((INTERFACE_TYPE)v4->LowPart, v4->HighPart, v4[1], &AddressSpace, &TranslatedAddress) 840 | && HalTranslateBusAddress((INTERFACE_TYPE)v4->LowPart, v4->HighPart, BusAddress, &v19, &BusAddress) ) 841 | { 842 | v12 = TranslatedAddress; 843 | } 844 | else 845 | { 846 | v12 = v4[1]; 847 | TranslatedAddress = v12; 848 | } 849 | v13 = BusAddress.LowPart - v12.LowPart; 850 | ViewSize = BusAddress.QuadPart - v12.QuadPart; 851 | if ( BusAddress.LowPart == v12.LowPart ) 852 | { 853 | v11 = -1073741823; 854 | goto LABEL_31; 855 | } 856 | if ( (unsigned int)((__int64 (__fastcall *)(_QWORD, _QWORD))sub_1400013E4)((LARGE_INTEGER)v12.QuadPart, v13) ) 857 | return 3221225506i64; 858 | if ( AddressSpace ) 859 | { 860 | if ( a4 ) 861 | *v9 = v12.LowPart; 862 | else 863 | *v7 = v12.LowPart; 864 | goto LABEL_30; 865 | } 866 | SectionOffset = v12; 867 | if ( !a4 ) 868 | { 869 | v23 = 0i64; 870 | v11 = ZwMapViewOfSection( 871 | Handle, 872 | (HANDLE)0xFFFFFFFFFFFFFFFFi64, 873 | &v23, 874 | 0i64, 875 | v13, 876 | &SectionOffset, 877 | &ViewSize, 878 | ViewShare, 879 | 0, 880 | 4u); 881 | if ( v11 >= 0 ) 882 | { 883 | *v7 = TranslatedAddress.LowPart + (_DWORD)v23 - SectionOffset.LowPart; 884 | goto LABEL_30; 885 | } 886 | LABEL_35: 887 | v5 = Handle; 888 | goto LABEL_37; 889 | } 890 | BaseAddress = 0i64; 891 | v11 = ZwMapViewOfSection( 892 | SectionHandle, 893 | (HANDLE)0xFFFFFFFFFFFFFFFFi64, 894 | &BaseAddress, 895 | 0i64, 896 | v13, 897 | &SectionOffset, 898 | &ViewSize, 899 | ViewShare, 900 | 0, 901 | 4u); 902 | if ( v11 >= 0 ) 903 | { 904 | LODWORD(BaseAddress) = TranslatedAddress.LowPart - SectionOffset.LowPart + (_DWORD)BaseAddress; 905 | *v9 = (unsigned int)BaseAddress; 906 | LABEL_30: 907 | v11 = 0; 908 | LABEL_31: 909 | if ( a4 ) 910 | goto LABEL_32; 911 | goto LABEL_35; 912 | } 913 | LABEL_32: 914 | v6 = SectionHandle; 915 | LABEL_33: 916 | if ( v6 ) 917 | { 918 | v5 = v6; 919 | LABEL_38: 920 | ZwClose(v5); 921 | } 922 | return (unsigned int)v11; 923 | } 924 | ~~~ 925 | 926 | 927 | 928 | ### IOCTL 0xA0406408 929 | 930 | This IOCTL code triggers port read operation in function sub_140002654 . 931 | 932 | ~~~c 933 | __int64 __fastcall sub_140002654(__int64 a1, _DWORD *a2) 934 | { 935 | int v2; // edi 936 | unsigned __int32 *v4; // rsi 937 | ULONG v5; // ebp 938 | DWORD LowPart; // ebx 939 | unsigned __int32 v8; // eax 940 | unsigned __int16 v9; // ax 941 | unsigned __int8 v10; // al 942 | ULONG AddressSpace; // [rsp+60h] [rbp+8h] BYREF 943 | PHYSICAL_ADDRESS BusAddress; // [rsp+68h] [rbp+10h] 944 | LARGE_INTEGER TranslatedAddress; // [rsp+78h] [rbp+20h] BYREF 945 | 946 | v2 = a2[6]; 947 | v4 = *(unsigned __int32 **)(a1 + 24); 948 | switch ( v2 ) 949 | { 950 | case 0xA0406400: 951 | v5 = 1; 952 | break; 953 | case 0xA0406404: 954 | v5 = 2; 955 | break; 956 | case 0xA0406408: 957 | v5 = 4; 958 | break; 959 | default: 960 | v5 = AddressSpace; 961 | break; 962 | } 963 | if ( a2[4] == 4 && a2[2] >= v5 ) 964 | { 965 | BusAddress.QuadPart = *v4; 966 | AddressSpace = 1; 967 | HalTranslateBusAddress(Isa, 0, BusAddress, &AddressSpace, &TranslatedAddress); 968 | LowPart = TranslatedAddress.LowPart; 969 | if ( (unsigned int)sub_14000130C(LOWORD(TranslatedAddress.LowPart)) ) 970 | return 3221225506i64; 971 | if ( AddressSpace == 1 ) 972 | { 973 | if ( v2 != 0xA0406400 ) 974 | { 975 | if ( v2 != 0xA0406404 ) 976 | { 977 | if ( v2 == 0xA0406408 ) 978 | { 979 | v8 = __indword(LowPart); 980 | LABEL_23: 981 | *v4 = v8; 982 | goto LABEL_28; 983 | } 984 | goto LABEL_28; 985 | } 986 | v9 = __inword(LowPart); 987 | goto LABEL_25; 988 | } 989 | v10 = __inbyte(LowPart); 990 | } 991 | else 992 | { 993 | if ( v2 != -1606392832 ) 994 | { 995 | if ( v2 != -1606392828 ) 996 | { 997 | if ( v2 == -1606392824 ) 998 | { 999 | v8 = *(_DWORD *)LowPart; 1000 | goto LABEL_23; 1001 | } 1002 | LABEL_28: 1003 | *(_QWORD *)(a1 + 56) = v5; 1004 | return 0i64; 1005 | } 1006 | v9 = *(_WORD *)LowPart; 1007 | LABEL_25: 1008 | *(_WORD *)v4 = v9; 1009 | goto LABEL_28; 1010 | } 1011 | v10 = *(_BYTE *)LowPart; 1012 | } 1013 | *(_BYTE *)v4 = v10; 1014 | goto LABEL_28; 1015 | } 1016 | return 0xC000000Di64; 1017 | } 1018 | ~~~ 1019 | 1020 | 1021 | 1022 | 1023 | 1024 | 1025 | 1026 | ### IOCTL 0xA0402014 1027 | 1028 | This code triggers port out operation. The operation is eventually completed in function sub_140001000. 1029 | 1030 | ```c 1031 | __int64 __fastcall sub_140001000(unsigned __int16 a1, __int16 a2, unsigned __int8 a3) 1032 | { 1033 | if ( a3 > 1u ) 1034 | { 1035 | if ( a3 > 2u ) 1036 | __outdword(a1, a2); 1037 | else 1038 | __outword(a1, a2); 1039 | } 1040 | else 1041 | { 1042 | __outbyte(a1, a2); 1043 | } 1044 | return 1i64; 1045 | } 1046 | ``` 1047 | 1048 | 1049 | 1050 | ### IOCTL 0xA0400F88 1051 | 1052 | This code triggers read operation on MSR. 1053 | 1054 | ```c 1055 | case 0xA0400F88: 1056 | v59 = *(_DWORD *)&MasterIrp->Type; 1057 | Status = (unsigned int)((__int64 (__fastcall *)(_QWORD, struct _IO_STACK_LOCATION *, __int64, __int64))sub_14000138C)( 1058 | *(unsigned int *)&MasterIrp->Type, 1059 | CurrentStackLocation, 1060 | Length, 1061 | v5) != 0 1062 | ? 0xC0000022 1063 | : 0; 1064 | MasterIrp->MdlAddress = (PMDL)__readmsr(v59);// rdmsr 1065 | Irp->IoStatus.Information = 16i64; 1066 | ``` 1067 | 1068 | 1069 | 1070 | ### IOCTL 0xA0400F8C 1071 | 1072 | This code triggers write operation on MSR. 1073 | 1074 | ```c 1075 | case 0xA0400F8C: 1076 | v58 = *(_DWORD *)&MasterIrp->Type; 1077 | Status = (unsigned int)((__int64 (__fastcall *)(_QWORD, struct _IO_STACK_LOCATION *, __int64, __int64))sub_14000138C)( 1078 | *(unsigned int *)&MasterIrp->Type, 1079 | CurrentStackLocation, 1080 | Length, 1081 | v5) != 0 1082 | ? 0xC0000022 1083 | : 0; 1084 | __writemsr(v58, (unsigned __int64)MasterIrp->MdlAddress);// wrmsr 1085 | goto LABEL_193; 1086 | ``` 1087 | 1088 | 1089 | 1090 | -------------------------------------------------------------------------------- /CVE-2024-33221/AsusBSItf.sys: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DriverHunter/Win-Driver-EXP/21726ae8475c10c893ae35f2b744dee8d7390057/CVE-2024-33221/AsusBSItf.sys -------------------------------------------------------------------------------- /CVE-2024-33221/README.md: -------------------------------------------------------------------------------- 1 | # Vulnerable Driver AsusBSItf.sys in ASUS BIOS Flash Driver v3.2.12.0 2 | 3 | --- 4 | 5 | AsusBSItf.sys in ASUS BIOS Flash Driver exposes functionality that allows low-privileged users to map physical memory between 0xf0000-0x100000 or higher than 0xffff0000, write arbitary i/o port via specially crafted IOCTL requests. This can be exploited for privilege escalation, code execution under high privileges, and information disclosure. These signed drivers can also be used to bypass the Microsoft driver-signing policy to deploy malicious code. 6 | 7 | 8 | 9 | ## version 10 | 11 | 3.03.36 12 | 13 | ## Vulnerability causes 14 | 15 | AsusBSItf.sys provides the functionality of mapping physical memory and read/write I/O ports , but it does not restrict the privileges of the caller, resulting in low-privileged users being able to call the driver and execute corresponding functions through DeviceIoControl. 16 | 17 | ~~~c 18 | __int64 __fastcall sub_140001070(__int64 a1, IRP *a2) 19 | { 20 | struct _IO_STACK_LOCATION *CurrentStackLocation; // rax 21 | NTSTATUS v4; // ebx 22 | DWORD LowPart; // ecx 23 | unsigned __int64 inputbuffer_len; // rdx 24 | unsigned __int64 outputbuffer_len; // r9 25 | UCHAR MajorFunction; // r8 26 | DWORD v9; // ecx 27 | DWORD v10; // ecx 28 | DWORD v11; // ecx 29 | DWORD v12; // ecx 30 | DWORD v13; // ecx 31 | struct _IRP *v14; // rbx 32 | PDEVICE_OBJECT v15; // rcx 33 | __int64 v16; // rdx 34 | _DWORD *inputbuffer; // r15 35 | unsigned int inputbuffer_0; // ebx 36 | SIZE_T inputbuffer_3; // r12 37 | unsigned int inputbuffer_3_1; // edx 38 | unsigned int inputbuffer_2; // eax 39 | int inputbuffer_1_1; // r9d 40 | unsigned int v24; // r8d 41 | unsigned int v25; // r10d 42 | int v26; // edx 43 | _QWORD *mapped_addr; // r13 44 | PHYSICAL_ADDRESS *allocate_mem; // rax 45 | LONGLONG *v29; // r14 46 | PHYSICAL_ADDRESS another_physical_addr; // rcx 47 | PVOID another_mapped_addr; // rax 48 | struct _MDL *mdl_for_another_mapped_addr; // rcx 49 | PVOID v33; // rax 50 | void *another_mapped_addr_1; // rcx 51 | PHYSICAL_ADDRESS v35; // rax 52 | LONGLONG **v36; // rax 53 | PDEVICE_OBJECT v37; // rcx 54 | __int64 v38; // rdx 55 | struct _IRP *v39; // rbx 56 | struct _IRP *v40; // r14 57 | PVOID *v41; // rdi 58 | _QWORD *v42; // rax 59 | PVOID *v43; // rcx 60 | struct _MDL *v44; // rdx 61 | PVOID v45; // rcx 62 | PVOID v46; // rcx 63 | PDEVICE_OBJECT v47; // rcx 64 | __int64 v48; // rdx 65 | PVOID PoolWithTag; // rdi 66 | ULONG v50; // r15d 67 | PVOID ContiguousMemory; // rax 68 | struct _MDL *v52; // rcx 69 | PVOID v53; // rax 70 | void *v54; // rcx 71 | _QWORD *v55; // rax 72 | void *v56; // rcx 73 | DWORD *pinputbuffer; // rbx 74 | __int64 inputbuffer_1_2; // r8 75 | unsigned int inputbuffer_0_1; // r14d 76 | unsigned int v60; // r12d 77 | unsigned int v61_ffff0000; // r15d 78 | char *v62; // rax 79 | char *v63; // r14 80 | PHYSICAL_ADDRESS PhysicalAddress; // [rsp+40h] [rbp-48h] 81 | int inputbuffer_1; // [rsp+48h] [rbp-40h] BYREF 82 | unsigned int v66[3]; // [rsp+4Ch] [rbp-3Ch] 83 | 84 | CurrentStackLocation = a2->Tail.Overlay.CurrentStackLocation; 85 | v4 = 0xC0000002; 86 | LowPart = CurrentStackLocation->Parameters.Read.ByteOffset.LowPart; 87 | inputbuffer_len = CurrentStackLocation->Parameters.Create.Options; 88 | outputbuffer_len = CurrentStackLocation->Parameters.Read.Length; 89 | a2->IoStatus.Information = 0i64; 90 | MajorFunction = CurrentStackLocation->MajorFunction; 91 | if ( !CurrentStackLocation->MajorFunction || MajorFunction == 2 ) 92 | goto LABEL_25; 93 | if ( MajorFunction != 14 ) 94 | goto LABEL_26; 95 | v9 = LowPart - 0x222804; 96 | if ( !v9 ) // 0x222804 97 | { 98 | pinputbuffer = (DWORD *)a2->AssociatedIrp.MasterIrp; 99 | inputbuffer_1_2 = pinputbuffer[1]; 100 | if ( inputbuffer_len < inputbuffer_1_2 + 8 || outputbuffer_len < inputbuffer_1_2 + 8 )// inputbuffer_len>=inputbuffer[1]+8 101 | // outputbuffer_len>=inputbuffer[1]+8 102 | { 103 | v15 = DeviceObject; 104 | if ( DeviceObject == (PDEVICE_OBJECT)&DeviceObject || (HIDWORD(DeviceObject->Timer) & 4) == 0 ) 105 | goto LABEL_15; 106 | v16 = 10i64; 107 | goto LABEL_14; 108 | } 109 | inputbuffer_0_1 = *pinputbuffer; 110 | v60 = *pinputbuffer + inputbuffer_1_2 - 1; 111 | v61_ffff0000 = -(int)NumberOfBytes; // ffff0000 112 | if ( DeviceObject != (PDEVICE_OBJECT)&DeviceObject ) 113 | { 114 | if ( (HIDWORD(DeviceObject->Timer) & 4) != 0 ) 115 | sub_140001F44( 116 | DeviceObject->AttachedDevice, 117 | 11i64, 118 | &unk_140003280, 119 | inputbuffer_0_1, 120 | inputbuffer_0_1 + inputbuffer_1_2 - 1); 121 | if ( DeviceObject != (PDEVICE_OBJECT)&DeviceObject && (HIDWORD(DeviceObject->Timer) & 4) != 0 ) 122 | sub_140001F44(DeviceObject->AttachedDevice, 12i64, &unk_140003280, v61_ffff0000, -1); 123 | } 124 | if ( (inputbuffer_0_1 < 0xF0000 || v60 > 0xFFFFF) && inputbuffer_0_1 < v61_ffff0000 )// inputbuffer[0]>=0xf0000 && inputbuffer[0]+inputbuffer[1]-1<0xfffff 125 | // 126 | // or 127 | // 128 | // inputbuffer[0]>=ffff0000 129 | { 130 | if ( DeviceObject != (PDEVICE_OBJECT)&DeviceObject && (HIDWORD(DeviceObject->Timer) & 4) != 0 ) 131 | sub_140001F44(DeviceObject->AttachedDevice, 14i64, &unk_140003280, inputbuffer_0_1, v60); 132 | goto LABEL_17; 133 | } 134 | v62 = (char *)MmMapIoSpace((PHYSICAL_ADDRESS)*pinputbuffer, pinputbuffer[1], MmNonCached);// mapping range is 0xf0000-0x100000 135 | // or ffff0000 136 | v63 = v62; 137 | if ( v62 ) 138 | { 139 | sub_140002300(pinputbuffer + 2, v62, pinputbuffer[1]); 140 | MmUnmapIoSpace(v63, pinputbuffer[1]); 141 | a2->IoStatus.Information = pinputbuffer[1] + 8i64; 142 | goto LABEL_25; 143 | } 144 | if ( DeviceObject != (PDEVICE_OBJECT)&DeviceObject && (HIDWORD(DeviceObject->Timer) & 4) != 0 ) 145 | sub_140001EE0(DeviceObject->AttachedDevice, 13i64, &unk_140003280); 146 | v4 = -1073741823; 147 | goto LABEL_26; 148 | } 149 | v10 = v9 - 4; 150 | if ( !v10 ) // 0x222808 151 | { 152 | v40 = a2->AssociatedIrp.MasterIrp; 153 | if ( (unsigned int)inputbuffer_len < 4 || (unsigned int)outputbuffer_len < 0x10 ) 154 | { 155 | v15 = DeviceObject; 156 | if ( DeviceObject == (PDEVICE_OBJECT)&DeviceObject || (HIDWORD(DeviceObject->Timer) & 4) == 0 ) 157 | goto LABEL_15; 158 | v16 = 15i64; 159 | goto LABEL_14; 160 | } 161 | v4 = -1073741670; 162 | PoolWithTag = ExAllocatePoolWithTag((POOL_TYPE)1024, 0x30ui64, 0x704D4Du); 163 | if ( PoolWithTag ) 164 | { 165 | v50 = *(_DWORD *)a2->AssociatedIrp.MasterIrp; 166 | *(_OWORD *)PoolWithTag = 0i64; 167 | *((_OWORD *)PoolWithTag + 1) = 0i64; 168 | *((_OWORD *)PoolWithTag + 2) = 0i64; 169 | ContiguousMemory = MmAllocateContiguousMemory(v50, (PHYSICAL_ADDRESS)0xFFFFFFFFi64); 170 | *((_QWORD *)PoolWithTag + 2) = ContiguousMemory; 171 | if ( ContiguousMemory ) 172 | *((_QWORD *)PoolWithTag + 3) = IoAllocateMdl(ContiguousMemory, v50, 0, 0, 0i64); 173 | v52 = (struct _MDL *)*((_QWORD *)PoolWithTag + 3); 174 | if ( v52 ) 175 | { 176 | MmBuildMdlForNonPagedPool(v52); 177 | v53 = MmMapLockedPages(*((PMDL *)PoolWithTag + 3), 1); 178 | v54 = (void *)*((_QWORD *)PoolWithTag + 2); 179 | *((_QWORD *)PoolWithTag + 5) = v53; 180 | *((PHYSICAL_ADDRESS *)PoolWithTag + 4) = MmGetPhysicalAddress(v54); 181 | *(_QWORD *)&v40->Type = *((_QWORD *)PoolWithTag + 5); 182 | v40->MdlAddress = (PMDL)*((_QWORD *)PoolWithTag + 4); 183 | a2->IoStatus.Information = 16i64; 184 | v55 = (_QWORD *)qword_1400042B8; 185 | if ( *(PVOID **)qword_1400042B8 != &P ) 186 | goto LABEL_92; 187 | *(_QWORD *)PoolWithTag = &P; 188 | *((_QWORD *)PoolWithTag + 1) = v55; 189 | *v55 = PoolWithTag; 190 | qword_1400042B8 = (__int64)PoolWithTag; 191 | v47 = DeviceObject; 192 | if ( DeviceObject == (PDEVICE_OBJECT)&DeviceObject || (HIDWORD(DeviceObject->Timer) & 4) == 0 ) 193 | goto LABEL_25; 194 | v48 = 16i64; 195 | goto LABEL_84; 196 | } 197 | v56 = (void *)*((_QWORD *)PoolWithTag + 2); 198 | if ( v56 ) 199 | MmFreeContiguousMemory(v56); 200 | ExFreePoolWithTag(PoolWithTag, 0x704D4Du); 201 | } 202 | v37 = DeviceObject; 203 | if ( DeviceObject == (PDEVICE_OBJECT)&DeviceObject || (HIDWORD(DeviceObject->Timer) & 4) == 0 ) 204 | goto LABEL_26; 205 | v38 = 17i64; 206 | LABEL_54: 207 | sub_140001EE0(v37->AttachedDevice, v38, &unk_140003280); 208 | goto LABEL_26; 209 | } 210 | v11 = v10 - 4; // 0x22280c 211 | if ( !v11 ) 212 | { 213 | v40 = a2->AssociatedIrp.MasterIrp; 214 | if ( (unsigned int)inputbuffer_len < 0x10 ) 215 | { 216 | v15 = DeviceObject; 217 | if ( DeviceObject == (PDEVICE_OBJECT)&DeviceObject || (HIDWORD(DeviceObject->Timer) & 4) == 0 ) 218 | goto LABEL_15; 219 | v16 = 18i64; 220 | goto LABEL_14; 221 | } 222 | v41 = (PVOID *)P; 223 | v4 = -1073741823; 224 | if ( P == &P ) 225 | { 226 | LABEL_71: 227 | if ( DeviceObject != (PDEVICE_OBJECT)&DeviceObject && (HIDWORD(DeviceObject->Timer) & 4) != 0 ) 228 | sub_140002040(DeviceObject->AttachedDevice, 20i64, &unk_140003280, v40->MdlAddress, *(_QWORD *)&v40->Type); 229 | goto LABEL_26; 230 | } 231 | while ( *(PVOID *)&v40->Type != v41[5] || v40->MdlAddress != v41[4] ) 232 | { 233 | v41 = (PVOID *)*v41; 234 | if ( v41 == &P ) 235 | goto LABEL_71; 236 | } 237 | v42 = *v41; 238 | if ( *((PVOID **)*v41 + 1) != v41 ) 239 | goto LABEL_92; 240 | v43 = (PVOID *)v41[1]; 241 | if ( *v43 != v41 ) 242 | goto LABEL_92; 243 | *v43 = v42; 244 | v42[1] = v43; 245 | v44 = (struct _MDL *)v41[3]; 246 | if ( v44 ) 247 | { 248 | v45 = v41[5]; 249 | if ( v45 ) 250 | { 251 | MmUnmapLockedPages(v45, v44); 252 | IoFreeMdl((PMDL)v41[3]); // free 253 | } 254 | } 255 | v46 = v41[2]; 256 | if ( v46 ) 257 | MmFreeContiguousMemory(v46); 258 | ExFreePoolWithTag(v41, 0x704D4Du); 259 | v47 = DeviceObject; 260 | if ( DeviceObject == (PDEVICE_OBJECT)&DeviceObject || (HIDWORD(DeviceObject->Timer) & 4) == 0 ) 261 | goto LABEL_25; 262 | v48 = 19i64; 263 | LABEL_84: 264 | sub_140002040(v47->AttachedDevice, v48, &unk_140003280, v40->MdlAddress, *(_QWORD *)&v40->Type); 265 | goto LABEL_25; 266 | } 267 | v12 = v11 - 4; // 0x222810 268 | if ( !v12 ) 269 | { 270 | v39 = a2->AssociatedIrp.MasterIrp; 271 | if ( (unsigned int)inputbuffer_len < 8 ) 272 | { 273 | v15 = DeviceObject; 274 | if ( DeviceObject == (PDEVICE_OBJECT)&DeviceObject || (HIDWORD(DeviceObject->Timer) & 4) == 0 ) 275 | goto LABEL_15; 276 | v16 = 21i64; 277 | goto LABEL_14; 278 | } 279 | if ( !word_14000400C ) 280 | goto LABEL_17; 281 | ((void (__fastcall *)(_QWORD, _QWORD, _QWORD, unsigned __int64))out_func)( 282 | word_14000400C, 283 | *(unsigned int *)&v39->Type, 284 | *(unsigned int *)(&v39->Size + 1), 285 | outputbuffer_len); 286 | if ( DeviceObject != (PDEVICE_OBJECT)&DeviceObject && (HIDWORD(DeviceObject->Timer) & 4) != 0 ) 287 | sub_140001F44( 288 | DeviceObject->AttachedDevice, 289 | 22i64, 290 | &unk_140003280, 291 | *(unsigned int *)&v39->Type, 292 | *(_DWORD *)(&v39->Size + 1)); 293 | goto LABEL_25; 294 | } 295 | v13 = v12 - 4; // 0x222814 296 | if ( !v13 ) 297 | { 298 | inputbuffer = &a2->AssociatedIrp.MasterIrp->Type; 299 | if ( (unsigned int)inputbuffer_len < 0x20 ) 300 | { 301 | v15 = DeviceObject; 302 | if ( DeviceObject == (PDEVICE_OBJECT)&DeviceObject || (HIDWORD(DeviceObject->Timer) & 4) == 0 ) 303 | goto LABEL_15; 304 | v16 = 23i64; 305 | goto LABEL_14; 306 | } 307 | if ( !word_14000400C ) 308 | goto LABEL_17; 309 | inputbuffer_0 = *inputbuffer; 310 | inputbuffer_3 = (unsigned int)inputbuffer[3]; 311 | inputbuffer_3_1 = inputbuffer[3]; 312 | if ( DeviceObject != (PDEVICE_OBJECT)&DeviceObject && (HIDWORD(DeviceObject->Timer) & 4) != 0 ) 313 | { 314 | sub_140001FE0(DeviceObject->AttachedDevice, 24i64, &unk_140003280, inputbuffer_0); 315 | inputbuffer_3_1 = inputbuffer[3]; 316 | } 317 | inputbuffer_1 = inputbuffer[1]; 318 | inputbuffer_2 = inputbuffer[2]; 319 | v66[1] = inputbuffer_3_1; 320 | v66[0] = inputbuffer_2; 321 | sub_14000101E(word_14000400C, inputbuffer_0, &inputbuffer_1);// 0xb2 port 322 | inputbuffer_1_1 = inputbuffer_1; 323 | v24 = v66[0]; 324 | v25 = v66[1]; 325 | inputbuffer[1] = inputbuffer_1; 326 | inputbuffer[2] = v24; // (DWORD*)inputbuffer[2] 327 | inputbuffer[3] = v25; // (DWORD*)inputbuffer[1] 328 | v26 = inputbuffer_1_1; 329 | if ( DeviceObject != (PDEVICE_OBJECT)&DeviceObject && (HIDWORD(DeviceObject->Timer) & 4) != 0 ) 330 | { 331 | sub_140001F8C(DeviceObject->AttachedDevice, 25i64, &unk_140003280); 332 | v26 = inputbuffer[1]; 333 | } 334 | *((_QWORD *)inputbuffer + 2) = 0i64; 335 | v4 = 0; 336 | *((_QWORD *)inputbuffer + 3) = 0i64; 337 | if ( v26 ) 338 | { 339 | LABEL_49: 340 | a2->IoStatus.Information = 32i64; 341 | goto LABEL_26; 342 | } 343 | PhysicalAddress.HighPart = inputbuffer[2]; 344 | PhysicalAddress.LowPart = inputbuffer[3]; 345 | mapped_addr = MmMapIoSpace(PhysicalAddress, 0x18ui64, MmNonCached);// mapping memory specified by inputbuffer[2],inputbuffer[3] 346 | if ( !mapped_addr ) 347 | { 348 | v4 = 0xC000009A; 349 | LABEL_51: 350 | v37 = DeviceObject; 351 | if ( DeviceObject == (PDEVICE_OBJECT)&DeviceObject || (HIDWORD(DeviceObject->Timer) & 4) == 0 ) 352 | goto LABEL_26; 353 | v38 = 26i64; 354 | goto LABEL_54; 355 | } 356 | allocate_mem = (PHYSICAL_ADDRESS *)ExAllocatePoolWithTag((POOL_TYPE)1024, 0x30ui64, 0x704D4Du); 357 | v29 = (LONGLONG *)allocate_mem; 358 | if ( !allocate_mem ) 359 | { 360 | v4 = 0xC000009A; 361 | LABEL_48: 362 | MmUnmapIoSpace(mapped_addr, 0x18ui64); 363 | if ( v4 >= 0 ) 364 | goto LABEL_49; 365 | goto LABEL_51; 366 | } 367 | another_physical_addr = (PHYSICAL_ADDRESS)mapped_addr[1];// Here, because the address is not checked for readability before mapping, it can lead to a blue screen if it is not readable. 368 | allocate_mem[4] = another_physical_addr; 369 | another_mapped_addr = MmMapIoSpace(another_physical_addr, inputbuffer_3, MmNonCached);// mapping memory specified by mapped_addr[1] it's weird??? 370 | // another_physical_addr = mapped_addr[1] 371 | v29[2] = (LONGLONG)another_mapped_addr; 372 | if ( another_mapped_addr ) 373 | v29[3] = (LONGLONG)IoAllocateMdl(another_mapped_addr, inputbuffer_3, 0, 0, 0i64); 374 | mdl_for_another_mapped_addr = (struct _MDL *)v29[3]; 375 | if ( !mdl_for_another_mapped_addr ) 376 | { 377 | v4 = -1073741670; 378 | ExFreePoolWithTag(v29, 0x704D4Du); 379 | goto LABEL_48; 380 | } 381 | MmBuildMdlForNonPagedPool(mdl_for_another_mapped_addr); 382 | v33 = MmMapLockedPages((PMDL)v29[3], 1); 383 | another_mapped_addr_1 = (void *)v29[2]; 384 | v29[5] = (LONGLONG)v33; 385 | v35 = MmGetPhysicalAddress(another_mapped_addr_1); 386 | v29[2] = 0i64; 387 | v29[4] = v35.QuadPart; 388 | v36 = (LONGLONG **)qword_1400042B8; 389 | if ( *(PVOID **)qword_1400042B8 == &P ) 390 | { 391 | *v29 = (LONGLONG)&P; 392 | v29[1] = (LONGLONG)v36; 393 | *v36 = v29; 394 | qword_1400042B8 = (__int64)v29; 395 | *((_QWORD *)inputbuffer + 3) = v29[4]; 396 | *((_QWORD *)inputbuffer + 2) = v29[5]; 397 | goto LABEL_48; 398 | } 399 | LABEL_92: 400 | __fastfail(3u); 401 | } 402 | if ( v13 == 4 ) // 0x222818 403 | { 404 | v14 = a2->AssociatedIrp.MasterIrp; 405 | if ( (unsigned int)inputbuffer_len < 8 ) 406 | { 407 | v15 = DeviceObject; 408 | if ( DeviceObject == (PDEVICE_OBJECT)&DeviceObject || (HIDWORD(DeviceObject->Timer) & 4) == 0 ) 409 | goto LABEL_15; 410 | v16 = 27i64; 411 | LABEL_14: 412 | sub_140001EE0(v15->AttachedDevice, v16, &unk_140003280); 413 | LABEL_15: 414 | v4 = -1073741811; 415 | goto LABEL_26; 416 | } 417 | if ( !word_14000400C ) 418 | { 419 | LABEL_17: 420 | v4 = -1073741637; 421 | goto LABEL_26; 422 | } 423 | if ( DeviceObject != (PDEVICE_OBJECT)&DeviceObject && (HIDWORD(DeviceObject->Timer) & 4) != 0 ) 424 | sub_140001F44( 425 | DeviceObject->AttachedDevice, 426 | 28i64, 427 | &unk_140003280, 428 | *(unsigned int *)&v14->Type, 429 | *(_DWORD *)(&v14->Size + 1)); 430 | sub_14000104B(word_14000400C, *(_DWORD *)&v14->Type, &v14->Size + 1); 431 | if ( DeviceObject != (PDEVICE_OBJECT)&DeviceObject && (HIDWORD(DeviceObject->Timer) & 4) != 0 ) 432 | sub_140001F08(DeviceObject->AttachedDevice, 29i64, &unk_140003280, *(unsigned int *)(&v14->Size + 1)); 433 | a2->IoStatus.Information = 8i64; 434 | LABEL_25: 435 | v4 = 0; 436 | } 437 | LABEL_26: 438 | a2->IoStatus.Status = v4; 439 | IofCompleteRequest(a2, 0); 440 | return (unsigned int)v4; 441 | } 442 | ~~~ 443 | 444 | ### IOCTL 0x222804 445 | 446 | This IOCTL code triggers physical memory map operation. 447 | 448 | ~~~c 449 | v9 = LowPart - 0x222804; 450 | if ( !v9 ) // 0x222804 451 | { 452 | pinputbuffer = (DWORD *)a2->AssociatedIrp.MasterIrp; 453 | inputbuffer_1_2 = pinputbuffer[1]; 454 | if ( inputbuffer_len < inputbuffer_1_2 + 8 || outputbuffer_len < inputbuffer_1_2 + 8 )// inputbuffer_len>=inputbuffer[1]+8 455 | // outputbuffer_len>=inputbuffer[1]+8 456 | { 457 | v15 = DeviceObject; 458 | if ( DeviceObject == (PDEVICE_OBJECT)&DeviceObject || (HIDWORD(DeviceObject->Timer) & 4) == 0 ) 459 | goto LABEL_15; 460 | v16 = 10i64; 461 | goto LABEL_14; 462 | } 463 | inputbuffer_0_1 = *pinputbuffer; 464 | v60 = *pinputbuffer + inputbuffer_1_2 - 1; 465 | v61_ffff0000 = -(int)NumberOfBytes; // ffff0000 466 | if ( DeviceObject != (PDEVICE_OBJECT)&DeviceObject ) 467 | { 468 | if ( (HIDWORD(DeviceObject->Timer) & 4) != 0 ) 469 | sub_140001F44( 470 | DeviceObject->AttachedDevice, 471 | 11i64, 472 | &unk_140003280, 473 | inputbuffer_0_1, 474 | inputbuffer_0_1 + inputbuffer_1_2 - 1); 475 | if ( DeviceObject != (PDEVICE_OBJECT)&DeviceObject && (HIDWORD(DeviceObject->Timer) & 4) != 0 ) 476 | sub_140001F44(DeviceObject->AttachedDevice, 12i64, &unk_140003280, v61_ffff0000, -1); 477 | } 478 | if ( (inputbuffer_0_1 < 0xF0000 || v60 > 0xFFFFF) && inputbuffer_0_1 < v61_ffff0000 )// inputbuffer[0]>=0xf0000 && inputbuffer[0]+inputbuffer[1]-1<0xfffff 479 | // 480 | // or 481 | // 482 | // inputbuffer[0]>=ffff0000 483 | { 484 | if ( DeviceObject != (PDEVICE_OBJECT)&DeviceObject && (HIDWORD(DeviceObject->Timer) & 4) != 0 ) 485 | sub_140001F44(DeviceObject->AttachedDevice, 14i64, &unk_140003280, inputbuffer_0_1, v60); 486 | goto LABEL_17; 487 | } 488 | v62 = (char *)MmMapIoSpace((PHYSICAL_ADDRESS)*pinputbuffer, pinputbuffer[1], MmNonCached);// mapping range is 0xf0000-0x100000 489 | // or ffff0000 490 | v63 = v62; 491 | if ( v62 ) 492 | { 493 | sub_140002300(pinputbuffer + 2, v62, pinputbuffer[1]); 494 | MmUnmapIoSpace(v63, pinputbuffer[1]); 495 | a2->IoStatus.Information = pinputbuffer[1] + 8i64; 496 | goto LABEL_25; 497 | } 498 | if ( DeviceObject != (PDEVICE_OBJECT)&DeviceObject && (HIDWORD(DeviceObject->Timer) & 4) != 0 ) 499 | sub_140001EE0(DeviceObject->AttachedDevice, 13i64, &unk_140003280); 500 | v4 = -1073741823; 501 | goto LABEL_26; 502 | } 503 | ~~~ 504 | 505 | 506 | 507 | ### IOCTL 0x222810 508 | 509 | This IOCTL code triggers port write operation in function sub_140001000. 510 | 511 | ~~~c 512 | __int16 __fastcall sub_140001000(unsigned __int16 a1, __int16 a2) 513 | { 514 | __int16 result; // ax 515 | 516 | result = a2; 517 | if ( HIBYTE(a2) ) 518 | __outword(a1, a2); 519 | else 520 | __outbyte(a1, a2); 521 | return result; 522 | } 523 | ~~~ 524 | 525 | 526 | 527 | 528 | -------------------------------------------------------------------------------- /CVE-2024-33222/README.md: -------------------------------------------------------------------------------- 1 | # Vulnerable Driver ATSZIO64.sys in ASUS ATSZIO Driver v0.2.1.7 2 | 3 | --- 4 | 5 | ATSZIO64.sys in ASUS ATSZIO Driver 0.2.1.7 exposes functionality that allows low-privileged users to map arbitrary physical memory, read and write arbitary i/o port and interact MSR via specially crafted IOCTL requests. This can be exploited for privilege escalation, code execution under high privileges, and information disclosure. These signed drivers can also be used to bypass the Microsoft driver-signing policy to deploy malicious code. 6 | 7 | ## version 8 | 9 | 0.2.1.7 10 | 11 | ## Vulnerability causes 12 | 13 | ATSZIO64.sys provides the functionality of mapping physical memory, read/write I/O ports and MSR interaction, but it does not restrict the privileges of the caller, resulting in low-privileged users being able to call the driver and execute corresponding functions through DeviceIoControl. 14 | 15 | ~~~c 16 | __int64 __fastcall ioctler(_DRIVER_OBJECT *driver_object, _IRP *a2) 17 | { 18 | int v3; // ebx 19 | struct _IO_STACK_LOCATION *CurrentStackLocation; // rax 20 | unsigned int LowPart; // edx 21 | ULONG_PTR length; // r14 22 | ULONG_PTR Length; // r15 23 | PWSTR Buffer; // rsi 24 | struct _IRP *v9; // r9 25 | unsigned __int8 v10; // al 26 | struct _IRP *v11; // rcx 27 | char v12; // al 28 | unsigned __int8 v13; // al 29 | unsigned __int16 v14; // dx 30 | unsigned int MdlAddress_high; // eax 31 | unsigned __int16 v16; // dx 32 | struct _IRP *v17; // rcx 33 | char v18; // al 34 | unsigned __int32 v19; // eax 35 | unsigned __int32 v20; // eax 36 | unsigned __int16 MdlAddress; // dx 37 | struct _IRP *v22; // rcx 38 | char v23; // dl 39 | char Type; // al 40 | unsigned __int32 v25; // eax 41 | struct _IRP *v26; // r9 42 | PVOID inputbuffer; // rsi 43 | unsigned __int16 v28; // r15 44 | NTSTATUS v29; // eax 45 | _BYTE *mapped_virtual_addr_1; // rdx 46 | char v31; // al 47 | struct _IRP *v32; // rsi 48 | unsigned __int16 v33; // r15 49 | char v34; // al 50 | struct _IRP *v35; // r9 51 | unsigned __int16 v36; // cx 52 | _BYTE *v37; // r10 53 | unsigned __int8 v38; // al 54 | struct _IRP *v39; // rcx 55 | unsigned __int16 v40; // dx 56 | _BYTE *v41; // r9 57 | unsigned __int8 v42; // al 58 | struct _IRP *v43; // rcx 59 | unsigned __int16 v44; // dx 60 | _DWORD *v45; // r8 61 | unsigned __int32 v46; // eax 62 | PVOID inputbuffer_1; // rsi 63 | __int64 v48; // r12 64 | _BYTE *mapped_virtual_addr_2; // rcx 65 | signed __int64 v50; // rsi 66 | struct _IRP *v51; // r14 67 | ULONG BusDataByOffset; // eax 68 | int v53; // r9d 69 | char v54; // al 70 | struct _IRP *v55; // rsi 71 | struct _LIST_ENTRY *ContiguousMemory; // r14 72 | struct _IRP *v57; // r14 73 | ULONG v58; // edx 74 | ULONG v59; // ecx 75 | char v60; // al 76 | int Flags_low; // eax 77 | __int64 v62; // r8 78 | struct _IRP *v63; // rcx 79 | __int64 v64; // r8 80 | struct _IRP *v65; // rcx 81 | char v66; // dl 82 | PVOID inputbuffer_2; // rsi 83 | unsigned int Status; // ebx 84 | __int128 v70; // [rsp+30h] [rbp-48h] BYREF 85 | __int64 v71; // [rsp+40h] [rbp-38h] 86 | int v72; // [rsp+48h] [rbp-30h] 87 | PVOID mapped_virtual_addr; // [rsp+80h] [rbp+8h] BYREF 88 | PHANDLE physical_memory_handle; // [rsp+88h] [rbp+10h] BYREF 89 | 90 | physical_memory_handle = (PHANDLE)a2; 91 | v3 = 0; 92 | a2->IoStatus.Status = 0; 93 | a2->IoStatus.Information = 0i64; 94 | CurrentStackLocation = a2->Tail.Overlay.CurrentStackLocation; 95 | LowPart = CurrentStackLocation->Parameters.Read.ByteOffset.LowPart; 96 | length = CurrentStackLocation->Parameters.Create.Options; 97 | Length = CurrentStackLocation->Parameters.Read.Length; 98 | Buffer = driver_object->DriverName.Buffer; 99 | if ( LowPart <= 0x88070F84 ) 100 | { 101 | if ( LowPart == 0x88070F84 ) 102 | { 103 | inputbuffer_1 = a2->AssociatedIrp.MasterIrp; 104 | *((_QWORD *)inputbuffer_1 + 4) = 0i64; 105 | if ( !(_DWORD)length ) 106 | goto LABEL_140; 107 | v48 = 4096i64; 108 | v29 = call_ZwMapOfSection( 109 | (union _LARGE_INTEGER)(*((_QWORD *)inputbuffer_1 + 3) & 0xFFFFFFFFFFFFF000ui64), 110 | 0x1000u, 111 | &mapped_virtual_addr, 112 | (PHANDLE)&physical_memory_handle); 113 | mapped_virtual_addr_1 = mapped_virtual_addr; 114 | *((_QWORD *)inputbuffer_1 + 4) = mapped_virtual_addr; 115 | *((_QWORD *)inputbuffer_1 + 1) = physical_memory_handle; 116 | if ( v29 < 0 ) 117 | goto LABEL_137; 118 | mapped_virtual_addr_2 = mapped_virtual_addr_1; 119 | v50 = (_BYTE *)inputbuffer_1 - mapped_virtual_addr_1;// ?! here can cause BSOD 120 | do 121 | { 122 | mapped_virtual_addr_2[v50 + 40] = *mapped_virtual_addr_2; 123 | ++mapped_virtual_addr_2; 124 | --v48; 125 | } 126 | while ( v48 ); 127 | } 128 | else 129 | { 130 | if ( LowPart <= 0x88070F6C ) 131 | { 132 | switch ( LowPart ) 133 | { 134 | case 0x88070F6C: 135 | KeWaitForSingleObject(*((PVOID *)Buffer + 5), Executive, 0, 0, 0i64); 136 | v26 = a2->AssociatedIrp.MasterIrp; 137 | if ( LOBYTE(v26->Type) != 1 ) 138 | goto LABEL_130; 139 | __outbyte((unsigned __int16)v26->MdlAddress, BYTE2(v26->MdlAddress)); 140 | v13 = BYTE2(v26->Flags); 141 | v14 = LOWORD(v26->MdlAddress) + 1; 142 | goto LABEL_14; 143 | case 0x88070F58: 144 | KeWaitForSingleObject(*((PVOID *)Buffer + 5), Executive, 0, 0, 0i64); 145 | v17 = a2->AssociatedIrp.MasterIrp; 146 | __outdword(0xCF8u, *(_DWORD *)(&v17->Size + 1)); 147 | Type = v17->Type; 148 | if ( LOBYTE(v17->Type) == 1 ) 149 | { 150 | v19 = __indword(0xCFCu); 151 | goto LABEL_35; 152 | } 153 | if ( Type == 2 ) 154 | { 155 | v20 = __indword(0xCFCu); 156 | goto LABEL_38; 157 | } 158 | if ( Type != 4 ) 159 | goto LABEL_130; 160 | MdlAddress = 3324; 161 | break; 162 | case 0x88070F5C: 163 | KeWaitForSingleObject(*((PVOID *)Buffer + 5), Executive, 0, 0, 0i64); 164 | v22 = a2->AssociatedIrp.MasterIrp; 165 | __outdword(0xCF8u, *(_DWORD *)(&v22->Size + 1)); 166 | __indword(0xCFCu); 167 | v23 = v22->Type; 168 | if ( LOBYTE(v22->Type) == 1 ) 169 | { 170 | MdlAddress_high = 0; 171 | } 172 | else if ( v23 == 2 ) 173 | { 174 | MdlAddress_high = 0; 175 | } 176 | else 177 | { 178 | if ( v23 != 4 ) 179 | goto LABEL_130; 180 | MdlAddress_high = HIDWORD(v22->MdlAddress); 181 | } 182 | v16 = 3324; 183 | goto LABEL_32; 184 | case 0x88070F60: // in primitive 185 | KeWaitForSingleObject(*((PVOID *)Buffer + 5), Executive, 0, 0, 0i64); 186 | v17 = a2->AssociatedIrp.MasterIrp; 187 | v18 = v17->Type; 188 | if ( LOBYTE(v17->Type) == 1 ) 189 | { 190 | LOBYTE(v19) = __inbyte((unsigned __int16)v17->MdlAddress); 191 | LABEL_35: 192 | BYTE2(v17->Flags) = v19; 193 | goto LABEL_42; 194 | } 195 | if ( v18 == 2 ) 196 | { 197 | LOWORD(v20) = __inword((unsigned __int16)v17->MdlAddress); 198 | LABEL_38: 199 | LOWORD(v17->Flags) = v20; 200 | goto LABEL_42; 201 | } 202 | if ( v18 != 4 ) 203 | goto LABEL_130; 204 | MdlAddress = (unsigned __int16)v17->MdlAddress; 205 | break; 206 | case 0x88070F64:// out primitive 207 | KeWaitForSingleObject(*((PVOID *)Buffer + 5), Executive, 0, 0, 0i64); 208 | v11 = a2->AssociatedIrp.MasterIrp; 209 | v12 = v11->Type; 210 | if ( LOBYTE(v11->Type) == 1 ) 211 | { 212 | v13 = BYTE2(v11->Flags); 213 | v14 = (unsigned __int16)v11->MdlAddress; 214 | LABEL_14: 215 | __outbyte(v14, v13); 216 | LABEL_131: 217 | KeSetEvent(*((PRKEVENT *)Buffer + 5), 0, 0); 218 | goto LABEL_141; 219 | } 220 | if ( v12 == 2 ) 221 | { 222 | __outword((unsigned __int16)v11->MdlAddress, v11->Flags); 223 | goto LABEL_131; 224 | } 225 | if ( v12 != 4 ) 226 | goto LABEL_130; 227 | MdlAddress_high = HIDWORD(v11->MdlAddress); 228 | v16 = (unsigned __int16)v11->MdlAddress; 229 | LABEL_32: 230 | __outdword(v16, MdlAddress_high); 231 | goto LABEL_131; 232 | case 0x88070F68: 233 | KeWaitForSingleObject(*((PVOID *)Buffer + 5), Executive, 0, 0, 0i64); 234 | v9 = a2->AssociatedIrp.MasterIrp; 235 | if ( LOBYTE(v9->Type) == 1 ) 236 | { 237 | __outbyte((unsigned __int16)v9->MdlAddress, BYTE2(v9->MdlAddress)); 238 | v10 = __inbyte(LOWORD(v9->MdlAddress) + 1); 239 | BYTE2(v9->Flags) = v10; 240 | LABEL_42: 241 | a2->IoStatus.Information = 20i64; 242 | goto LABEL_131; 243 | } 244 | LABEL_130: 245 | a2->IoStatus.Status = -1073741811; 246 | goto LABEL_131; 247 | default: 248 | LABEL_140: 249 | a2->IoStatus.Status = 0xC000000D; 250 | goto LABEL_141; 251 | } 252 | v25 = __indword(MdlAddress); 253 | HIDWORD(v17->MdlAddress) = v25; 254 | goto LABEL_42; 255 | } 256 | switch ( LowPart ) 257 | { 258 | case 0x88070F70: 259 | KeWaitForSingleObject(*((PVOID *)Buffer + 5), Executive, 0, 0, 0i64); 260 | v43 = a2->AssociatedIrp.MasterIrp; 261 | v44 = (unsigned __int16)v43->MdlAddress; 262 | if ( v44 <= 0x200u ) 263 | { 264 | if ( v44 ) 265 | { 266 | v45 = (_DWORD *)((char *)&v43->MdlAddress + 2); 267 | do 268 | { 269 | __outdword(0xCF8u, *(_DWORD *)&v43->Type); 270 | v46 = __indword(0xCFCu); 271 | *v45 = v46; 272 | *(_DWORD *)&v43->Type += 4; 273 | a2->IoStatus.Information = 524i64; 274 | v3 += 4; 275 | ++v45; 276 | } 277 | while ( v3 < LOWORD(v43->MdlAddress) ); 278 | } 279 | goto LABEL_131; 280 | } 281 | goto LABEL_130; 282 | case 0x88070F74: 283 | KeWaitForSingleObject(*((PVOID *)Buffer + 5), Executive, 0, 0, 0i64); 284 | v39 = a2->AssociatedIrp.MasterIrp; 285 | v40 = (unsigned __int16)v39->MdlAddress; 286 | if ( v40 <= 0x200u ) 287 | { 288 | if ( v40 ) 289 | { 290 | v41 = (char *)&v39->MdlAddress + 2; 291 | do 292 | { 293 | v42 = __inbyte(*(&v39->Size + 1)); 294 | *v41 = v42; 295 | ++*(&v39->Size + 1); 296 | a2->IoStatus.Information = 524i64; 297 | ++v3; 298 | ++v41; 299 | } 300 | while ( v3 < LOWORD(v39->MdlAddress) ); 301 | } 302 | goto LABEL_131; 303 | } 304 | goto LABEL_130; 305 | case 0x88070F78: 306 | KeWaitForSingleObject(*((PVOID *)Buffer + 5), Executive, 0, 0, 0i64); 307 | v35 = a2->AssociatedIrp.MasterIrp; 308 | v36 = (unsigned __int16)v35->MdlAddress; 309 | if ( v36 <= 0x200u && v36 ) 310 | { 311 | v37 = (char *)&v35->MdlAddress + 2; 312 | do 313 | { 314 | __outbyte(*(&v35->Size + 1), *((_BYTE *)&v35->Size + 4)); 315 | v38 = __inbyte(*(&v35->Size + 1) + 1); 316 | *v37 = v38; 317 | ++*((_BYTE *)&v35->Size + 4); 318 | a2->IoStatus.Information = 524i64; 319 | ++v3; 320 | ++v37; 321 | } 322 | while ( v3 < LOWORD(v35->MdlAddress) ); 323 | } 324 | goto LABEL_131; 325 | } 326 | if ( LowPart != 0x88070F7C ) 327 | { 328 | if ( LowPart != 0x88070F80 ) 329 | goto LABEL_140; 330 | inputbuffer = a2->AssociatedIrp.MasterIrp; 331 | v28 = *((_WORD *)inputbuffer + 12) & 0xFFF; 332 | *((_QWORD *)inputbuffer + 4) = 0i64; 333 | if ( !(_DWORD)length ) 334 | goto LABEL_140; 335 | v29 = call_ZwMapOfSection( // write arbitrary physical memory IOCTL_CODE = 0x88070f80 336 | (union _LARGE_INTEGER)(*((_QWORD *)inputbuffer + 3) & 0xFFFFFFFFFFFFF000ui64), 337 | *((_DWORD *)inputbuffer + 4), 338 | &mapped_virtual_addr, 339 | (PHANDLE)&physical_memory_handle); 340 | mapped_virtual_addr_1 = mapped_virtual_addr; 341 | *((_QWORD *)inputbuffer + 4) = mapped_virtual_addr; 342 | *((_QWORD *)inputbuffer + 1) = physical_memory_handle; 343 | if ( v29 >= 0 ) 344 | { 345 | v31 = *(_BYTE *)inputbuffer; 346 | if ( *(_BYTE *)inputbuffer == 1 ) // write byte 347 | { 348 | mapped_virtual_addr_1[v28] = *((_BYTE *)inputbuffer + 1); 349 | } 350 | else if ( v31 == 2 ) // write word 351 | { 352 | if ( v28 > 0xFFEu ) 353 | goto LABEL_140; 354 | *(_WORD *)&mapped_virtual_addr_1[v28] = *((_WORD *)inputbuffer + 1); 355 | } 356 | else // write dword 357 | { 358 | if ( v31 != 4 || v28 > 0xFFCu ) 359 | goto LABEL_140; 360 | *(_DWORD *)&mapped_virtual_addr_1[v28] = *((_DWORD *)inputbuffer + 1); 361 | } 362 | goto LABEL_60; 363 | } 364 | LABEL_137: 365 | a2->IoStatus.Status = v29; 366 | goto LABEL_141; 367 | } 368 | v32 = a2->AssociatedIrp.MasterIrp; 369 | v33 = (__int64)v32->AssociatedIrp.MasterIrp & 0xFFF; 370 | v32->ThreadListEntry.Flink = 0i64; 371 | if ( !(_DWORD)length ) 372 | goto LABEL_140; 373 | v29 = call_ZwMapOfSection( 374 | (union _LARGE_INTEGER)((unsigned __int64)v32->AssociatedIrp.MasterIrp & 0xFFFFFFFFFFFFF000ui64), 375 | 0x1000u, 376 | &mapped_virtual_addr, 377 | (PHANDLE)&physical_memory_handle); 378 | v32->MdlAddress = (PMDL)physical_memory_handle; 379 | mapped_virtual_addr_1 = mapped_virtual_addr; 380 | v32->ThreadListEntry.Flink = (struct _LIST_ENTRY *)mapped_virtual_addr; 381 | if ( v29 < 0 ) 382 | goto LABEL_137; 383 | v34 = v32->Type; 384 | if ( LOBYTE(v32->Type) == 1 ) 385 | { 386 | HIBYTE(v32->Type) = mapped_virtual_addr_1[v33]; 387 | } 388 | else if ( v34 == 2 ) 389 | { 390 | if ( v33 > 0xFFEu ) 391 | goto LABEL_140; 392 | v32->Size = *(_WORD *)&mapped_virtual_addr_1[v33]; 393 | } 394 | else 395 | { 396 | if ( v34 != 4 || v33 > 0xFFCu ) 397 | goto LABEL_140; 398 | *(_DWORD *)(&v32->Size + 1) = *(_DWORD *)&mapped_virtual_addr_1[v33]; 399 | } 400 | } 401 | LABEL_60: 402 | a2->IoStatus.Information = length; 403 | v29 = call_ZwUnMapViewOfSection(physical_memory_handle, mapped_virtual_addr_1); 404 | goto LABEL_137; 405 | } 406 | if ( LowPart > 0x88072004 ) 407 | { 408 | if ( LowPart == 0x8807200C ) 409 | { 410 | inputbuffer_2 = a2->AssociatedIrp.MasterIrp; 411 | *((_QWORD *)inputbuffer_2 + 4) = 0i64; 412 | if ( (_DWORD)length ) 413 | { 414 | call_ZwMapOfSection( // mapping physical memory 415 | (union _LARGE_INTEGER)(*((_QWORD *)inputbuffer_2 + 3) & 0xFFFFFFFFFFFFF000ui64), 416 | *((_DWORD *)inputbuffer_2 + 4), 417 | (PVOID *)&physical_memory_handle, 418 | &mapped_virtual_addr); 419 | *((_QWORD *)inputbuffer_2 + 4) = physical_memory_handle; 420 | *((_QWORD *)inputbuffer_2 + 1) = mapped_virtual_addr; 421 | a2->IoStatus.Information = Length; 422 | goto LABEL_141; 423 | } 424 | goto LABEL_140; 425 | } 426 | if ( LowPart != 0x88072010 ) 427 | { 428 | if ( LowPart == -2012798956 ) 429 | { 430 | KeWaitForSingleObject(*((PVOID *)Buffer + 5), Executive, 0, 0, 0i64); 431 | v65 = a2->AssociatedIrp.MasterIrp; 432 | v66 = v65->Type; 433 | if ( ((LOBYTE(v65->Type) - 1) & 0xFC) == 0 && v66 != 3 && (unsigned int)length >= 0x23 ) 434 | { 435 | v70 = *(_OWORD *)((char *)&v65->Size + 5); 436 | v71 = *(_QWORD *)((char *)&v65->Flags + 7); 437 | v72 = *(_DWORD *)((char *)&v65->AssociatedIrp.SystemBuffer + 7); 438 | LOBYTE(v64) = v66; 439 | sub_140001010( 440 | *(unsigned __int16 *)((char *)&v65->Type + 1), 441 | *(unsigned int *)((char *)&v65->Size + 1), 442 | v64, 443 | &v70); 444 | goto LABEL_131; 445 | } 446 | goto LABEL_130; 447 | } 448 | if ( LowPart == -2012798952 ) 449 | { 450 | KeWaitForSingleObject(*((PVOID *)Buffer + 5), Executive, 0, 0, 0i64); 451 | v63 = a2->AssociatedIrp.MasterIrp; 452 | if ( ((LOBYTE(v63->Type) - 1) & 0xFC) == 0 && LOBYTE(v63->Type) != 3 && (unsigned int)length >= 0x23 ) 453 | { 454 | LOBYTE(v62) = v63->Type; 455 | sub_140001100( 456 | *(unsigned __int16 *)((char *)&v63->Type + 1), 457 | *(unsigned int *)((char *)&v63->Size + 1), 458 | v62, 459 | (char *)&v63->Size + 5); 460 | a2->IoStatus.Information = 35i64; 461 | goto LABEL_131; 462 | } 463 | goto LABEL_130; 464 | } 465 | goto LABEL_140; 466 | } 467 | v29 = call_ZwUnMapViewOfSection( 468 | a2->AssociatedIrp.MasterIrp->MdlAddress, 469 | a2->AssociatedIrp.MasterIrp->ThreadListEntry.Flink); 470 | a2->IoStatus.Information = 0i64; 471 | goto LABEL_137; 472 | } 473 | switch ( LowPart ) 474 | { 475 | case 0x88072004: 476 | KeWaitForSingleObject(*((PVOID *)Buffer + 5), Executive, 0, 0, 0i64); 477 | v57 = a2->AssociatedIrp.MasterIrp; 478 | LODWORD(physical_memory_handle) = 0; 479 | v58 = *((unsigned __int8 *)&v57->Size + 4); 480 | v59 = (unsigned __int8)*(_DWORD *)(&v57->Size + 1); 481 | v60 = v57->Type; 482 | if ( LOBYTE(v57->Type) == 1 ) 483 | { 484 | Flags_low = BYTE2(v57->Flags); 485 | } 486 | else if ( v60 == 2 ) 487 | { 488 | Flags_low = LOWORD(v57->Flags); 489 | } 490 | else 491 | { 492 | if ( v60 != 4 ) 493 | { 494 | a2->IoStatus.Status = -1073741811; 495 | LABEL_120: 496 | if ( HalSetBusDataByOffset( 497 | PCIConfiguration, 498 | v58, 499 | (*(_DWORD *)(&v57->Size + 1) & 0x700 | (*(_DWORD *)(&v57->Size + 1) >> 8) & 0xF8u) >> 3, 500 | &physical_memory_handle, 501 | v59, 502 | LOBYTE(v57->Type)) == LOBYTE(v57->Type) ) 503 | goto LABEL_42; 504 | goto LABEL_130; 505 | } 506 | Flags_low = HIDWORD(v57->MdlAddress); 507 | } 508 | LODWORD(physical_memory_handle) = Flags_low; 509 | goto LABEL_120; 510 | case 0x88070F88: 511 | a2->AssociatedIrp.MasterIrp->MdlAddress = (PMDL)__readmsr(*(_DWORD *)a2->AssociatedIrp.MasterIrp);// rdmsr 512 | a2->IoStatus.Information = 16i64; 513 | break; 514 | case 0x88070F8C: 515 | __writemsr(*(_DWORD *)a2->AssociatedIrp.MasterIrp, (unsigned __int64)a2->AssociatedIrp.MasterIrp->MdlAddress);// wrmsr 516 | break; 517 | case 0x88070F90: 518 | v55 = a2->AssociatedIrp.MasterIrp; 519 | DbgPrint("XXXXXXXX alloc mem size is 0x%lx bytes !\n", v55->Flags); 520 | v55->ThreadListEntry.Flink = 0i64; 521 | ContiguousMemory = (struct _LIST_ENTRY *)MmAllocateContiguousMemory(v55->Flags, (PHYSICAL_ADDRESS)0xFFFFFFFFi64); 522 | if ( !ContiguousMemory ) 523 | goto LABEL_140; 524 | DbgPrint("XXXXXXXX address is 0x%lx !\n", v55->AssociatedIrp.MasterIrp); 525 | v55->AssociatedIrp.MasterIrp = (struct _IRP *)MmGetPhysicalAddress(ContiguousMemory).LowPart; 526 | v55->ThreadListEntry.Flink = ContiguousMemory; 527 | a2->IoStatus.Information = 4136i64; 528 | break; 529 | case 0x88070F94: 530 | MmFreeContiguousMemory(a2->AssociatedIrp.MasterIrp->ThreadListEntry.Flink); 531 | break; 532 | case 0x88072000: 533 | KeWaitForSingleObject(*((PVOID *)Buffer + 5), Executive, 0, 0, 0i64); 534 | v51 = a2->AssociatedIrp.MasterIrp; 535 | LODWORD(physical_memory_handle) = 0; 536 | BusDataByOffset = HalGetBusDataByOffset( 537 | PCIConfiguration, 538 | *((unsigned __int8 *)&v51->Size + 4), 539 | (*(_DWORD *)(&v51->Size + 1) & 0x700 | (*(_DWORD *)(&v51->Size + 1) >> 8) & 0xF8u) >> 3, 540 | &physical_memory_handle, 541 | (unsigned __int8)*(_DWORD *)(&v51->Size + 1), 542 | LOBYTE(v51->Type)); 543 | v53 = (int)physical_memory_handle; 544 | if ( BusDataByOffset != LOBYTE(v51->Type) ) 545 | v53 = -1; 546 | LODWORD(physical_memory_handle) = v53; 547 | v54 = v51->Type; 548 | if ( LOBYTE(v51->Type) == 1 ) 549 | { 550 | BYTE2(v51->Flags) = v53; 551 | } 552 | else if ( v54 == 2 ) 553 | { 554 | LOWORD(v51->Flags) = v53; 555 | } 556 | else if ( v54 == 4 ) 557 | { 558 | HIDWORD(v51->MdlAddress) = v53; 559 | } 560 | else 561 | { 562 | a2->IoStatus.Status = -1073741811; 563 | } 564 | goto LABEL_42; 565 | default: 566 | goto LABEL_140; 567 | } 568 | LABEL_141: 569 | Status = a2->IoStatus.Status; 570 | IofCompleteRequest(a2, 0); 571 | return Status; 572 | } 573 | ~~~ 574 | 575 | ### IOCTL 0x88070F60 576 | 577 | This IOCTL code triggers port in operation. 578 | 579 | ~~~c 580 | case 0x88070F60: 581 | KeWaitForSingleObject(*((PVOID *)Buffer + 5), Executive, 0, 0, 0i64);// in primitive 582 | v17 = a2->AssociatedIrp.MasterIrp; 583 | v18 = v17->Type; 584 | if ( LOBYTE(v17->Type) == 1 ) 585 | { 586 | LOBYTE(v19) = __inbyte((unsigned __int16)v17->MdlAddress); 587 | LABEL_35: 588 | BYTE2(v17->Flags) = v19; 589 | goto LABEL_42; 590 | } 591 | if ( v18 == 2 ) 592 | { 593 | LOWORD(v20) = __inword((unsigned __int16)v17->MdlAddress); 594 | LABEL_38: 595 | LOWORD(v17->Flags) = v20; 596 | goto LABEL_42; 597 | } 598 | if ( v18 != 4 ) 599 | goto LABEL_130; 600 | MdlAddress = (unsigned __int16)v17->MdlAddress; 601 | break; 602 | ~~~ 603 | 604 | 605 | 606 | ### IOCTL 0x88070F64 607 | 608 | This IOCTL code triggers port out operation . 609 | 610 | ~~~c 611 | case 0x88070F64: 612 | KeWaitForSingleObject(*((PVOID *)Buffer + 5), Executive, 0, 0, 0i64);// out primitive 613 | v11 = a2->AssociatedIrp.MasterIrp; 614 | v12 = v11->Type; 615 | if ( LOBYTE(v11->Type) == 1 ) 616 | { 617 | v13 = BYTE2(v11->Flags); 618 | v14 = (unsigned __int16)v11->MdlAddress; 619 | LABEL_14: 620 | __outbyte(v14, v13); 621 | LABEL_131: 622 | KeSetEvent(*((PRKEVENT *)Buffer + 5), 0, 0); 623 | goto LABEL_141; 624 | } 625 | if ( v12 == 2 ) 626 | { 627 | __outword((unsigned __int16)v11->MdlAddress, v11->Flags); 628 | goto LABEL_131; 629 | } 630 | if ( v12 != 4 ) 631 | goto LABEL_130; 632 | MdlAddress_high = HIDWORD(v11->MdlAddress); 633 | v16 = (unsigned __int16)v11->MdlAddress; 634 | LABEL_32: 635 | __outdword(v16, MdlAddress_high); 636 | goto LABEL_131; 637 | ~~~ 638 | 639 | 640 | 641 | ### IOCTL 0x8807200C 642 | 643 | This IOCTL code triggers memory map operation in function 0x140005B0C . 644 | 645 | ~~~c 646 | NTSTATUS __fastcall call_ZwMapOfSection(union _LARGE_INTEGER a1, unsigned int a2, PVOID *a3, PHANDLE a4) 647 | { 648 | ULONG_PTR v4; // rbx 649 | NTSTATUS result; // eax 650 | SIZE_T v9; // r15 651 | NTSTATUS v10; // eax 652 | void *v11; // rcx 653 | NTSTATUS v12; // ebx 654 | NTSTATUS v13; // ebx 655 | union _LARGE_INTEGER SectionOffset; // [rsp+58h] [rbp-39h] BYREF 656 | ULONG_PTR ViewSize; // [rsp+60h] [rbp-31h] BYREF 657 | struct _OBJECT_ATTRIBUTES ObjectAttributes; // [rsp+68h] [rbp-29h] BYREF 658 | struct _UNICODE_STRING DestinationString; // [rsp+98h] [rbp+7h] BYREF 659 | PVOID Object; // [rsp+A8h] [rbp+17h] BYREF 660 | PVOID BaseAddress; // [rsp+F8h] [rbp+67h] BYREF 661 | 662 | v4 = a2; 663 | RtlInitUnicodeString(&DestinationString, L"\\Device\\PhysicalMemory"); 664 | ObjectAttributes.RootDirectory = 0i64; 665 | ObjectAttributes.SecurityDescriptor = 0i64; 666 | ObjectAttributes.SecurityQualityOfService = 0i64; 667 | ObjectAttributes.ObjectName = &DestinationString; 668 | ObjectAttributes.Length = 48; 669 | ObjectAttributes.Attributes = 512; 670 | result = ZwOpenSection(a4, 7u, &ObjectAttributes); 671 | BaseAddress = 0i64; 672 | v9 = (unsigned int)v4; 673 | ViewSize = v4; 674 | SectionOffset = a1; 675 | if ( result >= 0 ) 676 | { 677 | v10 = ObReferenceObjectByHandle(*a4, 7u, 0i64, 0, &Object, 0i64); 678 | v11 = *a4; 679 | v12 = v10; 680 | if ( v10 >= 0 ) 681 | { 682 | v13 = ZwMapViewOfSection( 683 | v11, // rcx 684 | (HANDLE)0xFFFFFFFFFFFFFFFFi64, // rdx 685 | &BaseAddress, // r8 686 | 0i64, // r9 687 | v9, // rsp+20 688 | &SectionOffset, // rsp+28 689 | &ViewSize, // rsp+30 690 | ViewShare, // rsp+38 691 | 0, 692 | 4u); 693 | ZwClose(*a4); 694 | result = v13; 695 | *a3 = BaseAddress; 696 | return result; 697 | } 698 | ZwClose(v11); 699 | result = v12; 700 | } 701 | *a3 = 0i64; 702 | return result; 703 | } 704 | ~~~ 705 | 706 | ### IOCTL 0x88070F88 707 | 708 | This IOCTL code triggers MSR read operation. 709 | 710 | ~~~c 711 | case 0x88070F88: 712 | a2->AssociatedIrp.MasterIrp->MdlAddress = (PMDL)__readmsr(*(_DWORD *)a2->AssociatedIrp.MasterIrp);// rdmsr 713 | a2->IoStatus.Information = 16i64; 714 | break; 715 | ~~~ 716 | 717 | ### IOCTL 0x88070F8C 718 | 719 | This IOCTL code triggers MSR write operation. 720 | 721 | ~~~c 722 | case 0x88070F8C: 723 | __writemsr(*(_DWORD *)a2->AssociatedIrp.MasterIrp, (unsigned __int64)a2->AssociatedIrp.MasterIrp->MdlAddress);// wrmsr 724 | break; 725 | ~~~ 726 | 727 | -------------------------------------------------------------------------------- /CVE-2024-33222/rtkio64.sys: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DriverHunter/Win-Driver-EXP/21726ae8475c10c893ae35f2b744dee8d7390057/CVE-2024-33222/rtkio64.sys -------------------------------------------------------------------------------- /CVE-2024-33223/IOMap64.sys: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DriverHunter/Win-Driver-EXP/21726ae8475c10c893ae35f2b744dee8d7390057/CVE-2024-33223/IOMap64.sys -------------------------------------------------------------------------------- /CVE-2024-33223/README.md: -------------------------------------------------------------------------------- 1 | # Vulnerable Driver IOMap64.sys in ASUS GPU TweakII v1.4.5.2 2 | 3 | --- 4 | 5 | IOMap64.sys in ASUS GPU TweakII v1.4.5.2 exposes functionality that allows low-privileged users to map arbitrary physical memory, read and write i/o port via specially crafted IOCTL requests. This can be exploited for privilege escalation, code execution under high privileges, and information disclosure. These signed drivers can also be used to bypass the Microsoft driver-signing policy to deploy malicious code. 6 | 7 | ## version 8 | 9 | 1.4.5.2 10 | 11 | ## Vulnerability causes 12 | 13 | IOMap64.sys provides the functionality of mapping physical memory, read/write I/O ports , but it does not restrict the privileges of the caller, resulting in low-privileged users being able to call the driver and execute corresponding functions through DeviceIoControl. 14 | 15 | ~~~c 16 | __int64 __fastcall sub_11294(__int64 a1, IRP *a2) 17 | { 18 | __int64 v3; // rbp 19 | struct _IO_STACK_LOCATION *CurrentStackLocation; // rcx 20 | ULONG_PTR *p_Information; // rsi 21 | struct _IRP *MasterIrp; // rdi 22 | __int64 Length; // r8 23 | __int64 Options; // rdx 24 | unsigned int LowPart; // eax 25 | char v10; // al 26 | unsigned __int32 v11; // eax 27 | unsigned int Status; // edi 28 | int v14; // eax 29 | PVOID v15; // rcx 30 | int v16; // eax 31 | unsigned int v17; // ecx 32 | ULONG v18; // eax 33 | int v19; // r10d 34 | unsigned int MdlAddress; // r8d 35 | unsigned int MdlAddress_high; // ecx 36 | struct _IRP *v22; // r9 37 | unsigned int Flags; // eax 38 | int v24; // r8d 39 | __int64 v25; // rcx 40 | unsigned int v26; // eax 41 | unsigned __int32 v27; // eax 42 | PVOID v28; // rax 43 | unsigned int v29; // [rsp+60h] [rbp+8h] 44 | 45 | if ( a1 ) 46 | { 47 | if ( a2 ) 48 | { 49 | v3 = *(_QWORD *)(a1 + 0x40); 50 | CurrentStackLocation = a2->Tail.Overlay.CurrentStackLocation; 51 | p_Information = &a2->IoStatus.Information; 52 | a2->IoStatus.Status = 0; 53 | a2->IoStatus.Information = 0i64; 54 | if ( CurrentStackLocation ) 55 | { 56 | if ( v3 ) 57 | { 58 | MasterIrp = a2->AssociatedIrp.MasterIrp; 59 | Length = CurrentStackLocation->Parameters.Read.Length; 60 | Options = CurrentStackLocation->Parameters.Create.Options; 61 | if ( !CurrentStackLocation->MajorFunction || CurrentStackLocation->MajorFunction == 2 ) 62 | goto LABEL_27; 63 | if ( CurrentStackLocation->MajorFunction != 14 ) 64 | return v29; 65 | LowPart = CurrentStackLocation->Parameters.Read.ByteOffset.LowPart; 66 | if ( LowPart > 0x83002104 ) 67 | { 68 | if ( LowPart == -2097143532 ) 69 | { 70 | if ( (int)((__int64 (__fastcall *)(struct _IRP *, __int64, __int64))sub_122C4)(MasterIrp, Options, Length) >= 0 ) 71 | { 72 | LABEL_71: 73 | *p_Information = 8i64; 74 | goto LABEL_72; 75 | } 76 | goto LABEL_73; 77 | } 78 | if ( LowPart != 0x83002118 ) 79 | { 80 | switch ( LowPart ) 81 | { 82 | case 0x83002134: 83 | if ( !*(_DWORD *)&MasterIrp->Type && (v28 = BaseAddress) != 0i64 84 | || *(_DWORD *)&MasterIrp->Type == 1 && (v28 = qword_15130) != 0i64 ) 85 | { 86 | qword_15140 = (__int64)v28; 87 | v10 = 1; 88 | } 89 | else 90 | { 91 | v10 = 0; 92 | } 93 | goto LABEL_18; 94 | case 0x83002138: 95 | if ( (unsigned int)((__int64 (__fastcall *)(struct _IRP *, __int64, __int64))sub_1183C)(// map primitive 96 | MasterIrp, 97 | v3, 98 | Length) ) 99 | { 100 | *p_Information = 12i64; 101 | goto LABEL_72; 102 | } 103 | break; 104 | case 0x8300213C: 105 | v19 = *(_DWORD *)&MasterIrp->Type; 106 | MdlAddress = (unsigned int)MasterIrp->MdlAddress; 107 | MdlAddress_high = HIDWORD(MasterIrp->MdlAddress); 108 | v22 = MasterIrp->AssociatedIrp.MasterIrp; 109 | Flags = MasterIrp->Flags; 110 | if ( *(_DWORD *)&MasterIrp->Type <= 0x100u 111 | && *(_DWORD *)(&MasterIrp->Size + 1) <= 0x20u 112 | && MdlAddress <= 8 113 | && Flags ) 114 | { 115 | if ( Flags > 0x400 ) 116 | { 117 | MasterIrp->Flags = 1024; 118 | Flags = 1024; 119 | } 120 | if ( MdlAddress_high <= 0x400 ) 121 | { 122 | if ( MdlAddress_high <= Flags + MdlAddress_high ) 123 | { 124 | v24 = 4 125 | * (MdlAddress_high 126 | + ((MdlAddress + 8 * (*(_DWORD *)(&MasterIrp->Size + 1) + 32 * (v19 + 0x8000))) << 6)); 127 | v25 = Flags + 1; 128 | do 129 | { 130 | v26 = v24; 131 | v24 += 4; 132 | __outdword(0xCF8u, v26); 133 | v27 = __indword(0xCFCu); 134 | *(_DWORD *)&v22->Type = v27; 135 | v22 = (struct _IRP *)((char *)v22 + 4); 136 | --v25; 137 | } 138 | while ( v25 ); 139 | } 140 | *p_Information = 40i64; 141 | goto LABEL_72; 142 | } 143 | } 144 | break; 145 | case 0x83002140: 146 | v17 = (unsigned int)MasterIrp->MdlAddress; 147 | if ( *(_DWORD *)&MasterIrp->Type <= 0x100u 148 | && *(_DWORD *)(&MasterIrp->Size + 1) <= 0x20u 149 | && v17 <= 8 150 | && HIDWORD(MasterIrp->MdlAddress) <= 0x80 ) 151 | { 152 | __outdword( 153 | 0xCF8u, 154 | 4 155 | * (HIDWORD(MasterIrp->MdlAddress) 156 | + ((v17 + 8 * (*(_DWORD *)(&MasterIrp->Size + 1) + 32 * (*(_DWORD *)&MasterIrp->Type + 0x8000))) << 6))); 157 | v18 = __indword(0xCFCu); 158 | MasterIrp->Flags = v18; 159 | goto LABEL_34; 160 | } 161 | break; 162 | default: 163 | LABEL_44: 164 | a2->IoStatus.Status = sub_12EE4( 165 | v3, 166 | CurrentStackLocation->Parameters.Read.ByteOffset.LowPart, 167 | Options, 168 | Length, 169 | (__int64)MasterIrp, 170 | (__int64)MasterIrp, 171 | (__int64)p_Information); 172 | goto LABEL_27; 173 | } 174 | goto LABEL_37; 175 | } 176 | v16 = sub_1174C(MasterIrp, v3); 177 | qword_15130 = *(PVOID *)(v3 + 112); 178 | } 179 | else 180 | { 181 | if ( LowPart != -2097143548 ) 182 | { 183 | if ( LowPart != -2097143600 ) 184 | { 185 | if ( LowPart != -2097143596 ) 186 | { 187 | if ( LowPart != 0x830020D8 ) 188 | { 189 | switch ( LowPart ) 190 | { 191 | case 0x830020F4: 192 | v10 = ((__int64 (__fastcall *)(__int64, __int64, __int64))sub_11FCC)( 193 | 2197823748i64, 194 | Options, 195 | Length); 196 | LABEL_18: 197 | *p_Information = 4i64; 198 | if ( v10 ) 199 | *(_DWORD *)&MasterIrp->Type = 1; 200 | else 201 | *(_DWORD *)&MasterIrp->Type = 0; 202 | goto LABEL_72; 203 | case 0x830020F8: 204 | __outbyte(0xD808u, 0xAu); 205 | v11 = __indword(0xD80Cu); 206 | *(_DWORD *)(&MasterIrp->Size + 1) = BYTE1(v11); 207 | *(_DWORD *)&MasterIrp->Type = BYTE2(v11); 208 | break; 209 | case 0x830020FC: 210 | __outbyte(0xD808u, 0xAu); 211 | __indword(0xD830u); 212 | __outdword(0xD80Cu, 0x59490Cu); 213 | break; 214 | case 0x83002100: 215 | v10 = ((__int64 (__fastcall *)(__int64, __int64, __int64))sub_1214C)( 216 | 2197823748i64, 217 | Options, 218 | Length); 219 | goto LABEL_18; 220 | default: 221 | goto LABEL_44; 222 | } 223 | goto LABEL_71; 224 | } 225 | if ( (unsigned int)Length >= 4 ) 226 | { 227 | *(_DWORD *)&MasterIrp->Type = 0x1000000; 228 | *p_Information = 4i64; 229 | LABEL_72: 230 | a2->IoStatus.Status = 0; 231 | goto LABEL_27; 232 | } 233 | a2->IoStatus.Status = -1073741811; 234 | LABEL_27: 235 | Status = a2->IoStatus.Status; 236 | IofCompleteRequest(a2, 0); 237 | return Status; 238 | } 239 | v14 = sub_11CA8((unsigned __int16 *)MasterIrp, Options, Length); 240 | if ( v14 >= 0 ) 241 | { 242 | *p_Information = 32i64 * v14; 243 | goto LABEL_72; 244 | } 245 | LABEL_73: 246 | a2->IoStatus.Status = -1073741670; 247 | goto LABEL_27; 248 | } 249 | v15 = BaseAddress; 250 | PhysicalAddress.LowPart = (DWORD)MasterIrp->MdlAddress; 251 | PhysicalAddress.QuadPart = PhysicalAddress.LowPart; 252 | *(_DWORD *)(v3 + 84) = *(_DWORD *)&MasterIrp->Type; 253 | *(_DWORD *)(v3 + 88) = *(_DWORD *)(&MasterIrp->Size + 1); 254 | if ( v15 ) 255 | { 256 | MmUnmapIoSpace(v15, 0x1000000ui64); 257 | BaseAddress = 0i64; 258 | } 259 | ((void (__fastcall *)(_QWORD, _QWORD, _QWORD))sub_13478)( 260 | v3, 261 | (PHYSICAL_ADDRESS)PhysicalAddress.QuadPart, 262 | 0x1000000i64); 263 | LODWORD(MasterIrp->MdlAddress) = PhysicalAddress.LowPart; 264 | HIDWORD(MasterIrp->MdlAddress) = *(_DWORD *)(v3 + 96); 265 | BaseAddress = *(PVOID *)(v3 + 96); 266 | LABEL_34: 267 | *p_Information = 20i64; 268 | goto LABEL_72; 269 | } 270 | v16 = ((__int64 (__fastcall *)(struct _IRP *, __int64, __int64))sub_11B94)(MasterIrp, v3, Length);// map primitive 271 | qword_15128 = *(PVOID *)(v3 + 120); 272 | } 273 | if ( v16 ) 274 | goto LABEL_34; 275 | LABEL_37: 276 | a2->IoStatus.Status = -1073741823; 277 | goto LABEL_27; 278 | } 279 | } 280 | } 281 | } 282 | return 3221225473i64; 283 | } 284 | ~~~ 285 | 286 | ### IOCTL 0x83002138 287 | 288 | This IOCTL code triggers memory map operation in function sub_1198C. You can find more memory map operation by Xref of MmMapIoSpace 289 | 290 | ~~~c 291 | __int64 __fastcall sub_1198C(unsigned __int16 *a1, __int64 a2) 292 | { 293 | unsigned __int16 v2; // di 294 | void *v5; // rcx 295 | PVOID v6; // rax 296 | void *v7; // rcx 297 | PVOID v8; // rax 298 | PHYSICAL_ADDRESS BusAddress; // [rsp+70h] [rbp+8h] 299 | LARGE_INTEGER TranslatedAddress; // [rsp+80h] [rbp+18h] BYREF 300 | 301 | v2 = *a1; 302 | if ( *a1 < 0x10u ) 303 | { 304 | *(_DWORD *)(a2 + 80) = 5; 305 | *(_DWORD *)(a2 + 92) = 0; 306 | BusAddress.QuadPart = *((unsigned int *)a1 + 2); 307 | if ( !a1[10] ) 308 | { 309 | v5 = (void *)qword_15220[v2]; 310 | if ( v5 ) 311 | { 312 | MmUnmapIoSpace(v5, 0x1000000ui64); 313 | qword_15220[v2] = 0i64; 314 | if ( !v2 ) 315 | { 316 | BaseAddress = 0i64; 317 | qword_15140 = 0i64; 318 | *(_QWORD *)(a2 + 96) = 0i64; 319 | } 320 | if ( v2 == 1 ) 321 | { 322 | *(_QWORD *)(a2 + 112) = 0i64; 323 | qword_15130 = 0i64; 324 | } 325 | } 326 | HalTranslateBusAddress( 327 | *(INTERFACE_TYPE *)(a2 + 80), 328 | *(_DWORD *)(a2 + 84), 329 | BusAddress, 330 | (PULONG)(a2 + 92), 331 | &TranslatedAddress); 332 | v6 = MmMapIoSpace(BusAddress, 0x1000000ui64, MmNonCached); 333 | qword_15220[v2] = (__int64)v6; 334 | *((_DWORD *)a1 + 1) = (_DWORD)v6; 335 | if ( !v2 ) 336 | { 337 | BaseAddress = (PVOID)qword_15220[0]; 338 | qword_15140 = qword_15220[0]; 339 | *(_QWORD *)(a2 + 96) = qword_15220[0]; 340 | } 341 | if ( v2 == 1 ) 342 | { 343 | *(_QWORD *)(a2 + 112) = qword_15228; 344 | qword_15130 = (PVOID)qword_15228; 345 | } 346 | return 1i64; 347 | } 348 | if ( a1[10] == 1 ) 349 | { 350 | v7 = (void *)qword_152E0[v2]; 351 | if ( v7 ) 352 | { 353 | MmUnmapIoSpace(v7, 0x40000ui64); 354 | qword_152E0[v2] = 0i64; 355 | if ( !v2 ) 356 | { 357 | qword_15128 = 0i64; 358 | *(_QWORD *)(a2 + 112) = 0i64; 359 | qword_15138 = 0i64; 360 | } 361 | } 362 | HalTranslateBusAddress( 363 | *(INTERFACE_TYPE *)(a2 + 80), 364 | *(_DWORD *)(a2 + 84), 365 | BusAddress, 366 | (PULONG)(a2 + 92), 367 | &TranslatedAddress); 368 | v8 = MmMapIoSpace(BusAddress, 0x40000ui64, MmNonCached); 369 | qword_152E0[v2] = (__int64)v8; 370 | *((_DWORD *)a1 + 1) = (_DWORD)v8; 371 | *(_DWORD *)(a2 + 128) = 0x40000; 372 | if ( !v2 ) 373 | { 374 | qword_15128 = (PVOID)qword_152E0[0]; 375 | *(_QWORD *)(a2 + 112) = qword_152E0[0]; 376 | qword_15138 = qword_152E0[0]; 377 | } 378 | return 1i64; 379 | } 380 | } 381 | return 0i64; 382 | } 383 | ~~~ 384 | 385 | 386 | 387 | ### IOCTL 0x8300213C, 0x83002140, 0x830020F4, 0x830020F8, 0x830020FC, 0x83002100 388 | 389 | This IOCTL expose in/out operation on fixed io port 0xCF8,0xCFCu. There is a potential risk that may result in a Blue Screen of Death. 390 | 391 | The operations triggered by the IO control code 0x8300213C are as follows. 392 | 393 | ```c 394 | case 0x8300213C: 395 | v19 = *(_DWORD *)&MasterIrp->Type; 396 | MdlAddress = (unsigned int)MasterIrp->MdlAddress; 397 | MdlAddress_high = HIDWORD(MasterIrp->MdlAddress); 398 | v22 = MasterIrp->AssociatedIrp.MasterIrp; 399 | Flags = MasterIrp->Flags; 400 | if ( *(_DWORD *)&MasterIrp->Type <= 0x100u 401 | && *(_DWORD *)(&MasterIrp->Size + 1) <= 0x20u 402 | && MdlAddress <= 8 403 | && Flags ) 404 | { 405 | if ( Flags > 0x400 ) 406 | { 407 | MasterIrp->Flags = 1024; 408 | Flags = 1024; 409 | } 410 | if ( MdlAddress_high <= 0x400 ) 411 | { 412 | if ( MdlAddress_high <= Flags + MdlAddress_high ) 413 | { 414 | v24 = 4 415 | * (MdlAddress_high 416 | + ((MdlAddress + 8 * (*(_DWORD *)(&MasterIrp->Size + 1) + 32 * (v19 + 0x8000))) << 6)); 417 | v25 = Flags + 1; 418 | do 419 | { 420 | v26 = v24; 421 | v24 += 4; 422 | __outdword(0xCF8u, v26); 423 | v27 = __indword(0xCFCu); 424 | *(_DWORD *)&v22->Type = v27; 425 | v22 = (struct _IRP *)((char *)v22 + 4); 426 | --v25; 427 | } 428 | while ( v25 ); 429 | } 430 | *p_Information = 40i64; 431 | goto LABEL_72; 432 | } 433 | } 434 | break; 435 | ``` 436 | 437 | -------------------------------------------------------------------------------- /CVE-2024-33224/README.md: -------------------------------------------------------------------------------- 1 | # Vulnerable Driver rtkio64.sys in Realtek Semiconductor Corp Realtek lO Driver v1.008.0823.2017 2 | 3 | --- 4 | 5 | rtkio64.sys in Realtek Semiconductor Corp Realtek lO Driver v1.008.0823.2017 exposes functionality that allows low-privileged users to map arbitrary physical memory, read and write i/o port via specially crafted IOCTL requests. This can be exploited for privilege escalation, code execution under high privileges, and information disclosure. These signed drivers can also be used to bypass the Microsoft driver-signing policy to deploy malicious code. 6 | 7 | ## version 8 | 9 | 1.008.0823.2017 10 | 11 | ## Vulnerability causes 12 | 13 | rtkio64.sys provides the functionality of mapping physical memory, read/write I/O ports, but it does not restrict the privileges of the caller, resulting in low-privileged users being able to call the driver and execute corresponding functions through DeviceIoControl. 14 | 15 | ~~~c 16 | __int64 __fastcall sub_134BC(__int64 a1, __int64 a2) 17 | { 18 | unsigned int v3; // r12d 19 | unsigned __int16 *v4; // r13 20 | unsigned int v5; // ebx 21 | __int64 v6; // r9 22 | unsigned __int16 v7; // si 23 | unsigned __int8 v8; // di 24 | unsigned __int16 v9; // bx 25 | KAFFINITY ActiveProcessors; // rax 26 | __int64 v11; // rdx 27 | __int64 v12; // rbx 28 | unsigned __int8 v13; // al 29 | unsigned __int16 v14; // ax 30 | unsigned __int32 v15; // eax 31 | unsigned int *v16; // rbx 32 | _QWORD *v17; // rsi 33 | struct _MDL *v18; // rsi 34 | PVOID v19; // rax 35 | struct _MDL *Mdl; // rax 36 | unsigned int *PoolWithTag; // rax 37 | __int64 LowPart_low; // rcx 38 | __int64 v23; // r9 39 | unsigned __int16 v24; // ax 40 | int v25; // eax 41 | __int64 v26; // rcx 42 | __int64 v27; // r8 43 | int v28; // eax 44 | unsigned int v29; // ebx 45 | unsigned int v30; // eax 46 | __int64 v31; // rbx 47 | unsigned __int8 v32; // al 48 | char v33; // al 49 | int v34; // ecx 50 | int v35; // r8d 51 | int v36; // edx 52 | int v37; // ecx 53 | __int64 v38; // rdx 54 | int v39; // eax 55 | unsigned __int16 v40; // r11 56 | unsigned __int32 v41; // eax 57 | unsigned __int8 v42; // al 58 | unsigned __int8 v43; // bl 59 | unsigned __int16 v44; // dx 60 | unsigned __int16 v45; // dx 61 | unsigned __int16 v46; // r11 62 | unsigned __int32 v47; // eax 63 | unsigned __int8 v48; // al 64 | unsigned __int8 v49; // bl 65 | unsigned __int16 v50; // dx 66 | unsigned __int16 v51; // ax 67 | PIRP Irp; // [rsp+20h] [rbp-B8h] 68 | PIRP Irpa; // [rsp+20h] [rbp-B8h] 69 | PIRP Irpb; // [rsp+20h] [rbp-B8h] 70 | PIRP Irpc; // [rsp+20h] [rbp-B8h] 71 | PIRP Irpd; // [rsp+20h] [rbp-B8h] 72 | PIRP Irpe; // [rsp+20h] [rbp-B8h] 73 | PIRP Irpf; // [rsp+20h] [rbp-B8h] 74 | unsigned __int16 v60; // [rsp+70h] [rbp-68h] 75 | unsigned __int16 v61; // [rsp+72h] [rbp-66h] 76 | PVOID v62; // [rsp+78h] [rbp-60h] 77 | __int16 v63; // [rsp+78h] [rbp-60h] 78 | PVOID BaseAddress; // [rsp+F0h] [rbp+18h] BYREF 79 | PHYSICAL_ADDRESS PhysicalAddress; // [rsp+F8h] [rbp+20h] BYREF 80 | 81 | v3 = 0; 82 | if ( DeviceObject != (PDEVICE_OBJECT)&DeviceObject 83 | && (BYTE4(DeviceObject->Timer) & 1) != 0 84 | && BYTE1(DeviceObject->Timer) >= 4u ) 85 | { 86 | sub_11314(DeviceObject->AttachedDevice, 42i64, &unk_16150); 87 | } 88 | *(_DWORD *)(a2 + 48) = 0; 89 | *(_QWORD *)(a2 + 56) = 0i64; 90 | PhysicalAddress = *(PHYSICAL_ADDRESS *)(a2 + 184); 91 | v4 = *(unsigned __int16 **)(a2 + 24); 92 | v5 = *(_DWORD *)(PhysicalAddress.QuadPart + 16); 93 | LODWORD(BaseAddress) = *(_DWORD *)(PhysicalAddress.QuadPart + 8); 94 | sub_110AC(5i64, "inBufLength=%x outBufLength=%x", v5, (unsigned int)BaseAddress); 95 | if ( !v5 ) 96 | { 97 | v3 = -1073741811; 98 | goto LABEL_120; 99 | } 100 | sub_110AC(5i64, "IoControlCode = %x", *(unsigned int *)(PhysicalAddress.QuadPart + 24)); 101 | sub_111C8(*(unsigned int *)(PhysicalAddress.QuadPart + 24)); 102 | v6 = *(unsigned int *)(PhysicalAddress.QuadPart + 24); 103 | if ( (unsigned int)v6 > 0x8000201C ) 104 | { 105 | switch ( (_DWORD)v6 ) 106 | { 107 | case 0x80002024: 108 | sub_110AC(5i64, "!!IOCTL_PHYMEM_GETEEPROM\n"); 109 | sub_110AC(5i64, "IoBase =%x Reg = %x\n", *v4, v4[1]); 110 | v46 = 6; 111 | if ( v5 == 6 && (unsigned int)BaseAddress >= 2 ) 112 | { 113 | *(_QWORD *)(a2 + 56) = 2i64; 114 | v47 = __indword(*v4 + 68); 115 | if ( (v47 & 0x40) != 0 ) 116 | v46 = 7; 117 | v48 = __inbyte(*v4 + 80); 118 | v49 = v48; 119 | v50 = *v4 + 80; 120 | __outbyte(v50, 0x80u); 121 | __outbyte(v50, 0x84u); 122 | __outbyte(v50, 0x80u); 123 | v51 = sub_12040((unsigned int)*v4 + 80, v4[1], v46); 124 | *v4 = v51; 125 | __outbyte(v51 + 80, 0x80u); 126 | __outbyte(v51 + 80, 0x84u); 127 | __outbyte(v51 + 80, 0x80u); 128 | __outbyte(*v4 + 80, v49); 129 | } 130 | else 131 | { 132 | v3 = -1073741811; 133 | } 134 | break; 135 | case 0x80002028: 136 | sub_110AC(5i64, "!!IOCTL_PHYMEM_SETEEEPROM\n"); 137 | sub_110AC(5i64, "IoBase =%x Reg = %x Value = %x\n", *v4, v4[1], v4[2]); 138 | v40 = 6; 139 | if ( v5 == 6 ) 140 | { 141 | *(_QWORD *)(a2 + 56) = 2i64; 142 | v41 = __indword(*v4 + 68); 143 | if ( (v41 & 0x40) != 0 ) 144 | v40 = 7; 145 | v42 = __inbyte(*v4 + 80); 146 | v43 = v42; 147 | v44 = *v4 + 80; 148 | __outbyte(v44, 0x80u); 149 | __outbyte(v44, 0x84u); 150 | __outbyte(v44, 0x80u); 151 | sub_12320((unsigned int)*v4 + 80, v4[1], v4[2], v40); 152 | v45 = *v4 + 80; 153 | __outbyte(v45, 0x80u); 154 | __outbyte(v45, 0x84u); 155 | __outbyte(v45, 0x80u); 156 | __outbyte(v45, v43); 157 | } 158 | else 159 | { 160 | v3 = -1073741811; 161 | } 162 | break; 163 | case 0x8000202C: 164 | sub_110AC(5i64, "!!IOCTL_PHYMEM_GETCHANNEL\n"); 165 | sub_110AC( 166 | 5i64, 167 | "BUS =%x DEV = %x FN = %x PcieBase = %p\n", 168 | *(unsigned __int8 *)v4, 169 | *((unsigned __int8 *)v4 + 1), 170 | *((unsigned __int8 *)v4 + 2), 171 | *((const void **)v4 + 3)); 172 | LODWORD(Irpe) = *((_DWORD *)v4 + 2); 173 | sub_110AC( 174 | 5i64, 175 | "MutexType =%x AddrRegOffset = %x AddrRegValue = %x\n", 176 | *((unsigned __int8 *)v4 + 3), 177 | *((unsigned __int8 *)v4 + 4), 178 | Irpe); 179 | LODWORD(Irpf) = v4[10]; 180 | sub_110AC( 181 | 5i64, 182 | "DataRegOffset =%x DataRegValue = %x WaitTime = %x\n", 183 | *((unsigned __int8 *)v4 + 12), 184 | *((unsigned int *)v4 + 4), 185 | Irpf); 186 | if ( v5 == 40 && (unsigned int)BaseAddress >= 4 ) 187 | { 188 | v37 = v4[10]; 189 | v38 = *((_QWORD *)v4 + 3); 190 | LOBYTE(v38) = *((_BYTE *)v4 + 1); 191 | LOBYTE(v37) = *(_BYTE *)v4; 192 | v39 = sub_1161C( 193 | v37, 194 | v38, 195 | *((unsigned __int8 *)v4 + 2), 196 | v4[16], 197 | *((_QWORD *)v4 + 3), 198 | v4[10], 199 | *((_BYTE *)v4 + 3), 200 | 0, 201 | 0, 202 | *((_DWORD *)v4 + 2), 203 | *((unsigned __int8 *)v4 + 4), 204 | *((unsigned __int8 *)v4 + 12)); 205 | if ( v39 == -1 ) 206 | { 207 | v3 = -1073741823; 208 | } 209 | else 210 | { 211 | *(_DWORD *)v4 = v39; 212 | *(_QWORD *)(a2 + 56) = 4i64; 213 | } 214 | } 215 | else 216 | { 217 | v3 = -1073741811; 218 | } 219 | break; 220 | case 0x80002030: 221 | sub_110AC(5i64, "!!IOCTL_PHYMEM_SETCHANNEL\n"); 222 | sub_110AC( 223 | 5i64, 224 | "BUS =%x DEV = %x FN = %x\n", 225 | *(unsigned __int8 *)v4, 226 | *((unsigned __int8 *)v4 + 1), 227 | *((unsigned __int8 *)v4 + 2)); 228 | LODWORD(Irpc) = *((_DWORD *)v4 + 2); 229 | sub_110AC( 230 | 5i64, 231 | "MutexType =%x AddrRegOffset = %x AddrRegValue = %x\n", 232 | *((unsigned __int8 *)v4 + 3), 233 | *((unsigned __int8 *)v4 + 4), 234 | Irpc); 235 | LODWORD(Irpd) = v4[10]; 236 | sub_110AC( 237 | 5i64, 238 | "DataRegOffset =%x DataRegValue = %x WaitTime = %x\n", 239 | *((unsigned __int8 *)v4 + 12), 240 | *((unsigned int *)v4 + 4), 241 | Irpd); 242 | if ( v5 == 40 ) 243 | { 244 | v35 = *((_DWORD *)v4 + 4); 245 | v36 = v4[10]; 246 | LOBYTE(v35) = *((_BYTE *)v4 + 2); 247 | LOBYTE(v36) = *((_BYTE *)v4 + 1); 248 | LOBYTE(v34) = *(_BYTE *)v4; 249 | v3 = sub_1187C( 250 | v34, 251 | v36, 252 | v35, 253 | v4[16], 254 | *((_QWORD *)v4 + 3), 255 | v4[10], 256 | *((_BYTE *)v4 + 3), 257 | 0, 258 | 0, 259 | *((_DWORD *)v4 + 2), 260 | *((unsigned __int8 *)v4 + 4), 261 | *((_DWORD *)v4 + 4), 262 | *((unsigned __int8 *)v4 + 12)); 263 | } 264 | else 265 | { 266 | v3 = -1073741811; 267 | } 268 | break; 269 | case 0x80002034: 270 | sub_110AC(5i64, "!!IOCTL_PHYMEM_INFORM_FP_FW_S3S4S5\n"); 271 | sub_110AC( 272 | 5i64, 273 | "BUS =%x DEV = %x FN = %x\n", 274 | *(unsigned __int8 *)v4, 275 | *((unsigned __int8 *)v4 + 1), 276 | *((unsigned __int8 *)v4 + 2)); 277 | LODWORD(Irpa) = *((_DWORD *)v4 + 2); 278 | sub_110AC( 279 | 5i64, 280 | "MutexType =%x AddrRegOffset = %x AddrRegValue = %x\n", 281 | *((unsigned __int8 *)v4 + 3), 282 | *((unsigned __int8 *)v4 + 4), 283 | Irpa); 284 | LODWORD(Irpb) = v4[10]; 285 | sub_110AC( 286 | 5i64, 287 | "DataRegOffset =%x DataRegValue = %x WaitTime = %x\n", 288 | *((unsigned __int8 *)v4 + 12), 289 | *((unsigned int *)v4 + 4), 290 | Irpb); 291 | sub_110AC(5i64, "PCIEBASE =%p IOBASE = %x \n", *((const void **)v4 + 3), v4[16]); 292 | byte_17161 = 0; 293 | word_17164 = 0; 294 | Src = 0; 295 | dword_1716C = 0; 296 | if ( v5 == 40 ) 297 | { 298 | memmove(&byte_17180, v4, 0x28ui64); 299 | v32 = sub_11B58(byte_17180, byte_17181, byte_17182, *(__int64 *)&qword_17198, 4u, 1u); 300 | sub_11CE4(byte_17180, byte_17181, byte_17182, *(__int64 *)&qword_17198, 4u, v32 | 7, 1u); 301 | v33 = sub_11B58(byte_17180, byte_17181, byte_17182, *(__int64 *)&qword_17198, 0x44u, 1u); 302 | sub_11CE4(byte_17180, byte_17181, byte_17182, *(__int64 *)&qword_17198, 0x44u, v33 & 0xFC, 1u); 303 | sub_128E8(); 304 | byte_17160 = 1; 305 | } 306 | else 307 | { 308 | v3 = -1073741811; 309 | } 310 | break; 311 | default: 312 | goto LABEL_92; 313 | } 314 | } 315 | else 316 | { 317 | switch ( (_DWORD)v6 ) 318 | { 319 | case 0x8000201C: 320 | sub_110AC(5i64, "IOCTL_ENUM_RTKNIC\n"); 321 | LOWORD(PhysicalAddress.LowPart) = 0; 322 | do 323 | { 324 | LOBYTE(v24) = 0; 325 | v61 = 0; 326 | do 327 | { 328 | v60 = (unsigned __int8)v24; 329 | LOBYTE(v23) = 12; 330 | LOBYTE(LowPart_low) = v3; 331 | v25 = sub_143D6(LowPart_low, (unsigned __int8)v24, 0i64, v23); 332 | if ( v25 == -1 || (v25 & 0x800000) == 0 ) 333 | v63 = 1; 334 | else 335 | v63 = 8; 336 | LOBYTE(v26) = 0; 337 | LOBYTE(BaseAddress) = 0; 338 | while ( 1 ) 339 | { 340 | LOBYTE(v27) = v26; 341 | LOBYTE(v26) = v3; 342 | v28 = sub_143D6(v26, v60, v27, 0i64); 343 | if ( v28 == -2127163156 344 | || v28 == -2127097620 345 | || v28 == -2123951892 346 | || v28 == -2123886356 347 | || v28 == -2123820820 348 | || v28 == -2124017428 349 | || v28 == -2124345108 ) 350 | { 351 | break; 352 | } 353 | LOBYTE(v26) = (_BYTE)BaseAddress + 1; 354 | LOBYTE(BaseAddress) = v26; 355 | if ( (unsigned __int8)v26 >= (unsigned __int16)v63 ) 356 | { 357 | LowPart_low = LOWORD(PhysicalAddress.LowPart); 358 | goto LABEL_82; 359 | } 360 | } 361 | LOBYTE(v23) = 16; 362 | LOBYTE(v27) = (_BYTE)BaseAddress; 363 | LOBYTE(v26) = v3; 364 | v29 = sub_143D6(v26, v60, v27, v23); 365 | sub_110AC(5i64, "Hardware ID: 0x%08X\n", v29); 366 | v30 = LOWORD(PhysicalAddress.LowPart); 367 | *(_DWORD *)&v4[2 * LOWORD(PhysicalAddress.LowPart) + 2] = v29 - 1; 368 | sub_110AC(5i64, "cnt=%d\n", v30); 369 | LOWORD(LowPart_low) = ++LOWORD(PhysicalAddress.LowPart); 370 | LABEL_82: 371 | v24 = v61 + 1; 372 | v61 = v24; 373 | } 374 | while ( v24 < 0x20u ); 375 | LOWORD(v3) = v3 + 1; 376 | } 377 | while ( (unsigned __int16)v3 < 0x100u ); 378 | *(_DWORD *)v4 = (unsigned __int16)LowPart_low; 379 | *(_QWORD *)(a2 + 56) = 4i64 * ((unsigned __int16)LowPart_low + 1); 380 | sub_110AC(5i64, "pSysBuf:"); 381 | v31 = 10i64; 382 | v3 = 0; 383 | do 384 | { 385 | sub_110AC(5i64, (const char *)qword_14DE0, *(unsigned int *)v4); 386 | v4 += 2; 387 | --v31; 388 | } 389 | while ( v31 ); 390 | sub_110AC(5i64, (const char *)qword_14DF0); 391 | break; 392 | case 0x80002000:// map primitive 393 | sub_110AC(5i64, "!!IOCTL_PHYMEM_MAP\n"); 394 | if ( v5 != 16 || (_DWORD)BaseAddress != 8 ) 395 | { 396 | v3 = -1073741811; 397 | break; 398 | } 399 | PhysicalAddress.QuadPart = 0i64; 400 | BaseAddress = 0i64; 401 | v18 = 0i64; 402 | v16 = 0i64; 403 | memmove(&PhysicalAddress, v4, 8ui64); 404 | v19 = MmMapIoSpace(PhysicalAddress, *((unsigned int *)v4 + 2), MmNonCached); 405 | v62 = v19; 406 | if ( v19 ) 407 | { 408 | Mdl = IoAllocateMdl(v19, *((_DWORD *)v4 + 2), 0, 0, 0i64); 409 | v18 = Mdl; 410 | if ( Mdl ) 411 | { 412 | MmBuildMdlForNonPagedPool(Mdl); 413 | BaseAddress = MmMapLockedPagesSpecifyCache(v18, 1, MmNonCached, 0i64, 0, 0x10u); 414 | if ( BaseAddress ) 415 | { 416 | PoolWithTag = (unsigned int *)ExAllocatePoolWithTag(NonPagedPool, 0x28ui64, 0x6F697452u); 417 | v16 = PoolWithTag; 418 | if ( PoolWithTag ) 419 | { 420 | *((_QWORD *)PoolWithTag + 1) = v18; 421 | *((_QWORD *)PoolWithTag + 2) = v62; 422 | *((_QWORD *)PoolWithTag + 3) = BaseAddress; 423 | PoolWithTag[8] = *((_DWORD *)v4 + 2); 424 | *(_QWORD *)PoolWithTag = P; 425 | P = PoolWithTag; 426 | LODWORD(Irp) = *((_DWORD *)v4 + 2); 427 | sub_110AC(5i64, "Map physical 0x%p to virtual 0x%p, size %u", *(const void **)v4, BaseAddress, Irp); 428 | memmove(v4, &BaseAddress, 8ui64); 429 | *(_QWORD *)(a2 + 56) = 8i64; 430 | } 431 | else 432 | { 433 | sub_110AC(5i64, "Call to ExAllocatePoolWithTag MAPINFO failed\n"); 434 | v3 = -1073741670; 435 | } 436 | } 437 | else 438 | { 439 | sub_110AC(5i64, "Call to MmMapLockedPagesSpecifyCache MAPINFO failed\n"); 440 | v3 = -1073741670; 441 | } 442 | } 443 | else 444 | { 445 | v3 = -1073741670; 446 | } 447 | } 448 | else 449 | { 450 | v3 = -1073741670; 451 | } 452 | if ( v3 ) 453 | { 454 | if ( BaseAddress ) 455 | MmUnmapLockedPages(BaseAddress, v18); 456 | if ( v18 ) 457 | IoFreeMdl(v18); 458 | if ( v62 ) 459 | MmUnmapIoSpace(v62, *((unsigned int *)v4 + 2)); 460 | if ( v16 ) 461 | goto LABEL_63; 462 | } 463 | break; 464 | case 0x80002004: 465 | sub_110AC(5i64, "!!IOCTL_PHYMEM_UNMAP\n"); 466 | if ( v5 != 16 ) 467 | { 468 | v3 = -1073741811; 469 | break; 470 | } 471 | v16 = (unsigned int *)P; 472 | v17 = P; 473 | if ( P ) 474 | { 475 | while ( *((_QWORD *)v16 + 3) != *(_QWORD *)v4 ) 476 | { 477 | v17 = v16; 478 | v16 = *(unsigned int **)v16; 479 | if ( !v16 ) 480 | goto LABEL_120; 481 | } 482 | if ( v16[8] != *((_DWORD *)v4 + 2) ) 483 | { 484 | v3 = -1073741811; 485 | break; 486 | } 487 | MmUnmapLockedPages(*((PVOID *)v16 + 3), *((PMDL *)v16 + 1)); 488 | IoFreeMdl(*((PMDL *)v16 + 1)); 489 | MmUnmapIoSpace(*((PVOID *)v16 + 2), v16[8]); 490 | if ( v16 == P ) 491 | P = *(PVOID *)v16; 492 | else 493 | *v17 = *(_QWORD *)v16; 494 | LABEL_63: 495 | ExFreePoolWithTag(v16, 0); 496 | } 497 | break; 498 | case 0x80002008:// in primitive 499 | sub_110AC(5i64, "!!IOCTL_PHYMEM_GETPORT\n"); 500 | sub_110AC(5i64, "pPort->dwPort=%x\n", *(unsigned int *)v4); 501 | if ( v5 == 12 ) 502 | { 503 | *(_QWORD *)(a2 + 56) = 4i64; 504 | switch ( *((_DWORD *)v4 + 1) ) 505 | { 506 | case 1: 507 | v13 = __inbyte(*(_DWORD *)v4); 508 | *(_DWORD *)v4 = v13; 509 | break; 510 | case 2: 511 | v14 = __inword(*(_DWORD *)v4); 512 | *(_DWORD *)v4 = v14; 513 | break; 514 | case 4: 515 | v15 = __indword(*(_DWORD *)v4); 516 | *(_DWORD *)v4 = v15; 517 | break; 518 | default: 519 | v3 = -1073741811; 520 | break; 521 | } 522 | } 523 | else 524 | { 525 | v3 = -1073741811; 526 | } 527 | break; 528 | case 0x8000200C://out primitive 529 | sub_110AC(5i64, "!!IOCTL_PHYMEM_SETPORT"); 530 | if ( v5 == 12 ) 531 | { 532 | *(_QWORD *)(a2 + 56) = 4i64; 533 | switch ( *((_DWORD *)v4 + 1) ) 534 | { 535 | case 1: 536 | __outbyte(*(_DWORD *)v4, *((_BYTE *)v4 + 8)); 537 | break; 538 | case 2: 539 | __outword(*(_DWORD *)v4, v4[4]); 540 | break; 541 | case 4: 542 | __outdword(*(_DWORD *)v4, *((_DWORD *)v4 + 2)); 543 | break; 544 | default: 545 | v3 = -1073741811; 546 | break; 547 | } 548 | } 549 | else 550 | { 551 | v3 = -1073741811; 552 | } 553 | break; 554 | case 0x80002018: 555 | *(_QWORD *)(a2 + 56) = 8i64; 556 | sub_110AC(5i64, "!!IOCTL_PHYMEM_SENDSMI"); 557 | v7 = *v4; 558 | v8 = *((_BYTE *)v4 + 2); 559 | v9 = v4[2]; 560 | sub_110AC(5i64, "!!!!!!SmiPort=0x%x SmiCommand=0x%x SmiSubCommand=0x%x!!\n", *v4, v8, v9); 561 | ActiveProcessors = KeQueryActiveProcessors(); 562 | sub_110AC(5i64, "KeActiveProcessors=0x%zx", ActiveProcessors); 563 | KeSetSystemAffinityThread(1ui64); 564 | LOBYTE(v11) = v8; 565 | v12 = (unsigned __int16)sub_143A0(v7, v11, v9); 566 | KeSetSystemAffinityThread(1ui64); 567 | sub_110AC(5i64, "SmiResult=%d\n", (unsigned int)v12); 568 | *(_QWORD *)v4 = v12; 569 | break; 570 | default: 571 | LABEL_92: 572 | if ( DeviceObject != (PDEVICE_OBJECT)&DeviceObject 573 | && (BYTE4(DeviceObject->Timer) & 1) != 0 574 | && BYTE1(DeviceObject->Timer) >= 4u ) 575 | { 576 | sub_11008(DeviceObject->AttachedDevice, 43i64, &unk_16150, v6); 577 | } 578 | v3 = -1073741808; 579 | break; 580 | } 581 | } 582 | LABEL_120: 583 | *(_DWORD *)(a2 + 48) = v3; 584 | IofCompleteRequest((PIRP)a2, 0); 585 | if ( DeviceObject != (PDEVICE_OBJECT)&DeviceObject 586 | && (BYTE4(DeviceObject->Timer) & 1) != 0 587 | && BYTE1(DeviceObject->Timer) >= 4u ) 588 | { 589 | sub_11008(DeviceObject->AttachedDevice, 44i64, &unk_16150, v3); 590 | } 591 | return v3; 592 | } 593 | ~~~ 594 | 595 | ### IOCTL 0x80002000 596 | 597 | This IOCTL code triggers memory map operation as blow. 598 | 599 | ~~~c 600 | case 0x80002000:// map primitive 601 | sub_110AC(5i64, "!!IOCTL_PHYMEM_MAP\n"); 602 | if ( v5 != 16 || (_DWORD)BaseAddress != 8 ) 603 | { 604 | v3 = -1073741811; 605 | break; 606 | } 607 | PhysicalAddress.QuadPart = 0i64; 608 | BaseAddress = 0i64; 609 | v18 = 0i64; 610 | v16 = 0i64; 611 | memmove(&PhysicalAddress, v4, 8ui64); 612 | v19 = MmMapIoSpace(PhysicalAddress, *((unsigned int *)v4 + 2), MmNonCached); 613 | v62 = v19; 614 | if ( v19 ) 615 | { 616 | Mdl = IoAllocateMdl(v19, *((_DWORD *)v4 + 2), 0, 0, 0i64); 617 | v18 = Mdl; 618 | if ( Mdl ) 619 | { 620 | MmBuildMdlForNonPagedPool(Mdl); 621 | BaseAddress = MmMapLockedPagesSpecifyCache(v18, 1, MmNonCached, 0i64, 0, 0x10u); 622 | if ( BaseAddress ) 623 | { 624 | PoolWithTag = (unsigned int *)ExAllocatePoolWithTag(NonPagedPool, 0x28ui64, 0x6F697452u); 625 | v16 = PoolWithTag; 626 | if ( PoolWithTag ) 627 | { 628 | *((_QWORD *)PoolWithTag + 1) = v18; 629 | *((_QWORD *)PoolWithTag + 2) = v62; 630 | *((_QWORD *)PoolWithTag + 3) = BaseAddress; 631 | PoolWithTag[8] = *((_DWORD *)v4 + 2); 632 | *(_QWORD *)PoolWithTag = P; 633 | P = PoolWithTag; 634 | LODWORD(Irp) = *((_DWORD *)v4 + 2); 635 | sub_110AC(5i64, "Map physical 0x%p to virtual 0x%p, size %u", *(const void **)v4, BaseAddress, Irp); 636 | memmove(v4, &BaseAddress, 8ui64); 637 | *(_QWORD *)(a2 + 56) = 8i64; 638 | } 639 | else 640 | { 641 | sub_110AC(5i64, "Call to ExAllocatePoolWithTag MAPINFO failed\n"); 642 | v3 = -1073741670; 643 | } 644 | } 645 | else 646 | { 647 | sub_110AC(5i64, "Call to MmMapLockedPagesSpecifyCache MAPINFO failed\n"); 648 | v3 = -1073741670; 649 | } 650 | } 651 | else 652 | { 653 | v3 = -1073741670; 654 | } 655 | } 656 | else 657 | { 658 | v3 = -1073741670; 659 | } 660 | if ( v3 ) 661 | { 662 | if ( BaseAddress ) 663 | MmUnmapLockedPages(BaseAddress, v18); 664 | if ( v18 ) 665 | IoFreeMdl(v18); 666 | if ( v62 ) 667 | MmUnmapIoSpace(v62, *((unsigned int *)v4 + 2)); 668 | if ( v16 ) 669 | goto LABEL_63; 670 | } 671 | break; 672 | ~~~ 673 | 674 | 675 | 676 | ### IOCTL 0x8000200C 677 | 678 | This IOCTL code triggers port out operation . 679 | 680 | ```c 681 | case 0x8000200C://out primitive 682 | sub_110AC(5i64, "!!IOCTL_PHYMEM_SETPORT"); 683 | if ( v5 == 12 ) 684 | { 685 | *(_QWORD *)(a2 + 56) = 4i64; 686 | switch ( *((_DWORD *)v4 + 1) ) 687 | { 688 | case 1: 689 | __outbyte(*(_DWORD *)v4, *((_BYTE *)v4 + 8)); 690 | break; 691 | case 2: 692 | __outword(*(_DWORD *)v4, v4[4]); 693 | break; 694 | case 4: 695 | __outdword(*(_DWORD *)v4, *((_DWORD *)v4 + 2)); 696 | break; 697 | default: 698 | v3 = -1073741811; 699 | break; 700 | } 701 | } 702 | else 703 | { 704 | v3 = -1073741811; 705 | } 706 | break; 707 | ``` 708 | 709 | ### IOCTL 0x8000200C 710 | 711 | This IOCTL code triggers port in operation . 712 | 713 | ```c 714 | case 0x80002008:// in primitive 715 | sub_110AC(5i64, "!!IOCTL_PHYMEM_GETPORT\n"); 716 | sub_110AC(5i64, "pPort->dwPort=%x\n", *(unsigned int *)v4); 717 | if ( v5 == 12 ) 718 | { 719 | *(_QWORD *)(a2 + 56) = 4i64; 720 | switch ( *((_DWORD *)v4 + 1) ) 721 | { 722 | case 1: 723 | v13 = __inbyte(*(_DWORD *)v4); 724 | *(_DWORD *)v4 = v13; 725 | break; 726 | case 2: 727 | v14 = __inword(*(_DWORD *)v4); 728 | *(_DWORD *)v4 = v14; 729 | break; 730 | case 4: 731 | v15 = __indword(*(_DWORD *)v4); 732 | *(_DWORD *)v4 = v15; 733 | break; 734 | default: 735 | v3 = -1073741811; 736 | break; 737 | } 738 | } 739 | else 740 | { 741 | v3 = -1073741811; 742 | } 743 | break; 744 | ``` 745 | 746 | -------------------------------------------------------------------------------- /CVE-2024-33224/rtkio64.sys: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DriverHunter/Win-Driver-EXP/21726ae8475c10c893ae35f2b744dee8d7390057/CVE-2024-33224/rtkio64.sys -------------------------------------------------------------------------------- /CVE-2024-33225/README.md: -------------------------------------------------------------------------------- 1 | # Vulnerable Driver RTKVHD64.sys in Realtek Semiconductor Corp Realtek(r) High Definition Audio Function Driver v6.0.9549.1 2 | 3 | --- 4 | 5 | RTKVHD64.sys in Realtek Semiconductor Corp Realtek(r) High Definition Audio Function Driver v6.0.9549.1 exposes functionality that allows low-privileged users to map arbitrary physical memory, read and write i/o port via specially crafted IOCTL requests. This can be exploited for privilege escalation, code execution under high privileges, and information disclosure. These signed drivers can also be used to bypass the Microsoft driver-signing policy to deploy malicious code. 6 | 7 | ## version 8 | 9 | 6.0.9549.1 10 | 11 | ## Vulnerability causes 12 | 13 | RTKVHD64.sys provides the functionality of mapping physical memory, read/write I/O ports, but it does not restrict the privileges of the caller, resulting in low-privileged users being able to call the driver and execute corresponding functions through DeviceIoControl. The driver exposes memory mapping operation by MmMapIoSpace and MmMapLockedPagesSpecifyCache, exposes port io operation by in/out instruction. The ioctler is located at offset 0x59C190 as below. 14 | 15 | ```c 16 | __int64 __fastcall ioctler(PDEVICE_OBJECT pDeviceObject, PIRP pIrp) 17 | { 18 | struct _IO_STACK_LOCATION *CurrentStackLocation; // rsi 19 | _DWORD *v4; // rbp 20 | unsigned int Status; // ebx 21 | PFILE_OBJECT FileObject; // rdx 22 | unsigned int v8; // eax 23 | PFILE_OBJECT v9; // rdx 24 | int v10; // ebx 25 | int v11; // r14d 26 | int v12; // eax 27 | PNAMED_PIPE_CREATE_PARAMETERS Parameters; // rcx 28 | KIRQL CurrentIrql; // si 29 | unsigned int v16; // edi 30 | ULONG InboundQuota; // eax 31 | 32 | CurrentStackLocation = pIrp->Tail.Overlay.CurrentStackLocation; 33 | v4 = (char *)pDeviceObject->DeviceExtension + 512; 34 | Status = -1073741823; 35 | if ( *((_DWORD *)pDeviceObject->DeviceExtension + 172) ) 36 | { 37 | pIrp->IoStatus.Status = -1073741823; 38 | LABEL_24: 39 | pIrp->IoStatus.Information = 0i64; 40 | goto LABEL_27; 41 | } 42 | FileObject = CurrentStackLocation->FileObject; 43 | if ( FileObject && !RtlCompareUnicodeString((PCUNICODE_STRING)&stru_1401D9AC0.Queue, &FileObject->FileName, 1u) ) 44 | { 45 | if ( CurrentStackLocation->Parameters.Read.ByteOffset.LowPart == 2508800 46 | || CurrentStackLocation->Parameters.Read.ByteOffset.LowPart == 2508804 47 | || CurrentStackLocation->Parameters.Read.ByteOffset.LowPart == 2508808 48 | || CurrentStackLocation->Parameters.Read.ByteOffset.LowPart == 2525188 49 | || CurrentStackLocation->Parameters.Read.ByteOffset.LowPart == 2525192 ) 50 | { 51 | v8 = sub_1403FC494(v4 + 46, CurrentStackLocation->Parameters.Read.ByteOffset.LowPart, pIrp); 52 | LABEL_11: 53 | Status = v8; 54 | LABEL_27: 55 | IofCompleteRequest(pIrp, 0); 56 | return Status; 57 | } 58 | LABEL_23: 59 | pIrp->IoStatus.Status = Status; 60 | goto LABEL_24; 61 | } 62 | v9 = CurrentStackLocation->FileObject; 63 | if ( v9 && !RtlCompareUnicodeString((PCUNICODE_STRING)&stru_1401D9AC0.Queue.Wcb.DeviceContext, &v9->FileName, 1u) ) 64 | { 65 | if ( DeviceObject != (PDEVICE_OBJECT)&DeviceObject 66 | && (HIDWORD(DeviceObject->Timer) & 0x20) != 0 67 | && BYTE1(DeviceObject->Timer) >= 4u ) 68 | { 69 | sub_140016898(DeviceObject->AttachedDevice, 59i64, &unk_140167840); 70 | } 71 | if ( CurrentStackLocation->Parameters.Read.ByteOffset.LowPart == 2229312 72 | || CurrentStackLocation->Parameters.Read.ByteOffset.LowPart == 2229316 ) 73 | { 74 | v8 = sub_1403FCCE8(v4 + 46, CurrentStackLocation->Parameters.Read.ByteOffset.LowPart, pIrp); 75 | goto LABEL_11; 76 | } 77 | } 78 | v10 = 0; 79 | v11 = 0; 80 | if ( CurrentStackLocation->Parameters.Read.ByteOffset.LowPart == 3080195 ) 81 | { 82 | if ( CurrentStackLocation->Parameters.Create.Options < 0x18 ) 83 | goto LABEL_33; 84 | Parameters = CurrentStackLocation->Parameters.CreatePipe.Parameters; 85 | if ( *(_QWORD *)&Parameters->NamedPipeType == 0x47292F78A855A48Ci64 86 | && *(_QWORD *)&Parameters->CompletionMode == 0xEF9E6B7468195190ui64 ) 87 | { 88 | if ( ((Parameters->InboundQuota - 1) & 0xFFFFFFFB) == 0 ) 89 | goto LABEL_33; 90 | } 91 | else 92 | { 93 | if ( *(_QWORD *)&Parameters->NamedPipeType != 0x11D06E1B45FFAAA0i64 94 | || *(_QWORD *)&Parameters->CompletionMode != 0x54534544F2BCi64 ) 95 | { 96 | goto LABEL_33; 97 | } 98 | InboundQuota = Parameters->InboundQuota; 99 | if ( InboundQuota != 50 && InboundQuota != 5 ) 100 | { 101 | if ( InboundQuota - 52 <= 2 ) 102 | v11 = 1; 103 | goto LABEL_33; 104 | } 105 | } 106 | v10 = 1; 107 | } 108 | else 109 | { 110 | v12 = sub_1403FC6E0(v4 + 46, pDeviceObject, pIrp); 111 | Status = -1073741811; 112 | if ( v12 == -1073741811 ) 113 | goto LABEL_23; 114 | v10 = 0; 115 | if ( v12 >= 0 ) 116 | { 117 | Status = pIrp->IoStatus.Status; 118 | goto LABEL_27; 119 | } 120 | } 121 | LABEL_33: 122 | CurrentIrql = KeGetCurrentIrql(); 123 | if ( !CurrentIrql && *v4 && !v11 ) 124 | KeWaitForSingleObject((char *)v4 + (v10 != 0 ? 64i64 : 8i64), Executive, 0, 0, 0i64); 125 | v16 = PcDispatchIrp(pDeviceObject, pIrp); 126 | if ( !CurrentIrql && *v4 && !v11 ) 127 | KeReleaseMutex((PRKMUTEX)((char *)v4 + (v10 != 0 ? 64i64 : 8i64)), 0); 128 | return v16; 129 | } 130 | ``` 131 | 132 | -------------------------------------------------------------------------------- /CVE-2024-33225/RTKVHD64.sys: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DriverHunter/Win-Driver-EXP/21726ae8475c10c893ae35f2b744dee8d7390057/CVE-2024-33225/RTKVHD64.sys -------------------------------------------------------------------------------- /CVE-2024-33226/Access64.sys: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DriverHunter/Win-Driver-EXP/21726ae8475c10c893ae35f2b744dee8d7390057/CVE-2024-33226/Access64.sys -------------------------------------------------------------------------------- /CVE-2024-33226/README.md: -------------------------------------------------------------------------------- 1 | # Vulnerable Driver Access64.sys in Wistron Corporation TBT Force Power Control v1.0.0.0 2 | 3 | --- 4 | 5 | Access64.sys in Wistron Corporation TBT Force Power Control v1.0.0.0 exposes functionality that allows low-privileged users to map arbitrary physical memory, read and write i/o port via specially crafted IOCTL requests. This can be exploited for privilege escalation, code execution under high privileges, and information disclosure. These signed drivers can also be used to bypass the Microsoft driver-signing policy to deploy malicious code. 6 | 7 | ## version 8 | 9 | 6.0.9549.1 10 | 11 | ## Vulnerability causes 12 | 13 | Access64.sys provides the functionality of mapping physical memory, read/write I/O ports, but it does not restrict the privileges of the caller, resulting in low-privileged users being able to call the driver and execute corresponding functions through DeviceIoControl. 14 | 15 | ```c 16 | __int64 __fastcall ioctler(__int64 a1, __int64 a2) 17 | { 18 | _DWORD *v2; // rcx 19 | unsigned int v4; // eax 20 | unsigned int v5; // eax 21 | unsigned int v6; // eax 22 | unsigned int v7; // eax 23 | unsigned int v8; // eax 24 | unsigned int v9; // eax 25 | unsigned int v11; // ebx 26 | __int64 v12; // rcx 27 | __int64 v13; // rdx 28 | __int64 v14; // r8 29 | unsigned __int16 *v15; // rcx 30 | unsigned __int16 v16; // dx 31 | unsigned __int32 v17; // eax 32 | unsigned __int16 v18; // ax 33 | unsigned __int8 v19; // al 34 | __int64 v20; // rax 35 | unsigned int v21; // eax 36 | unsigned int v22; // eax 37 | unsigned int v23; // eax 38 | unsigned int v24; // eax 39 | PVOID *v25; // rbx 40 | __int64 v26; // rcx 41 | __int64 v27; // rcx 42 | unsigned __int32 v28; // eax 43 | unsigned int *v29; // rbx 44 | PVOID ContiguousMemory; // rax 45 | unsigned int v31; // eax 46 | unsigned int v32; // eax 47 | unsigned int v33; // eax 48 | unsigned int v34; // eax 49 | unsigned int v35; // eax 50 | __int64 v36; // rbx 51 | unsigned int v37; // eax 52 | unsigned int v38; // eax 53 | unsigned int v39; // eax 54 | unsigned int v40; // eax 55 | 56 | v2 = *(_DWORD **)(a2 + 184); 57 | v4 = v2[6]; 58 | if ( v4 > 0x2220C4 ) 59 | { 60 | if ( v4 > 0x222140 ) 61 | { 62 | v37 = v4 - 2236740; 63 | if ( v37 ) 64 | { 65 | v38 = v37 - 60; 66 | if ( !v38 ) 67 | return (unsigned int)sub_11DB8((PIRP)a2); 68 | v39 = v38 - 4; 69 | if ( !v39 ) 70 | return (unsigned int)sub_11ED4((PIRP)a2); 71 | v40 = v39 - 4; 72 | if ( !v40 ) 73 | return (unsigned int)sub_11F8C((PIRP)a2); 74 | if ( v40 == 4 ) 75 | return (unsigned int)sub_12044((PIRP)a2); 76 | goto LABEL_85; 77 | } 78 | if ( v2[4] == 12 ) 79 | { 80 | __writemsr(**(_DWORD **)(a2 + 24), *(_QWORD *)(*(_QWORD *)(a2 + 24) + 4i64)); 81 | goto LABEL_95; 82 | } 83 | goto LABEL_91; 84 | } 85 | if ( v4 != 2236736 ) 86 | { 87 | v31 = v4 - 2236616; 88 | if ( v31 ) 89 | { 90 | v32 = v31 - 4; 91 | if ( !v32 ) 92 | return (unsigned int)sub_11A58((PIRP)a2);// map primitive 93 | v33 = v32 - 4; 94 | if ( !v33 ) 95 | return (unsigned int)sub_11B50((PIRP)a2); 96 | v34 = v33 - 4; 97 | if ( !v34 ) 98 | return (unsigned int)sub_11C40((PIRP)a2); 99 | v35 = v34 - 44; 100 | if ( !v35 ) 101 | return (unsigned int)sub_11CF4((PIRP)a2); 102 | if ( v35 != 4 ) 103 | goto LABEL_85; 104 | if ( v2[4] == 11 ) 105 | { 106 | v36 = *(_QWORD *)(a2 + 24); 107 | if ( HalSetBusDataByOffset( 108 | PCIConfiguration, 109 | *(unsigned __int8 *)(v36 + 2), 110 | (*(_DWORD *)v36 & 0x700 | (*(_DWORD *)v36 >> 8) & 0xF8u) >> 3, 111 | (PVOID)(v36 + 7), 112 | *(unsigned __int16 *)(v36 + 4), 113 | *(unsigned __int8 *)(v36 + 6)) != *(unsigned __int8 *)(v36 + 6) ) 114 | { 115 | *(_QWORD *)(a2 + 56) = 0i64; 116 | *(_DWORD *)(a2 + 48) = -1073741491; 117 | IofCompleteRequest((PIRP)a2, 0); 118 | } 119 | goto LABEL_95; 120 | } 121 | } 122 | else if ( v2[4] == 16 ) 123 | { 124 | MmFreeContiguousMemory(*(PVOID *)(*(_QWORD *)(a2 + 24) + 8i64)); 125 | goto LABEL_95; 126 | } 127 | goto LABEL_91; 128 | } 129 | if ( v2[4] != 4 && v2[2] != 8 ) 130 | goto LABEL_91; 131 | **(_QWORD **)(a2 + 24) = __readmsr(**(_DWORD **)(a2 + 24)); 132 | goto LABEL_47; 133 | } 134 | if ( v4 == 2236612 ) 135 | { 136 | if ( v2[4] != 12 || v2[2] < 0x10u ) 137 | goto LABEL_91; 138 | v29 = *(unsigned int **)(a2 + 24); 139 | ContiguousMemory = MmAllocateContiguousMemory(*v29, *(PHYSICAL_ADDRESS *)(v29 + 1)); 140 | *((_QWORD *)v29 + 1) = ContiguousMemory; 141 | *(PHYSICAL_ADDRESS *)v29 = MmGetPhysicalAddress(ContiguousMemory); 142 | *(_QWORD *)(a2 + 56) = 16i64; 143 | goto LABEL_96; 144 | } 145 | if ( v4 > 0x222050 ) 146 | { 147 | v21 = v4 - 2236500; 148 | if ( !v21 ) 149 | { 150 | if ( v2[4] != 6 || v2[2] != 4 ) 151 | goto LABEL_91; 152 | v27 = *(_QWORD *)(a2 + 24); 153 | __outdword(0xCF8u, *(_DWORD *)v27 | *(_WORD *)(v27 + 4) & 0xFC); 154 | v28 = __indword(0xCFCu); 155 | *(_DWORD *)v27 = v28; 156 | *(_QWORD *)(a2 + 56) = 4i64; 157 | goto LABEL_96; 158 | } 159 | v22 = v21 - 4; 160 | if ( !v22 ) 161 | { 162 | if ( v2[4] == 11 ) 163 | { 164 | v26 = *(_QWORD *)(a2 + 24); 165 | if ( *(_BYTE *)(v26 + 6) == 4 ) 166 | { 167 | __outdword(0xCF8u, *(_DWORD *)v26 | *(_WORD *)(v26 + 4) & 0xFC); 168 | __outdword(0xCFCu, *(_DWORD *)(v26 + 7)); 169 | goto LABEL_95; 170 | } 171 | } 172 | LABEL_91: 173 | v11 = -1073741811; 174 | goto LABEL_92; 175 | } 176 | v23 = v22 - 4; 177 | if ( !v23 ) 178 | { 179 | if ( v2[4] != 4 ) 180 | goto LABEL_14; 181 | dword_1416C = **(_DWORD **)(a2 + 24); 182 | goto LABEL_95; 183 | } 184 | v24 = v23 - 4; 185 | if ( !v24 ) 186 | return (unsigned int)sub_118C0((PIRP)a2); 187 | if ( v24 != 96 ) 188 | goto LABEL_85; 189 | if ( v2[4] != 8 || v2[2] < 8u ) 190 | goto LABEL_91; 191 | v25 = *(PVOID **)(a2 + 24); 192 | *(PHYSICAL_ADDRESS *)v25 = MmGetPhysicalAddress(*v25); 193 | LABEL_47: 194 | *(_QWORD *)(a2 + 56) = 8i64; 195 | goto LABEL_96; 196 | } 197 | if ( v4 == 2236496 ) 198 | return (unsigned int)sub_117C8((PIRP)a2); 199 | v5 = v4 - 2236416; 200 | if ( !v5 ) 201 | { 202 | if ( v2[2] >= 6u ) 203 | { 204 | v20 = *(_QWORD *)(a2 + 24); 205 | *(_BYTE *)v20 = 2; 206 | *(_BYTE *)(v20 + 1) = 0; 207 | *(_WORD *)(v20 + 2) = 2013; 208 | *(_BYTE *)(v20 + 4) = 4; 209 | *(_BYTE *)(v20 + 5) = 12; 210 | *(_QWORD *)(a2 + 56) = 6i64; 211 | goto LABEL_96; 212 | } 213 | goto LABEL_34; 214 | } 215 | v6 = v5 - 4; 216 | if ( !v6 ) 217 | { 218 | if ( v2[2] >= 4u ) 219 | { 220 | **(_DWORD **)(a2 + 24) = dword_14180; 221 | *(_QWORD *)(a2 + 56) = 4i64; 222 | goto LABEL_96; 223 | } 224 | LABEL_34: 225 | v11 = -1073741789; 226 | goto LABEL_15; 227 | } 228 | v7 = v6 - 60; 229 | if ( !v7 ) 230 | { 231 | v14 = (unsigned int)v2[2]; 232 | if ( v2[4] != 2 ) 233 | goto LABEL_91; 234 | v15 = *(unsigned __int16 **)(a2 + 24); 235 | v16 = *v15; 236 | switch ( (_DWORD)v14 ) // in primitive 237 | { 238 | case 1: 239 | v19 = __inbyte(v16); 240 | *(_BYTE *)v15 = v19; 241 | break; 242 | case 2: 243 | v18 = __inword(v16); 244 | *v15 = v18; 245 | break; 246 | case 4: 247 | v17 = __indword(v16); 248 | *(_DWORD *)v15 = v17; 249 | break; 250 | default: 251 | goto LABEL_21; 252 | } 253 | *(_QWORD *)(a2 + 56) = v14; 254 | LABEL_96: 255 | *(_DWORD *)(a2 + 48) = 0; 256 | IofCompleteRequest((PIRP)a2, 0); 257 | return 0; 258 | } 259 | v8 = v7 - 4; 260 | if ( !v8 ) // out primitive 261 | { 262 | if ( v2[4] == 7 ) 263 | { 264 | v13 = *(_QWORD *)(a2 + 24); 265 | switch ( *(_BYTE *)(v13 + 2) ) 266 | { 267 | case 1: 268 | __outbyte(*(_WORD *)v13, *(_BYTE *)(v13 + 3)); 269 | break; 270 | case 2: 271 | __outword(*(_WORD *)v13, *(_WORD *)(v13 + 3)); 272 | break; 273 | case 4: 274 | __outdword(*(_WORD *)v13, *(_DWORD *)(v13 + 3)); 275 | break; 276 | default: 277 | LABEL_21: 278 | v11 = -1073741788; 279 | LABEL_92: 280 | *(_QWORD *)(a2 + 56) = 0i64; 281 | goto LABEL_93; 282 | } 283 | LABEL_95: 284 | *(_QWORD *)(a2 + 56) = 0i64; 285 | goto LABEL_96; 286 | } 287 | goto LABEL_91; 288 | } 289 | v9 = v8 - 4; 290 | if ( !v9 ) 291 | { 292 | if ( v2[4] != 6 ) 293 | { 294 | LABEL_14: 295 | v11 = -1073741811; 296 | LABEL_15: 297 | *(_QWORD *)(a2 + 56) = 0i64; 298 | LABEL_93: 299 | *(_DWORD *)(a2 + 48) = v11; 300 | IofCompleteRequest((PIRP)a2, 0); 301 | return v11; 302 | } 303 | v12 = *(_QWORD *)(a2 + 24); 304 | dword_14164 = *(_DWORD *)v12; 305 | word_14168 = *(_WORD *)(v12 + 4); 306 | goto LABEL_95; 307 | } 308 | if ( v9 != 4 ) 309 | { 310 | LABEL_85: 311 | v11 = -1073741808; 312 | goto LABEL_92; 313 | } 314 | return (unsigned int)sub_116B8((PIRP)a2); 315 | } 316 | ``` 317 | 318 | ### IOCTL 0x2220CC 319 | 320 | This IOCTL code triggers memory map operation as blow. 321 | 322 | ~~~c 323 | if ( v4 != 0x222140 ) 324 | { 325 | v31 = v4 - 0x2220C8; 326 | if ( v31 ) 327 | { 328 | v32 = v31 - 4; 329 | if ( !v32 ) 330 | return (unsigned int)((__int64 (__fastcall *)(PIRP))sub_11A58)((PIRP)a2);// map primitive 331 | ~~~ 332 | 333 | ### IOCTL 0x222040 334 | 335 | This IOCTL code triggers port in operation as blow. 336 | 337 | ~~~c 338 | if ( !v7 ) 339 | { 340 | v14 = (unsigned int)v2[2]; 341 | if ( v2[4] != 2 ) 342 | goto LABEL_91; 343 | v15 = *(unsigned __int16 **)(a2 + 24); 344 | v16 = *v15; 345 | switch ( (_DWORD)v14 ) // in primitive 346 | { 347 | case 1: 348 | v19 = __inbyte(v16); 349 | *(_BYTE *)v15 = v19; 350 | break; 351 | case 2: 352 | v18 = __inword(v16); 353 | *v15 = v18; 354 | break; 355 | case 4: 356 | v17 = __indword(v16); 357 | *(_DWORD *)v15 = v17; 358 | break; 359 | default: 360 | goto LABEL_21; 361 | } 362 | ~~~ 363 | 364 | ### IOCTL 0x222044 365 | 366 | This IOCTL code triggers port out operation as blow. 367 | 368 | ~~~c 369 | v8 = v7 - 4; 370 | if ( !v8 ) // out primitive 371 | { 372 | if ( v2[4] == 7 ) 373 | { 374 | v13 = *(_QWORD *)(a2 + 24); 375 | switch ( *(_BYTE *)(v13 + 2) ) 376 | { 377 | case 1: 378 | __outbyte(*(_WORD *)v13, *(_BYTE *)(v13 + 3)); 379 | break; 380 | case 2: 381 | __outword(*(_WORD *)v13, *(_WORD *)(v13 + 3)); 382 | break; 383 | case 4: 384 | __outdword(*(_WORD *)v13, *(_DWORD *)(v13 + 3)); 385 | break; 386 | default: 387 | LABEL_21: 388 | v11 = -1073741788; 389 | LABEL_92: 390 | *(_QWORD *)(a2 + 56) = 0i64; 391 | goto LABEL_93; 392 | } 393 | LABEL_95: 394 | *(_QWORD *)(a2 + 56) = 0i64; 395 | goto LABEL_96; 396 | } 397 | goto LABEL_91; 398 | } 399 | ~~~ 400 | 401 | 402 | 403 | 404 | 405 | -------------------------------------------------------------------------------- /CVE-2024-33227/README.md: -------------------------------------------------------------------------------- 1 | # Vulnerable Driver ddcdrv.sys in Nicomsoft WinI2C/DDC v3.7.4.0 2 | 3 | --- 4 | 5 | ddcdrv.sys in Nicomsoft WinI2C/DDC v3.7.4.0 exposes functionality that allows low-privileged users to map arbitrary physical memory, read and write i/o port via specially crafted IOCTL requests. This can be exploited for privilege escalation, code execution under high privileges, and information disclosure. These signed drivers can also be used to bypass the Microsoft driver-signing policy to deploy malicious code. 6 | 7 | ## version 8 | 9 | 3.7.4.0 10 | 11 | ## Vulnerability causes 12 | 13 | ddcdrv.sys provides the functionality of mapping physical memory, read/write I/O ports, but it does not restrict the privileges of the caller, resulting in low-privileged users being able to call the driver and execute corresponding functions through DeviceIoControl. 14 | 15 | ```c 16 | __int64 __fastcall ioctler(__int64 a1, IRP *a2) 17 | { 18 | __int64 v2; // r12 19 | unsigned int v4; // esi 20 | NTSTATUS v5; // ebx 21 | struct _IO_STACK_LOCATION *CurrentStackLocation; // r11 22 | unsigned int Options; // edx 23 | unsigned int LowPart; // eax 24 | unsigned int Length; // r13d 25 | struct _IRP *MasterIrp; // rdi 26 | unsigned int v11; // eax 27 | int v12; // ebp 28 | unsigned int v13; // eax 29 | unsigned int v14; // eax 30 | unsigned int v15; // eax 31 | unsigned int v16; // eax 32 | unsigned int v17; // eax 33 | int v18; // eax 34 | CSHORT v19; // ax 35 | int v20; // eax 36 | unsigned __int8 v21; // al 37 | unsigned __int32 v22; // eax 38 | int v23; // eax 39 | unsigned int v24; // eax 40 | unsigned int v25; // eax 41 | unsigned int v26; // eax 42 | unsigned int v27; // eax 43 | unsigned int v28; // eax 44 | unsigned __int32 v29; // eax 45 | unsigned int v30; // r8d 46 | unsigned __int32 v31; // eax 47 | __int64 v32; // rax 48 | __int64 v33; // rdi 49 | __int64 v34; // rcx 50 | __int64 v35; // rax 51 | LARGE_INTEGER MdlAddress; // rdx 52 | LARGE_INTEGER v37; // rcx 53 | bool v38; // cf 54 | PVOID v39; // r13 55 | _QWORD *v40; // rbp 56 | __int64 v41; // rax 57 | _QWORD *Pool; // rax 58 | int v43; // ecx 59 | int v44; // ecx 60 | int v45; // ecx 61 | void *SectionHandle; // [rsp+50h] [rbp-A8h] BYREF 62 | LARGE_INTEGER BusAddress; // [rsp+58h] [rbp-A0h] BYREF 63 | ULONG_PTR ViewSize; // [rsp+60h] [rbp-98h] BYREF 64 | PVOID Object; // [rsp+68h] [rbp-90h] BYREF 65 | struct _UNICODE_STRING DestinationString; // [rsp+70h] [rbp-88h] BYREF 66 | struct _OBJECT_ATTRIBUTES ObjectAttributes; // [rsp+80h] [rbp-78h] BYREF 67 | ULONG AddressSpace; // [rsp+100h] [rbp+8h] BYREF 68 | LARGE_INTEGER TranslatedAddress; // [rsp+108h] [rbp+10h] BYREF 69 | PVOID BaseAddress; // [rsp+110h] [rbp+18h] BYREF 70 | LARGE_INTEGER v56; // [rsp+118h] [rbp+20h] BYREF 71 | 72 | v2 = *(_QWORD *)(a1 + 64); 73 | v4 = 0; 74 | v5 = 0; 75 | KeWaitForSingleObject((PVOID)(v2 + 192), Executive, 0, 0, 0i64); 76 | CurrentStackLocation = a2->Tail.Overlay.CurrentStackLocation; 77 | Options = CurrentStackLocation->Parameters.Create.Options; 78 | LowPart = CurrentStackLocation->Parameters.Read.ByteOffset.LowPart; 79 | Length = CurrentStackLocation->Parameters.Read.Length; 80 | if ( Options || LowPart == 2236424 || LowPart == 2236432 || LowPart == 2236436 ) 81 | { 82 | MasterIrp = a2->AssociatedIrp.MasterIrp; 83 | if ( LowPart > 0x222020 ) 84 | { 85 | v24 = LowPart - 0x222024; 86 | if ( !v24 ) 87 | { 88 | v45 = *(_DWORD *)(&MasterIrp->Size + 1); 89 | if ( *(_DWORD *)&MasterIrp->Type < 0xFFu ) 90 | { 91 | AddressSpace = 1; 92 | if ( !HalTranslateBusAddress( 93 | PCIBus, 94 | *(_DWORD *)&MasterIrp->Type, 95 | (PHYSICAL_ADDRESS)*(unsigned int *)(&MasterIrp->Size + 1), 96 | &AddressSpace, 97 | &TranslatedAddress) ) 98 | goto LABEL_36; 99 | LOWORD(v45) = TranslatedAddress.LowPart; 100 | } 101 | __outbyte(v45, (unsigned __int8)MasterIrp->MdlAddress);// out byte primitive IOCTL CODE 0x222024 102 | goto LABEL_91; 103 | } 104 | v25 = v24 - 4; 105 | if ( !v25 ) 106 | { 107 | v44 = *(_DWORD *)(&MasterIrp->Size + 1); 108 | if ( *(_DWORD *)&MasterIrp->Type < 0xFFu ) 109 | { 110 | AddressSpace = 1; 111 | if ( !HalTranslateBusAddress( 112 | PCIBus, 113 | *(_DWORD *)&MasterIrp->Type, 114 | (PHYSICAL_ADDRESS)*(unsigned int *)(&MasterIrp->Size + 1), 115 | &AddressSpace, 116 | &TranslatedAddress) ) 117 | goto LABEL_36; 118 | LOWORD(v44) = TranslatedAddress.LowPart; 119 | } 120 | __outword(v44, (unsigned __int16)MasterIrp->MdlAddress);// out word primitive IOCTL CODE 0x222028 121 | goto LABEL_91; 122 | } 123 | v26 = v25 - 4; 124 | if ( !v26 ) 125 | { 126 | v43 = *(_DWORD *)(&MasterIrp->Size + 1); 127 | if ( *(_DWORD *)&MasterIrp->Type < 0xFFu ) 128 | { 129 | AddressSpace = 1; 130 | if ( !HalTranslateBusAddress( 131 | PCIBus, 132 | *(_DWORD *)&MasterIrp->Type, 133 | (PHYSICAL_ADDRESS)*(unsigned int *)(&MasterIrp->Size + 1), 134 | &AddressSpace, 135 | &TranslatedAddress) ) 136 | goto LABEL_36; 137 | LOWORD(v43) = TranslatedAddress.LowPart; 138 | } 139 | __outdword(v43, (unsigned int)MasterIrp->MdlAddress);// out word primitive IOCTL CODE 0x22202c 140 | goto LABEL_91; 141 | } 142 | v27 = v26 - 4; 143 | if ( v27 ) 144 | { 145 | v28 = v27 - 4; 146 | if ( !v28 ) 147 | { 148 | v32 = *(_QWORD *)&MasterIrp->Type; 149 | v33 = *(_QWORD *)(v2 + 176); 150 | v34 = 0i64; 151 | while ( v33 ) 152 | { 153 | if ( *(_QWORD *)v33 == v32 ) 154 | { 155 | v35 = *(_QWORD *)(v33 + 16); 156 | if ( v34 ) 157 | *(_QWORD *)(v34 + 16) = v35; 158 | else 159 | *(_QWORD *)(v2 + 176) = v35; 160 | ZwUnmapViewOfSection(*(HANDLE *)(v33 + 8), *(PVOID *)v33); 161 | ZwClose(*(HANDLE *)(v33 + 8)); 162 | ExFreePoolWithTag((PVOID)v33, 0); 163 | --*(_DWORD *)(v2 + 184); 164 | goto LABEL_91; 165 | } 166 | v34 = v33; 167 | v33 = *(_QWORD *)(v33 + 16); 168 | } 169 | goto LABEL_91; 170 | } 171 | if ( v28 == 4 ) 172 | { 173 | if ( Length >= 4 && Options >= 4 ) 174 | { 175 | __outdword(0xCF8u, *(_DWORD *)&MasterIrp->Type); 176 | v29 = __indword(0xCFCu); 177 | v30 = v29; 178 | __outdword(0xCF8u, *(_DWORD *)&MasterIrp->Type); 179 | __outdword(0xCFCu, 0xFFFFFFFF); 180 | __outdword(0xCF8u, *(_DWORD *)&MasterIrp->Type); 181 | v31 = __indword(0xCFCu); 182 | __outdword(0xCF8u, *(_DWORD *)&MasterIrp->Type); 183 | __outdword(0xCFCu, v30); 184 | v4 = 4; 185 | *(_DWORD *)&MasterIrp->Type = v31; 186 | goto LABEL_91; 187 | } 188 | goto LABEL_36; 189 | } 190 | goto LABEL_48; 191 | } 192 | if ( Length >= 4 ) // map primitive IOCTL CODE 0x222030 193 | { 194 | MdlAddress = (LARGE_INTEGER)MasterIrp->MdlAddress; 195 | v37.QuadPart = MdlAddress.QuadPart + MasterIrp->Flags; 196 | v38 = *(_DWORD *)&MasterIrp->Type < 0xFFu; 197 | v56 = MdlAddress; 198 | BusAddress = v37; 199 | if ( v38 ) 200 | { 201 | AddressSpace = 0; 202 | if ( !HalTranslateBusAddress(PCIBus, *(_DWORD *)&MasterIrp->Type, MdlAddress, &AddressSpace, &v56) 203 | || !HalTranslateBusAddress(PCIBus, *(_DWORD *)&MasterIrp->Type, BusAddress, &AddressSpace, &BusAddress) ) 204 | { 205 | goto LABEL_36; 206 | } 207 | MdlAddress.LowPart = v56.LowPart; 208 | v37.LowPart = BusAddress.LowPart; 209 | } 210 | if ( v37.LowPart == MdlAddress.LowPart ) 211 | { 212 | v5 = 0xC0000001; 213 | } 214 | else 215 | { 216 | RtlInitUnicodeString(&DestinationString, L"\\Device\\PhysicalMemory"); 217 | ObjectAttributes.ObjectName = &DestinationString; 218 | ObjectAttributes.Length = 48; 219 | ObjectAttributes.RootDirectory = 0i64; 220 | ObjectAttributes.Attributes = 64; 221 | ObjectAttributes.SecurityDescriptor = 0i64; 222 | ObjectAttributes.SecurityQualityOfService = 0i64; 223 | if ( ZwOpenSection(&SectionHandle, 0xF001Fu, &ObjectAttributes) >= 0 ) 224 | { 225 | Object = 0i64; 226 | ObReferenceObjectByHandle(SectionHandle, 0xF001Fu, 0i64, 0, &Object, 0i64); 227 | BaseAddress = 0i64; 228 | TranslatedAddress = v56; 229 | ViewSize = MasterIrp->Flags; 230 | v5 = ZwMapViewOfSection( 231 | SectionHandle, 232 | (HANDLE)0xFFFFFFFFFFFFFFFFi64, 233 | &BaseAddress, 234 | 0i64, 235 | MasterIrp->Flags, 236 | &TranslatedAddress, 237 | &ViewSize, 238 | ViewShare, 239 | 0, 240 | 0x204u); 241 | if ( v5 >= 0 ) 242 | { 243 | MasterIrp->Flags = ViewSize; 244 | BaseAddress = (char *)BaseAddress + v56.QuadPart - TranslatedAddress.QuadPart; 245 | ZwClose(SectionHandle); 246 | v39 = BaseAddress; 247 | v40 = (_QWORD *)(v2 + 176); 248 | v41 = *(_QWORD *)(v2 + 176); 249 | if ( v41 ) 250 | { 251 | while ( *(_QWORD *)(v41 + 16) ) 252 | v41 = *(_QWORD *)(v41 + 16); 253 | v40 = (_QWORD *)(v41 + 16); 254 | } 255 | Pool = ExAllocatePool(NonPagedPool, 0x18ui64); 256 | if ( Pool ) 257 | { 258 | Pool[1] = -1i64; 259 | Pool[2] = 0i64; 260 | *Pool = v39; 261 | *v40 = Pool; 262 | ++*(_DWORD *)(v2 + 184); 263 | } 264 | v4 = 8; 265 | *(_QWORD *)&MasterIrp->Type = BaseAddress; 266 | } 267 | else 268 | { 269 | ZwClose(SectionHandle); 270 | } 271 | } 272 | else 273 | { 274 | v5 = 0xC0000008; 275 | } 276 | } 277 | goto LABEL_91; 278 | } 279 | LABEL_36: 280 | v5 = -1073741811; 281 | goto LABEL_91; 282 | } 283 | if ( LowPart == 0x222020 ) 284 | { 285 | v12 = 4; 286 | if ( Length < 4 ) 287 | goto LABEL_36; 288 | v23 = *(_DWORD *)(&MasterIrp->Size + 1); 289 | if ( *(_DWORD *)&MasterIrp->Type < 0xFFu ) 290 | { 291 | AddressSpace = 1; 292 | if ( !HalTranslateBusAddress( 293 | PCIBus, 294 | *(_DWORD *)&MasterIrp->Type, 295 | (PHYSICAL_ADDRESS)*(unsigned int *)(&MasterIrp->Size + 1), 296 | &AddressSpace, 297 | &TranslatedAddress) ) 298 | goto LABEL_36; 299 | LOWORD(v23) = TranslatedAddress.LowPart; 300 | } 301 | v22 = __indword(v23); // in dword primitive IOCTL CODE 0X222020 302 | } 303 | else 304 | { 305 | v11 = LowPart - 0x222004; 306 | if ( !v11 ) 307 | { 308 | v12 = 280; 309 | if ( Length < 0x118 || Options < 0x118 ) 310 | goto LABEL_36; 311 | v5 = sub_11534(v2, (__int64)a2->AssociatedIrp.MasterIrp); 312 | LABEL_35: 313 | v4 = v12; 314 | goto LABEL_91; 315 | } 316 | v12 = 4; 317 | v13 = v11 - 4; 318 | if ( v13 ) 319 | { 320 | v14 = v13 - 4; 321 | if ( !v14 ) 322 | { 323 | if ( Options >= 4 ) 324 | { 325 | *(_DWORD *)(v2 + 188) = *(_DWORD *)&MasterIrp->Type; 326 | goto LABEL_91; 327 | } 328 | goto LABEL_36; 329 | } 330 | v15 = v14 - 4; 331 | if ( v15 ) 332 | { 333 | v16 = v15 - 4; 334 | if ( !v16 ) 335 | { 336 | sub_1104C(v2); 337 | goto LABEL_91; 338 | } 339 | v17 = v16 - 4; 340 | if ( v17 ) 341 | { 342 | if ( v17 == 4 ) 343 | { 344 | if ( Length >= 2 ) 345 | { 346 | v18 = *(_DWORD *)(&MasterIrp->Size + 1); 347 | if ( *(_DWORD *)&MasterIrp->Type >= 0xFFu ) 348 | { 349 | LABEL_19: 350 | v19 = __inword(v18); // in word primitive IOCTL CODE 0X22201C 351 | MasterIrp->Type = v19; 352 | v4 = 2; 353 | LABEL_91: 354 | KeReleaseMutex((PRKMUTEX)(v2 + 192), 0); 355 | a2->IoStatus.Information = v4; 356 | goto LABEL_92; 357 | } 358 | AddressSpace = 1; 359 | if ( HalTranslateBusAddress( 360 | PCIBus, 361 | *(_DWORD *)&MasterIrp->Type, 362 | (PHYSICAL_ADDRESS)*(unsigned int *)(&MasterIrp->Size + 1), 363 | &AddressSpace, 364 | &TranslatedAddress) ) 365 | { 366 | LOWORD(v18) = TranslatedAddress.LowPart; 367 | goto LABEL_19; 368 | } 369 | } 370 | goto LABEL_36; 371 | } 372 | LABEL_48: 373 | v5 = -1073741808; 374 | goto LABEL_91; 375 | } 376 | if ( Length ) 377 | { 378 | v20 = *(_DWORD *)(&MasterIrp->Size + 1); 379 | if ( *(_DWORD *)&MasterIrp->Type < 0xFFu ) 380 | { 381 | AddressSpace = 1; 382 | if ( !HalTranslateBusAddress( 383 | PCIBus, 384 | *(_DWORD *)&MasterIrp->Type, 385 | (PHYSICAL_ADDRESS)*(unsigned int *)(&MasterIrp->Size + 1), 386 | &AddressSpace, 387 | &TranslatedAddress) ) 388 | goto LABEL_36; 389 | LOWORD(v20) = TranslatedAddress.LowPart; 390 | } 391 | v21 = __inbyte(v20); // in byte primitive IOCTL CODE 0X222018 392 | LOBYTE(MasterIrp->Type) = v21; 393 | v4 = 1; 394 | goto LABEL_91; 395 | } 396 | goto LABEL_36; 397 | } 398 | sub_110C4(v2); 399 | } 400 | if ( Length < 4 ) 401 | goto LABEL_36; 402 | v22 = *(_DWORD *)(v2 + 168); 403 | } 404 | *(_DWORD *)&MasterIrp->Type = v22; 405 | goto LABEL_35; 406 | } 407 | KeReleaseMutex((PRKMUTEX)(v2 + 192), 0); 408 | v5 = -1073741808; 409 | a2->IoStatus.Information = 0i64; 410 | LABEL_92: 411 | a2->IoStatus.Status = v5; 412 | IofCompleteRequest(a2, 0); 413 | return (unsigned int)v5; 414 | } 415 | ``` 416 | 417 | ### IOCTL 0x222024(out byte), 0x222028(out word), 0x22202c(out dword) 418 | 419 | This IOCTL code triggers port out operation as blow. 420 | 421 | ~~~c 422 | if ( LowPart > 0x222020 ) 423 | { 424 | v24 = LowPart - 0x222024; 425 | if ( !v24 ) 426 | { 427 | v45 = *(_DWORD *)(&MasterIrp->Size + 1); 428 | if ( *(_DWORD *)&MasterIrp->Type < 0xFFu ) 429 | { 430 | AddressSpace = 1; 431 | if ( !HalTranslateBusAddress( 432 | PCIBus, 433 | *(_DWORD *)&MasterIrp->Type, 434 | (PHYSICAL_ADDRESS)*(unsigned int *)(&MasterIrp->Size + 1), 435 | &AddressSpace, 436 | &TranslatedAddress) ) 437 | goto LABEL_36; 438 | LOWORD(v45) = TranslatedAddress.LowPart; 439 | } 440 | __outbyte(v45, (unsigned __int8)MasterIrp->MdlAddress);// out byte primitive IOCTL CODE 0x222024 441 | goto LABEL_91; 442 | } 443 | v25 = v24 - 4; 444 | if ( !v25 ) 445 | { 446 | v44 = *(_DWORD *)(&MasterIrp->Size + 1); 447 | if ( *(_DWORD *)&MasterIrp->Type < 0xFFu ) 448 | { 449 | AddressSpace = 1; 450 | if ( !HalTranslateBusAddress( 451 | PCIBus, 452 | *(_DWORD *)&MasterIrp->Type, 453 | (PHYSICAL_ADDRESS)*(unsigned int *)(&MasterIrp->Size + 1), 454 | &AddressSpace, 455 | &TranslatedAddress) ) 456 | goto LABEL_36; 457 | LOWORD(v44) = TranslatedAddress.LowPart; 458 | } 459 | __outword(v44, (unsigned __int16)MasterIrp->MdlAddress);// out word primitive IOCTL CODE 0x222028 460 | goto LABEL_91; 461 | } 462 | v26 = v25 - 4; 463 | if ( !v26 ) 464 | { 465 | v43 = *(_DWORD *)(&MasterIrp->Size + 1); 466 | if ( *(_DWORD *)&MasterIrp->Type < 0xFFu ) 467 | { 468 | AddressSpace = 1; 469 | if ( !HalTranslateBusAddress( 470 | PCIBus, 471 | *(_DWORD *)&MasterIrp->Type, 472 | (PHYSICAL_ADDRESS)*(unsigned int *)(&MasterIrp->Size + 1), 473 | &AddressSpace, 474 | &TranslatedAddress) ) 475 | goto LABEL_36; 476 | LOWORD(v43) = TranslatedAddress.LowPart; 477 | } 478 | __outdword(v43, (unsigned int)MasterIrp->MdlAddress);// out word primitive IOCTL CODE 0x22202c 479 | goto LABEL_91; 480 | } 481 | ~~~ 482 | 483 | ### IOCTL 0x222030 484 | 485 | This IOCTL code triggers memory mapping operation as blow. 486 | 487 | ~~~c 488 | if ( Length >= 4 ) // map primitive IOCTL CODE 0x222030 489 | { 490 | MdlAddress = (LARGE_INTEGER)MasterIrp->MdlAddress; 491 | v37.QuadPart = MdlAddress.QuadPart + MasterIrp->Flags; 492 | v38 = *(_DWORD *)&MasterIrp->Type < 0xFFu; 493 | v56 = MdlAddress; 494 | BusAddress = v37; 495 | if ( v38 ) 496 | { 497 | AddressSpace = 0; 498 | if ( !HalTranslateBusAddress(PCIBus, *(_DWORD *)&MasterIrp->Type, MdlAddress, &AddressSpace, &v56) 499 | || !HalTranslateBusAddress(PCIBus, *(_DWORD *)&MasterIrp->Type, BusAddress, &AddressSpace, &BusAddress) ) 500 | { 501 | goto LABEL_36; 502 | } 503 | MdlAddress.LowPart = v56.LowPart; 504 | v37.LowPart = BusAddress.LowPart; 505 | } 506 | if ( v37.LowPart == MdlAddress.LowPart ) 507 | { 508 | v5 = 0xC0000001; 509 | } 510 | else 511 | { 512 | RtlInitUnicodeString(&DestinationString, L"\\Device\\PhysicalMemory"); 513 | ObjectAttributes.ObjectName = &DestinationString; 514 | ObjectAttributes.Length = 48; 515 | ObjectAttributes.RootDirectory = 0i64; 516 | ObjectAttributes.Attributes = 64; 517 | ObjectAttributes.SecurityDescriptor = 0i64; 518 | ObjectAttributes.SecurityQualityOfService = 0i64; 519 | if ( ZwOpenSection(&SectionHandle, 0xF001Fu, &ObjectAttributes) >= 0 ) 520 | { 521 | Object = 0i64; 522 | ObReferenceObjectByHandle(SectionHandle, 0xF001Fu, 0i64, 0, &Object, 0i64); 523 | BaseAddress = 0i64; 524 | TranslatedAddress = v56; 525 | ViewSize = MasterIrp->Flags; 526 | v5 = ZwMapViewOfSection( 527 | SectionHandle, 528 | (HANDLE)0xFFFFFFFFFFFFFFFFi64, 529 | &BaseAddress, 530 | 0i64, 531 | MasterIrp->Flags, 532 | &TranslatedAddress, 533 | &ViewSize, 534 | ViewShare, 535 | 0, 536 | 0x204u); 537 | if ( v5 >= 0 ) 538 | { 539 | MasterIrp->Flags = ViewSize; 540 | BaseAddress = (char *)BaseAddress + v56.QuadPart - TranslatedAddress.QuadPart; 541 | ZwClose(SectionHandle); 542 | v39 = BaseAddress; 543 | v40 = (_QWORD *)(v2 + 176); 544 | v41 = *(_QWORD *)(v2 + 176); 545 | if ( v41 ) 546 | { 547 | while ( *(_QWORD *)(v41 + 16) ) 548 | v41 = *(_QWORD *)(v41 + 16); 549 | v40 = (_QWORD *)(v41 + 16); 550 | } 551 | Pool = ExAllocatePool(NonPagedPool, 0x18ui64); 552 | if ( Pool ) 553 | { 554 | Pool[1] = -1i64; 555 | Pool[2] = 0i64; 556 | *Pool = v39; 557 | *v40 = Pool; 558 | ++*(_DWORD *)(v2 + 184); 559 | } 560 | v4 = 8; 561 | *(_QWORD *)&MasterIrp->Type = BaseAddress; 562 | } 563 | else 564 | { 565 | ZwClose(SectionHandle); 566 | } 567 | } 568 | else 569 | { 570 | v5 = 0xC0000008; 571 | } 572 | } 573 | goto LABEL_91; 574 | } 575 | ~~~ 576 | 577 | ### IOCTL 0x222018(in byte),0x22201C(in word), 0x222020(in dword) 578 | 579 | This IOCTL code triggers port in operation as blow. 580 | 581 | ~~~c 582 | if ( LowPart == 0x222020 ) 583 | { 584 | v12 = 4; 585 | if ( Length < 4 ) 586 | goto LABEL_36; 587 | v23 = *(_DWORD *)(&MasterIrp->Size + 1); 588 | if ( *(_DWORD *)&MasterIrp->Type < 0xFFu ) 589 | { 590 | AddressSpace = 1; 591 | if ( !HalTranslateBusAddress( 592 | PCIBus, 593 | *(_DWORD *)&MasterIrp->Type, 594 | (PHYSICAL_ADDRESS)*(unsigned int *)(&MasterIrp->Size + 1), 595 | &AddressSpace, 596 | &TranslatedAddress) ) 597 | goto LABEL_36; 598 | LOWORD(v23) = TranslatedAddress.LowPart; 599 | } 600 | v22 = __indword(v23); // in dword primitive IOCTL CODE 0X222020 601 | } 602 | else 603 | { 604 | v11 = LowPart - 0x222004; 605 | if ( !v11 ) 606 | { 607 | v12 = 280; 608 | if ( Length < 0x118 || Options < 0x118 ) 609 | goto LABEL_36; 610 | v5 = sub_11534(v2, (__int64)a2->AssociatedIrp.MasterIrp); 611 | LABEL_35: 612 | v4 = v12; 613 | goto LABEL_91; 614 | } 615 | v12 = 4; 616 | v13 = v11 - 4; 617 | if ( v13 ) 618 | { 619 | v14 = v13 - 4; 620 | if ( !v14 ) 621 | { 622 | if ( Options >= 4 ) 623 | { 624 | *(_DWORD *)(v2 + 188) = *(_DWORD *)&MasterIrp->Type; 625 | goto LABEL_91; 626 | } 627 | goto LABEL_36; 628 | } 629 | v15 = v14 - 4; 630 | if ( v15 ) 631 | { 632 | v16 = v15 - 4; 633 | if ( !v16 ) 634 | { 635 | sub_1104C(v2); 636 | goto LABEL_91; 637 | } 638 | v17 = v16 - 4; 639 | if ( v17 ) 640 | { 641 | if ( v17 == 4 ) 642 | { 643 | if ( Length >= 2 ) 644 | { 645 | v18 = *(_DWORD *)(&MasterIrp->Size + 1); 646 | if ( *(_DWORD *)&MasterIrp->Type >= 0xFFu ) 647 | { 648 | LABEL_19: 649 | v19 = __inword(v18); // in word primitive IOCTL CODE 0X22201C 650 | MasterIrp->Type = v19; 651 | v4 = 2; 652 | LABEL_91: 653 | KeReleaseMutex((PRKMUTEX)(v2 + 192), 0); 654 | a2->IoStatus.Information = v4; 655 | goto LABEL_92; 656 | } 657 | AddressSpace = 1; 658 | if ( HalTranslateBusAddress( 659 | PCIBus, 660 | *(_DWORD *)&MasterIrp->Type, 661 | (PHYSICAL_ADDRESS)*(unsigned int *)(&MasterIrp->Size + 1), 662 | &AddressSpace, 663 | &TranslatedAddress) ) 664 | { 665 | LOWORD(v18) = TranslatedAddress.LowPart; 666 | goto LABEL_19; 667 | } 668 | } 669 | goto LABEL_36; 670 | } 671 | LABEL_48: 672 | v5 = -1073741808; 673 | goto LABEL_91; 674 | } 675 | if ( Length ) 676 | { 677 | v20 = *(_DWORD *)(&MasterIrp->Size + 1); 678 | if ( *(_DWORD *)&MasterIrp->Type < 0xFFu ) 679 | { 680 | AddressSpace = 1; 681 | if ( !HalTranslateBusAddress( 682 | PCIBus, 683 | *(_DWORD *)&MasterIrp->Type, 684 | (PHYSICAL_ADDRESS)*(unsigned int *)(&MasterIrp->Size + 1), 685 | &AddressSpace, 686 | &TranslatedAddress) ) 687 | goto LABEL_36; 688 | LOWORD(v20) = TranslatedAddress.LowPart; 689 | } 690 | v21 = __inbyte(v20); // in byte primitive IOCTL CODE 0X222018 691 | LOBYTE(MasterIrp->Type) = v21; 692 | v4 = 1; 693 | goto LABEL_91; 694 | } 695 | ~~~ 696 | 697 | -------------------------------------------------------------------------------- /CVE-2024-33227/ddcdrv.sys: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DriverHunter/Win-Driver-EXP/21726ae8475c10c893ae35f2b744dee8d7390057/CVE-2024-33227/ddcdrv.sys -------------------------------------------------------------------------------- /CVE-2024-33228/segwindrvx64.sys: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DriverHunter/Win-Driver-EXP/21726ae8475c10c893ae35f2b744dee8d7390057/CVE-2024-33228/segwindrvx64.sys -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Win-Driver-EXP 2 | This repo contains EXPs about Vulnerable Windows Driver 3 | --------------------------------------------------------------------------------