Hook when any file is closed

c++ / delphi package - dll injection and api hooking

Hook when any file is closed

Postby andrewc » Mon Jun 28, 2004 9:31 am

I want to find out when any file on the machine is closed.

These shell change notifiers don't seem to work very well so I am thinking about hooking the CloseHandle API.

Am I going about this the right way ?

Also is there any way to find out if a THandle is a file handle and if so how to get the filename from it.

Another thing, what happens if someone else's program also hooks the same API ?

Thanks for any help.
andrewc
 
Posts: 5
Joined: Mon Jun 28, 2004 9:25 am

Postby Claes » Mon Jun 28, 2004 12:50 pm

I did a silimar thing this way: Hook CreateFile, build a list of Handles to files created and then hook CloseHandle, see if the Handle of CloseHandle is in your list. I can post my code, if you are interested?
Claes
 
Posts: 52
Joined: Thu Apr 22, 2004 10:52 pm
Location: Denmark

Postby andrewc » Mon Jun 28, 2004 12:59 pm

I have just come to the same conclusion. Hook all versions of CreateFile and keep a list of Handles. Then hook CloseHandle and if its in my list I send IPC to my app with the filename. I have a working test program now.

My big worry is that I assume CloseHandle will be used rather a lot for many things so will it slow the system down to be scanning my list of handles every time it gets called ?

It would be interesting to see your code.

Also what happens of some other app decides to try and hook these API calls also ?
andrewc
 
Posts: 5
Joined: Mon Jun 28, 2004 9:25 am

Postby Claes » Mon Jun 28, 2004 1:24 pm

My hook isn't systemwide, I hook only ONE specific app. So I don't know about overhead, although I think you may be right that IS quite an overhead! And you may experience a systemlockups, as your app will prolly use CreateFile too. Also, my code only hooks CreateFileA. For a systemwide hook, you may need to hook CreateFileW as well. Anyhow, here is the code - I hope you find it useful.

Code: Select all
library Hook;

uses
  Windows,
  Classes,
  SysUtils,
  madCodeHook,
  madStrings,
  HookInit;

{$R *.res}

var
  CreateFileNext: function(lpFileName: PAnsiChar; dwDesiredAccess, dwShareMode: DWORD;
    lpSecurityAttributes: PSecurityAttributes; dwCreationDisposition, dwFlagsAndAttributes: DWORD;
    hTemplateFile: THandle): DWORD; stdcall;
  CloseHandleNext: function(hObject: THandle): BOOL; stdcall;

function CreateFileCallback(lpFileName: PAnsiChar; dwDesiredAccess, dwShareMode: DWORD;
  lpSecurityAttributes: PSecurityAttributes; dwCreationDisposition, dwFlagsAndAttributes: DWORD;
  hTemplateFile: THandle): DWORD; stdcall;
begin
  Result :=
    CreateFileNext(lpFileName,
                   dwDesiredAccess,
                   dwShareMode,
                   lpSecurityAttributes,
                   dwCreationDisposition,
                   dwFlagsAndAttributes,
                   hTemplateFile);

  if not Closing then
    if IsTextEqual(ExtractFilePath(lpFileName), SaveDir) then
      if Files.IndexOfObject(TObject(Result)) < 0 then
        Files.AddObject(lpFileName, TObject(Result));
end;

function CloseHandleCallback(hObject: THandle): BOOL; stdcall;
var
  I: Integer;
begin
  if not Closing then
  begin
    I := Files.IndexOfObject(TObject(hObject));
    if I >= 0 then
    begin
      StrPCopy(MessageBuf.FileName, Files.Strings[I]);
      MessageBuf.FileHandle := DWORD(Files.Objects[I]);
      Files.Delete(I);
      SendIpcMessage(DLLName, @MessageBuf, SizeOf(MessageBuf));
    end;
  end;

  Result := CloseHandleNext(hObject);
end;

begin
  HookAPI('kernel32.dll', 'CreateFileA', @CreateFileCallback, @CreateFileNext);
  HookAPI('kernel32.dll', 'CloseHandle', @CloseHandleCallback, @CloseHandleNext);
end.


I use an initialization unit, that sets the global var Closing. Without this variable, the code will crash when you exit the targetapp. This unit is also responsible for creating and freeing the list of files.

Code: Select all
unit HookInit;

interface

uses
  Windows, Classes, SysUtils, AnotherUnit;

type
  TMessageBuf = record
    FileName: array [0..MAX_PATH] of Char;
    FileHandle: DWORD;
  end;

const
  DLLName = 'Hook.dll';
 
var
  Files: TStringList;
  MessageBuf: TMessageBuf;
  SaveDir: string;
  Closing: Boolean;

implementation

initialization
  Closing := False;
  Files := TStringList.Create;
  SaveDir := IncludeTrailingPathDelimiter(AnotherUnit.GetDir);

finalization
  Closing := True;
  Files.Free;

end.
Claes
 
Posts: 52
Joined: Thu Apr 22, 2004 10:52 pm
Location: Denmark

Postby madshi » Mon Jun 28, 2004 7:03 pm

When hooking APIs like CreateFile + CloseHandle system wide you have to very careful with what you do. Performance might be a problem, if your hook callback functions do too much work. The hook itself should not be a problem, though. Please make sure that you follow all hooking rules (see madCodeHook documentation). Also don't transport each and every call via SendIpcMessage. madCodeHook's IPC message functions do work, but they're not the fasting thing on earth.
madshi
Site Admin
 
Posts: 9664
Joined: Sun Mar 21, 2004 5:25 pm


Return to madCodeHook

Who is online

Users browsing this forum: No registered users and 2 guests