понедельник, 16 февраля 2009 г.

For russian fellow Maaacheba or getting method name dynamically

It is still a draft implementation,
but it can be extended for other x86 opcodes.
So it is a base idea.
And it can be extended to support dynamic methods invocation.

TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
Published
procedure StaticMethod;
procedure VirtualMethod(a,b,c,d:integer);virtual;
end;

THelper= class helper for Tobject
function GetMethodAddress:pointer;
end;


implementation

type
PPDWORD=^PDWORD;

function AnalizeCallMethod(Self:PPDWORD;ReturnAddress:pbyte;SomePlaceInTheMethodCode:pointer):DWORD;
var Operation:DWORD;
VMT:PDWORD;
Offset:Integer;
begin
{$POINTERMATH ON}
//Virtual Call
Operation:=DWORD((@ReturnAddress[-6])^) AND $FF;
case Operation of
$FF:
begin
VMT:=Self[0];
Offset:=DWORD((@ReturnAddress[-4])^);
result:=DWORD((@(Pbyte(VMT)[Offset]))^);
exit;
end;
end;
Operation:=DWORD((@ReturnAddress[-5])^) AND $E8;
//Static Call
case Operation of
$E8:
begin
result:=DWORD(ReturnAddress)+DWORD((@ReturnAddress[-4])^);
exit;
end;
end;
{$POINTERMATH OFF}
end;

{ THelper }

function THelper.GetMethodAddress: pointer;
asm
mov edx,[ebp+04];
mov ecx,[esp];
Call AnalizeCallMethod;
end;

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
StaticMethod;
VirtualMethod(1,2,3,4);
end;

procedure TForm1.StaticMethod;
begin
showmessage(MethodName(GetMethodAddress));
end;

procedure TForm1.VirtualMethod(a,b,c,d:integer);
begin
showmessage(MethodName(GetMethodAddress));
end;