Нашёл всё-таки волшебную функцию RtlAnsiStringToUnicodeString для перевода в unicode. Но теперь возникла другая проблема... ZwCreateFile не воспринимает полученную unicode строку. Код (Text): .data szFileName db "\\??\\c:\\test.txt",0 .code start proc local hFile:HANDLE local as:ANSI_STRING local us:UNICODE_STRING local oa:OBJECT_ATTRIBUTES local iosb:IO_STATUS_BLOCK mov eax,sizeof szFileName mov as._Length,ax mov as.MaximumLength,ax mov eax,offset szFileName mov as.Buffer,eax invoke RtlAnsiStringToUnicodeString,addr us,addr as,TRUE invoke MessageBoxW,0,us.Buffer,us.Buffer,0 ; InitializeObjectAttributes addr oa,us.Buffer,OBJ_CASE_INSENSITIVE+OBJ_KERNEL_HANDLE,0,0 lea ecx,oa mov dword ptr [ecx],000000018h and dword ptr [ecx+000000004h],0 mov dword ptr [ecx+00000000Ch],00000240h and dword ptr [ecx+000000010h],0 push us.Buffer pop dword ptr [ecx+000000008h] and dword ptr [ecx+000000014h],0 invoke ZwCreateFile,addr hFile,SYNCHRONIZE,addr oa,addr iosb,0,FILE_ATTRIBUTE_NORMAL,\ 0,FILE_CREATE,FILE_SYNCHRONOUS_IO_NONALERT,0,0 invoke ZwClose,hFile invoke ExitProcess,0 start endp end start Не подскажите в чём может быть проблема? Спасибо.
Дело в том, что практически во всех NT-шных API используется не UNICODE строка, а т.н. INITIALIZED UNICODE. Внимательнее читай MSDN: typedef struct _UNICODE_STRING { USHORT Length; USHORT MaximumLength; PWSTR Buffer; } UNICODE_STRING; как раз для преобразования существует функция: VOID RtlInitUnicodeString( PUNICODE_STRING DestinationString, PCWSTR SourceString );
Zufyxe Благодарю, всё получилось! Но теперь проблема, как обратно возвратить? Вот на примере этого кода: Код (Text): invoke RtlGetCurrentDirectory_U,520,addr us.Buffer invoke MessageBoxW,0,addr us.Buffer,addr us.Buffer,0 invoke RtlInitUnicodeString,addr us2,addr us.Buffer invoke RtlUnicodeStringToAnsiString,addr as,addr us2,1 invoke MessageBox,0,as.Buffer,as.Buffer,0 Разве не правильно делаю?
Структура UNICODE_STRING отличается от ANSI_STRING только указателем на строку т.е.: typedef struct _ANSI_STRING { USHORT Length; USHORT MaximumLength; PCHAR Buffer; } ANSI_STRING; Дерзай... ---------------------- С уважением Евгений.
- это поможет, если ты внимательнее посмотришь на типы: RtlUnicodeStringToAnsiString возвращает pANSI_STRING, а MessageBox принимает LPCTSTR, разница существенна.
IceStudent У мя в MessageBoxW всё отлично, с MessageBoxА - борода Zufyxe Хоть убей, не доходит... Уже как хошь пробовал, там полный линк не отабражается, либо "C:", либо какие-то каракулы ](4@" Даж пытался юзать аналогичному RtlInitUnicodeString -> RtlInitAnsiString после RtlUnicodeStringToAnsiString, серавно нормальной строки не могу получить.
Flasher Хех. Ну да, затираешь стек и утверждаешь, что отлично? Бог в помощь Код (Text): local buffer[520]:BYTE local us:UNICODE_STRING local as:ANSI_STRING ; тут не знаю, может 520/2 надо.. invoke RtlGetCurrentDirectory_U,520,addr buffer invoke MessageBoxW,0,addr buffer,addr buffer,0 invoke RtlInitUnicodeString,addr us,addr buffer invoke RtlUnicodeStringToAnsiString,addr as,addr us,1 invoke MessageBox,0,as.Buffer,as.Buffer,0
IceStudent Спасибо, оказывается вон как всё просто. Рас моно в RtlGetCurrentDirectory_U и в RtlInitUnicodeString обыкновенный buffer юзать, почему в справочниках этот параметр имеет вид STRUCT'ур'ы ? Чтоб меня путать?
Flasher Какой параметр? О назначение структур (XXX_STRING), кажется, писал Four-F. В двух словах, это для оптимизации работы с выделяемой памятью: если выделяешь память под строку, то выделяй не Length, а где-то 1.5*Length и записывай размер буфера в MaximumLength, а собственно длину строки - в Length.
Может кому понадобится... Код (Text): mov edi,offset ansistring mov esi,offset unicodestr push offset unicodestr call _strlenw mov edx,eax shl edx,2 xor eax,eax .while SDWORD ptr edx >= 0 lodsw stosb sub edx,4 .endw _strlenw: pop eax pop edx push eax xor ecx,ecx @@:mov eax,[edx+ecx*2] add ecx,1 test eax,00000ffffh jz @F add ecx,1 test eax,0ffff0000h jnz @B @@:xchg eax,ecx retn