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
GetOsVersion(PULONG MajorVersion OPTIONAL,PULONG MinorVersion OPTIONAL,PULONG BuildNumber OPTIONAL,PUNICODE_STRING CSDVersion OPTIONAL)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
MyDeviceIoControl(HANDLE h,DWORD dwIoControlCode,PVOID lpInBuffer,DWORD nInBufferSize,PVOID lpOutBuffer,DWORD nOutBufferSize,DWORD * lpBytesReturned,PVOID lpOverlapped)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
Sleep(ULONG t)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
MyGlobalAlloc(ULONG Size)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
MyGlobalFree(PVOID Addr)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
PrintNtConsole(PCHAR DebugMessage,...)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
EnvFileOpenW(PWCHAR Name,HANDLE * ph)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
EnvFileOpenA(PCHAR Name,HANDLE * ph)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
EnvFileClose(HANDLE hFile)327 EnvFileClose(
328     HANDLE hFile
329     )
330 {
331     return NtClose(hFile);
332 } // end EnvFileClose()
333 
334 extern "C"
335 NTSTATUS
EnvFileGetSizeByHandle(HANDLE hFile,PLONGLONG lpFileSize)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
EnvFileGetSizeA(PCHAR Name,PLONGLONG lpFileSize)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
EnvFileGetSizeW(PWCHAR Name,PLONGLONG lpFileSize)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
EnvFileExistsA(PCHAR Name)408 EnvFileExistsA(PCHAR Name) {
409     LONGLONG Size;
410     EnvFileGetSizeA(Name, &Size);
411     return Size != -1;
412 }
413 
414 extern "C"
415 BOOLEAN
EnvFileExistsW(PWCHAR Name)416 EnvFileExistsW(PWCHAR Name) {
417     LONGLONG Size;
418     EnvFileGetSizeW(Name, &Size);
419     return Size != -1;
420 }
421 
422 extern "C"
423 NTSTATUS
EnvFileWrite(HANDLE h,PVOID ioBuffer,ULONG Length,PULONG bytesWritten)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
EnvFileRead(HANDLE h,PVOID ioBuffer,ULONG Length,PULONG bytesRead)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
EnvFileSetPointer(HANDLE hFile,LONGLONG lDistanceToMove,LONGLONG * lResultPointer,DWORD dwMoveMethod)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 
EnvFileDeleteW(PWCHAR Name)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