搜索
bottom↓
回复: 30

求助:跨进程获取delphi控件TDBGridEh的内容

[复制链接]

出10入23汤圆

发表于 2016-8-31 21:41:33 | 显示全部楼层 |阅读模式
如题:
有一个第三方软件用了TDBGridEh控件,想获取表格控件上的内容,网上看到有用dll hook的办法获取TstringGrid的内容
因此也想用dll hook的办法获取TDBGridEh内容,求高人指点一下

阿莫论坛20周年了!感谢大家的支持与爱护!!

阿莫论坛才是最爱国的,关心国家的经济、社会的发展、担心国家被别国牵连卷入战争、知道珍惜来之不易的和平发展,知道师夷之长,关注世界的先进文化与技术,也探讨中国文化的博大精深,也懂得警惕民粹主义的祸国殃民等等等等,无不是爱国忧民的表现。(坛友:tianxian)

出0入0汤圆

发表于 2016-8-31 22:41:05 | 显示全部楼层
既然网上有,,就老老实实,,,按网上的去试,,,

出10入23汤圆

 楼主| 发表于 2016-8-31 23:12:39 来自手机 | 显示全部楼层
litop 发表于 2016-8-31 22:41
既然网上有,,就老老实实,,,按网上的去试,,,

试了,现在在findcontrol这里卡住了,无法获取到控件实例对象

出0入70汤圆

发表于 2016-8-31 23:18:24 | 显示全部楼层
无句柄的控件获取不了

出10入23汤圆

 楼主| 发表于 2016-8-31 23:38:28 来自手机 | 显示全部楼层
SkyGz 发表于 2016-8-31 23:18
无句柄的控件获取不了

控件有句柄,我自己另外写了一个测试软件,可以获取到这个测试软件的对象实例,
但是目标软件无法获取,findcontrol总是失败

出0入70汤圆

发表于 2016-8-31 23:45:25 | 显示全部楼层
本帖最后由 SkyGz 于 2016-8-31 23:51 编辑
zouzhichao 发表于 2016-8-31 23:38
控件有句柄,我自己另外写了一个测试软件,可以获取到这个测试软件的对象实例,
但是目标软件无法获取,f ...


那你确定 那个软件用的就是 TDBGridEh????????????           你确定 测试软件所用软件 和 目标软件是同一控件?

用SPY++看能找到目标控件不,        能找到的话, 那就是你程序不对了,  试试遍历窗口内所有子控件,把类名都 列出来看看

出10入23汤圆

 楼主| 发表于 2016-9-1 00:01:34 | 显示全部楼层
SkyGz 发表于 2016-8-31 23:45
那你确定 那个软件用的就是 TDBGridEh????????????           你确定 测试软件所用软件 和 目标软件是同 ...

以下是我自己写的测试软件的TDBGgridEh的spy++信息:

以下是目标软件的TDBGgridEh的spy++信息:


自己写的测试软件可以被获取到,而对于目标软件执行MyfindControl总是失败
以下是hook的dll的源码
  1. unit UHook;

  2. interface

  3. uses Windows, Messages, SysUtils, Controls, Grids, DBGrids, DBGridEh, Classes;

  4. procedure InstallHook(MainWnd, DestWnd: HWND); stdcall;
  5. procedure UninstallHook; stdcall;
  6. function GetHookedCell: PChar; stdcall;

  7. implementation

  8. uses UShare;

  9. var
  10.   ControlAtom: TAtom;
  11.   ControlAtomString: string;
  12.   RM_GetObjectInstance: DWORD;  // registered window message


  13. function MyFindControl_test(Handle: HWnd): TWinControl;
  14. type  
  15.   PObjectInstance = ^TObjectInstance;
  16.   TObjectInstance = packed record  
  17.     Code: Byte;            { 短跳转 $E8 }  
  18.     Offset: Integer;       { CalcJmpOffset(Instance, @Block^.Code); }
  19.     Next: PObjectInstance; { MainWndProc 地址 }
  20.     Self: Pointer;         { 控件对象地址 }
  21.   end;  
  22. var  
  23.   wc: PObjectInstance;  
  24. begin  
  25.   Result := nil;  
  26.   wc     := Pointer(GetWindowLong(Handle, GWL_WNDPROC));  
  27.   if wc <> nil then  
  28.   begin  
  29.     Result := wc.Self;  
  30.   end;  
  31. end;


  32. function MyFindControl(Handle: HWnd): TWinControl;
  33. var
  34.   OwningProcess: DWORD;
  35. begin
  36.   Result := nil;
  37.   if (Handle <> 0) and (GetWindowThreadProcessID(Handle, OwningProcess) <> 0) and
  38.      (OwningProcess = GetCurrentProcessId) then
  39.   begin
  40.     if GlobalFindAtom(PChar(ControlAtomString)) = ControlAtom then
  41.       Result := Pointer(GetProp(Handle, MakeIntAtom(ControlAtom)))
  42.     else
  43.       Result := Pointer(SendMessage(Handle, RM_GetObjectInstance, 0, 0));
  44.   end;
  45. end;

  46. function MsgWndProc(hwnd: HWND; Msg: UINT; WParam: WPARAM; LParam: LPARAM): LRESULT; stdcall;
  47. var
  48.   DG: TDBGridEh;
  49.   aName: array [0..255] of Char;
  50. begin
  51.   case Msg of
  52.     CM_QUERYROW:                      //获取行数
  53.       begin
  54.         Result := -1;
  55.         if P^.DestWnd <> 0 then
  56.         begin
  57.           GetClassName(P^.DestWnd, aName, 256);
  58.           if string(aName) = 'TDBGridEh' then MessageBeep(MB_OK);
  59.           DG := Pointer(MyFindControl(P^.DestWnd));
  60.           if DG <> nil then Result := DG.RowCount;
  61.         end;
  62.         Exit;
  63.       end;
  64.     CM_QUERYCOL:                              //获取列数
  65.       begin
  66.         Result := -1;
  67.         if P^.DestWnd <> 0 then
  68.         begin
  69.           GetClassName(P^.DestWnd, aName, 256);
  70.           if string(aName) = 'TDBGridEh' then MessageBeep(MB_OK);
  71.           DG := Pointer(MyFindControl(P^.DestWnd));
  72.           if DG <> nil then Result := DG.Columns.Count;
  73.         end;
  74.         Exit;
  75.       end;
  76.     CM_HOOKCELL:                                //获取内容
  77.       begin
  78.         DG := Pointer(MyFindControl(P^.DestWnd));
  79.         if DG <> nil then MessageBeep(MB_OK);
  80.         Exit;
  81.       end;
  82.   end;
  83.   Result := DefWindowProc(hwnd, Msg, WParam, LParam);
  84. end;

  85. function GetMsgProc(Code: UINT; WParam: WPARAM; LParam: LPARAM): LRESULT; stdcall;
  86. begin
  87.   if Code = HC_ACTION then
  88.   begin
  89.   end;
  90.   Result := CallNextHookEx(P^.hkMsg, Code, WParam, LParam);
  91. end;

  92. procedure InstallHook(MainWnd, DestWnd: HWND); stdcall;
  93. begin
  94.   if P^.hkMsg = 0 then
  95.     P^.hkMsg := SetWindowsHookEx(WH_GETMESSAGE, @GetMsgProc, HInstance, 0);
  96.   P^.HostWnd := MainWnd;
  97.   P^.HostPID := GetCurrentProcessId;
  98.   P^.DestWnd := DestWnd;
  99. end;

  100. procedure UninstallHook; stdcall;
  101. begin
  102.   if P^.hkMsg <> 0 then
  103.   begin
  104.     UnhookWindowsHookEx(P^.hkMsg);
  105.     P^.hkMsg := 0;
  106.   end;
  107. end;

  108. function GetHookedCell: PChar; stdcall;
  109. begin
  110.   Result := P^.Text;
  111. end;

  112. var
  113.   DoClear: Boolean;
  114.   DestPID: DWORD;
  115.   DestProcess: Boolean = False;
  116.   UtilWindowClass: TWndClass = (
  117.     style: 0;
  118.     lpfnWndProc: @MsgWndProc;
  119.     cbClsExtra: 0;
  120.     cbWndExtra: 0;
  121.     hInstance: 0;
  122.     hIcon: 0;
  123.     hCursor: 0;
  124.     hbrBackground: 0;
  125.     lpszMenuName: nil;
  126.     lpszClassName: 'THookSGMsgWindow');

  127. initialization
  128.   hMapFile := OpenFileMapping(FILE_MAP_WRITE, False, cMapFileName);
  129.   DoClear := hMapFile = 0;
  130.   if hMapFile = 0 then
  131.     hMapFile := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE,
  132.       0, SizeOf(TShareData), cMapFileName);
  133.   P := MapViewOfFile(hMapFile, FILE_MAP_WRITE, 0, 0, 0);
  134.   if DoClear then FillChar(P^, SizeOf(TShareData), 0);
  135.   ControlAtomString := Format('ControlOfs%.8X%.8X', [GetModuleHandle(nil), GetCurrentThreadID]);
  136.   ControlAtom := GlobalAddAtom(PChar(ControlAtomString));
  137.   RM_GetObjectInstance := RegisterWindowMessage(PChar(ControlAtomString));
  138.   if P^.DestWnd <> 0 then
  139.   begin
  140.     GetWindowThreadProcessId(P^.DestWnd, DestPID);
  141.     if DestPID = GetCurrentProcessId then
  142.     begin
  143.       DestProcess := True;
  144.       UtilWindowClass.hInstance := HInstance;
  145.       Windows.RegisterClass(UtilWindowClass);
  146.       P^.MsgWnd := CreateWindowEx(
  147.         WS_EX_TOOLWINDOW,              // extended window style
  148.         UtilWindowClass.lpszClassName, // pointer to registered class name
  149.         UtilWindowClass.lpszClassName, // pointer to window name
  150.         WS_POPUP,                      // window style
  151.         0,                             // horizontal position of window
  152.         0,                             // vertical position of window
  153.         0,                             // window width
  154.         0,                             // window height
  155.         0,                             // handle to parent or owner window
  156.         0,                             // handle to menu, or child-window identifier
  157.         HInstance,                     // handle to application instance
  158.         nil);                          // pointer to window-creation data
  159.       PostMessage(P^.HostWnd, CM_MSGWNDCREATED, P^.MsgWnd, 1);
  160.     end;
  161.   end;
  162. finalization
  163.   if DestProcess then
  164.   begin
  165.     DestroyWindow(P^.MsgWnd);
  166.     PostMessage(P^.HostWnd, CM_MSGWNDCREATED, P^.MsgWnd, 0);
  167.   end;
  168.   GlobalDeleteAtom(ControlAtom);
  169.   ControlAtomString := '';
  170.   UnmapViewOfFile(P);
  171.   CloseHandle(hMapFile);
  172. end.
复制代码

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出10入23汤圆

 楼主| 发表于 2016-9-1 00:02:46 | 显示全部楼层
SkyGz 发表于 2016-8-31 23:45
那你确定 那个软件用的就是 TDBGridEh????????????           你确定 测试软件所用软件 和 目标软件是同 ...

虽然没有遍历,但是类名获取是对的,用if加beep验证过了

出10入23汤圆

 楼主| 发表于 2016-9-1 00:07:39 | 显示全部楼层
SkyGz 发表于 2016-8-31 23:45
那你确定 那个软件用的就是 TDBGridEh????????????           你确定 测试软件所用软件 和 目标软件是同 ...

现在我怀疑是spy++信息中的实例句柄不一致导致的(图中用红笔标示),但又不知道如何修改程序,以前没用过delphi,完全新手

出10入23汤圆

 楼主| 发表于 2016-9-1 09:33:30 来自手机 | 显示全部楼层
自己再顶一下

出10入23汤圆

 楼主| 发表于 2016-9-1 12:34:13 来自手机 | 显示全部楼层
再次把帖子顶上来

出350入477汤圆

发表于 2016-9-1 13:35:01 来自手机 | 显示全部楼层
如果它是先自己画到内存DC,再拷到界面上的,那么你啥也得不到。因为它里面根本就没有文字,实际是个图片。很多用这种高级控件的都是为了自己画,不然干嘛不用系统自带的那种?

