Aug 24 2012

Playing Red Alert 2 with Network using Wine

Few months ago, I bought a MacBook air and I’m pretty satisfied. One of the problems I’ve encountered, Is playing old games.

Every now and then, You will find an old game that you wish to play again. The problem is, that most of the old games doesn’t have a mac version, and even if so not an intel processor mac version.

One of those old games I wished to play was Red Alert 2. I’ve been in a friend house in the north, and he had a copy of the game, and we decided why not giving it a shot.

I’ve tried to launch the game with Wine, and it launched perfectly, the only problem was that network play didn’t work at all.

The first problem was that Red Alert 2 uses IPX which is a obsolete and most OS doesn’t support any longer. Luckily, someone else solved that problem for me, and created a patch that converts the IPX to UDP. All you need to do, is to extract this patch to the Red Alert 2 directory. What the patch does is pretty simple, the name of the DLL is “wsock32.dll” so when the process tries to load winsock, instead of getting the original Windows DLL, it will get our new DLL which hooks three major functions: socket, bind and sendto (and some other minor ones in order to trick the process to believe it is using IPX). The changes in those function replaces all the IPX socket creation request with UDP socket, and the IPX message sending with UDP broadcast.

This solution worked perfectly on Windows, but didn’t work at all on my Mac while using Wine.

The first problem with Wine was that the new DLL wasn’t even loaded. The reason for that is that Wine has some built-in implementation for well-known DLLs such as wsock32. But, Luckily enough, has the ability to override this behavior. The user will have to launch winecfg and add an overwrite rule for wsock32 (selecting native first, and then built-in).

Now the solution worked only partially, Still when clicking on “Network” on the main menu nothing happened, but when going to Options->Network it seemed like the game thinks that IPX is available. After some debugging (Launching OllyDbg on Wine is weird!) I’ve found out that the binding of the sockets fails with the error: WSAEACCES. After few minutes trying to figure out why, I’ve discovered that the default port the patch is using is 320. But all-in-all, the game is running on a unix-based OS, meaning, all ports under 1024 requires special privileges.

The first solution I thought of was to patch-the-patch so it will use another port. But then I’ve discovered that this port is not hard-coded. Meaning, The patch extracts the port from somewhere in the binding of the IPX. After playing around a bit with the configuration I’ve figured out that the way to affect the port was to change the “Socket Number” parameter in the game (Options->Network  screen). When I’ve changed it to 1000 suddenly everything worked (This value is not the port that will be used, but only influence it. Changing it to 1000 will change the port to be 59459 which is good enough).

NOTE: All of your clients must have the same socket number so they will be able to communicate with each other, otherwise they won’t be able to find each other.


Aug 2 2012

Hooking StartService

In the past two days, I was looking for a way to detect when service starts and prevent it.
At first I thought it would be rather “easy”, All I need to do is to create a filter-driver and catch the request for a service creation and that’s it.

Unfortunately, It’s not that “easy”. I thought there should be a representation of services in the kernel, but as it seems, there are none!
When one calls the StartService function, All it does is to send RPC message to services.exe. Then services.exe do all what counts: checks the service’s configuration, checking the dependencies, calls CreateProcess if needed, etc.
In all this procedure, the only kernel calls are the delivery of the RPC  (which you might hook if you are very, very sadistic), and a lot of registry related functions (reading/writing configurations), and of course a call to CreateProcess if needed, with no indication that the process is a service what-so-ever (remember, not all services are hosted in a unique process, some services can share the same process).
As it seems, there is just no way to determine when a service was launched from the kernel’s point-of-view.

So what should one do?

One can inject a DLL to services.exe and make a detour to RStartService(the function that handles the StartService RPC). Why should you hook that function and not StartService(system wide)? Because a service can be launched from a remote computer, therefor StartService won’t be called on the specific computer at all (and of course, a developer can implement the StartService by himself by calling the RPC directly, so even local commands might not be detected).

Note: If you want to detect a specific service from launching (i.e. check the service name and decide whether to block that service), hooking RStartService won’t be good enough.
Because RStartService won’t be called for the dependencies of the service the user launched, only the service itself. If one would like to fully block a specific service, it would be better to hook ScStartService (which is the function that actually starts every service).

This site is hosted by: