Common.h
//
//===================================================================
//
#pragma warning( disable : 4311 4312 4313 )
//
//===================================================================
//
#define mem_addr DWORD
#define vfptr mem_addr*
#define fptr mem_addr*
//
//===================================================================
//
#define SAFE_DELETE(x) { if (x) delete (x); (x) = NULL; }
#define SAFE_DELETEARRAY(x) { if (x) delete[] (x); (x) = NULL; }
//
//===================================================================
//
#define GET_ELEMENT_ADDRESS( obj, ofs ) (((LPBYTE)&(obj))+(ofs))
#define GET_ELEMENT_PTR( type, obj, ofs ) (type*)GET_ELEMENT_ADDRESS( obj, ofs )
#define GET_ELEMENT_VALUE( type, obj, ofs ) *GET_ELEMENT_PTR( type, obj, ofs )
#define GET_VFPTR( obj, ofs ) (vfptr)GET_ELEMENT_VALUE( mem_addr, obj, ofs )
#define GET_FPTR( _vfptr, idx ) (fptr)(*((fptr)(_vfptr) + idx))
//
//===================================================================
//
typedef void (*PFUN) ( void );
//
//===================================================================
//
Class.h
//
//===================================================================
//
class _A
{
public:
_A() : nInt(0){
};
public:
void virtual Fun1( void )
{
printf( "/t/t _A::Fun1(void) /t/r/n" );
}
void virtual Fun2( void )
{
printf( "/t/t _A::Fun2(void) /t/r/n" );
}
int nInt;
};
class _B
{
public:
void virtual Fun3( void )
{
printf( "/t/t _B::Fun3(void) /t/r/n" );
}
void virtual Fun4( void )
{
printf( "/t/t _B::Fun4(void) /t/r/n" );
}
};
class _C : public _A, _B
{
public:
void virtual Fun1( void )
{
printf( "/t/t _C::Fun1(void) /t/r/n" );
}
void virtual Fun2( void )
{
printf( "/t/t _C::Fun2(void) /t/r/n" );
}
void virtual Fun3( void )
{
printf( "/t/t _C::Fun3(void) /t/r/n" );
}
void virtual Fun4( void )
{
printf( "/t/t _C::Fun4(void) /t/r/n" );
}
};
//
//===================================================================
//
Struct.h
//
//===================================================================
//
void A_Fun1(void);
void A_Fun2(void);
void B_Fun3(void);
void B_Fun4(void);
void C_Fun1(void);
void C_Fun2(void);
void C_Fun3(void);
void C_Fun4(void);
extern DWORD dwRewriteState;
//
//===================================================================
//
#define REWRITE_FUN1 0x0001
#define REWRITE_FUN2 0x0002
#define REWRITE_FUN3 0x0004
#define REWRITE_FUN4 0x0008
//
//===================================================================
//
typedef struct tagVirtualTableA
{
fptr Fun1;
fptr Fun2;
tagVirtualTableA() : Fun1(NULL), Fun2(NULL)
{
InitInstance( A_Fun1, A_Fun2 );
};
void InitInstance( PFUN fun1, PFUN fun2 )
{
Fun1 = (fptr)fun1;
Fun2 = (fptr)fun2;
}
}VirtualTableA, *LPVirtualTableA;
typedef struct tagVirtualTableB
{
fptr Fun3;
fptr Fun4;
tagVirtualTableB() : Fun3(NULL), Fun4(NULL)
{
InitInstance( B_Fun3, B_Fun4 );
};
void InitInstance( PFUN fun3, PFUN fun4 )
{
Fun3 = (fptr)fun3;
Fun4 = (fptr)fun4;
}
}VirtualTableB, *LPVirtualTableB;
extern LPVirtualTableA lpvfA;
struct A
{
LPVirtualTableA __vfptr;
int nInt;
A() : __vfptr(NULL), nInt(0)
{
__vfptr = lpvfA;
}
~A()
{
__vfptr = NULL;
}
};
extern LPVirtualTableB lpvfB;
struct B
{
LPVirtualTableB __vfptr;
B() : __vfptr(NULL)
{
__vfptr = lpvfB;
}
~B()
{
__vfptr = NULL;
}
};
struct C : public A, public B
{
C() : A(), B()
{
}
};
void InitVirtualTable( void );
void ExitVirtualTable( void );
//
//===================================================================
//
void TestEx( void );
//
//===================================================================
//
Class.cpp
//
//===================================================================
//
void A_Fun1(void)
{
printf( "/t/t A::Fun1(void) /t/r/n" );
};
void A_Fun2(void)
{
printf( "/t/t A::Fun2(void) /t/r/n" );
};
void B_Fun3(void)
{
printf( "/t/t B::Fun3(void) /t/r/n" );
};
void B_Fun4(void)
{
printf( "/t/t B::Fun4(void) /t/r/n" );
};
void C_Fun1(void)
{
printf( "/t/t C::Fun1(void) /t/r/n" );
};
void C_Fun2(void)
{
printf( "/t/t C::Fun2(void) /t/r/n" );
};
void C_Fun3(void)
{
printf( "/t/t C::Fun3(void) /t/r/n" );
};
void C_Fun4(void)
{
printf( "/t/t C::Fun4(void) /t/r/n" );
};
DWORD dwRewriteState = REWRITE_FUN1 | REWRITE_FUN2 | REWRITE_FUN3 | REWRITE_FUN4;
BOOL IsRewriteFun1( void ){ return (dwRewriteState & REWRITE_FUN1); }
BOOL IsRewriteFun2( void ){ return (dwRewriteState & REWRITE_FUN2); }
BOOL IsRewriteFun3( void ){ return (dwRewriteState & REWRITE_FUN3); }
BOOL IsRewriteFun4( void ){ return (dwRewriteState & REWRITE_FUN4); }
//
//===================================================================
//
LPVirtualTableA lpvfA = NULL;
LPVirtualTableB lpvfB = NULL;
void InitVirtualTable( void )
{
ExitVirtualTable();
lpvfA = new VirtualTableA;
lpvfB = new VirtualTableB;
PFUN fun1(NULL), fun2(NULL), fun3(NULL), fun4(NULL);
fun1 = IsRewriteFun1() ? C_Fun1 : A_Fun1;
fun2 = IsRewriteFun2() ? C_Fun2 : A_Fun2;
fun3 = IsRewriteFun3() ? C_Fun3 : B_Fun3;
fun4 = IsRewriteFun4() ? C_Fun4 : B_Fun4;
lpvfA->InitInstance( fun1, fun2 );
lpvfB->InitInstance( fun3, fun4 );
}
void ExitVirtualTable( void )
{
SAFE_DELETE(lpvfA);
SAFE_DELETE(lpvfB);
}
//
//===================================================================
//
void TestEx( void )
{
InitVirtualTable();
C cObj;
PRINT_OBJECT_NAME( "[Instance of struct C] : cObj" );
PRINT_OBJECT_ADDRESS( cObj );
PRINT_OBJECT_SIZE( cObj );
PFUN Fun = NULL;
vfptr _vfptrA = GET_VFPTR( cObj, 0 );
PRINT_VFPTR_VALUE( _vfptrA );
Fun = (PFUN)GET_FPTR( _vfptrA, 0 );
Fun();
PRINT_FPTR_VALUE( Fun );
PRINT_FPTR_ADDRESS( _vfptrA + 0 );
Fun = (PFUN)GET_FPTR( _vfptrA, 1 );
Fun();
PRINT_FPTR_VALUE( Fun );
PRINT_FPTR_ADDRESS( _vfptrA + 1 );
vfptr _vfptrB = GET_VFPTR( cObj, sizeof(vfptr)+sizeof(int) );
PRINT_VFPTR_VALUE( _vfptrB );
Fun = (PFUN)GET_FPTR( _vfptrB, 0 );
Fun();
PRINT_FPTR_VALUE( Fun );
PRINT_FPTR_ADDRESS( _vfptrB + 0 );
Fun = (PFUN)GET_FPTR( _vfptrB, 1 );
Fun();
PRINT_FPTR_VALUE( Fun );
PRINT_FPTR_ADDRESS( _vfptrB + 1 );
PRINT_NEWLINE();
ExitVirtualTable();
}
_C _cObj; // Class _C;
C cObj; // Struct C