Problem with dll hooking

c++ / delphi package - dll injection and api hooking
Stevie
Posts: 7
Joined: Wed Aug 25, 2004 1:41 pm

Problem with dll hooking

Post by Stevie »

Hi,

my project looks like this:

Code: Select all

unit frDllHook;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    OpenDialog1: TOpenDialog;
    procedure Button1Click(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses
  CommDlg, madCodeHook;

var GetOpenFileNameOld : function(var OpenFile: tagOFNA): longbool; stdcall;

function GetOpenFileNameCallback(var OpenFile: tagOFNA) : longbool; stdcall;
begin
  ShowMessage('Fehler');
  OpenFile.lpstrTitle := 'Ein gehookter FileOpenDialog!';
  Result := GetOpenFileNameOld(OpenFile);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  OpenFile: tagOFNA;
begin
//  OpenDialog1.Execute;
  GetOpenFileName(OpenFile);
end;

initialization
  if HookAPI('comdlg32.dll', 'GetOpenFileName',
   @GetOpenFileNameCallback, @GetOpenFileNameOld) then
    ShowMessage('GetOpenFileName wurde erfolgreich gehookt!');

finalization
  UnHookAPI(@GetOpenFileNameOld);

end.
But when I press the Button, it seems that the method is not hooked, why?
nildo
Posts: 249
Joined: Mon Mar 22, 2004 11:32 am
Contact:

Post by nildo »

Thats because GetOpenFileName calls 'GetOpenFileNameA'. So, try this:

Code: Select all

  if HookAPI('comdlg32.dll', 'GetOpenFileNameA', 
   @GetOpenFileNameCallback, @GetOpenFileNameOld) then 
    ShowMessage('GetOpenFileName wurde erfolgreich gehookt!');
Stevie
Posts: 7
Joined: Wed Aug 25, 2004 1:41 pm

Post by Stevie »

Ok, it worked, but now I'm trying to hook the FileOpenDialog for the whole system:
Dll-Code:

Code: Select all

library DllHook;

uses
  SysUtils, Classes, CommDlg, madCodeHook, Windows, Messages;

const
  FCIDM_SHVIEW_LARGEICON  = 28713;
  FCIDM_SHVIEW_SMALLICON  = 28714;
  FCIDM_SHVIEW_LIST       = 28715;
  FCIDM_SHVIEW_REPORT     = 28716;
  FCIDM_SHVIEW_THUMBNAIL  = 28717; //    XP only
  FCIDM_SHVIEW_TILE       = 28718; //    XP

var GetOpenFileNameOld : function(var OpenFile: tagOFNA): longbool; stdcall;

function Hook(Wnd: HWND; Msg: Cardinal; wParam: Integer; lParam: Integer): Cardinal; stdcall;
var
  Ctrl: HWND;
  Parent: HWND;
begin
  if Msg = WM_SHOWWINDOW then
  begin
    Parent := GetParent(Wnd);
    Ctrl := FindWindowEx(Parent, 0, PChar('SHELLDLL_DefView'), nil);
    if Ctrl <> 0 then
      SendMessage(Ctrl, WM_COMMAND, FCIDM_SHVIEW_THUMBNAIL, 0);
  end;
  Result := 0;
//  PostMessage(Wnd, WM_USER, GetParent(Wnd), 0);
end;

function GetOpenFileNameCallback(var OpenFile: tagOFNA) : longbool; stdcall;
begin
  OpenFile.lpfnHook := Hook;
  OpenFile.Flags := OpenFile.Flags or OFN_ENABLEHOOK or OFN_EXPLORER;
  OpenFile.lpstrTitle := 'Ein gehookter FileOpenDialog!';
  Result := GetOpenFileNameOld(OpenFile);
end;

begin
  HookAPI('comdlg32.dll', 'GetOpenFileNameA',
   @GetOpenFileNameCallback, @GetOpenFileNameOld);
end.
ApplicationCode:

Code: Select all

unit frDllHook;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    OpenDialog1: TOpenDialog;
    procedure Button1Click(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses
  CommDlg, madCodeHook;

procedure TForm1.Button1Click(Sender: TObject);
begin
  OpenDialog1.Execute;
end;

initialization
//  if not HookAPI('comdlg32.dll', 'GetOpenFileNameA',
//   @GetOpenFileNameCallback, @GetOpenFileNameOld, ) then
//  ShowMessage('Fehler beim Hook von GetOpenFileName!');
  if not InjectLibrary((ALL_SESSIONS or SYSTEM_PROCESSES), 'DllHook.dll') then
    ShowMessage('Fehler beim Inject von DllHook.dll');

finalization
//  UnHookAPI(@GetOpenFileNameOld);
  UnInjectLibrary((ALL_SESSIONS or SYSTEM_PROCESSES), 'DllHook.dll');

end.
But it only seems to work for my Application but not for others, i.e. I tried to open a file from the notepad, but the FileOpenDialog did not change.
nildo
Posts: 249
Joined: Mon Mar 22, 2004 11:32 am
Contact:

Post by nildo »

Thats because NotePad calls GetOpenFileNameW. So your DLL must be like this:

Code: Select all

library DllHook; 

uses
  SysUtils,
  Classes,
  CommDlg,
  madCodeHook,
  Windows,
  Messages;

const
  FCIDM_SHVIEW_LARGEICON  = 28713; 
  FCIDM_SHVIEW_SMALLICON  = 28714; 
  FCIDM_SHVIEW_LIST       = 28715; 
  FCIDM_SHVIEW_REPORT     = 28716; 
  FCIDM_SHVIEW_THUMBNAIL  = 28717; //    XP only 
  FCIDM_SHVIEW_TILE       = 28718; //    XP

var GetOpenFileNameAOld : function(var OpenFile: tagOFNA): longbool; stdcall;
    GetOpenFileNameWOld : function(var OpenFile: tagOFNW): longbool; stdcall;

function Hook(Wnd: HWND; Msg: Cardinal; wParam: Integer; lParam: Integer): Cardinal; stdcall;
var
  Ctrl: HWND;
  Parent: HWND;
begin 
  if Msg = WM_SHOWWINDOW then
  begin 
    Parent := GetParent(Wnd); 
    Ctrl := FindWindowEx(Parent, 0, PChar('SHELLDLL_DefView'), nil); 
    if Ctrl <> 0 then 
      SendMessage(Ctrl, WM_COMMAND, FCIDM_SHVIEW_THUMBNAIL, 0); 
  end; 
  Result := 0; 
//  PostMessage(Wnd, WM_USER, GetParent(Wnd), 0); 
end; 

function GetOpenFileNameACallback(var OpenFile: tagOFNA) : longbool; stdcall;
begin
  OpenFile.lpfnHook := Hook;
  OpenFile.Flags := OpenFile.Flags or OFN_ENABLEHOOK or OFN_EXPLORER;
  OpenFile.lpstrTitle := 'Ein gehookter FileOpenDialog!';
  Result := GetOpenFileNameAOld(OpenFile);
end;

function GetOpenFileNameWCallback(var OpenFile: tagOFNW) : longbool; stdcall;
begin
  OpenFile.lpfnHook := Hook;
  OpenFile.Flags := OpenFile.Flags or OFN_ENABLEHOOK or OFN_EXPLORER;
  OpenFile.lpstrTitle := 'Ein gehookter FileOpenDialog!';
  Result := GetOpenFileNameWOld(OpenFile);
end;

begin
  HookAPI('comdlg32.dll', 'GetOpenFileNameA',
   @GetOpenFileNameACallback, @GetOpenFileNameAOld);
  HookAPI('comdlg32.dll', 'GetOpenFileNameW',
   @GetOpenFileNameWCallback, @GetOpenFileNameWOld);
end.
Does it work now?
Stevie
Posts: 7
Joined: Wed Aug 25, 2004 1:41 pm

Post by Stevie »

Yeah, it works, but ...

New Questions:
1. How can I make my Delphi to debug the dll if it is called from another process - let's say notepad?
2. How can I make the routine work, so that the Dialog is set to specified style?

Ok, 2. is not really a question to the topic, but perhaps you know? :confused:
nildo
Posts: 249
Joined: Mon Mar 22, 2004 11:32 am
Contact:

Post by nildo »

Stevie wrote:1. How can I make my Delphi to debug the dll if it is called from another process - let's say notepad?
The only way I do is to put many MessageBox ! (not ShowMessage, because showmessage uses VCL).
2. How can I make the routine work, so that the Dialog is set to specified style?
I think you would do a Google search ;-) I really don't know
Stevie
Posts: 7
Joined: Wed Aug 25, 2004 1:41 pm

Post by Stevie »

The only way I do is to put many MessageBox ! (not ShowMessage, because showmessage uses VCL).
:crazy: I hate MessageBoxes!!! :crazy:
Oh, wait, perhaps a user breakpoint should do it... and then debug...
I think you would do a Google search ;-) I really don't know
Just did it, but perhaps I should do again... :wink:
nildo
Posts: 249
Joined: Mon Mar 22, 2004 11:32 am
Contact:

