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