Jump to content

Platonic

Contributor
  • Posts

    934
  • Joined

  • Last visited

  • Days Won

    39

Everything posted by Platonic

  1. Move the libUE4.so file to correct directory, see video.
  2. Platonic

    Improve script

    This is my point, it does meet the requirement because valStart gets incremented by 0x250 before the if statement will check and compare valStart. If i put the if statement at the top, the loop will index once more which is a waste to do because we already know that the value has reached the condition when valStart was incremented. So for that reason i placed the if statement at the bottom. dex = {} for i = 1, loop do if valStart >= range[3]["end"] then print(i, "Condition: "..string.format("%x", valStart), string.format("%x", valEnd)) break end print(i, "Current: "..string.format("%x", valStart),"End address: "..string.format("%x", valEnd)) dex[#dex + 1] = {address = valStart, flags = gg.TYPE_QWORD} valStart = valStart + 0x250 end Look like this: It will increment loop once more and then do the break. At the top. But here i do if statement at the botton before loop index increments: dex = {} for i = 1, loop do print(i, "Current: "..string.format("%x", valStart),"End address: "..string.format("%x", valEnd)) dex[#dex + 1] = {address = valStart, flags = gg.TYPE_QWORD} valStart = valStart + 0x250 if valStart >= range[3]["end"] then print(i, "Condition: "..string.format("%x", valStart), string.format("%x", valEnd)) break end end
  3. Platonic

    Improve script

    Hmm although i see what you mean. I just printed out but i can't see a difference that would cause unwanted addresses. When the condition in the loop is met it will break the loop. In this case regardless if the if statement is placed at start or end. Because the variable varStart gets incremented by 250 before new address and flags gets added to the dex table. So actually i think its better that the if statement is at the end(in this case) so that the loop gets broken before the loop increments. dex = {} for i = 1, loop do dex[#dex + 1] = {address = valStart, flags = gg.TYPE_QWORD} valStart = valStart + 0x250 if valStart >= range[3]["end"] then break end -- break before loop gets incremented end But let me know your opinion.
  4. local count = gg.getResultsCount() local valueRes = gg.getResults(count) local valueResFi = {} for i, v in ipairs(valueRes) do valueResFi[i] = {address = v.value, flags = v.flags} end gg.loadResults(valueResFi) This? Did not try to touch to much the variables.
  5. Platonic

    Improve script

    Thanks for providing the info. Notes taken for next time. A small question regarding reference. Is there specific reason why byte.value got referenced through the variable "value" ?
  6. Because the question was not "improve my script" or something like that. Personally i build on what is provided unless asked otherwise.
  7. Platonic

    Improve script

    Must load start address of executables with there responding path name. I use it if i need to find for example the libil2cpp.so in a split apk without moving the files to different folder. But its only made for my device, wont work on most other devices. Offsets different..etc
  8. Platonic

    Improve script

    Can the script be improved in writing and speed? When i run the script it seems to take a suspicious amount of time to add the string names to the corresponding addresses. Im not sure how i could improve it so that the script in general goes faster. local range = gg.getRangesList("anon:linker_alloc") local valStart = range[3].start + 0x20 local valEnd = range[3]["end"] local loop = valEnd - valStart dex = {} for i = 1, loop do dex[#dex + 1] = {address = valStart, flags = gg.TYPE_QWORD} valStart = valStart + 0x250 if valStart >= range[3]["end"] then break end end gg.loadResults(dex) gg.refineNumber(0, gg.TYPE_QWORD, nil, gg.SIGN_NOT_EQUAL) local dex = gg.getResults(gg.getResultsCount()) local strPointer = {} local exe = {} for i, v in ipairs(dex) do strPointer[i] = {address = v.address + 0xC8, flags = gg.TYPE_QWORD} exe[i] = {address = v.value, flags = gg.TYPE_DWORD} end exe = gg.getValues(exe) strPointer = gg.getValues(strPointer) local lup = 1 local executable = {} for i = 1, #exe do local stringAddress = {} local final = {} for j = 1, 150 do stringAddress[#stringAddress + 1] = {address = strPointer[lup].value, flags = gg.TYPE_BYTE} strPointer[lup].value = strPointer[lup].value + 1 end strings = gg.getValues(stringAddress) for b, t in ipairs(strings) do if strings[b].value ~= "0" then final[#final + 1] = string.char(t.value&0xFF) a = table.concat(final) else break end end executable[#executable + 1] = {address = exe[i].address, flags = gg.TYPE_DWORD, name = a} lup = lup + 1 end gg.addListItems(executable) local lib = {} for i, v in ipairs(executable) do if (string.find(v.name, "libil2cpp.so")) ~= nil then lib[#lib + 1] = v break end end gg.loadResults(lib)
  9. local start = gg.getRangesList('libil2cpp.so')[1].start gg.setValues({{address = start + 0x6225F4, flags = 4, value = '~A MOV R0, #1'},{address = start + 0x6225F0, flags = 4, value = '~A BX LR'}})
  10. If it is a item from the store, you can just know it by changing the value of that item and then buying something in the game store. If the math done on the values you changed are based on the original value before modification then it is server sided. Regardless what the value shows on your screen.
  11. Maby reading the following sources helps: https://en.m.wikipedia.org/wiki/Data_segment https://en.wikipedia.org/wiki/Library_(computing) Maby it helps to know how it works: https://docs.unity3d.com/560/Documentation/Manual/IL2CPP-HowItWorks.html https://docs.unity3d.com/Manual/IL2CPP.html#HowItWorks https://en.m.wikipedia.org/wiki/Offset_(computer_science)
  12. You have to be in the game, and the game should not be on pause when you activate the script because it will set the value to zero. Make sure there is no message on screen. Here is video: mobizen_20221207_195944.mp4
  13. Its possible that the actual levels are xor encrypted or somehow only accesses through pointers. If they are xor encrypted one could try finding the revert button value because that one also cant be found by normal search nor unknown search. Which i think is also in the class UIManager and static. If that one turns out to be a encrypted xor value one could try same xor value on the currency and levels and hope they are the same. But thats just speculation. It could be more efficient to see what methods it has in Xa i think. Total moves is actually float while current moves used is dword, Could already be suspicious, but share me your thoughts and approaches we could try.
  14. Hey, i am not sure if i can help a hand with the research, but there is this class, UIManager, it has 260 fields. It could be interesting? To be fair personally i find design of this game weird but im suspecting everything relevant is under that one class. Either by direct dword values or pointers. I dunno how to check Xa but perhaps its as well interesting for you to research.
  15. Its a unity game, try using speedhack finder. Auto speedhack finder (#57uzsb98)
  16. Platonic

    limitations

    Like this? function setNewName() gg.setRanges(gg.REGION_ANONYMOUS) gg.searchNumber(';USP \"Line\"') gg.refineNumber(';U') local t = gg.getResults(gg.getResultsCount()) local replaceString = {} local stringSize = {} local str = {} gg.clearResults() for i= 1, 15 do str[i] = string.sub("USP \"Geometric\"", i, j) end for i, v in ipairs(t) do stringSize[#stringSize + 1] = {address = t[i].address - 0x4, flags = gg.TYPE_WORD, value = 15} for charCount = 1, 15 do replaceString[#replaceString + 1] = {address = t[i].address, flags = gg.TYPE_WORD, value = string.byte(string.sub(str[charCount], 1, 1))} t[i].address = t[i].address + 2 end end gg.setValues(replaceString) gg.setValues(stringSize) end setNewName()
  17. Platonic

    limitations

    Oh, The desired skin is always USP "Line" ?
  18. Platonic

    limitations

    Very weird, i tried on 64 and 32 bit emulator. Should work fine. Did you put the string properly? Show video.
  19. Platonic

    limitations

    If it works, adjust the script so that it is compatible with yours.
  20. Platonic

    limitations

    Does this work? function setNewName() local t = gg.getResults(gg.getResultsCount()) local replaceString = {} local stringSize = {} local str = {} gg.clearResults() for i= 1, #editname[1] do str[i] = string.sub(editname[1], i, j) end for i, v in ipairs(t) do stringSize[#stringSize + 1] = {address = t[i].address - 0x4, flags = gg.TYPE_WORD, value = #editname[1]} for charCount = 1, #editname[1] do replaceString[#replaceString + 1] = {address = t[i].address, flags = gg.TYPE_WORD, value = string.byte(string.sub(str[charCount], 1, 1))} t[i].address = t[i].address + 2 end end gg.setValues(replaceString) gg.setValues(stringSize) end function findName() gg.setRanges(gg.REGION_ANONYMOUS) gg.searchNumber(';'..playername[1]) local a = gg.getResults(gg.getResultsCount()) if #a == 0 then gg.toast("name not found, search again") prompt_search() else gg.refineNumber(a[1].value..';'..a[2].value..';'..a[3].value..'::5') gg.refineNumber(a[1].value) end end -- if menu is nil function noselect() gg.toast('You not select anything') end function prompt_edit() editname = gg.prompt( {[1] = 'Input name to modify to'}, {[1] = '0'}, {[1] = 'text'}) if editname == nil then noselect() else setNewName() end end function prompt_search() playername = gg.prompt( {[1] = 'Input desired player name.'}, {[1] = '0'}, {[1] = 'text'}) if playername == nil then noselect() else findName() prompt_edit() end end prompt_search() while (true) do if gg.isVisible() then gg.setVisible(false) prompt_search() end gg.sleep(100) end
  21. Appreciate the info about memory occupation in Lua and thanks as well for the script examples! Although your scripts are way more efficient, I assumed the 100k method would be faster to reach the full address range of a segment. Reason i don't want to use search is because i miss the data that gets allocated at unused memory addresses while old data gets replaced or cleared due to memory management techniques. Being dependable on addresses being used or not was in this case out of option to me, so i thought i should and could get all addresses in a reasonable time frame. And thats my mistake for thinking that was even optional with loops of 1m+ CmP is basically pointing out that it is not possible to do that(having a table that has all those addresses stored) because of memory. And if by your own method it still would take long time to process then i guess i have to work towards something else because its just not pleasant to work like that. The scripts you provided where educational for efficiency!
  22. Its unfortunate that there is no maturity test before making an account. It would be great if you can change the attitude a bit. People that want to show how superior they are do act in a way as you do, Could be by giving joke answers to serious questions. Or simply enable to have a proper conversation. Very self centered and serious arrogance. My question remains.
  23. Or perhaps the script needs to be written differently?
×
×
  • 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.