Post by nildo »

Try to use WinSight and then change the style of the Dialog and see if it receives any message...
Stevie
Posts: 7
Joined: Wed Aug 25, 2004 1:41 pm

Post by Stevie »

I checked out, what Message is receives, and it is the WM_COMMAND with 28716 as lParam, (if I change to Report View). And it is received by the SHELLDLL_DefView-Object, that is a child of the Dialog. But why can't I find it within the function? Perhaps it is the wrong Message (WM_SHOWWINDOW) ? But what Message should I take???
I tried this, but nothing, why????

Code: Select all

 function Hook(Wnd: HWND; Msg: Cardinal; wParam: Integer; lParam: Integer): Cardinal; stdcall;
var
  Ctrl: HWND;
begin
  Ctrl := FindWindowEx(Wnd, 0, PChar('SHELLDLL_DefView'), nil);
  if Ctrl <> 0 then
    SendMessage(Ctrl, WM_COMMAND, FCIDM_SHVIEW_REPORT, 0);
  Result := 0;
end;
nildo
Posts: 249
Joined: Mon Mar 22, 2004 11:32 am
Contact:

Post by nildo »

I really don't know. I'll try to check when I have a time... Sorry
Stevie
Posts: 7
Joined: Wed Aug 25, 2004 1:41 pm

