Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //////////////////////////////////////////////////////////////////////////////
- //
- // Test a detour of a member function (member.cpp of member.exe)
- //
- // Microsoft Research Detours Package, Version 2.1.
- //
- // Copyright (c) Microsoft Corporation. All rights reserved.
- //
- // By default, C++ member functions use the __thiscall calling convention.
- // In order to Detour a member function, both the trampoline and the detour
- // must have exactly the same calling convention as the target function.
- // Unfortunately, the VC compiler does not support a __thiscall, so the only
- // way to create legal detour and trampoline functions is by making them
- // class members of a "detour" class.
- //
- // In addition, C++ does not support converting a pointer to a member
- // function to an arbitrary pointer. To get a raw pointer, the address of
- // the member function must be moved into a temporrary member-function
- // pointer, then passed by taking it's address, then de-referencing it.
- // Fortunately, the compiler will optimize the code to remove the extra
- // pointer operations.
- //
- // If X::Target is a virtual function, the following code will *NOT* work
- // because &X::Target is the address of a thunk that does a virtual call,
- // not the real address of the X::Target. You can get the real address
- // of X::Target by looking directly in the VTBL for class X, but there
- // is no legal way to 1) get the address of X's VTBL or 2) get the offset
- // of ::Target within that VTBL. You can of course, figure these out for
- // a particular class and function, but there is no general way to do so.
- //
- #include <stdio.h>
- #include <windows.h>
- #include <detours.h>
- #include "..\slept\verify.cpp"
- //////////////////////////////////////////////////////////////// Target Class.
- //
- class CMember
- {
- public:
- void Target(void);
- };
- void CMember::Target(void)
- {
- printf(" CMember::Target! (this:%p)\n", this);
- }
- //////////////////////////////////////////////////////////////// Detour Class.
- //
- class CDetour /* add ": public CMember" to enable access to member variables... */
- {
- public:
- void Mine_Target(void);
- static void (CDetour::* Real_Target)(void);
- // Class shouldn't have any member variables or virtual functions.
- };
- void CDetour::Mine_Target(void)
- {
- printf(" CDetour::Mine_Target! (this:%p)\n", this);
- (this->*Real_Target)();
- }
- void (CDetour::* CDetour::Real_Target)(void) = (void (CDetour::*)(void))&CMember::Target;
- //////////////////////////////////////////////////////////////////////////////
- //
- int main(int argc, char **argv)
- {
- (void)argc;
- (void)argv;
- //////////////////////////////////////////////////////////////////////////
- //
- #if (_MSC_VER < 1310)
- void (CMember::* pfTarget)(void) = CMember::Target;
- void (CDetour::* pfMine)(void) = CDetour::Mine_Target;
- Verify("CMember::Target", *(PBYTE*)&pfTarget);
- Verify("*CDetour::Real_Target", *(PBYTE*)&CDetour::Real_Target);
- Verify("CDetour::Mine_Target", *(PBYTE*)&pfMine);
- #else
- Verify("CMember::Target", (PBYTE)(&(PBYTE&)CMember::Target));
- Verify("*CDetour::Real_Target", *(&(PBYTE&)CDetour::Real_Target));
- Verify("CDetour::Mine_Target", (PBYTE)(&(PBYTE&)CDetour::Mine_Target));
- #endif
- printf("\n");
- DetourTransactionBegin();
- DetourUpdateThread(GetCurrentThread());
- #if (_MSC_VER < 1310)
- pfMine = CDetour::Mine_Target;
- DetourAttach(&(PVOID&)CDetour::Real_Target,
- *(PBYTE*)&pfMine);
- #else
- DetourAttach(&(PVOID&)CDetour::Real_Target,
- (PVOID)(&(PVOID&)CDetour::Mine_Target));
- #endif
- LONG l = DetourTransactionCommit();
- printf("DetourTransactionCommit = %d\n", l);
- printf("\n");
- #if (_MSC_VER < 1310)
- pfTarget = CMember::Target;
- pfMine = CDetour::Mine_Target;
- Verify("CMember::Target", *(PBYTE*)&pfTarget);
- Verify("*CDetour::Real_Target", *(&(PBYTE&)CDetour::Real_Target));
- Verify("CDetour::Mine_Target", *(PBYTE*)&pfMine);
- #else
- Verify("CMember::Target", (PBYTE)(&(PBYTE&)CMember::Target));
- Verify("*CDetour::Real_Target", *(&(PBYTE&)CDetour::Real_Target));
- Verify("CDetour::Mine_Target", (PBYTE)(&(PBYTE&)CDetour::Mine_Target));
- #endif
- printf("\n");
- //////////////////////////////////////////////////////////////////////////
- //
- CMember target;
- printf("Calling CMember (w/o Detour):\n");
- (((CDetour*)&target)->*CDetour::Real_Target)();
- printf("Calling CMember (will be detoured):\n");
- target.Target();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement