Categories > Exploiting > Roblox >

task::defer crashing

New Reply

Posts: 5

Threads: 1

Joined: Dec, 2024

Reputation: 0

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." 

 

  • 0

  • Comment

RealNickk

nick / reversed-coffee

patron

Posts: 31

Threads: 3

Joined: Mar, 2023

Reputation: 10

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);

 

Comments

ub4v 0 Reputation

Commented

I do 

class bytecode_encoder_t : public Luau::BytecodeEncoder {
    std::uint8_t encodeOp(const std::uint8_t opcode) {
        return opcode * 227;
    }
} encoder{};

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

  • 0

  • Comment

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.

  • 0

  • Comment

Used to be involved with game hacking, now I'm involved in cybersecurity. https://reversed.coffee/blog

Posts: 5

Threads: 1

Joined: Dec, 2024

Reputation: 0

Replied

@RealNickk

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.

  • 0

  • Comment

RealNickk

nick / reversed-coffee

patron

Posts: 31

Threads: 3

Joined: Mar, 2023

Reputation: 10

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.

  • 0

  • Comment

Used to be involved with game hacking, now I'm involved in cybersecurity. https://reversed.coffee/blog

Posts: 5

Threads: 1

Joined: Dec, 2024

Reputation: 0

Replied

@RealNickk

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

  • 0

  • 0

  • Comment

Login to unlock the reply editor

Add your reply

Users viewing this thread:

( Members: 0, Guests: 1, Total: 1 )