public IntPtr Scan(SigScanTarget target) { if (_memory == null || _memory.Length != _size) { _memory = new byte[_size]; int read; if (!SafeNativeMethods.ReadProcessMemory(_process.Handle, _address, _memory, _size, out read) || read != _size) { _memory = null; return(IntPtr.Zero); } } foreach (SigScanTarget.Signature sig in target.Signatures) { IntPtr ptr = this.FindPattern(sig.Pattern, sig.Mask, sig.Offset); if (ptr != IntPtr.Zero) { if (target.OnFound != null) { ptr = target.OnFound(_process, ptr); } return(ptr); } } return(IntPtr.Zero); }
// also works for anything derived from CBaseEntity (player etc) (no multiple inheritance) // var must be included by one of the DEFINE_FIELD macros public static bool GetBaseEntityMemberOffset(string member, Process game, SignatureScanner scanner, out int offset) { offset = -1; IntPtr stringPtr = scanner.Scan(new SigScanTarget(0, Encoding.ASCII.GetBytes(member))); if (stringPtr == IntPtr.Zero) { return(false); } var b = BitConverter.GetBytes(stringPtr.ToInt32()); var target = new SigScanTarget(10, String.Format("C7 05 ?? ?? ?? ?? {0:X02} {1:X02} {2:X02} {3:X02}", b[0], b[1], b[2], b[3])); // mov dword_15E2BF1C, offset aM_fflags ; "m_fFlags" target.OnFound = (proc, s, ptr) => { // this instruction is almost always directly after above one, but there are a few cases where it isn't // so we have to scan down and find it var proximityScanner = new SignatureScanner(proc, ptr, 256); return(proximityScanner.Scan(new SigScanTarget(6, "C7 05 ?? ?? ?? ?? ?? ?? 00 00"))); // mov dword_15E2BF20, 0CCh }; IntPtr addr = scanner.Scan(target); if (addr == IntPtr.Zero) { return(false); } return(game.ReadInt32(addr, out offset)); }
public IntPtr Scan(SigScanTarget target) { if (_memory == null || _memory.Length != _size) { _memory = new byte[_size]; int read; if (!SafeNativeMethods.ReadProcessMemory(_process.Handle, _address, _memory, _size, out read) || read != _size) { _memory = null; return IntPtr.Zero; } } foreach (SigScanTarget.Signature sig in target.Signatures) { IntPtr ptr = this.FindPattern(sig.Pattern, sig.Mask, sig.Offset); if (ptr != IntPtr.Zero) { if (target.OnFound != null) ptr = target.OnFound(_process, this, ptr); return ptr; } } return IntPtr.Zero; }
// also works for anything derived from CBaseEntity (player etc) (no multiple inheritance) // var must be included by one of the DEFINE_FIELD macros public static bool GetBaseEntityMemberOffset(string member, Process game, SignatureScanner scanner, out int offset) { offset = -1; IntPtr stringPtr = scanner.Scan(new SigScanTarget(0, Encoding.ASCII.GetBytes(member))); if (stringPtr == IntPtr.Zero) { return(false); } var b = BitConverter.GetBytes(stringPtr.ToInt32()); var target = new SigScanTarget(10, $"C7 05 ?? ?? ?? ?? {b[0]:X02} {b[1]:X02} {b[2]:X02} {b[3]:X02}"); // mov dword_15E2BF1C, offset aM_fflags ; "m_fFlags" target.OnFound = (proc, s, ptr) => { // this instruction is almost always directly after above one, but there are a few cases where it isn't // so we have to scan down and find it var proximityScanner = new SignatureScanner(proc, ptr, 256); return(proximityScanner.Scan(new SigScanTarget(6, "C7 05 ?? ?? ?? ?? ?? ?? 00 00"))); // mov dword_15E2BF20, 0CCh }; IntPtr addr = scanner.Scan(target); if (addr == IntPtr.Zero) { // seen in Black Mesa Source (legacy version) var target2 = new SigScanTarget(1, "68 ?? ?? ?? ??", // push 256 $"68 {b[0]:X02} {b[1]:X02} {b[2]:X02} {b[3]:X02}"); // push offset aM_fflags ; "m_fFlags" addr = scanner.Scan(target2); if (addr == IntPtr.Zero) { return(false); } } return(game.ReadValue(addr, out offset)); }
public GameMemory(SourceSplitSettings settings) { _settings = settings; // detect game offsets in a game/version-independent way by scanning for code signatures // TODO: refine hl2 2014 signatures once an update after the may 29th one is released // TODO: find a generic curTime signature // frameTime->curtime WIP sig, 76% success // \xe8...\x00\xd9\x1d....\x8b\x0d....\x8b\x11 // CGlobalVarsBase::curtime (g_ClientGlobalVariables aka gpGlobals) _curTimeTarget = new SigScanTarget(); _curTimeTarget.OnFound = (proc, scanner, ptr) => proc.ReadPtr32(ptr, out ptr) ? ptr : IntPtr.Zero; // orange box and older // \xa3....\xb9....\xa3....\xe8....\xd9\x1d(....)\xb9....\xe8....\xd9\x1d _curTimeTarget.AddSignature(22, "A3 ?? ?? ?? ??", // mov dword_2038BA6C, eax "B9 ?? ?? ?? ??", // mov ecx, offset unk_2038B8E8 "A3 ?? ?? ?? ??", // mov dword_2035DDA4, eax "E8 ?? ?? ?? ??", // call sub_20048110 "D9 1D ?? ?? ?? ??", // fstp curTime "B9 ?? ?? ?? ??", // mov ecx, offset unk_2038B8E8 "E8 ?? ?? ?? ??", // call sub_20048130 "D9 1D"); // fstp frametime // portal 2 // \x89\x96\xc4\x00\x00\x00\x8b\x86\xc8\x00\x00\x00\x8b\xce\xa3....\xe8....\xd9\x1d(....)\x8b\xce\xe8....\xd9\x1d _curTimeTarget.AddSignature(26, "89 96 C4 00 00 00", // mov [esi+0C4h], edx "8B 86 C8 00 00 00", // mov eax, [esi+0C8h] "8B CE", // mov ecx, esi "A3 ?? ?? ?? ??", // mov dword_10414AD0, eax "E8 ?? ?? ?? ??", // call sub_100A0F30 "D9 1D ?? ?? ?? ??", // fstp curTime "8B CE", // mov ecx, esi "E8 ?? ?? ?? ??", // call sub_100A0FB0 "D9 1D"); // fstp frametime // source 2009 // \x89\x8f\xc4\x00\x00\x00\x8b\x97\xc8\x00\x00\x00\x8b\xcf\x89\x15....\xe8....\xd9\x1d(....)\x8b\xcf\xe8....\xd9\x1d _curTimeTarget.AddSignature(27, "89 8F C4 00 00 00", // mov [edi+0C4h], ecx "8B 97 C8 00 00 00", // mov edx, [edi+0C8h] "8B CF", // mov ecx, edi "89 15 ?? ?? ?? ??", // mov dword_10422624, edx "E8 ?? ?? ?? ??", // call sub_1008FE40 "D9 1D ?? ?? ?? ??", // fstp curTime "8B CF", // mov ecx, edi "E8 ?? ?? ?? ??", // call sub_1008FEB0 "D9 1D"); // fstp flt_1042261C // hl2 may 29 2014 update // \xa3....\x89\x15....\xe8....\xd9\x1d....\x57\xb9....\xe8....\x8b\x0d....\xd9\x1d _curTimeTarget.AddSignature(18, "A3 ?? ?? ?? ??", // mov dword_103B4AC8, eax "89 15 ?? ?? ?? ??", // mov dword_10452F38, edx "E8 ?? ?? ?? ??", // call sub_100CE610 "D9 1D ?? ?? ?? ??", // fstp curTime "57", // push edi "B9 ?? ?? ?? ??", // mov ecx, offset unk_10452D98 "E8 ?? ?? ?? ??", // call sub_100CE390 "8B 0D ?? ?? ?? ??", // mov ecx, dword_1043686C "D9 1D"); // fstp frametime // CBaseClientState::m_nSignOnState (older engines) _signOnStateTarget1 = new SigScanTarget(); _signOnStateTarget1.OnFound = (proc, scanner, ptr) => proc.ReadPtr32(ptr, out ptr) ? ptr : IntPtr.Zero; // orange box and older // \x80\x3d....\x00\x74\x06\xb8....\xc3\x83\x3d(....)\x02\xb8 _signOnStateTarget1.AddSignature(17, "80 3D ?? ?? ?? ?? 00", // cmp byte_698EE114, 0 "74 06", // jz short loc_6936C8FF "B8 ?? ?? ?? ??", // mov eax, offset aDedicatedServe ; "Dedicated Server" "C3", // retn "83 3D ?? ?? ?? ?? 02", // cmp CBaseClientState__m_nSignonState, 2 "B8 ?? ?? ?? ??"); // mov eax, offset MultiByteStr // CBaseClientState::m_nSignOnState _signOnStateTarget2 = new SigScanTarget(); _signOnStateTarget2.OnFound = (proc, scanner, ptr) => { if (!proc.ReadPtr32(ptr, out ptr)) // deref instruction { return(IntPtr.Zero); } if (!proc.ReadPtr32(ptr, out ptr)) // deref ptr { return(IntPtr.Zero); } return(IntPtr.Add(ptr, 0x70)); // this+0x70 = m_nSignOnState }; // source 2009 / portal 2 // \x74.\x8b\x74\x87\x04\x83\x7e\x18\x00\x74\x2d\x8b\x0d(....)\x8b\x49\x18 _signOnStateTarget2.AddSignature(14, "74 ??", // jz short loc_693D4E22 "8B 74 87 04", // mov esi, [edi+eax*4+4] "83 7E 18 00", // cmp dword ptr [esi+18h], 0 "74 2D", // jz short loc_693D4DFC "8B 0D ?? ?? ?? ??", // mov ecx, baseclientstate "8B 49 18"); // mov mov ecx, [ecx+18h] // CBaseServer::m_szMapname[64] _curMapTarget = new SigScanTarget(); _curMapTarget.OnFound = (proc, scanner, ptr) => proc.ReadPtr32(ptr, out ptr) ? ptr : IntPtr.Zero; // \x68(....).\xe8...\x00\x83\xc4\x08\x85\xc0\x0f\x84..\x00\x00\x83\xc7\x01\x83.\x50\x3b\x7e\x18\x7c // source 2006 and older _curMapTarget.AddSignature(1, "68 ?? ?? ?? ??", // push offset map "??", // push ebp "E8 ?? ?? ?? 00", // call __stricmp "83 C4 08", // add esp, 8 "85 C0", // test eax, eax "0F 84 ?? ?? 00 00", // jz loc_200CDF8D "83 C7 01", // add edi, 1 "83 ?? 50", // add ebp, 50h "3B 7E 18", // cmp edi, [esi+18h] "7C"); // jl short loc_200CDEC0 // orange box and newer // \xd9.\x2c\xd9\xc9\xdf\xf1\xdd\xd8\x76.\x80.....\x00 _curMapTarget.AddSignature(13, "D9 ?? 2C", // fld dword ptr [edx+2Ch] "D9 C9", // fxch st(1) "DF F1", // fcomip st, st(1) "DD D8", // fstp st "76 ??", // jbe short loc_6946F651 "80 ?? ?? ?? ?? ?? 00"); // cmp map, 0 // CBaseEntityList::(CEntInfo)m_EntPtrArray _globalEntityListTarget = new SigScanTarget(); // \x6a\x00\x6a\x00\x50\x6a\x00\xb9(....)\xe8 // deref to get vtable ptr, add 4 to get start of entity list _globalEntityListTarget.OnFound = (proc, scanner, ptr) => proc.ReadPtr32(ptr, out ptr) ? ptr + 4 : IntPtr.Zero; _globalEntityListTarget.AddSignature(8, "6A 00", // push 0 "6A 00", // push 0 "50", // push eax "6A 00", // push 0 "B9 ?? ?? ?? ??", // mov ecx, offset CGlobalEntityList_vtable_ptr "E8"); // call sub_22289800 // CHostState::m_currentState _hostStateTarget = new SigScanTarget(); // subtract 4 to get m_currentState _hostStateTarget.OnFound = (proc, scanner, ptr) => proc.ReadPtr32(ptr, out ptr) ? ptr - 4 : IntPtr.Zero; // \xc7\x05....\x07\x00\x00\x00\xc3 _hostStateTarget.AddSignature(2, "C7 05 ?? ?? ?? ?? 07 00 00 00", // mov g_HostState_m_nextState, 7 "C3"); // retn // TODO: find better way to do this. multiple sigs instead? _gameDirTarget = new SigScanTarget(0, "25732F736176652F25732E736176"); // "%s/save/%s.sav" _gameDirTarget.OnFound = (proc, scanner, ptr) => { byte[] b = BitConverter.GetBytes(ptr.ToInt32()); var target = new SigScanTarget(-4, // push offset aSMapsS_sav String.Format("68 {0:X02} {1:X02} {2:X02} {3:X02}", b[0], b[1], b[2], b[3])); IntPtr ptrPtr = scanner.Scan(target); if (ptrPtr == IntPtr.Zero) { return(IntPtr.Zero); } IntPtr ret; proc.ReadPtr32(ptrPtr, out ret); return(ret); }; }
// also works for anything derived from CBaseEntity (player etc) (no multiple inheritance) // var must be included by one of the DEFINE_FIELD macros public static bool GetBaseEntityMemberOffset(string member, Process game, SignatureScanner scanner, out int offset) { offset = -1; IntPtr stringPtr = scanner.Scan(new SigScanTarget(0, Encoding.ASCII.GetBytes(member))); if (stringPtr == IntPtr.Zero) return false; var b = BitConverter.GetBytes(stringPtr.ToInt32()); var target = new SigScanTarget(10, String.Format("C7 05 ?? ?? ?? ?? {0:X02} {1:X02} {2:X02} {3:X02}", b[0], b[1], b[2], b[3])); // mov dword_15E2BF1C, offset aM_fflags ; "m_fFlags" target.OnFound = (proc, s, ptr) => { // this instruction is almost always directly after above one, but there are a few cases where it isn't // so we have to scan down and find it var proximityScanner = new SignatureScanner(proc, ptr, 256); return proximityScanner.Scan(new SigScanTarget(6, "C7 05 ?? ?? ?? ?? ?? ?? 00 00")); // mov dword_15E2BF20, 0CCh }; IntPtr addr = scanner.Scan(target); if (addr == IntPtr.Zero) return false; return game.ReadInt32(addr, out offset); }
public GameMemory(SourceSplitSettings settings) { _settings = settings; // detect game offsets in a game/version-independent way by scanning for code signatures // TODO: refine hl2 2014 signatures once an update after the may 29th one is released // TODO: find a generic curTime signature // frameTime->curtime WIP sig, 76% success // \xe8...\x00\xd9\x1d....\x8b\x0d....\x8b\x11 // CGlobalVarsBase::curtime (g_ClientGlobalVariables aka gpGlobals) _curTimeTarget = new SigScanTarget(); _curTimeTarget.OnFound = (proc, scanner, ptr) => proc.ReadPtr32(ptr, out ptr) ? ptr : IntPtr.Zero; // orange box and older // \xa3....\xb9....\xa3....\xe8....\xd9\x1d(....)\xb9....\xe8....\xd9\x1d _curTimeTarget.AddSignature(22, "A3 ?? ?? ?? ??", // mov dword_2038BA6C, eax "B9 ?? ?? ?? ??", // mov ecx, offset unk_2038B8E8 "A3 ?? ?? ?? ??", // mov dword_2035DDA4, eax "E8 ?? ?? ?? ??", // call sub_20048110 "D9 1D ?? ?? ?? ??", // fstp curTime "B9 ?? ?? ?? ??", // mov ecx, offset unk_2038B8E8 "E8 ?? ?? ?? ??", // call sub_20048130 "D9 1D"); // fstp frametime // portal 2 // \x89\x96\xc4\x00\x00\x00\x8b\x86\xc8\x00\x00\x00\x8b\xce\xa3....\xe8....\xd9\x1d(....)\x8b\xce\xe8....\xd9\x1d _curTimeTarget.AddSignature(26, "89 96 C4 00 00 00", // mov [esi+0C4h], edx "8B 86 C8 00 00 00", // mov eax, [esi+0C8h] "8B CE", // mov ecx, esi "A3 ?? ?? ?? ??", // mov dword_10414AD0, eax "E8 ?? ?? ?? ??", // call sub_100A0F30 "D9 1D ?? ?? ?? ??", // fstp curTime "8B CE", // mov ecx, esi "E8 ?? ?? ?? ??", // call sub_100A0FB0 "D9 1D"); // fstp frametime // source 2009 // \x89\x8f\xc4\x00\x00\x00\x8b\x97\xc8\x00\x00\x00\x8b\xcf\x89\x15....\xe8....\xd9\x1d(....)\x8b\xcf\xe8....\xd9\x1d _curTimeTarget.AddSignature(27, "89 8F C4 00 00 00", // mov [edi+0C4h], ecx "8B 97 C8 00 00 00", // mov edx, [edi+0C8h] "8B CF", // mov ecx, edi "89 15 ?? ?? ?? ??", // mov dword_10422624, edx "E8 ?? ?? ?? ??", // call sub_1008FE40 "D9 1D ?? ?? ?? ??", // fstp curTime "8B CF", // mov ecx, edi "E8 ?? ?? ?? ??", // call sub_1008FEB0 "D9 1D"); // fstp flt_1042261C // hl2 may 29 2014 update // \xa3....\x89\x15....\xe8....\xd9\x1d....\x57\xb9....\xe8....\x8b\x0d....\xd9\x1d _curTimeTarget.AddSignature(18, "A3 ?? ?? ?? ??", // mov dword_103B4AC8, eax "89 15 ?? ?? ?? ??", // mov dword_10452F38, edx "E8 ?? ?? ?? ??", // call sub_100CE610 "D9 1D ?? ?? ?? ??", // fstp curTime "57", // push edi "B9 ?? ?? ?? ??", // mov ecx, offset unk_10452D98 "E8 ?? ?? ?? ??", // call sub_100CE390 "8B 0D ?? ?? ?? ??", // mov ecx, dword_1043686C "D9 1D"); // fstp frametime // CBaseClientState::m_nSignOnState (older engines) _signOnStateTarget1 = new SigScanTarget(); _signOnStateTarget1.OnFound = (proc, scanner, ptr) => proc.ReadPtr32(ptr, out ptr) ? ptr : IntPtr.Zero; // orange box and older // \x80\x3d....\x00\x74\x06\xb8....\xc3\x83\x3d(....)\x02\xb8 _signOnStateTarget1.AddSignature(17, "80 3D ?? ?? ?? ?? 00", // cmp byte_698EE114, 0 "74 06", // jz short loc_6936C8FF "B8 ?? ?? ?? ??", // mov eax, offset aDedicatedServe ; "Dedicated Server" "C3", // retn "83 3D ?? ?? ?? ?? 02", // cmp CBaseClientState__m_nSignonState, 2 "B8 ?? ?? ?? ??"); // mov eax, offset MultiByteStr // CBaseClientState::m_nSignOnState _signOnStateTarget2 = new SigScanTarget(); _signOnStateTarget2.OnFound = (proc, scanner, ptr) => { if (!proc.ReadPtr32(ptr, out ptr)) // deref instruction return IntPtr.Zero; if (!proc.ReadPtr32(ptr, out ptr)) // deref ptr return IntPtr.Zero; return IntPtr.Add(ptr, 0x70); // this+0x70 = m_nSignOnState }; // source 2009 / portal 2 // \x74.\x8b\x74\x87\x04\x83\x7e\x18\x00\x74\x2d\x8b\x0d(....)\x8b\x49\x18 _signOnStateTarget2.AddSignature(14, "74 ??", // jz short loc_693D4E22 "8B 74 87 04", // mov esi, [edi+eax*4+4] "83 7E 18 00", // cmp dword ptr [esi+18h], 0 "74 2D", // jz short loc_693D4DFC "8B 0D ?? ?? ?? ??", // mov ecx, baseclientstate "8B 49 18"); // mov mov ecx, [ecx+18h] // CBaseServer::m_szMapname[64] _curMapTarget = new SigScanTarget(); _curMapTarget.OnFound = (proc, scanner, ptr) => proc.ReadPtr32(ptr, out ptr) ? ptr : IntPtr.Zero; // \x68(....).\xe8...\x00\x83\xc4\x08\x85\xc0\x0f\x84..\x00\x00\x83\xc7\x01\x83.\x50\x3b\x7e\x18\x7c // source 2006 and older _curMapTarget.AddSignature(1, "68 ?? ?? ?? ??", // push offset map "??", // push ebp "E8 ?? ?? ?? 00", // call __stricmp "83 C4 08", // add esp, 8 "85 C0", // test eax, eax "0F 84 ?? ?? 00 00", // jz loc_200CDF8D "83 C7 01", // add edi, 1 "83 ?? 50", // add ebp, 50h "3B 7E 18", // cmp edi, [esi+18h] "7C"); // jl short loc_200CDEC0 // orange box and newer // \xd9.\x2c\xd9\xc9\xdf\xf1\xdd\xd8\x76.\x80.....\x00 _curMapTarget.AddSignature(13, "D9 ?? 2C", // fld dword ptr [edx+2Ch] "D9 C9", // fxch st(1) "DF F1", // fcomip st, st(1) "DD D8", // fstp st "76 ??", // jbe short loc_6946F651 "80 ?? ?? ?? ?? ?? 00"); // cmp map, 0 // CBaseEntityList::(CEntInfo)m_EntPtrArray _globalEntityListTarget = new SigScanTarget(); // \x6a\x00\x6a\x00\x50\x6a\x00\xb9(....)\xe8 // deref to get vtable ptr, add 4 to get start of entity list _globalEntityListTarget.OnFound = (proc, scanner, ptr) => proc.ReadPtr32(ptr, out ptr) ? ptr + 4 : IntPtr.Zero; _globalEntityListTarget.AddSignature(8, "6A 00", // push 0 "6A 00", // push 0 "50", // push eax "6A 00", // push 0 "B9 ?? ?? ?? ??", // mov ecx, offset CGlobalEntityList_vtable_ptr "E8"); // call sub_22289800 // CHostState::m_currentState _hostStateTarget = new SigScanTarget(); // subtract 4 to get m_currentState _hostStateTarget.OnFound = (proc, scanner, ptr) => proc.ReadPtr32(ptr, out ptr) ? ptr - 4 : IntPtr.Zero; // \xc7\x05....\x07\x00\x00\x00\xc3 _hostStateTarget.AddSignature(2, "C7 05 ?? ?? ?? ?? 07 00 00 00", // mov g_HostState_m_nextState, 7 "C3"); // retn // TODO: find better way to do this. multiple sigs instead? _gameDirTarget = new SigScanTarget(0, "25732F736176652F25732E736176"); // "%s/save/%s.sav" _gameDirTarget.OnFound = (proc, scanner, ptr) => { byte[] b = BitConverter.GetBytes(ptr.ToInt32()); var target = new SigScanTarget(-4, // push offset aSMapsS_sav String.Format("68 {0:X02} {1:X02} {2:X02} {3:X02}", b[0], b[1], b[2], b[3])); IntPtr ptrPtr = scanner.Scan(target); if (ptrPtr == IntPtr.Zero) return IntPtr.Zero; IntPtr ret; proc.ReadPtr32(ptrPtr, out ret); return ret; }; }
public GameMemory(SourceSplitSettings settings) { _settings = settings; // TODO: refine hl2 2014 signatures once an update after the may 29th one is released /*// CBaseServer::(server_state_t)m_State * _serverStateTarget = new SigScanTarget(); * _serverStateTarget.OnFound = (proc, ptr) => !ReadProcessPtr32(proc, ptr, out ptr) ? IntPtr.Zero : ptr; * // works for every engine.dll * // \x83\xf8\x01\x0f\x8c..\x00\x00\x3d\x00\x02\x00\x00\x0f\x8f..\x00\x00\x83\x3d(....)\x02\x7d * _serverStateTarget.AddSignature(22, * "83 F8 01", // cmp eax, 1 * "0F 8C ?? ?? 00 00", // jl loc_200087FB * "3D 00 02 00 00", // cmp eax, 200h * "0F 8F ?? ?? 00 00", // jg loc_200087FB * "83 3d ?? ?? ?? ?? 02", // cmp m_State, 2 * "7D"); // jge short loc_200085FD*/ // CGlobalVarsBase::curtime (g_ClientGlobalVariables aka gpGlobals) // hl2 old engine / portal latest / hl2 new engine _curTimeTarget = new SigScanTarget(); _curTimeTarget.OnFound = (proc, ptr) => !ReadProcessPtr32(proc, ptr, out ptr) ? IntPtr.Zero : ptr; // \xa3....\xb9....\xa3....\xe8....\xd9\x1d(....)\xb9....\xe8....\xd9\x1d _curTimeTarget.AddSignature(22, "A3 ?? ?? ?? ??", // mov dword_2038BA6C, eax "B9 ?? ?? ?? ??", // mov ecx, offset unk_2038B8E8 "A3 ?? ?? ?? ??", // mov dword_2035DDA4, eax "E8 ?? ?? ?? ??", // call sub_20048110 "D9 1D ?? ?? ?? ??", // fstp curTime "B9 ?? ?? ?? ??", // mov ecx, offset unk_2038B8E8 "E8 ?? ?? ?? ??", // call sub_20048130 "D9 1D"); // fstp frametime // dear esther / portal 2 // \x89\x96\xc4\x00\x00\x00\x8b\x86\xc8\x00\x00\x00\x8b\xce\xa3....\xe8....\xd9\x1d(....)\x8b\xce\xe8....\xd9\x1d _curTimeTarget.AddSignature(26, "89 96 C4 00 00 00", // mov [esi+0C4h], edx "8B 86 C8 00 00 00", // mov eax, [esi+0C8h] "8B CE", // mov ecx, esi "A3 ?? ?? ?? ??", // mov dword_10414AD0, eax "E8 ?? ?? ?? ??", // call sub_100A0F30 "D9 1D ?? ?? ?? ??", // fstp curTime "8B CE", // mov ecx, esi "E8 ?? ?? ?? ??", // call sub_100A0FB0 "D9 1D"); // fstp frametime // l4d2 // \x89\x8f\xc4\x00\x00\x00\x8b\x97\xc8\x00\x00\x00\x8b\xcf\x89\x15....\xe8....\xd9\x1d(....)\x8b\xcf\xe8....\xd9\x1d _curTimeTarget.AddSignature(27, "89 8F C4 00 00 00", // mov [edi+0C4h], ecx "8B 97 C8 00 00 00", // mov edx, [edi+0C8h] "8B CF", // mov ecx, edi "89 15 ?? ?? ?? ??", // mov dword_10422624, edx "E8 ?? ?? ?? ??", // call sub_1008FE40 "D9 1D ?? ?? ?? ??", // fstp curTime "8B CF", // mov ecx, edi "E8 ?? ?? ?? ??", // call sub_1008FEB0 "D9 1D"); // fstp flt_1042261C // hl2 may 29 2014 update // \xa3....\x89\x15....\xe8....\xd9\x1d....\x57\xb9....\xe8....\x8b\x0d....\xd9\x1d _curTimeTarget.AddSignature(18, "A3 ?? ?? ?? ??", // mov dword_103B4AC8, eax "89 15 ?? ?? ?? ??", // mov dword_10452F38, edx "E8 ?? ?? ?? ??", // call sub_100CE610 "D9 1D ?? ?? ?? ??", // fstp curTime "57", // push edi "B9 ?? ?? ?? ??", // mov ecx, offset unk_10452D98 "E8 ?? ?? ?? ??", // call sub_100CE390 "8B 0D ?? ?? ?? ??", // mov ecx, dword_1043686C "D9 1D"); // fstp frametime // CBaseClientState::m_nSignOnState (older engines) _signOnStateTarget1 = new SigScanTarget(); _signOnStateTarget1.OnFound = (proc, ptr) => !ReadProcessPtr32(proc, ptr, out ptr) ? IntPtr.Zero : ptr; // \x80\x3d....\x00\x74\x06\xb8....\xc3\x83\x3d(....)\x02\xb8....\x7c\x05 _signOnStateTarget1.AddSignature(17, "80 3D ?? ?? ?? ?? 00", // cmp byte_698EE114, 0 "74 06", // jz short loc_6936C8FF "B8 ?? ?? ?? ??", // mov eax, offset aDedicatedServe ; "Dedicated Server" "C3", // retn "83 3D ?? ?? ?? ?? 02", // cmp CBaseClientState__m_nSignonState, 2 "B8 ?? ?? ?? ??"); // mov eax, offset MultiByteStr // CBaseClientState::m_nSignOnState (newer engines) _signOnStateTarget2 = new SigScanTarget(); _signOnStateTarget2.OnFound = (proc, ptr) => { if (!ReadProcessPtr32(proc, ptr, out ptr)) // deref instruction { return(IntPtr.Zero); } if (!ReadProcessPtr32(proc, ptr, out ptr)) // deref ptr { return(IntPtr.Zero); } return(IntPtr.Add(ptr, 0x70)); // this+0x70 = m_nSignOnState }; // \x74.\x8b\x74\x87\x04\x83\x7e\x18\x00\x74\x2d\x8b\x0d(....)\x8b\x49\x18 _signOnStateTarget2.AddSignature(14, "74 ??", // jz short loc_693D4E22 "8B 74 87 04", // mov esi, [edi+eax*4+4] "83 7E 18 00", // cmp dword ptr [esi+18h], 0 "74 2D", // jz short loc_693D4DFC "8B 0D ?? ?? ?? ??", // mov ecx, baseclientstate "8B 49 18"); // mov mov ecx, [ecx+18h] // CBaseServer::m_szMapname[64] _curMapTarget = new SigScanTarget(); _curMapTarget.OnFound = (proc, ptr) => !ReadProcessPtr32(proc, ptr, out ptr) ? IntPtr.Zero : ptr; // TODO: these signatures arent very generic // \x68(....).\xe8...\x00\x83\xc4\x08\x85\xc0\x0f\x84..\x00\x00\x47\x83.\x50\x3b\x7e\x18\x7c _curMapTarget.AddSignature(1, "68 ?? ?? ?? ??", // push offset map "??", // push ebx "E8 ?? ?? ?? 00", // call __stricmp "83 C4 08", // add esp, 8 "85 C0", // test eax, eax "0F 84 ?? ?? 00 00", // jz loc_6947E980 "47", // inc edi "83 ?? 50", // add ebx, 50h "3B 7E 18", // cmp edi, [esi+18h] "7C"); // jl short loc_6947E830 // \x68(....).\xe8...\x00\x83\xc4\x08\x85\xc0\x0f\x84..\x00\x00\x83\xc7\x01\x83.\x50\x3b\x7e\x18\x7c _curMapTarget.AddSignature(1, "68 ?? ?? ?? ??", // push offset map "??", // push ebp "E8 ?? ?? ?? 00", // call __stricmp "83 C4 08", // add esp, 8 "85 C0", // test eax, eax "0F 84 ?? ?? 00 00", // jz loc_200CDF8D "83 C7 01", // add edi, 1 "83 ?? 50", // add ebp, 50h "3B 7E 18", // cmp edi, [esi+18h] "7C"); // jl short loc_200CDEC0 // \x68(....).\xe8...\x00\x83\xc4\x08\x85\xc0\x0f\x84..\x00\x00\x47\x81.\xb0\x00\x00\x00\x3b\x7e\x18\x7c _curMapTarget.AddSignature(1, "68 ?? ?? ?? ??", // push offset map "??", // push ebp "E8 ?? ?? ?? 00", // call __stricmp "83 C4 08", // add esp, 8 "85 C0", // test eax, eax "0F 84 ?? ?? 00 00", // jz loc_101B2BC1 "47", // inc edi "81 ?? B0 00 00 00", // add ebp, 0B0h "3B 7E 18", // cmp edi, [esi+18h] "7C"); // jl short loc_101B2A62 // hl2 may 29 2014 update // \xc7\x05....\x00\x00\x00\x00\x5f\x84\xc0\x75.\x68....\x51\x68 _curMapTarget.AddSignature(16, "C7 05 ?? ?? ?? ?? 00 00 00 00", // mov dword_103B5BE4, 0 "5F", // pop edi "84 C0", // test al, al "75 ??", // jnz short loc_101AA0C7 "68 ?? ?? ?? ??", // push offset map "51", // push ecx "68"); // push offset aLevelTransitio }