Page 1 of 1

Java Hacking

Posted: Fri Dec 31, 2021 7:41 am
by OverlordQ
So instead of working from an object, I work from a class, to start out with my LUA looks like:

Code: Select all

javaInjectAgent()

local classes = java_getLoadedClasses()
Then I walk through the classes until I find the one I want:

Code: Select all

    for k, v in pairs(classes) do
        if (v.signature:find("^Lmindustry/core/GameState;") ~= nil) then
            local jclass = v.jclass
            local instances = java_findAllObjectsFromClass(jclass)
            local len = math.min(100, #instances)

            print(string.format("objs=%s, length=%d", tostring(instances), #instances))
            for k, v in pairs(instances) do
                addGameState(jclass, v)
            end
        end
    end
Problem 1: I *thought* I could just do

Code: Select all

local jClass = java_findClass('Lmindustry/core/GameState;')
However that always returns 0, so I end up doing the walk over loadedClasses.

So my GameState function does the following:

Code: Select all

function addGameState(class, instance)
    local fields = java_getClassFields(class)
    print(string.format("fields=%d", #fields))
    for k, field in pairs(fields) do
        local fieldValue = java_getField(instance, field.jfieldid, field.signature)
        print(string.format("%s %s = %s", field.signature, field.name, tostring(fieldValue)))
    end
end
Problem 2: Some of these fields instead of being simple types are classes I need to further walk and recurse. Anything I've tried to fetch references to these classes ends up just freezing up CE. Any ideas?

So full script:

Code: Select all

javaInjectAgent()

local addressList = getAddressList()
local classes = java_getLoadedClasses()

if addressList.Count >= 1 then
    for i = addressList.Count - 1, 0, -1 do
        local mr = addressList.getMemoryRecord(i)
        mr.delete()
    end
end

function addGameStates()
    -- Find GameStates

    gsHeader = addressList.createMemoryRecord()
    gsHeader.Description = "Game States"
    gsHeader.IsGroupHeader = true

    for k, v in pairs(classes) do
        if (v.signature:find("^Lmindustry/core/GameState;") ~= nil) then
            local jclass = v.jclass
            local instances = java_findAllObjectsFromClass(jclass)
            local len = math.min(100, #instances)

            print(string.format("objs=%s, length=%d", tostring(instances), #instances))
            for k, v in pairs(instances) do
                printGameState(jclass, v)
            end
        end
    end
end

function printGameState(class, instance)
    local fields = java_getClassFields(class)
    print(string.format("fields=%d", #fields))
    for k, field in pairs(fields) do
        local fieldValue = java_getField(instance, field.jfieldid, field.signature)
        print(string.format("%s %s = %s", field.signature, field.name, tostring(fieldValue)))
    end
end

addGameStates()
Output:

Code: Select all

objs=table: 000000001C25B200, length=2 
fields=12 
I wave = 1 
F wavetime = 0.0 
Z gameOver = false 
Z serverPaused = false 
Z wasTimeout = false 
Lmindustry/maps/Map; map = 1647081208 
Lmindustry/game/Rules; rules = 1647081200 
Lmindustry/game/GameStats; stats = 1647081192 
Lmindustry/world/blocks/Attributes; envAttrs = 1647081184 
Lmindustry/game/Teams; teams = 1647081176 
I enemies = 0 
Lmindustry/core/GameState$State; state = 1647081168 
fields=12 
I wave = 26 
F wavetime = 3753.3090820313 
Z gameOver = false 
Z serverPaused = false 
Z wasTimeout = false 
Lmindustry/maps/Map; map = 1647081160 
Lmindustry/game/Rules; rules = 1647081152 
Lmindustry/game/GameStats; stats = 1647081144 
Lmindustry/world/blocks/Attributes; envAttrs = 1647081136 
Lmindustry/game/Teams; teams = 1647081128 
I enemies = 0 
Lmindustry/core/GameState$State; state = 1647081120
I basically need/want to modify some fields of the objects in the map/rules/teams fields. And I can't figure out how to walk the objects

Re: Java Hacking

Posted: Sat Jan 01, 2022 10:24 am
by Frouk
instead of print use return & table with table.insert,just insert results into table

Re: Java Hacking

Posted: Sat Jan 01, 2022 11:03 pm
by OverlordQ
Frouk wrote:
Sat Jan 01, 2022 10:24 am
instead of print use return & table with table.insert,just insert results into table
So if getField returns a specific object class, I can just pass that back into getField and so on till I reach the primitive type I'm looking for?

Re: Java Hacking

Posted: Sun Jan 02, 2022 9:50 am
by Frouk
OverlordQ wrote:
Sat Jan 01, 2022 11:03 pm
Frouk wrote:
Sat Jan 01, 2022 10:24 am
instead of print use return & table with table.insert,just insert results into table
So if getField returns a specific object class, I can just pass that back into getField and so on till I reach the primitive type I'm looking for?
I guess, i haven't hacked a java game yet