Accessing program counter / instruction pointer

How does one transfer the program counter / instruction pointer to a variable in C++?

I want to be able to:
1) obtain the current execution address
2) pass that address to another function (f)
3) in function (f), check the integrity of the calling function's code and/or modify it

This seems to require at least some assembly code. I presume that I could check the actual addresses in question in a disassembler and hard-code them into my program, but that would be tedious.

Relatedly:
1) How to obtain the start address of a function?
2) How to obtain the address of a label?

In C++ (VC5) I always get the error: 'illegal operation on bound member function expression' when I try to take the address of a function.
eleighAsked:
Who is Participating?
 
NickRepinConnect With a Mentor Commented:
It is not necessary to reject my answer, especially if it is "Good".

#include <windows.h>
#include <iostream.h>

class A
{
   public:
       void f1();

  typedef void (A::*pfunc) ();
};

void A::f1()
{
   A a;
   union {
      A::pfunc p;
      DWORD addrf1;
   } u;
   u.p=this->f1;
   cout<<hex<<u.addrf1<<endl;

}

void main(void)
{
   A a;
   union {
      A::pfunc p;
      DWORD addrf1;
   } u;
   u.p=a.f1;
   cout<<hex<<u.addrf1<<endl;
   a.f1();
}
0
 
NickRepinCommented:
#include <windows.h>
#include <iostream.h>
#include <stdio.h>

void a()
{
   cout<<"a() func"<<endl;
}

void aendmark() { }

void main(void)
{
   DWORD current_instruction_pointer;
   DWORD label_address;
   DWORD function_address;

   cout<<"Obtain current value of instruction pointer"<<endl;

   __asm {
label1:
      mov current_instruction_pointer,offset label1
   }

   cout<<"Obtain label address"<<endl;

   __asm {
      mov label_address,offset label2
   }


   cout<<"Obtain function address"<<endl;
   
   function_address=DWORD(a);

   cout<<current_instruction_pointer<<endl;
   cout<<label_address<<endl;
   cout<<function_address<<endl;

label2:
   exit(0);
}

0
 
eleighAuthor Commented:
Good answer, thanks, except ... taking the address of a function in C++ only works when it's global (or perhaps when it's a member of a static class), but not when it's an ordinary class function (sorry, should have made that clearer before):

MyClass::func1()
{
  void *ptr1 = [address of this->func1()]
  void *ptr2 = [address of this->func2()]
}

MyClass::func2()
{
....
}
0
Receive 1:1 tech help

Solve your biggest tech problems alongside global tech experts with 1:1 help.

 
NickRepinCommented:
Sorry,   " A a; " in f1() is not necessary.
   
0
 
NickRepinCommented:
Sorry again, the code above returns not the address of the function itself, but the address of jmp instruction that points to this function. I'll fix this in minutes.
0
 
NickRepinCommented:
This code works fine for Borland compiler. For VC++ you have to use the following (note: you can use A::f1 instead of a.f1)

#include <windows.h>
#include <iostream.h>

// This is VC++ specific.
void fixVC(DWORD& addr)
{
#pragma pack(push,1)  
   typedef struct {
      char opcode;
      DWORD offset;
   } *pjmp;
#pragma pack(pop)
   pjmp jmp=(pjmp) addr;
   addr=addr+sizeof(*jmp)+jmp->offset;
}

class A
{
   public:
       void f1();

  typedef void (A::*pfunc) ();
};

void A::f1()
{
   union {
      A::pfunc p;
      DWORD addrf1;
   } u;
   u.p=A::f1;
   fixVC(u.addrf1);
   cout<<hex<<u.addrf1<<endl;

}

void main(void)
{
   A a;
   union {
      A::pfunc p;
      DWORD addrf1;
   } u;
   u.p=A::f1;
   fixVC(u.addrf1);
   cout<<hex<<u.addrf1<<endl;
   a.f1();
}
0
 
eleighAuthor Commented:
Many thanks! I would have got there eventually with the assembly code, but your fixVC() I wouldn't have worked out for myself. (Sorry about rejecting your original answer: didn't realise I could just add a comment to an answer.)
0
 
nietodCommented:
nick, what if it is a virtual function?
0
 
NickRepinCommented:
Is it the new question?
0
 
nietodCommented:
Huh?  I'm just pointing out that the approach won't work with virtual functions.
0
 
NickRepinCommented:
Yes, but the author of question is satisfied with my answer. It seems that he uses non-virtual functions. As you can see, this Q is not about theoretical, but about concrete stuff - something like copy protection. Of course, we can extend the Q to virtual functions, virtual base classes etc, but what's for?
0
 
nietodCommented:
Are you sure he doesn't use virtual functions?  Are you sure he knows and is satisfied that it won't work for virtual functions.?  Could be, I don't know either....
0
 
NickRepinCommented:
I think, eleigh will add comment about this if he wants.
But it must be something extremely super very cool if there is a need to get a actual memory address of virtual function!
0
 
nietodCommented:
"extremely super very cool"?  Just "super very cool" wouldn't justify it, then?  alright.  You're probably right....
0
 
eleighAuthor Commented:
OK, guys, I don't envisage needing the address of a virtual function so let's say we'll 'leave it as an exercise for the reader'. (One that's beyond me though: the address one ends up with is of the 'vcall' code which contains a jmp offset from edx. Haven't a clue how to take it from there, since the value of edx isn't defined unless you're calling the function.)
0
 
nietodCommented:
When do you end up with this "vcall code"?  with a virtual function?  If so you need to use the offset as an index in the the class's virtual function table.
0
All Courses

From novice to tech pro — start learning today.