How to navigate through methods of a vtable? - c++

I have an assignment for university which requires me to access the vtable of a class. I need to write a function (here called pb) which takes a pointer to an object as an argument as well as an integer, and then just prints the output of the methods of the class. I have managed to access the first function, but I don't know how to access the second function. Here's the code I have so far:
typedef int(*firstFun)();
typedef int(*secondFun)(int);
class B {
public:
virtual int __cdecl first() = 0;
virtual int __cdecl second(int) = 0;
};
class D : public B {
public:
virtual int __cdecl first() { return 42; }
virtual int __cdecl second(int x) {
return first() + x; }
};
void pb(B* object, int x) {
unsigned int adressVTable = *(unsigned int*)object;
unsigned int adressVTable2; //yet unknown
firstFun bFirst = (firstFun)(*(unsigned int*)(adressVTable));
secondFun bSecond = (secondFun)(*(unsigned int*)(int)(adressVTable2));
int f=bFirst();
int s=bSecond(x);
printf("First: %d, second: %d", f, s);
}
In conclusion, how to get bSecond to work for second(int) like bFirst works for first()?

The vTable is just an array of function pointers, so just an array of pointers. If the target process is x86 then just add 0x4 to the address of the first pointer and you will get the second pointer in the vtable. If the target process is x64, add 0x8 because that's the size of a pointer on that architecture.
Secondly, you're defining these as cdecl function which isn't going to work how you've planned. Virtual functions / member functions are __thiscall, which require the this pointer to be passed in ECX. So you need to typedef the function pointers correctly and pass the thisptr as the first argument.
Tested working:
typedef int(__thiscall *firstFun)(void* thisptr);
typedef int(__thiscall *secondFun)(void* thisptr, int);
class B
{
public:
virtual int first() = 0;
virtual int second(int) = 0;
};
class D : public B
{
public:
virtual int first() { return 42; }
virtual int second(int x)
{
return first() + x;
}
};
void pb(B* object, int x)
{
unsigned int adressVTable = *(unsigned int*)object;
unsigned int adressVTable2 = adressVTable + 0x4;
firstFun bFirst = (firstFun)(*(unsigned int*)(adressVTable));
secondFun bSecond = (secondFun)(*(unsigned int*)(adressVTable2));
int f = bFirst(object);
int s = bSecond(object, x);
printf("First: %d, second: %d", f, s);
}
int main()
{
D obj;
pb(&obj, 5);
getchar();
return 0;
}

Related

Passing const variable between member functions to be index of array

I have tried to solve this, but I can't. I have a class definition and I want a member function (siz) to return a constant value to another member function (abc). This value is used as maximum index in an array declaration in that function. But this doesn't seems to work. Here is a simplified version:
class bin {
constexpr int siz();
public:
void abc();
};
constexpr int bin::siz() {
const int sizz = sizeof(int) * 8;
}
void bin::abc() {
char arr[siz()]; // compiler: this expression didn't evaluate as constant (¿?)
};
However, this other very similar code (but using simple functions) does compile...
constexpr int siz() {
const int sizz = sizeof(int) * 8;
return sizz;
}
int main() {
char arr[siz()];
return 0;
}
I am not entirely sure but I think the problem is that in bin::abc, the object can be anything at run time. Hence, bin::siz() cannot be evaluated at compile time.
The following works fine
int main()
{
bin b;
char arr[b.siz()];
}
after changing bin to:
class bin {
public:
constexpr int siz();
};
constexpr int bin::siz() {
return sizeof(int) * 8;
}
If siz does not depend on the state of the object, as in your posted code, I suggest making it a static member function.
The following works fine for me.
class bin {
public:
static constexpr int siz();
void abc() const;
};
constexpr int bin::siz() {
return sizeof(int) * 8;
}
void bin::abc() const {
char arr[siz()];
}
int main()
{
bin b;
char arr[b.siz()];
}

