Back to offsetsdecamp.dev / tutorials

IDA reference

offset tutorials

Find each address yourself and verify where it comes from. Finished RVAs are left out because they change between Roblox builds.

Pointer tutorial

DataModel, PlayerConfigurer, TaskScheduler, VisualEngine

RTTI works for DataModel, PlayerConfigurer, and VisualEngine. TaskScheduler is easier to find from one of its own strings. This is not a method for every pointer in Roblox.

RTTI route

  1. Press Shift + F12 and search for the class you want:
    .?AVDataModel@RBX@@
    .?AVPlayerConfigurer@RBX@@
    .?AVVisualEngine@RBX@@
  2. Open the result and scroll to its TypeDescriptor. Put the cursor on it, press X, and open the first data reference.
  3. On the RTTI Complete Object Locator, pressX again. The qword below the locator pointer starts the class vtable.
    RTTI locator pointer
    class_vtable:
        function_1
        function_2
        function_3
  4. Press X on the vtable, open a code reference, and pressF5. The constructor writes the vtable to the start of the object.
    lea  rax, class_vtable
    mov  [object], rax
  5. Follow the constructor references until the new object is saved in a global qword.
    object = operator_new(object_size);
    Class_constructor(object);
    qword_xxxxx = object;

TaskScheduler route

  1. Open Strings and search for this scheduler error:
    Out of arbiter nodes: Increase the FInt::TaskSchedulerMaxNumOfArbiters value
  2. Open its code reference and press F5. Look for a global qword loaded by the surrounding scheduler code.
    scheduler = qword_xxxxx;
    if (scheduler)
        scheduler->run_or_create_jobs(...);
  3. Press X on the qword. Its other references should lead to scheduler jobs and TaskScheduler functions.

Calculate the RVA

pointer RVA = qword address - image base

Use the qword's address, not the heap address stored inside it. DataModel can have more than one candidate, so check candidates while Roblox is running.

FFlag tutorial

Find any FFlag

This example uses AdornRenderStats. The same steps work for other registered flags.

  1. Press Shift + F12 and search forAdornRenderStats without an FFlag prefix.
  2. Press X on the string, open its code reference, and pressF5.
    __int64 sub_xxxxx()
    {
        return register_flag(
            "AdornRenderStats",
            &xmmword_7994610,
            1
        );
    }
  3. The global beside the flag name is its storage address. Remove thexmmword_ prefix and add the hexadecimal prefix.
    7994610  ->  0x7994610
  4. The result matches the runtime dumper entry:
    inline constexpr std::uintptr_t Flag_AdornRenderStats = 0x7994610;

This IDB uses an image base of zero, so 0x7994610 is already an RVA. If your IDB has a nonzero image base, subtract it from the global address first.