-
Posts
663 -
Joined
-
Last visited
-
Days Won
16
Content Type
Profiles
Forums
Downloads
Gallery
Everything posted by nok1a
-
It's a unity game. If you know the class name you can more easy find value. Use this script to find what field name the value represent: Class name and Field offset searcher (#4udgq21d)
-
Can only explain you how i do it personally, but perhaps someone can explain another way. I also don´t know how familiar you are with Lua. But you said you are new so i will assume that you don´t know Lua. Also since you been doing everything from scratch without code to help you, so i will provide you helper examples. I will provide you more or less a building structure which is familiar to me and which you can modify how you want. First you need to search the class name in the global-metadata.dat. For do that you need the start and end address of where your global-metadata.dat is located within the memory of your process. You can make a function similar like the one below that first locates the global-metadata.dat in memory (assuming it is not hidden) and takes the start and end address of that lib (see more info about the gg.getRangesList: https://gameguardian.net/help/classgg.html#a8bb9745b0b7ae43f8a228a373031b1ed function metaDataOffsets() -- Will give you start and end range of the global-metadata lib which resides in region Other. startAddressDat = 0 endAddressDat = 0 local rangesDat = gg.getRangesList("global-metadata.dat") for i, v in ipairs(rangesDat) do if v.state == "O" then startAddressDat = v.start -- start endAddressDat = rangesDat[i]["end"] -- end break end end end Then you make a function that searches for your class name in which to which the field belongs, but as well the AssemblyCSharp string, you will need that one in order to filter out unwanted pointers. You search those strings in the address range of the global-metadata.dat, you just fetched it's the start and end addresses from your previous function metaDataOffsets() For readability purposes and clarity we make a function where you initialize your string names (class names) and give them meaningful variable names which we can then later search with GG. Note that you must search the class name as a string of bytes and append 00 to the front and end of the bytes which indicate the start and end of the string of bytes. You can use this website to convert ascii characters to their representing byte and as that create your string of bytes. We put the "h" at the beginning of the string so we can let GG know that we are searching in Hex. See a example function that initialize the strings to their variables, so that we then can use in a later stage as a GG search: -- string names function stringNames() Class_AssemblyCSharp = "h00417373656d626c792d4353686172702e646c6c00" Class_Weapons = "h00576561706f6e7300" end stringNames() We must perform pointer search on the second character of the string. We can make a function that receives the string as a argument and will saves the address of where the second character is stored in memory. This function is useful if you want to access many classes, less repetitive code: function searchString(className) -- takes in name of desired class, searches in the range of the global-metadata.dat gg.clearResults() gg.searchNumber(className, gg.TYPE_BYTE, nil, nil, startAddressDat, endAddressDat) -- start and end range local t = gg.getResults(2) tableMetadataOffsets = t[2].address -- stores address at variable tableMetadataOffset gg.clearResults() return tableMetadataOffsets -- returns that address to the calling function which will be used to perform pointer search. end Since i don´t know if your running the game on 32 bit or 64 bit we should include a function that checks if your running game on 32 bit or 64 bit. This is also helpful in case someone sees this post and want to do same as your doing. So it's a general solution. See example function(s): function isProcess64Bit() -- we only call this function once. It will check if the final address that gg.getRangesList is more then 32 bits. If so your game is running on 64 bit. Else it´s 32. local regions = gg.getRangesList() local lastAddress = regions[#regions]["end"] return (lastAddress >> 32) ~= 0 end In my case i only want to call isProcess64Bit once. So i store the result in a separate function, but this is up to creator choice. This function is from my old script and should be updates as there is better ways to write this function, but for example purposes it will be ok: function validISA() -- we store result in the variable "instructionSetArchitecture" (Maybe given it a shorter name does not hurt, lol) instructionSetArchitecture = 0 if isProcess64Bit() == true then -- calling isProcess64Bit() instructionSetArchitecture = 64 else instructionSetArchitecture = 32 end return instructionSetArchitecture end Now we can make a function where we initialize or variables with the values which are only dependable on the instruction set of the game. Separate the offsets in separate functions to not get to confused. For example a function that has the offsets relevant to the class and it's fields. And the a function that has offsets that you have to use in almost every function. For example: function instructionsOffset() if instructionSetArchitecture == 32 then -- if true then 32 bit else 64 bit hexConvert = 0xFFFFFFFF -- You need this for safely perform pointer searches on 32 bit. dataType = 4 -- on 32 bit when performing pointer search you do it using gg.TYPE_DWORD (4). classOffset = 0x8 -- when performing pointer search on second character of string you must do a -0x8 to reach class pointer. else dataType = 32 -- on 62 bit when performing pointer search you do it using gg.TYPE_QWORD (32). classOffset = 0x10 -- when performing pointer search on second character of string you must do a -0x10 to reach class pointer. end end instructionsOffset() Then a function where we put offsets only relevant to the class that we try to change it's fields of: function weaponSettingsOffsets() if instructionSetArchitecture == 32 then weaponPointerToIdOffset = 0x8 weaponPointerToAmmoOffset = 0x48 weaponPointerToRecoilOffset = 0x78 else weaponPointerToIdOffset = 0x10 weaponPointerToAmmoOffset = 0x60 weaponPointerToRecoilOffset = 0x90 end end weaponSettingsOffsets() Now we must make function that takes the second character of the AssemblyCSharp string and then use the address of the pointer pointing to that chracter it's address. We use it in future use cases for checking purposes of other class pointers. As i mentioned before: function assemblyAddressCheck() gg.setRanges(gg.REGION_ANONYMOUS | gg.REGION_C_ALLOC | gg.REGION_OTHER) -- we enable the regions in which we allow GG to search searchString(Class_AssemblyCSharp) -- we call the function searchString and parse the string that we made at function stringNames(), it will return the second character of the string under the name tableMetadataOffsets. gg.searchNumber(tableMetadataOffsets, dataType) -- We perfoming pointer search on the second character. dataType: 32bit = 4(dword) | 64bit = 32(qword) assembly = gg.getResults(1) -- we now have the pointer which we use to check if the class pointer you have is valid once or not. gg.clearResults() return assembly -- we can now use this variable every time for checking. end assemblyAddressCheck() Now we can work on finding your field value as we setted up the main structure. Make a function with the name of your class which will first call searchString in order to get the second character of the string, then perform pointer search on that second character. Then do offset - 0x8 or-0x10 depending on your instruction set architecture. Then check if the value at those addresses is equal to the value of assembly which you received from the function assemblyAddressCheck() Then once that check is complete you can start working with the pointer that is equal to assembly. Perform a pointer search on that pointer. That will give you all the instances that point to your class pointer. see an example: function weaponsSettings() gg.clearResults() gg.setRanges(gg.REGION_ANONYMOUS | gg.REGION_C_ALLOC | gg.REGION_OTHER) searchString(Class_Weapons) gg.searchNumber(tableMetadataOffsets, dataType) a = gg.getResults(5) for i, v in ipairs(a) do v.address = v.address - classOffset -- classOffset: 32bit = 0x8 | 64bit = 0x10 end a = gg.getValues(a) gg.clearResults() compareWeaponsToAssembly = {} for i,v in ipairs(a) do if instructionSetArchitecture == 32 then v.value = v.value & hexConvert -- hexConvert: 32bit = 0xFFFFFFFF end if v.value == assembly[1].address then -- if matches with assembly then store class pointer in compareWeaponsToAssembly (should ony be 1) compareWeaponsToAssembly[#compareWeaponsToAssembly + 1] = v end end gg.searchNumber(compareWeaponsToAssembly[1].address, dataType) -- perform pointer search on class pointer to get it's instances. weaponPointers = gg.getResults(1141) -- maybe you get to many instances and will need to do extra checks to get the correct instances. gg.clearResults() weaponId = {} for i, v in ipairs(weaponPointers) do --find your field by adding your field offset. It will do instance base address + field. Also add the desired data type of that field using the flags. weaponId[i] = {address = v.address - weaponPointerToIdOffset, flags = dataType} recoilTableOn[i] = {address = v.address + weaponPointerToRecoilOffset, flags = gg.TYPE_DOUBLE} maxAmmoCapacityTableOn[i] = {address = v.address + weaponPointerToAmmoOffset, flags = gg.TYPE_DWORD} end gg.toast('recoil, reload, max ammo, accumulation ready') end weaponsSettings() I hope this more or less explains it. sadly i don't have a simple script but i can provide you some, you take your time to understand they might make sense. All my scripts are written in similar way. games.burny.playdoku.block.puzzle.lua com.gameinsight.gobandroid (1).lua Also have a look at this video:
-
"How do you normally find the value" was maybe more accurate question. Make a video. Then we can see from there.
-
What's the value your looking for?
-
-
You use -10 because i guess that's where all instances of the class are pointing to. For fix issue i guess you need to add B40000 before the address on which you want to perform the pointer search.
-
Genshin Impact| How to find values using pointers and metadata (#cmvrumr0)
-
Will be honest. You can't really defend from that, maybe make it harder for someone to find it using pointers and fake searches...etc. All type of redundant stuff to waste someone his time. Accept that when you make script and use GG function and offset calculations or anything that's in the script people can get it.
-
I don't think you can make a DWORD value infinity. If the number is more then what can be represented in DWORD then you need to select another type. I believe infinity only exist with floating point numbers.
-
I don't really get it. You want to unlock images that are currently locked because the game will shut down? And then keep that as a new apk? If this game is online they will just shut down the servers and the game will not be playable anymore unless you run your own server i believe.
-
If this game is Unity have you tried speedhack finder: Auto speedhack finder (#57uzsb98)
-
-
I think the logic remains the same. But since the values are in region Other you might need to change a setting in the GG app. Put memory areas on Empty or No(Slow). Like here: No results found after searching copied values from the memory view (#ra89asn) @mindfulanswer
-
Oke maybe the algorithm is different. Have you tried just using unknown search - changed for each time you continue the path? If you just want to edit the stats without gold or progress you can overwrite existing script with this one so you win every battle: main.dd2c5021e47dbf813d5d.js Original code: return Fu(t, e), Object.defineProperty(t.prototype, "life", { get: function() { return this._lifeStat.value }, enumerable: !0, configurable: !0 }), Object.defineProperty(t.prototype, "lifeMax", { get: function() { return this._lifeStat.maxValue }, enumerable: !0, configurable: !0 }), Object.defineProperty(t.prototype, "defense", { get: function() { return this._defenseStat.value }, enumerable: !0, configurable: !0 }), Object.defineProperty(t.prototype, "attackLow", { get: function() { return this._attackStat.lowestValue }, enumerable: !0, configurable: !0 }), Object.defineProperty(t.prototype, "attackHigh", { get: function() { return this._attackStat.value }, enumerable: !0, configurable: !0 }), Object.defineProperty(t.prototype, "speed", { get: function() { return this._speedStat.value }, Changed to: return Fu(t, e), Object.defineProperty(t.prototype, "life", { get: function() { return 1000000 }, enumerable: !0, configurable: !0 }), Object.defineProperty(t.prototype, "lifeMax", { get: function() { return 1000000 }, enumerable: !0, configurable: !0 }), Object.defineProperty(t.prototype, "defense", { get: function() { return 1000000 }, enumerable: !0, configurable: !0 }), Object.defineProperty(t.prototype, "attackLow", { get: function() { return 1000000 }, enumerable: !0, configurable: !0 }), Object.defineProperty(t.prototype, "attackHigh", { get: function() { return 1000000 }, enumerable: !0, configurable: !0 }), Object.defineProperty(t.prototype, "speed", { get: function() { return 1000000 },
-
Oke and you did as in this video, correct? https://youtu.be/0HUNesMSmTI?si=nL9fJdeEQvQ8NhZX
-
It's different on emulators apparently. So i just puzzled around in the directory folders. And i believe the file responsible for the values in the game is stored at /data/app/com.keeweed.pathofadventure-Cakb2P0ZsunlZCe-vhEn-Q==/base.apk\assets\www, there is a js script starting with main. Did some random changes in the file as i don't know javascript and then saved the changes. And apparently the changes take effect. But i don't know JS so it was just a random edit in the file. Someone else that know JS can easily edit that file. Or you can ask chatgpt to help you with it. Once i know how to read the file accordingly i will for sure share the edited version with you. Aside from that, are you running x86/x86_64 because i recall for some native game that also had the logic build in javascript(i guess) that the logic worked different for those architectures.
-
Are you on emulator?
-
-
Personally dunno how the GG speed works but maybe if you run GG and the game in a virtual space like F1VM or x8Sandbox? And your not on a emulator or anything running x86_64, x86 instead of ARM or ARM 64 bit ?
- 7 replies
-
- Pocket Mortys
- Timeskip
-
(and 1 more)
Tagged with:
-
Yeah it's encrypted. I can't help you with decrypting it. But when you play the game you can see the methods, fields structs...etc. So in the game the main things haven't changed that much. You just need to find a way to cheat the things you want without relying on that encrypted metadata. But i think there are some tutorials on the internet that explain you how to decrypt a metadata. Maybe check the platinmods forum. What you can also try is dump a older version of the game where the files aren't encrypted and then search the names with GG.
-
il2cpp dumper doesn't recognize it as a valid metadata file. To be honest, the header doesn't make much sense. Which game is that? I guess you manually edited the first 4 bytes?
-
You used autospeedhack finder and the speed increased? Just not the right speed? Or how you mean. What you want to speedup in pokcet mortys?
- 7 replies
-
- Pocket Mortys
- Timeskip
-
(and 1 more)
Tagged with:
-
You probably need to explain more specific.
- 3 replies
-
- Eldrum: Red Tide
- Help
-
(and 2 more)
Tagged with: