Virtual functions and detouring - c++

I've been programming with detours lately and all that comes with it. I have detoured a lot of different functions; thiscall, stdcall, cdecl, virtual functions etc. But there is one thing I haven't managed (which might not even be possible), and that is to hook a base class virtual function. For example; there is a Car class which declares a virtual function (empty) Drive. Then there are 3 other car classes which inherits car and implements Drive.
If I hook the Car's (base class) Drive function (using a simple 'jmp' hook) would it be triggered by the descendants of Car, when they trigger Drive, if they do not call the base function?
To explain even more thoroughly:
class Car
{
virtual void Drive(void) { } // Empty virtual function
}
class Lamborghini : public Car
{
void Drive(void) { // does lots of stuff, but does NOT call base function }
}
So I'm wondering whether the base method get's called or if it can be hooked somehow? Does the function exectution jump directly to Lamborghini::Drive or does it somehow pass through the Car class so it's detectable whenever a descendant calls Drive?
EDIT: And if the base class function is empty, is it even possible to hook it, since it requires 5 bytes of space?

No, the base method does not get automagically called. The dynamic dispatch mechanism will detect which override it needs to call and that will be the function that gets called. This is usually implemented by means of a virtual table (vtable) that stores the pointers to the final overriders for each virtual function in a class. When dynamic dispatch is used, the compiler injects an indirect call through that table and jumps to the proper function.
Note that the vtable actually holds pointers to thunks or trampolines that can potentially modify this (implicit first argument) before forwarding the call. The advantage of using this approach is that if this does not need to be updated, the compiler can jump directly into the final overrider. At any rate, you can take advantage of this feature and modify the vtables to point to your own code (i.e. you can update the pointer in each vtable --one per type-- to refer to your own thunk or function)

If I got your question correctly, method Drive in your Lamborghini class will be called based on table of virtual functions. If you want to call a Drive method of a base class, you must write something like Car::Drive;. And base class needs some space because of the VTBL. Hope I've unanswered on your question.

If I understand it right, you want Car::Drive to be called each time Lamborghini::Drive is called, even if Lamborghini:Drive does not call directly the base function ?
For that, the simplest method is to use an 'inner' function, which will be virtual (and protected), whereas the initial method will be non-virtual and will route the call.
Here's an example:
class Car
{
void Drive(void)
{
// ...
Car::innerDrive(); // Base function call
// ...
this->innerDrive(); // 'Derived' function call
// ...
}
protected:
virtual void innerDrive(void) { } // Empty virtual function
}
class Lamborghini : public Car
{
protected:
void innerDrive(void) { // does lots of stuff, but does NOT call base function }
}

Related

Pure virtual function not used in one of the derived classes

I asked a similar question earlier, but deleted it because I couldn't come up with a specific example. I was able to come up with one now. I often find myself designing codes such that virtual functions are only useful in some, but not all, of the subclasses.
Here is an example of a base class travel that is inherited by driving and flying. travel has a compute_travel_info() function that computes the velocity and altitude. The former is relevant for both driving and flying, but the latter is only relevant for flying.
In this design, driving::compute_altitude() does nothing, but we must define it because the function is pure virtual (I could alternatively made it a virtual function in travel and defined it, and then not override it in driving). Also, ideally, I wouldn't even want to call the compute_altitude() function in compute_travel_info if it was operating on a driving object, so the code can appear to be misleading the way it is written.
Is what I did considered to be bad practice? Is it frowned on to have a virtual function that is useless in one of the subclasses and to call the virtual function that isn't used in some of the subclasses?
Note that this is just a particular example, and ideally, I'd like an answer that applies generically, and not just to the specific example provided. In other words, I don't want readers to be too fixated on this example
class travel
{
public:
//function for representing the state in bits
void compute_travel_info()
{
compute_velocity();
compute_altitude();
}
private:
double velocity;
virtual void compute_velocity() = 0;
virtual void compute_altitude() = 0;
};
class flying : domain
{
void compute_velocity()
{
//compute the velocity
}
void compute_altitude()
{
//compute the altitude
}
};
class driving : travel
{
void compute_velocity()
{
//compute the velocity
}
void compute_altitude()
{
//do nothing (assume car is driving on a flat earth where altitude doesn't change)
}
};
Clearly compute_altitude is not supposed to be part of your virtual interface since calling it through a base pointer is not guaranteed to do anything reasonable if it is implemented as stub in the derived class.
However, compute_travel_info does seem to be part of the virtual interface that should always be callable through a base pointer.
Therefore compute_travel_info should be (pure) virtual and implemented in all derived classes. Some of these derived classes may have a compute_altitude function that is called and some might not, but that shouldn't matter to the base class. The base class should not have a compute_altitude function at all.
You can provide a default implementation for compute_travel_info in the base class which is only overridden when needed.
You can also call the base class implementation of compute_travel_info in the derived class with a qualified name (e.g. this->travel::compute_travel_info()) if you need to just add some additional work to it.
Or you can move the common behavior into another base class function that is called by the compute_travel_info implementations in the derived classes.
You could add an override of the function compute_travel_info in flying.
In this redefined function you can call back to the function of the parent class which would only hold the compute_velocity function and then call the compute_altitude function only in the overridden function.

Function resolution from vtable in C++

I have a confusion regarding vtable after reading more about name mangling.
for ex:
class Base
{
public:
virtual void print()
{
}
};
class A : public Base
{
public:
void hello()
{
....
}
void print()
{
}
};
A obj;
obj.hello();
Base* test = new A();
test->print();
As per my understanding after the name manging obj.hello() call will be converted to something like _ZASDhellov(&obj) now
how this virtual functions will be invoked from vtable?
my wild guess test->__vtable[_ZASDprintv](&test(dynamic cast to derived???)) is correct?
How the function names are resolved from vtable?
Firstly, vtables are not in any way part of the C++ language, but rather an implementation detail used by particular compilers. Below I describe one way it is commonly used as such.
Second, your function hello is not virtual. To make it virtual, you would simply pre-pend virtual to the declaration.
Assuming it is now virtual: Your guess is quite close. In fact, the vtable (to which a pointer is stored with every instance of a virtual class) is an array of function pointers. The way that a particular function is looked up in it is by its ordinal. The first declared virtual function in A is the first entry in its vtable, the second one is the second entry and so on. If A had a base class, the index of A's first (non-override) virtual function in the table would be n+1, where n is the index of the last virtual function of its base class. If A has more than one base class, their entries precede A's entries in order of their declaration as base classes of A.
If A uses virtual inheritance, the picture is a bit more complicated than that, I won't elaborate unless you're specifically interested.
UPDATE: I'll add a very brief description for the virtual inheritance case as requested. If A had Base as a virtual base class, A's vtable would store at the very beginning (before the function addresses) the byte offset of where Base's data starts within the A object. This is necessary because, unlike in normal inheritance, a base class does not have its data precede the derived class's data - instead it follows it. So in effect, any function call to a virtual function defined in Base has to have its this pointer offset by that amount. Additionally, Base would have to have its own vtable pointer, right at the beginning of its data where it expects to find it. Thus the full A object would contain two vtable pointers instead of one. The actual vtable pointed to by this second pointer would be the same one as the first vtable pointer, except advanced to skip the offset entry described above (so that any Base code using the vtable would find the first virtual function at the beginning where it is expected). Apart from these differences, the vtable itself is the same as before.

Calling Pure Virtual Function From Abstract Base Class Member Function?

So, based on a cursory search, I already know that calling a virtual function (pure or otherwise) from a constructor is a no go. I have restructured my code to ensure that I am not doing that. While this causes the user of my classes to add an extra function call in their code, this is really not that big of a deal. Namely, instead of calling the constructor in a loop, they now call the function which (in fact!) increases performance of the code since we don't have the housekeeping of building and destroying the object in question every time.
However, I have stumbled across something interesting...
In the abstract class I have something like this:
// in AbstractClass.h:
class AbstractClass {
public:
AbstractClass() {}
virtual int Func(); //user can override
protected:
// Func broken up, derived class must define these
virtual int Step1() = 0;
virtual int Step2() = 0;
virtual int Step3() = 0;
// in AbstractClass.cpp:
int AbstractClass::Func() {
Step1();
// Error checking goes here
Step2();
// More error checking...
// etc...
}
Basically, there is a common structure that the pure virtual functions follow most of the time, but if they don't Func() is virtual and allows the derived class to specify the order. However, each step must be implemented in derived classes.
I just wanted to be sure that there's nothing that I necessarily am doing wrong here since the Func() function calls the pure virtual ones. That is, using the base class, if you call StepX(), bad things will happen. However, the class is utilized by creating a derived object and then calling Func() (e.g. MyDerivedObject.Func();) on that derived object, which should have all the pure virtual functions overloaded properly.
Is there anything that I'm missing or doing incorrectly by following this method? Thanks for the help!
Func is calling the virtual ones, not the pure virtual ones. You would have to qualify the calls with a scope operator, i.e. AbstractClass::Step1() to call THAT (virtual pure) function. Since you are not, you will always get an implementation by a derived class.
A virtual function in a base class makes the derived classes able to override it. But it seems things stop there.
But if the base class virtual function is pure, that forces the derived classes to implement the function.
As a side comment you can make the Step1, Step2, Step3 methods private so that you'll be prevented by the compiler from directly calling them.

Why in destructors is the virtual table set back to that level?

Following this question - Pure virtual call in destructor of most derived class - I tried some code to check some syntax and discovered that as sucessive destructors are called, they call their relevant virtual functions. Consider this code:
class Base
{
public:
virtual void Method() = 0;
};
class Derived : public Base
{
public:
~Derived()
{
Method();
}
virtual void Method()
{
cout << "D";
}
};
class DoubleD : public Derived
{
public:
~DoubleD()
{
Method();
}
virtual void Method()
{
cout << "DD";
}
};
int main(array<System::String ^> ^args)
{
DoubleD D;
DoubleD E;
return 0;
}
As expected, as the object gets destructed, it calls the correct method (eg first the most derived and then the the second most derived).
Ouput: DD D
My question is, why does this work? Since you are not meant to call virtual functions in a c'tor/d'tor, why does the virtual table "unwind" correctly.
Eg, I can see why the most derived one works, that was the state the virtual function pointer table was in when this started. But why, when Derived's destructor is called, does the table get correctly set to point at that classes implementation of Method.
Why not just leave it, or if it is being nice, set the value to NULL.
Since you are not meant to call virtual functions in a c'tor/d'tor,
why does the virtual table "unwind" correctly.
The premise is wrong. There's nothing wrong with calling virtual functions from a constructor or destructor, provided you know how they work. As you've seen, the dynamic type is the type of the constructor or destructor being run, so you don't get virtual calls to the parts of the object that haven't yet been constructed or have already been destroyed.
The behaviour is perfectly well defined. You shouldn't worry about how your compiler vendor managed to implement it (though it's not very hard to reason out yourself, or just look up).
It's generally not advised to call virtual functions in the destructor because of the non-intuitive behaviour, but there's nothing fundamentally wrong with it.
This is how it is supposed to work according to the standard.
As for why, after you've run the destructor for a derived class you can't count on any of the properties of that class to be valid or consistent. Calling one of the virtual methods at that point would be a disaster if it went into a derived class method.
It's quite likely that the compiler bypasses the vtable altogether, since it already knows which overridden method applies to the current state of the object. That's just an implementation detail though.
Virtual table doesn't get modified at run time after the initial setup at object creation.
On some implementations, Virtual table shall be created as per class basis.
In your example, when DoubleD object is destroyed, it calls method function in DoubleD class, Because, the DoubleD part of the object is not yet destroyed completely.
VTable of DoubleD class has an entry for method function to point to method in its class as it is overridden(in the last level of inheritance)
Once DoubleD is destroyed, now the object type is of type Derived. So the call has to go to the method in vtable of class Derived. Hence the behavior.

When is it safe to call a virtual function in a constructor

I have some code where I really want to call a virtual method from a constructor. I know this is considered unsafe, and I know enough about object construction to also understand why. I also am not experiencing these problems. Currently my code is working and I think it should be fine, but I want to make sure.
Here is what I am doing:
I have some class hierarchy and there is a normal public function which just forwards to a private virtual method, as usual. However I do want to call this public method upon construction of my objects, because it is filling all data into the object. I will be absolutely sure that this virtual call comes from the leaf class, because using this virtual method from any other part of the class hierarchy simply does not make sense at all.
So in my opinion the object creation should be finished once I am doing the virtual call and everything should be fine. Is there still anything that could go wrong? I guess I'll have to mark this part of the logic with some big comments to explain why this logic should never ever be moved to any of the base clases, even though it looks like it could be moved. But other than stupidity of other programmers I should be fine, shouldn't I?
It is absolutely safe to call any non-abstract virtual function in the constructor or the destructor! However, its behavior may be confusing as it may not do what is expected. While the constructor of a class is executed, the static and dynamic type of the object is the type of the constructor. That is, the virtual function will never be dispatched to the override of a further derived class. Other than that, virtual dispatch actually works: e.g. when calling a virtual function via a base class pointer or reference correctly dispatches to the override in the class being currently constructor or destructed. For example (probably riddled with typos as I currently can't this code):
#include <iostream>
struct A {
virtual ~A() {}
virtual void f() { std::cout << "A::f()\n"; }
void g() { this->f(); }
};
struct B: A {
B() { this->g(); } // this prints 'B::f()'
void f() { std::cout << "B::f()\n"; }
};
struct C: B {
void f() { std::cout << "C::f()\n"; } // not called from B::B()
};
int main() {
C c;
}
That is, you can call a virtual function, directly or indirectly, in the constructor or a destructor of a class if you don't want the virtual function to be dispatched to a further derived function. You can even do this is virtual function is abstract in the given class as long as it is defined. However, having an undefined abstract function being dispatched to will cause a run-time error.
When a constructor is called, the class is set up to be an instance of that class but not the derived class. You cannot call into a virtual function of a derived class from a base constructor. By the time you get to the constructor of the most derived class, all of the virtual functions should be safe to call.
If you wish to ensure that someone can't make an incorrect call, define the virtual function in the base class and have it assert and/or throw an exception when it is called.
The rule isn't so much that you need to be in a leaf class as to realize that when you make a member call from Foo::Foo(..), the object is exactly a Foo, even if it's on its way to being a Bar (assuming Foo is derived from Bar and you're constructing a Bar instance). That's 100% reliable.
Otherwise, the fact that the member is virtual isn't all that significant. There are other pitfalls that happen just as well with non-virtual functions: if you were to call a virtual or non-virtual method that assumed the object was completely constructed but called it within the constructor before that was the case, you'd also have problems. These are just hard cases to pin down because not only must the function you call be okay, all the functions it calls must be okay.
It doesn't sound like you have a problem, it's just one of those places prone for errors to crop up.