Начал недавно постигать программирование в Ring-0 и тут столкнулся с проблемой недостатка информации ... Вобщем заинтересовала меня функция (Nt\Zw)LockFile - но она недокументированная и никаких примеров ее использования я не нашел =( Может кто подскажет как ей пользоваться? PS: и еще такое вопрос - чем отличаются Nt* от Zw* ?
Названием. В ntdll.dll ясно же написано: <ol type=1>Zw* proc near Nt* label near</ol> Я как раз только что из IDA. Нашел Кучу толковых функций, на которые тоже не найдешь описание.
Вообще дизассемблируй kernel32.dll. Тебе нужно смотреть LockFile (лучше LockFileEx). Эти функции используют ZwLockFile. ZwLockFile получает 10 (!) параметров. В основном они идут из тех, что передаешь LockFile (LockFileEx), а еще из структуры OVERLAPPED (указатель на нее - последний параметр, передаваемый функции LockFileEx).
Код (Text): NTSYSAPI NTSTATUS NTAPI ZwLockFile( IN HANDLE FileHandle, IN HANDLE Event OPTIONAL, IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, IN PVOID ApcContext OPTIONAL, OUT PIO_STATUS_BLOCK IoStatusBlock, IN PULARGE_INTEGER LockOffset, IN PULARGE_INTEGER LockLength, IN ULONG Key, IN BOOLEAN FailImmediately, IN BOOLEAN ExclusiveLock );
Вот например дизассемблировал один троян: Код (Text): .text:00010676 push 0 ; EaLength .text:00010678 push 0 ; EaBuffer .text:0001067A push 20h ; CreateOptions .text:0001067C push 1 ; CreateDisposition .text:0001067E push 0 ; ShareAccess .text:00010680 push 80h ; FileAttributes .text:00010685 push 0 ; AllocationSize .text:00010687 push offset IoStatusBlock ; IoStatusBlock .text:0001068C push offset ObjectAttributes ; ObjectAttributes .text:00010691 push 1 ; DesiredAccess .text:00010693 push offset FileHandle ; FileHandle .text:00010698 call ZwCreateFile .text:0001069D or eax, eax .text:0001069F jnz short loc_10700 .text:000106A1 push 5 ; FileInformationClass .text:000106A3 push 14h ; FileInformationLength .text:000106A5 push offset FileInformation ; FileInformation .text:000106AA push offset IoStatusBlock ; IoStatusBlock .text:000106AF push FileHandle ; FileHandle .text:000106B5 call ZwQueryInformationFile .text:000106BA push FileInformation .text:000106C0 pop LockLength.LowPart .text:000106C6 mov eax, [esp+50h+Key] .text:000106CA push 2 ; ExclusiveLock .text:000106CC push 0 ; FailImmediately .text:000106CE push eax ; Key .text:000106CF push offset LockLength ; LockLength .text:000106D4 push offset LockLength.HighPart ; LockOffset .text:000106D9 push offset IoStatusBlock ; IoStatusBlock .text:000106DE push 0 ; ApcContext .text:000106E0 push 0 ; ApcRoutine .text:000106E2 push 0 ; Event .text:000106E4 push FileHandle ; FileHandle .text:000106EA call NtLockFile Вобщем под вопросом у меня вот это: Что это за Key и LockLength и где их брать? PS: полностью этот файл в аттаче 3576668__vdnt32.vsys
Вот ещё немного инфы, Ms Rem что-то не всё запостил Код (Text): Routine Description: This service locks a specified range of bytes on the file specified by the FileHandle parameter. The lock may either be an exclusive lock or a shared lock. Furthermore, the caller has the option of specifying whether or not the service should return immediately if the lock cannot be acquired without waiting. Arguments: FileHandle - Supplies a handle to an open file. Event - Supplies an optional event to be set to the Signaled state when the operation is complete. ApcRoutine - Supplies an optional APC routine to be executed when the operation is complete. ApcContext - Supplies a context parameter to be passed to the ApcRoutine, if an ApcRoutine was specified. IoStatusBlock - Address of the caller's I/O status block. ByteOffset - Specifies the starting byte offset of the range to lock. Length - Specifies the length of the byte range to be locked. Key - Specifies the key to be associated with the lock. FailImmediately - Specifies that if the lock cannot immediately be acquired that the service should return to the caller. ExclusiveLock - Specifies, if TRUE, that the lock should be an exclusive lock; otherwise the lock is a shared lock. Return Value: The status returned is success if the operation was properly queued to the I/O system. Once the operation completes, the status can be determined by examining the Status field of the I/O status block. Key может быть таким: ULONG LockFileKey = 1; 0 возможно, есть и другие значения, но я не нашел :-(
Вот накатал Код (Text): LockFile proc local oa:OBJECT_ATTRIBUTES local iosb:IO_STATUS_BLOCK local hFile:HANDLE local cb:PLARGE_INTEGER local bo:PLARGE_INTEGER local fsi:FILE_STANDARD_INFORMATION InitializeObjectAttributes addr oa, $CCOUNTED_UNICODE_STRING("\\??\\C:\\WINDOWS\\SYSTEM32\\test.exe"),\ OBJ_CASE_INSENSITIVE + OBJ_KERNEL_HANDLE, NULL, NULL invoke ZwCreateFile, addr hFile, FILE_WRITE_EA + SYNCHRONIZE, addr oa, addr iosb, 0, \ FILE_ATTRIBUTE_NORMAL, 0, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0 invoke ZwOpenFile, addr hFile, FILE_WRITE_EA + SYNCHRONIZE, addr oa, addr iosb, FILE_SHARE_READ, \ FILE_SYNCHRONOUS_IO_NONALERT invoke ZwQueryInformationFile, hFile, addr iosb, addr fsi, sizeof fsi, FileStandardInformation mov eax, fsi.EndOfFile.LowPart inc eax lea ecx,cb assume ecx:PLARGE_INTEGER mov [ecx].LowPart, eax mov [ecx].HighPart, eax invoke NtLockFile, hFile, 0, 0, 0, addr iosb, addr bo, addr cb, 1, 0, 2 invoke ZwClose, hFile ret LockFile endp Блокирует почему-то не все файлы - в чем может быть ошибка?
Вот я не пойму, почему последний параметр равен двум, когда он максимум может быть TRUE? Не блокирует возможно потому, что другой процесс его уже заблокировал с Exclusive Access'ом . Может GetLastError что подскажет? Еще. Если Key может быть равен единице, это вовсе не значит, что он должен быть равен единице.
Дык если файл вообще открыт другим процессом, то как его возможно заблокировать то? Поэтому и не блочит.
dr_dred > В Си, как и в ассемблере нет булевых типов данных. так что 2 это тоже TRUE. А то, что TRUE != 2 - это неправильное использование языка microsoft'ом, а следом за ним и другими людьми. подробнее про такие баги можно почитать в книге Ален Голуб "Верёвка достаточной длины, что бы выстрелить себе в ногу"
S_T_A_S_ эээ, ты же читал приводимую тобой в пример книгу, а сам пишешь такое... единственно верной может быть (и должна быть!) только проверка TRUE != 0 или TRUE == 0.
Скорее это не баг, а системное ограничение. Иначе как можно определить TRUE и какой будет результат при занесении этого в переменную любого целого типа? #define TRUE (some != 0) В принципе для чистоты можно написать функцию сравнения псевдобулевых значений: Код (Text): template<class T> inline BOOL CmpBool (T a, T b) { return (a != 0) == (b != 0); }
нет, все нормально. А вот если найдешь в коде Код (Text): if (doSomth() [b]==[/b] TRUE) тогда это точно баг будет.
alpet > А зачем его определять? Язык C не поддерживает булевый тип данных. В принципе, это не является проблемой для написания программ, поскольку этот тип излишество. Если же он нужен, то можно использовать C++ - большенство компиляторов его поддерживают. Или делать свой тип посредством enum. infern0 > Ага, а ещё и if ( foo == FALSE ) встретить можно. IMHO это незнание возможностей языка.
S_T_A_S_ В таком случае придется смириться с "TRUE = 1". Во всяком случае я и в Це++ программах использую именно эту константу, а не значение bool::true.
вот флеймеры Да просто когда я дизассемблирова тот файл который я выложил там и увидел ExclusiveLock = 2 А файл который используется тоже нормально блокируется. Не блокируются только уже частично заблокированные файлы - можно это как-нибудь обойти?
alpet А что мешает использовать встроенный в C++ тип bool? В С99 добавилен _Bool. Да и практически всегда можно целый тип использовать вместо. Эти кривые макросы себе дороже обойдутся, с ними можно долго искать сверхестественный глюк