A run-time API resolver for IL2CPP Unity in External.
i have provided basic memory r/w and helper functions in Unity/rw/usermode.h.
if you are using for kernel project, you need replace with your own one.
see Example;
if you have more unity different version struct or code improve, pull request!
GameObject* GetLocalPlayer()
{
GameObject* Player = Unity::ObjectIterator(
[](void* ptr, GameObject object) -> GameObject* {
char buf[255];
um::ReadMemory(object.m_ObjectName, &buf);
if (buf[10] == 'L') // L - Local , R - Remote
{
return (GameObject*)ptr;
}
return nullptr;
}
);
return Player;
}
void Hack()
{
// example manipulate of rigidbody.isKinematic
GameObject* Player = GetLocalPlayer();
Component* Component = Unity::GetComponentByIndex(Player, 1, true);
if(!Component)
return;
Rigidbody rigidbody;
um::ReadMemory(Component, &rigidbody);
rigidbody.isKinematic = false;
um::WriteMemory(Component, &rigidbody);
}
Position Get/Set:
// Teleport to self
void Teleport()
{
GameObject* Player = GetLocalPlayer();
Vector3 position = Unity::GetPosition(Player);
Unity::SetPosition(Player, position);
}
loop through different type(Active,Tagged,UnTagged) of GameObjects in ALL Scenes:
// ObjectIterator lambda: return nullptr to make continue loop.
Unity::ObjectIterator(
[](void* ptr, GameObject object) -> GameObject* {
return nullptr;
}, eLOOPTYPE_UnTagged // eLOOPTYPE_Active | eLOOPTYPE_Tagged | eLOOPTYPE_UnTagged
);
find the class we want, and use it for find the component
// Example of VRChat
namespace GlobalVar // put it on some globalvar, cache it
{
il2cppClass* VRCPickup;
}
void CacheClasses()
{
std::vector<std::pair<il2cppClass*, il2cppClass>> Classes;
IL2CPP::FetchClasses(&Classes, "VRCSDK3"); // in other game, game classes are mostly in Assembly-CSharp.dll
GlobalVar::VRCPickup = IL2CPP::FilterClass(Classes, "VRCPickup", "VRC.SDK3.Components");
}
void Hack()
{
Unity::ObjectIterator(
[](void* ptr, GameObject object) -> GameObject* {
// the loop is manually, see TODO #1
void* buffer = malloc(object.m_iComponents * sizeof(ComponentList));
um::ReadMemory((void*)((uintptr_t)object.m_ComponentList + 8), buffer, object.m_iComponents * sizeof(ComponentList));
if (!buffer)
{
return nullptr;
}
for (int i = 0; i < object.m_iComponents; i++)
{
ComponentList* list = (ComponentList*)buffer;
Component component;
um::ReadMemory(list[i].m_Component, &component);
il2cppClass* klass = IL2CPP::GetClassByComponent(component.m_Component, false);
if (klass == Cache::VRCPickup) // we compare the il2cppClass Pointer, it will be same
{
bool DisallowTheft = false;
um::WriteMemory((void*)((uintptr_t)component.m_Component + 0x1C), &DisallowTheft); // use component.m_Component because its game class
// or do something to component...
break;
}
}
free(buffer);
return nullptr;
}, eLOOPTYPE_UnTagged
);
}
- This is still working-in-progress.
- Basic struct maybe DIFFERENT between DIFFERENT Unity Engine version.(Change in Classes.h)
- C++ 17 or greater
- Auto-Detect System Class and Game Class for component looping
- More Unity Version Support
- More Methods
- Fetch Method from Module by giving Method's Name
- VRChat[Unity 2019.4]