Jump to content

CmP

Contributor
  • Posts

    639
  • Joined

  • Last visited

  • Days Won

    43

Everything posted by CmP

  1. CmP

    ARM LDR

    Either with 3 instructions as @XEKEX has described in his post or with 1 instruction and 4 bytes for address that need to be not far from the instruction as I have mentioned in this post.
  2. CmP

    ARM LDR

    There are 12 bits in the instruction that are used for encoding offset from PC in bytes, so the limit is from -4095 to 4095. Reference: https://developer.arm.com/documentation/ddi0406/cb/Application-Level-Architecture/Instruction-Details/Alphabetical-list-of-instructions/LDR--literal-?lang=en
  3. CmP

    ARM LDR

    As other have mentioned above, such case requires more than one instruction. At least 8 bytes are required: 4 for LDR instruction and 4 for your new address that needs to be placed somewhere not far from LDR instruction. For example: Address | Instruction/Value 12345678 | LDR R0, [PC, #-4] 1234567C | 0xAFFDACA4
  4. CmP

    ARM LDR

    It can't be used, because it is a pseudo-instruction that requires more space than single instruction. Description and examples of LDR pseudo-instruction are present in ARM documentation: https://developer.arm.com/documentation/dui0802/b/A32-and-T32-Instructions/LDR-pseudo-instruction
  5. GG was unable to get information about selected process, that's why nil is returned by "getTargetInfo" function. The following isn't a proper fix of the issue, but it may allow you to try the script. Insert the following code after second line of script's code: if info == nil then info = {packageName = "unknown", x64 = false} end This will cause the script to work as if process has been identified as 32-bit. To force identification as 64-bit, correspondingly, "x64 = true" should be used.
  6. Just presence of two base64url-encoded parts separated by dot is not enough to conclude that string is JSON Web Token. In fact, your string isn't valid JWT as per step 4 of "Validating a JWT" section of RFC 7519 (https://www.rfc-editor.org/rfc/rfc7519#section-7.2).
  7. And loading saved list with option to set values can't really be faster than setting values directly by definition, since loading list in this case includes setting values. Also what makes loading saved list significantly slower than directly setting values is not setting values part, it's everything that needs to be done before that: reading and parsing saved list file, populating saved list with items.
  8. Then I can do it for you, since it turns out that you are not only wrong about performance of loading saved list and setting values, but are terribly wrong. Code that has been used for test: local savedListFilePath = "/mnt/windows/BstSharedFolder/com.cxinventor.file.explorer.txt" gg.clearList() local clockStart = os.clock() gg.loadList(savedListFilePath, gg.LOAD_VALUES) local loadListTime = os.clock() - clockStart local values = gg.getListItems() clockStart = os.clock() gg.setValues(values) local setValuesTime = os.clock() - clockStart print("gg.loadList time: " .. string.format("%.3f", loadListTime)) print("gg.setValues time: " .. string.format("%.3f", setValuesTime)) Saved list file that has been used for test: com.cxinventor.file.explorer.txt Result of the test: Interpretation of result: Loading list of 8192 4-byte values with option to set values with "loadList" API function took around 100x more time than setting the same values with "setValues" API function. So it's not a question of which method works faster. The question that remains is why did you, @zolotov_official0, post nonsense results instead of doing proper test.
  9. Do you even understand yourself these "results"? They are beyond nonsense. Loading list with 100000 values took less than a millisecond? Setting 100000 values took 5699 seconds? At least include the code that has been used for "testing".
  10. CmP

    Improve script

    Only because it's a suitable name for the variable, could have been any other suitable name with the same success. As for the reason of having the variable, it's a small optimization to not have to get the same value from table two times.
  11. Is this opinion based on facts or your subjective preferences? Almost all claims don't correspond to reality. 1. "ancient methods of patching". Restoring saved list has been there before scripts, so it's clearly the other way around. 2. "loadlists are faster". Based on what? Where are the results of performance tests? What's obvious without tests is that both methods are "instant" for editing hundreds or even few thousands values. 3. "loadlists are easier to update". Nothing prevents one from writing script in a way to be as easy updatable as possible, for example, with configuration table. And format of saved lists is far from being comfortable to work with manually. 4. "loadlists take less code". They do, at cost of losing all flexibility. How to restore only some of patched values with saved lists? To keep saved list for each desired state of values? What if there are tens of such states? And for some reason one of the most obvious disadvantages of saved lists isn't mentioned. It is required to (at least temporary) have a file for each one. So instead of directly patching values you suggest to create a file with saved list data and load it only to accomplish the same. If that isn't highly redundant approach, then I don't know what is.
  12. CmP

    Improve script

    Rewrite of the loop with inner loops with comments to main fixed issues (one mistake and one statement misplacement): local executable = {} for i = 1, #exe do local stringBytes = {} local startAddress = strPointer[i].value - 1 for j = 1, 150 do stringBytes[j] = {address = startAddress + j, flags = gg.TYPE_BYTE} end stringBytes = gg.getValues(stringBytes) local stringChars = {} for index, byte in ipairs(stringBytes) do local value = byte.value if value == 0 then -- comparison to string "0" is a mistake since value field is a number break end stringChars[index] = string.char(value & 0xFF) end local str = table.concat(stringChars) -- get final string only once after construction of table with characters is finished executable[i] = {address = exe[i].address, flags = gg.TYPE_DWORD, name = str} end gg.addListItems(executable)
  13. Before you proceed to try different or modified apks of the games, consider checking structure of installed files of games for which SH loads and for which doesn't to see, whether there are any patterns there. Root folder to start checking and comparing from is game's folder (or rather sub-folder that includes package name) in /data/app.
  14. I confirm this observation, "Stop, but not a breakpoint" seems to be unintended result. The logs also contain some details about what goes wrong when this happens. The first difference of interest is on the line that starts with "breakpoint:". "WSTOPSIG(5)" in logs with loaded SH means that process has been stopped because it received SIGTRAP signal, i.e. a breakpoint has been encountered. "WSTOPSIG(11)" in logs with failure, on the other hand, means that process has been stopped because it received SIGSEGV signal which is caused by invalid memory access. The second difference of interest, that allows to understand what caused invalid memory access, is on the following line that starts with "aarch64:" and contains information about values in registers. In logs with loaded SH value in "pc" (program counter) register is some existing address in process memory, for example, 0x703142802c from "loaded_shatteredpixel.txt". In logs with failure it is different, value in "pc" register is not an existing address in process memory, since it is clearly too small for that (for example, 0x8be3f0 from "failed_dreadrune.txt"). One possible interpretation of the differences described above is that in cases of failure to load SH something (maybe injected code) for some reason causes jump to invalid address that, as has been mentioned, causes SIGSEGV. Unfortunately, the logs by themselves don't allow to investigate further, that would most likely require using a debugger and would be significantly more complicated than analysis of logs.
  15. String contents doesn't matter. If two strings are compared, they are compared accordingly. It's a simple system. It gets more complicated (and confusing) when variety of implicit conversions may be involved, like for example in JavaScript.
  16. For "equal" it doesn't matter much, since comparison of strings will work as well. For "greater than" and "less than" it is correct solution and string comparison is not. String comparison works by comparing strings character-by-character in alphabetical order, so it's not applicable for comparing strings that represent versions.
  17. There is built-in way to ensure that version is not older than specified one, by using "gg.require" function. For example: gg.require("101.1") One other important note is NOT to compare version strings using operators ">" and "<" like it's done in some answers in this topic, because it won't work as expected in all cases. The condition "99.0" > "101.0" evaluates to true, but version 99.0 is not greater than 101.0. That's why to compare versions using by "greater than" or "less than" conditions "gg.VERSION_INT" constant that MAARS has mentioned in his answer should be used instead.
  18. The main issue is with the approach itself. Processing all results/values at once isn't going to work when there are millions of them. There is simply not enough memory that is available to Java part of the application neither to load millions of results at once nor to build a table in Lua script that represents millions of values. The solution is to process results/values in parts. Reasonable choice for part size is around 100k, since in practice GG can load 100k results fine in most cases. Another issue is related to efficiency as MAARS also mentioned above. First thing to avoid is using "gg.loadResults" function when it's not necessary. If it's applicable, use searches to get all results for processing, then process them in parts by getting results and removing them after the part is processed. Alternatively build a table with part of values to process, but then don't use results list, proceed to getting/setting values directly using corresponding API functions, then repeat for remaining parts.
  19. There is "one small issue" with this example. It implies that GG daemon would attach to itself. Not only it can't work like that, GG also doesn't show it's own daemon in process list (for the aforementioned reason). You clearly confused something in this example, but instead of admitting it, you have resorted to suggesting that critique of your example stems from "lack of knowledge". Such desperate attempts to "never make mistakes" is a sign of arrogance and an obstacle that prevents learning from one's own mistakes.
  20. This example doesn't make sense. Only memory of selected process can be modified. Scripts have no control over which process is selected. So the question remains, what does GG daemon have to do with this?
  21. How to "hook the GG daemon" from script for GG? Or what is this supposed to mean? Where in a process that is selected in GG would there be anything related to GG daemon? As for executing arbitrary code, the approach from your previous sentence already allows that, but of course code can only be executed in context of the process that is selected in GG. So what does GG daemon have to do with this?
  22. Most likely it was meant to configure GG to work with SELinux. Start screen, "Fix it" button, "Switch to work with SeLinux and restart the app" option. Reference: Android 11 My phone is rooted but game gaurdian not work properly I'm downloading latest version it's not fix (#axy2r12m)
  23. Having password that is required to execute a script for GG is not a good idea in general, but having limited password (by expiration time, amount of uses or something else) is a faulty one, because the limit can't be enforced anyhow. If a script for GG can be executed once, this is already enough to preserve all of the required data to execute it again unlimited amount of times regardless of password. In other words, password for a script for GG can only work as initial protection: either user doesn't know the password and won't be able to execute the script at all or user knows the password and with certain preparations will have unlimited access to the script after executing it one time.
  24. This is absolutely not the case. Here is an example of packet capture application for Android that can show users decrypted contents of HTTPS requests and responses from/to GG: https://play.google.com/store/apps/details?id=app.greyshirts.sslcapture Similarly, there are other applications for Android and a bunch of much more well-known ones for Windows, each of which has this capability.
  25. CmP

    arm edit

    There was a mistake in my last example. Edited the post with fixed version, so probably it should work as expected now.
×
×
  • 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.