寻找HyperV端口占用原因

大类
Env
技术标签
逆向-Windows
原理研究-Windows
优先级
Medium
开始日期
Oct 27, 2021
状态
Monitoring
Public
Public
最后更新
Dec 29, 2021

起因

EnableExcludedPortRange这个东西不管用了
而且WSL开启之后占用端口奇多无比,无法正常使用
 

首次探索(2021.10.27)

  • 逆向winnat.sys入手,通过函数名找到分配端口的函数是SlbNatAllocPortsWsk,每次分配PortChunkSize大小的端口chunk,默认大小100
    • 改成40之后,WSL网络并发性能明显下降,无法apt更新
  • 调研了一下WinNat的运作方式,认为应该都是通过Nsi的一套东西走的, 所以找到WinNat对应的moduleID:NPI_MS_WINNAT_MODULEID,找到GUID:{eb004a209b1a11d4-9123-0050047759bc},全局搜索找到了这些dll
    • gns.dll:Guest Network Service
    • HostNetSvc.dll:Host Network Service
    • ipnathlp.dll:IP Nat Helper, SharedAccess服务
    • ipxlatcfg.dll
    • netiomig.dll
    • wbem\NetNat.dll:PowerShell MSFT_NetNat的provider
    • netttcim.dll
 

二次探索(2021.12.28)

  • 这次建立了Windows 11 Insider的虚拟机,这样就可以进行内核调试打断点了
  • NetNatExternalAddress的创建在winnat中,excludedportrange端口分配最后有SlbNatAllocPortsWsk执行
    • SlbNatCreateExternalAddressForFamilySlbNatAllocPortCallbackSlbNatAllocatePortsSlbNatAllocPortsWsk
    • SlbNatCreateStaticMappingSlbNatAllocatePorts
  • 断点断在SlbNatAllocPortsWsk,找到用户态调用均位于ipnathlp.dll内,由RPC调用该dll,随后该dll触发至内核中
    • bp winnat!SlbNatAllocPortsWsk
    • 逆向ipnathlp.dll中的RPC服务器GUID,搜索找到IpNatHlpClient.dll,由HostNetSvc.dll引入
    • 导出的函数为V2IpNatHlpStartSharingInternalPrefix
  • HostNetSvc.dll中在HNS::Service::Resource::ICSResource::StartSharing调用V2IpNatHlpStartSharingInternalPrefix,通过HNS::Service::Resource::ICSResource::SharingDisabled标志位控制是否分配动态地址
    • DisableSharing标志位的计算过于复杂,无法逆向,在网络描述JSON中存在,但是修改后覆盖上去不生效
    • 直接patch这个方法为全局disable sharing,WSL无网络
  • x64dbg断入WmiPrvSe断点V2IpNatHlpStartSharingInternalPrefix,在重新生成时回溯找到最初的栈帧
    • 发现HNS::Service::Core::IsAdapterSuitableForMirroring控制某个adapter具体生成不生成对应的HCN网络
    • Patch这个函数为永远不生成,成功
  • 随后发现Default Switch也是可以直接删除的,全部删除后,占用端口仅剩2000余个,不影响
 

三次探索(2022.6.5)

  • 重新分析了HNS::Service::Resource::ICSResource::SharingDisabled,发现Flags的128控制是否开启Sharing