What's new

Welcome to HvH Forum!

SignUp Now! Download Free HvH CS2/CS:GO Cheats, CFG, LUA/JS Scripts, And More!


SignUp Now!

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

Rookie HvHer
User ID
138768
Messages
3
Reactions
15
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" );


0a52b36a-0078-4254-a694-464705c0c425

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.

f537bf11-e371-4da7-b8d2-c16ec25936d6

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.

8718f384-5f61-4b25-bb24-382d2c30e61d

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?

3650b0e4-0f2a-4390-bd23-e91b71ab30f4

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.

72af1523-674f-4d65-b57f-969e983a2c5d

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.

5f85667c-6d4a-4e82-91eb-4699390d7b43

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 :).

d7ad1780-bbd4-4469-b03f-d79321d2e385

Figure 7. In action.


e466a197-1039-46c5-bdee-6f5fad24e198

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.

Top