Delphi跨进程访问DBGRID

要想跨进程访问DBGRID,貌似只能用HOOK,写一个DLL想办法注入到目标进程。注入成功后,使DLL与目标进程在同一进程空间中(其内有一些细节问题,请参见代码),这时可以访问目标进程的VCL组件。并把VCL组件的数据通过进程通信的方式发给Sniffer进程。

 

如何进行注入?

     可以安装一个WH_CALLWNDPROC钩子,这样当有消息在窗口函数中时,系统就会装载HOOK,即执行DLL部分。

 

如何发消息?

    可以在DLL中设置一个自定义消息,在安装完钩子后,发送一个自定义消息至目标进程的窗口函数。

 

 

以下实例可读出另一进程的EDIT、LABEL、DBGRID等控件的值。

如何了解这个原理,跨进程读取StringGrid等控件也并非难事!

//DLL单元1

(*//

标题:窗体嗅探器

作者:王集鹄(Zswang)

博客:http://blog.csdn.net/zswang

日期:2009年3月14日

.//*)

unit Sniffer;

interface

uses Windows,DBGrids,DB;

function ExeSniffer( // 执行嗅探

  AHandle: THandle; // 窗体句柄

  AParam: Integer // 附加参数

): BOOL; stdcall;

implementation

// 尊重作者,转贴请注明出处 王集鹄(Zswang) 2009年3月14日

uses SysUtils, Classes, Controls, StdCtrls, Messages;

var

  WM_SNIFFWINDOW: Longword;

type

  TSnifferInfo = packed record

    rHOOK: HHOOK;

    rHandle: HWND;

    rParam: Integer;

  end;

  PSnifferInfo = ^TSnifferInfo;

var

  vMapFile: THandle;

  vSnifferInfo: PSnifferInfo;

var

  ControlAtom: TAtom;

  ControlAtomString: string = '';

  RM_GetObjectInstance: DWORD;  // registered window message

function FindControl(Handle: HWnd): TWinControl;

var

  OwningProcess: DWORD;

begin

  Result := nil;

  if (Handle <> 0) and (GetWindowThreadProcessID(Handle, OwningProcess) <> 0) and

     (OwningProcess = GetCurrentProcessId) then

  begin

    if GlobalFindAtom(PChar(ControlAtomString)) = ControlAtom then

      Result := Pointer(GetProp(Handle, MakeIntAtom(ControlAtom)))

    else

      Result := Pointer(SendMessage(Handle, RM_GetObjectInstance, 0, 0));

  end;

end; { FindControl }

function SnifferProc(code: Integer; wparam: WPARAM; lparam: LPARAM): LRESULT; stdcall;

var

  vWinControl: TWinControl;

  vCopyDataStruct: TCopyDataStruct;

  I,J: Integer;

  S: string;

  tmpGridStr:string;

  DataSet: TDataSet;

begin

  case code of

    HC_ACTION:

      begin

        if PCWPStruct(lParam)^.message = WM_SNIFFWINDOW then

        begin

          if ControlAtomString = '' then

          begin

            ControlAtomString := Format('ControlOfs%.8X%.8X', [

              GetWindowLong(vSnifferInfo^.rHandle, GWL_HINSTANCE),

              GetWindowThreadProcessId(vSnifferInfo^.rHandle)]);

            ControlAtom := GlobalAddAtom(PChar(ControlAtomString));

            RM_GetObjectInstance := RegisterWindowMessage(PChar(ControlAtomString));

          end;

          vWinControl := FindControl(vSnifferInfo^.rHandle);

          if Assigned(vWinControl) then

          begin

            for I := 0 to vWinControl.ComponentCount - 1 do

            begin

              S := '';

              if SameText(vWinControl.Components[I].ClassName, 'TLabel') then

              begin

                S := Format('%s: %s', [vWinControl.Components[I].Name,

                  QuotedStr(TLabel(vWinControl.Components[I]).Caption)]);

              end else if SameText(vWinControl.Components[I].ClassName, 'TMemo')

                or SameText(vWinControl.Components[I].ClassName, 'TEdit') then

              begin

                S := Format('%s: %s', [vWinControl.Components[I].Name,

                  QuotedStr(TLabel(vWinControl.Components[I]).Caption)]);

              end

              else if SameText(vWinControl.Components[I].ClassName, 'TDBGrid') then

              begin

                DataSet := TDBGrid(vWinControl.Components[I]).DataSource.DataSet;

                tmpGridStr:='';

                for J:=0 to DataSet.RecordCount-1 do

                begin

                  tmpGridStr:=tmpGridStr+ dataset.Fields[0].AsString+' '+dataset.Fields[1].AsString+' ' ;

                  DataSet.Next;

                end;

                S := Format('%s: %s', [vWinControl.Components[I].Name,

                  QuotedStr(tmpGridStr)]);

                   

              end;

              vCopyDataStruct.cbData := Length(S);

              vCopyDataStruct.dwData := 0;

              vCopyDataStruct.lpData := @S[1];

              SendMessage(vSnifferInfo^.rParam, WM_COPYDATA,

                vSnifferInfo^.rHandle, Integer(@vCopyDataStruct));

            end;

          end;

        end;

      end;

  end;

  Result := CallNextHookEx(vSnifferInfo^.rHOOK, code, wParam, lParam);

end;

function ExeSniffer( // 执行嗅探

  AHandle: THandle; // 窗体句柄

  AParam: Integer // 附加参数

): BOOL; stdcall;

begin

  vSnifferInfo^.rHandle := AHandle;

  vSnifferInfo^.rParam := AParam;

  vSnifferInfo^.rHOOK := SetWindowsHookEx(

    WH_CALLWNDPROC, SnifferProc, HInstance, GetWindowThreadProcessId(AHandle));

  Result := SendMessageTimeout(AHandle, WM_SNIFFWINDOW, 0, 0,

    SMTO_NORMAL, 3000, THandle(Result)) = 0;

  UnhookWindowsHookEx(vSnifferInfo^.rHOOK);

end;

initialization

  WM_SNIFFWINDOW := RegisterWindowMessage('SnifferLib.SniffWindow');

  vMapFile := OpenFileMapping(FILE_MAP_ALL_ACCESS, False, '~Sniffer');

  if vMapFile = 0 then

    vMapFile := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0,

      SizeOf(TSnifferInfo), '~Sniffer');

  vSnifferInfo := MapViewOfFile(vMapFile, FILE_MAP_ALL_ACCESS, 0, 0, 0);

