我創建了Credential Manager
DLL以利用NPLogonNotify
事件。我正在對Windows 7 Ultimate
進行完全修補的實例進行測試。憑證管理器DLL在強制更改密碼時導致登錄掛起
當用戶登錄我的NPLogonNotify
實現時,會產生一些使用CreateProcess
的進程。這些進程是Windows應用程序,一切正常。
當我強制用戶在下次登錄時更改密碼時,他們更改密碼,系統掛起「更改密碼」。當用戶更改密碼時,在NPLoponNotify
內部創建新進程的某些操作不會很好。
我已驗證它是NPLogonNotify
代碼,通過註釋該導出中的所有代碼並測試強制密碼更改。如果我將所有代碼註釋掉了,那麼密碼更改就完美了,代碼會無限期地掛起。
下面是憑據管理器導出的函數
NPGetCaps
DWORD APIENTRY NPGetCaps(DWORD nIndex)
{
DWORD ret = 0;
switch (nIndex)
{
case WNNC_NET_TYPE:
ret = WNNC_CRED_MANAGER; // credential manager
break;
case WNNC_SPEC_VERSION:
// We are using version 5.1 of the spec.
ret = WNNC_SPEC_VERSION51;
break;
case WNNC_DRIVER_VERSION:
ret = 1; // This driver is version 1.
break;
case WNNC_START:
ret = 1; // We are already "started"
break;
}
return ret;
}
NPPasswordChangeNotify
DWORD APIENTRY NPPasswordChangeNotify(LPCWSTR lpAuthentInfoType, LPVOID lpAuthentInfo, LPCWSTR lpPreviousAuthentInfoType, LPVOID lpPreviousAuthentInfo, LPWSTR lpStationName, LPVOID StationHandle, DWORD dwChangeInfo)
{
return WN_SUCCESS;
}
注:以上功能對系統無影響H老化,我已經嘗試完全沒有出口,我仍然得到相同的結果。
NPLogonNotify
DWORD APIENTRY NPLogonNotify(PLUID lpLogon, LPCWSTR lpAuthentInfoType, LPVOID lpAuthentInfo, LPCWSTR lpPreviousAuthentInfoType, LPVOID lpPreviousAuthentInfo, LPWSTR lpStationName, LPVOID StationHandle, LPWSTR *lpLogonScript)
{
lpLogonScript = nullptr;
//auth type can help here to know what we're doing
if (lstrcmpi(lpAuthentInfoType, L"MSV1_0:Interactive") != 0 && lstrcmpiW(lpAuthentInfoType, L"Kerberos:Interactive"))
return WN_SUCCESS;
WCHAR filename[MAX_PATH];
GetModuleFileName(g_Module, filename, MAX_PATH);
wcsrchr(filename, L'\\')[0] = L'\0';
WCHAR exe1Filename[MAX_PATH];
wsprintf(exe1Filename, L"%lS\\exe1.exe", filename);
STARTUPINFOW si = { 0 };
PROCESS_INFORMATION pi = { 0 };
si.cb = sizeof(STARTUPINFO);
if (CreateProcess((LPWSTR)exe1Filename, nullptr, nullptr, nullptr, FALSE, 0, nullptr, nullptr, &si, &pi))
{
WaitForInputIdle(pi.hProcess, INFINITE);
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
}
MSV1_0_INTERACTIVE_LOGON *authInfo = (MSV1_0_INTERACTIVE_LOGON *)lpAuthentInfo;
si = { 0 };
pi = { 0 };
si.cb = sizeof(STARTUPINFO);
((PWSTR)(&((char *)authInfo->UserName.Buffer)[authInfo->UserName.Length]))[0] = L'\0';
WCHAR args[(UNLEN + 14) * 2];
wsprintf(args, L"exe2.exe %lS", authInfo->UserName.Buffer);
WCHAR exe2Path[MAX_PATH];
wsprintf(exe2Path, L"%lS\\exe2.exe", filename);
if (CreateProcess((LPWSTR)exe2Path, (LPWSTR)args, nullptr, nullptr, FALSE, 0, nullptr, nullptr, &si, &pi))
{
WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
}
return WN_SUCCESS;
}
我知道,上面的代碼是非常糟糕的,沒有錯誤檢查,也不安全。我正在做這個測試和學習練習來了解更多關於Credential Managers的信息。
有誰知道爲什麼NPLogonNotify
內的代碼在用戶登錄時可以完美工作,但是當用戶在登錄時被迫更改密碼時會完全掛起系統?
掛在'WaitForInputIdle'或'WaitForSingleObject(pi.hProcess,INFINITE);'我只能評論這個和測試。如果真的掛在這裏(當你不等待時不掛機) - 在你單獨的進程中執行任務。我在之前(在當前winlogon桌面上)啓動調試器並在其下查看 – RbMm
@RbMm好點,我將把它們拿出來看看。我認爲它甚至沒有達到這一點,因爲屏幕上沒有顯示任何內容,但它可能正在顯示,但是顯示爲其他內容或者沒有正常顯示,這會導致它出現凍結。我會用結果更新問題 – vane
您是否嘗試過...調試? – conio