This is a mobile optimized page that loads fast, if you want to load the real page, click this text.

Miscellaneous Core Logic Beginner Source Engine Getting VFTs from RTTI with only classnames

Rookie HvHer
User ID
138768
Messages
3
Reactions
14
Level
2
A while ago I stumbled upon an uc thread while I was working on a Half-Life 2 trainer, browsing for clues how virtual function tables work. I had a basic understanding of them before, but wanted to dive a bit deeper. I found Hinnie's thread from ~2020ish iirc, about a RTTI Virtual Function Table scanner.

And honestly, getting a VFT like this looks very nice:
const auto cmodelrender_vftable = utils::get_vftable( "engine.dll", "CModelRender" );



Figure 1. A long long time ago.


Since I was keen to try and figure it out myself, the only thing I took from Hinnie's thread was how RTTI mangles the classnames.


Figure 2. This helped (from ).


Also, I recommend you check out reading links before continuing with the post, and have them open in parallel afterwards.

They will give you a quick understanding of what we're doing here.

So, let's start.

When we search for a classname in the strings of a module (when the class vft exists), we can find this.


Figure 3. Searching for `CEngineClient`.


RTTI stores a funny string in the format of ".?AV{classname}@@".
(Since it's a string, we can search for it in the module but that will come in handy later)

What if we follow the string in IDA?


Figure 4. Following the mangled classname string.


We find the class's type_info object. From the ROP blog, we can recall that the Complete Object Locator stores a pointer to the type descriptor.


Figure 5. COL Structure.


Now let's try to find the COL of CEngineClient in IDA. We can do this by searching for xrefs for the typeinfo object. We can find this.


Figure 6. CEngineClient COL.


So, what can we note? COL starts off with a signature (ROL blog mentions this), then follows up with a offset in class, an offset to base class, a pointer to type info. So something like this.

COL Structure:
00 00 00 00   - signature
?? ?? ?? ??   - offset
?? ?? ?? ??   - offset to base class, if inherited
Dd Cc Bb Aa   - ptr to type info (le)

If we find the COL, we can find the vftable, since the vftable starts with a reference to the COL, pretty simple .


Figure 7. In action.



Figure 8. Offset in IDA.


And do they match? Yes! (check for the "col ref" log line, offset).

I hope this helps, frank out.



Oh also, a question for the reader

What if there are multiple COLs matching the pattern? (it is possible)
Look at the COL structure to see what differs on multiple matches.
 

Create an account or login to comment

You must be a member in order to leave a comment

Create account

Create an account on our community. It's easy!

Log in

Already have an account? Log in here.