19
19
#include < cstdint>
20
20
#include < cstdio>
21
21
22
+ /*
23
+ The following macros (#define) are relevant on this header:
24
+
25
+ INJECTOR_GVM_HAS_TRANSLATOR
26
+ If defined, the user should provide their own address_manager::translator function.
27
+ That function is responssible for translating a void pointer (that mayn't be an actual pointer) into an actual address.
28
+ The meaning of that void pointer will be made by YOU when you send it to the functions that receive pointers on this library.
29
+ The default translator does nothing but returns that void pointer as the address.
30
+
31
+ INJECTOR_GVM_OWN_DETECT
32
+ If defined, the user should provide it's own game detection function thought game_version_manager::Detect
33
+ By default it provide an good detection for the Grand Theft Auto series.
34
+
35
+ INJECTOR_GVM_PLUGIN_NAME
36
+ If this is defined, it will be used as the plugin name used at error messages.
37
+ By default it will use ""Unknown Plugin Name"
38
+
39
+ INJECTOR_GVM_DUMMY
40
+ If defined, the game_version_manager will be a dummy object
41
+ By default it provides a nice gvm for Grand Theft Auto series
42
+
43
+ INJECTOR_OWN_GVM
44
+ If defined, the game_version_manager should be implemented by the user before including this library.
45
+ By default it provides a nice gvm for Grand Theft Auto series
46
+ */
47
+
48
+
22
49
namespace injector
23
50
{
24
51
@@ -29,6 +56,8 @@ namespace injector
29
56
* Detects the game, the game version and the game region
30
57
* This assumes the executable is decrypted, so, Silent's ASI Loader is recommended.
31
58
*/
59
+ #ifndef INJECTOR_OWN_GVM
60
+ #ifndef INJECTOR_GVM_DUMMY
32
61
class game_version_manager
33
62
{
34
63
public:
@@ -41,10 +70,22 @@ class game_version_manager
41
70
public:
42
71
game_version_manager ()
43
72
{
44
- PluginName = " Unknown Plugin Name" ;
45
- game = region = major = minor = cracker = steam = 0 ;
73
+ #ifdef INJECTOR_GVM_PLUGIN_NAME
74
+ PluginName = INJECTOR_GVM_PLUGIN_NAME;
75
+ #else
76
+ PluginName = " Unknown Plugin Name" ;
77
+ #endif
78
+
79
+ this ->Clear ();
46
80
}
47
81
82
+
83
+ // Clear any information about game version
84
+ void Clear ()
85
+ {
86
+ game = region = major = minor = cracker = steam = 0 ;
87
+ }
88
+
48
89
// Checks if I don't know the game we are attached to
49
90
bool IsUnknown () { return game == 0 ; }
50
91
// Checks if this is the steam version
@@ -69,22 +110,7 @@ class game_version_manager
69
110
bool IsSA () { return game == ' S' ; }
70
111
71
112
// Detects game, region and version; returns false if could not detect it
72
- bool Detect ()
73
- {
74
- game = region = major = minor = cracker = steam = 0 ;
75
-
76
- // Look for game and version thought the entry-point
77
- return (DetectSA () || DetectVC () || DetectIII ());
78
- }
79
-
80
-
81
- // Thanks Silent for the DetectXXX() functions
82
- // DetectXXX():
83
- // The DetectXXX Methods tries to detect the region and version for game XXX
84
- // If it could not be detect, no changes are made to the object and the func returns false
85
- bool DetectIII ();
86
- bool DetectVC ();
87
- bool DetectSA ();
113
+ bool Detect ();
88
114
89
115
// Gets the game version as text, the buffer must contain at least 32 bytes of space.
90
116
char * GetVersionText (char * buffer)
@@ -118,6 +144,14 @@ class game_version_manager
118
144
MessageBoxA (0 , buf, PluginName, MB_ICONERROR);
119
145
}
120
146
};
147
+ #else // INJECTOR_GVM_DUMMY
148
+ class game_version_manager
149
+ {
150
+ public:
151
+ bool Detect () { return true ; }
152
+ };
153
+ #endif // INJECTOR_GVM_DUMMY
154
+ #endif // INJECTOR_OWN_GVM
121
155
122
156
123
157
/*
@@ -186,10 +220,8 @@ class address_manager : public game_version_manager
186
220
{ return translate_address (p); }
187
221
};
188
222
};
189
- #endif
190
-
191
-
192
223
224
+ #endif // #if 1
193
225
194
226
195
227
@@ -641,73 +673,81 @@ inline void MakeRET(memory_pointer_tr at, uint16_t pop = 0, bool vp = true)
641
673
642
674
643
675
676
+ #ifndef INJECTOR_GVM_OWN_DETECT // Should we implement our detection method?
644
677
645
-
646
- /*
647
- *
648
- *
649
- */
650
-
651
- inline bool game_version_manager::DetectIII ()
678
+ // Detects game, region and version; returns false if could not detect it
679
+ inline bool game_version_manager::Detect ()
652
680
{
653
- if (this ->IsUnknown () || this ->IsIII ())
681
+ // Cleanup data
682
+ this ->Clear ();
683
+
684
+ // Find NT header
685
+ uintptr_t base = (uintptr_t ) GetModuleHandleA (NULL );;
686
+ IMAGE_DOS_HEADER* dos = (IMAGE_DOS_HEADER*)(base);
687
+ IMAGE_NT_HEADERS* nt = (IMAGE_NT_HEADERS*)(base + dos->e_lfanew );
688
+
689
+ // Look for game and version thought the entry-point
690
+ // Thanks to Silent for many of the entry point offsets
691
+ switch (base + nt->OptionalHeader .AddressOfEntryPoint )
654
692
{
655
- if (ReadMemory< uint32_t >( raw_ptr ( 0x5C1E70 ), true ) == 0x53E58955 )
693
+ case 0x5C1E70 : // GTA III 1.0
656
694
game = ' 3' , major = 1 , minor = 0 , region = 0 , steam = false ;
657
- else if (ReadMemory<uint32_t >(raw_ptr (0x5C2130 ), true ) == 0x53E58955 )
695
+ return true ;
696
+
697
+ case 0x5C2130 : // GTA III 1.1
658
698
game = ' 3' , major = 1 , minor = 1 , region = 0 , steam = false ;
659
- else if (ReadMemory<uint32_t >(raw_ptr (0x5C6FD0 ), true ) == 0x53E58955 )
699
+ return true ;
700
+
701
+ case 0x5C6FD0 : // GTA III 1.1 (Cracked Steam Version)
702
+ case 0x9912ED : // GTA III 1.1 (Encrypted Steam Version)
660
703
game = ' 3' , major = 1 , minor = 1 , region = 0 , steam = true ;
661
- else
662
- return false ;
663
-
664
- return true ;
665
- }
666
- return false ;
667
- }
668
-
669
- inline bool game_version_manager::DetectVC ()
670
- {
671
- if (this ->IsUnknown () || this ->IsVC ())
672
- {
673
- if (ReadMemory<uint32_t >(raw_ptr (0x667BF0 ), true ) == 0x53E58955 )
704
+ return true ;
705
+
706
+ case 0x667BF0 : // GTA VC 1.0
674
707
game = ' V' , major = 1 , minor = 0 , region = 0 , steam = false ;
675
- else if (ReadMemory<uint32_t >(raw_ptr (0x667C40 ), true ) == 0x53E58955 )
708
+ return true ;
709
+
710
+ case 0x667C40 : // GTA VC 1.1
676
711
game = ' V' , major = 1 , minor = 1 , region = 0 , steam = false ;
677
- else if (ReadMemory<uint32_t >(raw_ptr (0xA402ED ), true ) == 0x56525153 )
678
- game = ' V' , major = 1 , minor = 1 , region = 0 , steam = true ;
679
- else
680
- return false ;
681
-
682
- return true ;
683
- }
684
- return false ;
685
- }
712
+ return true ;
686
713
687
- inline bool game_version_manager::DetectSA ()
688
- {
689
- if (this ->IsUnknown () || this ->IsSA ())
690
- {
691
- if (ReadMemory<uint32_t >(raw_ptr (0x82457C ), true ) == 0x94BF )
692
- {
714
+ case 0x666BA0 : // GTA VC 1.1 (Cracked Steam Version)
715
+ case 0xA402ED : // GTA VC 1.1 (Encrypted Steam Version)
716
+ game = ' V' , major = 1 , minor = 1 , region = 0 , steam = true ;
717
+ return true ;
718
+
719
+ case 0x82457C : // GTA SA 1.0 US Cracked
720
+ case 0x824570 : // GTA SA 1.0 US Compact
693
721
game = ' S' , major = 1 , minor = 0 , region = ' U' , steam = false ;
694
722
cracker = injector::ReadMemory<uint8_t >(raw_ptr (0x406A20 ), true ) == 0xE9 ? ' H' : 0 ;
695
- }
696
- else if (ReadMemory<uint32_t >(raw_ptr (0x8245BC ), true ) == 0x94BF )
723
+ return true ;
724
+
725
+ case 0x8245BC : // GTA SA 1.0 EU Cracked
697
726
game = ' S' , major = 1 , minor = 0 , region = ' E' , steam = false ;
698
- else if (ReadMemory<uint32_t >(raw_ptr (0x8252FC ), true ) == 0x94BF )
727
+ return true ;
728
+
729
+ case 0x8252FC : // GTA SA 1.1 US Cracked
699
730
game = ' S' , major = 1 , minor = 1 , region = ' U' , steam = false ;
700
- else if (ReadMemory<uint32_t >(raw_ptr (0x82533C ), true ) == 0x94BF )
731
+ return true ;
732
+
733
+ case 0x82533C : // GTA SA 1.1 EU Cracked
701
734
game = ' S' , major = 1 , minor = 1 , region = ' E' , steam = false ;
702
- else if (ReadMemory<uint32_t >(raw_ptr (0x85EC4A ), true ) == 0x94BF )
735
+ return true ;
736
+
737
+ case 0x85EC4A : // GTA SA 3.0 (Cracked Steam Version)
738
+ case 0xD3C3DB : // GTA SA 3.0 (Encrypted Steam Version)
703
739
game = ' S' , major = 3 , minor = 0 , region = 0 , steam = true ;
704
- else
705
- return false ;
740
+ return true ;
706
741
707
- return true ;
742
+ default :
743
+ return false ;
708
744
}
709
- return false ;
710
745
}
711
746
747
+ #endif
748
+
749
+
750
+
751
+
712
752
} // namespace
713
753
0 commit comments