要想跨进程访问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) 年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 <> ) and (GetWindowThreadProcessID(Handle, OwningProcess) <> ) and
(OwningProcess = GetCurrentProcessId) then
begin
if GlobalFindAtom(PChar(ControlAtomString)) = ControlAtom then
Result := Pointer(GetProp(Handle, MakeIntAtom(ControlAtom)))
else
Result := Pointer(SendMessage(Handle, RM_GetObjectInstance, , ));
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 := to vWinControl.ComponentCount - 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:= to DataSet.RecordCount- do
begin
tmpGridStr:=tmpGridStr+ dataset.Fields[].AsString+' '+dataset.Fields[].AsString+' ' ;
DataSet.Next;
end;
S := Format('%s: %s', [vWinControl.Components[I].Name,
QuotedStr(tmpGridStr)]); end;
vCopyDataStruct.cbData := Length(S);
vCopyDataStruct.dwData := ;
vCopyDataStruct.lpData := @S[];
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, , ,
SMTO_NORMAL, , THandle(Result)) = ;
UnhookWindowsHookEx(vSnifferInfo^.rHOOK);
end;
initialization
WM_SNIFFWINDOW := RegisterWindowMessage('SnifferLib.SniffWindow');
vMapFile := OpenFileMapping(FILE_MAP_ALL_ACCESS, False, '~Sniffer');
if vMapFile = then
vMapFile := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, ,
SizeOf(TSnifferInfo), '~Sniffer');
vSnifferInfo := MapViewOfFile(vMapFile, FILE_MAP_ALL_ACCESS, , , );
finalization
UnmapViewOfFile(vSnifferInfo);
CloseHandle(vMapFile);
end.

//DLL单元2

library SnifferLib;
uses
Windows,
Sniffer in 'Sniffer.pas';
{$R *.res}
exports
ExeSniffer;
begin
end.

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 = then Exit;
ExeSniffer(vHandle, Handle);
end;
procedure TFormSniffer.WMCOPYDATA(var Msg: TWMCopyData);
var
S: string;
begin
if Msg.CopyDataStruct^.cbData <= then Exit;
SetLength(S, Msg.CopyDataStruct^.cbData);
Move(Msg.CopyDataStruct^.lpData^, S[], Msg.CopyDataStruct^.cbData);
Memo1.Lines.Add(S);
end;
end

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

Delphi跨进程访问DBGRID的更多相关文章

  1. 跨进程访问VCL的一个用例(Delphi6、TurboDelphi测试通过)

    Controls.pas单元中有一个FindControl函数,通过句柄获得对应的TWinControl对象. function FindControl(Handle: HWnd): TWinCont ...

  2. 在C#或者SWT上跨进程访问SWT控件的问题

    可能为了进程安全,无论是C#的Form还是Eclipse的SWT,都不允许跨进程访问控件. 通俗一点说就是: A进程创建了控件Widget,若想在B进程中访问控件Widget就会报错,必须在创建Wid ...

  3. C# HttpBrowser 跨进程访问,解决内存泄露问题

    #undef DEBUG using Microsoft.Win32; using Newtonsoft.Json; using System; using System.Collections.Ge ...

  4. 关于跨进程使用回调函数的研究:以跨进程获取Richedit中RTF流为例(在Delphi 初始化每一个TWinControl 对象时,将会在窗体 的属性(PropData)中加入一些标志,DLL的HInstance的值与HOST 进程的HInstance并不一致)

    建议先参考我上次写的博文跨进程获取Richedit中Text: 获得QQ聊天输入框中的内容 拿到这个问题,我习惯性地会从VCL内核开始分析.找到TRichEdit声明的单元,分析TRichEdit保存 ...

  5. Android跨进程通信访问其他应用程序的Activity

    访问其他应用程序的ActivityActivity既可以在进程内(同一个应用程序)访问,也可以跨进程访问.如果想在同一个应用程序中访问Activity,需要指定Context对象和Activity的C ...

  6. Android随笔之——跨进程通信(一) Activity篇

    在Android应用开发中,我们会碰到跨进程通信的情况,例如:你用QQ通讯录打电话的时候会调用系统的拨号应用.某些新闻客户端可以将新闻分享到QQ.微信等应用,这些都是跨进程通信的情况.简而言之,就是一 ...

  7. Android中的跨进程调用技术AIDL

    什么是AIDL Android系统中的进程之间不能共享内存,因此,需要提供一些机制在不同进程之间进行数据通信. 为了使其他的应用程序也可以访问本应用程序提供的服务,Android系统采用了远程过程调用 ...

  8. Android跨进程通信的四种方式

    由于android系统中应用程序之间不能共享内存.因此,在不同应用程序之间交互数据(跨进程通讯)就稍微麻烦一些.在android SDK中提供了4种用于跨进程通讯的方式.这4种方式正好对应于andro ...

  9. Android四大组件应用系列——使用ContentProvider实现跨进程通讯

    一.问题描述 如何在Android中实现不同应用之间的通讯(既跨进程进行调用)?Android提供了多种实现方式,使我们可以实现跨进程访问Activity.通过ContentProvider跨进程访问 ...

随机推荐

  1. 使用Eclipse自带的Axis1插件生成Web Service服务端客户端

    JDK版本:1.5.0_22 Eclipse版本:Helios Service Release 2(3.6.2) WSDL文件的创建过程见http://blog.csdn.net/a19881029/ ...

  2. JAVA中日期和时间的格式化选项

    一.使用printf方法 import java.util.Date; import java.util.Scanner; public class Test { public static void ...

  3. Python之路,第三篇:Python入门与基础3

    1,  布尔运算符 运算符;    not      and   or not 运算符: 作用:逻辑取反 语法: not  表达式 例: not  True     #  False not   Fa ...

  4. HTML5 canvas 内部元素事件响应

    HTML5 canvas 内部元素事件响应 isPointInPath 只能拿当前上下文的路径 重画每个部分 都isPointInPath判断

  5. Django中的session于cookie的用法

    1.cookies 1.django 中使用 cookies 1.设置cookies的值(将数据保存到客户端) 语法: 响应对象.set_cookie(key,value,expires) key:c ...

  6. day python calss08 深浅copy

    一  join (格式:   . join) 遍历列表把列表中的每一项用指定符号进行拼接.(把列表转成字符串0 # lst = ["汪峰", "吴君如", &q ...

  7. 费马大定理以及求解a^2+b^2=c^2的奇偶数列法则

    <一>费马大定理:a^n+b^n=c^n 当n大于2时无正整数解. <二>求解a^2+b^=c^2可以使用a值奇偶法则:1.当a=2*n时,b=n^2-1,c=n^2+1   ...

  8. 【Wannafly挑战赛24】【C失衡天平】

    https://www.nowcoder.com/acm/contest/186/C 题意:有n个武器,每个武器都有一个重量 Wi,有一个天平,只要两端的重量差不大于m就能达到平衡,求在天平平衡的情况 ...

  9. 【BZOJ2154】Crash的数字表格

    算是学会反演了……(其实挺好学的一天就能学会…… 原题: 今天的数学课上,Crash小朋友学习了最小公倍数(Least Common Multiple).对于两个正整数a和b,LCM(a, b)表示能 ...

  10. centos7之zabbix入门(一)

    初始化状态如下 首先按照下面的步骤进行,主机名和可见名可以自己起,dns那里最好也填一下,其它默认就可以了 点击确认后,自动跳转到以下页面 可以看到zbx那里没有亮起来,说明还没有配置成功,接下来点击 ...