This is the AMP version of this page.
If you want to load the real page instead, click this text.

Tutorial Finding & Creating instance of any classes and Static fields, methods.

Numark

Awesome Active Platinian
Original poster
May 23, 2017
117
945
193
Hello, I will showing you guys how to get the instance of any classes. This does not require IDA Pro, but unless you want to load your libil2cpp.so or GameAssembly.dll and do it manually from there.

Also, this tutorial works for iOS, Android, & PC.

So what we are going to understand first is, we will go through our UnityEngine functions within dump.cs or loading the UnityEngine.dll inside dnspy after dumping the game.
In this tutorial, we will be going through dump.cs as I am using it most of the time.

First of all, you want to search up is a class called Object within UnityEngine namespace. It is in within UnityEngine.CoreModule.dll, so please remember that.

So what are we doing? Why are we going through the Object class? What is the purpose?


MEANING:
The Object class in UnityEngine is the base class for all objects in Unity. It provides a foundation for many of the key functionalities in the Unity engine.
The Object class is the root class from which all Unity objects derive. It provides essential features and common operations for all Unity objects, such as instantiation, destruction, and comparison.


Basically, we want to find an Object within any class such as Player, Weapons, Photon, Vehicle, etc.
Why is that? Because once we find the Object of the class aka the instance, we can finally access pointers, methods, fields, calling that in any class to Update without having to waste so much time to hard code it. What I'm saying is, you can call your instance in any class.

Now within Object class, we will be using a monoArray method called FindObjectsOfType.

You are probably wondering, what is FindObjectsOfType?
FindObjectsOfType is a method in Unity's Object class that allows you to find all active instances of a particular type in the scene. This can be extremely useful when you need to interact with multiple objects of the same type or need to perform operations on a group of objects at once.

The FindObjectsOfType method is used to search for and return an array of all active objects in the scene that match a specified type. This is helpful when you need to access or modify multiple objects of the same type.

The method can be called with a specific type, and it will return an array containing all instances of that type. For example, you can use it to find all objects of type GameObject, Component, or any custom script you have created.

So in my dump.cs, this is what it would look like:
We will only grab the FindObjectsOfType that only uses the parameter of Type. Don't worry, I will explain later.

We will grab the method and create a function of it.
C++:
monoArray<void**>* FindObjectsOfType(void* Type)
{
    static const auto green_fn = (monoArray<void**>*(*)(void*)) (getAbsolute(0x4389fc0)); //Offset
    return green_fn(Type);
}
NOTE! Please, if you are on Android, or iOS, create your own function pointer. Don't try to copy and just paste this, as you will get errors. There are many tutorials on Platinmods. So find those instead that relates to iOS and Android!

Now, we created a pointer for our FindObjectsOfType. How will we use this? We can't YET, because we need to grab our Type.

WHAT is Type?
In UnityEngine, Type typically refers to the use of the .NET System.Type class, which is used to represent and work with types in a way that allows for reflection. Reflection is the ability to inspect and interact with the metadata of types at runtime. This can be useful in various scenarios, such as dynamically creating instances of objects, invoking methods, or accessing fields and properties.

The System.Type class in .NET provides information about a type, such as its name, its methods, properties, and other members. In Unity, this class is commonly used when you need to work with types dynamically.

We will grab our method GetType inside Type class within mscorlib.dll (UnityEngine):


We will create a function pointer for it.

Code:
void* GetType(monoString* Type)
{
    static const auto fn = (void* (*)(monoString*)) (getAbsolute(0x390b170)); //Offset
    return fn(Type);
}
We will only grab the parameter of String only, everything else is not needed, unless you wanna hardcode everything yourself, goodluck.
Now since we grabbed our two methods, we are ready to set and code.


Go find a class, like Player or Weapon, etc and make your own Hooking code within Update.

For an example, here is mine.

C++:
void(UNITY_CALLING_CONVENTION _Player_Update)(...); //THIS IS FOR PC, create your own hooks for android or ios.
inline void Player_Update(void* obj)
{
    if (obj)
    {
       
    }

    return _Player_Update(obj);
}

Now we created our hook, how will we access other classes? Well, this is the fun part. We are getting there now.
We will create our code for FindObjectsOfType. The FindObjectsOfType will be using our pointer of GetType that we also grabbed and made.
It will look like this:

C++:
void(UNITY_CALLING_CONVENTION _Player_Update)(...); //THIS IS FOR PC, create your own hooks for android or ios.

inline void Player_Update(void* obj)

{

    if (obj)

    {

        monoArray<void**>* objMaterial = FindObjectsOfType(GetType(CreateIl2cppString("WeaponController")));

    }



    return _Player_Update(obj);

}
Please, if the class name says WeaponController, please put it like that and DO NOT MAKE ANY MISTAKES PUTTING SPACE, OR MISSPELLING ELSE IT WILL CRASH!

So, we aren't done yet. We will have to create a loop/list for this.

C++:
void(UNITY_CALLING_CONVENTION _Player_Update)(...); //THIS IS FOR PC, create your own hooks for android or ios.
inline void Player_Update(void* obj)
{
    if (obj)
    {
    // Find all instances of WeaponController
    monoArray<void**>* objMaterial = FindObjectsOfType(GetType(CreateIl2cppString("WeaponController")));

    if (!objMaterial)
    {
        return _Player_Update(obj);
    }

    int length = objMaterial->getLength();
    void** objects = objMaterial->getPointer();

    // Loop through each found WeaponController instance
    for (int j = 0; j < length; j++)
    {
        void* object = objects[j];

        if (object)
        {
            // Perform operations on the object
        }
    }

    return _Player_Update(obj);
}
Why are we looping the code?
The FindObjectsOfType function is used to find all instances of a specific type (WeaponController in this case) in the Unity scene. This returns an array of pointers to those objects.

We are looping and getting the pointer to the current object to perform operations on each instance of the WeaponController type found in the scene. This approach allows us to interact with and manipulate each of these instances individually.

Using pointers allows direct memory access to the objects, which can be necessary for certain operations, especially when working within the IL2CPP environment where managed and unmanaged code interacts.

Now we grabbed the instance it and renamed it as Object shown in the code.

Now since we made our isntance, you can now modify static fields, access fields in general, static methods, etc.

Final code will look like this:

C++:
void(UNITY_CALLING_CONVENTION _Player_Update)(...); //THIS IS FOR PC, create your own hooks for android or ios.
inline void Player_Update(void* obj)
{
    if (obj)
    {
    // Find all instances of WeaponController
    monoArray<void**>* objMaterial = FindObjectsOfType(GetType(CreateIl2cppString("WeaponController")));

    if (!objMaterial)
    {
        return _Player_Update(obj);
    }

    int length = objMaterial->getLength();
    void** objects = objMaterial->getPointer();

    // Loop through each found WeaponController instance
    for (int j = 0; j < length; j++)
    {
        void* object = objects[j];

        if (object) //This will point to the WeaponController
        {
            *(bool*)((uint64_t)object + 0x19c) = true; //isUnlimitedAmmo from WeaponController
        }
    }

    return _Player_Update(obj);
}

ADDITIONAL CODES:


MonoArray code:

C++:
/*
This struct can hold a native C# array. Credits to caoyin.
Think of it like a wrapper for a C array. For example, if you had Player[] players in a dump,
the resulting monoArray definition would be monoArray<void **> *players;
To get the C array, call getPointer.
To get the length, call getLength.
*/
template <typename T>
struct monoArray
{
    void* klass;
    void* monitor;
    void* bounds;
    int   max_length;
    void* vector[1];
    int getLength()
    {
        return max_length;
    }
    T getPointer()
    {
        return (T)vector;
    }
};

MonoString code:

C++:
/*
This struct represents a C# string. Credits to caoyin.
It is pretty straight forward. If you have this in a dump,
public class Player {
    public string username; // 0xC8
}
getting that string would look like this: monoString *username = *(monoString **)((uint64_t)player + 0xc8);
C# strings are UTF-16. This means each character is two bytes instead of one.
To get the length of a monoString, call getLength.
To get a std::string from a monoString, call toCPPString.
To get a C string from a monoString, call toCString.

Had to also adapt the cast for android, as simple as getting the char16 and passing it to a string16,
after that just call the conversion and that's it. TLDR: use getString() and getChars()
*/

typedef struct _monoString
{
    void* klass;
    void* monitor;
    int length;
    char chars[1];

    int getLength()
    {
        return length;
    }

    std::string getChars()
    {
        return std::string(chars, length * 2);
    }
} monoString;

WARNING!
FindObjectsOfType will CAUSE LAGS! BECAUSE it is instantly grabbing ALL OBJECTS AROUND and will slow down performance. The only way to fix this is by using another METHOD or calling it in another class where IT WILL NOT LAG! Calling it in some other classes will help as this did for me. SO be careful.

More tutorials for hooking, creating strings, and function pointers are mostly on Platinmods! So please find them and learn from it before coming here instead of struggling!

Credits to EVERYONE!

Thanks for your time.