Accessing entry of Array of function pointers, within a class C++

I wrote a simple class that performs basic arithmetic operations using a method that receives an index and two values to compute.
The index indicates which operation to perform in a table that contains pointers to functions.
Here is my code:
#include <iostream>
using namespace std;
class TArith
{
public:
static const int DIV_FACTOR = 1000;
typedef int (TArith::*TArithActionFunc)(int,int);
struct TAction
{
enum Values
{
Add,
Sub,
count,
};
};
int action(TAction::Values a_actionIdx, int a_A, int a_B)
{
return ( this->*m_actionFcns[a_actionIdx] )(a_A,a_B);
}
private:
int add(int a_A, int a_B)
{
return a_A + a_B ;
}
int sub(int a_A, int a_B)
{
return a_A - a_B ;
}
static TArithActionFunc m_actionFcns[TAction::count];
int m_a;
int m_b;
};
TArith:: TArithActionFunc TArith:: m_actionFcns[TAction::count] = {
TArith::add,
TArith::sub
};
void main(void)
{
TArith arithObj;
int a=100;
int b=50;
for(int i = 0 ; i <TArith::TAction::count ; ++i)
{
cout<<arithObj.action( (TArith::TAction::Values)i,a,b )<<endl;
}
cout<<endl;
}
Compiler says:
'TArith::add': function call missing argument list; use '&TArith::add' to create a pointer to member
'TArith::sub': function call missing argument list; use '&TArith::sub' to create a pointer to member
why do I need to use the & symbol?
TArith:: TArithActionFunc TArith:: m_actionFcns[TAction::count] = {
TArith::add,
TArith::sub,
TArith::mul,
TArith::div
};
Correct syntax for a pointer to a member function f of a class C is &C::f. You're missing the leading &.
Try:
TArith:: TArithActionFunc TArith:: m_actionFcns[TAction::count] = {
&TArith::add,
&TArith::sub,
&TArith::mul,
&TArith::div
};

C++ member function pointer to global function pointer

I have to solve, at least for me, a tricky problem in C++. There is a dll which i can not modify. It gets a function pointer as argument. If I pass a pointer to a global function everything works fine. Unfortunatelly there is a list of same class objects to pass to the dll. In C# I solved this by using delegates. How can this be done in C++? Using std::function does not work. With that there are coding convention errors during runtime. Further using MSVC2010 would be optimal.
I wrote a sample which describes the problem:
#include <stdio.h>
// global function which works
void __stdcall task_global(float x, float y) { printf("Called global function with: %f %f\n", x, y); }
typedef void(__stdcall *f_pointer)(float, float);
// try of using a member function
class BaseTask {
public:
virtual void __stdcall task(float x, float y) = 0;
};
class ListeningTask :public BaseTask {
public:
void __stdcall task(float x, float y) { printf("Called this member function with: %f %f\n", x, y); }
};
typedef void (BaseTask::*member_f_pointer)(float, float);
// the dll to use
class RegisterTask {
public:
// no posibility to access or modify!
void __stdcall subscribe(f_pointer fp) { fp(1.0f, 2.0f); }
// just for demonstration how to use a member function pointer
void __stdcall subscribeMemberDemo(member_f_pointer mfp) { /*how to use mfp?*/};
};
int main() {
RegisterTask register_task{};
// use global function
f_pointer pointer_to_global_task = task_global;
register_task.subscribe(pointer_to_global_task);
/*---------------------------------------------------------------*/
// use member function?
std::list<ListeningTask> listening_task_list;
for(int i = 0; i < 10; i++) {
listening_task_list.push_back(ListeningTask lt);
member_f_pointer pointer_to_member_task = &listening_task_list.back().task; //error C2276: '&': illegal operation on bound member function expression
register_task.subscribeMemberDemo(pointer_to_member_task);
// the tricky and important one to solve
// how to pass the member function to this subscribe(f_pointer)?
register_task.subscribe(pointer_to_member_task);
}
getchar();
return 0;
}
The important question is how to pass a member function pointer to the RegisterTask::subscribe(f_pointer)?
The parenthetic question is how to pass a member function to the RegisterTask::subscribeMemberDemo(member_f_pointer)?
I hope someone can help me to solve this? I am working on this since days.
Edit:
I modified the question to emphasize the problem with the list of ListenerTask. How to pass a member function pointer is now clear to me through the answers of #pokey909 and #AndyG. Both of them provide a pointer to one object or rather a list of objects. If the callback is called the one ListenerTask or all std::list<*ListenerTask> are called at once. But how to let only one ListenerTask of the list to be called. Passing more than one callback to the dll. It (RegisterTask) can do that, because the following example with global functions works.
void __stdcall task_global_1(float x, float y) { printf("Called global function 1 with: %f %f\n", x, y); }
void __stdcall task_global_2(float x, float y) { printf("Called global function 2 with: %f %f\n", x, y); }
void __stdcall task_global_3(float x, float y) { printf("Called global function 3 with: %f %f\n", x, y); }
typedef void(__stdcall *f_pointer)(float, float);
int main() {
// give the functions to the dll.
f_pointer pointer_to_global_task_1 = task_global_1;
register_task.subscribe(pointer_to_global_task_1);
f_pointer pointer_to_global_task_2 = task_global_2;
register_task.subscribe(pointer_to_global_task_2);
f_pointer pointer_to_global_task_3 = task_global_3;
register_task.subscribe(pointer_to_global_task_3);
}
There are three global function pointers. They are all given to the dll. Now, if the dll has a task for task_global_2 it notifies this only! How to achive this distinction with member function pointer?
Note:
I got the source of the dll. Hope this helps. Unfortunately modifying, building is not possible. Here is the callback definition:
type TCallback = procedure( x : single; y : single; ); stdcall;
procedure subscribe(aCallback: TCallback ); StdCall;
begin
TaskSocket.addTask( aCallback );
end;
procedure TSocket.addTask( aCallback : TCallback);
var newTask : TTask;
begin
newTask := TTask.Create(aCallback);
TaskList.addItem(newTask);
end;
You can use a freestanding function that calls a wrapper which binds your instance to it.
Here is rough example
#include <iostream>
#include <string>
#include <functional>
// global function which works
std::function<void(float, float)> memberCb;
void task_global(float x, float y) { memberCb(x, y); }
typedef void(*f_pointer)(float, float);
// try of using a member function
class BaseTask {
public:
virtual void task(float x, float y) = 0;
};
class ListeningTask :public BaseTask {
public:
void task(float x, float y) { printf("Called this member function with: %f %f\n", x, y); }
};
typedef void (BaseTask::*member_f_pointer)(float, float);
void callbackWrapper(BaseTask* t, float x, float y) { t->task(x, y); }
// the dll to use
class RegisterTask {
public:
// no posibility to access or modify!
void subscribe(f_pointer fp) {
fp(1.0f, 2.0f);
}
// just for demonstration how to use a member function pointer
void subscribeMemberDemo(member_f_pointer mfp) { /*???*/ };
};
int main() {
RegisterTask register_task{};
ListeningTask listening_task{};
memberCb = std::bind(&callbackWrapper, &listening_task, std::placeholders::_1, std::placeholders::_2);
register_task.subscribe(task_global);
return 0;
}
Note
Based on the comment, I'm not sure if all of this works in MSVC2010, since I don't have this compiler version. But rudimentary C++11 support should be in there.
Edit
I'm not sure if thats what you are after, but would this solve your problem?
void callbackWrapper(const std::list<BaseTask*> &taskList, float x, float y) {
for (auto t : taskList)
t->task(x, y);
}
int main() {
RegisterTask register_task{};
std::list<BaseTask*> taskList;
for (int i = 0; i < 4; ++i)
taskList.push_back(new ListeningTask);
memberCb = std::bind(&callbackWrapper, taskList, std::placeholders::_1, std::placeholders::_2);
register_task.subscribe(task_global);
return 0;
}
Edit 2
Ok I think I got what you want. The best I can come up with without splattering your code with global functions manually is with template magic.
Note however, that it is not as flexible as you might want because you have to bind those methods at compile time.
If you need to add them at runtime, you can probably use the same trick but without templates. Simply put all the std::function objects in a vector and wrap that up in a singleton or something similar.
#include <iostream>
#include <string>
#include <functional>
#include <list>
/* Simulated DLL */
typedef void(*f_pointer)(float, float);
class RegisterTask {
public:
void subscribe(f_pointer fp) {
fp(1.0f, 2.0f);
}
};
/* Static function generator to ease the pain to define all of them manually */
template<unsigned int T>
std::function<void(float, float)> &getWrapper() {
static std::function<void(float, float)> fnc;
return fnc;
}
/* Same here */
template<unsigned int T>
void task_global(float x, float y) { getWrapper<T>()(x, y); }
class BaseTask {
public:
virtual void task(float x, float y) = 0;
};
class ListeningTask :public BaseTask {
public:
ListeningTask(int taskNum) : m_taskNum(taskNum) {}
void task(float x, float y) { printf("Called this member of task %d function with: %f %f\n", getTaskNum(), x, y); }
int getTaskNum() const { return m_taskNum; }
private:
int m_taskNum;
};
/* Context injector */
void callbackWrapper(BaseTask* t, float x, float y) {
t->task(x, y);
}
/* Convenience function to bind an instance to a task */
template<unsigned int T>
void bindTask(ListeningTask* t) {
getWrapper<T>() = std::bind(&callbackWrapper, t, std::placeholders::_1, std::placeholders::_2);
}
int main() {
RegisterTask register_task{};
auto task0 = new ListeningTask(1337);
auto task1 = new ListeningTask(1984);
auto task2 = new ListeningTask(42);
bindTask<0>(task0);
register_task.subscribe(task_global<0>);
bindTask<1>(task1);
register_task.subscribe(task_global<1>);
bindTask<2>(task2);
register_task.subscribe(task_global<2>);
return 0;
}
Run Code demo
pokey909's answer is totally great, but if you don't even have access to std::function and std::bind, we can hack our way around it.
The gist of the approach is that we are going to define a template class with an implicit conversion to the desired function type. The downside is that each new additional wrapper requires a new type declaration.
// assumes two function arguments
template<class Ret, class Mem, class Arg1, class Arg2, int>
struct MemBind
{
typedef Ret(Mem::*mem_fn_type)(Arg1, Arg2);
static void Set(mem_fn_type _fn, Mem* _instance)
{
fn = _fn;
instance = _instance;
}
static Ret DoTheThing(Arg1 first, Arg2 second)
{
return ((*instance).*fn)(first, second);
}
typedef Ret(*fn_type)(Arg1, Arg2);
operator fn_type ()
{
return DoTheThing;
}
static mem_fn_type fn;
static Mem* instance;
};
Given some struct Foo with our desired callback:
struct Foo
{
void Bar(float a, float b)
{
std::cout << "Foo::Bar(float, float) " << a << " , " << b << std::endl;
}
};
We have to define our static members:
typedef MemBind<void, Foo, float, float, 0> MemBindZero;
template<> Foo* MemBindZero::instance = nullptr;
template<> void(Foo::*MemBindZero::fn)(float, float) = nullptr;
We can have a caller that takes in a function pointer:
void Caller(void(*_fn)(float, float))
{
_fn(42.0, 1337.0);
}
The key here is that MemBind has an implicit conversion to the desired function type. The 0 in the typedef for MemBindZero allows us to re-use the same types for the other arguments, but increment the counter to 1 when used. I think you could probably replace it with a __COUNTER__ macro or something like that, but it would be nonstandard so I did it manually.
Now the next bit is to create an instance of MemBindZero, then set the static members, and finally pass our instance into Caller:
Foo f;
MemBindZero bound;
bound.Set(&Foo::Bar, &f);
Caller(bound);
Demo
In the demo I wrapped the static member initialization into a more convenient macro:
#define MEMBIND(RET, CLASS, ARG1, ARG2, COUNT, ALIAS) \
typedef MemBind<RET, CLASS, ARG1, ARG2, COUNT> ALIAS; \
template<> CLASS * ALIAS::instance = nullptr; \
template<> RET(CLASS::*ALIAS::fn)(ARG1, ARG2) = nullptr;
So that I could call it like so:
MEMBIND(void, Foo, float, float, 0, MemBindZero)
MEMBIND(void, OtherFoo, float, float, 1, MemBindOne)

