Skip to content

Commit 62c8c47

Browse files
committed
Cleo injection fixes
1 parent df8dc84 commit 62c8c47

File tree

13 files changed

+182
-111
lines changed

13 files changed

+182
-111
lines changed

CHANGELOG

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1+
v0.1.15 -- Mar 05 2014
2+
Bug fix: CLEO scripts injection works with CLEO 4.1 and below
3+
Bug fix: CLEO folder don't need to exist on the game base path for CLEO 4.3 to work
4+
15
v0.1.14 -- Mar 04 2014
2-
Feature: CLEO files do not need copy and paste to work anymore, they're injected into CLEO.asi searches
6+
Feature: CLEO files aren't copied and pasted anymore, they're injected into CLEO.asi searches
37
Feature: Binary IPLs are automatically detected
48
Bug fix: Fixed binary IPLs being handled wrongly
59
Bug fix: Fixed crash on exit if playing SA:MP

doc/plugins/std-asi.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
*************************************************************************
22
Name: std-asi
3-
Version: 0.10
3+
Version: 0.11
44
Author: LINK/2012 <[email protected]>
55
Default Priority: 50
66
*************************************************************************

src/injector/calling.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* Injectors - Function Calls Using Variadic Templates
33
* Header with helpful stuff for ASI memory hacking
44
*
5-
* (C) 2012-2014 LINK/2012 <[email protected]>
5+
* (C) 2014 LINK/2012 <[email protected]>
66
*
77
* This source code is offered for use in the public domain. You may
88
* use, modify or distribute it freely.

src/injector/game/fxt.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* Injectors - Fake GTA Text Implementation
33
* Header with helpful stuff for ASI memory hacking
44
*
5-
* (C) 2012-2014 LINK/2012 <[email protected]>
5+
* (C) 2014 LINK/2012 <[email protected]>
66
*
77
* This source code is offered for use in the public domain. You may
88
* use, modify or distribute it freely.

src/injector/game/fxt_parser.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* Injectors - Fake GTA Text Implementation
33
* Header with helpful stuff for ASI memory hacking
44
*
5-
* (C) 2012-2014 LINK/2012 <[email protected]>
5+
* (C) 2014 LINK/2012 <[email protected]>
66
*
77
* This source code is offered for use in the public domain. You may
88
* use, modify or distribute it freely.

src/injector/game/saving.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* Injectors - Save Notification
33
* Header with helpful stuff for ASI memory hacking
44
*
5-
* (C) 2012-2014 LINK/2012 <[email protected]>
5+
* (C) 2014 LINK/2012 <[email protected]>
66
*
77
* This source code is offered for use in the public domain. You may
88
* use, modify or distribute it freely.

src/injector/hooking.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* Injectors - Classes for making your hooking life easy
33
* Header with helpful stuff for ASI memory hacking
44
*
5-
* (C) 2012-2014 LINK/2012 <[email protected]>
5+
* (C) 2013-2014 LINK/2012 <[email protected]>
66
*
77
* This source code is offered for use in the public domain. You may
88
* use, modify or distribute it freely.

src/injector/injector.hpp

Lines changed: 110 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,33 @@
1919
#include <cstdint>
2020
#include <cstdio>
2121

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+
2249
namespace injector
2350
{
2451

@@ -29,6 +56,8 @@ namespace injector
2956
* Detects the game, the game version and the game region
3057
* This assumes the executable is decrypted, so, Silent's ASI Loader is recommended.
3158
*/
59+
#ifndef INJECTOR_OWN_GVM
60+
#ifndef INJECTOR_GVM_DUMMY
3261
class game_version_manager
3362
{
3463
public:
@@ -41,10 +70,22 @@ class game_version_manager
4170
public:
4271
game_version_manager()
4372
{
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();
4680
}
4781

82+
83+
// Clear any information about game version
84+
void Clear()
85+
{
86+
game = region = major = minor = cracker = steam = 0;
87+
}
88+
4889
// Checks if I don't know the game we are attached to
4990
bool IsUnknown() { return game == 0; }
5091
// Checks if this is the steam version
@@ -69,22 +110,7 @@ class game_version_manager
69110
bool IsSA () { return game == 'S'; }
70111

71112
// 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();
88114

89115
// Gets the game version as text, the buffer must contain at least 32 bytes of space.
90116
char* GetVersionText(char* buffer)
@@ -118,6 +144,14 @@ class game_version_manager
118144
MessageBoxA(0, buf, PluginName, MB_ICONERROR);
119145
}
120146
};
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
121155

