1+ #include " scheduledProfiler.hpp"
2+ #include " ProfilerAdapter.hpp"
3+ #include " AdapterTracy.hpp"
4+ #include < client.hpp>
5+ #include < shared_mutex>
6+ #include " scriptProfiler.hpp"
7+ #include " SignalSlot.hpp"
8+
9+ #if _WIN32
10+ #include < windows.h>
11+ #endif
12+
13+
14+ extern " C" {
15+ uintptr_t vmSimulateJmpback;
16+
17+ bool __fastcall sVMSimStableReal (uintptr_t , float deltaT, float timeLimit);
18+ bool __fastcall sVMSimProfReal (uintptr_t , float deltaT, float timeLimit);
19+ bool VMSimulateHook (uintptr_t , float deltaT, float timeLimit);
20+
21+ decltype (sVMSimProfReal )* sVMSimReal = sVMSimProfReal;
22+ }
23+
24+
25+ HookManager hooks;
26+
27+
28+
29+ // "scrVM" prof scope
30+ HookManager::Pattern pat_vmSimulateProf{
31+ " xxxxxxxx?xxxxxxxxx??xxxxxxx?xxxx?xxxxxx?xxxxxxxxxxxx?????xxxx????xxxx????xxxx????xxx????xxxx????xxxx????x?x????xxx????xxx????xxx????xxx????xxxxxx????xxxxx????x????xx????xx?????xxx????xxxx????xxxxxx?xx?????xx?xxx?x?xxx????x?xxx?xx????xx????x?xxx????xx??x?xxxxxxxxxxxx?x?x????xxx?x?xxx?xxx?xxx????xxx????xxxxxxx????xxx?xxx?xxx????xxx?xxxx????xxxxxxx?xxxxx" sv,
32+ "\x4C\x8B\xDC\x55\x53\x49\x8D\x6B\x00\x48\x81\xEC\xA8\x00\x00\x00\x80\x79\x00\x00\x48\x8B\xD9\x41\x0F\x29\x73\x00\x0F\x28\xF2\x75\x00\x32\xC0\x41\x0F\x28\x73\x00\x48\x81\xC4\xA8\x00\x00\x00\x5B\x5D\xC3\x80\x3D\x00\x00\x00\x00\x00\x48\x89\xB4\x24\x00\x00\x00\x00\x48\x89\xBC\x24\x00\x00\x00\x00\x4C\x89\xA4\x24\x00\x00\x00\x00\x4C\x8D\x25\x00\x00\x00\x00\x4C\x89\xB4\x24\x00\x00\x00\x00\x4C\x89\xBC\x24\x00\x00\x00\x00\x75\x00\xE8\x00\x00\x00\x00\x48\x8D\x15\x00\x00\x00\x00\x4C\x89\x25\x00\x00\x00\x00\x4C\x8D\x05\x00\x00\x00\x00\x48\x89\x15\x00\x00\x00\x00\x44\x8B\xC8\x4C\x89\x05\x00\x00\x00\x00\x49\x8B\xCC\x89\x05\x00\x00\x00\x00\xE8\x00\x00\x00\x00\x89\x05\x00\x00\x00\x00\xC6\x05\x00\x00\x00\x00\x00\x48\x8D\x3D\x00\x00\x00\x00\x48\x8B\xCF\xE8\x00\x00\x00\x00\x45\x33\xFF\x48\x89\x7D\x00\x83\x3D\x00\x00\x00\x00\x00\x88\x45\x00\x4C\x89\x7D\x00\x74\x00\x44\x38\x3D\x00\x00\x00\x00\x75\x00\x84\xC0\x74\x00\xFF\x15\x00\x00\x00\x00\x39\x05\x00\x00\x00\x00\x75\x00\x44\x38\x3D\x00\x00\x00\x00\xC6\x45\x00\x00\x74\x00\x0F\x31\x48\xC1\xE2\x20\x48\x0B\xC2\x48\x89\x45\x00\xEB\x00\xE8\x00\x00\x00\x00\x48\x89\x45\x00\xEB\x00\x44\x88\x7D\x00\x4C\x89\x7D\x00\x44\x38\x3D\x00\x00\x00\x00\x48\x8D\x3D\x00\x00\x00\x00\xBE\xFF\xFF\xFF\xFF\x0F\x84\x00\x00\x00\x00\x48\x8B\x43\x00\x48\x8D\x55\x00\x48\x8B\x88\x00\x00\x00\x00\x44\x8B\x71\x00\x48\x8B\xCB\xE8\x00\x00\x00\x00\x4C\x8B\x00\x4D\x85\xC0\x74\x00\x49\x83\xC0\x10\xEB"sv
33+ };
34+
35+ // "Global namespace not passed (script %s)",
36+ HookManager::Pattern pat_vmSimulatePerf{
37+ " xxxxxxxx??xxxxxxx?xxxx?xxxxxx?xxxxxxxxxx????xxxx????xxx?xxxx?xxxx?xxxx?xxx????xx????xxx????xxx????xxx??xxxx?x????xxx????xxxx?xxxxx?xxx?xxx????xxxxxxxxx?xxxxxx?xxxx?xxxxxxxx?xxx????xxx?xxx????xxxx?xxx?xxx????xx????xxx?xxx?xxxxx????xxxxxxxxxxxxxx?xxxx?x????xxx????xxxxx????xxx????xxx????xxxx????xxxx?xxx?xxx????xxxx?xxxx?xxxxxx?xxxx?xxxxx?xxxxx????xxx?xx?????x?xxx????xxx?xxx?xxxx?xxx?xxx?xxxx?xxxxxx?xxxx?xxxxx?xxx?xxx????xxxx?xx??x?xxx?x" sv,
38+ "\x40\x53\x48\x83\xEC\x70\x80\x79\x00\x00\x48\x8B\xD9\x0F\x29\x74\x24\x00\x0F\x28\xF2\x75\x00\x32\xC0\x0F\x28\x74\x24\x00\x48\x83\xC4\x70\x5B\xC3\x48\x89\xAC\x24\x00\x00\x00\x00\x48\x89\xB4\x24\x00\x00\x00\x00\x48\x8B\x71\x00\x48\x89\x7C\x24\x00\x4C\x89\x74\x24\x00\x48\x85\xF6\x75\x00\x40\x38\x35\x00\x00\x00\x00\x0F\x84\x00\x00\x00\x00\x48\x8D\x35\x00\x00\x00\x00\x48\x8D\x05\x00\x00\x00\x00\xC6\x44\x24\x00\x00\x48\x89\x44\x24\x00\xE8\x00\x00\x00\x00\x48\x8B\x3D\x00\x00\x00\x00\x48\x89\x44\x24\x00\xF3\x0F\x11\x74\x24\x00\xF0\xFF\x46\x00\x48\x89\x35\x00\x00\x00\x00\xBE\xFF\xFF\xFF\xFF\x48\x85\xFF\x74\x00\x8B\xC6\xF0\x0F\xC1\x47\x00\x83\xF8\x01\x75\x00\x48\x8B\x07\x48\x8B\xCF\xFF\x50\x00\x48\x8B\x2D\x00\x00\x00\x00\x48\x8B\x43\x00\x48\x89\x05\x00\x00\x00\x00\x48\x85\xED\x74\x00\x48\x8B\x4B\x00\x0F\xB6\x85\x00\x00\x00\x00\x88\x81\x00\x00\x00\x00\x48\x8B\x4B\x00\x4C\x8D\x4B\x00\x33\xC0\x48\x8D\x15\x00\x00\x00\x00\x48\x85\xDB\x44\x8B\xC6\x4C\x0F\x44\xC8\x48\x8D\x44\x24\x00\x48\x89\x44\x24\x00\xE8\x00\x00\x00\x00\x48\x8D\x0D\x00\x00\x00\x00\x44\x0F\xB6\xF0\xE8\x00\x00\x00\x00\x48\x8B\x0D\x00\x00\x00\x00\x48\x89\x2D\x00\x00\x00\x00\x48\x8B\xAC\x24\x00\x00\x00\x00\x48\x85\xFF\x74\x00\xF0\xFF\x47\x00\x48\x89\x3D\x00\x00\x00\x00\x48\x8B\x7C\x24\x00\x48\x85\xC9\x74\x00\x8B\xC6\xF0\x0F\xC1\x41\x00\x83\xF8\x01\x75\x00\x48\x8B\x01\xFF\x50\x00\x45\x84\xF6\x0F\x84\x00\x00\x00\x00\x48\x8B\x43\x00\x83\xB8\x00\x00\x00\x00\x00\x75\x00\x48\x8B\x80\x00\x00\x00\x00\x48\x8B\x4B\x00\x48\x8B\x50\x00\x48\x85\xD2\x74\x00\xF0\xFF\x42\x00\x48\x89\x53\x00\x48\x85\xC9\x74\x00\x8B\xC6\xF0\x0F\xC1\x41\x00\x83\xF8\x01\x75\x00\x48\x8B\x01\xFF\x50\x00\x48\x8B\x4B\x00\x48\x8B\x81\x00\x00\x00\x00\x48\x85\xC0\x74\x00\x80\x78\x00\x00\x74\x00\x48\x8B\x53\x00\xEB"sv
39+ };
40+
41+
42+ struct scriptVM {
43+
44+ uintptr_t vtable1;
45+ uintptr_t _a;
46+ uintptr_t _b;
47+ uintptr_t vtable2;
48+ intercept::types::vm_context* context;
49+ void * b;
50+ bool c;
51+ bool d;
52+ bool e;
53+ bool f;
54+ bool g; // 2.22
55+
56+ game_value argument;
57+ r_string name;
58+ };
59+
60+
61+ std::unordered_map<const char *, std::shared_ptr<ScopeInfo>> scopeCache;
62+ extern std::string getScriptName (const r_string& str, const r_string& filePath, uint32_t returnFirstLineIfNoName = 0 );
63+
64+ bool VMSimulateHook (uintptr_t vmPtr, float deltaT, float timeLimit)
65+ {
66+ auto vm = (scriptVM*)vmPtr;
67+
68+ if (!vm->context )
69+ return sVMSimProfReal (vmPtr, deltaT, timeLimit);
70+
71+ auto tracyProf = std::reinterpret_pointer_cast<AdapterTracy>(GProfilerAdapter);
72+
73+ std::unordered_map<const char *, std::shared_ptr<ScopeInfo>>::iterator found = scopeCache.find (vm->context ->sdoc .content .c_str ());
74+ if (found == scopeCache.end ())
75+ {
76+ auto name = r_string (getScriptName (vm->context ->sdoc .content , vm->context ->sdoc .sourcefile , 1 ));
77+ auto res = scopeCache.insert ({ vm->context ->sdoc .content .c_str (), tracyProf->createScope (name, vm->context ->sdoc .sourcefile , 0 ) });
78+ found = res.first ;
79+ }
80+
81+ auto tmp = tracyProf->enterScope (found->second );
82+
83+ auto res = sVMSimReal (vmPtr, deltaT, timeLimit);
84+
85+ return res;
86+ }
87+
88+
89+ void ScheduledProfiler::init () {
90+
91+
92+ if (hooks.placeHook (hookTypes::sVMSimulate , pat_vmSimulateProf, reinterpret_cast <uintptr_t >(VMSimulateHook), vmSimulateJmpback, 0x11 )) {
93+ sVMSimReal = sVMSimProfReal ;
94+ } else if (hooks.placeHook (hookTypes::sVMSimulate , pat_vmSimulatePerf, reinterpret_cast <uintptr_t >(VMSimulateHook), vmSimulateJmpback, 0x7 )) {
95+ sVMSimReal = sVMSimStableReal ;
96+ }
97+
98+
99+ }
0 commit comments