Categories > Coding > C++ >
[HELP] printsploit C++
Posted
i have printsploit in C++ bypassing byfron and its source code how can i use it to execute Lua scripts besides print?
Cancel
Post
Replied
I split this guide into 3 parts to avoid the character limit.
Part 1: Finding offsets
First, you need to get the task scheduler, which can be found by searching for the string "FrameTime" in memory. You need to find the reference that calls a function right above and assigns it to the variable, like this.
In this case, sub_102E74FE0 is the function that gets the FrameTime offset from TaskScheduler. Decompile it and you will find something like this.
Near the end, you will see a variable being assigned to a qword, in my case it is qword_1050CAF18. This qword is the task scheduler, so it is the address of it.
Now you need to find some offsets from the TaskScheduler. First is JobsStart and JobsEnd. These can be found from a function that uses a while loop and references the TaskScheduler address. Look around references and you should be able to find it. You should see something like this, however it varies.
The JobsStart offset should be smaller than the JobEnd offset and should be incremented like you see in the for loop. So in my case JobsStart is element 55 and JobsEnd is element 56. These are not the actual offsets, they are an index. Now TaskScheduler could be described as an array of pointers, which is 4 bytes on a 32 bit computer and 8 bytes on a 64 bit computer. Multiply the index by the number of bytes, 8 in my case, and you should get the offset. I have a 64 bit computer and I get 440 for JobsStart and 448 for JobsEnd. Convert these to hex if you want, 0x1b8 and 0x1c0 respectively.
You only need to find one more offset, which is the offset that gets ScriptContext from the job we are going to use. Search for the string "WaitingHybridScriptsJob", it should be referenced once. You will see something similar to this.
Near the end, you can see the offset, which is 536 in my case. However, unlike the previous two offset, here it will be easier if you divide this number by the size of the pointer. It would get me 67, which in hex is 0x47.
Cancel
Post
Added
Part 2: Finding function addresses
You will need getstate for this to work. This can be found by finding a reference to the string "Unable to create a new thread for %s". In that same function where the string is referenced, you should see a string "Script Start", right before it is the function that is getState.
In my case, getState is sub_100A5786A.
To execute scripts, you need luau_load, find it by searching for the string "GameLdr-PerformanceCheck0,GameLdr-PerformanceCheck2". It should be used in a function that gets called in luau_load. Find the function reference and scroll up if using IDA, since it would not be initialized as a sub and would be a location. The first location you see while scrolling up is luau_load which is loc_1028459A7 in my case.
You will also need to get the spawn address. Search for the string "Spawn function requires 1 argument". The function it is referenced in the spawn function.
sub_1009EAFCE is the spawn function in my case.
To push things off the Luau stack, you need lua_settop. You can try to find it yourself by looking at the Luau source, but if you can't, I will help you.
That is basically it for the functions, however you can get some Luau C functions to confirm if the Lua state you have is correct. That is not necessarily needed, so I will not find them in this guide.
Cancel
Post
Added
Part 3: Making the exploit
In your exploit source, you have to use the offsets. I recommend giving the offsets a variable name so that you can change them easily once an update happens. Ensure you import all the necessary header files. Make sure to replace the function addresses and offsets.
const int jobs_start = 0x1b8;
const int jobs_end = 0x1c0;
const int jobs_offset = 0x10;
uint64_t taskscheduler_address = 0x1050CAF18 + GetModuleHandleA(0);
typedef uint64_t (*getstate_typedef)(uint64_t script_context, int* type, const int64_t* argument);
uint64_t getstate_address = 0x100A5786A + GetModuleHandleA(0);
getstate_typedef rbx_getstate = reinterpret_cast<getstate_typedef>(getstate_address);
typedef int64_t (*load_typedef)(uint64_t state, const char* source, const char* bytecode, int len, int env);
uint64_t load_address = 0x1028459A7 + GetModuleHandleA(0);
load_typedef rbx_load = reinterpret_cast<load_typedef>(load_address);
typedef int64_t (*spawn_typedef)(uint64_t state);
uint64_t spawn_address = 0x1009EAFCE + GetModuleHandleA(0);
spawn_typedef rbx_spawn = reinterpret_cast<spawn_typedef>(spawn_address);
typedef int64_t (*settop_typedef)(uint64_t state, int size);
uint64_t settop_address = 0x10282448B + GetModuleHandleA(0);
settop_typedef rbx_settop = reinterpret_cast<settop_typedef>(settop_address);
jobs_offset should be 0x10 and is mandatory.
I am not sure how finding the address of a function or object is done on Windows, I think it is GetModuleHandleA(0), you know since your print function works.
Define a structure for the TaskScheduler.
namespace scheduler {
struct job {
void** vtable;
char padding[0x88]; //0x10
std::string job_name; // 0x18
};
std::vector<job*> scheduler_jobs;
}
The next few steps will be complicated so I will describe them first.
- Define a function called getGlobalState or similar to get the Lua state and use the offsets.
2. Make a while loop in the function to iterate through jobs.
3. Check if the job name matches and that we do not have a Lua state yet.
4. Find ScriptContext and get the Lua state.
5. Return the Lua state.
This is the getGlobalState function.
uint64_t getRobloxState() {
// Define a function called getGlobalState or similar to get the Lua state and use the offsets.
uint64_t state = 0;
uint64_t scheduler = *(uint64_t*)taskscheduler_address;
uint64_t start = *(uint64_t*)(scheduler + jobs_start);
uint64_t end = *(uint64_t*)(scheduler + jobs_end);
// Make a while loop in the function to iterate through jobs.
while (start < end) {
auto job = *(scheduler::job**)start;
scheduler::scheduler_jobs.push_back(job);
// Check if the job name matches and that we do not have a state yet.
if (job->job_name == "WaitingHybridScriptsJob" && state == 0) {
// Find ScriptContext and get the Lua state.
int thread_type = 0;
const int64_t trigger = 0;
void** job_address = (void**)job;
uint64_t script_context = (uint64_t)job_address[script_context];
uint64_t rbx_state = rbx_getstate(script_context, &thread_type, &trigger);
// Return the Lua state.
return rbx_state;
}
start += offsets::jobs_offset;
}
return 0;
}
Next, create a function that executes Luau scripts. Download the Luau source from GitHub, initialize the header files and library files in your project. I will not go into this, if you need help ask me.
I will outline the function below.
- Define a function called execute_script or similar to execute Luau scripts.
2. Compile the script to Luau bytecode.
3. Load the bytecode and check if it is successful.
4. If loading is unsuccessful, push the function off the stack.
5. If loading is successful, call spawn to execute the function pushed to the stack, and push the function off the stack.
// Define a function called execute_script or similar to execute Luau scripts.
bool execute_script(uint64_t state, std::string script) {
// Compile the script to Luau bytecode.
std::string script_bytecode = Luau::compile(script);
// Load the bytecode and check if it is successful.
if (rbx_load(state, script_author.c_str(), script_bytecode.c_str(), script_bytecode.size(), 0) != 0) {
// If loading is unsuccessful, push the function off the stack.
rbx_settop(state, 0);
return false;
}
// If loading is successful, call spawn to execute the function pushed to the stack, and push the function off the stack.
rbx_spawn(rl);
rbx_settop(rl, 0);
return true;
}
Do this in your main function.
// Get the Lua state
uint64_t roblox_thread = getRobloxState();
// Execute a script
std::string teststring = R"(print("hi"))";
execute_script(roblox_thread, teststring);
The teststring variable has to be a raw string.
Reply to this thread if you have questions.
Cancel
Post
Replied
Do you have a discord? I want to message you because I need help with this. My IDA is not doing the same things yours is. At least not showing what yours shows
Cancel
Post
Replied
Same for me though i use roblox studio since i don't know how to exploit on roblox yet since byfron.
Cancel
Post
Replied
If you have any questions, message me on Discord, user is "cherpixel" without the quotes. I will help you dump Roblox and get anything you need.
You can also DM me if you want help setting the identity.
Cancel
Post
Users viewing this thread:
( Members: 0, Guests: 2, Total: 2 )
Comments
RoBloxedHacked 0 Reputation
Commented
What level would this be executing code at?
0
Cherpixel 1 Reputation
Commented
It doesn't change the identity so it would be at 0.
0
Deux 0 Reputation
Commented
how can I improve it?
0
HexDX_nbVKCH 0 Reputation
Commented
I have 2 question how do you dump roblox and also the address finding methods above do they work? Like on roblox i mean because on roblox studio they don't.
0
Deux 0 Reputation
Commented
make a dump using IDA
0