WinINet 代理设置与注册表位置
2024-03-17 17:33:41

按用户代理时的注册表位置

Windows系统默认是”按用户代理”的,意味着每个系统账户都有属于自己独立的代理设置。我们可以运行命令Inetcpl.cpl来打开IE选项窗口,在”连接”选项卡中点击”局域网设置”便可以显示代理设置界面,
代理设置最终会保存在注册表中。

自动配置部分

1
2
3
4
5
6
[HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings]
"AutoDetect"=dword:00000001
"AutoConfigURL"="http://localhost/test.pac"
"ProxyEnable"=dword:00000001
"ProxyServer"="127.0.0.1:7890"
"ProxyOverride"="<local>"
  • AutoDetect
    自动检测设置开关,通过 Process Monitor 监测发现,打开选项设置窗口后会将其值同步到DefaultConnectionSettings并删除AutoDetect,看上去是一种”升级”操作,将旧设置迁移至新位置,所以尽量还是以DefaultConnectionSettings为准。

  • AutoConfigURL
    PAC文件URL。如果没有值或值为空,表示未启用状态,会尝试从DefaultConnectionSettings获取最近一次的值并显示。
    需要注意的是,PAC 地址应该是一个使用HTTP协议的地址,而不应使用本地文件路径,否则会无法加载,原因见 Windows 10 does not read a PAC file referenced by a file protocol。并且服务器应该为其指定MIME类型为application/x-ns-proxy-autoconfig

  • ProxyEnable
    是否启用代理。

  • ProxyServer
    各协议所使用的代理服务器,用分号分隔。如果不指定具体协议而直接写上服务器与端口号,则表示所有协议使用同一个代理。

  • ProxyOverride
    禁止使用代理服务器的地址列表,通常指定为本地地址。支持通配符,用分号分隔。它同时也是”对于本地地址不使用代理服务器”选项的开关。

代理服务器部分

1
2
3
4
[HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings]
"ProxyEnable"=dword:00000001
"ProxyServer"="http=127.0.0.1:7890;https=127.0.0.1:7890;ftp=127.0.0.1:7890;socks=127.0.0.1:7890"
"ProxyOverride"="localhost;127.*;10.*;172.16.*;172.17.*;172.18.*;172.19.*;172.20.*;172.21.*;172.22.*;172.23.*;172.24.*;172.25.*;172.26.*;172.27.*;172.28.*;172.29.*;172.30.*;172.31.*;192.168.*;<local>"
  • ProxyEnable
    是否启用代理。

  • ProxyServer
    各协议所使用的代理服务器,用分号分隔。如果不指定具体协议而直接写上服务器与端口号,则表示所有协议使用同一个代理。

  • ProxyOverride
    禁止使用代理服务器的地址列表,通常指定为本地地址。支持通配符,用分号分隔。它同时也是”对于本地地址不使用代理服务器”选项的开关。

在IE浏览器中,启动浏览器、开关或关闭代理设置窗口都会将设置同步到DefaultConnectionSettings键值中,读取代理设置时都会以DefaultConnectionSettings中的值为准(缓存代理设置的作用)。
而对于非IE浏览器,则以Internet Settings中的设置为准。

按计算机代理时的注册表位置

运行命令gpedit.msc打开策略编辑器,依次打开”计算机配置”、”管理模板”、”Windows 组件”、”Internet Explorer”,找到”按计算机(而不是按用户)进行代理”,启用这个选项将会在注册表保存一个值

1
2
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\Internet Settings]
"ProxySettingsPerUser"=dword:00000000

值不存在或是非0值,意味着”按用户代理”,否则就是”按计算机代理”。
当系统变为”按计算机代理”后,代理设置的注册表根位置将从HKEY_CURRENT_USER变为HKEY_LOCAL_MACHINE。而且必须使用管理员方式运行IE才能成功修改代理设置。
**要注意的是,按计算机代理后WinINet不会再读取Internet Settings下的设置了,而是直接读取DefaultConnectionSettings**。

解密DefaultConnectionSettings

它是一个未公开的结构体,我们可以在泄露的Windows 2003源码中找到蛛丝马迹,
头文件 proxreg.cxx 中的结构体 INTERNET_PROXY_INFO_EX 就是它了,函数 WriteProxySettings 用于将这个结构体写入注册表,而 ReadProxySettingsDefaultConnectionSettings读取到结构体中,这就是一个序列化,反序列化的过程。

开始的4字节表示结构体大小,同时也用于标识结构体版本,XP到Win10为止仅修改过一次,所以目前只有两种可能的值:0x3C和0x46。
根据源码中的定义,IE5和IE6都是0x3C,也就是第一版的结构体

