Exetools

Exetools (https://forum.exetools.com/index.php)
-   General Discussion (https://forum.exetools.com/forumdisplay.php?f=2)
-   -   How to call the original function when it's overridden? (https://forum.exetools.com/showthread.php?t=16081)

BlackWhite 08-13-2014 21:26

How to call the original function when it's overridden?
 
MFC has a class named CWinApp, and CWinApp has a destruction
function called ~CWinApp(). Now I want to override ~CWinApp()
yet still want to call the original version of ~CWinApp(), the code
is as follows:
Code:

void wrap(void)
{
  CWinApp::~CWinApp();
}

CWinApp::~CWinApp()
{
  if(GetCurrentProcessId() != process_id)
      return; // do nothing!
  else
  {
      wrap(); // It seems wrap() calls the overridden ~CWinApp(),
              // not the original one, thus it should not be called here.
              // Then, how to call the original ~CWinApp() here?
  }
}


SubzEro 08-13-2014 23:37


BlackWhite 08-14-2014 12:06

Quote:

Originally Posted by Cyber_Coder (Post 93549)

What he concerns about is not the same as mine.
His question was related to two different classes, while mine is associated with the same class.
What I concerns about is how to get the address of the function before it's overridden, and
if one function is overridden, does its original version still exist?

SubzEro 08-14-2014 12:15

sorry i am not programmer just trying to help

mr.exodia 08-15-2014 00:19

When overriding classes the constructor is called automatically in the constructor of the inheriting class (before the constructor of the inheriting class). Same with the deconstructor.

To call the base function explicitely use the syntax Base::Function, you should never call deconstructors explicitely though. Use delete of your class is an object allocated with new.

LaDidi 08-23-2014 22:45

@BlackWhite:
What you only need to know is class method
It's standard in all object programming...
+1 / mr.exodia : not a good idea to call destructor !

BlackWhite 08-24-2014 12:52

Quote:

Originally Posted by LaDidi (Post 93989)
@BlackWhite:
What you only need to know is class method
It's standard in all object programming...
+1 / mr.exodia : not a good idea to call destructor !

If I create a class say MyClass which inherits CWin, and assume
that ~MyClass() will be automatically called when the MyClass object is deleted, then I can decide whether to transfer control to ~CWin() in
~MyClass(). But the weird situation is that ~CWin() is called instead of
~MyClass() when the MyClass object is deleted.
So, how to deal with it?

deepzero 08-24-2014 14:36

you should never call a destructor explicitly! pull the destructor code into another method, if you think you do.


in the case of 'class MyClass : public CWin'

both ~MyCLass() and ~CWin() destructor will be invoked by the compiler (~MyCLass first). There is nothing you can do about it, you cant decide.

mr.exodia 08-24-2014 18:58

@BlackWhite: here is an example of how you should work. When you want to call the deconstructor, let the variable go out of scope or delete it.

Code:
http://codepad.org/1jq6nsQF

Output:
Code:

test() called!
 >Animal("Schnickelfritz") called!
 >Cat("Schnickelfritz") called!
 >~Cat("Schnickelfritz") called!
 >~Animal("Schnickelfritz") called!
test() returned!

deltest() called!
 >Animal("Koobenfarben") called!
 >Cat("Koobenfarben") called!
 >~Cat("Koobenfarben") called!
 >~Animal("Koobenfarben") called!
deltest() returned!


tonyweb 08-24-2014 22:19

Quote:

Originally Posted by BlackWhite (Post 93999)
If I create a class say MyClass which inherits CWin, and assume
that ~MyClass() will be automatically called when the MyClass object is deleted,

This is a good assumption given that you inherited "correctly" (see later).

Quote:

Originally Posted by BlackWhite (Post 93999)
then I can decide whether to transfer control to ~CWin() in
~MyClass().

As deepzero wrote, both ~MyClass() and ~CWin() will be called because of the hierarchy you established between the two classes.

Quote:

Originally Posted by BlackWhite (Post 93999)
But the weird situation is that ~CWin() is called instead of
~MyClass() when the MyClass object is deleted.

And, maybe, here's what you're missing (if I understood you correctly)! The destructor of the base class MUST BE virtual if you're destroying the object of the derived class through a pointer of the base class type.

cfr. http://stackoverflow.com/questions/461203/when-to-use-virtual-destructors

Hope this helps a bit :)

Regards,
Tony

BlackWhite 08-25-2014 20:45

Quote:

Originally Posted by tonyweb (Post 94033)
And, maybe, here's what you're missing (if I understood you correctly)! The destructor of the base class MUST BE virtual if you're destroying the object of the derived class through a pointer of the base class type.
cfr. http://stackoverflow.com/questions/461203/when-to-use-virtual-destructors

Yes, the base class is virtual, but I do not delete the object myself,
instead, it is deleted by the system. In fact, I wrote an MFC DLL, the
object is "theApp". Here is the code:
Code:

#include "stdafx.h"
#include "Hook.h"
#pragma comment(linker, "/SECTION:.SHARED,RWS")
#pragma data_seg(".SHARED")
HHOOK hHook = NULL; 
dword process_id= 0;
#pragma data_seg()

LRESULT CALLBACK hook_F12(int code, WPARAM wParam,        LPARAM lParam);
extern "C" __declspec(dllexport) void install_F12_hook(void);
void uninstall_F12_hook(void);

CHookApp theApp;

CHookApp::CHookApp()
{
}

/*
CWinApp::~CWinApp()  // Here we override the original CWinApp::~CWinApp
{                    // to prevent other hooked processes' crashing on exit
  if(GetCurrentProcessId() != process_id)
      return; // do nothing!
  // how to call the original ~CWinApp() ?
}
*/

void uninstall_F12_hook(void)
{
  if(hHook != NULL)
  {
      UnhookWindowsHookEx(hHook);
      hHook = 0;
  }
}

LRESULT CALLBACK hook_F12(int code, WPARAM wParam,        LPARAM lParam)
{
  if(GetCurrentProcessId() == process_id &&
      (code == HC_ACTION        || code == HC_NOREMOVE) &&
      wParam == VK_F12)
  {
      if((lParam & 0x80000000) != 0) // F12 is released
        return TRUE; // discard this key signal
      // So F12 is pressed,
      // do something here
      // ... (code removed)
      return TRUE; // do not pass the message to next hook or window proc     
  }
  return CallNextHookEx(hHook, code, wParam, lParam);
}

extern "C" __declspec(dllexport) void install_F12_hook(void)

  atexit(uninstall_F12_hook);
  process_id = GetCurrentProcessId();
  hHook = SetWindowsHookEx(WH_KEYBOARD,        hook_F12,
        GetModuleHandle("hook.dll"), 0); 
}

