• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

Delphi跨进程访问DBGRID

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

要想跨进程访问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   下载地址

 


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
delphi中socket心跳包的实现发布时间:2022-07-18
下一篇:
看看Delphi中的列表(List)和泛型发布时间:2022-07-18
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap