1 //////////////////////////////////////////////////////////////////// 2 // Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine 3 // All rights reserved 4 // This file was released under the GPLv2 on June 2015. 5 //////////////////////////////////////////////////////////////////// 6 7 #ifdef NT_NATIVE_MODE 8 9 #include "regtools.h" 10 #include <stdarg.h> 11 12 /*typedef BOOLEAN (*PPsGetVersion) ( 13 PULONG MajorVersion OPTIONAL, 14 PULONG MinorVersion OPTIONAL, 15 PULONG BuildNumber OPTIONAL, 16 PUNICODE_STRING CSDVersion OPTIONAL 17 ); 18 19 //PPsGetVersion _PsGetVersion = PsGetVersion; 20 21 /*NTSTATUS 22 KernelGetProcAddress( 23 PWCHAR DllName, 24 PUCHAR ProcName, 25 PVOID* ProcAddr 26 ) 27 { 28 NTSTATUS RC; 29 HANDLE h; 30 UNICODE_STRING uname; 31 ANSI_STRING aname; 32 33 RtlInitUnicodeString(&uname, DllName); 34 *ProcAddr = NULL; 35 36 // RC = LdrGetDllHandle(NULL, NULL, &uname, &h); 37 if(!NT_SUCCESS(RC)) 38 return RC; 39 40 RtlInitAnsiString(&aname, ProcName); 41 42 // RC = LdrGetProcedureAddress(h, &aname, 0, ProcAddr); 43 return RC; 44 } */ 45 46 47 BOOLEAN 48 GetOsVersion( 49 PULONG MajorVersion OPTIONAL, 50 PULONG MinorVersion OPTIONAL, 51 PULONG BuildNumber OPTIONAL, 52 PUNICODE_STRING CSDVersion OPTIONAL 53 ) 54 { 55 WCHAR Str[32]; 56 ULONG mn=0, mj=0, bld=0; 57 58 // if(_PsGetVersion) 59 // return _PsGetVersion(MajorVersion, MinorVersion, BuildNumber, CSDVersion); 60 61 RtlZeroMemory(Str, sizeof(Str)); 62 if(RegTGetStringValue(NULL, L"\\Registry\\Machine\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 63 L"CurrentVersion", 64 &Str[0], sizeof(Str)-sizeof(WCHAR))) { 65 ULONG i=0; 66 WCHAR a; 67 while(a = Str[i]) { 68 if(a == '.') 69 break; 70 if(a < '0' || a > '9') 71 break; 72 mj = mj*16 + (a-'0'); 73 i++; 74 } 75 i++; 76 while(a = Str[i]) { 77 if(a == '.') 78 break; 79 if(a < '0' || a > '9') 80 break; 81 mn = mn*16 + (a-'0'); 82 i++; 83 } 84 } 85 86 if(RegTGetStringValue(NULL, L"\\Registry\\Machine\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 87 L"CurrentBuildNumber", 88 &Str[0], sizeof(Str)-sizeof(WCHAR))) { 89 ULONG i=0; 90 WCHAR a; 91 while(a = Str[i]) { 92 if(a < '0' || a > '9') 93 break; 94 bld = bld*10 + (a-'0'); 95 i++; 96 } 97 } 98 if(MajorVersion) 99 *MajorVersion = mj; 100 if(MinorVersion) 101 *MinorVersion = mn; 102 if(BuildNumber) 103 *BuildNumber = bld; 104 return TRUE; 105 } 106 107 BOOLEAN 108 MyDeviceIoControl( 109 HANDLE h, 110 DWORD dwIoControlCode, 111 PVOID lpInBuffer, 112 DWORD nInBufferSize, 113 PVOID lpOutBuffer, 114 DWORD nOutBufferSize, 115 DWORD* lpBytesReturned, 116 PVOID lpOverlapped 117 ) 118 { 119 120 NTSTATUS RC; 121 BOOLEAN DevIoCtl = TRUE; 122 IO_STATUS_BLOCK Iosb; 123 124 if ( dwIoControlCode >> 16 == FILE_DEVICE_FILE_SYSTEM ) { 125 DevIoCtl = FALSE; 126 } else { 127 DevIoCtl = TRUE; 128 } 129 130 if ( DevIoCtl ) { 131 RC = NtDeviceIoControlFile( 132 h, 133 NULL, 134 NULL, // APC routine 135 NULL, // APC Context 136 &Iosb, 137 dwIoControlCode, // IoControlCode 138 lpInBuffer, // Buffer for data to the FS 139 nInBufferSize, 140 lpOutBuffer, // OutputBuffer for data from the FS 141 nOutBufferSize // OutputBuffer Length 142 ); 143 } else { 144 RC = NtFsControlFile( 145 h, 146 NULL, 147 NULL, // APC routine 148 NULL, // APC Context 149 &Iosb, 150 dwIoControlCode, // IoControlCode 151 lpInBuffer, // Buffer for data to the FS 152 nInBufferSize, 153 lpOutBuffer, // OutputBuffer for data from the FS 154 nOutBufferSize // OutputBuffer Length 155 ); 156 } 157 158 if ( RC == STATUS_PENDING) { 159 // Operation must complete before return & Iosb destroyed 160 RC = NtWaitForSingleObject( h, FALSE, NULL ); 161 if ( NT_SUCCESS(RC)) { 162 RC = Iosb.Status; 163 } 164 } 165 166 if ( NT_SUCCESS(RC) ) { 167 *lpBytesReturned = Iosb.Information; 168 return TRUE; 169 } else { 170 // handle warning value STATUS_BUFFER_OVERFLOW somewhat correctly 171 if ( !NT_ERROR(RC) ) { 172 *lpBytesReturned = Iosb.Information; 173 } 174 return FALSE; 175 } 176 } 177 178 VOID 179 Sleep( 180 ULONG t 181 ) 182 { 183 LARGE_INTEGER delay = {0,0}; 184 delay.QuadPart = -10I64*1000*t; 185 NtDelayExecution(FALSE, &delay); 186 } 187 188 HANDLE hGlobalHeap = NULL; 189 190 extern "C" 191 PVOID 192 MyGlobalAlloc( 193 ULONG Size 194 ) 195 { 196 if(!hGlobalHeap) { 197 // Initialize some heap 198 hGlobalHeap = RtlCreateHeap( HEAP_GROWABLE, // Flags 199 NULL, // HeapBase 200 0, // ReserveSize 201 0, // CommitSize 202 NULL, // Lock 203 NULL ); // Parameters 204 if(!hGlobalHeap || hGlobalHeap == (HANDLE)(-1)) { 205 hGlobalHeap = NULL; 206 return NULL; 207 } 208 } 209 return RtlAllocateHeap( hGlobalHeap, 0, Size ); 210 } 211 212 extern "C" 213 VOID 214 MyGlobalFree( 215 PVOID Addr 216 ) 217 { 218 if(!hGlobalHeap) { 219 // BrutePoint(); 220 return; 221 } 222 RtlFreeHeap( hGlobalHeap, 0, Addr ); 223 return; 224 } 225 226 CHAR dbg_print_tmp_buff[2048]; 227 WCHAR dbg_stringBuffer[2048]; 228 229 BOOLEAN was_enter = TRUE; 230 231 extern "C" 232 VOID 233 PrintNtConsole( 234 PCHAR DebugMessage, 235 ... 236 ) 237 { 238 int len; 239 UNICODE_STRING msgBuff; 240 va_list ap; 241 va_start(ap, DebugMessage); 242 243 if(was_enter) { 244 strcpy(&dbg_print_tmp_buff[0], NT_DBG_PREFIX); 245 len = _vsnprintf(&dbg_print_tmp_buff[sizeof(NT_DBG_PREFIX)-1], 2047-sizeof(NT_DBG_PREFIX), DebugMessage, ap); 246 } else { 247 len = _vsnprintf(&dbg_print_tmp_buff[0], 2047, DebugMessage, ap); 248 } 249 dbg_print_tmp_buff[2047] = 0; 250 if(len > 0 && 251 (dbg_print_tmp_buff[len-1] == '\n' || 252 dbg_print_tmp_buff[len-1] == '\r') ) { 253 was_enter = TRUE; 254 } else { 255 was_enter = FALSE; 256 } 257 258 len = swprintf( dbg_stringBuffer, L"%S", dbg_print_tmp_buff ); 259 msgBuff.Buffer = dbg_stringBuffer; 260 msgBuff.Length = len * sizeof(WCHAR); 261 msgBuff.MaximumLength = msgBuff.Length + sizeof(WCHAR); 262 NtDisplayString( &msgBuff ); 263 264 va_end(ap); 265 266 } // end PrintNtConsole() 267 268 extern "C" 269 NTSTATUS 270 EnvFileOpenW( 271 PWCHAR Name, 272 HANDLE* ph 273 ) 274 { 275 OBJECT_ATTRIBUTES ObjectAttributes; 276 IO_STATUS_BLOCK IoStatus; 277 NTSTATUS Status; 278 UNICODE_STRING fName; 279 280 RtlInitUnicodeString(&fName, Name); 281 282 InitializeObjectAttributes(&ObjectAttributes, &fName, OBJ_CASE_INSENSITIVE, NULL, NULL); 283 284 Status = NtCreateFile(ph, 285 GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, 286 &ObjectAttributes, 287 &IoStatus, 288 NULL, 289 FILE_ATTRIBUTE_NORMAL, 290 FILE_SHARE_READ | FILE_SHARE_WRITE, 291 FILE_OPEN, 292 FILE_SYNCHRONOUS_IO_NONALERT | FILE_COMPLETE_IF_OPLOCKED /*| FILE_WRITE_THROUGH*/, 293 NULL, 294 0); 295 296 return Status; 297 } // end EnvFileOpenW() 298 299 extern "C" 300 NTSTATUS 301 EnvFileOpenA( 302 PCHAR Name, 303 HANDLE* ph 304 ) 305 { 306 ULONG len; 307 PWCHAR NameW; 308 NTSTATUS Status; 309 310 len = strlen(Name); 311 312 NameW = (PWCHAR)MyAllocatePool__(NonPagedPool, (len+1)*sizeof(WCHAR)); 313 if(!NameW) 314 return STATUS_INSUFFICIENT_RESOURCES; 315 316 swprintf(NameW, L"%S", Name); 317 318 Status = EnvFileOpenW(NameW, ph); 319 320 MyFreePool__(NameW); 321 322 return Status; 323 } // end EnvFileOpenA() 324 325 extern "C" 326 NTSTATUS 327 EnvFileClose( 328 HANDLE hFile 329 ) 330 { 331 return NtClose(hFile); 332 } // end EnvFileClose() 333 334 extern "C" 335 NTSTATUS 336 EnvFileGetSizeByHandle( 337 HANDLE hFile, 338 PLONGLONG lpFileSize 339 ) 340 { 341 NTSTATUS Status; 342 IO_STATUS_BLOCK IoStatusBlock; 343 FILE_STANDARD_INFORMATION StandardInfo; 344 345 Status = NtQueryInformationFile( 346 hFile, 347 &IoStatusBlock, 348 &StandardInfo, 349 sizeof(StandardInfo), 350 FileStandardInformation 351 ); 352 if (NT_SUCCESS(Status)) { 353 *lpFileSize = StandardInfo.EndOfFile.QuadPart; 354 } 355 return Status; 356 } // end EnvFileGetSizeByHandle() 357 358 extern "C" 359 NTSTATUS 360 EnvFileGetSizeA( 361 PCHAR Name, 362 PLONGLONG lpFileSize 363 ) 364 { 365 NTSTATUS Status; 366 HANDLE hFile; 367 368 (*lpFileSize) = -1I64; 369 370 Status = EnvFileOpenA(Name, &hFile); 371 372 if(!NT_SUCCESS(Status)) 373 return Status; 374 375 Status = EnvFileGetSizeByHandle(hFile, lpFileSize); 376 377 NtClose(hFile); 378 379 return Status; 380 } // end EnvFileGetSizeA() 381 382 extern "C" 383 NTSTATUS 384 EnvFileGetSizeW( 385 PWCHAR Name, 386 PLONGLONG lpFileSize 387 ) 388 { 389 NTSTATUS Status; 390 HANDLE hFile; 391 392 (*lpFileSize) = -1I64; 393 394 Status = EnvFileOpenW(Name, &hFile); 395 396 if(!NT_SUCCESS(Status)) 397 return Status; 398 399 Status = EnvFileGetSizeByHandle(hFile, lpFileSize); 400 401 NtClose(hFile); 402 403 return Status; 404 } // end EnvFileGetSizeW() 405 406 extern "C" 407 BOOLEAN 408 EnvFileExistsA(PCHAR Name) { 409 LONGLONG Size; 410 EnvFileGetSizeA(Name, &Size); 411 return Size != -1; 412 } 413 414 extern "C" 415 BOOLEAN 416 EnvFileExistsW(PWCHAR Name) { 417 LONGLONG Size; 418 EnvFileGetSizeW(Name, &Size); 419 return Size != -1; 420 } 421 422 extern "C" 423 NTSTATUS 424 EnvFileWrite( 425 HANDLE h, 426 PVOID ioBuffer, 427 ULONG Length, 428 PULONG bytesWritten 429 ) 430 { 431 IO_STATUS_BLOCK IoStatus; 432 NTSTATUS Status; 433 434 Status = NtWriteFile( 435 h, 436 NULL, // Event 437 NULL, // ApcRoutine 438 NULL, // ApcContext 439 &IoStatus, 440 ioBuffer, 441 Length, 442 NULL, // ByteOffset 443 NULL // Key 444 ); 445 (*bytesWritten) = IoStatus.Information; 446 447 return Status; 448 } // end EnvFileWrite() 449 450 extern "C" 451 NTSTATUS 452 EnvFileRead( 453 HANDLE h, 454 PVOID ioBuffer, 455 ULONG Length, 456 PULONG bytesRead 457 ) 458 { 459 IO_STATUS_BLOCK IoStatus; 460 NTSTATUS Status; 461 462 Status = NtReadFile( 463 h, 464 NULL, // Event 465 NULL, // ApcRoutine 466 NULL, // ApcContext 467 &IoStatus, 468 ioBuffer, 469 Length, 470 NULL, // ByteOffset 471 NULL // Key 472 ); 473 (*bytesRead) = IoStatus.Information; 474 475 return Status; 476 } // end EnvFileRead() 477 478 extern "C" 479 NTSTATUS 480 EnvFileSetPointer( 481 HANDLE hFile, 482 LONGLONG lDistanceToMove, 483 LONGLONG* lResultPointer, 484 DWORD dwMoveMethod 485 ) 486 { 487 NTSTATUS Status; 488 IO_STATUS_BLOCK IoStatus; 489 FILE_POSITION_INFORMATION CurrentPosition; 490 FILE_STANDARD_INFORMATION FileInfo; 491 492 switch (dwMoveMethod) { 493 case ENV_FILE_BEGIN : 494 CurrentPosition.CurrentByteOffset.QuadPart = lDistanceToMove; 495 break; 496 497 case ENV_FILE_CURRENT : 498 499 // Get the current position of the file pointer 500 Status = NtQueryInformationFile( 501 hFile, 502 &IoStatus, 503 &CurrentPosition, 504 sizeof(CurrentPosition), 505 FilePositionInformation 506 ); 507 if(!NT_SUCCESS(Status)) { 508 return Status; 509 } 510 CurrentPosition.CurrentByteOffset.QuadPart += lDistanceToMove; 511 break; 512 513 case ENV_FILE_END : 514 Status = NtQueryInformationFile( 515 hFile, 516 &IoStatus, 517 &FileInfo, 518 sizeof(FileInfo), 519 FileStandardInformation 520 ); 521 if (!NT_SUCCESS(Status)) { 522 return Status; 523 } 524 CurrentPosition.CurrentByteOffset.QuadPart = 525 FileInfo.EndOfFile.QuadPart + lDistanceToMove; 526 break; 527 528 default: 529 return STATUS_INVALID_PARAMETER; 530 } 531 532 if ( CurrentPosition.CurrentByteOffset.QuadPart < 0 ) { 533 return Status; 534 } 535 536 Status = NtSetInformationFile( 537 hFile, 538 &IoStatus, 539 &CurrentPosition, 540 sizeof(CurrentPosition), 541 FilePositionInformation 542 ); 543 544 if(!NT_SUCCESS(Status)) { 545 return Status; 546 } 547 if(lResultPointer) { 548 *lResultPointer = CurrentPosition.CurrentByteOffset.QuadPart; 549 } 550 return STATUS_SUCCESS; 551 } // end EnvFileSetPointer() 552 553 NTSTATUS EnvFileDeleteW(PWCHAR Name) { 554 555 OBJECT_ATTRIBUTES ObjectAttributes; 556 IO_STATUS_BLOCK IoStatus; 557 NTSTATUS Status; 558 UNICODE_STRING fName; 559 HANDLE Handle; 560 FILE_DISPOSITION_INFORMATION Disposition; 561 562 RtlInitUnicodeString(&fName, Name); 563 564 InitializeObjectAttributes(&ObjectAttributes, &fName, OBJ_CASE_INSENSITIVE, NULL, NULL); 565 566 Status = NtOpenFile( 567 &Handle, 568 (ACCESS_MASK)DELETE, 569 &ObjectAttributes, 570 &IoStatus, 571 FILE_SHARE_DELETE | 572 FILE_SHARE_READ | 573 FILE_SHARE_WRITE, 574 FILE_NON_DIRECTORY_FILE | FILE_OPEN_FOR_BACKUP_INTENT 575 ); 576 577 578 if ( !NT_SUCCESS(Status) ) { 579 return Status; 580 } 581 582 Disposition.DeleteFile = TRUE; 583 584 Status = NtSetInformationFile( 585 Handle, 586 &IoStatus, 587 &Disposition, 588 sizeof(Disposition), 589 FileDispositionInformation 590 ); 591 592 NtClose(Handle); 593 594 return Status; 595 } 596 #endif //NT_NATIVE_MODE 597