Issue while passing pointer to constant as an argument

In this eg,using call by address concept in order to retrieve all the data changes which is happening in the function call...
In main(),
i)passing two arguments
i)int pointer
ii)pointer to constant -> which cannot change the value it is holding...
ii)Changing the values of int * and assigning some values to const void * in the function calls.
*Finally i'm trying to print the values in main()
*getting the int pointer values properly(no issues)
*getting the void pointer value as NULL..
Requirement:
Need to get the output in main() like this
main::ajskdffllagkdjdjdhdjhd(i mean to say that i need to print the void * values like this)
But i'm getting the value as main:: NULL
What shall i need to do inorder to get the expected output?
#include <stdio.h>
#include <stdlib.h>
void func(int *len,const void *pBuf);
void func2(int **len,const void **pBuf);
void func3(int ***len,const void ***pBuf);
int main()
{
int len = 0;
const void *pBuf;
printf("len b4 ::%d\n",len);
printf("%p\n",&pBuf);
func(&len,&pBuf);
printf("len after::%d\n",len);
printf("%p\n",&pBuf);
printf("main::%s\n",(const char *)pBuf);
return 0;
}
void func(int *len,const void *pBuf)
{
*len = 20;
printf("func1 :: %p\n",&pBuf);
func2(&len,&pBuf);
}
void func2(int **len,const void **pBuf)
{
printf("func2::%p\n",&pBuf);
**len = 30;
func3(&len,&pBuf);
}
void func3(int ***len,const void ***pBuf)
{
const void *pMy = "ajskdffllagkdjdjdhdjhd";
**pBuf = pMy;
printf("func3::%p\n",&pBuf);
printf("func3::%s\n",(const char *)**pBuf);
***len = 40;
}
Output:
len b4::0
0x7fffa9c51468
func1 :: 0x7fffa9c51440
func2::0x7fffa9c51420
func3::0x7fffa9c513f0
func3::ajskdffllagkdjdjdhdjhd
len after::40
0x7fffa9c51468
main::(null)
You are right with the string literal. Sorry.
However, you need to change the address where pBuf points to:
void func(int *len,const void **pBuf)
{
*len = 20;
printf("func1 :: %p\n",pBuf);
func2(&len,&pBuf);
}
void func2(int **len,const void ***pBuf)
{
printf("func2::%p\n",pBuf);
**len = 30;
func3(&len,&pBuf);
}
void func3(int ***len,const void ****pBuf)
{
const void *pMy = "ajskdffllagkdjdjdhdjhd";
***pBuf = pMy;
printf("func3::%p\n",&pBuf);
printf("func3::%s\n",(const char *)***pBuf);
***len = 40;
}
len is an int. In order to change it, you need to call func() with the address of that int value.
pBuf is a pointer. To change the address where it points to, you need to call func() with the address of that pointer.
You are catching address of int with single pointer and catching the address of pointer also with single pointer.. This is problem. In functions, change *pBuf as **pBuf and **pBuf as ***pBuf and so on..

