Jump to content
Enyby

LUA scripting

Recommended Posts

Starting from version 8.28.0 GG have support of LUA scripts.

It can be loaded and run.

https://www.lua.org/manual/5.2/manual.html

Scripting Documentation: https://gameguardian.net/help/

Spoiler

 

GG function stored in table named gg.

You can print it for get short help.


print(gg)

gg =   table(5393242c): {
       [BUILD] = 6147
       [CACHE_DIR] = /data/data/catch_.me_.if_.you_.can_/cache
       [EXT_CACHE_DIR] = /mnt/sdcard/Android/data/catch_.me_.if_.you_.can_/cache
       [EXT_FILES_DIR] = /mnt/sdcard/Android/data/catch_.me_.if_.you_.can_/files
       [FILES_DIR] = /data/data/catch_.me_.if_.you_.can_/files
       [PACKAGE] = catch_.me_.if_.you_.can_
       [REGION_ANONYMOUS] = 32
       [REGION_ASHMEM] = 524288
       [REGION_BAD] = 131072
       [REGION_CODE_APP] = 16384
       [REGION_CODE_SYS] = 32768
       [REGION_C_ALLOC] = 4
       [REGION_C_BSS] = 16
       [REGION_C_DATA] = 8
       [REGION_C_HEAP] = 1
       [REGION_JAVA] = 65536
       [REGION_JAVA_HEAP] = 2
       [REGION_OTHER] = -1032320
       [REGION_PPSSPP] = 262144
       [REGION_STACK] = 64
       [SIGN_EQUAL] = 536870912
       [SIGN_FUZZY_EQUAL] = 536870912
       [SIGN_FUZZY_GREATER] = 67108864
       [SIGN_FUZZY_LESS] = 134217728
       [SIGN_FUZZY_NOT_EQUAL] = 268435456
       [SIGN_GREATER_OR_EQUAL] = 67108864
       [SIGN_LESS_OR_EQUAL] = 134217728
       [SIGN_NOT_EQUAL] = 268435456
       [TYPE_AUTO] = 127
       [TYPE_BYTE] = 1
       [TYPE_DOUBLE] = 64
       [TYPE_DWORD] = 4
       [TYPE_FLOAT] = 16
       [TYPE_QWORD] = 32
       [TYPE_WORD] = 2
       [TYPE_XOR] = 8
       [VERSION] = 8.31.0
       [VERSION_INT] = 83100
       [alert] = function: alert /* gg.alert(string text [, string positive = 'ok' [, string negative = nil [, string neutral = nil]]]) -> int: 0 = cancel, 1 = positive, 2 = negative, 3 = neutral */
       [choice] = function: choice /* gg.choice(table items [, string selected = nil [, string message = nil]]) -> string || nil */
       [clearResults] = function: clearResults /* gg.clearResults() -> nil */
       [copyMemory] = function: copyMemory /* gg.copyMemory(long from, long to, int bytes) -> true || string with error */
       [copyText] = function: copyText /* gg.copyText(string text [, bool fixLocale = true]) -> nil */
       [dumpMemory] = function: dumpMemory /* gg.dumpMemory(long from, long to, string dir) -> true || string with error */
       [editAll] = function: editAll /* gg.editAll(string value, int type) -> count of changed || string with error */
       [getFile] = function: getFile /* gg.getFile() -> string */
       [getLine] = function: getLine /* gg.getLine() -> int */
       [getLocale] = function: getLocale /* gg.getLocale() -> string */
       [getRanges] = function: getRanges /* gg.getRanges() -> int */
       [getResultCount] = function: getResultCount /* gg.getResultCount() -> long */
       [getResults] = function: getResults /* gg.getResults(int count) -> array || string with error */
       [getSpeed] = function: getSpeed /* gg.getSpeed() -> double */
       [getTargetInfo] = function: getTargetInfo /* gg.getTargetInfo() -> table || nil */
       [getTargetPackage] = function: getTargetPackage /* gg.getTargetPackage() -> string || nil */
       [getValuesRange] = function: getValuesRange /* gg.getValuesRange(table values) -> table || string with error */
       [getValues] = function: getValues /* gg.getValues(table values) -> table || string with error */
       [gotoAddress] = function: gotoAddress /* gg.gotoAddress(long address) -> nil */
       [isPackageInstalled] = function: isPackageInstalled /* gg.isPackageInstalled(string pkg) -> bool */
       [isProcessPaused] = function: isProcessPaused /* gg.isProcessPaused() -> bool */
       [isVisible] = function: isVisible /* gg.isVisible() -> bool */
       [multiChoice] = function: multiChoice /* gg.multiChoice(table items [, table selection = {} [, string message = nil]]) -> table || nil */
       [processKill] = function: processKill /* gg.processKill() -> bool */
       [processPause] = function: processPause /* gg.processPause() -> bool */
       [processResume] = function: processResume /* gg.processResume() -> bool */
       [processToggle] = function: processToggle /* gg.processToggle() -> bool */
       [prompt] = function: prompt /* gg.prompt(table prompts [, table defaults = {} [, table types = {} ]]) -> nil || table with keys from prompts and values from inputs */
       [removeResults] = function: removeResults /* gg.removeResults(table results) -> true || string with error */
       [searchAddress] = function: searchAddress /* gg.searchAddress(string text [, long mask = -1 [, int type = gg.TYPE_AUTO [, int sign = gg.SIGN_EQUAL [, long memoryFrom = 0 [, long memoryTo = -1]]]]]) -> true || string with error */
       [searchFuzzy] = function: searchFuzzy /* gg.searchFuzzy([string difference = '0' [, int type = gg.TYPE_AUTO [, int sign = gg.SIGN_FUZZY_EQUAL [, long memoryFrom = 0 [, long memoryTo = -1]]]]]) -> true || string with error */
       [searchNumber] = function: searchNumber /* gg.searchNumber(string text [, int type = gg.TYPE_AUTO [, bool encrypted = false [, int sign = gg.TYPE_EQUAL [, longmemoryFrom = 0 [, long memoryTo = -1]]]]]) -> true || string with error */
       [setRanges] = function: setRanges /* gg.setRanges(int ranges) -> nil */
       [setSpeed] = function: setSpeed /* gg.setSpeed(double speed) -> true || string with error */
       [setValues] = function: setValues /* gg.setValues(table values) -> true || string with error */
       [setVisible] = function: setVisible /* gg.setVisible(bool visible) -> nil */
       [skipRestoreState] = function: skipRestoreState /* gg.skipRestoreState() -> nil */
       [sleep] = function: sleep /* gg.sleep(int milliseconds) -> nil */
       [startFuzzy] = function: startFuzzy /* gg.startFuzzy([int type = gg.TYPE_AUTO [, long memoryFrom = 0 [, long memoryTo = -1]]]) -> true || string with error */
       [timeJump] = function: timeJump /* gg.timeJump(string time) -> true || string with error */
       [toast] = function: toast /* gg.toast(string text [, bool fast = false]) -> nil */
}

In future we add help with examples.

 

 

Share this post


Link to post
Share on other sites

Interesting.

One may just load Lua script and only input the value.

Other options like type and region will be automatically set.

Also I think it could automatically calculate and add the other values based on the value found with stored offsets in it, makes many things easier.

Share this post


Link to post
Share on other sites

Yes. And can be created automated calculator/tool based on gg.

Present function 'toast', 'alert' and 'prompt' which allow create some dialogs for user.

For example 'Input gold amount:' and use this value for make search.

data = gg.prompt({[1]='Search value', [2]='Replace value', [3]='Max count'}, {[1]='123', [2]='456', [3]='321'})
gg.searchNumber(data[1], gg.TYPE_DWORD, false, gg.SIGN_EQUAL, 0, -1)
found = gg.getResultCount()
gg.alert('We found: '..found)
gg.getResults(data[3])
replaced = gg.editAll(data[2], gg.TYPE_DWORD)
gg.alert('We replaced: '..replaced)
gg.alert('Summary: We search '..data[1]..', found '..found..', replaced '..replaced..' to '..data[2]..' with max count '..data[3]..';')
print('Script ended.')

bandicam 2017-07-17 07-41-24-722.pngbandicam 2017-07-17 07-41-33-494.pngbandicam 2017-07-17 07-41-38-267.pngbandicam 2017-07-17 07-41-41-348.pngbandicam 2017-07-17 07-41-45-676.pngbandicam 2017-07-17 07-41-58-375.pngbandicam 2017-07-17 07-42-01-589.png

