EXETOOLS FORUM  

Go Back   EXETOOLS FORUM > General > General Discussion

Notices

Reply
 
Thread Tools Display Modes
  #1  
Old 08-13-2014, 21:26
BlackWhite BlackWhite is offline
Friend
 
Join Date: Apr 2013
Posts: 51
Rept. Given: 4
Rept. Rcvd 4 Times in 3 Posts
Thanks Given: 3
Thanks Rcvd at 8 Times in 6 Posts
BlackWhite Reputation: 4
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?
   }
}
Reply With Quote
  #2  
Old 08-13-2014, 23:37
SubzEro
 
Posts: n/a
Reply With Quote
  #3  
Old 08-14-2014, 12:06
BlackWhite BlackWhite is offline
Friend
 
Join Date: Apr 2013
Posts: 51
Rept. Given: 4
Rept. Rcvd 4 Times in 3 Posts
Thanks Given: 3
Thanks Rcvd at 8 Times in 6 Posts
BlackWhite Reputation: 4
Quote:
Originally Posted by Cyber_Coder View Post
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?

Last edited by BlackWhite; 08-14-2014 at 12:14.
Reply With Quote
  #4  
Old 08-14-2014, 12:15
SubzEro
 
Posts: n/a
sorry i am not programmer just trying to help
Reply With Quote
  #5  
Old 08-15-2014, 00:19
mr.exodia's Avatar
mr.exodia mr.exodia is offline
Super Moderator
 
Join Date: Nov 2011
Posts: 855
Rept. Given: 496
Rept. Rcvd 1,154 Times in 308 Posts
Thanks Given: 92
Thanks Rcvd at 528 Times in 202 Posts
mr.exodia Reputation: 1100-1299 mr.exodia Reputation: 1100-1299 mr.exodia Reputation: 1100-1299 mr.exodia Reputation: 1100-1299 mr.exodia Reputation: 1100-1299 mr.exodia Reputation: 1100-1299 mr.exodia Reputation: 1100-1299 mr.exodia Reputation: 1100-1299 mr.exodia Reputation: 1100-1299
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.
__________________
x64dbg: http://x64dbg.com
My Blog: http://mrexodia.cf
Reply With Quote
The Following 2 Users Gave Reputation+1 to mr.exodia For This Useful Post:
zeuscane (08-15-2014)
  #6  
Old 08-23-2014, 22:45
LaDidi LaDidi is offline
VIP
 
Join Date: Aug 2004
Posts: 171
Rept. Given: 2
Rept. Rcvd 11 Times in 10 Posts
Thanks Given: 11
Thanks Rcvd at 17 Times in 11 Posts
LaDidi Reputation: 11
@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 !
Reply With Quote
  #7  
Old 08-24-2014, 12:52
BlackWhite BlackWhite is offline
Friend
 
Join Date: Apr 2013
Posts: 51
Rept. Given: 4
Rept. Rcvd 4 Times in 3 Posts
Thanks Given: 3
Thanks Rcvd at 8 Times in 6 Posts
BlackWhite Reputation: 4
Quote:
Originally Posted by LaDidi View Post
@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?
Reply With Quote
  #8  
Old 08-24-2014, 14:36
deepzero's Avatar
deepzero deepzero is offline
VIP
 
Join Date: Mar 2010
Location: Europe
Posts: 212
Rept. Given: 99
Rept. Rcvd 60 Times in 38 Posts
Thanks Given: 82
Thanks Rcvd at 68 Times in 31 Posts
deepzero Reputation: 60
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.
Reply With Quote
The Following User Gave Reputation+1 to deepzero For This Useful Post:
BlackWhite (08-25-2014)
  #9  
Old 08-24-2014, 18:58
mr.exodia's Avatar
mr.exodia mr.exodia is offline
Super Moderator
 
Join Date: Nov 2011
Posts: 855
Rept. Given: 496
Rept. Rcvd 1,154 Times in 308 Posts
Thanks Given: 92
Thanks Rcvd at 528 Times in 202 Posts
mr.exodia Reputation: 1100-1299 mr.exodia Reputation: 1100-1299 mr.exodia Reputation: 1100-1299 mr.exodia Reputation: 1100-1299 mr.exodia Reputation: 1100-1299 mr.exodia Reputation: 1100-1299 mr.exodia Reputation: 1100-1299 mr.exodia Reputation: 1100-1299 mr.exodia Reputation: 1100-1299
@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!
__________________
x64dbg: http://x64dbg.com
My Blog: http://mrexodia.cf
Reply With Quote
  #10  
Old 08-24-2014, 22:19
tonyweb tonyweb is offline
Family
 
Join Date: Jan 2009
Posts: 137
Rept. Given: 162
Rept. Rcvd 86 Times in 31 Posts
Thanks Given: 1,128
Thanks Rcvd at 138 Times in 68 Posts
tonyweb Reputation: 86
Quote:
Originally Posted by BlackWhite View Post
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 View Post
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 View Post
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
__________________
Want to learn unpacking ... but I'm too stupid

Last edited by tonyweb; 08-24-2014 at 22:28.
Reply With Quote
  #11  
Old 08-25-2014, 20:45
BlackWhite BlackWhite is offline
Friend
 
Join Date: Apr 2013
Posts: 51
Rept. Given: 4
Rept. Rcvd 4 Times in 3 Posts
Thanks Given: 3
Thanks Rcvd at 8 Times in 6 Posts
BlackWhite Reputation: 4
Quote:
Originally Posted by tonyweb View Post
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().
Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
[C] Helper function to call arbitrary x86 Delphi functions zeffy Source Code 0 04-13-2018 10:25


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


��ICP��05004977��
Always Your Best Friend: Aaron, JMI, ahmadmansoor, ZeNiX