Did you know? elitepvpers has its own image host, epvpimg.com.
This is a discussion on Silkroad Multiclient within the General Coding forum part of the Coders Den category; Hi, long time no post. Took some time today to get my hands on bigger games like Silkroad, good time ...
Hi, long time no post. Took some time today to get my hands on bigger games like Silkroad, good time for it as a new patch disabled multiclients and multiclient is extremely useful in SRO.
Alright, here's the technical detail.
When you start sro_client.exe by hand it says "Run Silkroad.exe". How does sro_client.exe know who the caller is? Most probably because it gets passed some commandline args. So I wrote a little tool that I called sro_client.exe, put it into the Silkroad directory and launched Silkroad.exe to see the arguments.
They looked like
sro_client.exe [randomnumber] /18 0 0
No clue what the randomly looking number is or what the rest means but when you launch sro_client.exe like this it doesn't complain. Alright.
If you try to launch a second SRO it says "Silkroad is already running!" or something like that. So let's fix it.
I launched IDA and disassembled sro_client.exe which takes quite some time. Because I knew the technique used to make a program unique are mutexes, I searched for CreateMutex references and I think there were two. So basically had to patch the code to ignore ERROR_ALREADY_EXISTS, the error CreateMutex returns if the mutex already exists. Wrote a launcher for, tried it but after some time of loading a messagebox with unreadable text appeared and SRO quitted. Crap.
If I could've read the text I could've searched for the stringref and see what caused it but thanks to the gibberish I had to go through the shitlong list of MessageBox xrefs to see what rougly looked like the one I saw and eventually found it.
As you see I already commented it. We see a call, a test eax,eax and a jump we WANT to take place because else the crap message is shown. We could patch another jump but I wanted to know what the problem was and had a look at the routine.
Because I knew eax was zero when the message box appeared I looked for early retn out of the routine and found it.
It checked if a call to bind() failed. Well, when can bind() fail? When the port we're trying to bind to is taken and indeed, the port SRO tries to bind to is hardcoded:
Makes sense. First SRO binds to 15779, second one tries to do that, too, bind() fails, SRO talks gibberish, quits. To solve this we have to make sure, every instance binds to another port so I wrote a little loader that does that:
- Load sro_client.exe with the commandline
- Fix two jumps so a failing CreateMutex doesn't matter
- Make the port random