//////////////////////////////////////////////////////////////////// // Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine // All rights reserved // This file was released under the GPLv2 on June 2015. //////////////////////////////////////////////////////////////////// #ifdef NT_NATIVE_MODE #include "regtools.h" #include /*typedef BOOLEAN (*PPsGetVersion) ( PULONG MajorVersion OPTIONAL, PULONG MinorVersion OPTIONAL, PULONG BuildNumber OPTIONAL, PUNICODE_STRING CSDVersion OPTIONAL ); //PPsGetVersion _PsGetVersion = PsGetVersion; /*NTSTATUS KernelGetProcAddress( PWCHAR DllName, PUCHAR ProcName, PVOID* ProcAddr ) { NTSTATUS RC; HANDLE h; UNICODE_STRING uname; ANSI_STRING aname; RtlInitUnicodeString(&uname, DllName); *ProcAddr = NULL; // RC = LdrGetDllHandle(NULL, NULL, &uname, &h); if(!NT_SUCCESS(RC)) return RC; RtlInitAnsiString(&aname, ProcName); // RC = LdrGetProcedureAddress(h, &aname, 0, ProcAddr); return RC; } */ BOOLEAN GetOsVersion( PULONG MajorVersion OPTIONAL, PULONG MinorVersion OPTIONAL, PULONG BuildNumber OPTIONAL, PUNICODE_STRING CSDVersion OPTIONAL ) { WCHAR Str[32]; ULONG mn=0, mj=0, bld=0; // if(_PsGetVersion) // return _PsGetVersion(MajorVersion, MinorVersion, BuildNumber, CSDVersion); RtlZeroMemory(Str, sizeof(Str)); if(RegTGetStringValue(NULL, L"\\Registry\\Machine\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", L"CurrentVersion", &Str[0], sizeof(Str)-sizeof(WCHAR))) { ULONG i=0; WCHAR a; while(a = Str[i]) { if(a == '.') break; if(a < '0' || a > '9') break; mj = mj*16 + (a-'0'); i++; } i++; while(a = Str[i]) { if(a == '.') break; if(a < '0' || a > '9') break; mn = mn*16 + (a-'0'); i++; } } if(RegTGetStringValue(NULL, L"\\Registry\\Machine\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", L"CurrentBuildNumber", &Str[0], sizeof(Str)-sizeof(WCHAR))) { ULONG i=0; WCHAR a; while(a = Str[i]) { if(a < '0' || a > '9') break; bld = bld*10 + (a-'0'); i++; } } if(MajorVersion) *MajorVersion = mj; if(MinorVersion) *MinorVersion = mn; if(BuildNumber) *BuildNumber = bld; return TRUE; } BOOLEAN MyDeviceIoControl( HANDLE h, DWORD dwIoControlCode, PVOID lpInBuffer, DWORD nInBufferSize, PVOID lpOutBuffer, DWORD nOutBufferSize, DWORD* lpBytesReturned, PVOID lpOverlapped ) { NTSTATUS RC; BOOLEAN DevIoCtl = TRUE; IO_STATUS_BLOCK Iosb; if ( dwIoControlCode >> 16 == FILE_DEVICE_FILE_SYSTEM ) { DevIoCtl = FALSE; } else { DevIoCtl = TRUE; } if ( DevIoCtl ) { RC = NtDeviceIoControlFile( h, NULL, NULL, // APC routine NULL, // APC Context &Iosb, dwIoControlCode, // IoControlCode lpInBuffer, // Buffer for data to the FS nInBufferSize, lpOutBuffer, // OutputBuffer for data from the FS nOutBufferSize // OutputBuffer Length ); } else { RC = NtFsControlFile( h, NULL, NULL, // APC routine NULL, // APC Context &Iosb, dwIoControlCode, // IoControlCode lpInBuffer, // Buffer for data to the FS nInBufferSize, lpOutBuffer, // OutputBuffer for data from the FS nOutBufferSize // OutputBuffer Length ); } if ( RC == STATUS_PENDING) { // Operation must complete before return & Iosb destroyed RC = NtWaitForSingleObject( h, FALSE, NULL ); if ( NT_SUCCESS(RC)) { RC = Iosb.Status; } } if ( NT_SUCCESS(RC) ) { *lpBytesReturned = Iosb.Information; return TRUE; } else { // handle warning value STATUS_BUFFER_OVERFLOW somewhat correctly if ( !NT_ERROR(RC) ) { *lpBytesReturned = Iosb.Information; } return FALSE; } } VOID Sleep( ULONG t ) { LARGE_INTEGER delay = {0,0}; delay.QuadPart = -10I64*1000*t; NtDelayExecution(FALSE, &delay); } HANDLE hGlobalHeap = NULL; extern "C" PVOID MyGlobalAlloc( ULONG Size ) { if(!hGlobalHeap) { // Initialize some heap hGlobalHeap = RtlCreateHeap( HEAP_GROWABLE, // Flags NULL, // HeapBase 0, // ReserveSize 0, // CommitSize NULL, // Lock NULL ); // Parameters if(!hGlobalHeap || hGlobalHeap == (HANDLE)(-1)) { hGlobalHeap = NULL; return NULL; } } return RtlAllocateHeap( hGlobalHeap, 0, Size ); } extern "C" VOID MyGlobalFree( PVOID Addr ) { if(!hGlobalHeap) { // BrutePoint(); return; } RtlFreeHeap( hGlobalHeap, 0, Addr ); return; } CHAR dbg_print_tmp_buff[2048]; WCHAR dbg_stringBuffer[2048]; BOOLEAN was_enter = TRUE; extern "C" VOID PrintNtConsole( PCHAR DebugMessage, ... ) { int len; UNICODE_STRING msgBuff; va_list ap; va_start(ap, DebugMessage); if(was_enter) { strcpy(&dbg_print_tmp_buff[0], NT_DBG_PREFIX); len = _vsnprintf(&dbg_print_tmp_buff[sizeof(NT_DBG_PREFIX)-1], 2047-sizeof(NT_DBG_PREFIX), DebugMessage, ap); } else { len = _vsnprintf(&dbg_print_tmp_buff[0], 2047, DebugMessage, ap); } dbg_print_tmp_buff[2047] = 0; if(len > 0 && (dbg_print_tmp_buff[len-1] == '\n' || dbg_print_tmp_buff[len-1] == '\r') ) { was_enter = TRUE; } else { was_enter = FALSE; } len = swprintf( dbg_stringBuffer, L"%S", dbg_print_tmp_buff ); msgBuff.Buffer = dbg_stringBuffer; msgBuff.Length = len * sizeof(WCHAR); msgBuff.MaximumLength = msgBuff.Length + sizeof(WCHAR); NtDisplayString( &msgBuff ); va_end(ap); } // end PrintNtConsole() extern "C" NTSTATUS EnvFileOpenW( PWCHAR Name, HANDLE* ph ) { OBJECT_ATTRIBUTES ObjectAttributes; IO_STATUS_BLOCK IoStatus; NTSTATUS Status; UNICODE_STRING fName; RtlInitUnicodeString(&fName, Name); InitializeObjectAttributes(&ObjectAttributes, &fName, OBJ_CASE_INSENSITIVE, NULL, NULL); Status = NtCreateFile(ph, GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, &ObjectAttributes, &IoStatus, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT | FILE_COMPLETE_IF_OPLOCKED /*| FILE_WRITE_THROUGH*/, NULL, 0); return Status; } // end EnvFileOpenW() extern "C" NTSTATUS EnvFileOpenA( PCHAR Name, HANDLE* ph ) { ULONG len; PWCHAR NameW; NTSTATUS Status; len = strlen(Name); NameW = (PWCHAR)MyAllocatePool__(NonPagedPool, (len+1)*sizeof(WCHAR)); if(!NameW) return STATUS_INSUFFICIENT_RESOURCES; swprintf(NameW, L"%S", Name); Status = EnvFileOpenW(NameW, ph); MyFreePool__(NameW); return Status; } // end EnvFileOpenA() extern "C" NTSTATUS EnvFileClose( HANDLE hFile ) { return NtClose(hFile); } // end EnvFileClose() extern "C" NTSTATUS EnvFileGetSizeByHandle( HANDLE hFile, PLONGLONG lpFileSize ) { NTSTATUS Status; IO_STATUS_BLOCK IoStatusBlock; FILE_STANDARD_INFORMATION StandardInfo; Status = NtQueryInformationFile( hFile, &IoStatusBlock, &StandardInfo, sizeof(StandardInfo), FileStandardInformation ); if (NT_SUCCESS(Status)) { *lpFileSize = StandardInfo.EndOfFile.QuadPart; } return Status; } // end EnvFileGetSizeByHandle() extern "C" NTSTATUS EnvFileGetSizeA( PCHAR Name, PLONGLONG lpFileSize ) { NTSTATUS Status; HANDLE hFile; (*lpFileSize) = -1I64; Status = EnvFileOpenA(Name, &hFile); if(!NT_SUCCESS(Status)) return Status; Status = EnvFileGetSizeByHandle(hFile, lpFileSize); NtClose(hFile); return Status; } // end EnvFileGetSizeA() extern "C" NTSTATUS EnvFileGetSizeW( PWCHAR Name, PLONGLONG lpFileSize ) { NTSTATUS Status; HANDLE hFile; (*lpFileSize) = -1I64; Status = EnvFileOpenW(Name, &hFile); if(!NT_SUCCESS(Status)) return Status; Status = EnvFileGetSizeByHandle(hFile, lpFileSize); NtClose(hFile); return Status; } // end EnvFileGetSizeW() extern "C" BOOLEAN EnvFileExistsA(PCHAR Name) { LONGLONG Size; EnvFileGetSizeA(Name, &Size); return Size != -1; } extern "C" BOOLEAN EnvFileExistsW(PWCHAR Name) { LONGLONG Size; EnvFileGetSizeW(Name, &Size); return Size != -1; } extern "C" NTSTATUS EnvFileWrite( HANDLE h, PVOID ioBuffer, ULONG Length, PULONG bytesWritten ) { IO_STATUS_BLOCK IoStatus; NTSTATUS Status; Status = NtWriteFile( h, NULL, // Event NULL, // ApcRoutine NULL, // ApcContext &IoStatus, ioBuffer, Length, NULL, // ByteOffset NULL // Key ); (*bytesWritten) = IoStatus.Information; return Status; } // end EnvFileWrite() extern "C" NTSTATUS EnvFileRead( HANDLE h, PVOID ioBuffer, ULONG Length, PULONG bytesRead ) { IO_STATUS_BLOCK IoStatus; NTSTATUS Status; Status = NtReadFile( h, NULL, // Event NULL, // ApcRoutine NULL, // ApcContext &IoStatus, ioBuffer, Length, NULL, // ByteOffset NULL // Key ); (*bytesRead) = IoStatus.Information; return Status; } // end EnvFileRead() extern "C" NTSTATUS EnvFileSetPointer( HANDLE hFile, LONGLONG lDistanceToMove, LONGLONG* lResultPointer, DWORD dwMoveMethod ) { NTSTATUS Status; IO_STATUS_BLOCK IoStatus; FILE_POSITION_INFORMATION CurrentPosition; FILE_STANDARD_INFORMATION FileInfo; switch (dwMoveMethod) { case ENV_FILE_BEGIN : CurrentPosition.CurrentByteOffset.QuadPart = lDistanceToMove; break; case ENV_FILE_CURRENT : // Get the current position of the file pointer Status = NtQueryInformationFile( hFile, &IoStatus, &CurrentPosition, sizeof(CurrentPosition), FilePositionInformation ); if(!NT_SUCCESS(Status)) { return Status; } CurrentPosition.CurrentByteOffset.QuadPart += lDistanceToMove; break; case ENV_FILE_END : Status = NtQueryInformationFile( hFile, &IoStatus, &FileInfo, sizeof(FileInfo), FileStandardInformation ); if (!NT_SUCCESS(Status)) { return Status; } CurrentPosition.CurrentByteOffset.QuadPart = FileInfo.EndOfFile.QuadPart + lDistanceToMove; break; default: return STATUS_INVALID_PARAMETER; } if ( CurrentPosition.CurrentByteOffset.QuadPart < 0 ) { return Status; } Status = NtSetInformationFile( hFile, &IoStatus, &CurrentPosition, sizeof(CurrentPosition), FilePositionInformation ); if(!NT_SUCCESS(Status)) { return Status; } if(lResultPointer) { *lResultPointer = CurrentPosition.CurrentByteOffset.QuadPart; } return STATUS_SUCCESS; } // end EnvFileSetPointer() NTSTATUS EnvFileDeleteW(PWCHAR Name) { OBJECT_ATTRIBUTES ObjectAttributes; IO_STATUS_BLOCK IoStatus; NTSTATUS Status; UNICODE_STRING fName; HANDLE Handle; FILE_DISPOSITION_INFORMATION Disposition; RtlInitUnicodeString(&fName, Name); InitializeObjectAttributes(&ObjectAttributes, &fName, OBJ_CASE_INSENSITIVE, NULL, NULL); Status = NtOpenFile( &Handle, (ACCESS_MASK)DELETE, &ObjectAttributes, &IoStatus, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_NON_DIRECTORY_FILE | FILE_OPEN_FOR_BACKUP_INTENT ); if ( !NT_SUCCESS(Status) ) { return Status; } Disposition.DeleteFile = TRUE; Status = NtSetInformationFile( Handle, &IoStatus, &Disposition, sizeof(Disposition), FileDispositionInformation ); NtClose(Handle); return Status; } #endif //NT_NATIVE_MODE