finalization

  UnmapViewOfFile(vSnifferInfo);

  CloseHandle(vMapFile);

end.
View Code

//DLL单元2

library SnifferLib;

uses

  Windows,

  Sniffer in 'Sniffer.pas';

{$R *.res}

exports

  ExeSniffer;

begin

end.
View Code

sniffer程序

unit SnifferUnit;

interface

uses

  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

  Dialogs, StdCtrls;

type

  TFormSniffer = class(TForm)

    ButtonStart: TButton;

    Memo1: TMemo;

    EditClassName: TEdit;

    LabelClassName: TLabel;

    procedure ButtonStartClick(Sender: TObject);

  private

    { Private declarations }

    procedure WMCOPYDATA(var Msg: TWMCopyData); message WM_COPYDATA;

  public

    { Public declarations }

  end;

var

  FormSniffer: TFormSniffer;

implementation

{$R *.dfm}

function ExeSniffer( // 执行嗅探

  AHandle: THandle; // 窗体句柄

  AParam: Integer // 附加参数

): BOOL; stdcall;

external 'SnifferLib.dll'; // 执行嗅探

procedure TFormSniffer.ButtonStartClick(Sender: TObject);

var

  vHandle: THandle;

begin

  Memo1.Clear;

  vHandle := FindWindow(PChar(EditClassName.Text), nil);

  if vHandle = 0 then Exit;

  ExeSniffer(vHandle, Handle);

end;

procedure TFormSniffer.WMCOPYDATA(var Msg: TWMCopyData);

var

  S: string;

begin

  if Msg.CopyDataStruct^.cbData <= 0 then Exit;

  SetLength(S, Msg.CopyDataStruct^.cbData);

  Move(Msg.CopyDataStruct^.lpData^, S[1], Msg.CopyDataStruct^.cbData);

  Memo1.Lines.Add(S);

end;

end
View Code

 

http://pan.baidu.com/s/1GFZuZ   下载地址

 

你可能感兴趣的:(Delphi)