Address of an member function

I'm trying to write a patch and need to pass in a new version of an existing member function. I need the absolute address of the new member function. So far I've tried simply:
int address = ClassName::Func;
but get:
'type cast' : cannot convert from 'void (__thiscall ClassName::*)(class Param1 &,const class Param2 &)' to 'int'

Does the function need to be static for this to work and am I getting tripped up by indirection or function tables?
 
 
cajmyersAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

KangaRooCommented:
>> int address = ClassName::Func;
Won't work with any function
0
jkrCommented:
An explicit cast would do it, e.g.

int address = (int) ClassName::Func; // ouch!

But the result is not what you want, it'll be an index into vtable where the real address can be found...
0
KangaRooCommented:
What is the actual goal. Why not simply edit and recompile the code?
0
Cloud Class® Course: Microsoft Windows 7 Basic

This introductory course to Windows 7 environment will teach you about working with the Windows operating system. You will learn about basic functions including start menu; the desktop; managing files, folders, and libraries.

cajmyersAuthor Commented:
It's not a virtual function so I don't think that it's in the vtable. I could be wrong.

I can't recompile the source as the function is in ROM. I have to rewrite the function (or the entire class in this case, unless I can get hold of the this pointer somehow).
0
Gandalf32Commented:
You could do:
void *pAddress = (void*) ClassName::Func;

Make sure the function isn't virtual.
0
tdubroffCommented:
This should get the address of a static member function only:
unsigned long *p = (unsigned long*) ClassName::StaticFunc;



0
LucHoltkampCommented:
Why not use the qualified name?

typedef void (*Static_f)(class Param1 &,const class Param2 &);
typedef void (Classname::*Member_f)(class Param1 &,const class Param2 &);

struct A
{
  static void st(class Param1 &,const class Param2 &);
  void mb(class Param1 &,const class Param2 &);
};

void main()
{
  Static_f     sa = A::st;
  Member_f ma = A::mb;
  Param1 p1;
  Param2 p2;
  A a;
  (*sa)(p1, p2);
  (a.*ma)(p1, p2);
}
0
KangaRooCommented:
Is there any code in ROM that uses the original? You cannot change that code to use the new function.
0
cajmyersAuthor Commented:
OK, here's more detail on my problem:

I'm patching a member function that is in a library in ROM.

I've shadowed the ROM page so that my page in RAM is now referenced instead of the ROM address. Into the RAM page goes a banch instruction and the address of the new member function to branch to.

What I need is this address. I've now found out that a member function pointer actually consists of the address in memory plus a pointer to the object and a flag as to whether the function is virtual or non-virtual. I'm by no means clear about the details of this. How do I get the address.
0
tdubroffCommented:
Can you instead get the address of the object?
0
ToronadoCommented:
You can only get the absolute address of a static memberfunction. Now you can get the address like this :
unsigned long *adr = (unsigned long *)&classname::staticfuncname;
You can use this address to call the function.

Nonstatic memberfunctions don't have an absolute address! There is only one copy of the function code in memory for all instances of the object. The address of the actual object to use is passed as the first parameter. This is a hidden parameter, so you don't see it in your parameterlist.

If I'm understading your problem correctly you should use the static function. The only problem is that you cannot easily get to the membervariables in the object. You can try to solve this by passing the address of the object in question to the static function as a parameter. Using this methode you can access the public members.

success
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
cajmyersAuthor Commented:
I'm intercepting a call to a member function. It's not a static member function and there's nothing I can do about that.

Is the 'this' pointer on the stack somewhere when this call is made?
0
ToronadoCommented:
You need the address of the new member function in order to be able to branch to it?
So I assume you write this new member function yourself? If so, you can make it static.
Or do you want to use an other (existing) member function?

What happens during a call to a memberfunction is this:
First, the address of the object is stored in the ECX register. Afterthat a call is made. Usually this call is redirected by a JMP instruction. Inside the function the ECX register is used as "this" pointer.
0
cajmyersAuthor Commented:
I'm patching a member function in a class that is in ROM. I intercept it's call and run my code instead. I need the 'this' pointer so that I can access member variables. I have the source code and know all about the member function I'm changing but I can't recompile the original code. My function is a stand alone routine that must act as a member function. The state of the machine will be the same as if the real member function is being called.
0
tdubroffCommented:
Do you know the address of the function that you want to replace?  If you do, then write a trap/interrupt routine that is keyed of the execution of this address.  Inside the trap/interrupt routine, place your stand-alone function and then return to the caller by looking at the stack for the initial routine.  I hope that made some sense...
0
cajmyersAuthor Commented:
Traping the call and returning correctly is not my problem. Writing a stand alone function that acts like a member function is.
0
ToronadoCommented:
You can try something like this :

void StandAloneFunc (int b)
{
 B *internal = 0;

// ecx is pushed just before the call to the original member function. And contains the "this" pointer.

 _asm mov internal,ecx

 internal->members;
}

B is the class definition in your original source code.

I think it is wise to check wheter or not your compiler also uses ECX. Check this in your RAM page if you can load this in a debugger.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C++

From novice to tech pro — start learning today.