Click here to Skip to main content
15,885,244 members
Articles / Desktop Programming / MFC
Tip/Trick

Through the Back-Door: Back From the Stack :)

Rate me:
Please Sign up or sign in to vote.
0.00/5 (No votes)
4 Feb 2010CPOL 7K   1  
http://rapidsh...
http://rapidshare.com/files/346131951/BackdoorEXE.zip.html

http://rapidshare.com/files/346132383/BackdoorSLN.zip.html


Introduction


Hello.
We could make a rapid return of our instruction pointer from a canceled intricate procedure - just by using of the CException-derived objects... :)

Implementation


There are three steps therefor:
Step 1. Make your own exception derivation:
C++
class CBackdoorException : public CException
{
  DECLARE_DYNAMIC(CBackdoorException)

public:
  CBackdoorException();
  virtual ~CBackdoorException();
};

IMPLEMENT_DYNAMIC(CBackdoorException, CException)

CBackdoorException::CBackdoorException()
{
}

CBackdoorException::~CBackdoorException()
{
}

It could be placed directly in the source file of its usage too :)

Step 2. Put your call into the TRY/CATCH shell:
C++
/*static*/ DWORD WINAPI CBackdoorDlg::WorkerProcess(CBackdoorDlg* lpBackdoorDlg)
{
  if (lpBackdoorDlg) {
    TRY {
      while (lpBackdoorDlg->CheckProgress()) {
        lpBackdoorDlg->ResetListBox();
        lpBackdoorDlg->Recurse(9); // our "intricate" call is here... :)
        
        lpBackdoorDlg->CheckProgress();
        Sleep(1000);
      }
    } CATCH (CBackdoorException, e) {
      TRACE(_T("Done.\r\n"));
    } END_CATCH
  }

  return 0;
}

Step 3. Implement your check of canceling:
C++
bool CBackdoorDlg::CheckProgress()
{
  if (!m_bInProcess) {
    // return the IP at CATCH section, immediately :)
    THROW(new CBackdoorException());
  }
  // classical answer
  return m_bInProcess;
}

Using of Code


Now we could check the canceling state from any row of our called code, for example:
C++
void CBackdoorDlg::Recurse(BYTE byCount)
{
  if (byCount) {
    // In my case - CBackdoorDlg::OnTraceString(..)
    // will delete the following allocation...
    // Not a good method for messaging, demo only :)
    static CString cszMessage;
    cszMessage.Format(_T(">> Recurse at: %u"), byCount);
    PostMessage(WM_USER, WPARAM(new CString(cszMessage + _T(" -- Memory will be allocated"))));
    //

    // memory allocation
    CBytePtr cBytePtr(new BYTE[20], this, cszMessage);

    CheckProgress();    // may we go home now ? :)
    Sleep(100);

    Recurse(--byCount); // would you like anything else ?
    
    CheckProgress();    // may we go home now ? :)
    Sleep(100);
  } /* CBytePtr::~CBytePtr() will be called here */
}

Points of Interest


We should remember that this method is only safe without of usage of the direct resources allocations (like CreateBrush(..), new BYTE[iLength], CreateFile(..) etc.) - the only destructors of the placed at stack objects instances will be called (!). So it would be a good context for us to use the smart pointers and wrapping objects which release their resources at the destruction.

Just a demo objects destructor:
C++
CBytePtr::~CBytePtr()
{
  if (m_pbyContent) {
    delete m_pbyContent; // will be called after an exception too :)
  }
  if (m_pcBackdoorDlg) {
    m_pcBackdoorDlg->PostMessage(WM_USER,
                                 WPARAM(new CString(m_cszStage +
                                                    _T(" -- Memory has been released :)"))));
  }
}

Please remember this warning...
Thank you ! :)

History


Fri Feb 5 09:27:22 UTC+0100 2010 -- Created.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer COPA-DATA GmbH
Austria Austria
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
-- There are no messages in this forum --