Post by Stevie »

YEAH!!! I did it!!! 8)

Code: Select all

function Hook(Wnd: HWND; Msg: Cardinal; wParam: Integer; lParam: Integer): Cardinal; stdcall;
var
  Ctrl: HWND;
begin
  if Msg = WM_NOTIFY then
  begin
    Ctrl := FindWindowEx(GetParent(Wnd), 0, PChar('SHELLDLL_DefView'), nil);
    if Ctrl <> 0 then
      SendMessage(Ctrl, WM_COMMAND, FCIDM_SHVIEW_REPORT, 0);
  end;
  Result := 0;
end;
How can I register my dll, that everytime I open the Dialog this hook is active?
nildo
Posts: 249
Joined: Mon Mar 22, 2004 11:32 am
Contact:

Post by nildo »

Congratz!

Once you have injected this DLL in the way you did, every time that any program opens this dialog, this hook will be alread activated.

So, you need to put a Loader (program that inject your DLL into every System processess) to start with Windows.
Stevie
Posts: 7
Joined: Wed Aug 25, 2004 1:41 pm

Post by Stevie »

Jepp, I created a service and it works. Thx again!!!
nildo
Posts: 249
Joined: Mon Mar 22, 2004 11:32 am
Contact:

Post by nildo »

Awww I forgot about the services... lol!

Congratulations! I'm happy that it's working now!
madshi
Site Admin
Posts: 10766
Joined: Sun Mar 21, 2004 5:25 pm

Post by madshi »

Thanks nildo for helping out... :wink:
Post Reply