Tutorial How to obtain Roblox addresses for your Lua executor (ROBLOX)

NotALegitGuy

Solid & Active Platinian
Original poster
Sep 24, 2018
69
67
18
Costa Rica
Hey there my friends of PlatinMods, i am nop
You should at least have used IDA Pro and modded native games before so you know what I mean as i will be skipping some stuff to not make this thread too large.
I am learning to make roblox exploits for Android with just C++ and honestly, the lack of resources is a hell of a pain to bear with.

So since no one has yet made a tutorial on how to open Roblox on IDA Pro and obtain the addresses i decided to make this to help any new modders trying to make a Roblox executor for Android.

I only cover the basic addresses that are mostly needed to get basic execution, i will add more later when I feel like it.

If there's anything wrong with it such as my explanations being bad, please say below in the replies and I'll try my best to fix it.

Shown ones are: currentidentity, getglobalstate, gettop, spawn, pushcclosure, setreadonly, settop, pushstring, setfield, getfield, pcall, sandboxthread, ScriptContextHook, newthread, deserialize, index2adr

Planning to add:

Updated: Fixed explanations, added new addresses

• currentidentity

To get currentidentity just search "Current identity is %d" or "printidentity()" in the strings window and click it, if you clicked printidentity, you need to click the sub below it to access the function.
Decompile it, then scroll up a bit around where the variables are set on line 15 and up.

You will find a sub that looks like this: sub_xxxxxx();

Just click it, and then you will see it's pseudocode.
It will return a sub_xxxxxx, that returned sub_xxxxx is the currentidentity address.

Sometimes it is returned sometimes it isn't.

You know when it isn't returned if you get a heck ton of pseudocode instead of a return.

• getglobalstate

To get getglobalstate just search "Cannot require a non-robloxscript module from a Roblox script"
Then decompile it with F5 Obviously and scroll up until you see variables again, around line 36 you'll find 3 variables with 3 functions/sub_xxxx.
One of them will be like this ((int (*)(void))sub_xxxx)().
Go up 2 lines after that one and you'll find getglobalstate.
Here's an example

C-like:
v4 = sub_xxxxxx(a1); //<== This is getglobalstate

v5 = sub_xxxxxx(*v3, v4);

v6 = ((int (*)(void))sub_xxxxxx)();
• gettop
To get gettop just search "Spawn function requires 1 argument"
Decompile it and you should find an if statement above the string, and inside the parameters something like

C-like:
sub_xxxxx(v1) <= 0
just double click the sub_xxxxxx and you'll find a return. It will be returning a function like this

C-like:
return sub_xxxxxx(a1)
That sub being returned is gettop function!

You can also get the Offsets of top and base inside the gettop function, just double click it and you'll see it returning a Lua State, just look inside the Lua State and you will see 3 numbers, in my case they are 12, 32 and 4.

Top is 12 and Base is 32, the 4 isn't used.

• spawn
Just search "Spawn function requires 1 argument" like in gettop

Then scroll up all the way to the top in line 1. You will see something like this

C-like:
int __fastcall sub_xxxxxx(int a1)
The spawn address is that sub after fastcall.

• pushcclosure

just search "__index" and decompile it, then below it will be something like sub_xxxxxx just double click it and the sub it returns is pushcclosure

• setreadonly

again, search "__index" and decompile it, scroll to the bottom and you'll find sub_xxxxx immediately after a bracket.

It should have the following parameters sub_xxxxxx(v7, -1, 1);

Just double click that sub, and then the other sub it returns is setreadonly

• settop

search "__index" and decompile it, scroll to the bottom and just below setreadonly you will find it. It should look like this

C-like:
result = sub_xxxxxx(v7, -2);
Just click that sub and the sub it returns is settop.

• getfield

Search isdst, CTRL + X and click the second XREF

search for something like this

C-like:
sub_xxxxxx(a1, -2, "month");
That sub is getfield, just in case match it with the others like year, day or etc.

There's 2 getfield offsets but that's one of them.

• setfield

Search isdst, CTRL + X and click the first XREF, then you will see something simpler than getfield.

Just search for something like this

C-like:
sub_xxxxxx(a1, -2, "yday");
That sub is setfield, just in case match it with the others like month, year, day or etc.

• pushstring

Search "__index", click the first result, decompile it.
You will see this

C-like:
sub_xxxxx(v6, "__index"); //<= this sub is pushstring

sub_xxxxx(a bunch of args here); //<= this sub is pushcclosure.

sub_xxxxx(v7,  -3);
Just click the sub that is marked on the code i just put above and then you will see within its pseudocode that it is returning another sub, that returned sub is pushstring, or pushcclosure if you decided to get that too.

• pcall

Search "syntax error: %s", CTRL + X and click the 2nd XREF and decompile, then around Line 73 you should see something like this

C-like:
v17 = sub_xxxxx(*(_DWORD *)(v9 + 4), 0, 1, 0);
That sub is pcall.

• sandboxthread

Search "unable to create a new thread for %s", decompile it.

Go down some lines and after the while loop below unable to create a new thread for %s string, is sandboxthread.

It should look like this

C-like:
sub_xxxxxx(v45, &v157, &v152);
It might of course change, but that's sandboxthread.

• ScriptContextHook

Search "unable to create a new thread for %s", decompile it

Go to line 1, and you will see something like this:

C-like:
int __fastcall sub_xxxxxxx(int a1, unsigned __int64 *a2, unsigned int *a3, int a4);
That sub after fastcall is ScriptContextHook

• newthread

search "Spawn function requires 1 argument"
Decompile it and below the string is newthread

It should look like this

C-like:
v4 = sub_xxxxxx(v1);
just double click that sub and it will return another sub

That returned sub is newthread

• deserialize

Search "s: bytecode version mismatch (expected %d, got %d)"

Decompile it as always, then go to line 1 at the top, and you will find something like this:


C-like:
signed int __fastcall sub_xxxxxx(int a1, const char *a2, __BYTE a3, int a4, int a5)
That sub after the fastcall is deserialize.

• index2adr

just search "s: bytecode version mismatch (expected %d, got %d)"

Decompile it, then scroll down a bit and you should see something like this:

C-like:
if ( a5 )
   v11 = (int *)sub_xxxxxxx(v5, a5); // <= this sub is index2adr
else
   v11 = (int *)(v5 + 64);
Look closely and you will see a comment that says which one is index2adr.

NOTE: Sometimes if the string is at the bottom of the function, you need to scroll up and search for that piece of code i posted up there.
 
Last edited by a moderator: