获取到其它进程的TVirtualStringTree对象,但无法读取其数据

时间:2021-07-02 14:36:02
Delphi 7

目标应用主程序 App.exe ,而 TVirtualStringTree 对象由目标应用的一个ad.dll生成,大概类似Addin插件的方式吧, TVirtualStringTree 对象里是类似表格一样的数据,大概跟DBGRID一样的。

我使用Hook的方式,建立一个 hook.dll ,注入到目标应用,获得了 TVirtualStringTree 控件实例,可以获取到它的 height,width 信息,但是要运行它的方法或过程,比如SelectAll,SetFocus,GetFirst等方法时就会出现 Access violation as address 00470947 in module 'hook.dll' ,read of address 808B000A 的错误,然后目标应用就会死掉。

如果目标应用更改为自己写的一个程序 my.exe,TVirtualStringTree 对象直接由  my.exe 生成而不是使用dll,那么在hook进去获得 TVirtualStringTree 控件实例之后,调用它的属性、方法都正常运行,得到想要的结果。


请问这个错误是怎么回事?取得该对象后如何能够正确运行该对象方法?

7 个解决方案

#1


这个问题,是否会跟 TVirtualStringTree  的版本有关?我自己安装了一个4.7的版本,但我不知道目标应用使用什么版本。

还请大侠们确认一下,是否与版本有关,免得我在版本处理上浪费时间。

#2


尝试了一下,使用不同的版本 TVirtualStringTree  来编译的程序(即hook.dll和被hook的目标应用分别使用不同版本的TVirtualStringTree 环境来编译),确实会产生 Access violation 错误,百试不爽,看来问题基本可以定位在控件版本上了。

也难怪,控件源码里增加个成员或方法,生成的对象内存布局就不一样了,还是同样的方法,地址就极可能会有不同的偏移量,那样就出ccess violation 错误了。当然,类似high,width之类的属性,因为是父类就定义好的东西,对象内存布局中还是相同的,所以没有出错,但其它属于 TVirtualStringTree 本身的属性就不一定了。

有谁知道是否有获得对象的类的版本信息的方法吗?也不知道有没有类似“版本信息”这个属性,可以查看到控件类的版本。

#3


刚才看了一下,vt是通过一个全局常量定义版本号的。。。。。。。。。。
可能只能看dll里的vt具备的方法来确定是哪个版本了

#4


引用 3 楼 sz_haitao 的回复:
刚才看了一下,vt是通过一个全局常量定义版本号的。。。。。。。。。。
 可能只能看dll里的vt具备的方法来确定是哪个版本了


能提供个详细点的思路吗?要用RTTI,还是.....?

#5


Mark.

#6


引用 4 楼 qinjs 的回复:
引用 3 楼 sz_haitao 的回复:
刚才看了一下,vt是通过一个全局常量定义版本号的。。。。。。。。。。
可能只能看dll里的vt具备的方法来确定是哪个版本了


能提供个详细点的思路吗?要用RTTI,还是.....?


根据vt的版本历史说明,得到一些某版本后才有的方法,试着调用一下,支持则说明是某个版本以后的
不执行直接看,不知道dll能否列出它的类的方法。。。。。。。。dll自己使用过的方法,应该不会被优化掉

#7


如果新版本,在方法的写代码时的位置、或者实现体、或者其父类(TVirtualStringTree 是 vt的子类)的方法数目有变化,那么即使子类的方法名与参数不变,是不是调用同样的方法也会出现这样的问题?

#1


这个问题,是否会跟 TVirtualStringTree  的版本有关?我自己安装了一个4.7的版本,但我不知道目标应用使用什么版本。

还请大侠们确认一下,是否与版本有关,免得我在版本处理上浪费时间。

#2


尝试了一下,使用不同的版本 TVirtualStringTree  来编译的程序(即hook.dll和被hook的目标应用分别使用不同版本的TVirtualStringTree 环境来编译),确实会产生 Access violation 错误,百试不爽,看来问题基本可以定位在控件版本上了。

也难怪,控件源码里增加个成员或方法,生成的对象内存布局就不一样了,还是同样的方法,地址就极可能会有不同的偏移量,那样就出ccess violation 错误了。当然,类似high,width之类的属性,因为是父类就定义好的东西,对象内存布局中还是相同的,所以没有出错,但其它属于 TVirtualStringTree 本身的属性就不一定了。

有谁知道是否有获得对象的类的版本信息的方法吗?也不知道有没有类似“版本信息”这个属性,可以查看到控件类的版本。

#3


刚才看了一下,vt是通过一个全局常量定义版本号的。。。。。。。。。。
可能只能看dll里的vt具备的方法来确定是哪个版本了

#4


引用 3 楼 sz_haitao 的回复:
刚才看了一下,vt是通过一个全局常量定义版本号的。。。。。。。。。。
 可能只能看dll里的vt具备的方法来确定是哪个版本了


能提供个详细点的思路吗?要用RTTI,还是.....?

#5


Mark.

#6


引用 4 楼 qinjs 的回复:
引用 3 楼 sz_haitao 的回复:
刚才看了一下,vt是通过一个全局常量定义版本号的。。。。。。。。。。
可能只能看dll里的vt具备的方法来确定是哪个版本了


能提供个详细点的思路吗?要用RTTI,还是.....?


根据vt的版本历史说明,得到一些某版本后才有的方法,试着调用一下,支持则说明是某个版本以后的
不执行直接看,不知道dll能否列出它的类的方法。。。。。。。。dll自己使用过的方法,应该不会被优化掉

#7


如果新版本,在方法的写代码时的位置、或者实现体、或者其父类(TVirtualStringTree 是 vt的子类)的方法数目有变化,那么即使子类的方法名与参数不变,是不是调用同样的方法也会出现这样的问题?