Share this post


Link to post
Share on other sites

Haha, that's what I like.

I will try to learn it.

Will make Nice scripts.

Share this post


Link to post
Share on other sites
d = gg.prompt({A='A', B='B', C='C'}, {A='123', B='456', C='789'})
gg.alert('A + B - 3*C = '..(d.A + d.B - 3*d.C))

bandicam 2017-07-17 08-17-04-293.pngbandicam 2017-07-17 08-17-08-790.png

Share this post


Link to post
Share on other sites

Script can work with files. It can be useful for create complicated things.

API to GG will be edited and extend in future releases. Now present only basic features for scripts.

Scripts can be used for automate some things like lot of same actions. For example for Asphalt 8 Enduro Double Down can be written automated scripts which make hundred of replace in one run.

Share this post


Link to post
Share on other sites

I found it pretty easy.

Just copied the data from post above into a text file then replaced the ".txt" extention to ".Lua" and then went to search tab and rap on "more" (three lines) button and "excute script".

So simple.

I think by working with these samples, it's easily possible to make a good one for a game.

On it now.

 

Screenshot_20170717-095713.png

Screenshot_20170717-095723.png

Screenshot_20170717-095733.png

Screenshot_20170717-095741.png

Screenshot_20170717-095748.png

Share this post


Link to post
Share on other sites

No need change extension. You can load .txt files. Or any others.

Share this post


Link to post
Share on other sites

One thing, why the position of "C" and "B" are flipped?

The code is OK as I'm seeing it.

Share this post


Link to post
Share on other sites

Lua table not specified order of fields. Maybe in future I try fix this.

I make this support of scripting in last 3-4 weeks. It is first public release. Something can be not good or broken. In future we try improve it.

Share this post


Link to post
Share on other sites

Thanks for the hard work.

I will try to help too.

Share this post


Link to post
Share on other sites

Script for hack Asphalt 8 nitro:

gg.searchNumber('2;8;10;12;15;20;25;30:61', gg.TYPE_FLOAT, false, gg.SIGN_EQUAL, 0, -1)
gg.getResults(100)
print('Replaced: ', gg.editAll('1000', gg.TYPE_FLOAT))
print('Nitro hacked!')

bandicam 2017-07-17 08-49-37-459.pngbandicam 2017-07-17 08-49-50-457.pngbandicam 2017-07-17 08-50-24-287.png

Share this post


Link to post
Share on other sites

I'm working on hack for Quadropus Game.

I made it to hack the input value as double and Encrypted.

But I'm stuck in this situation:

The user needs get back into game and change the value and then come back GG and enter the new value.

Will this work? :

print('go to game and change the value and then load script again') 

So it loads the script again and it search in the found results...or it makes a new search?

_______________________________________________
added 3 minutes later

I want to make an IF Statement:

1_If found 1 value, edit value to 10000000000

2_if Not found 1 value, print'('go to game and change the value, then load the script again')

 

Possible? If yes, how?

Share this post


Link to post
Share on other sites

Depends on your logic. Read Lua manual reference posted in first post.

if gg.getResultCount() == 0 then
	gg.alert('Find something and run script again!')
else
	gg.alert('Wow! You found '..gg.getResultCount()..' results! Not bad!')
	gg.toast('You cool!')
end

