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

Protect 'DLL hijacking' in MFC app with MAPI and Microsoft Office

Rate me:
Please Sign up or sign in to vote.
0.00/5 (No votes)
19 Sep 2010CPOL1 min read 10K   3  
Protect 'DLL hijacking' in MFC app with MAPI and Microsoft Office


Introduction


Today there is lot of information about 'DLL hijacking vulnerabilities'. You can protect your Windows in two ways. First, install KB2264107 and set HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager CWDIllegalInDllSearch to ffffffff. Or second, you set in your app SetDllDirectory(_T("")) (I prefer this one). In both cases, the current working directory is removed from the DLL Search path. But now when you use the MFC MAPI support and you've got Microsoft Outlook as your MAPI client, you can't send any email from your app. Because The Outlook MAPI uses the current working directory to load MsMapi32.dll from %CommonProgramFiles%\.... With Outlook Express it works fine. There is another minor issue when you send an email from your app. After that, the current working directory is set to %CommonProgramFiles%\.... where Outlook MAPI found the MsMapi32.dll. You can check this with the file-open or file-saveas dialog.



Using the Code


The following steps can fix both in your MFC app.



  1. Implement an own function OnFileSendMail() in your document class.
  2. Save the current working directory with GetCurrentDirectory()
  3. Get the MsMapi path from the registry
  4. Set the DLL search path with SetDllDirectory()
  5. Call CDocument::OnFileSendMail()
  6. Set the DLL search path without current working directory
  7. Restore the current working directory with SetCurrentDirectory() In the attached demo app, you can see this in MapiFixDoc.cpp


void CMapiFixDoc::OnFileSendMail() 
{
	TCHAR szCurrentDirectory[MAX_PATH];
	VERIFY(0U < ::GetCurrentDirectory(_countof(szCurrentDirectory),
             szCurrentDirectory));
	TCHAR szMsMapiPath[MAX_PATH];
	if(FALSE != ::GetMsMapiPath(_countof(szMsMapiPath), szMsMapiPath))
	{
	    //add MsMapi to the default DLL search order
		::dynSetDllDirectory(szMsMapiPath);
	}
	CDocument::OnFileSendMail();	
    //removes the current directory from the default DLL search order
	::dynSetDllDirectory(_T(""));
	VERIFY(FALSE != ::SetCurrentDirectory(szCurrentDirectory));
}


Points of Interest


SetDllDirectory() is not available in older Windows versions. So I dynamically load this function from kernel32.dll. This is done in SetDllDirectory.h.


Compatibility


I test it with Windows 2000 till Windows 7 and Office 2000 till Office 2010. The demo app compiles with VC++ 6 and VS 2008. I think it should also compile with other VS versions.



History


04.09.2010 Initial publication

License

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


Written By
Switzerland Switzerland
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 --