Skip to content

Commit

Permalink
2.0.1.1
Browse files Browse the repository at this point in the history
Fixes:
- CLEO from location "2.0.1" now can be loaded (oops, im sorry!)
- Added an interface for CLEO API (for opcode-mods?)
  • Loading branch information
AndroidModLoader committed Sep 13, 2021
1 parent 95f9679 commit 907cef9
Show file tree
Hide file tree
Showing 3 changed files with 196 additions and 4 deletions.
99 changes: 99 additions & 0 deletions cleo.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
struct cleo_ifs_t
{
// interface v1

uint32_t (*GetInterfaceVersion)(); // currently = 1

eGameIdent (*GetGameIdentifier)();
eGameVerInternal (*GetGameVersionInternal)();

const char *(*GetPackageName)(); // PSP: DiscId
const char *(*GetPackageVersionStr)(); // PSP: DiscVersion
uint32_t (*GetPackageVersionCode)(); // PSP: DiscVersionCode

const char *(*GetCleoStorageDir)();
const char *(*GetCleoPluginLoadDir)(); // PSP: same as StorageDir

void (*PrintToCleoLog)(const char *str);

const char *(*GetMainLibraryFileName)();
void *(*GetMainLibraryLoadAddress)();

//typedef struct { uint32_t rva, size; } section_t;

uint32_t (*GetMainLibraryExecutableSections)(ICLEO::section_t *sections, uint32_t size);
void *(*FindExecutablePattern)(const char *pattern, uint32_t index);

#ifdef ANDROID
void *(*GetMainLibrarySymbol)(const char *name);
#endif

void (*MemWriteArr)(void *addr, uint8_t *arr, uint32_t size, bool protect);

#ifdef ANDROID
void (*ReplaceThumbCall)(void *addr, void *func_to);
void (*HookThumbFunc)(void *func, uint32_t startSize, void *func_to, void **func_orig);
void (*ReplaceArmCall)(void *addr, void *func_to);
void (*HookArmFunc)(void *func, uint32_t startSize, void *func_to, void **func_orig);
#else
void (*ReplaceMipsCall)(void *addr, void *func_to);
void (*HookMipsFunc)(void *func, uint32_t startSize, void *func_to, void **func_orig);
#endif

// ip is a pointer inside scriptHandle structure, the structure is different in all games
//typedef void (*opcode_handler_t)(void *scriptHandle, uint32_t *ip, uint16_t opcode, const char *name);

bool (*RegisterOpcode)(uint16_t opcode, ICLEO::opcode_handler_t handler);
bool (*RegisterOpcodeFunction)(const char *name, ICLEO::opcode_handler_t handler);

//typedef struct { union { int32_t i; uint32_t u; float f; }; } data_t;

ICLEO::data_t *(*ReadParam)(void *scriptHandle); // returned pointer has the data until next param read call (points into game's ScriptParams)
ICLEO::data_t *(*GetPointerToScriptVar)(void *scriptHandle); // returned pointer is valid all the time (points into game's script handle or into global seg)
bool (*ReadString8byte)(void *scriptHandle, char *buf, uint32_t size);
bool (*ReadStringLong)(void *scriptHandle, char *buf, uint32_t size); // supported only in III/VC/SA (so far)

bool (*IsParamListEnd)(uint32_t ip);
void (*SkipParamListEnd)(uint32_t *ip);

void *(*GetRealCodePointer)(uint32_t ip); // script ip to ptr, script ip has to be gained from handle->ip as *ip (handler param)
uint32_t (*GetIpUsingRealCodePointer)(void *realPtr); // ptr to script ip
void *(*GetRealLabelPointer)(void *scriptHandle, uint32_t offset); // offset has to be represented in the raw way i.e. opcode label param encoding
};

extern cleo_ifs_t* cleo;

class CLEO : public ICLEO
{
public:
uint32_t GetInterfaceVersion() { return cleo->GetInterfaceVersion(); };
eGameIdent GetGameIdentifier() { return cleo->GetGameIdentifier(); };
eGameVerInternal GetGameVersionInternal() { return cleo->GetGameVersionInternal(); };
const char *GetPackageName() { return cleo->GetPackageName(); };
const char *GetPackageVersionStr() { return cleo->GetPackageVersionStr(); };
uint32_t GetPackageVersionCode() { return cleo->GetPackageVersionCode(); };
const char *GetCleoStorageDir() { return cleo->GetCleoStorageDir(); };
//const char *GetCleoPluginLoadDir() { return cleo->GetCleoPluginLoadDir(); }; // Removed ¯\_(ツ)_/¯
void PrintToCleoLog(const char *str) { return cleo->PrintToCleoLog(str); };
const char *GetMainLibraryFileName() { return cleo->GetMainLibraryFileName(); };
void *GetMainLibraryLoadAddress() { return cleo->GetMainLibraryLoadAddress(); };
uint32_t GetMainLibraryExecutableSections(ICLEO::section_t *sections, uint32_t size) { return cleo->GetMainLibraryExecutableSections(sections, size); };
void *FindExecutablePattern(const char *pattern, uint32_t index) { return cleo->FindExecutablePattern(pattern, index); };
void *GetMainLibrarySymbol(const char *name) { return cleo->GetMainLibrarySymbol(name); };
void MemWriteArr(void *addr, uint8_t *arr, uint32_t size, bool protect) { return cleo->MemWriteArr(addr, arr, size, protect); };
void ReplaceThumbCall(void *addr, void *func_to) { return cleo->ReplaceThumbCall(addr, func_to); };
void HookThumbFunc(void *func, uint32_t startSize, void *func_to, void **func_orig) { return cleo->HookThumbFunc(func, startSize, func_to, func_orig); };
void ReplaceArmCall(void *addr, void *func_to) { return cleo->ReplaceArmCall(addr, func_to); };
void HookArmFunc(void *func, uint32_t startSize, void *func_to, void **func_orig) { return cleo->HookArmFunc(func, startSize, func_to, func_orig); };
bool RegisterOpcode(uint16_t opcode, ICLEO::opcode_handler_t handler) { return cleo->RegisterOpcode(opcode, handler); };
bool RegisterOpcodeFunction(const char *name, ICLEO::opcode_handler_t handler) { return cleo->RegisterOpcodeFunction(name, handler); };
ICLEO::data_t *ReadParam(void *scriptHandle) { return cleo->ReadParam(scriptHandle); };
ICLEO::data_t *GetPointerToScriptVar(void *scriptHandle) { return cleo->GetPointerToScriptVar(scriptHandle); };
bool ReadString8byte(void *scriptHandle, char *buf, uint32_t size) { return cleo->ReadString8byte(scriptHandle, buf, size); };
bool ReadStringLong(void *scriptHandle, char *buf, uint32_t size) { return cleo->ReadStringLong(scriptHandle, buf, size); };
bool IsParamListEnd(uint32_t ip) { return cleo->IsParamListEnd(ip); };
void SkipParamListEnd(uint32_t *ip) { return cleo->SkipParamListEnd(ip); };
void *GetRealCodePointer(uint32_t ip) { return cleo->GetRealCodePointer(ip); };
uint32_t GetIpUsingRealCodePointer(void *realPtr) { return cleo->GetIpUsingRealCodePointer(realPtr); };
void *GetRealLabelPointer(void *scriptHandle, uint32_t offset) { return cleo->GetRealLabelPointer(scriptHandle, offset); };
};
78 changes: 78 additions & 0 deletions icleo.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>

enum eGameIdent
{
GTA3,
GTAVC,
GTASA,
GTALCS,
GTAVCS
};

enum eGameVerInternal
{
VER_NONE,
VER_GTA3_1_4,
VER_GTAVC_1_03,
VER_GTASA_1_00,
VER_GTASA_1_01,
VER_GTASA_1_02,
VER_GTASA_1_03,
VER_GTASA_1_05,
VER_GTASA_1_06,
VER_GTASA_1_05_GER,
VER_GTASA_1_07,
VER_GTA3_1_6,
VER_GTAVC_1_06,
VER_GTASA_1_08,
VER_GTALCS_2_2,
VER_GTA3_1_8_OR_HIGHER,
VER_GTAVC_1_09_OR_HIGHER,
VER_GTASA_2_00_OR_HIGHER,
VER_GTALCS_2_4_OR_HIGHER,
VER_GTALCS_PSP_1_05_OR_HIGHER,
VER_GTAVCS_PSP_1_02_OR_HIGHER
};

class ICLEO
{
public:
virtual uint32_t GetInterfaceVersion() = 0;
virtual eGameIdent GetGameIdentifier() = 0;
virtual eGameVerInternal GetGameVersionInternal() = 0;
virtual const char *GetPackageName() = 0;
virtual const char *GetPackageVersionStr() = 0;
virtual uint32_t GetPackageVersionCode() = 0;
virtual const char *GetCleoStorageDir() = 0;
//virtual const char *GetCleoPluginLoadDir() = 0; // Removed ¯\_(ツ)_/¯
virtual void PrintToCleoLog(const char *str) = 0;
virtual const char *GetMainLibraryFileName() = 0;
virtual void *GetMainLibraryLoadAddress() = 0;
typedef struct { uint32_t rva, size; } section_t;
virtual uint32_t GetMainLibraryExecutableSections(section_t *sections, uint32_t size) = 0;
virtual void *FindExecutablePattern(const char *pattern, uint32_t index) = 0;
virtual void *GetMainLibrarySymbol(const char *name) = 0;
virtual void MemWriteArr(void *addr, uint8_t *arr, uint32_t size, bool protect) = 0;
virtual void ReplaceThumbCall(void *addr, void *func_to) = 0;
virtual void HookThumbFunc(void *func, uint32_t startSize, void *func_to, void **func_orig) = 0;
virtual void ReplaceArmCall(void *addr, void *func_to) = 0;
virtual void HookArmFunc(void *func, uint32_t startSize, void *func_to, void **func_orig) = 0;
// ip is a pointer inside scriptHandle structure, the structure is different in all games
typedef void opcode_handler_t(void *scriptHandle, uint32_t *ip, uint16_t opcode, const char *name);
virtual bool RegisterOpcode(uint16_t opcode, opcode_handler_t handler) = 0;
virtual bool RegisterOpcodeFunction(const char *name, opcode_handler_t handler) = 0;
typedef struct { union { int32_t i; uint32_t u; float f; }; } data_t;
virtual data_t *ReadParam(void *scriptHandle) = 0; // returned pointer has the data until next param read call (points into game's ScriptParams)
virtual data_t *GetPointerToScriptVar(void *scriptHandle) = 0; // returned pointer is valid all the time (points into game's script handle or into global seg)
virtual bool ReadString8byte(void *scriptHandle, char *buf, uint32_t size) = 0;
virtual bool ReadStringLong(void *scriptHandle, char *buf, uint32_t size) = 0; // supported only in III/VC/SA (so far)
virtual bool IsParamListEnd(uint32_t ip) = 0;
virtual void SkipParamListEnd(uint32_t *ip) = 0;
virtual void *GetRealCodePointer(uint32_t ip) = 0; // script ip to ptr, script ip has to be gained from handle->ip as *ip (handler param)
virtual uint32_t GetIpUsingRealCodePointer(void *realPtr) = 0; // ptr to script ip
virtual void *GetRealLabelPointer(void *scriptHandle, uint32_t offset) = 0; // offset has to be represented in the raw way i.e. opcode label param encoding
};
23 changes: 19 additions & 4 deletions main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,18 @@
#include <stdint.h>
#include <dlfcn.h>

#include "icleo.h"
#include "cleo.h"
CLEO cleoLocal;
ICLEO* cleoInterface = &cleoLocal;

#include "isautils.h"
ISAUtils* sautils = nullptr;
cleo_ifs_t* cleo = nullptr;

#define sizeofA(__aVar) ((int)(sizeof(__aVar)/sizeof(__aVar[0])))

MYMODCFG(net.rusjj.cleolib, CLEO Library, 2.0.1, Alexander Blade & RusJJ)
MYMODCFG(net.rusjj.cleolib, CLEO Library, 2.0.1.1, Alexander Blade & RusJJ)
BEGIN_DEPLIST()
ADD_DEPENDENCY_VER(net.rusjj.aml, 1.0.0.4)
END_DEPLIST()
Expand Down Expand Up @@ -49,7 +55,7 @@ void OnRedArrowChanged(int oldVal, int newVal)
cfg->Save();
}

extern "C" void OnModLoad()
extern "C" void OnModPreLoad()
{
logger->SetTag("CLEO Mod");
pCLEOLocation = cfg->Bind("CLEO_Location", 0);
Expand All @@ -73,9 +79,11 @@ extern "C" void OnModLoad()
if(libEntry == nullptr) goto OOPSIE;

dladdr((void*)libEntry, &pDLInfo);
setenv("EXTERNAL_STORAGE", std::filesystem::path(aml->GetConfigPath()).parent_path().parent_path().c_str(), 1);
cleo = (cleo_ifs_t*)((uintptr_t)pDLInfo.dli_fbase + 0x219AA8);
if(pCLEOLocation->GetInt() == 1)
{
setenv("EXTERNAL_STORAGE", std::filesystem::path(aml->GetConfigPath()).parent_path().parent_path().c_str(), 1);

aml->Unprot((uintptr_t)pDLInfo.dli_fbase + 0x146A9, 11);
uintptr_t cleoDir = (uintptr_t)pDLInfo.dli_fbase + 0x146A9;
*(char*)(cleoDir + 3) = '\0';
Expand All @@ -90,17 +98,24 @@ extern "C" void OnModLoad()
}
else if(pCLEOLocation->GetInt() == 2)
{
auto VAR = std::filesystem::path(aml->GetConfigPath()).parent_path().parent_path();
setenv("EXTERNAL_STORAGE", VAR.c_str(), 1);
std::filesystem::create_directory(VAR.c_str() + std::string("/cleo"));

aml->Unprot((uintptr_t)pDLInfo.dli_fbase + 0x146A9, 11);
uintptr_t cleoDir = (uintptr_t)pDLInfo.dli_fbase + 0x146A9;
*(char*)(cleoDir + 8) = '\0';
}

if(!pCLEORedArrow->GetBool())
aml->PlaceNOP((uintptr_t)pDLInfo.dli_fbase + 0xBD82, 2);

RegisterInterface("CLEO", cleoInterface);
libEntry();
logger->Info("CLEO initialized!");
}

extern "C" void OnModLoad()
{
sautils = (ISAUtils*)GetInterface("SAUtils");
if(sautils)
{
Expand Down

0 comments on commit 907cef9

Please sign in to comment.