bandicam 2017-07-17 09-07-47-077.pngbandicam 2017-07-17 09-08-16-419.pngbandicam 2017-07-17 09-08-18-478.png

Share this post


Link to post
Share on other sites

You can store state to file and load on each start script. Or wait for some actions. In last case user do not need run script each time.

But this not always possible.

function sleep(s)
  local ntime = os.clock() + s
  repeat until os.clock() > ntime
end

while gg.getResultCount() < 10 do
	c = gg.getResultCount()
	gg.toast('I wait for you! Only '..(10 - c)..' need!', true)
	sleep(3)
end

gg.alert('You done!')

bandicam 2017-07-17 09-16-53-901.pngbandicam 2017-07-17 09-17-08-872.png

Share this post


Link to post
Share on other sites

I have faced a problem now.

My code is this:

d = gg.prompt({A='Number of Orbs Or Dooblins'}, {A='0,})
gg.toast ('Quadropus 2.0.48 Hack by Backlift')
gg.setRanges ( gg.REGION_C_ALLOC)
gg.searchNumber (data[A], gg.TYPE_DOUBLE, true, gg.SIGN_EQUAL, 0, -1)
if gg.getResultCount() == 1 then gg.editAll('100000000', gg.TYPE_DOUBLE) gg.alert ('Hacking Done, Enjoy)
else gg.alert ('Go to game and change the value, then load the script again to continue')
end

 

 

Theorically it should:

1_open a prompt screen to user to get value and meanwhile, toast a message

2_after value input, set range to (Ca) and search the value as Encrypted Double

3_if found 1 value Change it to a very high number,  if not, tell user to change the value and reload script

 

 

But I get errors:

Script ended:
Script error: org.luaj.vm2.LuaError: load /sdcard/Notes/Quadropus 2.0.48 Script by Backlift.lua: org.luaj.vm2.LuaError: /sdcard/Notes/Quadropus 2.0.48 Script by Backlift.lua:1: unfinished string
    at org.luaj.vm2.LuaValue.error(LuaValue.java:1051)
    at org.luaj.vm2.Globals.loadfile(Globals.java:185)
    at android.ext.Script.runScript(Script.java:1035)
    at android.ext.Script.access$8(Script.java:1032)
    at android.ext.Script$ScriptThread.run(Script.java:998)
Caused by: org.luaj.vm2.LuaError: /sdcard/Notes/Quadropus 2.0.48 Script by Backlift.lua:1: unfinished string
    at org.luaj.vm2.compiler.LexState.lexerror(LexState.java:266)
    at org.luaj.vm2.compiler.LexState.read_string(LexState.java:451)
    at org.luaj.vm2.compiler.LexState.llex(LexState.java:611)
    at org.luaj.vm2.compiler.LexState.next(LexState.java:673)
    at org.luaj.vm2.compiler.LexState.checknext(LexState.java:822)
    at org.luaj.vm2.compiler.LexState.recfield(LexState.java:1129)
    at org.luaj.vm2.compiler.LexState.constructor(LexState.java:1167)
    at org.luaj.vm2.compiler.LexState.simpleexp(LexState.java:1418)
    at org.luaj.vm2.compiler.LexState.subexpr(LexState.java:1523)
    at org.luaj.vm2.compiler.LexState.expr(LexState.java:1541)
    at org.luaj.vm2.compiler.LexState.explist(LexState.java:1261)
    at org.luaj.vm2.compiler.LexState.funcargs(LexState.java:1278)
    at org.luaj.vm2.compiler.LexState.suffixedexp(LexState.java:1373)
    at org.luaj.vm2.compiler.LexState.simpleexp(LexState.java:1427)
    at org.luaj.vm2.compiler.LexState.subexpr(LexState.java:1523)
    at org.luaj.vm2.compiler.LexState.expr(LexState.java:1541)
    at org.luaj.vm2.compiler.LexState.explist(LexState.java:1258)
    at org.luaj.vm2.compiler.LexState.assignment(LexState.java:1636)
    at org.luaj.vm2.compiler.LexState.exprstat(LexState.java:1958)
    at org.luaj.vm2.compiler.LexState.statement(LexState.java:2055)
    at org.luaj.vm2.compiler.LexState.statlist(LexState.java:2072)
    at org.luaj.vm2.compiler.LexState.mainfunc(LexState.java:2088)
    at org.luaj.vm2.compiler.LuaC$CompileState.luaY_parser(LuaC.java:129)
    at org.luaj.vm2.compiler.LuaC$CompileState.access$0(LuaC.java:120)
    at org.luaj.vm2.compiler.LuaC.compile(LuaC.java:99)
    at org.luaj.vm2.Globals.compilePrototype(Globals.java:304)
    at org.luaj.vm2.Globals.loadPrototype(Globals.java:283)
    at org.luaj.vm2.Globals.load(Globals.java:254)
    at org.luaj.vm2.Globals.loadfile(Globals.java:183)
    ... 3 more

 

Share this post


Link to post
Share on other sites

Script can do some actions in background. For example every 5 seconds search some values and change it. Without user actions. In background.

_______________________________________________
added 0 minutes later
1 minute ago, Backlift said:

d = gg.prompt({A='Number of Orbs Or Dooblins'}, {A='0,})

quote not closed.

Share this post


Link to post
Share on other sites

{A='0',}

Fixed it, but still having issues

Share this post


Link to post
Share on other sites
7 minutes ago, Backlift said:

gg.alert ('Hacking Done, Enjoy)

Same.

_______________________________________________
added 1 minute later
8 minutes ago, Backlift said:

gg.searchNumber (data[A], gg.TYPE_DOUBLE, true, gg.SIGN_EQUAL, 0, -1)

data[A] but var data not defined. You used var d, not data before.

Share this post


Link to post
Share on other sites
1 minute ago, Enyby said:

Same.

Thanks, it executed.

I will keep my eyes on codes more aggressively from now.

Testing...

Share this post


Link to post
Share on other sites

And wrong format. Must be or `d.A` or `d['A']`.

_______________________________________________
added 1 minute later
d = gg.prompt({A='Number of Orbs Or Dooblins'}, {A='0'})
gg.toast ('Quadropus 2.0.48 Hack by Backlift')
gg.setRanges ( gg.REGION_C_ALLOC)
gg.searchNumber (d.A, gg.TYPE_DOUBLE, true, gg.SIGN_EQUAL, 0, -1)
if gg.getResultCount() == 1 then 
	gg.editAll('100000000', gg.TYPE_DOUBLE) 
	gg.alert ('Hacking Done, Enjoy')
else 
	gg.alert ('Go to game and change the value, then load the script again to continue')
end 

 

Share this post


Link to post
Share on other sites
1 minute ago, Enyby said:

And wrong format. Must be or `d.A` or `d['A']`.

Yeah it crashed when started searching.

Fixed that too, made it d['A']

Testing

_______________________________________________
added 3 minutes later

It is working good, but, 

I made the code to only search (c++ Alloc) range and the done it's job, in setting only (Ca) is checked but I'm getting results from other regions too, like Java heap.

 

Screenshot_20170717-111519.png

Screenshot_20170717-111505.png

Share this post


Link to post
Share on other sites

It searched the wrong region, didn't found the value.

_______________________________________________
added 1 minute later

Only searched the Java heap, however, I set it to search only C++ Alloc.

Share this post


Link to post
Share on other sites
1 minute ago, Enyby said:

:) Bug. Will be fixed in next release.

Yeah definitely a bug 😅

made it to search java heap, it gived results about c++ Alloc.😁

 

I copied 5 lines of values and had 2 bugs 😂, GG has millions of code lines, it must be an extreme hard task.

Your effort and patience (GG Team) is definitely admirable.

Thanks again.

Screenshot_20170717-112437.png

Screenshot_20170717-112431.png

Share this post


Link to post
Share on other sites

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

×