Tutorial How to modify Set Methods in Unity's il2cpp

Numark

Awesome Active Platinian
Hey guys, it's SliceCast. So people have been asking, "how do you modify a set method instead of using get?". It's simple, since I'm a nice person, I don't mind sharing this information for you newbies or advanced modders. Let's get started.

Wait, before we actually start anything...

You need to read this tutorial first BEFORE WE START! If you already know how to hook, then skip onto the set tutorial.

So get your set method, we're gonna make our set method a function pointer. We will be splitting this function pointer because when your lib is loaded sometimes, the libil2cpp isnt loaded already, but your lib doesn't know that and already tries to read the address which will result in a null pointer or crash. So here's how this will work.

C++:
void (*set_kills)(void *_instance, int AmountOfKills);

Now what were gonna do is use "set_kills" and paste it in our class hook which is get_ that we have made. All you need to do now is do "set_kills(instance, 999999);" without the parenthesis. It's really simple to do.

C++:
//the void *instance is a self-created variable.
int (*old_get_Kills)(void *instance);
int get_Kills(void *instance) {
    //Check if instance is NULL to prevent CRASH
    if (instance != NULL)
    {
        set_kills(instance, 999999); //Function Pointer mod
    }
    //return the original value (this code isn't really needed if you have a toggle/switch)
    return old_get_Kills(instance);
}

If this crashes, then you need to log the crashes and find out why.

It's pretty easy and simple. Last thing we need to do now is call the function pointer just like calling your MSHooks to make your mods work.

C++:
set_kills = (void (*)(void *, int))getRealOffset(OFFSET);



Also make sure to call your hooks (I forgot)
Note: HOOK_LIB is from LGL's mod menu template.
C++:
HOOK_LIB("libil2cpp.so", "0x00000", get_kills, old_get_kills);


Credits to SliceCast & Octowolve.
Discord: Slicey#5894
 
Last edited:
Oh yeah my mistake, you need to call it with MSHook, I was busy and rushed
so let's say I have a method called get_ammo and it has a set_ammo too, so If I wanted to modify set_ammo then I would hook get_ammo and create a function pointer for set_ammo right?
 
1 question tho, what if my function don't have any additional parameter?

C++:
public double DamageMultiplier
        {
            [Token(Token = "0x6002140")]
            [Address(RVA = "0x4D0E14", Offset = "0x4D0E14", VA = "0x4D0E14")]
            get
            {
                return 0.0;
            }
            [Token(Token = "0x6002141")]
            [Address(RVA = "0x4D0E20", Offset = "0x4D0E20", VA = "0x4D0E20")]
            set
Should I make it like this?

C++:
double (*set_DamageMultiplier)(void *instance);


double (*old_get_DamageMultiplier)(void *instance);
double get_DamageMultiplier(void *instance) {
    if(instance != NULL && getdmg) {
        set_DamageMultiplier; 99999;
    }
    return old_get_DamageMultiplier(instance);
}
you're just at the function, not the setter, go to the set part of that function, it could be something like set_FunctionName or setFunctionName, but yeah for that function there is a getter and setter, just find the setter
 
ouh I got it.

For general, what should I do if the function don't have additional parameter?
then just return the value you want (if it isn't a void) but if it is a void and has no parameters (highly unlikely) then just hook the getter (get) and modify it to return whatever you want
 
I have question, Let's say I've "Update" function and a "isKilled" function but it dont have additional parameters and it accept bool as return. So I create a hook for both Update and isKilled. Then create a function pointer for isKilled inside Update.
Will this work? or is there any other way to use function pointer that has no additional parameters?
you could just set a function pointer on isKilled and hook update.
Then just use iskilled inside update.
C++:
bool (*isKilled)(void*instance) = (bool (*)(void*))ScanAddress(...);

void (*old_Update)(void *instance);
void Update(void *instance)
{
    if (instance != NULL) //checks if instance is null
    {
        if (isKilled(instance))
        {
            //here do big hacking..
        }
    }
    old_Update(instance); //run old function.
}
 
you could just set a function pointer on isKilled and hook update.
Then just use iskilled inside update.
C++:
bool (*isKilled)(void*instance) = (bool (*)(void*))ScanAddress(...);

void (*old_Update)(void *instance);
void Update(void *instance)
{
    if (instance != NULL) //checks if instance is null
    {
        if (isKilled(instance))
        {
            //here do big hacking..
        }
    }
    old_Update(instance); //run old function.
}



Just a quick question if you're free to answer it, what if a void has a return default boolean parameter, is there a way to hook it using the update function or do i need to just hook the void's paramater insted? This is the example:




public void SetSPOILERState(bool LLSPOILER = False) { }
 
Bruh i already know Cpp its just that i never used it for modding...


Also i was just confusing that function with another so it was very easy to hook.
 
I have a void ApplyDamage(float damage, .... ,.. ) function, but I don't really know how to Hook it, the base tutorial isn't really showing what to do in the beginning
 
Please help. I did everything according to the tutorial, but all to no avail. Can you suggest what I did wrong?

This is from dnspy
C++:
[Token(Token = "0x17000015")]
public bool IsWin
{
    [Token(Token = "0x60000F2")]
    [Address(RVA = "0x4DB7F0", Offset = "0x4DB7F0", VA = "0x4DB7F0")]
    [Attribute(Name = "CompilerGeneratedAttribute", RVA = "0x2764E4", Offset = "0x2764E4")]
    get
    {
        return default(bool);
    }
    [Token(Token = "0x60000F3")]
    [Address(RVA = "0x4DB7F8", Offset = "0x4DB7F8", VA = "0x4DB7F8")]
    [Attribute(Name = "CompilerGeneratedAttribute", RVA = "0x2764F4", Offset = "0x2764F4")]
    set
    {
    }
}

this is hook
C++:
void (*set_IsWin)(void *instance, bool value);

//the void *instance is a self-created variable.
bool (*old_get_IsWin)(void *instance);
bool get_IsWin(void *instance) {
    //Check if instance is NULL to prevent CRASH
    if (instance != NULL && WinOK)
    {
        set_IsWin(instance, true); //Function Pointer mod
    }
    //return the original value (this code isn't really needed if you have a toggle/switch)
    return old_get_IsWin(instance);
}

and this call
C++:
set_IsWin = (void (*)(void *, bool))getAbsoluteAddress(targetLibName,0x4DB7F8);
    HOOK_LIB("libil2cpp.so", "0x4DB7F0", get_IsWin, old_get_IsWin);
 
Please help. I did everything according to the tutorial, but all to no avail. Can you suggest what I did wrong?

This is from dnspy
C++:
[Token(Token = "0x17000015")]
public bool IsWin
{
    [Token(Token = "0x60000F2")]
    [Address(RVA = "0x4DB7F0", Offset = "0x4DB7F0", VA = "0x4DB7F0")]
    [Attribute(Name = "CompilerGeneratedAttribute", RVA = "0x2764E4", Offset = "0x2764E4")]
    get
    {
        return default(bool);
    }
    [Token(Token = "0x60000F3")]
    [Address(RVA = "0x4DB7F8", Offset = "0x4DB7F8", VA = "0x4DB7F8")]
    [Attribute(Name = "CompilerGeneratedAttribute", RVA = "0x2764F4", Offset = "0x2764F4")]
    set
    {
    }
}

this is hook
C++:
void (*set_IsWin)(void *instance, bool value);

//the void *instance is a self-created variable.
bool (*old_get_IsWin)(void *instance);
bool get_IsWin(void *instance) {
    //Check if instance is NULL to prevent CRASH
    if (instance != NULL && WinOK)
    {
        set_IsWin(instance, true); //Function Pointer mod
    }
    //return the original value (this code isn't really needed if you have a toggle/switch)
    return old_get_IsWin(instance);
}

and this call
C++:
set_IsWin = (void (*)(void *, bool))getAbsoluteAddress(targetLibName,0x4DB7F8);
    HOOK_LIB("libil2cpp.so", "0x4DB7F0", get_IsWin, old_get_IsWin);


try using only the set method
 
Back
Top Bottom