Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: WinAPI и системное программирование > Перехватить открытие файла


Автор: tigger 8.3.2007, 16:33
Как можно перехватить например открытие любых txt файлов?

Автор: bartram 8.3.2007, 20:21
1. Поиск http://forum.vingrad.ru/act-Search/CODE/show/searchid-89f876b66e13b13b4430710d1125fa38/search_in-posts/result_type/topics/flag/search/highlite/%25CF%25E5%25F0%25E5%25F5%25E2%25E0%25F2+and+api/index.html
2. Перехватывай CreateFile

Автор: MetalFan 8.3.2007, 21:03
bartram, 
+ назначить в реестре на расширение txt свое приложение...

Автор: bartram 9.3.2007, 09:19
Цитата(MetalFan @  8.3.2007,  21:03 Найти цитируемый пост)
+ назначить в реестре на расширение txt свое приложение...

А зачем? Можно просто перехватывать обращение и фильтровать по расширению txt smile

Автор: MetalFan 11.3.2007, 20:10
Цитата(bartram @  9.3.2007,  09:19 Найти цитируемый пост)
Можно просто перехватывать обращение 

по моему перехват апи эт не совсем "просто"....

Автор: tigger 12.3.2007, 12:43
Начал делать на CreateFile сделал, на файле тыкаешь блокнот грузится хотя пустой не запускается. В чем дело не пойму.

Автор: bartram 12.3.2007, 12:45
Цитата(tigger @  12.3.2007,  12:43 Найти цитируемый пост)
Начал делать на CreateFile сделал, на файле тыкаешь блокнот грузится хотя пустой не запускается. В чем дело не пойму. 

Код в студию smile тут телепатов нет

Автор: tigger 12.3.2007, 13:21
За основу был взят пример по перехвату MessageBoxA.

Автор: bartram 12.3.2007, 15:26
Мдя....
Код

library AdvBox32;

uses
  Windows;

type
 OldCode = packed record
  One: dword;
  two: word;
 end;


far_jmp = packed record
  PuhsOp: byte;
  PushArg: pointer;
  RetOp: byte;
 end;

var
 JmpMbw, JmpMba: far_jmp;
 OldMbw, OldMba: OldCode;
 MbwAdr, MbaAdr: pointer;


function TrueCreateFile(lpFileName: PWideChar; dwDesiredAccess,
                       dwShareMode: DWORD;
                       lpSecurityAttributes: PSecurityAttributes;
                       dwCreationDisposition, dwFlagsAndAttributes: DWORD;
                       hTemplateFile: THandle): THandle; stdcall;
var
 Written: dword;
begin

WriteProcessMemory(INVALID_HANDLE_VALUE, MbwAdr,
                     @OldMbw, SizeOf(OldCode), Written);

Result:=0;//CreateFileW(lpFileName,dwDesiredAccess,dwShareMode,lpSecurityAttributes,dwCreationDisposition,dwFlagsAndAttributes,hTemplateFile);


WriteProcessMemory(INVALID_HANDLE_VALUE, MbwAdr,
                     @JmpMbw, SizeOf(far_jmp), Written);
end;

function MyCreateFileW(lpFileName: PWideChar; dwDesiredAccess,
                       dwShareMode: DWORD;
                       lpSecurityAttributes: PSecurityAttributes;
                       dwCreationDisposition, dwFlagsAndAttributes: DWORD;
                       hTemplateFile: THandle): THandle; stdcall;
begin
Result := TrueCreateFile(lpFileName,dwDesiredAccess,dwShareMode,lpSecurityAttributes,dwCreationDisposition,dwFlagsAndAttributes,hTemplateFile);
end;

function MyCreateFileA(lpFileName: PAnsiChar; dwDesiredAccess,
                       dwShareMode: DWORD;
                       lpSecurityAttributes: PSecurityAttributes;
                       dwCreationDisposition, dwFlagsAndAttributes: DWORD;
                       hTemplateFile: THandle): THandle; stdcall;
var
 cLen: dword;
 FileName:PWideChar;
begin
cLen := lstrlen(lpFileName) * SizeOf(WideChar) + 2;
GetMem(FileName, cLen);
StringToWideChar(lpFileName, FileName, cLen);
Result := MyCreateFileW(FileName,dwDesiredAccess,dwShareMode,lpSecurityAttributes,dwCreationDisposition,dwFlagsAndAttributes,hTemplateFile);
FreeMem(FileName);
end;


Procedure SetHook();
var
 hkernel32: dword;
 Bytes: dword;
begin
  hkernel32 := GetModuleHandle('kernel32.dll');

  MbwAdr  := GetProcAddress(hkernel32, 'CreateFileW');
  MbaAdr := GetProcAddress(hkernel32, 'CreateFileA');

  ReadProcessMemory(INVALID_HANDLE_VALUE, MbwAdr, @OldMbw, SizeOf(OldCode), Bytes);
  ReadProcessMemory(INVALID_HANDLE_VALUE, MbaAdr, @OldMba, SizeOf(OldCode), Bytes);


  JmpMbw.PuhsOp  := $68;
  JmpMbw.PushArg := @MyCreateFileW;
  JmpMbw.RetOp   := $C3;

  JmpMba.PuhsOp  := $68;
  JmpMba.PushArg := @MyCreateFileA;
  JmpMba.RetOp   := $C3;




  WriteProcessMemory(INVALID_HANDLE_VALUE, MbwAdr, @JmpMbw, SizeOf(far_jmp), Bytes);
  WriteProcessMemory(INVALID_HANDLE_VALUE, MbaAdr, @JmpMba, SizeOf(far_jmp), Bytes);

end;

Procedure Unhook();
var
 Bytes: dword;
begin
  WriteProcessMemory(INVALID_HANDLE_VALUE, MbaAdr, @OldMba, SizeOf(OldCode), Bytes);
  WriteProcessMemory(INVALID_HANDLE_VALUE, MbwAdr, @OldMbw, 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;
begin
 hMutex := CreateMutex(nil, false, 'AdvareHook');
 if GetLastError = 0 then
 CreateThread(nil, 0, @SetGlobalHookProc, nil, 0, TrId) else
 CloseHandle(hMutex);
end;

//входная точка dll
procedure DLLEntryPoint(dwReason: DWord);
begin
  case dwReason of
    DLL_PROCESS_ATTACH: begin
                             //установка глобальной ловушки
                          SetGlobalHook();
                          SetHook()
                        end;
    DLL_PROCESS_DETACH: UnHook();
  end;
end;


begin
 DllProc := @DLLEntryPoint;
 DLLEntryPoint(DLL_PROCESS_ATTACH);
end.

Так где ты собственно перехватываешь? Я не вижу например имени файла
Из кода я понял что ты просто пропускаешь эту функцию через свою dll, при этом ничего не изменяя. из-за этого и ошибки
И вообще ты взял плохой пример для понимания ИМХО smile
Вот держи  модули, и примеры перехвата, которые реализованы более "просто" для понимания. Если что то будут непонятно, то спрашивай smile

Автор: tigger 12.3.2007, 16:12
Спасибо посмотрю, завтра напишу.

Автор: tigger 12.3.2007, 16:48
Не могу скачать????

Автор: bartram 12.3.2007, 21:03
tigger, почему? сейчас проверил, все нормально качается. Ты как качаешь?

Автор: tigger 13.3.2007, 12:02
Сохранить объект как... и сохраняет под именем файла id-1061614.html

Автор: bartram 13.3.2007, 13:20
tigger, просто переходи по ссылке, все должно быть норм

Автор: Yanis 13.3.2007, 13:56
Цитата(tigger @  13.3.2007,  13:02 Найти цитируемый пост)
Сохранить объект как... и сохраняет под именем файла id-1061614.html 

Хитрый какой ;) Должен же форум посчитать кол-во скачиваний.

Автор: tigger 13.3.2007, 14:49
Кликаю на прямую открывается страница http://forum.vingrad.ru/act-Attach/type/post/id-1061614.html со следующим содержимым:

