GuiRoot Method
In this guide, we will find datamodel using the GuiRoot method
In this guide, we will find datamodel using the GuiRoot method
To find datamodel using guiroot method, you have to do 3 things:
Here is an example code of how to do Gui Root method:
const GuiRootMethod = struct {
// Scan for GuiRoot GuiItem
fn findGuiRootString(allocator: std.mem.Allocator, memory_accessor: anytype) !Memory.Address {
// Create buffer to store memory read from Roblox
var buffer: std.ArrayList(u8) = .{};
// Free buffer once done
defer buffer.deinit(allocator);
// Create page iterator
var it = Memory.PageIterator.init(memory_accessor);
// Iterate through all the pages
while (it.next()) |mbi| {
// We only want readable and writable pages but not executable
if(!mbi.canRead() or !mbi.canWrite() or mbi.canExecute())
continue;
// Resize buffer to match page size
try buffer.resize(allocator, mbi.getRegionSize());
// Read from roblox into our buffer
memory_accessor.readSlice(mbi.getBaseAddress(), u8, buffer.items) catch continue;
// Search for string "GuiRoot\x00GuiItem\x00" in the buffer and return the address
return mbi.getBaseAddress().shiftBy(std.mem.indexOf(u8, buffer.items, "GuiRoot\x00GuiItem\x00") orelse continue);
}
// If not found, return nullptr
return Memory.Address.nullptr();
}
pub fn getDatamodel(allocator: std.mem.Allocator, memory_accessor: anytype) !Roblox.Instance.View {
// get root gui str address
const guirootstr = try findGuiRootString(allocator, memory_accessor);
if(guirootstr.isNull())
return error.GuiRootStringNotFound;
// get fake datamodel from that
const fake_datamodel = try guirootstr.shiftBy(Roblox.Config.get("Offset/GuiRootMethod/FakeDatamodel")).read(memory_accessor, Memory.Address);
// get datamodel from fake datamodel
const datamodel = try fake_datamodel.shiftBy(Roblox.Config.get("Offset/FakeDatamodel/Datamodel")).read(memory_accessor, Memory.Address);
return Roblox.Instance.View.of(datamodel);
}
};
Now let's compare the result of GuiRoot method vs TopDown method
...
// Print datamodel address
try stdout.print("{s}{X}{c}", .{ "(TopDown) Datamodel is: ", datamodel.getPtr(), '\n' });
// Gui Root method
const guiroot_datamodel = try GuiRootMethod.getDatamodel(allocator, memory_accessor);
try stdout.print("{s}{X}{c}", .{ "(GuiRoot) Datamodel is: ", guiroot_datamodel.getPtr(), '\n' });
...
We got:
Roblox process handle is: A8
(TopDown) Datamodel is: 21B018A3E38
(GuiRoot) Datamodel is: 21B018A3E38
Datamodel name is: Ugc
It works! Remember the offsets used here are available in config.hscl on this site as always.