Now I load this "hook.dll" in an EXE say HELLO.EXE and call
function install_F12_hook() to install a keyboard hook,
HELLO.EXE runs happily and closes normally, but there are
problems with other running processes which are also
hooked by "hook.dll". When I close some other process,
that process will crash. I traced the crash by OllyDBG, and
found that ~CWinApp() is the bad guy.

Code:

*1402107 DllEntryPoint
01402174    57              push    edi
01402175    56              push    esi
01402176    53              push    ebx
+1402177    E8 E0FEFFFF    call    0140205C; _CRT_INIT(x,x,x)
0140217C    85C0            test    eax, eax
0140217E    75 03          jnz    short 01402183
|
*140205C;  _CRT_INIT(x,x,x)
014020DF    8B0E            mov    ecx, [esi]
014020E1    85C9            test    ecx, ecx
014020E3    74 07          je      short 014020EC
+14020E5    FFD1            call    ecx; =>*140104A
014020E7    A1 D8414001    mov    eax, [0x14041D8]
014020EC    83EE 04        sub    esi, 0x4
|
*140104A    55              push    ebp
0140104B    8BEC            mov    ebp, esp
0140104D    B9 F0404001    mov    ecx, 014040F0
+1401052    E8 490D0000    call    01401DA0
01401057    5D              pop    ebp
01401058    C3              retn
|
*1401DA0    55              push    ebp
01401DA1    8BEC            mov    ebp, esp
01401DA3    51              push    ecx
01401DA4    894D FC        mov    [ebp-0x4], ecx
01401DA7    8B4D FC        mov    ecx, [ebp-0x4]
+1401DAA    E8 53010000    call    <jmp.&MFC42.#CWinApp::~CWinApp_815>
                  ; Other hooked processes will crash inside!
01401DAF    8BE5            mov    esp, ebp
01401DB1    5D              pop    ebp
01401DB2    C3              retn

That's the reason why I want to override ~CWinApp().


All times are GMT +8. The time now is 10:18.

Powered by vBulletin® Version 3.8.8
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Always Your Best Friend: Aaron, JMI, ahmadmansoor, ZeNiX