gkms-localify-ios/GakumasLocalify/il2cpp_dump/Il2cppJson.hpp

124 lines
4.0 KiB
C++

#pragma once
#include <string>
#include <vector>
#include <map>
#include <cstdint>
#include "GakumasLocalify/GakumasLocalify/Local.h"
#include "GakumasLocalify/GakumasLocalify/Log.h"
namespace Il2cppJson {
// inline static uintptr_t s_baseAddress = 0;
inline uintptr_t& GetUnityBaseAddress()
{
static uintptr_t s_baseAddress = 0;
return s_baseAddress;
}
inline std::map<std::string, uintptr_t>& GetIl2cppAddressMap() {
static std::map<std::string, uintptr_t> il2cppAddress {
{ "il2cpp_object_new", 0x9D710C4 }, // 2.10.1、 2.10.2
{ "il2cpp_class_get_method_from_name", 0x9DCC534 },
{ "il2cpp_string_new", 0x9D7110C },
{ "il2cpp_class_get_field_from_name", 0x9DCC2B0 },
{ "il2cpp_class_from_type", 0x9D70E30},
{ "il2cpp_class_get_fields", 0x9DCC1DC },
{ "il2cpp_field_static_get_value_0+1", 0x9DC8D00 },
{ "il2cpp_class_from_system_type", 0x9DCC028 },
{ "il2cpp_init", 0x9D70D90 },
{ "il2cpp_class_from_name", 0x9DCE4A4 },
{ "il2cpp_assembly_get_image", 0x7C11B50 },
{ "il2cpp_domain_get", 0x9DB81AC },
{ "il2cpp_domain_assembly_open", 0x9D70EE4 },
{ "il2cpp_domain_assembly_open+1", 0x9DA374C },
{ "il2cpp_resolve_icall", 0x9D71304 },
// il2cpp_class_get_parent
// il2cpp_resolve_icall
// il2cpp_class_get_nested_types
// il2cpp_type_get_object
// il2cpp_class_get_type
// il2cpp_field_static_set_value
// il2cpp_runtime_invoke
// il2cpp_thread_attach
// il2cpp_domain_get_assemblies
// il2cpp_image_get_filename
// il2cpp_image_get_name
// il2cpp_image_get_class_count
// il2cpp_image_get_class
// ...
};
return il2cppAddress;
}
template <typename Return, typename... Args>
auto InvokeAddress(uintptr_t address, Args... args) -> Return {
return reinterpret_cast<Return(*)(Args...)>(address)(args...);
}
template <typename Return, typename... Args>
auto InvokeIl2cpp(const std::string& name, Args... args) -> Return {
if (auto it = GetIl2cppAddressMap().find(name); it != GetIl2cppAddressMap().end())
{
// GakumasLocal::Log::InfoFmt("InvokeIl2cpp: %s", name.c_str());
return InvokeAddress<Return>(GetUnityBaseAddress() + it->second, args...);
}
// GakumasLocal::Log::InfoFmt("InvokeIl2cpp failed: %s", name.c_str());
// return nullptr;
if constexpr (!std::is_void_v<Return>)
{
return Return{};
}
}
struct Method {
std::string name;
std::vector<std::string> paramTypes;
int paramCount = 0;
uintptr_t address = 0;
template <typename Return, typename... Args>
auto Invoke(Args... args) -> Return {
return reinterpret_cast<Return(*)(Args...)>(address)(args...);
}
};
struct Class {
std::string assemblyName;
std::string namespaceName;
std::string className;
// methodName -> overloaded methods
std::map<std::string, std::vector<Method>> methods;
Method* GetMethod(const std::string& methodName,
const std::vector<std::string>& args = {});
// template <typename T>
static void* New(void* address) {
return InvokeIl2cpp<void*>("il2cpp_object_new", address);
}
};
// assembly -> namespace -> className -> Class
using ClassMap = std::map<std::string, std::map<std::string, std::map<std::string, Class>>>;
/// Initialize the parser. Must be called before any GetClass/GetMethod calls.
/// @param baseAddress Runtime base address of the UnityFramework image.
/// {HOME}/Documents/gakumas-localify/il2cpp.json
bool Init(uintptr_t baseAddress);
Class* GetClass(const std::string& assemblyName,
const std::string& nameSpaceName,
const std::string& className);
Method* GetMethod(const std::string& assemblyName,
const std::string& nameSpaceName,
const std::string& className,
const std::string& methodName,
const std::vector<std::string>& args = {});
} // namespace Il2cppJson