我们知道,Obj.ClassName是一个函数而不是一个属性,而该函数的代码是:
class function TObject.ClassName: ShortString;
begin
Result := PShortString(PPointer(Integer(Self) + vmtClassName)^)^;
end;
对应的汇编代码优化之后非常简单:
mov ebx,eax
mov eax,[ebx]
mov ebx,[eax-2C]
这里假设对象指针存放在eax寄存器中。
这样在OD中招ClassName就很方便了:在eax寄存器上右键,选择数据窗口中跟随,此时的数据窗口的第一行一列就是eax的内容,用鼠标拖动选中四个字节的内容(例如B0 55 40 00),右键,选择数据窗口中跟随,我们得到此时数据窗口中第一行的地址是004055B0,拿这个地址减去2C,我们得到405584,还是在数据窗口中,按下ctrl+g,输入0405584,此时数据窗口中的第一行第一列显示的就是405584地址处的内容,选择这四个字节,右键,选择数据窗口中跟随,就可以找到ClassName了!
其实004055B0-2C是在004055B0的上面第三行第二列,拖动一下鼠标也可以到达。