I have a specific problem I'm trying to solve, I need to find the location (in memory) of a class's method. I think I've hit a syntax constraint because a pointer to a method is handled as a member pointer Example:
class Foo {
public:
int targetFunction(int value) { return value + 5; }
};
DWORD findLocation() { // ignore the fact that DWORD might not equal pointer size.
int (Foo::*address)(int) = &(Foo::targetFunction); // member function pointer
void* typeHide = (void*)&address; // Remove type
DWORD targetAddress = *(DWORD*)typeHide; // Convert type from void* to DWORD* and dereference to DWORD
return targetAddress;
}
int (Foo::*address)(int) = can also be written as auto address =
Now, in VS2008, it says Foo::targetFunction's address is "0x000F B890" but &Foo::targetFunction is "0x000F 1762"
First, the member pointer works correctly using the member pointer operators .* and ->*. If I cast targetAddress back to a member pointer, it still works!
Second, the location can be a thunk function!
Finally, if I use VS2008's debugger to change the value of targetFunction from the member pointer's address 1762 to the VS debugger reported value B890, my code works correctly!
Is there a C++ specific way of getting the address value (B890) instead of the member pointer value (1762)?
Upon request, here is code I'm trying to make work:
BYTE overwriteStorage[300][2];
void NOP(void)
{
// hackish, but works for now.
}
void disableOlderVersions(DWORD _address, int index)
{
//...
_address = findLocation();
DWORD protectionStorage = 0;
VirtualProtect((void *)_address, 1+4, PAGE_WRITECOPY, &protectionStorage); // windows.h: Make Read/Write the location in code
{
BYTE *edit = (BYTE*)_address;
overwriteStorage[index][0] = *(edit+0); // store previous value to revert if needed
*(edit+0) = 0XE9; // JUMP (32-bit)
overwriteStorage[index][1] = *(edit+1); // store second value
signed int correctOffset = (signed int)NOP - (signed int)_address - 5; // calculate 0xE9 relative jump
*(signed int*)(edit+1) = correctOffset; // set jump target
}
VirtualProtect((void *)_address, 1+4, PAGE_EXECUTE, &protectionStorage);
}
if I replace the first line of findLocation from a member pointer to an actual function pointer it works perfectly. However, I need to read&write to several class methods as well, this method is broken by the odd member pointers.
Also, I've had some local functions not report the correct address either (recently). Is there possibly another way to find function addresses without being constrained by the compiler behaviors?
It sounds like you're trying to compress a member-function call into a single function pointer. It's not possible.
Remember:
Object x;
x.a(1);
is actually short for
a(&x /*this*/, 1 /*arg1, ... */); //approximation, leprechauns may be involved in actual implementations.
That first argument is crucial, it's going to become "this".
So you can't do something like this:
class Object {
public:
void f(int);
}
typedef void (*FNPTR)(int);
Object a;
void (Object::* memberFuncPtr)(int);
void* nerfedPtr = (void*)memberFuncPtrl
FNPTR funcPtr = static_cast<FNPTR>(nerfedPtr);
funcPtr(1);
Because you've robbed the member function of it's object context.
There is no way to call an object member function without having both the address of the function and the address of the instance.
Related
I have a 64 bit reference to an object where the low order 32 bits of the reference are getting overwritten with 0xFFFFFFFF. I can't figure out how to set a data breakpoint on the bytes for the reference itself because the watch window gives me no way to acquire the address of the reference.
I see two solutions (if I correctly understood the problem):
change the reference to a pointer;
add a dummy variable in front of your reference - see the code below - and set the break-point to its address.
class object_t
{
public:
int i;
};
class test_t
{
public:
int64_t dummy {};
object_t& ro;
test_t( object_t& aro ) : ro { aro } {}
};
int main()
{
object_t obj;
test_t c { obj };
// without dummy
int64_t* p = (int64_t*)&c;
*(int32_t*)p = 0xffffffff; // simulates memory corruption
c.ro.i = 0; // exception
// with dummy
int64_t* p = (int64_t*)&c;
*(int32_t*)p = 0xffffffff; // will break
return 0;
}
I don't know any direct way to do this. But, here's a possible solution:
first, find where the variable is approximately: if you have a variable next to it, then get its address. If no variable nearby, then if the reference on the stack, then get the stack pointer (esp/rsp on x86). If the reference is in an object which is not on stack, then use the this pointer.
second, use the memory window, go to this approximate address, and search for the value of the reference, it will be somewhere nearby.
I'm trying to get function addresses which are hidden behind structures. Unfortunately, the void* basic C++ conversion doesn't work, so I used C++ template instead.
1. Basic void* C++ conversion doesn't work with functions inside structures, why?
void * lpfunction;
lpfunction = scanf; //OK
lpfunction = MessageBoxA; //OK
I made a simple structure :
struct FOO{
void PRINT(void){printf("bla bla bla");}
void SETA(int){} //nothing you can see
void SETB(int){} //nothing you can see
int GETA(void){} //nothing you can see
int GETB(void){} //nothing you can see
};
///////////////////////////////////////////
void *lpFunction = FOO::PRINT;
And the compiling error :
error C2440: 'initializing' :
cannot convert from 'void (__thiscall FOO::*)(void)' to 'void *'
2. Is getting function member addresses impossible?
Then, I made a template function which is able to convert a function member to address. Then I will call it by assembly. It should be something like this:
template <class F,void (F::*Function)()>
void * GetFunctionAddress() {
union ADDRESS
{
void (F::*func)();
void * lpdata;
}address_data;
address_data.func = Function;
return address_data.lpdata; //Address found!!!
}
And here is the code :
int main()
{
void * address = GetFunctionAddress<FOO,&FOO::PRINT>();
FOO number;
number.PRINT(); //Template call
void * lpdata = &number;
__asm mov ecx, lpdata //Attach "number" structure address
__asm call address //Call FOO::PRINT with assembly using __thiscall
printf("Done.\n");
system("pause");
return 0;
}
But, I see it is extremely specific. It looks like LOCK - KEY, and I have to make a new template for every set of argument types.
Original (OK) :
void PRINT(); //void FOO::PRINT();
Modify a bit :
void PRINT(int); //void FOO::PRINT(int);
Immediately with old template code the compiler shows :
//void (F::*func)();
//address_data.func = Function;
error C2440: '=' : cannot convert from
'void (__thiscall FOO::*)(int)' to 'void (__thiscall FOO::*)(void)'
Why? They are only addresses.
69: address_data.func = Function;
00420328 mov dword ptr [ebp-4],offset #ILT+2940(FOO::PRINT) (00401b81)
...
EDIT3 : I know the better solution :
void(NUMBER::*address_PRINT)(void) = FOO::PRINT;
int(NUMBER::*address_GETA)(void) = FOO::GETA;
int(NUMBER::*address_GETB)(void) = FOO::GETB;
void(NUMBER::*address_SETA)(int) = FOO::SETA;
void(NUMBER::*address_SETA)(int) = FOO::SETB;
It's much better than template. And by the way I want to achieve the goal :
<special_definition> lpfunction;
lpfunction = FOO::PRINT; //OK
lpfunction = FOO::GETA; //OK
lpfunction = FOO::GETB; //OK
lpfunction = FOO::SETA; //OK
lpfunction = FOO::SETB; //OK
Is this possible?
Pointers to member functions are nothing like pointers to global functions or static member functions. There are many reasons for this, but I'm not sure how much you know about how C++ works, and so I'm not sure what reasons will make sense.
I do know that what you are trying in assembly simply won't work in the general case. It seems like you have a fundamental misunderstanding about the purpose of member functions and function pointers.
The thing is, you are doing some things that you would generally not do in C++. You don't generally build up tables of function pointers in C++ because the things you would use that sort of thing for are what virtual functions are for.
If you are determined to use this approach, I would suggest you not use C++ at all, and only use C.
To prove these pointer types are completely incompatible, here is a program for you:
#include <cstdio>
struct Foo {
int a;
int b;
int addThem() { return a + b; }
};
struct Bar {
int c;
int d;
int addThemAll() { return c + d; }
};
struct Qux : public Foo, public Bar {
int e;
int addAllTheThings() { return Foo::addThem() + Bar::addThemAll() + e; }
};
int addThemGlobal(Foo *foo)
{
return foo->a + foo->b;
}
int main()
{
int (Qux::*func)();
func = &Bar::addThemAll;
printf("sizeof(Foo::addThem) == %u\n", sizeof(&Foo::addThem));
printf("sizeof(Bar::addThemAll) == %u\n", sizeof(&Bar::addThemAll));
printf("sizeof(Qux::addAllTheThings) == %u\n", sizeof(&Qux::addAllTheThings));
printf("sizeof(func) == %u\n", sizeof(func));
printf("sizeof(addThemGlobal) == %u\n", sizeof(&addThemGlobal));
printf("sizeof(void *) == %u\n", sizeof(void *));
return 0;
}
On my system this program yields these results:
$ /tmp/a.out
sizeof(Foo::addThem) == 16
sizeof(Bar::addThemAll) == 16
sizeof(Qux::addAllTheThings) == 16
sizeof(func) == 16
sizeof(addThemGlobal) == 8
sizeof(void *) == 8
Notice how the member function pointer is 16 bytes long. It won't fit into a void *. It isn't a pointer in the normal sense. Your code and union work purely by accident.
The reason for this is that a member function pointer often needs extra data stored in it related to fixing up the object pointer it's passed in order to be correct for the function that's called. In my example, when called Bar::addThemAll on a Qux object (which is perfectly valid because of inheritance) the pointer to the Qux object needs to be adjusted to point at the Bar sub-object before the function is called. So Qux::*s to member functions must have this adjustment encoded in them. After all, saying func = &Qux::addAllTheThings is perfectly valid, and if that function were called no pointer adjustment would be necessary. So the pointer adjustment is a part of the function pointer's value.
And that's just an example. Compilers are permitted to implement member function pointers in any way they see fit (within certain constraints). Many compilers (like the GNU C++ compiler on a 64-bit platform like I was using) will implement them in a way that do not permit any member function pointer to be treated as at all equivalent to normal function pointers.
There are ways to deal with this. The swiss-army knife of dealing with member function pointers is the ::std::function template in C++11 or C++ TR1.
An example:
#include <functional>
// .... inside main
::std::function<int(Qux *)> funcob = func;
funcob can point at absolutely anything that can be called like a function and needs a Qux *. Member functions, global functions, static member functions, functors... funcob can point at it.
That example only works on a C++11 compiler though. But if your compiler is reasonably recent, but still not a C++11 compiler, this may work instead:
#include <tr1/functional>
// .... inside main
::std::tr1::function<int(Qux *)> funcob = func;
If worse comes to worse, you can use the Boost libraries, which is where this whole concept came from.
But I would rethink your design. I suspect that you will get a lot more milage out of having a well thought out inheritance hierarchy and using virtual functions than you will out of whatever it is you're doing now. With an interpreter I would have a top level abstract 'expression' class that is an abstract class for anything that can be evaluated. I would give it a virtual evaluate method. Then you can derive classes for different syntax elements like an addition expression a variable or a constant. Each of them will overload the evaluate method for their specific case. Then you can build up expression trees.
Not knowing details though, that's just a vague suggestion about your design.
Here is a clean solution. By means of a template wrap your member function into a static member function. Then you can convert it to whatever pointer you want:
template<class F, void (F::*funct)()>
struct Helper: public T {
static void static_f(F *obj) {
((*obj).*funct)();
};
};
struct T {
void f() {
}
};
int main() {
void (*ptr)(T*);
ptr = &(Helper<T,&T::f>::static_f);
}
It seems that you need to convert a pointer to a member function to a void *. I presume you want to give that pointer as a "user data" to some library function and then you will get back your pointer and want to use it on some given object.
If this is the case a reinterpret_cast<void *>(...) could be the right thing... I assume that the library receiving the pointer is not using it.
I am getting access violation error in the below code..i have pointed it out in the program.
void *pBuff = 0;
void set_data(void *pBuff)
{
int value = 70, i;
int *phy_bn = new int[8];
for(i=0; i<8; i++)phy_bn[i] = value;
pBuff =phy_bn;
cout<<((int*)pBuff)[0];//..accessing 0th element value..no error here..gives 70 as result..
}
int main()
{
set_data(pBuff);
cout<<((int*)pBuff)[0];//acces violation error
return 0;
}
Why that access violation even when i am not assigning it the address of a local variable...
Yes i can use vector or pass by reference.
But i want to know why pBuff is not getting assigned
Because it is a copy of the pointer being modified within set_data(). Pass the pointer by reference so the change is visible to the caller:
void set_data(void*& pBuff)
Note that the function variable pBuff hides the global variable pBuff in the function set_data().
That said, I am unsure of the reason for void* and why vector<int> is not being used which handles all dynamic memory allocation for you.
When you say
pBuff = phy_bn;
You're just changing the local value of pBuff, not the global value of pBuff. Either pass pBuff as a double pointer, or simply remove the argument to the function, as pBuff is global already.
void *pBuff = 0; /* This is the global pBuff, which isn't being changed */
void set_data(void *pBuff /* This is the local pBuff, which is being changed */)
{
...
pBuff = phy_bn;
...
}
'plz i want to avoid double pointers..its not required i guess...'
Guessed wrong, it is required! You'll need a pointer reference for the pBuff parameter then:
void set_data(void*& pBuff)
{
// ...
}
This is effectively the same as using a double pointer.
The only thing you're doing with
pBuff =phy_bn;
is manipulating the function parameter representation on the local stack.
The pBuff inside set_data is not the global pBuff. The value of the global pBuff never gets changed from 0. Since this is C++ code, set_data can take its pointer argument by reference, and assigning to it will change the value at the point of the function call.
In C++, pointers are passed by value, the same as other value types. It may be instructional to think of a pointer as literally an integer type; then it’s easy to see why pBuff = phy_bn; doesn’t accomplish anything, for the same reason that this code doesn’t:
#include <iostream>
void set(int x) {
x = 5;
}
int main(int argc, char** argv) {
int y = 0;
set(y);
std::cout << y << '\n';
return 0;
}
Here, x is a local variable. It is a copy of y, not y itself. You can change its value by assigning to it, sure, but you’re merely changing the value of a variable which will not exist outside the scope of set(). If you change the definition of set() to use a reference:
void set(int& x) {
x = 5;
}
Then y will indeed be updated, because you have explicitly requested that x be an alias for the name you pass to set(), instead of a copy. You were misled by the names: the pBuf in set_data() is not the same variable pBuf in main(), even though they happen to have the same value; they’re like two different people with the same name and the same amount of money.
I have a thread-class Buffer (own made class), and many derived classes such as BufferTypeA, BufferTypeB...
Since I have to synchronize them in a certain order, I'm giving any of them an integer which represents the order to run certain task. I also have to know inside each thread Buffer which one is next to run the task, so I'm passing every BufferType a reference to an integer which all of them must share and I didn't want to make it Global.
I got lost at any point and I don't see where.
First I create all the BufferTypes from a class where I also define that shared integer as:
int currentThreadOrder;
And when creating the BufferTypes:
int position = 0;
if (NULL == bufferA) {
bufferA = new BufferTypeA(¤tThreadOrder, ++position,
waitCondition);
}
if (NULL == bufferB) {
bufferB = new BufferPos(¤tThreadOrder, ++position,
waitCondition);
}
if (NULL == bufferC) {
bufferC = new BufferRtk(¤tThreadOrder, ++position,
waitCondition);
}
Then, in BufferTypeA header:
class BufferTypeA: public Buffer {
public:
BufferTypeA(int currentThreadOrder,
int threadConnectionOrder = 0,
QWaitCondition *waitCondition = NULL);
//..
}
And in cpp file:
BufferTypeA::BufferTypeA(int currentThreadOrder, int threadConnectionOrder, QWaitCondition *waitCondition):
Buffer(currentThreadOrder, threadConnectionOrder, waitCondition) { }
Now I'll show Buffer header:
class Buffer: public QThread {
public:
Buffer(int ¤tThreadOrder,
int threadConnectionOrder = 0,
QWaitCondition *waitCondition = NULL);
//...
protected:
QWaitCondition *waitCondition;
int threadConnectionOrder;
int ¤tThreadOrder; // Shared address
}
And finally the cpp:
Buffer::Buffer(int ¤tThreadOrder, int threadConnectionOrder, QWaitCondition *waitCondition) {
this->threadConnectionOrder = threadConnectionOrder;
this->waitCondition = waitCondition;
this->currentThreadOrder = currentThreadOrder;
}
And the error I'm getting is error: uninitialized reference member Buffer::currentThreadOrder.
I'm embarrased to ask, because it's going to be a simple problem with pointers and addresses, but I can't see where the problem is, so please help.
When you create a class with a data-member that is a reference, the reference needs to be assigned a value in the constructor initializer list.
References have to be given a value when they are created, they are not pointers. They have to start with a value and that value cannot be changed (while the contents that is pointed to by that value can be changed).
Essentially you can think of a reference as an alias for an existing variable. You can't give a friend a nickname if you don't have a friend :)
RESPONSE TO COMMENT:
You don't "share a reference" between objects. Each object will have its own reference to the same variable. When you "pass by reference" you are telling the compiler that you want the variable in your function to actually be the variable in your outer scope, rather than creating a new variable by value. This means that you only have one variable at one memory location. The reference is just memory in some other place that forwards you to that same memory location.
Think of this as call forwarding... I can have 15 phone numbers in 15 different countries. I can set them all up to forward calls to my cell in the US. So, people are calling me no matter which number they call.
Each of your classes just has another reference to forward the "phone calls" or variable reads/writes to that same memory location. So, you're not sharing a reference between classes, you're making sure that each class HAS a reference to the same underlying memory location.
Back to the metaphore, each class won't have the same phone, but each class' phone will forward to the same number (variable) none-the-less which lets them all set/get the same value in the end.
RESPONSE II:
Here's a simple example to get your head going, it's pretty easy to apply to your classes. I didn't compile it but it should work minus a typo or two possibly.
class A
{
public:
A(int& shared) : m_shared(shared)
{
//No actions needed, initializer list initializes
//reference above. We'll just increment the variable
//so you can see it's shared in main.
m_shared += 7;
}
void DoSomethingWithIt()
{
//Will always reflect value in main no matter which object
//we are talking about.
std::cout << m_shared << std::endl;
}
private:
//Reference variable, must be initialized in
//initializer list of constructor or you'll get the same
//compiler error again.
int& m_shared;
};
int main()
{
int my_shared_integer = 0;
//Create two A instances that share my_shared_integer.
//Both A's will initialize their internal reference to
//my_shared_integer as they will take it into their
//constructors "by reference" (see & in constructor
//signature) and save it in their initializer list.
A myFirstA(my_shared_integer);
A mySecondA(my_shared_integer);
//Prints 14 as both A's incremented it by 7 in constructors.
std::cout << my_shared_integer << std::endl;
}
you pass a pointer int* as 1st argument to BufferTypeA, which expects and int, while you said in your question you meant to use a int&. To do this, the ctor of BufferTypeA should take a int& and initialise it in an initialisation list (i.e. not within the { } part of the ctor) like
class BufferType {
int &Ref;
public:
BufferTypeA(int& ref) : Ref(ref) { /* ... */ }
};
and in your construction of BufferA you must not pass an address, but the reference, i.e.
int counter;
Buffer = new BufferType(counter);
You want code like this:
Buffer::Buffer(
int ¤tThreadOrder0,
const int threadConnectionOrder0,
QWaitCondition *const waitCondition0
) :
threadConnectionOrder(threadConnectionOrder0),
waitCondition(waitCondition0),
currentThreadOrder(currentThreadOrder0)
{}
The reason is related to the reason you cannot write
const double pi;
pi = 3.14;
but can write
const double pi = 3.14;
A reference is typically implemented as a constant pointer, to which one cannot assign an address after one has initialized the pointer. Your version of the code assigns, as in the first pi example. My version of the code initializes, as in the second pi example.
I am trying to print the address of a virtual member function.
If I know which class implements the function I can write:
print("address: %p", &A::func);
But I want to do something like this:
A *b = new B();
printf("address: %p", &b->func);
printf("address: %p", &b->A::func);
However this does not compile. Is it possible to do something like this, perhaps looking up the address in the vtable at runtime?
Currently there is no standard way of doing this in C++ although the information must be available somewhere. Otherwise, how could the program call the function? However, GCC provides an extension that allows us to retrieve the address of a virtual function:
void (A::*mfp)() = &A::func;
printf("address: %p", (void*)(b->*mfp));
...assuming the member function has the prototype void func().
This can be pretty useful when you want to cache the address of a virtual function or use it in generated code. GCC will warn you about this construct unless you specify -Wno-pmf-conversions. It's unlikely that it works with any other compiler.
Pointers to member functions are not always simple memory addresses. See the table in this article showing the sizes of member function pointers on different compilers - some go up to 20 bytes.
As the article outlines a member function pointer is actually a blob of implementation-defined data to help resolve a call through the pointer. You can store and call them OK, but if you want to print them, what do you print? Best to treat it as a sequence of bytes and get its length via sizeof.
I found a way to do this using a disassembler (https://github.com/vmt/udis86). The steps are:
Get a pointer to the virtual function via normal C++ code
Disassemble the jmp instruction at that address
Parse the real address from the disassembled string
Here is how I did it:
// First get the raw pointer to the virtual function
auto myVirtualFuncPtr = &MyClass::myFunc;
void* myVirtualFuncPtrRaw = (void*&)myVirtualFuncPtr;
// Resolve the real function!
void* myFuncPtr = resolveVirtualFunctionAddress(myVirtualFuncPtrRaw);
...
static void* resolveVirtualFunctionAddress(void* address)
{
const int jumpInstructionSize = 5;
static ud_t ud_obj;
ud_init(&ud_obj);
ud_set_mode(&ud_obj, sizeof(void*) * 8);
ud_set_syntax(&ud_obj, UD_SYN_INTEL);
ud_set_pc(&ud_obj, (uint64_t)address);
ud_set_input_buffer(&ud_obj, (unsigned uint8_t*)address, jumpInstructionSize);
std::string jmpInstruction = "";
if (ud_disassemble(&ud_obj))
{
jmpInstruction += ud_insn_asm(&ud_obj);
}
// TODO: Implement startsWith and leftTrim yourself
if (startsWith(jmpInstruction, "jmp "))
{
std::string jumpAddressStr = leftTrim(jmpInstruction, "jmp ");
return hexToPointer(jumpAddressStr);
}
// If the jmp instruction was not found, then we just return the original address
return address;
}
static void* hexToPointer(std::string hexString)
{
void* address;
std::stringstream ss;
ss << std::hex << hexString;
ss >> address;
return address;
}
From what I can tell in the standard, the only time you get dynamic binding is during a virtual function call. And once you've called a function, you're executing the statements within the function (i.e., you can't "stop halfway" into the call and get the address.)
I think it's impossible.
Doesn't make a lot a of sense to me. If you have a normal function:
void f( int n ) {
}
then you can take its address:
f
but you cannot take the address of a function call, which is what you seem to want to do.