1
#define INTERNET_PROXY_INFO_EX_VERSION      60      // 60 := IE 5.x & 6.0 format

XP系统自带的是IE6,实际查看一下也确实如此

从Vista的IE7开始,结构体就升级了,变为了0x46。
我编写了一个010 Editor的模板,这样看起来比较直观

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
//------------------------------------------------
//--- 010 Editor v9.0 Binary Template
//
// File:
// Authors:
// Version:
// Purpose:
// Category:
// File Mask:
// ID Bytes:
// History:
//------------------------------------------------

enum PROXY_TYPE {
PROXY_TYPE_DIRECT = 1,
PROXY_TYPE_PROXY = 2,
PROXY_TYPE_AUTO_PROXY_URL = 4,
PROXY_TYPE_AUTO_DETECT = 8
};

struct INTERNET_PROXY_INFO_EX_1 {
DWORD dwStructSize <comment="结构版本">;;
DWORD dwCurrentSettingsVersion <comment="计数器,每次修改会增加">;
PROXY_TYPE dwFlags <comment="代理方式">;
DWORD cbProxy <comment="代理服务器字符串长度">;
CHAR szProxy[cbProxy] <comment="代理服务器地址">;;
DWORD cbProxyBypass <comment="代理忽略列表字符串长度">;
CHAR szProxyBypass[cbProxyBypass] <comment="代理忽略列表">;
DWORD cbAutoConfigUrl;
CHAR szAutoConfigUrl[cbAutoConfigUrl];
DWORD dwAutoDiscoveryFlags;
DWORD cbLastKnownGoodAutoConfigUrl;
CHAR szLastKnownGoodAutoConfigUrl[cbLastKnownGoodAutoConfigUrl];
FILETIME ftLastKnownDetectTime;
DWORD dwDetectedInterfaceIpCount;
DWORD arrDetectedInterfaceIp[dwDetectedInterfaceIpCount];
DWORD cbAutoconfigSecondaryUrl;
CHAR szAutoconfigSecondaryUrl[cbAutoconfigSecondaryUrl];
DWORD dwAutoconfigReloadDelayMins;
};

struct INTERNET_PROXY_INFO_EX_2 {
INTERNET_PROXY_INFO_EX_1 info1;
DWORD dwUnknown;
};

local DWORD dwVersion = ReadUInt();
if (dwVersion == 0x3C) {
INTERNET_PROXY_INFO_EX_1 info;
} else {
INTERNET_PROXY_INFO_EX_2 info;
}


从头部的4字节看,0x46 - 0x3C = 0xA,也就是在其dll内部的结构体多了10字节,但是持久化到注册表后只多了4字节。

  • dwFlags
    dwFlags实际上就是常量PROXY_TYPE_DIRECT和其他三个值的组合。
    1
    2
    3
    4
    #define PROXY_TYPE_DIRECT                               0x00000001   // direct to net
    #define PROXY_TYPE_PROXY 0x00000002 // via named proxy
    #define PROXY_TYPE_AUTO_PROXY_URL 0x00000004 // autoproxy URL
    #define PROXY_TYPE_AUTO_DETECT 0x00000008 // use autoproxy detection
  • 自动配置URL
    自动代理的URL有两个,一个主一个次,但是我们在IE设置中只能设置一个主要的,次要的URL是怎么配置进去的呢?这就是通过之前的一篇文章 IE自动部署工具包IEAK 中介绍过的INS文件写入进去的
    1
    2
    3
    4
    5
    6
    [URL]
    AutoDetect=1
    AutoConfig=1
    AutoConfigTime=1
    AutoConfigURL=http://localhost/test1.pac
    AutoConfigJSURL=http://localhost/test2.pac
    其中AutoConfigJSURL就是次选代理URL。但是经过测试发现,次选URL永远用不上,当AutoConfigURL无法访问时,网络会产生直连,而没有寻找次选代理URL。

总结

  1. 按用户代理时,WinINetInternet Settings中的值为准。但IE是个例外,IE以DefaultConnectionSettings中的值为准。
  2. 按计算机代理时,WinINetDefaultConnectionSettings中的值为准,在Internet Settings下的设置没有任何效果。
  3. 64位系统下,如果用直接修改注册表的方式改代理,要注意注册表WOW6432Node下的位置也要一起改。

相关阅读

How to disable automatic proxy caching in Internet Explorer

https://stackoverflow.com/questions/4283027/whats-the-format-of-the-defaultconnectionsettings-value-in-the-windows-registry

https://stackoverflow.com/questions/1674119/what-key-in-windows-registry-disables-ie-connection-parameter-automatically-det