Categories > Exploiting > Roblox >
task::defer crashing
Posted
I've been trying to get execution on the client for a while now but can't seem to call my closure without roblox crashing. Right now I'm doing
std::string compile(std::string source) {
Luau::CompileOptions options{};
options.coverageLevel = 0;
options.debugLevel = 1;
options.optimizationLevel = 1;
std::string bytecode = Luau::compile(source, options, {}, &encoder);
std::string compressed = compress(bytecode);
return compressed;
}
void execute(uint64_t lua_state, std::string bytecode) {
std::string name = "=ffff";
functions::luavm_load(lua_state, name.c_str(), bytecode.c_str(), bytecode.size());
functions::defer(lua_state);
}
int main() {
uint64_t lua_state = GetLuaState();
std::string source = "print(true)"; // I've also tried passing raw strings
std::string bytecode = compile(source);
execute(lua_state, bytecode);
return 0;
}
Roblox crashes after calling task::defer, and when I use spawn it just gives me "attempted to call a string value."
Cancel
Post
Replied
If I recall correctly, Roblox encodes the instruction opcodes differently but it's pretty easy to work around with an overload. I don't quite recall what you had to do...Found out what I had previously. Not sure if the encoding is right anymore, but you did have to modify how the bytecode was encoded to get anything to execute on Roblox. Provided pseudocode might need some changes.
Edit: Took a look at Luau. EncodeOp isn't a thing anymore!
Old encode call:
https://i.imgur.com/n8iiSIu.png
New encode call:
https://i.imgur.com/UFbpCRy.png
In the source, 'encodeOp' is replaced with 'encode', which has a different function signature. Looks like it'd be pretty easy to make a function that would fit the specifications by reimplementing that logic. This could be a decision made to prevent unskilled people from making exploits. This is what I had which used an old Luau build:
struct rbx_encoder : Luau::BytecodeEncoder {
std::uint8_t encodeOp(const std::uint8_t opcode) override {
return opcode * 227;
}
};
// ...
rbx_encoder encoder{};
auto compiled = Luau::compile(source, {}, {}, &encoder);
Cancel
Post
Added
Writing a new reply because the comments are getting messy (you can mention by doing an @ followed by username, @ub4v). I'll start up Roblox on some other hardware I have and see if I can verify that relative address.
Cancel
Post
Used to be involved with game hacking, now I'm involved in cybersecurity. https://reversed.coffee/blog
Replied
Ah, it's my first time using this site. I set up an exception handler (it spams me with exceptions), but I think you're right about their encoding be different than what it used to be. I'm kind of unsure as to how to go about reimplementing their logic because I doubt it's the same as it is in the luau build.
Cancel
Post
Replied
@ub4v Never got back to you on this. Had some technical issues getting Roblox to run but I would say to try hooking LuaVM::load, letting a LocalScript replicate and execute, pulling it from the hook, and decompressing it. Compare it to another script compiled on your Luau build with the same source. This is only if your defer function works correctly, which can be tested by pushing a function to the stack then calling it with defer.
Cancel
Post
Used to be involved with game hacking, now I'm involved in cybersecurity. https://reversed.coffee/blog
Replied
I'll try to get something like that working. Thanks for the help.
I got it working! I was calling luavm_load incorrectly, the correct type definition is typedef uint64_t(*load_typedef)(uintptr_t rl, std::string* source, const char* chunk, int env);
Comments
ItsNitro 4 Reputation
Commented
use luau load and pcall instead of luavm load
Cancel
Post
Users viewing this thread:
( Members: 0, Guests: 1, Total: 1 )
Comments
ub4v 0 Reputation
Commented
I do
and pass it as an argument in my compile function, then I compress with with zstd.
0
RealNickk 10 Reputation
Commented
Have you verified if the state's address is correct? What about the defer function?
Setting up an exception filter might give you some more insight on what's happening (i.e: find out what code is throwing an access violation).
Also you might just have an old Luau build. If they changed their bytecode formatting in any way, it'll error when deserializing. The instruction encoding could be wrong too.
0
ub4v 0 Reputation
Commented
I'm pretty sure the lua state is right. I get it from enurmeating the jobs and then passing ScriptContext to getglobalstateforinstance and then the decrypt function, which gives me a valid structure with a class called extra space at +0x78. My defer offset is 0xECD700. I'll try setting up an exception filter to see if it gives me anything.
0