Whats the significance of return by reference?

In C++,
function() = 10;
works if the function returns a variable by reference.
What are the use cases of it?
The commonest case is to implement things like operator[].
struct A {
int data[10];
int & operator[]( int i ) {
return data[i];
}
};
Another is to return a big object from a class via an accesor function:
struct b {
SomeBigThing big;
const SomeBigThing & MyBig() const {
return big;
}
};
in order to avoid the copying overhead.
Consider the following code, MyFunction returns a pointer to an int, and you set a value to the int.
int *i;
i = MyFunction();
*i = 10;
Now shorten that to
*(MyFunction()) = 10;
It does exactly the same thing as the first code block.
You can look at a reference as just a pointer that's always dereferenced. So if my function returned a reference - not a pointer - to an int the frist code block would become
int &i;
i = MyFunction();
i = 10;
and the second would become
MyFunction() = 10;
This is what i was looking for
Getters/setters for instance
class C
{
int some_param_;
public:
int& param() { return some_param_; }
int const& param() const { return some_param_; }
};
but here you should go with some_param being a public int. Containers provide functions that return by reference, eg. vector<T>::operator[] so that you can write v[k] = x.
A very normal use case is when you write an array like class. Here you want to overload the operator [] so as you can do a[0] = 10; In that case you would want the signature to be like int& operator[](int index);
In case you have a class that contains another structure, it can be useful to directly modify the contained structure:
struct S
{
int value;
};
class C
{
public:
S& ref() { return m_s; }
private:
S m_s;
};
Allows you to write something like:
void foo()
{
C c;
// Now you can do that:
c.ref().value = 1;
}
Note: in this example it might be more straightforward to directly make m_s public rather than returning a reference.
SO screwed up my answer
You don't even need to return a reference:
struct C { };
C f() {
return C();
}
int main() {
C a;
f() = a; // compiles fine
}
Because this behavior is quite surprising, you should normally return a const value or a const reference unless the user has a sensible intent to modify the result.
It can be usefull when implementing accessors
class Matrix
{
public:
//I skip constructor, destructor etc
int & operator ()(int row, int col)
{
return m_arr[row + col * size];
}
private:
int size;
int * m_arr;
}
Matrix m(10);
m(1,0) = 10; //assign a value to row 1, col 0
Another classic case:
class Foo {
Foo();
public:
static Foo& getSingleton();
};
std::vector has operator[] which would not allow vec[n] = m otherwise.
You can also achieve method chaining (if you so desire) using return by reference.
class A
{
public:
A& method1()
{
//do something
return *this; //return ref to the current object
}
A& method2(int i);
A& method3(float f); //other bodies omitted for brevity
};
int main()
{
A aObj;
aObj.method1().method2(5).method3(0.75);
//or use it like this, if you prefer
aObj.method1()
.method2(5)
.method3(0.75);
}
The named parameter idiom is a another use case. Consider
class Foo
{
public:
Foo(
int lions,
float tigers,
double bears,
std::string zookeeper
);
};
users of this class need to remember the position of each parameter
Foo foo( 1, 2.0, 5, "Fred" );
which can be non-obvious without looking at the header. Compared to a creator class like so
class CreateFoo
{
friend class Foo;
public:
CreateFoo();
CreateFoo& lions(int lions) {
_lions = lions;
return *this;
}
CreateFoo& tigers(float tigers) {
_tigers = tigers;
return *this;
}
CreateFoo& bears(double bears) {
_bears = bears;
return *this;
}
CreateFoo& zookeeper(const std::string& zookeeper) {
_zookeeper = zookeeper;
return *this;
}
private:
int _lions;
float _tigers;
double _bears;
std::string _zookeeper;
};
which can then be used by clients like so
Foo foo = CreateFoo().
lions(1).
tigers(2.0).
zookeeper("Fred").
bears(5)
;
assuming Foo has a constructor taking a const CreateFoo&.