瀏覽器自動完成儲存的密碼在網頁 <input type="password"> 中顯示為黑點,無法直接取得。本文提供兩種從 IE 取得密碼明文的方法:註冊表右鍵選單注入 VBScript、VC++ 透過 IHTMLDocument2 介面操作 DOM。
GetPwd.htm 腳本:<script language="VBScript">
Sub GetPassword()
Set srcEvent = external.menuArguments.event
Set doc = external.menuArguments.document
Set ele = doc.elementFromPoint(srcEvent.clientX, srcEvent.clientY)
If ele.type = "password" Then
If ele.value = "" Then MsgBox "密碼為空" Else MsgBox "密碼為:" & ele.value
End If
End Sub
GetPassword()
</script>
HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\MenuExt\取得密碼 新增字串值(預設)指向該檔案路徑,DWORD contexts = 4(僅表單元素顯示)。核心難點:跨進程取得 IE Internet Explorer_Server 視窗的 IHTMLDocument2 介面。步驟:
FindWindow/EnumChildWindows 找到類別名 "Internet Explorer_Server" 的子視窗 HWND。WM_HTML_GETOBJECT(RegisterWindowMessage 取得)給該 HWND,取回 LRESULT。OLEACC.DLL,取得 ObjectFromLresult 函數指標,呼叫轉換為 IHTMLDocument2*。GetDocInterfaceIHTMLDocument2* GetDocInterface(HWND hWnd) {
HINSTANCE hInst = LoadLibrary(_T("OLEACC.DLL"));
if (!hInst) return NULL;
UINT nMsg = RegisterWindowMessage(_T("WM_HTML_GETOBJECT"));
LRESULT lRes; SendMessageTimeout(hWnd, nMsg, 0, 0, SMTO_ABORTIFHUNG, 1000, (DWORD*)&lRes);
LPFNOBJECTFROMLRESULT pfn = (LPFNOBJECTFROMLRESULT)GetProcAddress(hInst, "ObjectFromLresult");
IHTMLDocument2* pDoc2 = NULL;
if (pfn) {
CComPtr<IDispatch> spDisp;
pfn(lRes, IID_IHTMLDocument, 0, (void**)&spDisp);
CComQIPtr<IHTMLWindow2> spWin(spDisp);
spWin->get_document(&pDoc2);
}
FreeLibrary(hInst); return pDoc2;
}
void CMyDlg::OnLButtonUp(UINT nFlags, CPoint point) {
if (m_bCapture) {
ReleaseCapture(); m_bCapture = FALSE;
POINT pt; GetCursorPos(&pt);
HWND hIE = WindowFromPoint(pt);
TCHAR cls[100]; GetClassName(hIE, cls, 100);
if (_tcscmp(cls, _T("Internet Explorer_Server")) == 0) {
ScreenToClient(hIE, &pt);
GetPassword(GetDocInterface(hIE), pt);
}
}
}
void GetPassword(IHTMLDocument2* pDoc, POINT pt) {
CComPtr<IHTMLElement> pElem;
pDoc->elementFromPoint(pt.x, pt.y, &pElem);
CComQIPtr<IHTMLInputTextElement> pInput(pElem);
if (pInput) {
CComBSTR type; pInput->get_type(&type);
if (CString(type).CompareNoCase(_T("password")) == 0) {
CComBSTR val; pInput->get_value(&val);
AfxMessageBox(CString(_T("密碼是:")) + CString(val));
}
}
pDoc->Release();
}
若上述失敗,可嘗試 AccessibleObjectFromWindow → IServiceProvider → QueryService(IID_IHTMLWindow2) 取得文件介面。完整代碼見文末 GetDocInterfaceByMSAA。
MSAA 執行元件(OLEACC.DLL)。CoInitialize/CoUninitialize。