Quote:
Originally Posted by tonyweb
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().