diff --git a/.github/patch_go122/48042aa09c2f878c4faa576948b07fe625c4707a.diff b/.github/patch_go122/48042aa09c2f878c4faa576948b07fe625c4707a.diff new file mode 100644 index 0000000..2c68233 --- /dev/null +++ b/.github/patch_go122/48042aa09c2f878c4faa576948b07fe625c4707a.diff @@ -0,0 +1,54 @@ +diff --git a/src/syscall/exec_windows.go b/src/syscall/exec_windows.go +index 06e684c7116b4..b311a5c74684b 100644 +--- a/src/syscall/exec_windows.go ++++ b/src/syscall/exec_windows.go +@@ -319,17 +319,6 @@ func StartProcess(argv0 string, argv []string, attr *ProcAttr) (pid int, handle + } + } + +- var maj, min, build uint32 +- rtlGetNtVersionNumbers(&maj, &min, &build) +- isWin7 := maj < 6 || (maj == 6 && min <= 1) +- // NT kernel handles are divisible by 4, with the bottom 3 bits left as +- // a tag. The fully set tag correlates with the types of handles we're +- // concerned about here. Except, the kernel will interpret some +- // special handle values, like -1, -2, and so forth, so kernelbase.dll +- // checks to see that those bottom three bits are checked, but that top +- // bit is not checked. +- isLegacyWin7ConsoleHandle := func(handle Handle) bool { return isWin7 && handle&0x10000003 == 3 } +- + p, _ := GetCurrentProcess() + parentProcess := p + if sys.ParentProcess != 0 { +@@ -338,15 +327,7 @@ func StartProcess(argv0 string, argv []string, attr *ProcAttr) (pid int, handle + fd := make([]Handle, len(attr.Files)) + for i := range attr.Files { + if attr.Files[i] > 0 { +- destinationProcessHandle := parentProcess +- +- // On Windows 7, console handles aren't real handles, and can only be duplicated +- // into the current process, not a parent one, which amounts to the same thing. +- if parentProcess != p && isLegacyWin7ConsoleHandle(Handle(attr.Files[i])) { +- destinationProcessHandle = p +- } +- +- err := DuplicateHandle(p, Handle(attr.Files[i]), destinationProcessHandle, &fd[i], 0, true, DUPLICATE_SAME_ACCESS) ++ err := DuplicateHandle(p, Handle(attr.Files[i]), parentProcess, &fd[i], 0, true, DUPLICATE_SAME_ACCESS) + if err != nil { + return 0, 0, err + } +@@ -377,14 +358,6 @@ func StartProcess(argv0 string, argv []string, attr *ProcAttr) (pid int, handle + + fd = append(fd, sys.AdditionalInheritedHandles...) + +- // On Windows 7, console handles aren't real handles, so don't pass them +- // through to PROC_THREAD_ATTRIBUTE_HANDLE_LIST. +- for i := range fd { +- if isLegacyWin7ConsoleHandle(fd[i]) { +- fd[i] = 0 +- } +- } +- + // The presence of a NULL handle in the list is enough to cause PROC_THREAD_ATTRIBUTE_HANDLE_LIST + // to treat the entire list as empty, so remove NULL handles. + j := 0 \ No newline at end of file diff --git a/.github/patch_go122/693def151adff1af707d82d28f55dba81ceb08e1.diff b/.github/patch_go122/693def151adff1af707d82d28f55dba81ceb08e1.diff new file mode 100644 index 0000000..ca41ec3 --- /dev/null +++ b/.github/patch_go122/693def151adff1af707d82d28f55dba81ceb08e1.diff @@ -0,0 +1,158 @@ +diff --git a/src/crypto/rand/rand.go b/src/crypto/rand/rand.go +index 62738e2cb1a7d..d0dcc7cc71fc0 100644 +--- a/src/crypto/rand/rand.go ++++ b/src/crypto/rand/rand.go +@@ -15,7 +15,7 @@ import "io" + // available, /dev/urandom otherwise. + // On OpenBSD and macOS, Reader uses getentropy(2). + // On other Unix-like systems, Reader reads from /dev/urandom. +-// On Windows systems, Reader uses the RtlGenRandom API. ++// On Windows systems, Reader uses the ProcessPrng API. + // On JS/Wasm, Reader uses the Web Crypto API. + // On WASIP1/Wasm, Reader uses random_get from wasi_snapshot_preview1. + var Reader io.Reader +diff --git a/src/crypto/rand/rand_windows.go b/src/crypto/rand/rand_windows.go +index 6c0655c72b692..7380f1f0f1e6e 100644 +--- a/src/crypto/rand/rand_windows.go ++++ b/src/crypto/rand/rand_windows.go +@@ -15,11 +15,8 @@ func init() { Reader = &rngReader{} } + + type rngReader struct{} + +-func (r *rngReader) Read(b []byte) (n int, err error) { +- // RtlGenRandom only returns 1<<32-1 bytes at a time. We only read at +- // most 1<<31-1 bytes at a time so that this works the same on 32-bit +- // and 64-bit systems. +- if err := batched(windows.RtlGenRandom, 1<<31-1)(b); err != nil { ++func (r *rngReader) Read(b []byte) (int, error) { ++ if err := windows.ProcessPrng(b); err != nil { + return 0, err + } + return len(b), nil +diff --git a/src/internal/syscall/windows/syscall_windows.go b/src/internal/syscall/windows/syscall_windows.go +index ab4ad2ec64108..5854ca60b5cef 100644 +--- a/src/internal/syscall/windows/syscall_windows.go ++++ b/src/internal/syscall/windows/syscall_windows.go +@@ -373,7 +373,7 @@ func ErrorLoadingGetTempPath2() error { + //sys DestroyEnvironmentBlock(block *uint16) (err error) = userenv.DestroyEnvironmentBlock + //sys CreateEvent(eventAttrs *SecurityAttributes, manualReset uint32, initialState uint32, name *uint16) (handle syscall.Handle, err error) = kernel32.CreateEventW + +-//sys RtlGenRandom(buf []byte) (err error) = advapi32.SystemFunction036 ++//sys ProcessPrng(buf []byte) (err error) = bcryptprimitives.ProcessPrng + + type FILE_ID_BOTH_DIR_INFO struct { + NextEntryOffset uint32 +diff --git a/src/internal/syscall/windows/zsyscall_windows.go b/src/internal/syscall/windows/zsyscall_windows.go +index e3f6d8d2a2208..5a587ad4f146c 100644 +--- a/src/internal/syscall/windows/zsyscall_windows.go ++++ b/src/internal/syscall/windows/zsyscall_windows.go +@@ -37,13 +37,14 @@ func errnoErr(e syscall.Errno) error { + } + + var ( +- modadvapi32 = syscall.NewLazyDLL(sysdll.Add("advapi32.dll")) +- modiphlpapi = syscall.NewLazyDLL(sysdll.Add("iphlpapi.dll")) +- modkernel32 = syscall.NewLazyDLL(sysdll.Add("kernel32.dll")) +- modnetapi32 = syscall.NewLazyDLL(sysdll.Add("netapi32.dll")) +- modpsapi = syscall.NewLazyDLL(sysdll.Add("psapi.dll")) +- moduserenv = syscall.NewLazyDLL(sysdll.Add("userenv.dll")) +- modws2_32 = syscall.NewLazyDLL(sysdll.Add("ws2_32.dll")) ++ modadvapi32 = syscall.NewLazyDLL(sysdll.Add("advapi32.dll")) ++ modbcryptprimitives = syscall.NewLazyDLL(sysdll.Add("bcryptprimitives.dll")) ++ modiphlpapi = syscall.NewLazyDLL(sysdll.Add("iphlpapi.dll")) ++ modkernel32 = syscall.NewLazyDLL(sysdll.Add("kernel32.dll")) ++ modnetapi32 = syscall.NewLazyDLL(sysdll.Add("netapi32.dll")) ++ modpsapi = syscall.NewLazyDLL(sysdll.Add("psapi.dll")) ++ moduserenv = syscall.NewLazyDLL(sysdll.Add("userenv.dll")) ++ modws2_32 = syscall.NewLazyDLL(sysdll.Add("ws2_32.dll")) + + procAdjustTokenPrivileges = modadvapi32.NewProc("AdjustTokenPrivileges") + procDuplicateTokenEx = modadvapi32.NewProc("DuplicateTokenEx") +@@ -55,7 +56,7 @@ var ( + procQueryServiceStatus = modadvapi32.NewProc("QueryServiceStatus") + procRevertToSelf = modadvapi32.NewProc("RevertToSelf") + procSetTokenInformation = modadvapi32.NewProc("SetTokenInformation") +- procSystemFunction036 = modadvapi32.NewProc("SystemFunction036") ++ procProcessPrng = modbcryptprimitives.NewProc("ProcessPrng") + procGetAdaptersAddresses = modiphlpapi.NewProc("GetAdaptersAddresses") + procCreateEventW = modkernel32.NewProc("CreateEventW") + procGetACP = modkernel32.NewProc("GetACP") +@@ -179,12 +180,12 @@ func SetTokenInformation(tokenHandle syscall.Token, tokenInformationClass uint32 + return + } + +-func RtlGenRandom(buf []byte) (err error) { ++func ProcessPrng(buf []byte) (err error) { + var _p0 *byte + if len(buf) > 0 { + _p0 = &buf[0] + } +- r1, _, e1 := syscall.Syscall(procSystemFunction036.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), 0) ++ r1, _, e1 := syscall.Syscall(procProcessPrng.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), 0) + if r1 == 0 { + err = errnoErr(e1) + } +diff --git a/src/runtime/os_windows.go b/src/runtime/os_windows.go +index 8ca8d7790909e..3772a864b2ff4 100644 +--- a/src/runtime/os_windows.go ++++ b/src/runtime/os_windows.go +@@ -127,15 +127,8 @@ var ( + _WriteFile, + _ stdFunction + +- // Use RtlGenRandom to generate cryptographically random data. +- // This approach has been recommended by Microsoft (see issue +- // 15589 for details). +- // The RtlGenRandom is not listed in advapi32.dll, instead +- // RtlGenRandom function can be found by searching for SystemFunction036. +- // Also some versions of Mingw cannot link to SystemFunction036 +- // when building executable as Cgo. So load SystemFunction036 +- // manually during runtime startup. +- _RtlGenRandom stdFunction ++ // Use ProcessPrng to generate cryptographically random data. ++ _ProcessPrng stdFunction + + // Load ntdll.dll manually during startup, otherwise Mingw + // links wrong printf function to cgo executable (see issue +@@ -151,11 +144,11 @@ var ( + ) + + var ( +- advapi32dll = [...]uint16{'a', 'd', 'v', 'a', 'p', 'i', '3', '2', '.', 'd', 'l', 'l', 0} +- ntdlldll = [...]uint16{'n', 't', 'd', 'l', 'l', '.', 'd', 'l', 'l', 0} +- powrprofdll = [...]uint16{'p', 'o', 'w', 'r', 'p', 'r', 'o', 'f', '.', 'd', 'l', 'l', 0} +- winmmdll = [...]uint16{'w', 'i', 'n', 'm', 'm', '.', 'd', 'l', 'l', 0} +- ws2_32dll = [...]uint16{'w', 's', '2', '_', '3', '2', '.', 'd', 'l', 'l', 0} ++ bcryptprimitivesdll = [...]uint16{'b', 'c', 'r', 'y', 'p', 't', 'p', 'r', 'i', 'm', 'i', 't', 'i', 'v', 'e', 's', '.', 'd', 'l', 'l', 0} ++ ntdlldll = [...]uint16{'n', 't', 'd', 'l', 'l', '.', 'd', 'l', 'l', 0} ++ powrprofdll = [...]uint16{'p', 'o', 'w', 'r', 'p', 'r', 'o', 'f', '.', 'd', 'l', 'l', 0} ++ winmmdll = [...]uint16{'w', 'i', 'n', 'm', 'm', '.', 'd', 'l', 'l', 0} ++ ws2_32dll = [...]uint16{'w', 's', '2', '_', '3', '2', '.', 'd', 'l', 'l', 0} + ) + + // Function to be called by windows CreateThread +@@ -251,11 +244,11 @@ func windowsLoadSystemLib(name []uint16) uintptr { + } + + func loadOptionalSyscalls() { +- a32 := windowsLoadSystemLib(advapi32dll[:]) +- if a32 == 0 { +- throw("advapi32.dll not found") ++ bcryptPrimitives := windowsLoadSystemLib(bcryptprimitivesdll[:]) ++ if bcryptPrimitives == 0 { ++ throw("bcryptprimitives.dll not found") + } +- _RtlGenRandom = windowsFindfunc(a32, []byte("SystemFunction036\000")) ++ _ProcessPrng = windowsFindfunc(bcryptPrimitives, []byte("ProcessPrng\000")) + + n32 := windowsLoadSystemLib(ntdlldll[:]) + if n32 == 0 { +@@ -531,7 +524,7 @@ func osinit() { + //go:nosplit + func readRandom(r []byte) int { + n := 0 +- if stdcall2(_RtlGenRandom, uintptr(unsafe.Pointer(&r[0])), uintptr(len(r)))&0xff != 0 { ++ if stdcall2(_ProcessPrng, uintptr(unsafe.Pointer(&r[0])), uintptr(len(r)))&0xff != 0 { + n = len(r) + } + return n \ No newline at end of file diff --git a/.github/patch_go122/7c1157f9544922e96945196b47b95664b1e39108.diff b/.github/patch_go122/7c1157f9544922e96945196b47b95664b1e39108.diff new file mode 100644 index 0000000..c1fc5f6 --- /dev/null +++ b/.github/patch_go122/7c1157f9544922e96945196b47b95664b1e39108.diff @@ -0,0 +1,162 @@ +diff --git a/src/net/hook_windows.go b/src/net/hook_windows.go +index ab8656cbbf343..28c49cc6de7e7 100644 +--- a/src/net/hook_windows.go ++++ b/src/net/hook_windows.go +@@ -14,7 +14,6 @@ var ( + testHookDialChannel = func() { time.Sleep(time.Millisecond) } // see golang.org/issue/5349 + + // Placeholders for socket system calls. +- socketFunc func(int, int, int) (syscall.Handle, error) = syscall.Socket + wsaSocketFunc func(int32, int32, int32, *syscall.WSAProtocolInfo, uint32, uint32) (syscall.Handle, error) = windows.WSASocket + connectFunc func(syscall.Handle, syscall.Sockaddr) error = syscall.Connect + listenFunc func(syscall.Handle, int) error = syscall.Listen +diff --git a/src/net/internal/socktest/main_test.go b/src/net/internal/socktest/main_test.go +index 0197feb3f199a..967ce6795aedb 100644 +--- a/src/net/internal/socktest/main_test.go ++++ b/src/net/internal/socktest/main_test.go +@@ -2,7 +2,7 @@ + // Use of this source code is governed by a BSD-style + // license that can be found in the LICENSE file. + +-//go:build !js && !plan9 && !wasip1 ++//go:build !js && !plan9 && !wasip1 && !windows + + package socktest_test + +diff --git a/src/net/internal/socktest/main_windows_test.go b/src/net/internal/socktest/main_windows_test.go +deleted file mode 100644 +index df1cb97784b51..0000000000000 +--- a/src/net/internal/socktest/main_windows_test.go ++++ /dev/null +@@ -1,22 +0,0 @@ +-// Copyright 2015 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. +- +-package socktest_test +- +-import "syscall" +- +-var ( +- socketFunc func(int, int, int) (syscall.Handle, error) +- closeFunc func(syscall.Handle) error +-) +- +-func installTestHooks() { +- socketFunc = sw.Socket +- closeFunc = sw.Closesocket +-} +- +-func uninstallTestHooks() { +- socketFunc = syscall.Socket +- closeFunc = syscall.Closesocket +-} +diff --git a/src/net/internal/socktest/sys_windows.go b/src/net/internal/socktest/sys_windows.go +index 8c1c862f33c9b..1c42e5c7f34b7 100644 +--- a/src/net/internal/socktest/sys_windows.go ++++ b/src/net/internal/socktest/sys_windows.go +@@ -9,38 +9,6 @@ import ( + "syscall" + ) + +-// Socket wraps syscall.Socket. +-func (sw *Switch) Socket(family, sotype, proto int) (s syscall.Handle, err error) { +- sw.once.Do(sw.init) +- +- so := &Status{Cookie: cookie(family, sotype, proto)} +- sw.fmu.RLock() +- f, _ := sw.fltab[FilterSocket] +- sw.fmu.RUnlock() +- +- af, err := f.apply(so) +- if err != nil { +- return syscall.InvalidHandle, err +- } +- s, so.Err = syscall.Socket(family, sotype, proto) +- if err = af.apply(so); err != nil { +- if so.Err == nil { +- syscall.Closesocket(s) +- } +- return syscall.InvalidHandle, err +- } +- +- sw.smu.Lock() +- defer sw.smu.Unlock() +- if so.Err != nil { +- sw.stats.getLocked(so.Cookie).OpenFailed++ +- return syscall.InvalidHandle, so.Err +- } +- nso := sw.addLocked(s, family, sotype, proto) +- sw.stats.getLocked(nso.Cookie).Opened++ +- return s, nil +-} +- + // WSASocket wraps [syscall.WSASocket]. + func (sw *Switch) WSASocket(family, sotype, proto int32, protinfo *syscall.WSAProtocolInfo, group uint32, flags uint32) (s syscall.Handle, err error) { + sw.once.Do(sw.init) +diff --git a/src/net/main_windows_test.go b/src/net/main_windows_test.go +index 07f21b72eb1fc..bc024c0bbd82d 100644 +--- a/src/net/main_windows_test.go ++++ b/src/net/main_windows_test.go +@@ -8,7 +8,6 @@ import "internal/poll" + + var ( + // Placeholders for saving original socket system calls. +- origSocket = socketFunc + origWSASocket = wsaSocketFunc + origClosesocket = poll.CloseFunc + origConnect = connectFunc +@@ -18,7 +17,6 @@ var ( + ) + + func installTestHooks() { +- socketFunc = sw.Socket + wsaSocketFunc = sw.WSASocket + poll.CloseFunc = sw.Closesocket + connectFunc = sw.Connect +@@ -28,7 +26,6 @@ func installTestHooks() { + } + + func uninstallTestHooks() { +- socketFunc = origSocket + wsaSocketFunc = origWSASocket + poll.CloseFunc = origClosesocket + connectFunc = origConnect +diff --git a/src/net/sock_windows.go b/src/net/sock_windows.go +index fa11c7af2e727..5540135a2c43e 100644 +--- a/src/net/sock_windows.go ++++ b/src/net/sock_windows.go +@@ -19,21 +19,6 @@ func maxListenerBacklog() int { + func sysSocket(family, sotype, proto int) (syscall.Handle, error) { + s, err := wsaSocketFunc(int32(family), int32(sotype), int32(proto), + nil, 0, windows.WSA_FLAG_OVERLAPPED|windows.WSA_FLAG_NO_HANDLE_INHERIT) +- if err == nil { +- return s, nil +- } +- // WSA_FLAG_NO_HANDLE_INHERIT flag is not supported on some +- // old versions of Windows, see +- // https://msdn.microsoft.com/en-us/library/windows/desktop/ms742212(v=vs.85).aspx +- // for details. Just use syscall.Socket, if windows.WSASocket failed. +- +- // See ../syscall/exec_unix.go for description of ForkLock. +- syscall.ForkLock.RLock() +- s, err = socketFunc(family, sotype, proto) +- if err == nil { +- syscall.CloseOnExec(s) +- } +- syscall.ForkLock.RUnlock() + if err != nil { + return syscall.InvalidHandle, os.NewSyscallError("socket", err) + } +diff --git a/src/syscall/exec_windows.go b/src/syscall/exec_windows.go +index 0a93bc0a80d4e..06e684c7116b4 100644 +--- a/src/syscall/exec_windows.go ++++ b/src/syscall/exec_windows.go +@@ -14,6 +14,7 @@ import ( + "unsafe" + ) + ++// ForkLock is not used on Windows. + var ForkLock sync.RWMutex + + // EscapeArg rewrites command line argument s as prescribed \ No newline at end of file diff --git a/.github/workflows/auto-build.yml b/.github/workflows/auto-build.yml index 4104d74..893f733 100644 --- a/.github/workflows/auto-build.yml +++ b/.github/workflows/auto-build.yml @@ -230,8 +230,25 @@ jobs: - name: Install Go uses: actions/setup-go@v5 with: - go-version: '1.20' + go-version: "1.22" cache-dependency-path: sealdice-core/go.sum + + # copy from https://github.com/MetaCubeX/mihomo/blob/0e228765fce4d709af1e672426dea5294e6b7544/.github/workflows/build.yml#L121-L141 + # modify from https://github.com/restic/restic/issues/4636#issuecomment-1896455557 + # this patch file only works on golang1.22.x + # that means after golang1.23 release it must be changed + # revert: + # 693def151adff1af707d82d28f55dba81ceb08e1: "crypto/rand,runtime: switch RtlGenRandom for ProcessPrng" + # 7c1157f9544922e96945196b47b95664b1e39108: "net: remove sysSocket fallback for Windows 7" + # 48042aa09c2f878c4faa576948b07fe625c4707a: "syscall: remove Windows 7 console handle workaround" + - name: Revert Golang1.22 commit for Windows7/8 + if: ${{ matrix.goos == 'windows' }} + run: | + cd $(go env GOROOT) + patch --verbose -R -p 1 < $GITHUB_WORKSPACE/.github/patch_go122/693def151adff1af707d82d28f55dba81ceb08e1.diff + patch --verbose -R -p 1 < $GITHUB_WORKSPACE/.github/patch_go122/7c1157f9544922e96945196b47b95664b1e39108.diff + patch --verbose -R -p 1 < $GITHUB_WORKSPACE/.github/patch_go122/48042aa09c2f878c4faa576948b07fe625c4707a.diff + - name: Install Dependencies working-directory: ./sealdice-core run: | @@ -299,7 +316,7 @@ jobs: GOOS: ${{ matrix.goos }} GOARCH: ${{ matrix.goarch }} GO111MODULE: on - CGO_ENABLED: ${{ matrix.goos == 'windows' && 1 || 0 }} + CGO_ENABLED: 1 CGO_FLAGS: -Werror=unused-variable -Werror=implicit-function-declaration -O2 -H=windowsgui CUR_TIME: ${{ steps.currentTime.outputs.time }} SEAL_TRUSTED_PRIVATE_KEY: ${{ secrets.SEAL_TRUSTED_PRIVATE_KEY }} @@ -343,7 +360,7 @@ jobs: - name: Install Go uses: actions/setup-go@v5 with: - go-version: '1.20' + go-version: "1.22" cache-dependency-path: sealdice-core/go.sum - name: Install dependencies working-directory: ./sealdice-core @@ -407,7 +424,7 @@ jobs: - name: Install Go uses: actions/setup-go@v5 with: - go-version: '1.20' + go-version: "1.22" cache-dependency-path: sealdice-core/go.sum - name: Install dependencies working-directory: ./sealdice-core @@ -752,7 +769,7 @@ jobs: name: 'Latest Beta Build ${{ steps.currentTime.outputs.time }}' prerelease: true body: '> ⚠️注意️️:这是自动构建的 Beta 版本,非正式版本!' - artifacts: | + artifacts: | dist/sealdice* allowUpdates: true removeArtifacts: true