Jump to content

CmP

Contributor
  • Posts

    672
  • Joined

  • Last visited

  • Days Won

    49

Posts posted by CmP

  1. local function createPhaseDisplayer(phaseValues, progressSymbol, backgroundSymbol)
      local phasesCount = #phaseValues
      local currentPhase = 0
      return function ()
        currentPhase = currentPhase + 1
        if currentPhase > phasesCount then
          os.exit()
        end
        local indicatorFirstPart = string.rep(progressSymbol, currentPhase)
        local indicatorSecondPart = string.rep(backgroundSymbol, phasesCount - currentPhase)
        local indicator = indicatorFirstPart .. indicatorSecondPart
        local phaseValue = phaseValues[currentPhase]
        local displayMessage = string.format("phase %d\nSymbol : %s\n%d", currentPhase, indicator, phaseValue)
        gg.toast(displayMessage, true)
      end
    end
    
    local phaseValues = {10, 20, 30, 40, 50}
    local symbol1 = "="
    local symbol2 = "-"
    local displayPhase = createPhaseDisplayer(phaseValues, symbol1, symbol2)
    
    -- Testing all phases with one extra
    for i = 1, #phaseValues + 1 do
      displayPhase()
    end
  2. Not very clear description, see yourself whether the following does what you want: 

    local function setSpeedForSeconds(speed, seconds)
      gg.setSpeed(speed)
      gg.sleep(seconds * 1000)
    end
    
    while true do
      setSpeedForSeconds(1, 15)
      setSpeedForSeconds(5, 360)
    end
  3. If this happens on emulator with binary translation (Bluestacks, LDPlayer, MEmu, etc) and instructions that are modified have been executed a bunch of times before modification, then this is expected. It's not a bug in GG, it writes memory successfully, behavior will be same regardless of which external tool is used to write memory (as long as method is same, see PTRACE_POKEDATA in ptrace man page). Possible workaround is to apply modification early on, before target instructions have been executed.

  4. @MonkeySAN modify the code to detect process bitness without relying on "getTargetInfo" (since it's not guaranteed to be available), for example like the following: 

    local ranges = gg.getRangesList()
    local highestAddress = ranges[#ranges]["end"]
    local is64 = (highestAddress >> 32) ~= 0
  5. How to store that data in your code effectively depends on which interface to choose an item script needs to provide. If user input is name of item, then table item names as keys and item identifiers as values can work well. If user chooses option from list of possible items, then it can be table of tables with each inner table having name and value fields. Below is an example of tables for both of mentioned options: 

    -- Option 1
    local items = {
      ["dirt"] = 123,
      ["stone"] = 456
    }
    -- Option 2
    local items = {
      {name = "dirt", value = 123},
      {name = "stone", value = 456}
    }
  6. 11 hours ago, MarkusLanez said:

    public SortedDictionary<UnitType, float> units;

    This indicates that value consists of one or more float values that correspond to units. You might be able to find float value corresponding to currently biggest unit used in particular instance of BigNumber, for that you can try range search (for example, if displayed value is 217.58C, then search "217.57~217.59" or maybe even "216.5~217.6", which should include the target value, but may also find many unrelated ones).

  7. 37 minutes ago, MAARS said:

    Should be sleeping in between each edit else it wont work as expected

    On 11/1/2024 at 7:27 PM, CmP said:
    for i = 1, 20 do
      gg.setValues(targetValues) -- doesn't really make sense without delay
    end
    Quote

    -- doesn't really make sense without delay

     

  8. 10 hours ago, dgmon said:

    not working

    The question is what you define as working. You asked for the code that modifies value(s) from saved list that are named "R" to "-2.0" 20 times in loop. The code above should do exactly that. Maybe that's not exactly what you need?

  9. local savedValues = gg.getListItems() -- Enough to get items once if list won't change during execution of loop
    local targetValues = {}
    for i, v in ipairs(savedValues) do
      if v.name == "R" then
        targetValues[#targetValues + 1] = {
          address = v.address,
          flags = v.flags,
          value = "-2.0"
        }
      end
    end
    for i = 1, 20 do
      gg.setValues(targetValues) -- doesn't really make sense without delay
    end

    And, please, don't mention anyone in questions that are not directed to someone specifically.

    Lua

    local function hack1()
      gg.toast("Hack 1")
    end
    
    local function hack2()
      gg.toast("Hack 2")
    end
    
    local function menu()
      gg.toast("Menu")
    end
    
    gg.setVisible(false)
    while not gg.isVisible() do
      gg.sleep(100)
    end
    hack1()
    
    gg.setVisible(false)
    while not gg.isVisible() do
      gg.sleep(100)
    end
    hack2()
    
    gg.setVisible(false)
    while true do
      if gg.isVisible() then
        menu()
      end
      gg.sleep(100)
    end
  10. Embed libraries finder


    This script consists of a module (Lua code organized in certain way) for finding addresses of native libraries that are loaded directly from apk (which is the case when android:extractNativeLibs manifest attribute is set to "false") and several examples of how to use the module.

    Finding name of libraries in the script is implemented by checking soname of memory regions that are loaded from apk (including splits), contents of which resemble library in ELF format. Libraries that don't have soname specified won't be found by the script. Though, typically, main libraries of interest in games have soname specified, so the script should be applicable in most cases when libraries are loaded directly from apk. If a library has soname specified, but the script doesn't find it, generate debug log (example 3 from the file) from attempt to find the library and include it in the comment with report of the issue.


     

  11. On 7/20/2024 at 11:38 AM, LightWarrior said:

    How can i make a group search of 10 and 40 that excludes 9 between them?

    With group search only it can be done if offset between first and second searched value is known beforehand. For your example and assuming all values that need to be included/excluded are dwords, offset between first and second value is 28 (0x1C), so there are exactly 6 dword values between them and each of them needs to be not equal to 9, which can be specified as "8~~10". So the string for group search for this case is "10;8~~10;8~~10;8~~10;8~~10;8~~10;8~~10;40::29". Then you can refine with "10;40::29" to get target results (but if any of values in between is 10 or 40, they will be included as well).

  12. Then it's reasonable to just search either first or second value and filter only desired results that have other value at needed offset. Something like the following: 

    local firstValue = 210.0
    local secondValue = 30.0
    local offset = 12
    
    gg.clearResults()
    gg.searchNumber(firstValue, gg.TYPE_DOUBLE)
    local firstValues = gg.getResults(gg.getResultsCount())
    local secondValues = {}
    for i, v in ipairs(firstValues) do
      secondValues[i] = {address = v.address + offset, flags = gg.TYPE_DOUBLE}
    end
    secondValues = gg.getValues(secondValues)
    local targetResults = {}
    local index = 1
    for i = 1, #firstValues do
      if secondValues[i].value == secondValue then
        targetResults[index] = firstValues[i]
        targetResults[index + 1] = secondValues[i]
        index = index + 2
      end
    end
    gg.loadResults(targetResults)
  13. What are the values? How many search results do you get when searching the values separately (i.e. new search for first value in desired ranges - X results, same for second value - Y results)? What is the offset between the values? Which option will work better for your case can be estimated only with knowledge of the details.

  14. 18 hours ago, Yelay12 said:

    I want to search value within the 7 to 700 range and that value divided by 7 is with remainder zero.

    If you mean how to do it without concatenating tables with results from separate searches for each value (and potentially significantly faster), it may be done by searching multiple values at once with range searches. The idea is to make initial search from lowest target value to highest, then N - 1 refine searches to exclude ranges of values that are between target values, so that only target values remain at the end. Below is an example implementation of this idea for your case (untested, may require minor changes if doesn't work as is).

    local function interpretAsInteger(double)
      return string.unpack("I8", string.pack("d", double))
    end
    
    local function interpretAsDouble(integer)
      return string.unpack("d", string.pack("I8", integer))
    end
    
    local function convertToString(double)
      return string.format("%.17g", double)
    end
    
    local function getNextDoubleStr(doubleValue)
      local intValue = interpretAsInteger(doubleValue)
      local nextDouble = interpretAsDouble(intValue + 1)
      return convertToString(nextDouble)
    end
    
    local function getPreviousDoubleStr(doubleValue)
      local intValue = interpretAsInteger(doubleValue)
      local previousDouble = interpretAsDouble(intValue - 1)
      return convertToString(previousDouble)
    end
    
    local function searchMultipleDoubleValues(values)
      if #values < 2 then
        return
      end
      table.sort(values)
      local initialSearchStr = convertToString(values[1]) .. "~" .. convertToString(values[#values])
      gg.clearResults()
      gg.searchNumber(initialSearchStr, gg.TYPE_DOUBLE)
      for i = 1, #values - 1 do
        local excludedRangeLowerBound = getNextDoubleStr(values[i])
        local excludedRangeUpperBound = getPreviousDoubleStr(values[i + 1])
        local excludedRangeSearchStr = excludedRangeLowerBound .. "~" .. excludedRangeUpperBound
        gg.refineNumber(excludedRangeSearchStr, gg.TYPE_DOUBLE, false, gg.SIGN_NOT_EQUAL)
      end
    end
    
    local valuesToSearch = {}
    for value = 7, 700, 7 do
      valuesToSearch[#valuesToSearch + 1] = value
    end
    searchMultipleDoubleValues(valuesToSearch)
    local resultsCount = gg.getResultsCount()
    print("Found " .. resultsCount .. " results")
  15. It's not a good idea to do that for many results (like 100k-200k+), since you will most likely run out of memory, but you can test how it goes in your case. Here is a function to concatenate results from table of tables with results: 

    function concatResults(resultsList)
      local mergedResults = {}
      local index = 0
      for _, results in ipairs(resultsList) do
        for __, result in ipairs(results) do
          index = index + 1
          mergedResults[index] = result
        end 
      end
      return mergedResults
    end

    And example of it's usage: 

    local resultsList = {}
    for i = 7, 700, 7 do
      gg.clearResults()
      gg.searchNumber(tostring(i), gg.TYPE_DOUBLE)
      resultsList[#resultsList + 1] = gg.getResults(gg.getResultsCount())
    end
    local allResults = concatResults(resultsList)
  16. Tagged pointers helper


    This script addresses GG not supporting tagged pointers natively by providing two features (going to pointer and searching pointers) that work for both regular and tagged pointers. Additionally, pointer search supports searching pointers for multiple targets at once.

    Script is used by selecting item(s) for desired operation in any of GG interface tabs and pressing "Sx" button to invoke script menu and choose the operation.

    Credits:
      - @BadCase - for method of searching for tagged pointers to multiple targets at once.


    • Submitter
      CmP
    • Submitted
      07/06/2024
    • Category

     

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.