122156

123157
/*
@@ -186,10 +220,8 @@ class address_manager : public game_version_manager
186220
{ return translate_address(p); }
187221
};
188222
};
189-
#endif
190-
191-
192223

224+
#endif // #if 1
193225

194226

195227

@@ -641,73 +673,81 @@ inline void MakeRET(memory_pointer_tr at, uint16_t pop = 0, bool vp = true)
641673

642674

643675

676+
#ifndef INJECTOR_GVM_OWN_DETECT // Should we implement our detection method?
644677

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()
652680
{
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)
654692
{
655-
if(ReadMemory<uint32_t>(raw_ptr(0x5C1E70), true) == 0x53E58955)
693+
case 0x5C1E70: // GTA III 1.0
656694
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
658698
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)
660703
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
674707
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
676711
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;
686713

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
693721
game = 'S', major = 1, minor = 0, region = 'U', steam = false;
694722
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
697726
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
699730
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
701734
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)
703739
game = 'S', major = 3, minor = 0, region = 0, steam = true;
704-
else
705-
return false;
740+
return true;
706741

707-
return true;
742+
default:
743+
return false;
708744
}
709-
return false;
710745
}
711746

747+
#endif
748+
749+
750+
751+
712752
} // namespace
713753

src/plugins/std-asi/ModuleInfo.cpp

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -73,24 +73,52 @@ CThePlugin::ModuleInfo::ModuleInfo(std::string&& path)
7373
/*
7474
* Find all cleo plugins already loaded and push them into asi list
7575
*/
76-
void CThePlugin::LocateCleoPlugins()
76+
void CThePlugin::LocateCleo()
7777
{
78-
ModulesWalk(GetCurrentProcessId(), [this](const MODULEENTRY32& entry)
78+
HMODULE hCleo = GetModuleHandleA("CLEO.asi");
79+
80+
// We need CLEO.asi module for cleo script injection
81+
if(hCleo)
7982
{
80-
// Find the extension for this module
81-
if(const char* p = strrchr(entry.szModule, '.'))
83+
char buffer[MAX_PATH];
84+
if(GetModuleFileNameA(hCleo, buffer, sizeof(buffer)))
8285
{
83-
// Is it a .cleo plugin?
84-
if(IsFileExtension(p+1, "cleo"))
86+
if(const char* p = path_translator_base::CallInfo::GetCurrentDir(buffer, this->modloader->gamepath, -1))
8587
{
86-
// Yep, take the relative path and push it to the asi list
87-
p = path_translator_base::CallInfo::GetCurrentDir(entry.szExePath, this->modloader->gamepath, -1);
88+
// Find the library version
89+
auto CLEO_GetVersion = (int (__stdcall*)()) GetProcAddress(hCleo, "_CLEO_GetVersion@0");
90+
this->iCleoVersion = CLEO_GetVersion? CLEO_GetVersion() : 0;
91+
92+
Log("CLEO library version %X found at \"%s\"", iCleoVersion, p);
93+
if(this->bHasNoCleoFolder = !IsPath("./CLEO/")) Log("Warning: No CLEO folder found, may cause problems");
94+
8895
this->asiList.emplace_back(p);
8996
}
9097
}
91-
92-
return true;
93-
});
98+
else
99+
hCleo = NULL;
100+
}
101+
102+
// Find all the already loaded cleo plugins
103+
if(hCleo)
104+
{
105+
ModulesWalk(GetCurrentProcessId(), [this](const MODULEENTRY32& entry)
106+
{
107+
// Find the extension for this module
108+
if(const char* p = strrchr(entry.szModule, '.'))
109+
{
110+
// Is it a .cleo plugin?
111+
if(IsFileExtension(p+1, "cleo"))
112+
{
113+
// Yep, take the relative path and push it to the asi list
114+
if(p = path_translator_base::CallInfo::GetCurrentDir(entry.szExePath, this->modloader->gamepath, -1))
115+
this->asiList.emplace_back(p);
116+
}
117+
}
118+
119+
return true;
120+
});
121+
}
94122
}
95123

96124

0 commit comments

Comments
 (0)