@@ -80,12 +80,17 @@ enum DataType {
8080 TYPE_POINTER_TO_BYTE
8181};
8282
83+ struct Signature {
84+ const char * pattern;
85+ int ripOffset;
86+ int instrLen;
87+ int postOffset;
88+ DataType type;
89+ };
90+
8391struct Pattern {
8492 std::string name;
85- std::vector<const char *> signatures; // take into consideration older and newer versions
86- int ripOffset;
87- int postOffset;
88- DataType type;
93+ std::vector<Signature> signatures; // take into consideration older and newer versions
8994};
9095
9196struct MemHandle {
@@ -117,16 +122,59 @@ struct MemHandle {
117122};
118123
119124std::vector<Pattern> PatternList = {
120- { " Current BPM" , {" F3 0F 11 05 ? ? ? ? F3 0F 2A 05 ? ? ? ?" }, 4 , 0 , TYPE_FLOAT },
121- { " Pattern/Song Toggle" , {" 48 8B 05 ? ? ? ? 83 38 ? 75 ? E8 ? ? ? ? 48 8D 88 48 1C 02 00" }, 3 , 0 , TYPE_POINTER_TO_INT },
122- { " Master Pitch" ,
125+ {
126+ " Current BPM" ,
123127 {
124- " 48 8B 05 ? ? ? ? 48 0F B7 00 66 89 85 08 02 00 00" ,
125- " 48 8B 05 ? ? ? ? 48 8B 8D 40 0B 00 00 48 8B 89 C0 44 00 00 48 0F BF 89 2C 00 10 00" // 25.2.2.5154
126- }, 3 , 0 , TYPE_POINTER_TO_SHORT
128+ { " F3 0F 11 05 ? ? ? ? F3 0F 2A 05 ? ? ? ?" , 4 , 6 , 0 , TYPE_FLOAT } // looks to be the same for every version
129+ }
130+ },
131+ {
132+ " Pattern/Song Toggle" ,
133+ {
134+ { " 48 8B 05 ? ? ? ? 83 38 ? 75 ? 48 8D 8D 90 02 00 00" , 3 , 6 , 0 , TYPE_POINTER_TO_INT }, // 24.1.2.4430
135+ { " 48 8B 05 ? ? ? ? 83 38 ? 75 ? E8 ? ? ? ? 48 8D 88 48 1C 02 00" , 3 , 6 , 0 , TYPE_POINTER_TO_INT },
136+
137+ { " 48 8B 05 ? ? ? ? 83 38 ? 0F 85 ? ? ? ? B1 ?" , 3 , 6 , 0 , TYPE_POINTER_TO_INT }, // 20.6.2.1549
138+ }
127139 },
128- { " Metronome Toggle" , {" 48 8B 0D ? ? ? ? 48 0F B6 09 88 88 88 09 00 00" }, 3 , 0 , TYPE_POINTER_TO_BYTE },
129- { " Playing Status" , {" 83 3D ? ? ? ? ? 74 ? 83 3D ? ? ? ? ? 7F" }, 2 , 0 , TYPE_BYTE }
140+ {
141+ " Master Pitch" ,
142+ {
143+ { " 48 8B 05 ? ? ? ? 03 18 48 8B 4D 20" , 3 , 6 , 0 , TYPE_POINTER_TO_SHORT },
144+ { " 48 8B 05 ? ? ? ? F3 0F 2A 00 48 8B 45 20" , 3 , 6 , 0 , TYPE_POINTER_TO_SHORT },
145+ { " 48 8B 05 ? ? ? ? 8B 8D B8 05 00 00 89 08 33 C0" , 3 , 6 , 0 , TYPE_POINTER_TO_SHORT },
146+ { " 48 8B 05 ? ? ? ? 8B 00 89 85 B8 05 00 00 8B 85 C0 05 00 00 A9 ? ? ? ? 74 ? 48 8B 8D 90 03 00 00" , 3 , 6 , 0 , TYPE_POINTER_TO_SHORT },
147+
148+ { " 48 8B 05 ? ? ? ? 48 0F B7 00 66 89 85 08 02 00 00" , 3 , 6 , 0 , TYPE_POINTER_TO_SHORT }, // 24.2.2.4597
149+ { " 48 8B 05 ? ? ? ? 48 8B 8D 40 0B 00 00 48 8B 89 C0 44 00 00 48 0F BF 89 2C 00 10 00" , 3 , 6 , 0 , TYPE_POINTER_TO_SHORT }, // 25.2.2.5154
150+ { " 48 8B 05 ? ? ? ? 48 0F B7 00 66 89 85 D8 04 00 00" , 3 , 6 , 0 , TYPE_POINTER_TO_SHORT }, // 21.0.3.3517
151+ { " 48 8B 05 ? ? ? ? 48 8B 8D 90 09 00 00 48 8B 89 00 04 00 00 48 0F BF 89 2C 00 10 00" , 3 , 6 , 0 , TYPE_POINTER_TO_SHORT }, // 21.1.1.3750
152+ { " 48 8B 05 ? ? ? ? 48 8B 8D C0 09 00 00 48 8B 89 20 48 00 00 48 0F BF 89 2C 00 10 00" , 3 , 6 , 0 , TYPE_POINTER_TO_SHORT }, // 24.1.2.4430
153+ { " 48 8B 05 ? ? ? ? 48 8B 8D 50 0B 00 00 48 8B 89 50 48 00 00 48 0F BF 89 2C 00 10 00" , 3 , 6 , 0 , TYPE_POINTER_TO_SHORT }, // 25.1.1.4879
154+ { " 48 8B 05 ? ? ? ? 48 8B 8D 40 0B 00 00 48 8B 89 40 48 00 00 48 0F BF 89 2C 00 10 00" , 3 , 6 , 0 , TYPE_POINTER_TO_SHORT }, // 25.1.5.4976
155+
156+ { " 48 8B 05 ? ? ? ? 48 8B 8D ? ? ? ? 48 8B 89 ? ? ? ? 48 0F BF 89" , 3 , 6 , 0 , TYPE_POINTER_TO_SHORT }, // 20.6.2.1549
157+ }
158+ },
159+ {
160+ " Metronome Toggle" ,
161+ {
162+ { " 48 8B 05 ? ? ? ? 48 0F B6 10 E8 ? ? ? ? 48 8B 05 ? ? ? ? 48 8B 00 48 8B 88 F8 0C 00 00" , 3 , 6 , 0 , TYPE_POINTER_TO_BYTE }, // 21.0.3.3517
163+ { " 48 8B 0D ? ? ? ? 48 0F B6 09 88 88 88 09 00 00" , 3 , 6 , 0 , TYPE_POINTER_TO_BYTE }, // 24.2.2.4597
164+
165+ { " 48 8B 05 ? ? ? ? ? ? ? 0F 84 ? ? ? ? 48 8B 05 ? ? ? ? ? ? 48 8B 05" , 3 , 6 , 0 , TYPE_POINTER_TO_BYTE }, // 20.6.2.1549
166+ }
167+ },
168+ {
169+ " Playing Status" ,
170+ {
171+ { " 48 8B 0D ? ? ? ? 83 39 ? 0F 94 C1 85 C0" , 3 , 6 , 0 , TYPE_POINTER_TO_INT }, // 21.0.3.3517
172+ { " 83 3D ? ? ? ? ? 74 ? 83 3D ? ? ? ? ? 7F" , 2 , 7 , 0 , TYPE_BYTE }, // versions 24 and up
173+
174+ { " 48 8B 05 ? ? ? ? ? ? ? 0F 85 ? ? ? ? 48 8B 05 ? ? ? ? ? ? 48 8B 0D" , 3 , 6 , 0 , TYPE_POINTER_TO_INT }, // 20.6.2.1549
175+
176+ }
177+ }
130178};
131179
132180DWORD GetProcId (const wchar_t * name) {
@@ -342,17 +390,19 @@ int main() {
342390 while (true ) {
343391 for (const auto & p : PatternList) {
344392 uintptr_t hit = 0 ;
393+ const Signature* matchedSig = nullptr ;
345394
346- for (const char * sig : p.signatures ) {
347- hit = FindPattern (hProc, modBase, modSize, sig);
348- if (hit) break ;
395+ for (const auto & sig : p.signatures ) {
396+ hit = FindPattern (hProc, modBase, modSize, sig.pattern );
397+ if (hit) {
398+ matchedSig = &sig;
399+ break ;
400+ }
349401 }
350-
351- if (!hit) continue ;
402+ if (!hit || !matchedSig) continue ;
352403
353404 MemHandle ptr{ hProc, hit };
354- int instrLen = (p.name == " Playing Status" ) ? 7 : 6 ;
355- MemHandle resolved = ptr.add (p.ripOffset ).rip (instrLen);
405+ MemHandle resolved = ptr.add (matchedSig->ripOffset ).rip (matchedSig->instrLen ).add (matchedSig->postOffset );
356406
357407 if (!printedPatterns[p.name ]) {
358408 std::cout << " [Memory] Pattern: " << p.name
@@ -361,49 +411,54 @@ int main() {
361411 printedPatterns[p.name ] = true ;
362412 }
363413
364- if (p.type == TYPE_FLOAT ) {
414+ if (p.name == " Current BPM " ) {
365415 g_bpm = resolved.as <float >();
366416 }
367- else if (p.type == TYPE_INT) {
368- g_playState = (resolved.as <int >() == 1 ) ? " Playing" : " Stopped" ;
369- }
370- else if (p.type == TYPE_POINTER_TO_INT) {
371- auto ptrVal = resolved.as_ptr <int >();
372- if (ptrVal) {
373- int v{};
374- if (ReadProcessMemory (hProc, ptrVal, &v, sizeof (v), nullptr ))
375- g_songMode = (v == 1 );
417+ else if (p.name == " Pattern/Song Toggle" ) {
418+ int val = 0 ;
419+ if (matchedSig->type == TYPE_POINTER_TO_INT) {
420+ auto ptrVal = resolved.as_ptr <int >();
421+ if (ptrVal) ReadProcessMemory (hProc, ptrVal, &val, sizeof (val), nullptr );
376422 }
423+ g_songMode = (val == 1 );
377424 }
378- else if (p.type == TYPE_POINTER_TO_SHORT) {
379- auto ptrVal = resolved.as_ptr <int16_t >();
380- if (ptrVal) {
381- int16_t raw{};
382- if (ReadProcessMemory (hProc, ptrVal, &raw, sizeof (raw), nullptr ))
383- g_masterPitch = static_cast <int >(raw);
425+ else if (p.name == " Master Pitch" ) {
426+ int16_t raw = 0 ;
427+ if (matchedSig->type == TYPE_POINTER_TO_SHORT) {
428+ auto ptrVal = resolved.as_ptr <int16_t >();
429+ if (ptrVal) ReadProcessMemory (hProc, ptrVal, &raw, sizeof (raw), nullptr );
384430 }
431+ g_masterPitch = static_cast <int >(raw);
385432 }
386- else if (p.type == TYPE_POINTER_TO_BYTE) {
387- auto ptrVal = resolved.as_ptr <unsigned char >();
388- if (ptrVal) {
389- unsigned char v{};
390- if (ReadProcessMemory (hProc, ptrVal, &v, sizeof (v), nullptr ))
391- g_metronome = (v != 0 );
433+ else if (p.name == " Metronome Toggle" ) {
434+ unsigned char val = 0 ;
435+ if (matchedSig->type == TYPE_POINTER_TO_BYTE) {
436+ auto ptrVal = resolved.as_ptr <unsigned char >();
437+ if (ptrVal) ReadProcessMemory (hProc, ptrVal, &val, sizeof (val), nullptr );
392438 }
439+ g_metronome = (val != 0 );
393440 }
394- else if (p.type == TYPE_BYTE) {
395- g_playState = (resolved.as <uint8_t >() == 1 ) ? " Playing" : " Stopped" ;
441+ else if (p.name == " Playing Status" ) {
442+ uint8_t val = 0 ;
443+ if (matchedSig->type == TYPE_BYTE) {
444+ val = resolved.as <uint8_t >();
445+ }
446+ else if (matchedSig->type == TYPE_POINTER_TO_INT) {
447+ int * ptrVal = resolved.as_ptr <int >();
448+ if (ptrVal) ReadProcessMemory (hProc, ptrVal, &val, sizeof (val), nullptr );
449+ }
450+ g_playState = (val == 1 ) ? " Playing" : " Stopped" ;
396451 }
397452 }
398453
399454 if (!initialCheckDone) {
400- for (const auto & p : PatternList) {
455+ for (const auto & p : PatternList) {
401456 if (printedPatterns.find (p.name ) == printedPatterns.end ()) {
402457 std::cout << " WARNING: Pattern '" << p.name << " ' was not found. Some features may not work.\n " ;
403458 }
404459 }
405- initialCheckDone = true ;
406- }
460+ initialCheckDone = true ;
461+ }
407462
408463 g_projectName = GetFLStudioProjectName ();
409464
0 commit comments