Skip to content

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

sockhook

A tiny spice2x hook DLL that makes AVS's keepalive "raw socket" check pass in environments where the process can't obtain CAP_NET_RAW — unprivileged Wine/proot setups such as GameNative or Winlator on Android. It lets AVS-based titles clear the network check without root and without a chroot.

The problem

Games built on the AVS runtime create an ICMP keepalive socket during startup, roughly:

socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);

Raw sockets require the CAP_NET_RAW capability. On a normal desktop Wine install this is usually available, but in unprivileged/sandboxed Linux environments — Android emulation layers like GameNative or Winlator, or any proot/no-root setup — the process can't get that capability, so the call fails with EACCES. AVS reports "failed to create raw socket" and the game's NETWORK CHECK never turns OK.

The conventional workaround on Android is to run the whole stack inside a rooted chroot so raw sockets are permitted. sockhook removes that requirement.

How it works

sockhook uses MinHook to inline-hook the Winsock entry points in ws2_32.dll from inside the game process:

  1. Downgrade the socket. When AVS calls socket() / WSASocketW() with SOCK_RAW, the hook rewrites the request to SOCK_DGRAM and creates a normal datagram socket instead. It records each handle it downgraded.
  2. Satisfy the raw-only setup. AVS then performs raw-only configuration on that handle — setsockopt, bind, WSAIoctl, ioctlsocket — which a datagram socket rejects. For the tracked handles only, the hook lets the real call run and, if it fails, returns success anyway without forwarding the unsupported option to the kernel.

AVS sees every step succeed, treats its keepalive socket as correctly set up, and marks the network OK. Nothing else in the process is affected.

Every intercepted call is written to sockhook.log next to the DLL, so you can see exactly what AVS attempted and where it would otherwise have tripped.

Why faking the check is safe here

The raw ICMP socket exists only for a local liveness keepalive. In a private-server or offline setup the real network liveness is handled by the server's HTTP keepalive, so the local raw-socket path is functionally redundant — there is nothing meaningful being kept alive over ICMP. sockhook only fakes the calls a datagram socket can't accept; the underlying handle is a real ICMP datagram socket, so with ping_group_range configured it can still send/receive ICMP to localhost if anything ever needs it.

This is a compatibility shim, not a network exploit: it changes only the behavior of the game's own socket calls inside its own process.

Compatibility

  • Tested: popn28 (data M39-2025092400) under spice2x.
  • Expected but unconfirmed: other AVS-based titles loaded through spice2x that fail the same raw-socket keepalive check. The hook is game-agnostic — it keys off the SOCK_RAW request, not any specific title — so it should apply broadly, but only pop'n has been verified. Reports welcome.

Requirements

  • Build: mingw-w64 (both i686- and x86_64- targets). MinHook is bundled in third_party/MinHook, so there's nothing else to fetch.
  • Runtime: links only against Wine builtins (kernel32, msvcrt, ws2_32). No extra runtime dependencies.
  • A working spice2x setup for your title. This repository contains no game data — you supply your own.

Download

Prebuilt DLLs are attached to every release — no build step required:

  • sockhook-x86.dll — for 32-bit spice.exe
  • sockhook-x64.dll — for 64-bit spice64.exe

Grab the one that matches your spice executable, drop it next to it, and jump to Usage. Prefer to build from source? See Build below.

Build

MinHook is bundled in this repo, so a plain clone is all you need:

git clone <your-repo-url>
cd sockhook
./build.sh

Output:

build/x86/sockhook.dll   # for 32-bit spice.exe
build/x64/sockhook.dll   # for 64-bit spice64.exe

Manual build

If you'd rather not use the script:

# 32-bit
i686-w64-mingw32-gcc -O2 -Wall -D_WIN32_WINNT=0x0601 \
  -Ithird_party/MinHook/include \
  src/sockhook.c \
  third_party/MinHook/src/*.c third_party/MinHook/src/hde/*.c \
  -shared -static-libgcc -o sockhook.dll -lws2_32 -lkernel32

# 64-bit
x86_64-w64-mingw32-gcc -O2 -Wall -D_WIN32_WINNT=0x0601 \
  -Ithird_party/MinHook/include \
  src/sockhook.c \
  third_party/MinHook/src/*.c third_party/MinHook/src/hde/*.c \
  -shared -static-libgcc -o sockhook.dll -lws2_32 -lkernel32

Usage

  1. Get the DLL of the correct bitness for your spice executable — download it from Releases or build it yourself. 32-bit for spice.exe, 64-bit for spice64.exe.
  2. Drop sockhook.dll next to that executable.
  3. Add it to your launch arguments with spice2x's -K hook flag, alongside any hooks you already load:
spice.exe -K sockhook.dll   # add alongside any other -K hooks you already load

On the next launch the NETWORK CHECK should clear without a rooted chroot. If you want to confirm the hooks fired, check sockhook.log next to the DLL.

Credits

  • MinHook by Tsuda Kageyu — inline hooking library (BSD-2-Clause), bundled in third_party/MinHook.
  • spice2x — the loader whose -K hook interface this plugs into.

Acknowledgments

The engineering, reverse-engineering, and design decisions behind this project are my own — but I'll freely admit it wouldn't have come together without Claude. It was a genuine collaborator for working through the Winsock hooking approach, making sense of AVS's socket behavior, and getting the build and packaging right.

License

MIT — see LICENSE. MinHook is a separate component distributed under its own BSD-2-Clause license.

About

A tiny ws2_32 hook DLL that lets AVS-based titles pass their raw-socket keepalive check in unprivileged Wine/Android setups without root or a chroot.

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages