How to stop of android cracked apks?
# android
n
How to stop of android cracked apks?
🤣 1
😶 7
v
You can’t stop it, but can make tedious to crack by enabling R8 (open source) or guardsquare (commercial)
d
And do most of your code in c with jni... Painful to work with, but even harder to reverse engineer.
s
For the vast majority of cases, just use an obfuscation tool like mentioned above and use a library like RootBeer to detect rooted devices. Clients are fundamentally insecure and you should always keep sensitive logic and data on the server side. Assume that all your client side code could be reverse engineered. Just make life difficult to deter hobbyists who are trying to poke around, if a large organisation or government wants to dig into your APK they will, and nothing you do will stop them. In most cases it's just not worth the pain of trying to write code in C or whatever.
m
@Sam
use a library like RootBeer to detect rooted devices
Or, alternatively, don't break your own app and annoy users, just like you don't break desktop and web apps just because someone has admin access on their PC (which is almost everyone).
s
@Marcin Wisniowski I don't disagree, generally though when I've worked on apps for very security conscious people then detection and blocking of rooted devices is something they demand.
m
I am aware, stakeholders may demand it, and that's fair. But it's just security theater, and I wouldn't suggest it as an answer to stopping cracked APKs.
🙄 1
For an example, putting a padlock icon on a checkout page is often a requirement and it does make people feel secure. But if someone asks "how do I take payments securely", saying "put a padlock image on the page" is not really a helpful answer. It's often done, and it has value in it's own way, but it's not an actual solution.
s
I'm not going to argue with you dude. There are legitimate reasons why wiping all customer data when root is detected could prevent certain attacks and to compare root detection to a padlock image is disingenuous. I'm going to extract myself from this conversation now because I don't think it's healthy or productive, have a good day.
m
Oh, this was just a friendly conversation, I did not mean to have an argument or anything, haha, sorry. Tone doesn't convey well over text.
There are legitimate reasons why wiping all customer data when root is detected could prevent certain attacks
Yep, totally agree! I just said it doesn't stop app piracy, that's all I'm saying.
compare root detection to a padlock image is disingenuous
Again, only in the context of stopping app piracy, should have been clearer, my bad. Padlock icons provide legitimate value (but not by making the process more secure), and root detection provides legitimate value (like the example you brought up, but not by stopping piracy). That's the parallel I was drawing.
d
Does anyone have any knowledge or opinion on why, in the android community and toolchains, that the concept of obfuscating code is held to be 'presumed universally agreed as fact' a critical form of security ? Im fairly new to android programming (3 yr) and this was one of the first major confusing things that still confuses me today. In my experience, its considered an anti-pattern to rely on obscurity for security, with strong evidence that it decreases overall security similar to the 'stickynote problem' and the 'I have RAID so I dont do Backups' problem -- e.g. people believe obfuscation provides security so they do not put any more effort into security -- leaving the 'front door locked but the back door wide open'. What still amazes me is that the android toolchain is so deeply connected rooted in obsfucation that its difficult to separate from other toolchain concepts such as minification. This is more obvious when attempting to build non-playstore APKs for embedded devices (e.g. NOT a consumer mass marketed phone , where the HW and SW are all managed together and the 'user' never sees the 'APKs' -- e.g. 'Kiosk' or 'embedded' devices. I personally have never found benefit, and have daily much pain, with 'obfuscation' - yet it is casually cited without refrence or aparent thought that 'Thats A Security Problem' <oppinion> As for APK 'cracks' wrt anti-piracy and company IP -- this has components of several issues, the objective ones being related to the above, and the subjective ones much more philosophical -- my personal philosophy is that the software business is primarily a service business not a IP business - that successful business models are derived by providing business services that are not achieved simply by 'cracking the software' -- ( bug fixes, maintenance, SLA contracts, consulting services, integrations to non-software-only services, convenience, confidence in organization expertiese etc). 'Pure' software is simply too ephemeral to base a reliable revenue stream on. From this perspective, 'piracy' is a form of marketing, something M.icrosoft has started to embrace in many ways. </oppinion>
m
why, in the android community and toolchains, that the concept of obfuscating code is held to be 'presumed universally agreed as fact' a critical form of security ?
It's not that obfuscation is perfect, it's just that it makes reverse engineering harder at almost no cost to the developer, so there is no reason not to use it. Plus, as is the case with ProGuard/R8, obfuscation is just one part of a minification process that increases performance and reduces app size, which you'd always want anyway. You are absolutely right that no one should rely on obfuscation for security, but it doesn't mean it doesn't help, and you can just consider it a side effect of minification if you want, where the actual goal is performance and app size.
As for piracy, I agree, and often the advice for people trying to stop piracy is just "don't bother, use your time to make a great product instead". It can be a problem for offline games though, where the game is certainly the product, and there is no service around it.
You say obfuscation causes problems for you, I'm curious what are they?
d
@Marcin Wisniowski -> agree with most everything. Why does obfuscation cause problems? when it works perfectly it does not 🙂 One set of cases where it fails is with tools that use reflection at runtime ( either annotation or class inspection). Say, Databinding libraries like Jackson. Everything works great at dev time, then buid/ship release all of a sudden a bunch of APIs fail with the equivalent of 'class not found' or 'field not found' Debugging, stack tracebacks, crashylitics, log tags, auto-generated database keys or schemas, annotation or reflection based parsers, 'creative' hacks by programmers that use this::class.name instead of Class::name debugging dex issues, debugging DI issues. And yes, there are, in theory, solutions to every one of these, individually, mostly on a case by case bass-is, and mostly require a phd isn R8/pro-guard or trust blindly copying gibberish from a web posting, or fiding out what version and minor version of gradle, android tools, and proguard/r8 corespond to what changes in the DSL, which progruad/r8 file is used, what mode does what in what variant. its the kind of issue that tends to creep up at the worse time -- just prior or just after release, and where the tools are not present or not as easily available ( e.g. in the field, in QA test grid, on Someone Elses Device) Can easily add days or weeks to total project schedule For what benefit ? Is it enough to make up for that ? "it depends:" for me its definitely NOT "something you'd always want anyway" Maybe the size reduction or performance gains are worth it -- that is if they really exist ... what is due to 'optimizations' vs 'obsfucation' -- and are they always cooperative ? is every obfuscation also a performance increase ? really? or are there some things that obscure code that make it go slower -- it seems like it would be much harder to guarentee every obsfucastion was also a performance improvement -- if its not, do you keep it or toss it ? This is different then say pure 'optimizations' which are agnostic about if they make the result harder or easer to reverse engineer. Specifically symbol mangling -- how mcuh does that really help runtime performance? Then theres the whole ';toss all the unused functions/classes'' aspect -- which I would have no problem with if it actually worked perfectly like it does in other languages that do this for optimization purposes. In java or kotlin that simply is not possible as long as there is either reflection or dynamic jar/dex loading. So it is known to be 'less than perfect' with the result of failure usually a app crash or equally bad. Yet, its on by default and belived to be universally good. That may have made great sense early on when you needed to get a 10MB java app down to 100k to fit into a phone's internal storage, now -- the devices are not 'Mini Crays' -- but even legacy ( say 4.4 kitkat) devices are usually beefy enough that to me it would make more sense to default to 'do no harm;' vs 'nuke everything hope for the best', and require more effort to squeeze out more bytes at the risk of app problems, vs putting the burden on both detecting and then fixing issues just to get where the app works properly. To me this seems like the wrong priority - correctness should come first, then optimizations, then obsfucation. (or swap the last 2 depending on bus needs).
m
Everything works great at dev time, then buid/ship release all of a sudden a bunch of APIs fail with the equivalent of 'class not found' or 'field not found'
Yeah, learned that the hard way too. Issues you bring up definitely happen in the real world, it's not perfect. Obviously everyone's experience is different, but in my experience these were never big issues, but occasional issues with a quick fix. I would assume that's the case for most devs. You say removing unused code breaks reflection / dynamic jar loading, and yet it's on by default, which is true, but at the same time it's considered a bad idea to use reflection on Android, and dynamic jar loading is completely forbidden on Google Play (where most apps end up). So I don't see an inconsistency in "universal beliefs" here: the defaults assume you don't do things that generally should't be done, and if you do them, that's fine, but then the defaults weren't made with you in mind.
devices are usually beefy enough
Developers going "eh, who cares about optimization, devices are powerful nowadays" is never a good thing and this shouldn't be a factor. If it makes sense for your use case, it's absolutely within your power to not use obfuscation, but I disagree it shouldn't be the default. Most apps don't use fancy reflection or dynamic code loading, nor should they (and if they do, it's through libraries that handle this correctly and have ProGuard rules built-in). And most devs don't want to make it easy to reverse engineer / copy their app. Ultimately it comes to how you weight the pros and cons. To me the issues you bring up, while absolutely real, are not a big deal and come up rarely (again, your experience may differ). For most companies it would be unthinkable to just publish your source code in the open , which you effectively do without obfuscation, and the occasional issues with it are insignificant compared to other everyday issues of development. I would be surprised if issues caused by obfuscation made a top 10 list of issues Android developers face in their work.
j
Does anyone have any knowledge or opinion on why, in the android community and toolchains, that the concept of obfuscating code is held to be 'presumed universally agreed as fact' a critical form of security ?
...that its difficult to separate from other toolchain concepts such as minification
In terms of ProGuard/R8, they've been in the toolchain for a long time now and so it's become standard for Android developers to use them but @Marcin Wisniowski's comment is important here w.r.t. ProGuard/R8: "you can just consider it a side effect of minification if you want, where the actual goal is performance and app size." It seems that there is a common misconception that the goal of ProGuard/R8 is obfuscation and with a cursory look at the final APK it may seem like that but the primary goal of these tools is minification, not security. ProGuard does 3 main things with the primary goal of shrinking/minification: * Renaming class, method, field names (name obfuscation) -> this makes the app smaller because the identifiers are shorter; it makes the app only slightly harder to reverse engineer. * Shrinking (tree-shaking) to remove unused classes, methods, fields -> this is especially useful to remove unused library code which can add a lot to an app. * Code optimization -> this is intended to shrink the code rather than obfuscate it; in some ways it's similar to code obfuscation since it does modify the code such that the result is not the same as the original, but that's not the primary goal. The primary goal of ProGuard optimizations is always to make smaller/faster code; not to make obfuscated code. ProGuard doesn't apply any code obfuscation specific techniques like control flow obfuscation, opaque predicates, virtualization etc.
👌 1
l
@Nurbanu Kahraman Spread self "cracked" apks that stop working after some time because of "crack detected" so people give up and finally buy the original.