Skip to content

4. Advanced Custom Functions

AsynchronousAI edited this page Sep 1, 2025 · 4 revisions

If you do make some of your own utilities or functions please contribute them.

Functions

Much more utilities are provided for more advanced functions. Some of the built in functions will now be provided as examples.

printf

    ["printf"] = function()
        local args = extract_args()
        local fmt = args[1]
        table.remove(args, 1)
        print(format_string(read_string(fmt), args))
    end,
  • read_string is a function that is exposed to convert a string inside the memory buffer to a Luau string. It works by taking in a start pointer (int) and reading until it finds a null terminator (\0).
  • format_string is a function that is meant to act like string.format but have support for:
    • formatting pointers into %s (with read_string)
    • converting ints into floats for %f

memcpy

     ["memcpy"] = function()
        local args = extract_args()

        local dest = args[1] -- dest pointer in memory
        local src = args[2] -- source pointer in memory
        local count = args[3]

        buffer.copy(memory, dest, memory, src, count)
    end,

This is a simple wrapper for buffer.copy.

Utilities

extract_args

local function extract_args()
   return {
       registers.x10,
       registers.x11,
       registers.x12,
       registers.x13,
       registers.x14,
       registers.x15,
       registers.x16,
       registers.x17,
   }
end

In RISC-V Assembly registers x10 to x17 represent arguments 1 to 7.

read_string

local function read_string(startPointer)
    -- read null terminated strings from memory
    local pointer = startPointer
    local str = ""
    local byte
    repeat
        byte = buffer.readbits(memory, pointer * 8, 8)
        if byte == 0 then break end
        str = str .. string.char(byte)
        pointer = pointer + 1
        if pointer >= mem then error("Exceeded buffer size when reading string.") end
    until false
    return str
end

format_string

local function format_string(fmt, args)
    -- custom format string because strings are stored as pointers, and floats as ints.
    local arg_index = 1

    local result = fmt:gsub("%%([%d%.]*[dfs])", function(spec)
        local val = args[arg_index]
        arg_index = arg_index + 1

        if spec:sub(-1) == "d" then
            return string.format("%d", val)
        elseif spec:sub(-1) == "f" then
            return string.format("%"..spec, string.unpack("f", val))
        elseif spec:sub(-1) == "s" then
            return read_string(val)
        else
            return spec
        end
    end)

    return result
end

Clone this wiki locally