я попытался вызвать NtCreateFile ассемблере,кроме ошибки ничего вышло, ошибка как здесь https://board.flatassembler.net/topic.php?t=15444 ,переписал на язык Си все получилось
Mikl___, Код (C): #include <windows.h> typedef struct _UNICODE_STRING { USHORT Length; USHORT MaximumLength; PWSTR Buffer; } UNICODE_STRING; typedef UNICODE_STRING *PUNICODE_STRING; typedef struct _OBJECT_ATTRIBUTES { ULONG Length; HANDLE RootDirectory; PUNICODE_STRING ObjectName; ULONG Attributes; PVOID SecurityDescriptor; PVOID SecurityQualityOfService; } OBJECT_ATTRIBUTES; typedef OBJECT_ATTRIBUTES *POBJECT_ATTRIBUTES; typedef struct _IO_STATUS_BLOCK { #pragma warning(push) #pragma warning(disable: 4201) union { NTSTATUS Status; PVOID Pointer; } DUMMYUNIONNAME; #pragma warning(pop) ULONG_PTR Information; } IO_STATUS_BLOCK, *PIO_STATUS_BLOCK; VOID NTAPI RtlInitUnicodeString (PUNICODE_STRING DestinationString,PCWSTR SourceString); __kernel_entry NTSTATUS NTAPI NtCreateFile ( PHANDLE FileHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PIO_STATUS_BLOCK IoStatusBlock, PLARGE_INTEGER AllocationSize, ULONG FileAttributes, ULONG ShareAccess, ULONG CreateDisposition, ULONG CreateOptions, PVOID EaBuffer, ULONG EaLength ); __kernel_entry NTSTATUS NTAPI NtWriteFile ( HANDLE FileHandle, HANDLE Event, PVOID ApcRoutine, PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, PVOID Buffer, ULONG Length, PLARGE_INTEGER ByteOffset, PULONG Key ); __kernel_entry NTSTATUS NTAPI NtClose ( HANDLE FileHandle ); #define FILE_WRITE_DATA ( 0x0002 ) #define FILE_WRITE_ATTRIBUTES ( 0x0100 ) #define FILE_WRITE_EA ( 0x0010 ) #define FILE_APPEND_DATA ( 0x0004 ) #define SYNCHRONIZE (0x00100000L) #define DELETE (0x00010000L) #define READ_CONTROL (0x00020000L) #define WRITE_DAC (0x00040000L) #define WRITE_OWNER (0x00080000L) #define SYNCHRONIZE (0x00100000L) #define STANDARD_RIGHTS_REQUIRED (0x000F0000L) #define STANDARD_RIGHTS_READ (READ_CONTROL) #define STANDARD_RIGHTS_WRITE (READ_CONTROL) #define STANDARD_RIGHTS_EXECUTE (READ_CONTROL) #define STANDARD_RIGHTS_ALL (0x001F0000L) #define SPECIFIC_RIGHTS_ALL (0x0000FFFFL) #define FILE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x1FF) #define FILE_GENERIC_WRITE (STANDARD_RIGHTS_WRITE |\ FILE_WRITE_DATA |\ FILE_WRITE_ATTRIBUTES |\ FILE_WRITE_EA |\ FILE_APPEND_DATA |\ SYNCHRONIZE) #define FILE_DELETE_ON_CLOSE 0x00001000 #define FILE_CREATE 0x00000002 #define FILE_OVERWRITE_IF 0x00000005 #define FILE_RANDOM_ACCESS 0x00000800 #define FILE_NON_DIRECTORY_FILE 0x00000040 #define FILE_SYNCHRONOUS_IO_ALERT 0x00000010 #define FILE_SYNCHRONOUS_IO_NONALERT 0x00000020 #define OBJ_CASE_INSENSITIVE 0x00000040L #define InitializeObjectAttributes( p, n, a, r, s ) { \ (p)->Length = sizeof( OBJECT_ATTRIBUTES ); \ (p)->RootDirectory = r; \ (p)->Attributes = a; \ (p)->ObjectName = n; \ (p)->SecurityDescriptor = s; \ (p)->SecurityQualityOfService = NULL; \ } UNICODE_STRING stroka; HANDLE fhandle; OBJECT_ATTRIBUTES filename; IO_STATUS_BLOCK status_io; int runpoint(void) { InitializeObjectAttributes(&filename, &stroka,OBJ_CASE_INSENSITIVE, NULL, NULL); RtlInitUnicodeString(&stroka,L"\\??\\\\C:\\overrage.bin"); NtCreateFile(&fhandle,FILE_ALL_ACCESS,&filename,&status_io,0,FILE_ATTRIBUTE_NORMAL,0,FILE_OVERWRITE_IF,FILE_RANDOM_ACCESS|FILE_NON_DIRECTORY_FILE|FILE_SYNCHRONOUS_IO_NONALERT|FILE_DELETE_ON_CLOSE,0,0); NtClose(fhandle); return 0; }; --- Сообщение объединено, 24 май 2026 --- Mikl___, я пытался это сделать на x64 ассемблере
Скорей всего проблема в описании структур. К примеру если посмотреть на UNICODE_STRING, то поле Buffer начинается со-смещения 8, хотя на х32 оффсет был 4. Код (Text): 0: kd> dt _unicode_string -v nt!_UNICODE_STRING struct _UNICODE_STRING, 3 elements, 0x10 bytes +0x000 Length : Uint2B +0x002 MaximumLength : Uint2B +0x008 Buffer : Ptr64 to Uint2B 0: kd> То есть между MaxLen и Buffer нужно добавить ещё 1 дворд для выравнивания: Код (ASM): struct UNICODE_STRING Length dw 0 ; 00 MaxLength dw 0 ; 02 Padding dd 0 ; 04 <-------- Buffer dq 0 ; 08 ends
Вот на fasm'e - всё работает: Код (ASM): format pe64 gui 6.0 include 'win64w.inc' entry start section '.data' data readable writeable struct UNICODE_STRING Length dw 0 MaximumLength dw 0 Padding dd 0 ;<----- Buffer dq 0 ends struct OBJECT_ATTRIBUTES Length dq sizeof.OBJECT_ATTRIBUTES RootDirectory dq 0 ObjectName dq 0 Attributes dd 0 Padding dd 0 ;<----- SecurityDesc dq 0,0 ends struct IO_STATUS_BLOCK Status dq 0 Information dq 0 ends align 8 obj_name UNICODE_STRING attr OBJECT_ATTRIBUTES status IO_STATUS_BLOCK FILE_READ_DATA = 1 FILE_WRITE_DATA = 2 FILE_OVERWRITE_IF = 5 fname du '\??\D:\test64.txt',0 ;//<---- укажи свой путь align 8 fdata db 'wasm.in - x64 NtCreateFile() + NtWriteFile() example' dlen = $-fdata align 8 hFile dq 0 ByteOffset dq 0 ;//<---- Должен быть выровнен на 8 байт ;//----------------- section '.code' code readable executable start: sub rsp,8 frame invoke RtlInitUnicodeString, obj_name, fname mov [attr.ObjectName],obj_name invoke NtCreateFile,hFile,\ FILE_READ_DATA + FILE_WRITE_DATA,\ attr, status, 0,0,\ FILE_SHARE_READ + FILE_SHARE_WRITE,\ FILE_OVERWRITE_IF, 0,0,0 invoke NtWriteFile,[hFile],0,0,0,\ status,fdata,dlen,ByteOffset,0 invoke NtClose,[hFile] endf invoke ExitProcess,0 ;//------------------------ section '.idata' import data readable writeable library kernel32,'kernel32.dll',\ user32, 'user32.dll',\ ntdll, 'ntdll.dll' include 'api\kernel32.inc' include 'api\user32.inc' import ntdll,\ RtlInitUnicodeString,'RtlInitUnicodeString',\ NtCreateFile,'NtCreateFile',\ NtWriteFile, 'NtWriteFile',\ NtClose, 'NtClose'
Marylin, и всё же маленкая ошибка в вашем коде есть. Скорее даже не ошибка а мелкий недочёт (мой варнинг). Макрос endf должен по идее после вызова функции ExitProcess стоять. Или я ошибаюсь ?
GRAFik, endf можете поместить после вызова любой апи. просто exit уходит чёрт знает куда, и не возвращается обратно в этот код, поэтому лучше перестраховаться.
Зато код будет на две инструкции короче. Ассемблерщики же порой за каждую лишнюю инструкцию насмерть стоят. А перестраховываться там, по-моему, не от чего - опасности никакой. Код (ASM): call cs:NtClose add rsp, 60h sub rsp, 20h mov rcx, 0 call cs:ExitProcess ;========================= call cs:NtClose mov rcx, 0 call cs:ExitProcess ;=========================
ну конечно - сбил стек sub rsp,60h, и оставил его таким. в общем ставьте endf куда хотите.. хоть в секцию-данных.
Marylin, а почему то в некоторые структуры необязательно добавлять байты для выравнивания(то есть Padding),такие как IO_STATUS_BLOCK,все переменные должны быть по адресу кратному 8 ? Код (ASM): align 8 ; <----- то же должно быть выровнено на 8 байт ? obj_name UNICODE_STRING attr OBJECT_ATTRIBUTES status IO_STATUS_BLOCK FILE_READ_DATA = 1 FILE_WRITE_DATA = 2 FILE_OVERWRITE_IF = 5 fname du '\??\D:\test64.txt',0 align 8 fdata db 'wasm.in - x64 NtCreateFile() + NtWriteFile() example' dlen = $-fdata align 8 hFile dq 0 ByteOffset dq 0
Да, выравнивание критически важно в режиме х64. Переменные должны быть выровнены как мин на 4, хотя желательно ставить всегда 8, чтобы потом не вылавливать в отладчике блох. В структурах только указатели на память должны быть выровнены на границу 8-байт, при этом сами структуры тоже требуют выравнивания в памяти. Но учитывая, что размеры всех структур х64 всегда кратны 8 байт, то можно собрать их в последовательный массив, и указать align 8 только первой: Код (Text): align 8 ;<--- Выравнивание на 8 байт всего массива структур (размер каждой из них тоже кратен 8) obj_name UNICODE_STRING attr OBJECT_ATTRIBUTES status IO_STATUS_BLOCK Например WinDbg обозначает указатели как Ptr64 (pointer) - если посмотреть, то все эти линки выровнены. Код (Text): 0: kd> dt _UNICODE_STRING -v struct _UNICODE_STRING, 3 elements, 0x10 bytes ;<--- Размер кратен 8 (как и у остальных) +0x000 Length : Uint2B +0x002 MaximumLength : Uint2B ;<------------ Всего 4 байта, и нужно вставить 1 дворд +0x008 Buffer : Ptr64 ;<------------ Указатель на память 0: kd> dt _OBJECT_ATTRIBUTES -v struct _OBJECT_ATTRIBUTES, 6 elements, 0x30 bytes +0x000 Length : Uint4B <------ Расширить до 8 байт +0x008 RootDirectory : Ptr64 +0x010 ObjectName : Ptr64 to _UNICODE_STRING +0x018 Attributes : Uint4B <------ Расширить до 8 байт +0x020 SecurityDescriptor : Ptr64 +0x028 SecurityQualityOfService : Ptr64 0: kd> dt _IO_STATUS_BLOCK -v struct _IO_STATUS_BLOCK, 3 elements, 0x10 bytes +0x000 Status : Int4B ;<---------------------------------------+ +0x000 Pointer : Ptr64 ;<--- по смещению(0) может лежать или Status, или Pointer +0x008 Information : Uint8B
Кто-нибудь может чуть поподробней расписать - что в этом коде происходит ? Код (C): #include <windows.h> typedef struct _UNICODE_STRING { USHORT Length; USHORT MaximumLength; PWSTR Buffer; } UNICODE_STRING; typedef UNICODE_STRING *PUNICODE_STRING; typedef struct _OBJECT_ATTRIBUTES { ULONG Length; HANDLE RootDirectory; PUNICODE_STRING ObjectName; ULONG Attributes; PVOID SecurityDescriptor; PVOID SecurityQualityOfService; } OBJECT_ATTRIBUTES; typedef OBJECT_ATTRIBUTES *POBJECT_ATTRIBUTES; typedef struct _IO_STATUS_BLOCK { #pragma warning(push) #pragma warning(disable: 4201) union { NTSTATUS Status; PVOID Pointer; } DUMMYUNIONNAME; #pragma warning(pop) ULONG_PTR Information; } IO_STATUS_BLOCK, *PIO_STATUS_BLOCK; VOID NTAPI RtlInitUnicodeString (PUNICODE_STRING DestinationString,PCWSTR SourceString); __kernel_entry NTSTATUS NTAPI NtCreateFile ( PHANDLE FileHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PIO_STATUS_BLOCK IoStatusBlock, PLARGE_INTEGER AllocationSize, ULONG FileAttributes, ULONG ShareAccess, ULONG CreateDisposition, ULONG CreateOptions, PVOID EaBuffer, ULONG EaLength ); __kernel_entry NTSTATUS NTAPI NtWriteFile ( HANDLE FileHandle, HANDLE Event, PVOID ApcRoutine, PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, PVOID Buffer, ULONG Length, PLARGE_INTEGER ByteOffset, PULONG Key ); __kernel_entry NTSTATUS NTAPI NtClose ( HANDLE FileHandle ); #define FILE_WRITE_DATA ( 0x0002 ) #define FILE_WRITE_ATTRIBUTES ( 0x0100 ) #define FILE_WRITE_EA ( 0x0010 ) #define FILE_APPEND_DATA ( 0x0004 ) #define SYNCHRONIZE (0x00100000L) #define DELETE (0x00010000L) #define READ_CONTROL (0x00020000L) #define WRITE_DAC (0x00040000L) #define WRITE_OWNER (0x00080000L) #define SYNCHRONIZE (0x00100000L) #define STANDARD_RIGHTS_REQUIRED (0x000F0000L) #define STANDARD_RIGHTS_READ (READ_CONTROL) #define STANDARD_RIGHTS_WRITE (READ_CONTROL) #define STANDARD_RIGHTS_EXECUTE (READ_CONTROL) #define STANDARD_RIGHTS_ALL (0x001F0000L) #define SPECIFIC_RIGHTS_ALL (0x0000FFFFL) #define FILE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x1FF) #define FILE_GENERIC_WRITE (STANDARD_RIGHTS_WRITE |\ FILE_WRITE_DATA |\ FILE_WRITE_ATTRIBUTES |\ FILE_WRITE_EA |\ FILE_APPEND_DATA |\ SYNCHRONIZE) #define FILE_DELETE_ON_CLOSE 0x00001000 #define FILE_CREATE 0x00000002 #define FILE_OVERWRITE_IF 0x00000005 #define FILE_RANDOM_ACCESS 0x00000800 #define FILE_NON_DIRECTORY_FILE 0x00000040 #define FILE_SYNCHRONOUS_IO_ALERT 0x00000010 #define FILE_SYNCHRONOUS_IO_NONALERT 0x00000020 #define OBJ_CASE_INSENSITIVE 0x00000040L #define InitializeObjectAttributes( p, n, a, r, s ) { \ (p)->Length = sizeof( OBJECT_ATTRIBUTES ); \ (p)->RootDirectory = r; \ (p)->Attributes = a; \ (p)->ObjectName = n; \ (p)->SecurityDescriptor = s; \ (p)->SecurityQualityOfService = NULL; \ } UNICODE_STRING stroka; HANDLE fhandle; OBJECT_ATTRIBUTES filename; IO_STATUS_BLOCK status_io; int runpoint(void) { InitializeObjectAttributes(&filename, &stroka,OBJ_CASE_INSENSITIVE, NULL, NULL); RtlInitUnicodeString(&stroka,L"\\??\\\\C:\\overrage.bin"); NtCreateFile(&fhandle,FILE_ALL_ACCESS,&filename,&status_io,0,FILE_ATTRIBUTE_NORMAL,0,FILE_OVERWRITE_IF,FILE_RANDOM_ACCESS|FILE_NON_DIRECTORY_FILE|FILE_SYNCHRONOUS_IO_NONALERT|FILE_DELETE_ON_CLOSE,0,0); NtClose(fhandle); return 0; };
Не смотря на довольно древний приём, вызов Native-функций до сих пор обходит большинство аверов. Вот например одинаковый по функционалу код, только использует три разных способа: CreateFileA(), _lcreat(), и NtCreateFile(), который и стал чемпионом с всего 4 детектами, против 15. Спойлер: CreateFileA Код (ASM): format pe64 gui 6.0 include 'win64ax.inc' entry start ;//----------------- section '.data' data readable writeable bWriten dq 0 fname db 'C:\test64.txt',0 fdata db 'wasm.in - x64 NtCreateFile() + NtWriteFile() example' dlen = $-fdata ;//----------------- section '.code' code readable executable start: sub rsp,8 frame invoke CreateFile,fname,GENERIC_READ + GENERIC_WRITE,\ FILE_SHARE_READ + FILE_SHARE_WRITE,\ 0,CREATE_ALWAYS,0,0, push rax invoke WriteFile,rax,fdata,dlen,bWriten,0 pop rax invoke CloseHandle,rax endf invoke ExitProcess,0 ;//------------------------ section '.idata' import data readable writeable library kernel32,'kernel32.dll' include 'api\kernel32.inc' Спойлер: _lcreat Код (ASM): format pe64 gui 6.0 include 'win64ax.inc' entry start ;//----------------- section '.data' data readable writeable fname db 'C:\test64.txt',0 fdata db 'wasm.in - x64 NtCreateFile() + NtWriteFile() example' dlen = $-fdata ;//----------------- section '.code' code readable executable start: sub rsp,8 frame invoke _lcreat,fname,0 push rax invoke _lwrite,eax,fdata,dlen pop rax invoke _lclose,rax endf invoke ExitProcess,0 ;//------------------------ section '.idata' import data readable writeable library kernel32,'kernel32.dll' include 'api\kernel32.inc' Спойлер: NtCreateFile Код (ASM): format pe64 gui 6.0 include 'win64w.inc' entry start ;//----------------- section '.data' data readable writeable struct UNICODE_STRING Length dw 0 MaximumLength dw 0 Padding dd 0 ;<----- Buffer dq 0 ends struct OBJECT_ATTRIBUTES Length dq sizeof.OBJECT_ATTRIBUTES RootDirectory dq 0 ObjectName dq 0 Attributes dd 0 Padding dd 0 ;<----- SecurityDesc dq 0,0 ends struct IO_STATUS_BLOCK Status dq 0 Information dq 0 ends align 8 hFile dq 0 ByteOffset dq 0 obj_name UNICODE_STRING attr OBJECT_ATTRIBUTES status IO_STATUS_BLOCK FILE_READ_DATA = 1 FILE_WRITE_DATA = 2 FILE_OVERWRITE_IF = 5 fname du '\??\C:\test64.txt',0 align 8 fdata db 'wasm.in - x64 NtCreateFile() + NtWriteFile() example' dlen = $-fdata ;//----------------- section '.code' code readable executable start: sub rsp,8 frame invoke RtlInitUnicodeString, obj_name, fname mov [attr.ObjectName],obj_name invoke NtCreateFile,hFile,\ FILE_READ_DATA + FILE_WRITE_DATA,\ attr, status, 0,0,\ FILE_SHARE_READ + FILE_SHARE_WRITE,\ FILE_OVERWRITE_IF, 0,0,0 invoke NtWriteFile,[hFile],0,0,0,\ status,fdata,dlen,ByteOffset,0 invoke NtClose,[hFile] endf invoke ExitProcess,0 ;//----------------- section '.idata' import data readable writeable library kernel32,'kernel32.dll',\ user32, 'user32.dll',\ ntdll, 'ntdll.dll' include 'api\kernel32.inc' include 'api\user32.inc' import ntdll,\ RtlInitUnicodeString,'RtlInitUnicodeString',\ NtCreateFile,'NtCreateFile',\ NtWriteFile, 'NtWriteFile',\ NtClose, 'NtClose'
На NtCreateFile сигнатур значительно меньше, потому что не у всех хватает мозгов юзать Nt* функи. Еще: Интересно сколько будет детектов если убрать: FILE_DELETE_ON_CLOSE
В большинстве качественных антивирусов/EDR используются отдельные юзермлд-библиотеки под x86 и x64, через которые реализуются IAT-хуки, в частности кстати перехватываются Nt-функции из ntdll.dll, поскольку многие WinAPI-вызовы в конечном счете сводятся к Native, условно: GetProcAddress -> LdrGetProcedureAddress. А чтобы мониторить файловую систему, тут уже спускаются на уровень драйвера в котором регистрируют каллбеки на операции открытия, чтения, записи и изменения файлов. Кстати, у меня еще с августа лежит огромная статья которую я писал месяц про реверс анти-эксплойт антивируса HitmanPRO.Alert, на WASM сейчас статьи нельзя выкладывать как я понял со статусом новичка? --- Сообщение объединено, 26 май 2026 --- Код (C++): #include <windowsh> #include <winternl.h> #pragma comment(lib, "ntdll.lib") using NtCreateFileFunc = NTSTATUS(NTAPI*)( PHANDLE FileHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PIO_STATUS_BLOCK IoStatusBlock, PLARGE_INTEGER AllocationSize, ULONG FileAttributes, ULONG ShareAccess, ULONG CreateDisposition, ULONG CreateOptions, PVOID EaBuffer, ULONG EaLength ); int main() { HMODULE loadlibrary = LoadLibraryA("ntdll.dll"); if (!loadlibrary) { return 1; } using NTSTATUS_SUCCESS = NTSTATUS; const NTSTATUS_SUCCESS STATUS_SUCCESS = 0x00000000; NtCreateFileFunc pMNtCreateFile = reinterpret_cast<NtCreateFileFunc>(GetProcAddress(loadlibrary, "NtCreateFile")); // рантайм загрузка если что if (pMNtCreateFile != nullptr) { HANDLE fileHandle = NULL; NTSTATUS status; IO_STATUS_BLOCK ioStatusBlock = { 0 }; OBJECT_ATTRIBUTES objectAttributes; UNICODE_STRING ntPath; RtlInitUnicodeString(&ntPath, L"\\??\\C:\\wasm.txt"); InitializeObjectAttributes(&objectAttributes, &ntPath, OBJ_CASE_INSENSITIVE, NULL, NULL); status = pMNtCreateFile( &fileHandle, GENERIC_WRITE | SYNCHRONIZE, &objectAttributes, &ioStatusBlock, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ, FILE_SUPERSEDE, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0 ); if (status == STATUS_SUCCESS) { CloseHandle(fileHandle); } } FreeLibrary(loadlibrary); return 0; } Вот ссылка на документацию функции NtCreateFile - https://learn.microsoft.com/en-us/windows/win32/api/winternl/nf-winternl-ntcreatefile
Интересно как у них устроен поиск по сигнатурам. Какие данные накапливаются для детекта. Как происходит отделение зерен от плевел (вредоносное/не вредоносное).
Подправил слегка код который чуть выше. Код выше на C++, я подправил для СИ. Компилировал в VS 2022 Pro. Может кому-нибудь тоже будет интересно и пригодится. Код (C): #include <windows.h> #include <winternl.h> #pragma comment(lib, "ntdll.lib") typedef NTSTATUS(NTAPI* NtCreateFileFunc)( PHANDLE FileHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PIO_STATUS_BLOCK IoStatusBlock, PLARGE_INTEGER AllocationSize, ULONG FileAttributes, ULONG ShareAccess, ULONG CreateDisposition, ULONG CreateOptions, PVOID EaBuffer, ULONG EaLength ); int main(void) { HMODULE loadlibrary = LoadLibraryA("ntdll.dll"); if (!loadlibrary) { return 1; } NtCreateFileFunc pMNtCreateFile = (NtCreateFileFunc)GetProcAddress(loadlibrary, "NtCreateFile"); if (pMNtCreateFile != NULL) { HANDLE fileHandle = NULL; NTSTATUS status; IO_STATUS_BLOCK ioStatusBlock = { 0 }; OBJECT_ATTRIBUTES objectAttributes; UNICODE_STRING ntPath; RtlInitUnicodeString(&ntPath, L"\\??\\C:\\wasm.txt"); InitializeObjectAttributes( &objectAttributes, &ntPath, OBJ_CASE_INSENSITIVE, NULL, NULL ); status = pMNtCreateFile( &fileHandle, GENERIC_WRITE | SYNCHRONIZE, &objectAttributes, &ioStatusBlock, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ, FILE_SUPERSEDE, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0 ); if (NT_SUCCESS(status)) { CloseHandle(fileHandle); } } FreeLibrary(loadlibrary); return 0; }