-
Notifications
You must be signed in to change notification settings - Fork 0
acs_cosim_server
I expect it is illegal to distribute the patched executable directly, so instead i distribute a patchfile, which you can obtain from the releases page of this repo (or of course you can create your own - see Creating the patch from scratch).
The patch can be applied by using bspatch, another free utility from the bsdiff project. It is available on the Ubuntu official APT repos, so i suggest you to just use an UNIX system.
Backup the original acs.exe: mv acs.exe acs.exe.ori
Apply the patch: bspatch acs.exe.ori acs.exe patchfile
Move the newly patched acs.exe in your Assetto Corsa installation folder.
The patched executable must be first crafted by hand. I used Ghidra. Kunos Simulazioni s.r.l was kind enough to leave the .pdb file in the Assetto Corsa installation folder (thanks), so you should also load that into your tool.
Look for the PhysicsDriveThread::run function, and remove all logic related to synchronization with the wall clock.
You should be left with a busy loop which polls the input, advances the current time, performs a physics step, and then calls the physics step completed handlers. Also, i did not remove the pause logic.
You need some space on the stack to store the two event HANDLEs (8 bytes each). Some of the registers (most XMM registers) will become unused, so you can remove the logic which saves and restores them.
There should be enough space to initialize both HANDLEs to 0 during the stack frame setup.
You should be left with three huge NOP-slides - two of them can be used to insert the new logic; the other one, instead is between the call to the physics step and the call to the step completed handlers - you should not use it, as the one of the handlers is the component which updates the shared memory area (which we need).
You'll also need two names for the events. I used some strings which i found in the binary:
- go: "GODRAYS"
- done: "DOUBLESIDED"
At this point you can fit the new logic. In the first NOP-slide (before step):
MOV RAX,qword ptr [RSP + go_evt_handle]
TEST RAX,RAX
JNZ wait_for_go
LEA R9, [u_GODRAYS]
XOR R8D,R8D
XOR ECX,ECX
XOR EDX,EDX
CALL qword ptr [->KERNEL32.DLL::CreateEventW]
TEST RAX,RAX
JNZ wait_for_go
go_error:
CALL qword ptr [->KERNEL32.DLL::GetLastError]
MOV ECX,EAX
CALL qword ptr [->MSVCR120.DLL::exit]
wait_for_go:
MOV EDX,0xffffffff
MOV RCX,RAX
CALL qword ptr [->KERNEL32.DLL::WaitForSingleObject]
CMP EAX,-0x1
JZ go_errorand in the second:
MOV RAX,qword ptr [RSP + done_evt_handle]
TEST RAX,RAX
JNZ set_done
LEA R9,[u_DOUBLESIDED]
XOR R8D,R8D
XOR ECX,ECX
XOR EDX,EDX
CALL qword ptr [->KERNEL32.DLL::CreateEventW]
TEST RAX,RAX
JNZ set_done
done_error:
CALL qword ptr [->KERNEL32.DLL::GetLastError]
MOV ECX,EAX
CALL qword ptr [->MSVCR120.DLL::exit]
set_done:
MOV RCX,RAX
CALL qword ptr [->KERNEL32.DLL::SetEvent]
TEST EAX,EAX
JZ done_error
At this point you have your executable, so you don't really need to create a patchfile.
Anyhow, if you want, you could use bsdiff (see Applying the patch) to create it:
bsdiff acs.exe.ori acs.exe.patched patchfile