Help! FRIDA: Call to func pointer fails

bkR57

Platinian
Original poster
Jan 21, 2024
16
3
3
34
Hello,

i'm using frida to test a call to a function located in a class that is not "normaly used" by the game (i think is used by developer for testing purpose).

The class is like so:

C#:
public class ConsoleCommand // TypeDefIndex: 1447
{
    // Fields
    private static bool _enableFPS; // 0x0
    private static GameObject _fpsObj; // 0x8

    // Methods
    // RVA: 0x14FDEEE Offset: 0x14FDEEE VA: 0x14FDEEE
    public static void RegisterCommandHandlers() { }

    [CommandHandler]
    // RVA: 0x1500764 Offset: 0x1500764 VA: 0x1500764
    public static void EnableInvincibility() { }
   
    [CommandHandler]
    // RVA: 0x14FE37F Offset: 0x14FE37F VA: 0x14FE37F
    public static void KillMonster() { }

    [CommandHandler]
    // RVA: 0x14FEDD0 Offset: 0x14FEDD0 VA: 0x14FEDD0
    public static void Gold(long amount = 1) { }
}
i am able to create a pointer to "EnableInvincibility()" and call it successfully and its works, same for "KillMonster()", however, i got an "access violation accessing 0x10" exception when calling Gold(amount).

It happens basically for all function that require a parameter. Basically this error means program try to access a memory address "0x10" which is obviously a wrong address. To try to fix this, i allocated memory, write the (long)amount value inside it, and give that pointer to the function as param, but result is the same.

The 'Gold(long amount) function in IDA looks like so:
Capture.PNG

Do you guys have some hints ?

Thanks a lot
 
Last edited:

bkR57

Platinian
Original poster
Jan 21, 2024
16
3
3
34
Hi mlsmanXP,

I edited my post to add IDA decompiled view of the function.

I call it after creating a native pointer like so:
JavaScript:
function CallFuncArgs(Offset, ReturnType, ArgsType, myargs){
    var func_ptr = Module.findBaseAddress('libil2cpp.so').add(Offset);
    new NativePointer(func_ptr.sign());
    var func_call = new NativeFunction(func_ptr, ReturnType, ArgsType);

    func_call(myargs);
} 

CallFuncArgs(0x14FEDD0, 'void', ['long'], 9999999); //gold

// i tried also passing pointer to the amount like so:
const arg = Memory.alloc(8); //alloc of 8 size(long)
arg.writeInt(9999999);
CallFuncArgs(0x14FEDD0, 'void', ['pointer'], arg); //gold
In both case, i have "Error: access violation accessing 0x10" error.

I know the CallFuncArgs() to create the pointer is functionnal, as i am able to successfully call EnableInvincibility() with it

Thanks for your help
 

mIsmanXP

Approved Modder
Approved Modder
Feb 20, 2022
205
9,860
193
Republic of Indonesia
I don't know about frida but c# function doesn't accept a pointer for primitive types
So maybe just pass the value directly

*Edit looks like you already did that, sorry
 

bkR57

Platinian
Original poster
Jan 21, 2024
16
3
3
34
its sevenknightidle (netmarble)

Wondering if the access violation 0x10 error is not related to the IDA instruction:
STP X19, X30, [SP,#0x10]

if i understand well, it tries to store the value of X19 inside X30 located on the SP+0x10, but it would mean that SP is null, weird
 

Backshift

Solid & Active Platinian
Oct 10, 2023
56
38
18
32
I don't know much about arm assembly but i believe those instructions are just for setting up the stack
Yeah this, the prologue will setup the stack and registers at the beginning and the epilogue at the end of the function will reverse what the prologue did before returning control to the calling function.

@bkR57 If you right click in Pseudo Code do Synchronize with -> IDA View you will see the currently selected line in green, in this example you can see the green ASM view is the 3rd instruction yet the Pseudo code is the first line.
1709474118956.png
 

bkR57

Platinian
Original poster
Jan 21, 2024
16
3
3
34
Thanks,

So yeah it means that those 2 STP instuctions are not related to the "amount" args given to the function. So my "access violation accessing 0x10" error come from somewhere else.
If the function wanted a structure and not a LONG (which could explain that error) i think it would be written in the dump.
So in fact i don't have any idea on how to resolve this, maybe linked to the RegisterCommandHandlers() func ? at least i don't know what it is used for
 

Backshift

Solid & Active Platinian
Oct 10, 2023
56
38
18
32
Yeah, when I have seen that error it usually is because a valid pointer is expected but the parameter is NULL/0, the function then tries to do param + 0x10 and gets an access violiation because accessing 0x10 is wrong, this gold param is supposedly a standard long so it doesnt add up.
 

bkR57

Platinian
Original poster
Jan 21, 2024
16
3
3
34
For your information, i have investigate a bit, and it seems that the "long" param is in fact a pointer to the structure below:

C#:
public class ReqAdminCommand : IMessage // TypeDefIndex: 871
{
    // Fields
    public eAdminCommandType Type; // 0x10
    public long Variable1; // 0x18
    public long Variable2; // 0x20
    public long Variable3; // 0x28
    public long Variable4; // 0x30
    public long Variable5; // 0x38

    // Methods

    // RVA: 0x18CCB5B Offset: 0x18CCB5B VA: 0x18CCB5B Slot: 4
    public void Load(IBinaryReader reader) { }

    // RVA: 0x18CCDFB Offset: 0x18CCDFB VA: 0x18CCDFB Slot: 5
    public void Save(IBinaryWriter writer) { }

    // RVA: 0x18CD0A6 Offset: 0x18CD0A6 VA: 0x18CD0A6
    public void .ctor() { }
}


// With eAdminCommandType enum below:
public enum eAdminCommandType // TypeDefIndex: 1379
{
    // Fields
    public int value__; // 0x0
    public const eAdminCommandType None = 0;
    public const eAdminCommandType IncreaseGold = 1;
    public const eAdminCommandType IncreaseExp = 2;
    public const eAdminCommandType AllHeroes = 3;
    public const eAdminCommandType UpdateQuest = 4;
    public const eAdminCommandType AddItem = 5;
    [...]
}

More over, i think this is called within the Network.Client class with the method below:

C#:
// RVA: 0x19265A5 Offset: 0x19265A5 VA: 0x19265A5
    public void ReqAdminCommand(eAdminCommandType type, long[] argList) { }

It means the admin command is sent to server side, i could allocate memory to pass it the eAdminCommandType value i want to use, but the content of other field of the structure is completely unkown and no way to intercept a valid request from the method i want to then modify the value.

This is too much work for me, for no guaranty of success :face26:

Maybe better chance by setting up a local proxy and intercept the https request to edit it?