2023-04-13 20:29:46 +02:00
//////////////////////////////////////////////////////////
// Base game executable patch file; this executable
// contains all patches applied directly to the image.
2022-12-26 16:58:07 +01:00
2023-05-22 12:32:49 +02:00
/////////////////////////////
/////////////////////////////
//// 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
2023-04-13 20:29:46 +02:00
/////////////////////////////
/////////////////////////////
//// 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';
2022-12-26 16:58:07 +01:00
0x1318C00: 0x0000000000 --> 0x7792474101; // Add new entry in 'g_FieldTypes', this entry points to the 'FIELD_MODELINDEX' string we separated from 'FIELD_INTERVAL'.
2023-04-13 22:38:03 +02:00
/////////////////////////////
/////////////////////////////
//// 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"
2023-05-30 10:03:53 +02:00
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.
0x030DD29: "jmp 0x1412950E3" // Jump to code cave (alignment padding at end of executable segment).
0x12944E3: "test eax, eax" // Existing NULL check, moved here due to overwrite caused by long jmp.
0x12944E5: "je 0x1412950F0" // Conditional jump to rebuild of overwritten instruction.
0x12944E7: "cmp eax, 0x28" // Check if array index does NOT exceed size; max = 0x27 (this check was missing).
2023-05-30 20:24:52 +02:00
0x12944EA: "jb 0x14030E951" // Conditional jump to original code that indexes into userinfo cvar string array.
2023-05-30 10:03:53 +02:00
0x12944F0: "mov r8d, 0x104" // Rebuid of overwritten instruction caused by long jump to code cave.
0x12944F6: "jmp 0x14030E933" // Jump to original code past the user info cvar array indexing.