Jump to content

Recommended Posts

Posted

I have three optimizations about GG.

1. Add an API for converting byte array to string, such as

gg.bytesToString({0,104,0,105}, "utf-16");

, returns the string "Hi", similar to Java:

return new String ({0,104,0,105}, "utf-16"); 

2. When the address is negative number, it can automatically become positive number. When you enter -10 in the memory editing panel, the address will jump to 0xfffffffffffffff0. I hope to jump to 0xfffffff0.

3. Add API for file operating system to allow scripts to create folders.

Why do I need "bytesToString"?

I wrote a script for the game "WorldBox". Through the script, I can modify the equipment, talents and other attributes of the characters in the game. I pop up a menu to let users choose the characters to modify, so I read the character name from the memory. I use pure Lua implementation code, but the efficiency is very low. It will take a few seconds to read more text. I know this is very simple in Java, so I hope to add this function in the next version of GG.

Why do I want to automatically convert the address value of a negative number to a positive number?

I often encounter this situation: the value of the address 0x10001000 is 0x90001000. I want to get the value on the address 0x90001000.

Code:

local value = gg.getValues({{address = 0x10001000, flags = gg.TYPE_DWORD}})[1].value;

Now: value = -1879044096, the hexadecimal form is 0xffffffff90001000.

But I need 0x90001000 instead of 0xffffffff90001000. If I directly make address = 0xffffffff90001000, I will not get the value. My solution is to value << 32 >> 32, but I hope GG can avoid this problem in its design. My reason is, when the memory address is a negative number, the memory editor will turn it into a huge positive number. This is an astronomical number. Maybe the computer won't have such a large memory in 100 years. In terms of design, this is not in line with people's intuition.

Why do I need APIs related to file system operations?

Due to GG's security policy, "gg.execute" is disabled, which makes it impossible for me to create folders. When I replace the game archive, I need to create a new folder. This function is very important. I still have many designs that cannot be realized because of the lack of this function. Since this function may conflict with the security policy, I think it is necessary for me to talk about my views on the security policy. It's easy for scripts to do bad things. The person executing the script needs to evaluate the security himself. For malicious applications, it has no root permission, and only some ordinary permissions, such as accessing files, can still cause great damage. A script can access and modify memory, but cannot create folders. This script cannot do what an Android application can do. Of course, security measures also make sense. So I hope to allow the script to apply for the permission of a folder like the prompt when accessing the network. After the script has the permission of a folder, it can create a folder under this file path, traverse subdirectories and so on.

Finally, because my mother tongue is not English, I will miss a lot of information on the website when I don't actively translate, and I may make mistakes, also pardon me.

@Enyby

Posted
45 minutes ago, ctbear said:

1. Add an API for converting byte array to string

gg has already it. Use :Hi for utf-8 and ;Hi for utf-16 in gg.searchNumber().

gg.searchNumber(";Hi")

script will automatically convert into corresponding hex and will search it.

-----

54 minutes ago, ctbear said:

Why do I want to automatically convert the address value of a negative number to a positive number?

I often encounter this situation: the value of the address 0x10001000 is 0x90001000. I want to get the value on the address 0x90001000.

Code:

local value = gg.getValues({{address = 0x10001000, flags = gg.TYPE_DWORD}})[1].value;

Now: value = -1879044096, the hexadecimal form is 0xffffffff90001000.

You are trying to convert signed pointer values of armv-7 into positive address. But becuz of this one, gg should not convert all negative values into positive. There are not only pointers which use negative value.

you can try this short code to convert into positive hex.

local arch64 = gg.getTargetInfo().x64 --to check if arm32 or arm64

local function negativeToPositive(value)
  if not arch64 and value<0 then
    return value & 0xffffffff
  else
    return value
  end
end

local value = gg.getValues({{address = 0x10001000, flags = gg.TYPE_DWORD}})
value[1].value = negativeToPositive(value[1].value)
print(value[1].value)

-----

1 hour ago, ctbear said:

Add API for file operating system to allow scripts to create folders.

Lets wait for enyby.

Posted

