Forum > General

[SOLVED] Obtain VMT pointer without instance

(1/2) > >>

Khrys:
Is it possible to find the virtual method table of a type without having to create an instance first (needed for  TypeOf)? The only workaround I can think of is hackily relying on assembler symbols:


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---var  VMT_TOBJECT: Pointer; external name 'VMT_$SYSTEM_$$_TOBJECT$indirect';

Thaddy:
Well, yes and no: the VMT is a relative offset so it really depends on an instance to where it really is. But the VMT offset itself is known. (0)
https://www.freepascal.org/docs-html/prog/progsu166.html
It does not need hackery.
TypeOf may not fail if a class is never used. That is because it uses typeinfo and that is guaranteed.

Khrys:
Just found out that  TObject.ClassType() does the trick for me. I was wondering if it's possible to override a virtual method at runtime:


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---type  TFoo = class(TObject)    function ToString(): String; override;  end; function TFoo.ToString(): String;begin  Result := 'Bar';end; procedure Test();var  Instance: TObject;begin  Instance := TObject.Create();  PPVMT(Instance)^ := PVMT(TFoo.ClassType());  WriteLn(Instance.ToString()); // Prints "Bar"  Instance.Free();end;

marcov:
You can also try to duplicate the VMT but modify it.

It is all possible but dangerous, and shouldn't be done run of the mill. The classic exception is (in Delphi) when you got some code/component only in binary form.

In later versions Delphi got a way to streamline that a bit using http://docwiki.embarcadero.com/CodeExamples/Athens/en/TVirtualMethodInterceptor_(Delphi)

http://blog.barrkel.com/2010/09/virtual-method-interception.html

Afaik there has been some study to implement them in FPC in the last, say two years, but afaik it is not there yet.

Martin_fr:

--- Quote from: marcov on July 25, 2024, 12:05:27 pm ---You can also try to duplicate the VMT but modify it.

It is all possible but dangerous, and shouldn't be done run of the mill.

--- End quote ---

There will be a few problems you may run into...

As Marcov said, copy before modify. Depending on Target platform the original class may or may not be in read only memory. So you may or may not get an access violation when you try to change the pointer to a virtual method.

But even if you copy, and then modify, you will hit issue
* inherited:  inherited calls are often de virtualized. So the will call the parent class directly, bypassing the VMT. Changes in the VMT wont work.
* Apps compiled with WPO => more calls can be de virtualized....
* not sure about current compiler, but future versions may be smarter, and do more de-virtualization...
* future FPC version could remove unused entries from the VMT, so make sure not to rely on them being present.
* ...

Navigation

[0] Message Index

[#] Next page

Go to full version