-
Posts
934 -
Joined
-
Last visited
-
Days Won
40
Platonic last won the day on August 12
Platonic had the most liked content!
Additional Information
-
Android
6.x (Marshmallow)
Recent Profile Visitors
114,382 profile views
Platonic's Achievements
-
Move the libUE4.so file to correct directory, see video.
- 11 replies
-
- ToF
- Tower of Fantasy
-
(and 1 more)
Tagged with:
-
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
-
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.
-
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" ?
-
Because the question was not "improve my script" or something like that. Personally i build on what is provided unless asked otherwise.
-
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
-
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)
-
It was just an example
-
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'}})
-
How can I be sure that the value is stored on server side?
Platonic replied to Iqbroly's topic in General Discussion
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. -
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)
-
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
-
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.
-
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.
-
My YouTube channel.