Closed ImAxel0 closed 1 year ago
Take a look at this it's a similar issue -> https://github.com/sneakyevil/IL2CPP_Resolver/issues/21#issuecomment-1259945858
you have misunderstanding how it works.
you first find the gameobject, and then get the method "Sons.Characters.CharacterManager.DebugAddCharacter", i assume the class "Sons.Characters.CharacterManager" is a component that attched to "CharacterManager", so you need use it as like @BrownBison mentioned https://github.com/sneakyevil/IL2CPP_Resolver/issues/21#issuecomment-1259945858
also i highly recommended anyone before trying to hack unity game to get unity editor, and make some simple logic scripts in unity first, you will understanding how gameobject/component works
Thanks for the quick response. From what I understood and seeing #21 I tried like this:
Globals::CharacterManager = Unity::GameObject::Find("CharacterManager");
Globals::CharacterManager_component = Globals::CharacterManager->GetComponent("Sons.Characters.CharacterManager");
Globals::Methods::DebugAddCharacter = IL2CPP::Class::Utils::GetMethodPointer("Sons.Characters.CharacterManager", "DebugAddCharacter");
Both the component and the method are found but I get the same result calling it using Globals::CharacterManager_component
. Am I using the wrong GameObject/Component, wrong method pointer or passing wrong argument types (the System_string most likely) ?
u still didnt understand...
Globals::CharacterManager_component.CallMethod("DebugAddCharacter", IL2CPP::String::New("cannibal"), true);
u still didnt understand...
Globals::CharacterManager_component.CallMethod("DebugAddCharacter", IL2CPP::String::New("cannibal"), true);
Tried like that:
Globals::CharacterManager_component->CallMethod<bool, Unity::System_String*, bool>("DebugAddCharacter", IL2CPP::String::New("cannibal"), true);
Still gives access violation. Don't know if that matters but from UnityExplorer I see the "CharacterManager" gameobject is a child of the "GameManagers" gameobject: https://i.imgur.com/74LDw0F.png
Globals::CharacterManager = Unity::GameObject::Find("GameManager/CharacterManager");
Globals::CharacterManager_component = Globals::CharacterManager->GetComponent("CharacterManager");
Globals::CharacterManager_component->CallMethod("DebugAddCharacter", IL2CPP::String::New("cannibal"), true);
if still doesnt work, i will check the game later
Still got the same. This doesn't just happen with functions which have System_string as an argument but even only an int etc.
i got no problem with that code, your crash probably calling function outside of game thread or something. https://imgur.com/a/nZgJOGv
inside of hooked update, i choosed DamageDebugManager::Update
if (config::sometest)
{
Unity::CGameObject* characterManager = Unity::GameObject::Find("CharacterManager");
Logger::AddLog("CharacterManager Object: %p", characterManager);
if (characterManager)
{
Unity::CComponent* component = characterManager->GetComponent("CharacterManager");
Logger::AddLog("CharacterManager.Component: %p", characterManager);
if (component)
{
bool result = component->CallMethod<bool>("DebugAddCharacter", IL2CPP::String::New("cannibal"), true);
Logger::AddLog("CharacterManager.Component.DebugAddCharacter.result : %d", result);
}
}
config::sometest = false;
}
Thank you very much! It was all because I didn't called it like this:
IL2CPP::Callback::Initialize();
IL2CPP::Callback::OnUpdate::Add(OurUpdateFunction);
void OurUpdateFunction()
{
if (!Config::sometest)
{
Globals::CharacterManager_component->CallMethod<bool>("DebugAddCharacter", IL2CPP::String::New("cannibal"), true);
printf("called\n");
Config::sometest = true;
}
}
Basically I need to call the method one time inside the OurUpdateFunction()
and than I can call it everywhere like this:
if (ImGui::SmallButton("Spawn cannibal"))
{
Globals::CharacterManager_component->CallMethod<bool>("DebugAddCharacter", IL2CPP::String::New("cannibal"), true);
}
Would you mind briefly explaining what IL2CPP::Callback::OnUpdate::Add(OurUpdateFunction)
does and why the method needed to be called one time inside this function before calling it outside of it? Just curious and want to understand
Edit: seems like It doesn't always work, still crashes sometimes when calling with the imgui small button, will figure it out myself. Anyway thanks for all your help!
Edit: seems like It doesn't always work, still crashes sometimes when calling with the imgui small button, will figure it out myself. Anyway thanks for all your help!
you cant use it like that, in my code example, in menu , i did something like:
if (ImGui::Button1("Test"))
{
config::sometest = true;
}
Would you mind briefly explaining what IL2CPP::Callback::OnUpdate::Add(OurUpdateFunction) does and why the method needed to be called one time inside this function before calling it outside of it? Just curious and want to understand
Update() is called each frame, unity has like
while(true)
{
for(int i = 0; i < updatefunctions.size; i++)
{
if(updatefunctions[i].available)
{
updatefunctions[i].func(); // call it
}
}
}
its pseudocode but it works like that. also every unity thread is inside unity thread list, because GC(garbage collector) needs it ,also for exception handler, and etc... remember unity is c#? it becomes native code on compile because thats it, il2cpp(IL code to C++). still highly recommend to you to try unity editor, also try thinking how the game was developed
IL2CPP::Callback::OnUpdate::Add(OurUpdateFunction) is the function hooks root update(all update called from there), so you dont need find a suitable update like i did :
inside of hooked update, i choosed DamageDebugManager::Update
this issue is good for anyone who is new on hacking il2cpp games for reference
Yes that's what I have figured out my self, used this:
if (ImGui::Button("Spawn Cannibal", ImVec2(ImGui::GetContentRegionAvail().x, NULL)))
{
Config::MethodToggleCall::Value::DebugAddCharacter::character = "cannibal";
Config::MethodToggleCall::DebugAddDefinedCharacter = true;
}
to toggle call the methods inside the OurUpdateFunction()
Thank you for the explanation and all!
Working on a mod menu for Sons of the Forest, calling some of the game methods it's fine, but others always gives access violation. I'm pretty sure it's all setup correctly and there isn't any nullpointer at the moment of calling.
The method has a return of type bool and takes two parameters (string, bool). I tried to call it in these different ways:
Both GameObject and method pointer have valid values at the moment of calling, stepping through assembly the exception always occur when a nullptr is dereferenced, like
lea register, qword ptr [rax]
and rax register is 0 so the access violation occur. Passing nullptr as the string parameter doesn't make the game to crash.I can't understand why it happens since calling the method using UnityExplorer works fine and the same is for other C# codes I've seen online with the same methods on the same game.
I don't want to ask for help/fix since it could be game related, but if anyone has more knowledge than me any suggestion is highly appreciated.
If this is off-topic close the issue without any doubt and sorry for bothering.