X
X
xomachine2017-12-23 20:38:43
C++ / C#
xomachine, 2017-12-23 20:38:43

Is it possible to find out the signature of a virtual method from runtime?

There is a project to replace the MSVC calling conventions with GCC for the steam API. The substitution itself is successfully implemented by WINE, but requires steam API header files for this.
Everything would be fine, but the steam API is constantly changing and old applications from Steam use old versions (they ask steamclient.{so, dll} for the correct version) of the API. There is no access to header files for older versions of the API.
That was the preface, and now directly to the problem
According to the thiscall calling convention in MSVC, the arguments of the called method are pushed on the stack, and the called method must remove them from the stack before returning control.
In a similar situation, GCC leaves the responsibility of removing arguments from the stack to the calling code.
(more)
(and more details on the example of stdcall and cdecl)
Thus, if I want to wrap the call, I need to clear the stack from the method arguments in the interlayer between the MSVC and GCC code (and perform a few more operations, but this is already easier), and for this you need to know the signature method. And, as I already noted in the preface, I don’t know it for older versions of the steam API.
Accordingly, the question is: is it possible at the runtime level to find out how many arguments were placed on the stack before calling the virtual method (by the type of the stack, by the virtual table of the object or other information available at runtime)?
Or in another wording: How not to confuse a method argument on the stack with a local variable from top-level code?

Answer the question

In order to leave comments, you need to log in

2 answer(s)
X
xomachine, 2018-01-05
@xomachine

He asked himself, he found a solution (albeit not a universal one) It is
possible with a high degree of probability to successfully calculate the method signature by the depth of the stack to which the instructions refer. To do this, you need to disassemble the method and track the registers associated with the stack.
A working prototype of the tracking procedure for my case can be found here . The prototype is written in Nim using libopcode and libbfd from the binutils package, which is included with most Linux distributions.
In the screenshot, the result of such guessing the number of method arguments (CAdapterSteamClient017, on the right) and (on the left) a piece of the source code corresponding to this class. (I hope Valve doesn't ban me for posting a screenshot with a small piece of source code)
As you can see from the screenshot, the predicted number of arguments corresponds to the real one.
5a4e980def378215372175.png

J
jcmvbkbc, 2017-12-24
@jcmvbkbc

Is it possible at the runtime level to find out how many arguments were placed on the stack before calling the virtual method (by the type of the stack, by the virtual table of the object or other information available at runtime)?

Traditionally, in C++, the types of function parameters are encoded by the compiler in its name .

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question