The solution I ended up going with is the app opens a socket to listen on, writes out the port it got to a file in SIMULATOR_SHARED_RESOURCES_DIRECTORY, and the test runner reads that file and connects to the port.
I tried using a unix domain socket, but (as the app itself is in C#) the .NET API for that kept throwing PlatformNotSupportedException. I really don't know if there was a real error or if .NET just thinks iOS doesn't support domain sockets.
My approach did still require adding an entitlement, so I'll just have to modify my build script to only include that in the debug build.