r5sdk/r5dev/resource/patch/r5apex.patch
Kawe Mazidjatari 1afa75fec3 Fix >190FPS input system/simulation problems
Function 'CL_Move' has been fully rebuild in the SDK. Originally, the game checked if the delta time exceeded an amount defined by an immediate value, and dropped usercmd's if that was the case. This logic has been replaced with a more dynamic solution, and the console variable regulating this ('fps_input_max') is set to 200.0 by default (the same as the fix applied in the Season 9.1 Genesis update). This function also has been slightly optimized by removing duplicate operations that were performed in the original function. A second fix has been applied to 'CInput::JoyStickApplyMovement' that was also found changed in the Season 9.1 Genesis executable. In that function, an extraneous clamp was performed on the frame time causing viewstick problems when usercmd's get dropped in CL_Move.
2023-06-03 21:20:23 +02:00

92 lines
5.3 KiB
Diff

//////////////////////////////////////////////////////////
// Base game executable patch file; this executable
// contains all patches applied directly to the image.
/////////////////////////////
/////////////////////////////
//// Code adjustments ////
/////////////////////////////
/////////////////////////////
// This patch adds support for loading the 'LUMP_PAKFILE' lump as a discrete file.
// The function originally loaded the BSP, and stored the header in a local variable.
// This means that we need to store the BSP header in the lump too, if we want to load
// the packfile lump separately. To avoid this, we hook this function in SDK code,
// and load the BSP header into the static 's_MapHeader' memory. The patch below makes
// the function read the static fields instead, and uses the descritprs in the header to
// read out the lump path passed in. A separate tool sets the 'fileofs' field to 0, so the
// packfile lump can be loaded without any additional patching.
0x382152: "cmp dword ptr ds:[0x00000001666EC6C0], 0x50534272" // s_MapHeader.ident
0x382162: "mov eax, dword ptr ds:[0x00000001666EC6C4]" // s_MapHeader.version
0x382174: "cmp dword ptr ds:[0x00000001666EC954], 0x10" // s_MapHeader.lumps[LUMP_PAKFILE].filelen
0x382181: "movsxd rcx, dword ptr ds:[0x00000001666EC950]" // s_MapHeader.lumps[LUMP_PAKFILE].fileofs
0x382188: "mov rdx, rcx" // Move the operation done at 0x382181 (stored into RCX) into RDX; no need to index into it again.
// Due to the simplification of the operation above, 2 bytes had to be nopped.
0x38218B: "nop"
0x38218C: "nop"
0x38226E: "movsxd r8, dword ptr ds:[0x00000001666EC950]" // s_MapHeader.lumps[LUMP_PAKFILE].fileofs
0x382275: "movsxd rdx, dword ptr ds:[0x00000001666EC954]" // s_MapHeader.lumps[LUMP_PAKFILE].filelen
0x38247B: "cmp dword ptr ds:[0x00000001666EC6C0], 0x50534272" // s_MapHeader.ident
0x38248B: "mov eax, dword ptr ds:[0x00000001666EC6C4]" // s_MapHeader.version
0x38249D: "cmp dword ptr ds:[0x00000001666EC954], 0x10" // s_MapHeader.lumps[LUMP_PAKFILE].filelen
0x3824B6: "movsxd r8, dword ptr ds:[0x00000001666EC950]" // s_MapHeader.lumps[LUMP_PAKFILE].fileofs
0x38257E: movsxd r8, dword ptr ds:[0x00000001666EC950] // s_MapHeader.lumps[LUMP_PAKFILE].fileofs
0x382585: movsxd rdx, dword ptr ds:[0x00000001666EC954] // s_MapHeader.lumps[LUMP_PAKFILE].filelen
/////////////////////////////
/////////////////////////////
//// Code defects ////
/////////////////////////////
/////////////////////////////
// This fixes an engine bug where '-forceborder' did not force the border over the application window.
0x249DEE: "or byte ptr [rdi+14h], 3" --> "and byte ptr [rdi+14h], 0FDh";
// Concat happened due to bug in engine; Valve forgot a comma separator in the array.
0x1477876: 'FIELD_INTERVALFIELD_MODELINDEX\x00\x00' --> 'FIELD_INTERVAL\x00FIELD_MODELINDEX\x00';
0x1318C00: 0x0000000000 --> 0x7792474101; // Add new entry in 'g_FieldTypes', this entry points to the 'FIELD_MODELINDEX' string we separated from 'FIELD_INTERVAL'.
// In 'CInput::JoyStickApplyMovement' an extraneous 'fmin' clamp is performed on the frame time. BinDiff revealed that this was no longer performed on
// the 'Season 9.1 Genesis' executable. Further testing revealed that patching out just this clamp fixes the controller view stick problems when usercmd's
// get dropped in CL_Move.
0x6FD0E1: "movaps xmm0, xmm6" // Move frame time directly into the register that originally contained the clamped frame time.
0x6FD0EE: "nop (x4)" // Nop 'minss xmm0, xmm6' (extraneous clamp).
0x6FD114: "nop (x3)" // Nop 'movaps xmm6, xmm0' (extraneous move operation).
/////////////////////////////
/////////////////////////////
//// Exploitable defects ////
/////////////////////////////
/////////////////////////////
// This fixes a stack smash in 'CNetChan::ProcessSubChannelData' caused by the last fragment
// of a split packet, which could exceed the stack allocated buffer size of 560 bytes.
0x117F484: "jmp 0x1412950AE" // Jump to code cave (alignment padding at end of executable segment).
0x12944AE: "cmp rbp, 0x230" // Check if fragment size of 'last' split packet doesn't exceed stack buffer size.
0x12944B5: "jg 0x140261CE6" // Jump to gadget (xor al, al; pop..; ret;).
// Below the reconstruction of overwritten bytes caused by the long jump to code cave...
0x12944BB: "lea r8d, ds:[rbp*8]" // fragSize << 3
0x12944C3: "mov rcx, rbx"
0x12944C6: "jmp 0x140261A6B" // Jump back to original code; final split packet fragment is sane.
// This fixes a vulnerability in which the index field in the NET_SetConVar message
// could be used to read outside the static userinfo cvar string array.
0x030DD2B: "jmp 0x1412950E3" // Jump to code cave (alignment padding at end of executable segment).
// The instruction prior to the jump above performs a 'test' on the eax register.
// If the zero flag is set, it jumps to the rebuild of overwritten instructions
// caused by the long jmp to code cave.
0x12944E3: "je 0x1412950EE"
// This check was missing causing OOB reads! String array size is 0x27,
// so only index into it if its within bounds..
0x12944E5: "cmp eax, 0x28"
0x12944E8: "jb 0x14030E951"
// The following is rebuild as the long jump overwrote it,
// basically perform what was overwritten and jump back to
// original code...
0x12944EE: "mov r8d, 0x104"
0x12944F4: "jmp 0x14030E933"