麻烦的问题,我也不知道啊。。。如何通过虚拟函数表找到一个函数的位置???(300分)

  • 主题发起人 张无忌
  • 开始时间

张无忌

Unregistered / Unconfirmed
GUEST, unregistred user!
TBaseEvent = procedure of object;

TBase = class
private
protected
public
procedure ShowMessage
virtual;
constructor Create;
destructor Destroy
override;
end;

TClassA = class(TBase)
private
protected
public
procedure ShowMessage
override;
procedure Show
virtual;
procedure AfterConstruction
override;
constructor Create;
destructor Destroy
override;
end;

TClassB = class(TBase)
private
protected
public
procedure ShowMessage
override;
procedure Show
virtual;
constructor Create;
destructor Destroy
override;
end;

{ TBase }

constructor TBase.Create;
begin
Form1.ListBox1.Items.add('Base Create...');
end;

destructor TBase.Destroy;
begin
Form1.ListBox1.Items.add('Base Destroy...');
inherited Destroy;
end;

procedure TBase.ShowMessage;
begin
beep();
end;

{ TClassB }

constructor TClassB.Create;
begin
Form1.ListBox1.Items.add('TClassB Create...');
end;

destructor TClassB.Destroy;
begin
Form1.ListBox1.Items.add('TClassB Destroy...');
inherited Destroy;
end;

procedure TClassB.Show;
begin
beep();
end;

procedure TClassB.ShowMessage;
begin
beep();
end;

{ TClassA }

procedure TClassA.AfterConstruction;
begin
inherited;

end;

constructor TClassA.Create;
begin
Form1.ListBox1.Items.add('TClassA Create...');
inherited Create;
end;

destructor TClassA.Destroy;
begin
Form1.ListBox1.Items.add('TClassA Destroy...');
inherited Destroy;
end;

procedure TClassA.Show;
begin
beep();
end;

procedure TClassA.ShowMessage;
begin
beep();
inherited Destroy;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
a: TClassA;
Func: TBaseEvent;
FuncD, FuncE: integer;
begin
a := TClassA.Create;
try
Func := a.AfterConstruction;
FuncD := PInteger(PInteger(a)^)^
//这是ShowMessage 的地址
FuncE := PInteger(PInteger(a)^+4)^
//这是Show函数的地址,那AfterConstruction的地址在?
ListBox1.Items.Add(Format('A Size:%D',[a.InstanceSize]));
ListBox1.Items.Add(Format('Func Addr:%d,Base Addr:%d,All Get:%d', [Integer(@Func), FuncE, FuncD]));
finally
a.Free;
end;
 

来如风

Unregistered / Unconfirmed
GUEST, unregistred user!

张无忌

Unregistered / Unconfirmed
GUEST, unregistred user!
现在的问题是show函数和showmessage函数的地址我都可以通过虚拟函数表找到
但是AfterConstruction的地址就是无法找到
 

来如风

Unregistered / Unconfirmed
GUEST, unregistred user!
show函数和showmessage函数的地址 s 怎么找到的啊?我以前到没有找过这些东西
 
L

liuxi

Unregistered / Unconfirmed
GUEST, unregistred user!
TObject的虚方法都放在VMT的负方向上了
你要的东东在VMT偏移地址为-28的地方
 
D

dedema

Unregistered / Unconfirmed
GUEST, unregistred user!
PFun是函数指针.
a 是对象.
PFun(PInteger(PInteger(a)^)^+n)//n是要找的虚拟方法在用户自定义的虚拟方法表中的
次序乘以4
 

张无忌

Unregistered / Unconfirmed
GUEST, unregistred user!
Func := a.show;
FuncD := PInteger(PInteger(a)^)^
//这是ShowMessage 的地址
FuncE := PInteger(PInteger(a)^+4)^
//这是Show函数的地址,那AfterConstruction的地址在?
FuncE 是等于Integer(@Func)的
如果Func:=a.showmessage;
那么Integer(@func)是等于funcD的,
 

张无忌

Unregistered / Unconfirmed
GUEST, unregistred user!
我刚才修改了一下,这样就很直观了, liuxi的答案是对的,我也自己找到了,
这玩意麻烦的了
var
a: TClassA;
Func,FunB: TBaseEvent;
FuncD, FuncE: integer;
intVMT,tEmp:integer;
i:integer;
begin
a := TClassA.Create;
try
Func := a.AfterConstruction;
FunB:=a.BeforeDestruction;
intVMT:=PInteger(a)^;
tEmp:=intVMT;
FuncD := PInteger(PInteger(a)^)^
//这是ShowMessage 的地址
FuncE := PInteger(PInteger(a)^)^
//这是Show函数的地址,那AfterConstruction的地址在?

for i:= 0 to 12 do
begin

ListBox1.Items.Add(Format(' %d',[Pinteger(intVMT)^]));
Dec(intVMT,4);
end;

ListBox1.Items.add('==========================');
for i:= 0 to 12 do
begin

ListBox1.Items.Add(Format(' %d',[Pinteger(tEmp)^]));
Inc(tEmp,4);
end;


ListBox1.Items.Add(Format('A Size:%D',[integer(@FunB)]));
ListBox1.Items.Add(Format('Func Addr:%d', [Integer(@Func)]));
finally
a.Free;
end;
 

张无忌

Unregistered / Unconfirmed
GUEST, unregistred user!
谢谢liuxi 给出正确答案!
 
顶部