Thursday, October 27, 2011

it's been a while, but antilvl 1.4.0 is finally released. i did not plan to make another release, but there were some show-stopping bugs in the linux version and some other things that were just embarrassing. :D

Monday, October 17, 2011

if an app requires an unlocker key app, it's likely there will be protection hidden in the key. perhaps the key performs a checksum on the main app, or the key stores pre-computed checksum values for the main app. this is easy to add if you're a developer and is somewhat tricky to handle as a cracker. the reason is the cracker must know how to calculate the checksums himself and inject those values into the app.

calculating checksums is a way to determine if your apk has been modified. there are at least four easy methods to do this. they are: md5, sha1, crc32 and adler32. once you run these guys on your apk you will have either a long number or a byte array. of course, you can't store the checksum in your main app since you wont know the checksum until the app is finished. for this reason, either the calculations or just the checksum values must be stored in another app signed by the same certificate, such as a key / unlocker app.

here's some example code of what the protection may look like in java:

and here's what the above java looks like in smali, so you have some idea what to look for. cracking this will require you to write an app that simulates how the app calculates the checksum. then you'll have to come up with a clever way to get the value into the smali. if it's a long number, this is fairly easy, but if it's a byte array, you may need to use base64 encoding or some other method to make a byte array safe for literal strings. the keywords to look for, of course, are md5, sha1, crc32 and adler32. they may not appear at all if the developer is using reflection to make the method calls.

if you look at isDRMDone() you'll see that it's basically a big switch. input of 0 or 1 counts as valid. everything else is some kind of error. so we just need to make sure checkLicense returns 1 and doesn't call anything else that may have side effects (timeouts, checking to see if verizon app store is installed, etc..).

checkLicense() is defined in com/verizon/vcast/apps/LicenseAuthenticator.smali. after modification it looks like:

if you're a developer, depending on how they implement the insertion of their drm, it may still be possible to use classical protection / anti-tampering techniques. i'd like to know. but really though, don't waste your time on protection. i'm not blasting verizon or amazon or google for weak security. real effort should be spent improving the program, not slowing down (because you can't stop) crackers. if you want money, use ads.

Wednesday, June 8, 2011

one way an app will try to detect if it has been tampered with is to look at classes.dex inside the apk. just so you know, java code is compiled to java .class files, which is then transformed by dx into classes.dex. this one file contains all the compiled code of an app. once the code is finished and the app is ready to be published, properties of the file such as the size or crc (cyclic redundancy check) can be determined and then stored inside the resources of the app.

when the app runs, it can compare the stored values with the actual values of the classes.dex file. if they do not match, then the code was likely tampered with.

note that we're using zipentry here, but we could also use jarentry and jarfile. you can't simply look for getCrc() and feel safe either, because the method could be called with reflection.

.method private crcTest()V
.locals 7
.annotation system Ldalvik/annotation/Throws;
value = {
Ljava/io/IOException;
}
.end annotation
.prologue
.line 599
const/4 v2, 0x0
.line 602
# modified will be set to true if classes.dex crc is not what it should be
.local v2, modified:Z
sget-object v5, Lcom/lohan/testtarget/Main;->MyContext:Landroid/content/Context;
# get the crc value from string resources
const v6, 0x7f040002
invoke-virtual {v5, v6}, Landroid/content/Context;->getString(I)Ljava/lang/String;
move-result-object v5
# convert it to a long since ZipEntry.getCrc gives us long
invoke-static {v5}, Ljava/lang/Long;->parseLong(Ljava/lang/String;)J
move-result-wide v0
.line 604
.local v0, dexCrc:J
new-instance v4, Ljava/util/zip/ZipFile;
sget-object v5, Lcom/lohan/testtarget/Main;->MyContext:Landroid/content/Context;
# get the path to the apk on the system
invoke-virtual {v5}, Landroid/content/Context;->getPackageCodePath()Ljava/lang/String;
move-result-object v5
invoke-direct {v4, v5}, Ljava/util/zip/ZipFile;->(Ljava/lang/String;)V
.line 605
.local v4, zf:Ljava/util/zip/ZipFile;
# get classes.dex entry from our apk
const-string v5, "classes.dex"
invoke-virtual {v4, v5}, Ljava/util/zip/ZipFile;->getEntry(Ljava/lang/String;)Ljava/util/zip/ZipEntry;
move-result-object v3
.line 607
.local v3, ze:Ljava/util/zip/ZipEntry;
# you could crack here by providing v5 with the correct
# long value. this may be easier if later logic is convoluted
# or if the result is stored in a class variable and acted
# on later. you can write your own java program to get the

Monday, June 6, 2011

one way to figure out what an app is doing is to use a debugger so you can step through line by line. apktool makes it possible to debug apps to which you do not have the source, and you also have to setup a few other things covered in lesson 1 of the way of the android crack tutorials.

some apps try to protect against this and there are two techniques of doing so. the first is to check the android manifest to see if the app is set to debuggable. the java code would look something like this:

Wednesday, April 27, 2011

jesusfreke, the guy who wrote smali/baksmali, has some nice documentation on the smali syntax on the wiki for his project: http://code.google.com/p/smali/w/list i learned some stuff! thanks jesusfreke.

Monday, April 18, 2011

thanks to Notion and SuRViVe pointing out some instances of the lvl not being properly identified. i removed some requirements to match some key files that weren't likely necessary and were not being found recently. two new anti-cracking methods have been added and testtarget was updated appropriately.

Thursday, March 31, 2011

as i wrote back in another post about anti-cracking technique examples, one method that is often used is getinstallerpackagename(). if the apk is installed from adb, it will be null, but if it's installed from the market it will be com.google.android.feedback. antilvl is well aware of this already, but there is an easier solution for when you're in a hurry. i learned it reading this post at tim's fantastic blog on reversing. he's not affiliated with me and for all i know he's an upstanding white hat who just loves hacking android.

all you need is adb. just give it this command either in a shell or as:

adb install -i com.google.android.feedback com.protected.app

this will setup com.google.android.feedback as the installer for the com.protected.app. if you're not sure what the app name is for a given apk, just use aapt, from the android-sdk. ex: aapt d --values badging someapk.apk

Thursday, March 24, 2011

i've noticed some interest about a file that antilvl sometimes uses when cracking a program. it's called smalihook and it's purpose is to provide "hook" (actually replacement) methods for things like getting device id or signature. it's not really anything special, unless you actually modify the places in the app that make use of certain function calls. there is also a smalihook.java floating around that is actually a badly decompiled, broken version. i'd rather people have the real thing.

the variable strings that start with "%!" (ex: %!AppPackage%) are for antilvl to replace with the actual information when it copies it over.

if you want to use any of the functions here you can simply use antilvl.

if you just want to spoof your android_id or getdeviceid, try this: http://strazzere.com/blog/?p=217

Sunday, February 20, 2011

thanks to Ádám Tóth for creating a dark themed version. i've linked to it next to the main version.

update: 11/10/2011:

thanks to Jho for pointing out how to get code folding to work. i updated the syntax file and made a few other tweaks. the link and picture have been updated and here are the instructions for installing (tested with v5.9.6.1):
View -> User-Defined Dialogue...

Click Import

Select smali_npp.xml
no picture here, use imagination

There will be a message box that says "Import successful."
Any new files you open should have syntax highlighting.

there are many limitations for notepad++'s user defined language. i could not get many tokens to highlight correctly, or as well as ultraedit or the highlighter used on this blog. perhaps a full lexer plugin could handle it. if you write one or make improvements to this xml, let me know.

here's one that i modified slightly that shows a basic hello world app with a standard main method. also, in the comments you will see a way to quickly compile and run a smali file. this is sometimes quite useful in testing your code:

for the android reverser and more-so for one wishing to modify an apk, it is sometimes necessary to write large amounts of smali code. by large i mean over 10 lines, with a lot of control flow and api calls. keeping track of all those gotos, catches, switches, etc. is cumbersome unless you want to be some kind of smali wizard.

i wrote a class for antilvl to handle function hooks (really just replacements), and there is a lot of scary logic in there to have written manually. i've found it's best to create an android project in eclipse, write the code in java and decompile it into smali. the setup is easy. just download eclipse and install the ADT android plugin.

i recommend creating an android project just to prototype code. also, with the android plugin, when you run code it can either execute on your phone or start up an emulator. this has saved me tons of time while exploring various under-documented android api calls or digging around system settings or just trying to get a large bit of smali working.

writing code in java and then seeing it as smali will aid in understanding smali since you'll already be familiar with the functionality of the code. you can also automate the process of getting the smali file out by writing a shell script or batch file. here's an example batch file:

Sunday, February 13, 2011

also had to do some major refactoring so people could make use of the source once it's released, and i think i got most of the kinks out.

while working on this, i noticed a few more apps that were using string encryption. maybe it will start to get popular? i wrote a proof of concept decryptor just to see how feasible it would be to convert dex to java .class files and run the apk's own methods to decrypt the strings. it worked but i want to make something more general. here's my idea:

start with an apk and disassemble

chose to decode literal strings (ex: const-string "some-encoded-string") or assume strings are the result of a function call (ex: invoke-static LStringHolder;->getString(v0)).

show all lines that match the above selection and allow for regex filtering. this way, if you pick literal strings and not all strings are encoded, you can filter for just the ones that are

decode strings by one of several methods: run the function, in the case of function-call encryption, built-in stuff like base 64, etc. or by using reflection on the classes of the apk. this way if every literal string in the apk is decoded through some function, i could use dex2jar to get the java class, dynamically load that and run each string through it.

the goal is to make the tool generic enough so that it's useful in the most situations. shouldn't be too hard. half of the work will be making my patching and apk libraries more generic and useful, so it wont be a total waste of time.

Monday, February 7, 2011

several have asked for antilvl's source to use it in ways i could not have imagined. it seems it's true purpose is more of a general semi-automated apk patcher, which is fine. i'm thinking i should rename it and make it more general purpose, while still including the lvl-patching and anticracking-patching information.

i'm also getting a lot of fun out of this little shell extension for windows to get explorer to replace an apk's icon with the actual icon for the app inside: http://code.google.com/p/apkshellext/

Friday, February 4, 2011

for lesson 2 i'm using html and javascript to make things more readable. to test the template i rewrote and updated lesson 1 of way of the android cracker to include stuff on threads, stack dumps and using jdb with android apps. it's also in html now and the code looks much prettier. i'll rewrite lesson 0 if i ever get around to it.

finished antilvl 1.1. it's kind of scary how well it's working. now that the anti-cracking methods are added in, it should be able to crack the android license verification library and any type of protection i have ever seen, including a few i haven't.

the number of modifications done to an app has increased a bit, so there may be some mix up. let me know how it works for you.

here's the main gist of the changes:

introduced many anti-cracking bypassing methods. it's better than me!

improved --sign-only behavior, though it still errors every other time

Wednesday, January 26, 2011

to facilitate the eye-pleasing posting of smali on blogs and html and such, here is a brush for syntaxhighlighter. i'm in the process of converting my previous tutorials to html and they use this instead of screen shots of code or simple green coloring. it looks much nicer.

the problem could be non-standard resource qualifiers. it affects current versions of apktool (1.3.2), but may be fixed in a later version. the solution is to decomile using --keep-broken-res and fix the xml file manually. for an explanation of how to do this, read this issue by the developer himself: http://code.google.com/p/android-apktool/issues/detail?id=128#c1

this is because access to google's stuff requires an api key, stored in xml as a resource or perhaps in code, that is linked with the certificate of the app. if you modified and resigned it, the certificate is different and will not match the api key. you will have to get a valid key for the signature you are using.

you should already have your own certificate you sign everything with. this way if you release an updated version of the app, users of your previous modified version can update without needing to uninstall the old one first. if you don't already have your own certificate, follow the directions here: Signing Your Applications | Android Developers. you will need to use keytool and examples are given in the link.

Sunday, January 23, 2011

there are only a handful of anti-cracking techniques for android, at least that i know of. this seems to be because of how android apps must behave. they must operate inside their own virtual machine and are not allowed to store permenent data. when they are uninstalled, they must remove all traces of themselves. this makes things like timed trials difficult to implement because a simple reinstall will reset timers.

if an app wants to prevent cracking, it only has a few options. it can check file properties of the apk such as file size, last modified date and signature. it could also check the installer package name to test if it was installed via market. a cracker or pirate would install via adb, not market. antilvl can already hook and subvert signature checks. file size, last modified and installer package hooking are in the works. :D

but there's another way to perform any check in a more clever way that makes detection more difficult... by using java reflection. instead of calling the method directly, the app could use reflection to store the method in a variable and call it later indirectly. this makes searching for the direct method call difficult. it also allows the method name to be obfuscated since it is just a strong. let me show you in code what it may look like:

const-class v1, Landroid/content/pm/PackageManager;
# do not assume this will not always be a plain text
# it could be put together in a much more complicated way such as building character by character using ascii codes
# you'll have to hook reflection methods to test the name or figure it out manually
const-string v2, "getInstallerPackageName"
# make array of size 1
const/4 v3, 0x1
new-array v3, v3, [Ljava/lang/Class;
const/4 v4, 0x0
const-class v5, Ljava/lang/String;
# store String class in array v3, at index v4 (0)
aput-object v5, v3, v4
# get method of name v2 ("getInstallerPackageName") and move to v0
# http://download.oracle.com/javase/1.5.0/docs/api/java/lang/Class.html#getMethod(java.lang.String, java.lang.Class...)
invoke-virtual {v1, v2, v3}, Ljava/lang/Class;->getMethod(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;
move-result-object v0
# do something with v0, like store in class variable
# ....
# and then sometime later, somewhere else in code
# get the package manager and store in v1
invoke-virtual {p0}, Lcom/clever/app/Main;->getPackageManager()Landroid/content/pm/PackageManager;
move-result-object v1
const/4 v2, 0x1
new-array v2, v2, [Ljava/lang/Object;
const/4 v3, 0x0
invoke-virtual {p0}, Lcom/clever/app/Main;->getPackageName()Ljava/lang/String;
move-result-object v4
# put package name in array v2 at index v3 (0)
aput-object v4, v2, v3
# actually call "getInstallerPackageName" with the array we built as parameters
# which contains this package name
# http://download.oracle.com/javase/1.5.0/docs/api/java/lang/reflect/Method.html#invoke%28java.lang.Object,(java.lang.Object...)
invoke-virtual {v0, v1, v2}, Ljava/lang/reflect/Method;->invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;
move-result-object v0
check-cast v0, Ljava/lang/String;
# clever to not use any type of full string, just "goog"
# remember the full string is expected to be "com.google.android.feedback"
const-string v1, "goog"
invoke-virtual {v0, v1}, Ljava/lang/String;->indexOf(Ljava/lang/String;)I
move-result v0
# check to see if v0 has the correct value. if not... error :D

the next lesson in way of the android cracker will cover all anti-cracking techniques i know in detail, and antilvl will support these types of checks soon, but this is enough for anyone to figure it out. :D

Monday, January 10, 2011

it's been a while since my last update, so i figure i should say something about progress on antilvl 1.0.

i wanted to learn all kinds of best practices in java, so i spent a lot of time designing classes while trying to avoid coupling and other oop pitfalls. even threw in some unit testing. i also want antilvl to be able to be able to learn how to subvert any implementation of the lvl, and do it without having pages and pages of complicated regex code.

to accomplish this, antilvl's code will be more like an engine, with all file identification patterns and code modification information written in xml with a specification of my own design. it will be mature enough to have in-place dynamic variables and definable search patterns. the result will be almost any apk modification could be cleverly constructed inside the xml without touching the code in about 10-20 lines.

i must stress i'm not doing this for piracy. i'm doing it because it's a challenge. no one else has done it. it's really fun for me. if i was trying to be a pirate, i would not explain how the cracks work. if you're a developer and you insist on protection, you will have to roll your own and heavily modify the official lvl so known methods will not work. use antilvl to help you figure out if it's well protected.

most people don't mind paying a few euros for a program on what amounts to their main computing device. the benefit from spending many hours on increased protection may not be worth it unless your App is very expensive. or perhaps your and android master and just really get off to having wonderfully insane levels of protection.

Monday, January 3, 2011

many people find this blog by searching for smali syntax examples and finding a previous post on example smali syntax. since i originally hastily wrote it, i have learned more so i updated it as best i could for now. more helpfully, i worked out a syntax highlighter for smali using syntaxhighlighter. i'll upload it somewhere official when i'm finished so others can use it. because i know there are throngs of people just itching to have highlighted smali code!