原因分析:
首先這是正常現(xiàn)象(不是木馬也不是病毒),產(chǎn)生的原因是你的小飛機造成的,每次關閉一次,再打開就會有一個新進程,這是Windows自動處理PAC的進程,因為小飛機每次啟用的時候,使用了一個隨機字符串生成PAC,所以每一個新的PAC都對應一個新的HTTP XXXX的進程,重啟一次電腦(而不是關機再開機)可減少這個進程。
解決方法一:等待官方更新
解決方法二:
- HTTP Auto Proxy Detection Worker Process進程的程序文件是"C:WindowsSystem32pacjsworker.exe",由WPAD服務啟動;
- 這些進程不能手工殺死,重啟系統(tǒng)才能解決,用戶退出(logout)再登錄也不行;
- WPAD服務(Win HTTP Web Proxy Auto Discovery Service)的屬性不能修改,通過重啟WPAD服務殺死進程的路也不通;
- 1809版本才會出現(xiàn),在這之前版本的系統(tǒng)上運行正常;
- 情況復現(xiàn):打開SS客戶端,選擇PAC模式,勾選啟用系統(tǒng)代理;然后按電源鍵(或其他方式)讓電腦進入休眠;接著喚醒電腦進入桌面,任務管理器中就多了一個HTTP Auto Proxy Detection Worker Process進程;如此反復進入休眠又啟動,每次都會出現(xiàn)一個新進程;
- 后來發(fā)現(xiàn)不需要休眠也能復現(xiàn)情況:打開SS客戶端,選擇PAC模式,打開任務管理器;然后不斷禁用/啟用系統(tǒng)代理,在任務管理器窗口中可實時看到每次啟用系統(tǒng)代理后都會多一個進程;
- 最新版的SS客戶端依然有這個問題;
- 每次SS啟動系統(tǒng)代理后的PAC地址均不同;
- PAC地址中的secret參數(shù)僅在勾選“保護本地PAC(secure local PAC)”選項時才會出現(xiàn),但t參數(shù)一直都在。
根據(jù)網(wǎng)上知識,加上個人實驗和思考,對問題原因的理解為:WPAD是系統(tǒng)關鍵服務,用戶不能更改;以PAC模式啟動SS時,SS會在LAN配置中設置一個新的PAC腳本地址;WPAD檢測到有新的PAC腳本地址,喚醒一個新的pacjsworker.exe進程監(jiān)聽該地址;PAC地址失效后,監(jiān)聽進程不退出,于是進程堆積,慢慢出現(xiàn)幾十上百個進程的壯觀場景。
總結問題根源:1. Windows 10的進程不自動退出;2. 每次從休眠過來后,SS客戶端生成不同的PAC地址并將其配置到LAN設置中。
把問題搞清楚了,解決方案基本上章口就萊:
- 使用全局模式;全局模式不會設置PAC配置腳本,WPAD服務也就不會拉起新的進程;
- 等待巨硬修復問題;去年下半年就爆出問題,到現(xiàn)在問題依舊,應該有得等(本人最近才更新1809版本,故而發(fā)現(xiàn)得遲);另外我不認為這是巨硬的鍋,他們未必會修復;
- 重新編譯SS客戶端,生成相同的PAC(至少未重啟SS客戶端前PAC地址應一致)。
我的解決方案是重新編譯SS客戶端,做了兩個方案的客戶端:
- 方案一:總是生成相同的PAC地址,除非人工編輯"pac-secret.txt"文件。改動代碼如下:
<pre>// 文件: shadowsocks-csharpControllerServicePACServer.cs
public void UpdateConfiguration(Configuration config)
{
this._config = config;
if (config.secureLocalPac)
{
// 注釋掉部分
// var rd = new byte[32];
// RNG.GetBytes(rd);
// PacSecret = $"&secret={Convert.ToBase64String(rd)}";
if (!File.Exists(PAC_SECRET_FILE))
{
var rd = new byte[32];
RNG.GetBytes(rd);
string secret = Convert.ToBase64String(rd);
PacSecret = $"secret={secret}";
File.WriteAllText(PAC_SECRET_FILE, secret);
}
else
{
PacSecret = $"secret={File.ReadAllText(PAC_SECRET_FILE)}";
}
}
else
{
PacSecret = "";
}
// 注釋掉部分
// PacUrl = $"http://127.0.0.1:{config.localPort}/pac?t={GetTimestamp(DateTime.Now)}{PacSecret}";
PacUrl = $"http://127.0.0.1:{config.localPort}/pac?{PacSecret}";
}
</pre>
這個方案保證不管系統(tǒng)休眠重啟,還是退出SS客戶端再打開,都只會有一個HTTP Auto Proxy Detection Worker Process進程。
- 僅當系統(tǒng)中無PAC進程運行時才生成新的PAC地址并設置到LAN中。代碼如下:
<
pre>// 文件: shadowsocks-csharpControllerShadowsocksController.cs
protected void Reload()
{
Encryption.RNG.Reload();
// some logic in configuration updated the config when saving, we need to read it again
_config = Configuration.Load();
StatisticsConfiguration = StatisticsStrategyConfiguration.Load();
if (privoxyRunner == null) { privoxyRunner = new PrivoxyRunner(); } if (_pacServer == null) { _pacServer = new PACServer(); _pacServer.PACFileChanged += pacServer_PACFileChanged; _pacServer.UserRuleFileChanged += pacServer_UserRuleFileChanged; // 這一行代碼從外部移入 _pacServer.UpdateConfiguration(_config); } // 每次喚醒都更新的代碼刪除 // _pacServer.UpdateConfiguration(_config); if (gfwListUpdater == null) { gfwListUpdater = new GFWListUpdater(); gfwListUpdater.UpdateCompleted += pacServer_PACUpdateCompleted; gfwListUpdater.Error += pacServer_PACUpdateError; }
這個方案保證不退出SS客戶端情況下只有一個pacjsworker.exe進程。缺點是如果頻繁退出并重啟SS客戶端,同樣會出現(xiàn)有大量進程的現(xiàn)象。
根據(jù)源代碼思路,我認為第二種方案更合理,是原作者想要的。當然你應該想得到,我是先根據(jù)網(wǎng)上提示實現(xiàn)方案一,測試達到效果后繼續(xù)思考才做出的方案二。從這個角度也是方案二更合理。
兩個方案的exe文件我都編譯好了,需要請自?。?a rel="nofollow noreferrer">方案一 方案二