Thank you for your patience. @Lover1500
For byte array to string, my requirements are different from your understanding. I have a pointer to the string. I determine the length of the string through the nearby values (usually, in the game developed by unity, the specific bytes recording the length of the string and the content of the string are continuous). At this time, I want to read the bytes in the memory and convert them into a string according to the character encoding. There is no need to search for strings in this process. For example, when the player modifies the pet name, I only know the position of the pointer pointing to the name, jump to the pointer address, read the memory, and convert the byte array into a string to know the new name.
With regard to the address value of negative numbers, I hope to avoid this situation from GG itself.
I have some more to add to my theme. @Enyby
About converting byte arrays to Strings:
In fact, reading memory and then converting it into a string through Lua code is still a problem in efficiency. So I hope to add a method to read strings directly from memory on the basis of adding the new string() method.
function gg.getString(address:number, length:number,charset:string):string
About automatically turning negative numbers to positive numbers when reading memory addresses:
I think what I said before is not rigorous. If a pointer value is negative, it will only occur in a 32-bit process, and the first bit of this value is 1 (value ≥ 0x80000000), so my request should be: in a 32-bit application, the address value requested by the script will be automatically converted to 32 bits. In other words, automatically remove the 32 bits at the top.
About adding file system related APIs:
I think it is reasonable for scripts to request permissions under some paths. For example, the application package currently selected by GG is named "com.Worldbox", so it should be understandable that the script requests the highest permissions of the two file paths "/ data/data/com.Worldbox" and "/sdcard/ Android/data/com.Worldbox". We have reason to believe that script operation of these directories is a part of the script function. I can think of two designs to achieve my goal. The first: the script requests to obtain all permissions under a directory. The player will receive a pop-up warning, and the player will decide whether to allow the script to operate the directory. This is similar to the dynamic request permission in Android applications. The second: by default, the script is allowed to access the "/data/data/package.name" and "/sdcard/Android/data/package.name" directories associated with the currently selected process. Add two APIs, such as "gg. getDDFile()" and "gg.getADFile()" to return the related objects of the above two folders. These objects should encapsulate the APIs related to file operation. I think the most important thing is to create a folder and traverse all the files and directories under the folder.
 

Posted

I can tell you that if what you require can be achieved through the lua implementation that GG uses it is doubtful something additional would be added to the GG API, instead you should write a lua function that achieves your goal.

  • Administrators
Posted

1. Noted.

2. Scripts use 64-bit values. So (-1 + 1) must be zero. You want (-1 + 1) = 2^32.

3. Noted.

Posted
8 hours ago, ctbear said:

1. Add an API for converting byte array to string, such as

gg.bytesToString({0,104,0,105}, "utf-16");

, returns the string "Hi", similar to Java:

return new String ({0,104,0,105}, "utf-16"); 

To add to discussion of this suggestion:

Lua strings by themselves are encoding-agnostic, so desired conversion is actually from bytes that represent string in one encoding to bytes that represent the same string in other encoding (utf-8 in this case, it seems). Input and output bytes of a hypothetical API function for such conversion can be in the form of strings or tables with values of bytes, but strings seem to be more reasonable option, because internally they are represented as array of bytes (as opposed to table with 8-byte integers).

It's also worth to mention that GG API already has bytes function that converts bytes from utf-8 encoding to specified one, so it may be not a bad idea to extend the function by adding new parameter for source encoding (how to interpret string that is passed to the function) instead of creating a new function.

As for what can be done currently, without such function:

Since there is "utf8" library with functionality to construct a string from list of character codepoints, to be able to convert bytes from, for example, UTF-16LE encoding to UTF-8, it is enough to implement parsing of bytes that represent string in UTF-16LE encoding to list of character codepoints. The list then just need to be passed to "utf8.char" function and it will return desired string in UTF-8 encoding.

Posted

The reply I just submitted disappeared. I don't know what happened.

12 hours ago, BadCase said:

I can tell you that if what you require can be achieved through the lua implementation that GG uses it is doubtful something additional would be added to the GG API, instead you should write a lua function that achieves your goal.

Yes, but converting byte array into string is a very common function. GG already has the method of "gg.bytes" to convert string into byte array, so it is common to add a function with the opposite process. These two APIs are brothers.

7 hours ago, CmP said:

It's also worth to mention that GG API already has bytes function that converts bytes from utf-8 encoding to specified one, so it may be not a bad idea to extend the function by adding new parameter for source encoding (how to interpret string that is passed to the function) instead of creating a new function.

Yes, there is such a process in my Lua script implementation. But I don't think it's necessary to separate this process. In most cases, we need a final string. If there are special circumstances, you can use GG Bytes gets the byte array.

9 hours ago, Enyby said:

1. Noted.

2. Scripts use 64-bit values. So (-1 + 1) must be zero. You want (-1 + 1) = 2^32.

3. Noted.

Thanks. @Enyby

The script uses a 64 bit value, while the pointer value of a 32-bit process is 32 bits, which is the cause of the problem. There are no errors and unreasonable places, but some checks may be performed when obtaining memory data. The reason is that I need to judge the address a lot in the script to ensure that there is no negative value. This makes me wonder who is reasonable to deal with this kind of thing? In a 32-bit process, the script requests to access an address value that is obviously out of bounds. The script does not check this, GG does not process it, and the operating system does nothing. Is it unreasonable that GG allows scripts to access a very large address value? (this address will never have data).

BadCase said:

12 hours ago, BadCase said:

I can tell you that if what you require can be achieved through the lua implementation that GG uses it is doubtful something additional would be added to the GG API

I can understand that. However, Lua script should be responsible for the code of our business logic, rather than some too basic functions and some code irrelevant to business logic. I think this kind of code is meaningless and redundant. Some functions should become the basic API of GG, and some checksum conversion processes should be built in by GG. So I hope that the address value can be corrected automatically in "gg.setvalues(), gg. getvalues(), gg.loadresults()". There is also a memory viewing panel, and entering - 10 (0xfffffffffffffffff0) can jump to 0xfffffff0. You can do this only when a 32-bit process is running. We can discuss this problem again, because I think the current design is unreasonable, but I can't give a very reasonable solution.

A few digressions: Does GG have an update plan? Will the plan under development by GG be released? Where can I see it?

Posted
10 hours ago, Enyby said:

2. Scripts use 64-bit values. So (-1 + 1) must be zero. You want (-1 + 1) = 2^32.

I used to check the address value every time I used the pointer value as an address to read data. Now I complete this function by replacing GG existing methods.

if (not gg.getTargetPackage()['x64']) then
    local verifyAddress = function(items)
        for i, v in ipairs(items) do
            if (v.address < 0) then v.address = v.address & 0xFFFFFFFF end;
        end
        return items;
    end
    local setValue, getValue, loadResults = gg.setValues, gg.getValue, gg.loadResults;
    gg.setValues = function(items) return setValue(verifyAddress(items)) end
    gg.getValue = function(items) return getValue(verifyAddress(items)) end
    gg.loadResults = function(items) return loadResults(verifyAddress(items)) end
end

Put this code at the head of the script file. I no longer need to actively check the address somewhere in the code.
However, the above code is required for each script that reads the pointer value from memory and then uses the pointer value as an address to perform jump, offset and other operations. Every script maker needs to write similar code.
This is not a good phenomenon.

Posted
13 hours ago, ctbear said:

I used to check the address value every time I used the pointer value as an address to read data. Now I complete this function by replacing GG existing methods.

if (not gg.getTargetPackage()['x64']) then
    local verifyAddress = function(items)
        for i, v in ipairs(items) do
            if (v.address < 0) then v.address = v.address & 0xFFFFFFFF end;
        end
        return items;
    end
    local setValue, getValue, loadResults = gg.setValues, gg.getValue, gg.loadResults;
    gg.setValues = function(items) return setValue(verifyAddress(items)) end
    gg.getValue = function(items) return getValue(verifyAddress(items)) end
    gg.loadResults = function(items) return loadResults(verifyAddress(items)) end
end

Put this code at the head of the script file. I no longer need to actively check the address somewhere in the code.
However, the above code is required for each script that reads the pointer value from memory and then uses the pointer value as an address to perform jump, offset and other operations. Every script maker needs to write similar code.
This is not a good phenomenon.

Make what you think is simple is easier. All APIs are sufficient in gg 101.1.

@EnybyI hope I'm not wrong.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In 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.