( Заранее прошу не критиковать за выбор делфей и Юзермода, задача должна решиться именно так, в силу многих решающих причин) Хочу организовать мониторнг операции с файлами. Для начала - открытие (создание). Используя метод перехвата АПИ функций, описанным MS-REM (Перехват АПи функций, часть 1) хочу сделать эту функцию: ZwCreateFile. В МСДН вот такое описание: The ZwCreateFile routine creates a new file or opens an existing file. NTSTATUS ZwCreateFile( OUT PHANDLE FileHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK IoStatusBlock, IN PLARGE_INTEGER AllocationSize OPTIONAL, IN ULONG FileAttributes, IN ULONG ShareAccess, IN ULONG CreateDisposition, IN ULONG CreateOptions, IN PVOID EaBuffer OPTIONAL, IN ULONG EaLength ); В Делфи я переделал вот так: Function ZwCreateFile(FileHandle:PHANDLE; DesiredAccessWORD; ObjectAttributes:POBJECT_ATTRIBUTES; IoStatusBlock :PIO_STATUS_BLOCK; a:PLargeInteger; FileAttributes, ShareAccess, CreateDisposition, CreateOptionsWORD; EaBuffer:Pointer; EaLengthWORD ): NTStatus; stdcall; external 'ntdll.dll'; Ведется ее перехват Function NewZwCreateFile(FileHandle:PHANDLE; DesiredAccessWORD; ObjectAttributes:POBJECT_ATTRIBUTES; IoStatusBlock :PIO_STATUS_BLOCK; a:PLargeInteger; FileAttributes, ShareAccess, CreateDisposition, CreateOptionsWORD; EaBuffer:Pointer; EaLengthWORD ): NTStatus; stdcall; begin Result:=TrueZwCreateFile(FileHandle, DesiredAccess, ObjectAttributes, IoStatusBlock , a, FileAttributes, ShareAccess, CreateDisposition, CreateOptions, EaBuffer, EaLength, ); add2file('c:\FILESLOG.txt',pchar('NEWCREATEFILE, lAST ERROR = '+inttostr(GetLastError())+' , Result= ' +Inttostr(Result)+#13#10)); end; Ну так вот, если программа работает, то выдается ЛастЕррор = 478 (Attempt to access invalid address.) и функция возвращяет -1073741811 значение. Я думаю что описал функцию неправильно.. Но.. Не могу понять что не так.. А IoStatusBlock^.Status дает значение 437336 (ошибка) .. ПРи этом если открываею тектовый файл, то блокнот не старует, а тотал коммендер пишет что "не удалось запустить программу". Но втроенный вьювер текстовый файл открывает.
Сервисы возвращают LastStatusValue, LastErrorValue это получается из первого значения далее. У тебя сервис возвращает STATUS_INVALID_PARAMETER. Модуль в студию.
Упс, нашлась небольшая бага... Но исправив ее, нашлась новая.. Щас подправлю и посмотрю как работает... Ошибки нашлись, причем не в единственном экземпляре. Что называется лучше не переделывать, писать модуль заного, т.к. забываешь менять некоторые значения. Так и запутался. Еще касяк был что в обработчике у меня вызывается запись в файл, что собственно заного вызывает эту функцию, таким образом идет зацикливание (( Но месаджбокс выдается при открытии файла, работаю... Пока вопрос на опережение: Какие еще нужно будет функции хватать чтобы отловить запись в файл?
Итак, построил небольшой файловый монитор подобно FileNom В коно блокнота скидываются строки лога, какая прога и какой файл открывает. Впечатление такое что не всегда срабатывает...
CrystalIC Думаю человек просто учится тому, как вообще это делать, а не пытается от вас защититься. test555 Код нужно увидеть.
Пожалста. Код в студию! Код (Text): library Hide; uses Windows, NativeAPI, Messages; type OldCode = packed record One: dword; two: word; end; type LongRec = packed record case Integer of 0: (Lo, Hi: Word); 1: (Words: array [0..1] of Word); 2: (Bytes: array [0..3] of Byte); end; far_jmp = packed record PuhsOp: byte; PushArg: pointer; RetOp: byte; end; PUnicodeString = ^TUnicodeString; TUnicodeString = packed record Length: Word; MaximumLength: Word; Buffer: PWideChar; end; TOBJECT_ATTRIBUTES = packed record Length : ULONG; RootDirectory : THandle; ObjectName : PUnicodeString; Attributes : ULONG; SecurityDescriptor : Pointer; SecurityQualityOfService : Pointer; end; OBJECT_ATTRIBUTES = TOBJECT_ATTRIBUTES; POBJECT_ATTRIBUTES = ^TOBJECT_ATTRIBUTES; const FileDirectoryInformation = 1; FileFullDirectoryInformation = 2; FileBothDirectoryInformation = 3; FileNamesInformation = 12; KeyValueBasicInformation =0; KeyValueFullInformation =1; KeyValuePartialInformation =2; STATUS_NO_SUCH_FILE = $C000000F; STATUS_SUCCESS = $00000000; var JmpCreateFile: far_jmp; OldCreateFile : OldCode; PtrCreateFile: pointer; b:boolean; Function ZwCreateFile(FileHandle:PHANDLE; DesiredAccess:DWORD; ObjectAttributes:POBJECT_ATTRIBUTES; IoStatusBlock :PIO_STATUS_BLOCK; a:PLargeInteger; FileAttributes, ShareAccess, CreateDisposition, CreateOptions:DWORD; EaBuffer:Pointer; EaLength:DWORD ): NTStatus; stdcall; external 'ntdll.dll'; function AllocMem(Size: Cardinal): Pointer; begin GetMem(Result, Size); FillChar(Result^, Size, 0); end; function StrPas(const Str: PChar): string; begin Result := Str; end; function StrToInt(S: string): integer; begin Val(S, Result, Result); end; function IntToStr(I: integer): string; begin Str(I, Result); end; function GetModuleFileName: string; var Buffer: array[0..261] of Char; begin SetString(Result, Buffer, Windows.GetModuleFileName(HInstance, Buffer, SizeOf(Buffer))); end; Function TrueZwCreateFile(FileHandle:PHANDLE; DesiredAccess:DWORD; ObjectAttributes:POBJECT_ATTRIBUTES; IoStatusBlock :PIO_STATUS_BLOCK; a:PLargeInteger; FileAttributes, ShareAccess, CreateDisposition, CreateOptions:DWORD; EaBuffer:Pointer; EaLength:DWORD ): NTStatus; stdcall; var Written: dword; begin WriteProcessMemory(INVALID_HANDLE_VALUE, PtrCreateFile, @OldCreateFile, SizeOf(OldCode), Written); Result := ZwCreateFile(FileHandle, DesiredAccess, ObjectAttributes, IoStatusBlock, a, FileAttributes, ShareAccess, CreateDisposition, CreateOptions, EaBuffer, EaLength ); WriteProcessMemory(INVALID_HANDLE_VALUE, PtrCreateFile, @JmpCreateFile, SizeOf(far_jmp), Written); end; Function NewZwCreateFile(FileHandle:PHANDLE; DesiredAccess:DWORD; ObjectAttributes:POBJECT_ATTRIBUTES; IoStatusBlock :PIO_STATUS_BLOCK; a:PLargeInteger; FileAttributes, ShareAccess, CreateDisposition, CreateOptions:DWORD; EaBuffer:Pointer; EaLength:DWORD ): NTStatus; stdcall; var buf : array [0.. 16384-1] of char; s, st:string; M:integer; const hh=460752; // хендл поля куда скидывать логи. Обычно это поле блокнота (вычислять самому) begin Result:=TrueZwCreateFile(FileHandle, DesiredAccess, ObjectAttributes, IoStatusBlock , a, FileAttributes, ShareAccess, CreateDisposition, CreateOptions, EaBuffer, EaLength, ); SendMessage(hh,WM_GETTEXT, 16384, dword(@buf)); s:=strpas(buf); m:=length(s); if m>15000 then s:=''; s:=inttostr(Result) + ': '+ paramstr(0)+ ', ' + ObjectAttributes^.ObjectName.Buffer + ''+ #13#10 + s ; SendMessage(hh,WM_SETTEXT, 0, integer(pchar(s)) ); end; Procedure SetHook(); var Bytes, bytes2: dword; begin PtrCreateFile := GetProcAddress(GetModuleHandle('ntdll.dll'), 'ZwCreateFile'); ReadProcessMemory(INVALID_HANDLE_VALUE, PtrCreateFile, @OldCreateFile, SizeOf(OldCode), Bytes); JmpCreateFile.PuhsOp := $68; JmpCreateFile.PushArg := @NewZWCreateFile; JmpCreateFile.RetOp := $C3; WriteProcessMemory(INVALID_HANDLE_VALUE, PtrCreateFile, @JmpCreateFile, SizeOf(far_jmp), Bytes); end; Procedure Unhook(); var Bytes: dword; begin WriteProcessMemory(INVALID_HANDLE_VALUE, PtrCreateFile, @OldCreateFile, SizeOf(OldCode), Bytes); end; Function MessageProc(code : integer; wParam : word; lParam : longint) : longint; stdcall; begin CallNextHookEx(0, Code, wParam, lparam); Result := 0; end; Procedure SetGlobalHookProc(); begin SetWindowsHookEx(WH_GETMESSAGE, @MessageProc, HInstance, 0); Sleep(INFINITE); end; // Procedure SetGlobalHook(); var hMutex: dword; TrId: dword; i:integer; begin i:=0; hMutex := CreateMutex(nil, false, 'ProcHideHook'); if GetLastError = 0 then CreateThread(nil, 0, @SetGlobalHookProc, nil, 0, TrId) else CloseHandle(hMutex); end; procedure DLLEntryPoint(dwReason: DWord); var s:string; begin case dwReason of DLL_PROCESS_ATTACH: begin b:=true; SetGlobalHook(); SetHook(); end; DLL_PROCESS_DETACH: begin Unhook(); end; end; end; begin DllProc := @DLLEntryPoint; DLLEntryPoint(DLL_PROCESS_ATTACH); end. Верно замечено, что это больше учебная задача. Вообще-то это часть дипломного проекта. Но возможно что будет применяться в производстве. CrystalIC, а ты сможешь без прав админа запустить свой сервис Int2e (с АСМ я не дружу пока, я статью про введение в машинный код еще не прочел, т.е до прерываний дошел..) Вообще нужно будет мониторить, чтобы юзеры не сохраняли некотореы документы, например на флешки или сетевые папки...
В каком еще производстве? Это Вы зря. Думаю он справится, Вы о себе думайте. Т.к. в данном случае он прав - тут жесть какая-то. Вы если коды ошибок указываете указывайте их в 16м представлении и ее смысловое значение (врядли кто-то будет переводить, а потом еще и искать за Вас это же не школа) и строку что ли, где выходит такой код ошибки. Выглядит так будто каша сплошная в голове - не стоит скорее всего так спешить. По коду - Возвращаемые значения стоит проверять наверное. - SetGlobalHook нужна вобще? А мьютекс там зачем хоть? Про остальное говорить нет смысла - постарайтесь не просто неправильно копипастить код, а немного разобраться и попытаться написать в ручную с 0. Наверное поэтому тут так и не любят Delphi.
А это код из топика ниже, там кто то пытался от диспетчера скрыться и эту длл юзал, а ТС скопипастил, добавил только хук ZwCreateFile, ибо видимо не шарет как поставить хук. Даже название мьютекса оставил, наверно побоялся что работать не будет а вот сам топик http://www.wasm.ru/forum/viewtopic.php?id=29422
Ох, закритиковали. По порядку. PE_Kill, не скрываю, исходники были взяты из статьи, и переделаны. А смысла пока менять 'ProcHideHook' я не вижу (или я не прав??), не это щас главное. CrystalIC, "дурдом", это про что конкретно вы имеете ввиду? Код, приведенный здесь работает, и уже нет никаких ошибок -1073741811 и тд.. Кому интересно, задача - отловить запись некоторых документов в запрещенные места (сетевые диски, неразрешенные флешки). Юзеры имеют права Пользователя. Все же задача более учебная....