出350入477汤圆

发表于 2016-9-1 13:37:25 | 显示全部楼层
你用个可以屏幕取词的字典软件到它的窗口里面取一下试试看,如果字典取不到任何文字,那你就不用费事了

出10入23汤圆

 楼主| 发表于 2016-9-1 14:36:04 来自手机 | 显示全部楼层
redroof 发表于 2016-9-1 13:35
如果它是先自己画到内存DC,再拷到界面上的,那么你啥也得不到。因为它里面根本就没有文字,实际是个图片。 ...

不是这种,我都用spy++抓到了句柄了

出350入477汤圆

发表于 2016-9-1 14:39:50 | 显示全部楼层
zouzhichao 发表于 2016-9-1 14:36
不是这种,我都用spy++抓到了句柄了

跟句柄没关系。
他是个窗口控件,当然有句柄。
但它里面的东西到底是真正的文字还是图片,谁知道?
如果是当作图片画上去的,你完全没办法拿到

出10入23汤圆

 楼主| 发表于 2016-9-1 14:48:48 来自手机 | 显示全部楼层
redroof 发表于 2016-9-1 14:42
你以为控件没有句柄的那种,我也知道,那种整个窗口里面一切控件都是自己用图片画出来的。这样你只能看到 ...

理解你的意思了,我回去再看看
不过自绘控件的可能性不大,因为是个小众软件,应该不会这么折腾吧?

出10入23汤圆

 楼主| 发表于 2016-9-1 14:49:39 来自手机 | 显示全部楼层
redroof 发表于 2016-9-1 14:39
跟句柄没关系。
他是个窗口控件,当然有句柄。
但它里面的东西到底是真正的文字还是图片,谁知道?

谢谢你…

出10入23汤圆

 楼主| 发表于 2016-9-2 21:11:56 | 显示全部楼层
再顶一下!!!
问题还没解决

出10入23汤圆

 楼主| 发表于 2016-9-2 21:12:21 | 显示全部楼层
求高手支招!!!

出0入0汤圆

发表于 2016-9-2 21:18:51 | 显示全部楼层
看来我的软件防破解知道怎么去做了

出10入23汤圆

 楼主| 发表于 2016-9-2 22:32:55 | 显示全部楼层
在网上找到一篇靠边的文档,但是信息也不全,求高手提点
http://bbs.csdn.net/topics/90085650?list=lz

出10入23汤圆

 楼主| 发表于 2016-9-3 19:16:47 | 显示全部楼层
SkyGz 发表于 2016-8-31 23:45
那你确定 那个软件用的就是 TDBGridEh????????????           你确定 测试软件所用软件 和 目标软件是同 ...

大神,你好,会不会是目标软件加壳影响这个hook操作?

出0入70汤圆

发表于 2016-9-3 20:07:53 | 显示全部楼层
zouzhichao 发表于 2016-9-3 19:16
大神,你好,会不会是目标软件加壳影响这个hook操作?

没影响.........即使加壳了
程序也是在内存 解壳运行的

出10入23汤圆

 楼主| 发表于 2016-9-3 21:34:43 | 显示全部楼层
SkyGz 发表于 2016-9-3 20:07
没影响.........即使加壳了
程序也是在内存 解壳运行的

今天咨询了另一个人,他也说加壳影响的可能性小
他说可能跟delphi版本和控件版本有关

现在的情况是findcontrol可以返回一个非零值地址,但是把这个地址里都出来的控件实例数据不对

出0入70汤圆

发表于 2016-9-3 21:54:53 | 显示全部楼层
你这是消息HOOK吧, MsgWndProc里等于程序内的所有控件都会进入这个函数,  你没有判断HWND是否TDBGridEh,
只是根据有消息产生CM_QUERYROW,CM_QUERYCOL的,    就直接强制转换为TDBGridEh了
还有你的MyFindControl里SendMessage, 有没尝试过换为PostMessage之类的...

MessageBeep有响过吗......倒底有没有获取到句柄我也不知道了


function MsgWndProc(hwnd: HWND; Msg: UINT; WParam: WPARAM; LParam: LPARAM): LRESULT; stdcall;
var
  DG: TDBGridEh;
  aName: array [0..255] of Char;
begin
  case Msg of
    CM_QUERYROW:                      //获取行数
      begin
        Result := -1;
        if P^.DestWnd <> 0 then
        begin
          GetClassName(P^.DestWnd, aName, 256);
          if string(aName) = 'TDBGridEh' then MessageBeep(MB_OK);
          DG := Pointer(MyFindControl(P^.DestWnd));
          if DG <> nil then Result := DG.RowCount;
        end;
        Exit;
      end;
    CM_QUERYCOL:                              //获取列数
      begin
        Result := -1;
        if P^.DestWnd <> 0 then
        begin
          GetClassName(P^.DestWnd, aName, 256);
          if string(aName) = 'TDBGridEh' then MessageBeep(MB_OK);
          DG := Pointer(MyFindControl(P^.DestWnd));
          if DG <> nil then Result := DG.Columns.Count;
        end;
        Exit;
      end;
    CM_HOOKCELL:                                //获取内容
      begin
        DG := Pointer(MyFindControl(P^.DestWnd));
        if DG <> nil then MessageBeep(MB_OK);
        Exit;
      end;
  end;
  Result := DefWindowProc(hwnd, Msg, WParam, LParam);
end;

出10入23汤圆

 楼主| 发表于 2016-9-3 21:57:36 | 显示全部楼层
GetClassName(P^.DestWnd, aName, 256);
          if string(aName) = 'TDBGridEh' then MessageBeep(MB_OK);
这个Beep响了

出10入23汤圆

 楼主| 发表于 2016-9-3 21:58:26 | 显示全部楼层
还没有尝试过换为PostMessage

出0入0汤圆

发表于 2016-9-3 22:12:52 | 显示全部楼层
试试findwindow   enumchildwindows sendmessage 这个组合

出0入70汤圆

发表于 2016-9-3 23:51:04 | 显示全部楼层
zouzhichao 发表于 2016-9-3 21:58
还没有尝试过换为PostMessage

还有, 你DLL里的TDBGRIDEH 版本, 最好和 目标软件的TDGGRIDEH版本一样

出10入23汤圆

 楼主| 发表于 2016-9-3 23:57:34 | 显示全部楼层
SkyGz 发表于 2016-9-3 23:51
还有, 你DLL里的TDBGRIDEH 版本, 最好和 目标软件的TDGGRIDEH版本一样

问题是我现在不知道目标软件的控件版本
有什么办法没?除了一个一个版本试

出0入70汤圆

发表于 2016-9-4 00:52:37 | 显示全部楼层
zouzhichao 发表于 2016-9-3 23:57
问题是我现在不知道目标软件的控件版本
有什么办法没?除了一个一个版本试 ...

有壳就脱.....没就 提取窗口资源数据等信息找
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-9-16 10:16

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表