Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi:如何获取事件变量的地址?_Delphi_Debugging_Delphi 5_Disassembly - Fatal编程技术网

Delphi:如何获取事件变量的地址?

Delphi:如何获取事件变量的地址?,delphi,debugging,delphi-5,disassembly,Delphi,Debugging,Delphi 5,Disassembly,如何获取包含事件处理程序的变量的地址 e、 g 我想要FOnChange私有成员、事件处理程序、变量的地址 为什么? 我试图找出谁在用垃圾覆盖我的FOnChange处理程序变量 我正在逐步执行代码: if Assigned(FOnChange) then FOnChange(Self); 从未分配任何事件处理程序,并且对于一段时间,FOnChange变量在监视窗口中为nil: @FOnChange: nil Addr(FOnChange): nil 但是后来FOnChange变量变

如何获取包含事件处理程序的变量的地址

e、 g

我想要
FOnChange
私有成员、事件处理程序、变量的地址


为什么? 我试图找出谁在用垃圾覆盖我的
FOnChange
处理程序变量

我正在逐步执行代码:

if Assigned(FOnChange) then
    FOnChange(Self);
从未分配任何事件处理程序,并且对于一段时间
FOnChange
变量在监视窗口中为
nil

@FOnChange: nil
Addr(FOnChange): nil
但是后来
FOnChange
变量变成了垃圾:

@FOnChange: $2C
Addr(FOnChange): $2C
因此,我想在CPU窗口的数据窗格中查看
FOnChange
变量,以便从以下位置查看:

00410018 00000000

除了我不知道
FOnChange
的地址;我刚刚补足了410018美元

如何找到事件变量的地址


我尝试过的事情 观察列表

OnChange: nil
@OnChange: nil
@@OnChange: Variable required
@FOnChange: nil
Assigned(OnChange): False
Assigned(FOnChange): False
@@FOnChange: $253B588
addr(addr(FOnChange)): $253B588
Alt+F5

  • OnChange:
    OnChange:TNotifyEvent$253B588
  • FOnChange:检查“FOnChange”时出错:表达式错误
  • Self.FOnChange:检查“Self.FOnChange”时出错:表达式错误
  • @OnChange
    @OnChange:Pointer$253B588
  • @@OnChange:检查'@@OnChange'时出错:表达式错误
  • @FOnChange
    @FOnChange:Pointer$253B588
  • @@FOnChange
    @@FOnChange:^未键入(无地址)
    数据:@@FOnChange$253B588`
协议似乎位于地址
0x253B588

但是,当我运行一些示例代码时:

MyControl1.OnChange := TheOnChangeHandler;
这就变成了:

mov edx,[ebp+$08]         ;move stack variable $08 into edx
mov [eax+$00000208],edx   ;and then into offset $208 of my control

mov edx,[ebp+$0c]         ;move stack variable $0c into edx
mov [eax+$0000020c],edx   ;and then into offset $20c of my control

难怪我找不到
FOnChange
的地址,这是两个地址

您可以通过调试检查器获取地址。要获取字段的地址,请在更改发生之前的某个时间点(例如,在调用构造函数之后)在代码中放置断点。然后在调试检查器中打开对象。不知道如何在旧的IDE样式中获得它,但是在D2010中,您可以从Run->Inspect。。。菜单命令,从“计算/修改”中的按钮,或通过点击键盘上的ALT-F5。(小心不要按ALT-F4!)


调试检查器将向您显示对象及其所有字段。双击其中一个字段,它将在新的调试检查器窗口中打开。在编辑框中,顶部的条形图将显示字段的地址。您可以使用此设置内存断点以查找值更改的位置。

在Delphi 5中不确定,但您应该能够在AExample.FOnChange上设置数据断点(或地址断点)。

只要值发生变化,它就会断开。

既然你不能使用弗朗索瓦建议的智能解决方案,那么是时候开始破解了!在任何可以放置制动点的地方,编写如下代码:

var X:TExample;
X.OnChange := nil;
; assembler blah blah to get the address of X
xor EDX ; or whatever the compiler finds appropriate this time of day
mov [eax + $00000288], edx
mov [eax + $0000028c], edx
在X.OnChange:=零行上放置制动点;当调试器停在那里时,请查看“反汇编”窗格,您将看到如下内容:

var X:TExample;
X.OnChange := nil;
; assembler blah blah to get the address of X
xor EDX ; or whatever the compiler finds appropriate this time of day
mov [eax + $00000288], edx
mov [eax + $0000028c], edx

你不关心编译器使用的寄存器,你关心的是$288,第一条MOV指令使用的偏移量。这是从“X”地址到FOnChange字段的偏移量。记下来。现在回到你的错误程序,在某个地方设置一个制动点,点击Alt+F5调用调试检查器(如果你没有一个空的编辑框来输入你的查询,点击Ctrl+N),然后写“Integer(MyExampleVariable)”;不管你得到什么,把你在上一步记下的数字加起来,你就得到了MyExampleVariable实例的FOnChange文件的地址,你现在可以设置一个地址制动点。

我不知道它们是否存在于Delphi 5中,但是类型和函数应该会有所帮助

为什么?

我试图找出谁在用垃圾覆盖我的FOnChange处理程序变量

我可以回答这一点-你是!或者您正在查看错误的实例,而该实例没有正确创建?引用不正确?会是这样的。Delphi调试器擅长使一些不存在的东西看起来像它一样,直到


退后一点,试着看看树林而不是树木。我去过你所在的地方很多次了,你可能找错了方向(抱歉,这是双关语),很快就会给自己起各种各样的名字:)

返回
nil
;这很有意义,因为没有分配事件处理程序。在Delphi中也返回nil2010@Ian,@Cosmin:你说得对。我测试了错误的东西。修正了这个问题,并给出了一个实际可行的解释。你正在看X.FOnChange,它似乎保持为零。可能是X被覆盖了,而不是X.FOnChange!我会接受这个答案,即使它不完整。我对
TMethod
记录有一个模糊的记忆(通过
tThemeanager
),其中一个函数实际上是两个指针。事实证明这就是这里发生的事情。您的技术确实可以找到结构开头的地址。但是德尔福确实保守了这个秘密,并且使得追捕变得非常困难。每天都在学习!在Delphi 2010中,这实际上正如预期的那样有效。我也不知道,这是一个很棒的提示。+1来自我,这实际上是解决这个问题的最佳方案。+1来自“这很巧妙”。当然我不想这样做,但我以前从未考虑过!它不是“两个地址”,实际上,它是由两个指针组成的记录。您要查找的地址是记录开头的地址,
[eax+$00000208]
一个。我知道是我;当然是我!当我说谁时,我指的是哪一行代码。每一行源代码都是活的,它是有意识的,而且它试图欺骗我!最后我找到了答案:
FOnChanged
变量o