Rar!;Рs $gzЂ#*в¬^яП3CMT ”СLЛХЃиНBFГ}Ш ҐЃm…¶Y%…Ґ?р0-APЏВ?ЅЉIШ‚KcпItћ‹3іf5Џ'ђ4УM4фqsеП ЂeXтЈ1ы°(Aњыђy–рSxЅ”q%ЇаL)i.ЈIBрОЊъфЗФДЌ‘рІћИШ%ъRq¤(йЗЊбЕ9Е)L хв`7ІNњДJ»]Ш%rцМчжzvЎqМЂіLЈї&·„пІЦѓ°}уЏb‹ФCс“oь жЪш5гщKх7 Д§HєЈaБlp ЃҐ,‹U©sљТ>qЬ;З№9b_уМ¦†i5лvЋЕж"ХЅ@кЮ/:О©ц U‚ѕ>xмНОїВzVBлї»9d*ІJ/‘ЌцuTM JщYљЃЁїґXjtАђ/ҐЛ !3ј ў¦?23 Readme.txtр' ЌLМНь?»иаь©Р$ckFЧш·§LеєБҐІi ЦдJИ¶q&R[?ьлkУєh·`/nЌV«гm%N8н[0ФЪфДУiЖеВхЮ‡@u5О ръзЖIррыxGп ’рьш5;mЦ+”™ИnOO]/ =xSц&ЉZКПWt•,qy‹,[\®”ьЫцљЇАjЩ„лх—iЉ—йЈ<*нФї¦y6[ёkoQЉО:»Г#„№kЪfOБАГЋт?х№ЯYБ Ь=Tїъ:^IЄ Њ±ъоЉ‰&І*ц љFЮ»р±`|&м4Я±ІY-V`@ °ЙZ©w”їµu`}д|H &bУUMycхЙьaыW uщ` 5HпІнЦ9ХФпN8О‚Є:лj¬«змmTџy*ЉЎЭ$д|Л^љsvgЄ ?Эу>Э–лљшFвqNЩUиq°юм-µрyѕE1~ћй2Я«ўЉxAµOn‚А-¬ў”A>Ж3+П»–e3иPИdј* щ(йП[gxBјьx2еФ©d†гҐАµпb¶8Kи,9vЄеiІЁу=|f“ЅжИiuUЗЌ]KFFXuєЌІFkЪАМlsћhЈ +-n?HйcH+zУсЉ|љАўRo–µ‹Еq¦ыwаЎТq рлхЃЊkц…GИњЖх§+‘Ђ¤x~ё3%lг—Яљ{!_Ё}*dQ§цРX‘`·ЗиЌp¤SФ°T/ѓp†зҐJ~µu{уA/Тн{‡m5wi>†С;ф9PXд”L‚>;¶ЋГю¬+МдT>R0ЎF)ЉсOЪG3© qшт(zАIЧ іоЂхbў!,ъ›±j&pоЮ+rДт™г»ВCИb+1,Ґ Фm $ zbsБe ёЕ±¦¦+aё9Ах6Ущ _МP®4oщH_DЗ# ЙѓУЏrВЫН?Eb¶ейјUэБzяV « е?…m„Щ§!Х"ћ™)uпXоє№~!AиОТB°ў ЙvЩ$-N“ЮLeRЬKўШG-#xybЋш­S†`И'»&\ПУм1ўЗ.эКй}Xєь|К d9i„&%&z:Ы{YF;u gW¤“Ф‘1ъІюl;%є‘Tg•‰tzN;&ЯМ(ГaС3!Г вЄpґ%зюќ»Eт2•+NЦюшжЌОtО@‹"ш­цмІ^`•M'µ%ѓА‡–Dьgшфµ3шк1;Ўtё™ТШб}{-У.ХЦcАСЖ&„ѕ¬Џи¦ЦІHЗU”(НЅц§¦†ЉIбІЧЙґG*Ь ЁGUВyUрЯOzvOіюC2ЩЉqєµ _`+J«”Н+0-™]¶‚%ѓЅ\xйЪ© бScЄїј#`2ыѓљ:31ІЮО ·Пhш}7ЁгуA0є<єlU$OWQ АUЕШг“МЕ'фщ7µ kгљ!JБj7s§у~?ш,wЄ`Ж›L№ња:їШч‡ХЮaїlџЉбќ+ј$\=AqвыКх`ЛМќгБФс¤љ yiЕ8’Зl_І:’ъГЭ'Kz9’ўіЧњлёЁ иZxC#±ГUµК' ЎFP`ЮmъЄс…‹м7—аиш­ж4ЫыёчёќжQµ=ћЯh7’'хл$¬3) 6JжфYC‹R`Ю ·ЩpCаqмжdцq+ьуъ%яqЭкФ†ФЧхs РМ›±:ђYVz8°° ~yџGЗфХ(оЄ–ЖКДычIᥚю„\аШ/P}”‡z$UЬE ‘wZ~ёX;?vиY•4ЕvЙЎ7т'gя}Ѕ®ЯХЫъюБнЙя µШtРђ.*'5 ?°[n25 clean.batр$э=я`§dg‚с A-9ш%Ѓ’Rуk?Я$;–&@ьПа‡?.............. 

