How is this possible?

This is a new and novel hack (not the normal IAP hacks).  I know I should be happy that my game is popular enough to get hacked like this but somehow I’m not…

I’m curious, how is it possible to change in memory run-time values from another app when I thought Android (and iOS) ran all apps sand-boxed? (i assume you need at least root access)

https://www.youtube.com/watch?v=iWhF2tfcLGU

I would of hoped that Corona would block access to internal variables from threads other than it’s own.  What would be Corona’s recommendation to prevent this sort of thing?

Yes, I could obfuscate doubles in encrypted strings but this would require a lot of encoding/decoding whenever maths were involved - which would be in thousands of places for in game currency!

Sorry man.

I am guessing that is a rooted Android device,  and I’m pretty sure as long as they are willing to root their device they can pretty much do anything with memory they want if they have the Skillz or someone has bundled up tools to help them do it.

I always figured that if I ever get as far as publishing a useful game, I’d add a IAP of ‘Cheat’ and see if it got me anywhere :slight_smile:

(Caveat that Cheat excludes you from Hi-Scores, Achievements etc.)

For currency games it doesn’t help, but for puzzles etc, why not!

You could do one thing to make this a little more difficult for them.

Right now, my guess is that your GUI elements are polling the values or they are the values:

-- Polling local gold = 1000 local goldLabel = display.newRect( ... ) goldLabel.text = gold local function enterFrame() goldLabel.text = gold end Runtime:addEventListener( "enterFrame", enterFrame )

If you do something like this, then they can hexedit values till they find ‘gold’ and when they change it the label updates, giving them a positive ‘found it’ feedback.

So, do this instead:

-- NOT Polling local gold = 1000 local lastGold = 1000 local goldLabel = display.newRect( ... ) goldLabel.text = gold local function setGold( newValue ) gold = newValue lastGold = newValue goldLabel.text = newValue end local function getGold() if( lastGold ~= gold ) then gold = lastGold end return gold end local function incrGold( value ) lastGold = lastGold + value gold = lastGold goldLabel.text = gold return gold end ... later local tmpGold = incrGold( 10 ) ... local tmpGold = incrGold( -10 )

This does a couple things:

  1. Now they cannot hex set the gold value and get immediate feedback.
  2. Also, having a ‘lastGold’ value helps protect against hacks.  It isn’t great, but it is opaque and a bit more difficult to work out.

You could even get meaner:

local function getGold() if( lastGold ~= gold ) then gold = 0 lastGold = 0 end return gold end local function incrGold( value ) if( lastGold ~= gold ) then gold = 0 lastGold = 0 return 0 end lastGold = lastGold + value gold = lastGold goldLabel.text = gold return gold end

Hey Roaming… from the video what they are doing is working out the actual core double values for (in my case) money, gold and diamonds.  I could store them in obfuscated strings but then things like money = money - 1000 becomes much more complicated and prone to errors.

I could force online playing only and store these values on my server but my players love that they can actually play offline and that is something I am not keen on changing.

If corona blocked any threads that were not owned by corona that would negate this type of hack completely

I don’t know if you want to do this, but you could always report this users activity.  

I’m not sure Google would do anything about it, but s/he is  (essentially) teaching folks to bypass the GooglePlay monetization system.

https://www.youtube.com/channel/UCX5BYlgl3gj54Oppmghkj2w/about

  1. I don’t see them getting the variable names unless you call your variables’Value’?

  2. If they are not getting actual variable names, i.e. They are hunting for values, changing them, and then checking to see if that updated the GUI, then… my suggestion of:

  • using get(), set(), and incr()  PLUS
  • Phantom copies of key variables PLUS
  • Only updating GUI from set() and incr()

will help protect you a bit more.

If they are running a ROOTed Android, and running an app as SU, then nothing Corona does will prevent this.  They are literally reading and writing memory.

I’d get meaner :slight_smile:  

 If money \> unreasonableamount  then      start\_weirdly\_killing\_characters()    mess\_up\_inventory()    If been\_playing \> 2weeks        send\_happy\_cheating\_message   end end

Easy to get around (set to <unreasonable_amount) but a great deal of fun to mess with them :slight_smile:   Set version code to C when people complain :slight_smile:

This guy seems to make it his mission to hack games… we will call him low-life pond-dwelling wanker scum.  I guess I should be flattered!

I encrypt my local game saves and all my internet data transfers.  I guess I need to encrypt all my local in memory variables too!

I gotta go, but I’m pretty sure you can prevent casual hexedit hacking of your app with minimal changes focused on indirect access(), non-polling GUI updates, and phantom values for checking.

This shouldn’t cost too much effort or make coding too painful.  It is simply a balance of whether you think it is worthwhile.

Again, sorry this is happening to you, but scumbags and jerkoffs abound (harsh words I know, but those who steal our hardwork deserve no consideration.)

Intriguing idea.  A encryption protected get()/set() varaible system…

Up till now I allowed fraudulent purchases (as this is rife in certain countries) as this was actually a positive for my game.  My game relies on players creating cities and players making fraudulent purchases to create great cities actually promotes average players making legitimate IAPs to replicate.

My stance is players that make fraudulent purchases will never actually make a real purchase so it is not affecting my income stream.

I will work on protecting my in memory variables as this is a new attack vector that is relatively easy to  circumvent in pure LUA.  I’m thinking a simple base64 string representation of the double value would stop this dead.  Just a question of coding the get()/set() so it doesn’t interfere with normal game logic.  A proper class and properties implementation (as per .NET) would make this so simple!  

Why dont you try GGData module for Corona?
You can find it on github.

I saw this on the marketplace store

https://marketplace.coronalabs.com/plugin/save

Does that seem like it would help or can a rooted Android device bypass that safeguard technique as well?

Hey guys, thank you for your suggestions but that is for persisting data.  My persisted/network data is already encrypted.

The video I showed is in memory hacking.  Imagine you had a variable that tracked money in your app and you had 100 money, the hacking software scans all heap/stack addresses matching 100 and modifies them.

It is very difficult to stop hackers, I wrote a lot of the original versions of GameShark and Action Replay and we wrote extensive code to find infinite lives etc. you can try all the things in this thread but I can tell you we could pretty much hack anything for GameShark/Action Replay, Nintendo and Sony tried all sorts of things to stop us but we usually found a way round it.

How hard would it be to succeed in hacking an iOS device in a similar way if it were jailbroken?

Jail broken iOS is the same as rooted Android.