自己写的程序如何执行其它人写的DELPHI程序TOOLBAR上面的按钮事件

wmajia 2016-03-19 11:30:29
普通的BUTTON通过SPY++可以找到柄,然后通过SendMessage发一个鼠标单击事件就可以了

但TOOLBAR通过SPY++,只能定位到整个TToolbar,这个上面有好多个BUTTON用SPY++是没办法区分到的。

也就没办法通过SendMessage搞定了。求大神支招。


另外看了一篇文章很受启发(http://blog.csdn.net/flyfish1986/article/details/6211026)

用CreateRemoteThread执行别人程序中的代码,DELPHI程序按钮的响应函数用DeDe工具很容易定位到!

但有个地方搞不定的是,Delphi的按钮事件,我印象中至少有个TObjecct参数,用CreateRemoteThread执行这个响应函数,没办法正确传入这个参数。不知道有没有哪位研究过。


...全文
1117 10 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
传入的self是调用事件处理过程的对象实例,具体实现就是对象实例的内存地址(指针),理论上是可能每次程序运行都不同的,因为windows加载exe可以到不同的起始地址,而不必依照pe头的image base,但实际上不需要考虑,这种情况几乎不会出现。
wmajia 2016-03-22
  • 打赏
  • 举报
回复
谢谢, ollydbg曾经经常用,基本调试和反向跟踪还有些印象。如果按你的意思,那就是说,在执行这个线程时,只要让EAX是正确的值就可以了。 这地方有个问题,就是DELPHI程序每次关闭再重启,这个EAX中的值应该是不同的。既然是类似外挂,总不可能每次加载调试器吧?
引用 3 楼 DelphiGuy 的回复:
不是TObject,是self,触发事件的object实例。 获取这个实例也不复杂,既然“DELPHI程序按钮的响应函数用DeDe工具很容易定位到”,那把exe中该事件处理函数的第一字节改成0xcc(int 3),然后用调试器加载此exe,运行,点那个按钮,会断点在事件处理函数,此时的eax就是self。
wmajia 2016-03-22
  • 打赏
  • 举报
回复
十分感谢你在这个问题上的帮助! 函数入口点地址,我是用的一个DELPHI反编译工具,功能比较强大 ,你可以在看雪论坛下载,对DELPHI程序还是有些价值的(http://tools.pediy.com/windows/Decompilers/Delphi/DeDe/DeDeDark.rar)。 从调试来看,应该是函数入口点。有可能是你说的第二种。我再跟踪一下。是个期货交易程序,我只是想借这个程序获取得前面一段时间的历史价格。然后放进自己写的程序里面,进行一个价格运算。这个BOOLBAR上面的按钮,是刷新功能。
引用 9 楼 DelphiGuy 的回复:
动态创建并不代表在内存中的地址不固定,只要创建时机是确定的,比如程序启动时按顺序自动创建的组件,而不是在运行时随机创建,那么创建的对象实例的存地址就是固定的(相对于image base)。我写了个小程序测试了一下,空form上面放一个toolbar,toolbar上new出个button,双击button添加点击事件,在里面写上:asm int 3 end; 编译生成exe,用调试器加载运行,点按钮进入断点,就我的测试,每次运行产生的对象实例(eax)都是一样的。 至于你测试的结果“这个EAX值是变的”,我估计要么是你断点的位置不对,要么这个toolbar是位于某个动态创建的form上,而不是自动创建的form上。
  • 打赏
  • 举报
回复
引用 8 楼 wmajia 的回复:
试了一下,这个EAX值是变的,程序关闭重启是变的。DELPHI应该是动态创建BUTTON,每个BUTTON没有固定的CTRLID,这点跟VC写的程序也不一样,VC程序每个控件有唯一的CTRLID. 如果是动态创建实例,那地址肯定是不一样的,这个跟EXE加载的IMAGE BASE还是有区别IMAGE BASE一般保证程序的SECTION加载到基于IMAGE BASE的一个固定地址。而动态NEW出来的实例,在内存中地址肯定是不同的。
引用 5 楼 DelphiGuy 的回复:
传入的self是调用事件处理过程的对象实例,具体实现就是对象实例的内存地址(指针),理论上是可能每次程序运行都不同的,因为windows加载exe可以到不同的起始地址,而不必依照pe头的image base,但实际上不需要考虑,这种情况几乎不会出现。
动态创建并不代表在内存中的地址不固定,只要创建时机是确定的,比如程序启动时按顺序自动创建的组件,而不是在运行时随机创建,那么创建的对象实例的存地址就是固定的(相对于image base)。我写了个小程序测试了一下,空form上面放一个toolbar,toolbar上new出个button,双击button添加点击事件,在里面写上:asm int 3 end; 编译生成exe,用调试器加载运行,点按钮进入断点,就我的测试,每次运行产生的对象实例(eax)都是一样的。 至于你测试的结果“这个EAX值是变的”,我估计要么是你断点的位置不对,要么这个toolbar是位于某个动态创建的form上,而不是自动创建的form上。
wmajia 2016-03-22
  • 打赏
  • 举报
回复
试了一下,这个EAX值是变的,程序关闭重启是变的。DELPHI应该是动态创建BUTTON,每个BUTTON没有固定的CTRLID,这点跟VC写的程序也不一样,VC程序每个控件有唯一的CTRLID. 如果是动态创建实例,那地址肯定是不一样的,这个跟EXE加载的IMAGE BASE还是有区别IMAGE BASE一般保证程序的SECTION加载到基于IMAGE BASE的一个固定地址。而动态NEW出来的实例,在内存中地址肯定是不同的。
引用 5 楼 DelphiGuy 的回复:
传入的self是调用事件处理过程的对象实例,具体实现就是对象实例的内存地址(指针),理论上是可能每次程序运行都不同的,因为windows加载exe可以到不同的起始地址,而不必依照pe头的image base,但实际上不需要考虑,这种情况几乎不会出现。
Playmaster 2016-03-22
  • 打赏
  • 举报
回复
Toolbar上的button不是普通的button,一般都是speedbutton,一个TGraphic派生的控件, 本质上不是窗口,也没有窗口句柄。
  • 打赏
  • 举报
回复
不是TObject,是self,触发事件的object实例。 获取这个实例也不复杂,既然“DELPHI程序按钮的响应函数用DeDe工具很容易定位到”,那把exe中该事件处理函数的第一字节改成0xcc(int 3),然后用调试器加载此exe,运行,点那个按钮,会断点在事件处理函数,此时的eax就是self。
wmajia 2016-03-20
  • 打赏
  • 举报
回复
这两个都是我说的办法啊,第一个,事件在内存中的地址,那个地址,堆栈中有参数,TObject 第二个,鼠标移到位置,这个位置程序位置会变,而且必须要求程序不能最小化,SENDMESSAGE的话,只要找到句柄,程序最小话,也是可以运行CLICK事件。
引用 1 楼 lyhoo163 的回复:
两种方式: 1、找到该EXE文件执行后,事件在内存的地址。直接从该地址处运行。 2、编程做个程序: (1)鼠标移到该位置 (2)模拟鼠标点击事件。 具体代码 ,自己做吧。
lyhoo163 2016-03-20
  • 打赏
  • 举报
回复
两种方式: 1、找到该EXE文件执行后,事件在内存的地址。直接从该地址处运行。 2、编程做个程序: (1)鼠标移到该位置 (2)模拟鼠标点击事件。 具体代码 ,自己做吧。

1,183

社区成员

发帖
与我相关
我的任务
社区描述
Delphi Windows SDK/API
社区管理员
  • Windows SDK/API社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