bartram, 
может на ящик кинешь tigger@email.ru

Автор: bartram 14.3.2007, 09:26
Цитата(tigger @  13.3.2007,  14:49 Найти цитируемый пост)
может на ящик кинешь tigger@email.ru 

отправил

Автор: Yanis 14.3.2007, 11:09
Цитата(tigger @  13.3.2007,  15:49 Найти цитируемый пост)
Кликаю на прямую открывается страница http://forum.vingrad.ru/act-Attach/type/post/id-1061614.html со следующим содержимым:

Я подозреваю, что ты используешь в качестве броузера Opera.... У меня такая ситуация там постоянно повторялась.

Автор: Snowy 14.3.2007, 11:42
Цитата(tigger @  13.3.2007,  14:49 Найти цитируемый пост)
со следующим содержимым:
Клик правой кнопой.
В меню "Save target as..." (сохранить по ссылке как).

Автор: Coffein 18.4.2007, 19:49
Всех приветствую! У меня похожая проблема, и заключается она в следующем:

мне нужно реализовать механизм проверки прав доступа к ресурсам компьютера(к примеру запрет на откртыие определенных папок или запуск файлов) и в случае отсутствия их запетить доступ.

Я плохо понимаю перехват Апи-функций, bartram, ты выложил исходники, поясни мне пожалуста код и принцип advApiHook:
Код

function HookProc(lpModuleName, lpProcName: PChar;
                  NewProc: pointer; var OldProc: pointer): boolean;
var
 hModule: dword; 
 fnAdr: pointer;
begin
 Result := false;
 hModule := GetModuleHandle(lpModuleName);
 if hModule = 0 then hModule := LoadLibrary(lpModuleName);
 if hModule = 0 then Exit;
 fnAdr := GetProcAddress(hModule, lpProcName);
 if fnAdr = nil then Exit;
 Result := HookCode(fnAdr, NewProc, OldProc);
end;


и HookProc:
Код

program aHookProc;

uses
  Windows,
  advApiHook;
  
var
TrueMessageBoxA: function(hWnd: HWND; lpText, lpCaption:
                          PAnsiChar; uType: UINT): Integer; stdcall;

function NewMessageBoxA(hWnd: HWND; lpText, lpCaption:
                        PAnsiChar; uType: UINT): Integer; stdcall;
begin
  TrueMessageBoxA(0, 'Перехват установлен!', 'HookProc', 0);
end;

begin
  MessageBoxA(0, 'Новый метод API перехвата.', 'HookProc', 0);

  HookProc('user32.dll', 'MessageBoxA', @NewMessageBoxA, @TrueMessageBoxA);

  MessageBoxA(0, 'Не работает!', 'HookProc', 0);

  UnhookCode(@TrueMessageBoxA);
  
  MessageBoxA(0, 'Перехват снят.', 'HookProc', 0);
end.




Автор: bartram 19.4.2007, 16:05
Кратко:
Код

begin
  MessageBoxA(0, 'Новый метод API перехвата.', 'HookProc', 0); //показываем сообщение :)
  HookProc('user32.dll', 'MessageBoxA', @NewMessageBoxA, @TrueMessageBoxA); //установка перехвата
//первый аргумент - системная библиотека где находиться функция
//второй аргумент - имя функции (которую мы перехватываем) в этой библиотеке 
// третий аргумент - указатель на функцию КОТОРОЙ будет заменена оригинальная
// четвертый аргумент - указатель на оригинальную функцию (не перехваченную)
  MessageBoxA(0, 'Не работает!', 'HookProc', 0); //проверяем сработал ли перехват
  UnhookCode(@TrueMessageBoxA); //снимаем перехватчик
  
  MessageBoxA(0, 'Перехват снят.', 'HookProc', 0); // показываем сообщение о том что перехват снят
end.

Все предельно просто. Будут вопросы пиши.

Автор: Coffein 27.4.2007, 14:55
bartram, Спасибо за коментарии, с примером разобрался, но свою задачу так решить и не смог. Помоги разобраться:

- Мне нужно перехватывать функцию CopyFile глобально.  Для этого по примеру написал дллку:

Код

library Hook;

uses
  Windows,
  advApiHook;

{$R *.res}

const
  MutexName='__API_HOOK';

var
SH:HHOOK = 0;

  CopyFileNextHook: function (lpExistingFileName, lpNewFileName: PChar; bFailIfExists: BOOL): BOOL; stdcall;

//\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

function CopyFileHookProc(lpExistingFileName, lpNewFileName: PChar; bFailIfExists: BOOL): BOOL; stdcall;
begin
  MessageBox(0, 'Функция: CopyFile', 'Позволить ?', MB_YESNO or MB_ICONQUESTION);
end;

function MsgProc(code:DWORD;wParam,lparam:DWORD):DWORD;stdcall;
begin
  CallNextHookEx(SH,code,wParam,lparam);
end;

procedure SetWindowsHook(e:Boolean); stdcall;
var
  M:THandle;
begin
  if e then
   begin
    m:=CreateMutex(0,false,MutexName);
    if m=0 then exit;
    SH:=SetWindowsHookEx(WH_GETMESSAGE,@MsgProc,HInstance,0);
   end
       else
    UnhookWindowsHookEx(sh);
end;

procedure HandleEvents(reason: integer);
begin
  case reason of
    DLL_PROCESS_ATTACH:
      begin
        SetWindowsHook(true);
        HookProc('kernel32.dll', 'CopyFileW', @CopyFileHookProc, @CopyFileNextHook);
      end;
    DLL_PROCESS_DETACH:
      begin
        SetWindowsHook(false);  
        UnhookCode(@CopyFileNextHook);
      end;
  end;
end;

   //     HandleEvents(DLL_PROCESS_DETACH);

begin
  DllProc := @HandleEvents;
  MessageBox(0, 'Запускаем дллку', 'Позволить ?', MB_YESNO or MB_ICONQUESTION);
  HandleEvents(DLL_PROCESS_ATTACH);
///  CopyFile('C:\test.txt','C:\test1.txt',true);
end.
end.


ПРоблема в том что, если я в своем приложении вызываю функцию CopyFile, то она перехватывается, а если я в Винде жму копировать, то на меня ноль эмоций. ПОдскажи как быть? Может я не ту функцию отлавливаю, или чтобы подгрузит дллку к explorer'у надо что то еще сделать?

Автор: bartram 27.4.2007, 23:20
Цитата(Coffein @  27.4.2007,  16:55 Найти цитируемый пост)
ПРоблема в том что, если я в своем приложении вызываю функцию CopyFile, то она перехватывается, а если я в Винде жму копировать, то на меня ноль эмоций. ПОдскажи как быть? Может я не ту функцию отлавливаю, или чтобы подгрузит дллку к explorer'у надо что то еще сделать?

Если в своем приложении срабатывает значит делаешь правильно.  Ты внедряешь dll в Explorer?
Посмотри примеры advApiHook там есть пример внедрения dll в чужие процессы.

Автор: Coffein 28.4.2007, 12:52
Я в примере использую установку глобального хука на все события происходящие в Винде, тем самым внедряю свою дллку ко всем процессам. Отсюда я пологал что она внедряется и в explorer. Но в отличае всех приложений explorer  мне не выдал сообщение(при подключении дллки выполняется код вывода сообщения) о том что дллка к нему подключена. я завершал explorer, потом заново запускал, тогда сообщение мне выводилось, но результата ни какого. В примере advApiHook смотрел, но не разобрался как оно функцианирует. 

Автор: bartram 28.4.2007, 20:52
Попробуй завершить explorer и запустить его потом с помощью:
Код

function CreateProcessWithDll(lpApplicationName: pchar;
                              lpCommandLine: pchar;
                              lpProcessAttributes,
                              lpThreadAttributes: PSecurityAttributes;
                              bInheritHandles: boolean;
                              dwCreationFlags: dword;
                              lpEnvironment: pointer;
                              lpCurrentDirectory: pchar;
                              const lpStartupInfo: TStartupInfo;
                              var lpProcessInformation: TProcessInformation;
                              ModulePath: PChar): boolean;

И посмотри что будет.
эта функция есть в AdvApiHook
P.S. будет время напишу тебе рабочий код.

Автор: Coffein 30.4.2007, 20:00
bartram, если не трудно поясни парамметры функции.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)