Wednesday, November 9, 2011

Dictionary app

Dictionary.com: one of the best reference and dictionary apps, offers dictionary and Thesaurus content (words and definitions, synonyms, antonyms, phonetic and audio pronunciation, spelling suggestions, word origin and history and many more). This is a very useful tool for anybody (especially someone like me).
 From your phone search for "dictionary" and install. Happy spelling!

Tuesday, November 8, 2011

Tracking app for runners

 Imap my run. This is a very cool app for runners. It tracks the route, time, distance, speed, pace and calories in real time using the GPS on your device. There is also an option to sync your results with their website (http://www.mapmyrun.com/) for future comparising. Prety cool. From your phone search for "I map my run" and install it if you like it.
 Also another tracking app is "My tracks". It's very similar to the previous one and it gather useful statistics such as time, speed, distance, and elevation.

Translation app

 Google translate. This is an app that translates words or sentences from one language to another. Very useful for people traveling to foreign countries. It works 2 ways: you can type or you can talk to it. It will show you the translation in the second language. For some languages (the more common ones) there is an option to talk the translation back to you. There are around 30 languages available right now with new ones to be added in the future.
 This is a link to the Android Market if you want to read more about it: https://market.android.com/details?id=com.google.android.apps.translate&feature=search_result#?t=W251bGwsMSwxLDEsImNvbS5nb29nbGUuYW5kcm9pZC5hcHBzLnRyYW5zbGF0ZSJd
 From your phone go to Market and search for "Google translate" and install it.

Monday, November 7, 2011

Map and directions app

 In addition to the "Maps" that comes pre-installed on the phone, another good app is "Mapquest". Other then showing maps and giving driving directions, this app also provides live traffic reports. Here's a link to the Android Market page or you can search for "Mapquest" in Market from your phone :https://market.android.com/details?id=com.mapquest.android.ace&feature=search_result#?t=W251bGwsMSwxLDEsImNvbS5tYXBxdWVzdC5hbmRyb2lkLmFjZSJd.

Thursday, October 27, 2011

antilvl 1.4.0

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

major changes include:
  • option to use your own signatures
  • more control over which fingerprints are used
  • support for verizon drm
  • a few new anti-tampering checks are known
  • some fixes in how fingerprints were applied

you can read more / download here: http://androidcracking.blogspot.com/p/antilvl_01.html

Monday, October 17, 2011

protection using checksums and key / unlocker apps

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:
// Copied directly and made private from R.java of Key App
// After creating strings..
private static final int tt_crc32=0x7f040002;
private static final int tt_md5=0x7f040004;

public static TestResult checkCRC32ChkSum() {
// Get path to our apk on the system.
String apkPath = Main.MyContext.getPackageCodePath();
Long chksum = null;
try {
// Open the file and build a CRC32 checksum.
// You could also use Adler32 in place of CRC32.
FileInputStream fis = new FileInputStream(new File(apkPath));
CRC32 chk = new CRC32();

CheckedInputStream cis = new CheckedInputStream(fis, chk);
byte[] buff = new byte[80];
while ( cis.read(buff) >= 0 ) ;

chksum = chk.getValue();
} catch (Exception e) {
e.printStackTrace();
}

// After creating your apk, calculate the crc32 checksum
// and store it as a string value in the KEY / unlock App.
String keyStrVal = getKeyString(tt_crc32);

// Key is not installed.
if ( keyStrVal.equals("") ) {
// Key not installed. Validation failure.
}

Long chksumCmp = Long.parseLong(keyStrVal);

if ( chksum.equals(chksumCmp) ) {
// Success. Checksum stored in key matches the
// checksum we just created. We can assume APK
// is not modified. Kinda.
}
else {
// Validation failure! Apk has been modified.
}
}

public static TestResult checkMD5ChkSum() {
// Do pretty much the exact same thing here,
// except instead of a CRC32 checksum, we'll be
// using an MD5 digest. You could also use SHA1.
// Any cracker worth his salt will immediately recognize
// CRC32 and MD5 keywords and know them to be checksum
// attempts. Using Adler32 or SHA1 may put them off.
String apkPath = Main.MyContext.getPackageCodePath();
MessageDigest msgDigest = null;
byte[] digest = null;
try {
msgDigest = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e1) {
e1.printStackTrace();
}

byte[] bytes = new byte[8192];
int byteCount;
FileInputStream fis = null;

try {
fis = new FileInputStream(new File(apkPath));

while ((byteCount = fis.read(bytes)) > 0)
msgDigest.update(bytes, 0, byteCount);

digest = msgDigest.digest();
} catch (Exception e) {
e.printStackTrace();
}

String keyStrVal = getKeyString(tt_md5);
// Key is not installed.
if ( keyStrVal.equals("") ) {
// Key not installed. Validation failure.
}

// Using Base64 encoding is just a lazy way to store byte arrays.
// You -could- also embed the values in the code of the Apk
// Read more here:
// http://stackoverflow.com/questions/2721386/android-how-to-share-code-between-projects-signed-with-the-same-certificate
if ( Arrays.equals(Base64.decode(keyStrVal, Base64.DEFAULT), digest) )
// Validated
else
// Apk has been modified
}


private static String getKeyString(int resId) {
// You will need this to retrieve the stored checksums from the KEY App.
String result = "";

try {
Context c = Main.MyContext.createPackageContext("your.package.name.key", Context.CONTEXT_IGNORE_SECURITY);
result = c.getString(resId);
} catch (Exception e) {
Console.log("Error while getting key string:\n" + e);
e.printStackTrace();
result = "";
}

return result;
}


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.
.method public static checkCRC32ChkSum()V
.locals 11

.prologue
.line 934
sget-object v9, Lcom/lohan/testtarget/Main;->MyContext:Landroid/content/Context;

invoke-virtual {v9}, Landroid/content/Context;->getPackageCodePath()Ljava/lang/String;

move-result-object v0

.line 935
.local v0, apkPath:Ljava/lang/String;
const/4 v3, 0x0

.line 939
.local v3, chksum:Ljava/lang/Long;
:try_start_0
new-instance v7, Ljava/io/FileInputStream;

new-instance v9, Ljava/io/File;

invoke-direct {v9, v0}, Ljava/io/File;->(Ljava/lang/String;)V

invoke-direct {v7, v9}, Ljava/io/FileInputStream;->(Ljava/io/File;)V

.line 940
.local v7, fis:Ljava/io/FileInputStream;
new-instance v2, Ljava/util/zip/CRC32;

invoke-direct {v2}, Ljava/util/zip/CRC32;->()V

.line 942
.local v2, chk:Ljava/util/zip/CRC32;
new-instance v5, Ljava/util/zip/CheckedInputStream;

invoke-direct {v5, v7, v2}, Ljava/util/zip/CheckedInputStream;->(Ljava/io/InputStream;Ljava/util/zip/Checksum;)V

.line 943
.local v5, cis:Ljava/util/zip/CheckedInputStream;
const/16 v9, 0x50

new-array v1, v9, [B

.line 944
.local v1, buff:[B
:cond_0
invoke-virtual {v5, v1}, Ljava/util/zip/CheckedInputStream;->read([B)I

move-result v9

if-gez v9, :cond_0

.line 946
invoke-virtual {v2}, Ljava/util/zip/CRC32;->getValue()J

move-result-wide v9

invoke-static {v9, v10}, Ljava/lang/Long;->valueOf(J)Ljava/lang/Long;
:try_end_0
.catch Ljava/lang/Exception; {:try_start_0 .. :try_end_0} :catch_0

move-result-object v3

.line 953
.end local v1 #buff:[B
.end local v2 #chk:Ljava/util/zip/CRC32;
.end local v5 #cis:Ljava/util/zip/CheckedInputStream;
.end local v7 #fis:Ljava/io/FileInputStream;
:goto_0
const v9, 0x7f040002

invoke-static {v9}, Lcom/lohan/testtarget/PerformTestsTask;->getKeyString(I)Ljava/lang/String;

move-result-object v8

.line 956
.local v8, keyStrVal:Ljava/lang/String;
const-string v9, ""

invoke-virtual {v8, v9}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z

.line 960
invoke-static {v8}, Ljava/lang/Long;->parseLong(Ljava/lang/String;)J

move-result-wide v9

invoke-static {v9, v10}, Ljava/lang/Long;->valueOf(J)Ljava/lang/Long;

move-result-object v4

.line 962
.local v4, chksumCmp:Ljava/lang/Long;
invoke-virtual {v3, v4}, Ljava/lang/Long;->equals(Ljava/lang/Object;)Z

.line 970
return-void

.line 947
.end local v4 #chksumCmp:Ljava/lang/Long;
.end local v8 #keyStrVal:Ljava/lang/String;
:catch_0
move-exception v9

move-object v6, v9

.line 948
.local v6, e:Ljava/lang/Exception;
invoke-virtual {v6}, Ljava/lang/Exception;->printStackTrace()V

goto :goto_0
.end method

.method public static checkMD5ChkSum()V
.locals 12

.prologue
const/4 v11, 0x0

.line 981
sget-object v10, Lcom/lohan/testtarget/Main;->MyContext:Landroid/content/Context;

invoke-virtual {v10}, Landroid/content/Context;->getPackageCodePath()Ljava/lang/String;

move-result-object v0

.line 982
.local v0, apkPath:Ljava/lang/String;
const/4 v9, 0x0

.line 983
.local v9, msgDigest:Ljava/security/MessageDigest;
const/4 v3, 0x0

check-cast v3, [B

.line 985
.local v3, digest:[B
:try_start_0
const-string v10, "MD5"

invoke-static {v10}, Ljava/security/MessageDigest;->getInstance(Ljava/lang/String;)Ljava/security/MessageDigest;
:try_end_0
.catch Ljava/security/NoSuchAlgorithmException; {:try_start_0 .. :try_end_0} :catch_0

move-result-object v9

.line 990
:goto_0
const/16 v10, 0x2000

new-array v2, v10, [B

.line 992
.local v2, bytes:[B
const/4 v6, 0x0

.line 995
.local v6, fis:Ljava/io/FileInputStream;
:try_start_1
new-instance v7, Ljava/io/FileInputStream;

new-instance v10, Ljava/io/File;

invoke-direct {v10, v0}, Ljava/io/File;->(Ljava/lang/String;)V

invoke-direct {v7, v10}, Ljava/io/FileInputStream;->(Ljava/io/File;)V
:try_end_1
.catch Ljava/lang/Exception; {:try_start_1 .. :try_end_1} :catch_2

.line 997
.end local v6 #fis:Ljava/io/FileInputStream;
.local v7, fis:Ljava/io/FileInputStream;
:goto_1
:try_start_2
invoke-virtual {v7, v2}, Ljava/io/FileInputStream;->read([B)I

move-result v1

.local v1, byteCount:I
if-gtz v1, :cond_0

.line 1000
invoke-virtual {v9}, Ljava/security/MessageDigest;->digest()[B
:try_end_2
.catch Ljava/lang/Exception; {:try_start_2 .. :try_end_2} :catch_1

move-result-object v3

move-object v6, v7

.line 1005
.end local v1 #byteCount:I
.end local v7 #fis:Ljava/io/FileInputStream;
.restart local v6 #fis:Ljava/io/FileInputStream;
:goto_2
const v10, 0x7f040004

invoke-static {v10}, Lcom/lohan/testtarget/PerformTestsTask;->getKeyString(I)Ljava/lang/String;

move-result-object v8

.line 1007
.local v8, keyStrVal:Ljava/lang/String;
const-string v10, ""

invoke-virtual {v8, v10}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z

.line 1015
invoke-static {v8, v11}, Landroid/util/Base64;->decode(Ljava/lang/String;I)[B

move-result-object v10

invoke-static {v10, v3}, Ljava/util/Arrays;->equals([B[B)Z

.line 1020
return-void

.line 986
.end local v2 #bytes:[B
.end local v6 #fis:Ljava/io/FileInputStream;
.end local v8 #keyStrVal:Ljava/lang/String;
:catch_0
move-exception v10

move-object v5, v10

.line 987
.local v5, e1:Ljava/security/NoSuchAlgorithmException;
invoke-virtual {v5}, Ljava/security/NoSuchAlgorithmException;->printStackTrace()V

goto :goto_0

.line 998
.end local v5 #e1:Ljava/security/NoSuchAlgorithmException;
.restart local v1 #byteCount:I
.restart local v2 #bytes:[B
.restart local v7 #fis:Ljava/io/FileInputStream;
:cond_0
const/4 v10, 0x0

:try_start_3
invoke-virtual {v9, v2, v10, v1}, Ljava/security/MessageDigest;->update([BII)V
:try_end_3
.catch Ljava/lang/Exception; {:try_start_3 .. :try_end_3} :catch_1

goto :goto_1

.line 1001
.end local v1 #byteCount:I
:catch_1
move-exception v10

move-object v4, v10

move-object v6, v7

.line 1002
.end local v7 #fis:Ljava/io/FileInputStream;
.local v4, e:Ljava/lang/Exception;
.restart local v6 #fis:Ljava/io/FileInputStream;
:goto_3
invoke-virtual {v4}, Ljava/lang/Exception;->printStackTrace()V

goto :goto_2

.line 1001
.end local v4 #e:Ljava/lang/Exception;
:catch_2
move-exception v10

move-object v4, v10

goto :goto_3
.end method

.method private static asdfgetKeyString(I)Ljava/lang/String;
.locals 6
.parameter "resId"

.prologue
.line 1025
const-string v2, ""

.line 1028
.local v2, result:Ljava/lang/String;
:try_start_0
sget-object v3, Lcom/lohan/testtarget/Main;->MyContext:Landroid/content/Context;

const-string v4, "your.package.name.key"

const/4 v5, 0x2

invoke-virtual {v3, v4, v5}, Landroid/content/Context;->createPackageContext(Ljava/lang/String;I)Landroid/content/Context;

move-result-object v0

.line 1029
.local v0, c:Landroid/content/Context;
invoke-virtual {v0, p0}, Landroid/content/Context;->getString(I)Ljava/lang/String;
:try_end_0
.catch Ljava/lang/Exception; {:try_start_0 .. :try_end_0} :catch_0

move-result-object v2

.line 1036
.end local v0 #c:Landroid/content/Context;
:goto_0
return-object v2

.line 1030
:catch_0
move-exception v3

move-object v1, v3

.line 1031
.local v1, e:Ljava/lang/Exception;
new-instance v3, Ljava/lang/StringBuilder;

const-string v4, "Error while getting key string:\n"

invoke-direct {v3, v4}, Ljava/lang/StringBuilder;->(Ljava/lang/String;)V

invoke-virtual {v3, v1}, Ljava/lang/StringBuilder;->append(Ljava/lang/Object;)Ljava/lang/StringBuilder;

move-result-object v3

invoke-virtual {v3}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;

move-result-object v3

invoke-static {v3}, Lcom/lohan/testtarget/Console;->log(Ljava/lang/String;)V

.line 1032
invoke-virtual {v1}, Ljava/lang/Exception;->printStackTrace()V

.line 1033
const-string v2, ""

goto :goto_0
.end method

Wednesday, August 10, 2011

Cost-it





1. Create a Project
2. Edit Project Details
3. Open a Project
4. Delete a Project
5. Add a Task
6. Edit a Task Details
7. Complete a Task
8. Delete a Task
9. View Reports






Cost-It is a small, intuitive and easy-to-use application. The basic idea is that you define a project (and optional budget), its tasks and associated costs (estimated, actual, and how much you have paid). You then know how much the project is estimated to cost you; how much the project has actually cost you; and how much you have paid and have left to pay.
If you planning on getting married, have some DIY projects to cost out and track; or are planning your latest vacation then this is the application for you.

You can also check tasks off as done so you know the completion status of each project in terms of tasks complete and how much money has been spent and still needs to be spent.
This application is ideal for Wedding planning, DIY Projects, Vacation Planning. No Project is too big or small.


 0. Configuring Cost-It

You can configure this application to use up to three additional custom attributes for a task.
From the main projects screen select the menu button.
This will load the Preferences page. From here you can enable up to three attributes and give them a name.
This feature is useful if you have custom values you want to track such as tax, shipping or resale value.
This feature is only available from version 1.3.


 1. Creating a Project

The first time you launch Cost-It you will see the following screen:





 
To create your first Project, tap on the add icon at the top right of the screen. This will open up the Edit Project dialog as shown below:



Within this dialog you can enter the name of the project and the size of the budget (if required)
To confirm you want to create the project tap on the OK button. This will take you to the task management screen where you can add, edit and delete tasks from within your project.

To go back to the projects screen tap on the back button.


2. Edit Project Details

To edit the project, from the projects screen tap on the project and a quick action bar will appear as shown below:





Tap on the Edit Project option, this will open Edit Project Dialog where the details can be modified.

You can also edit the project details from the tasks page, by selecting the edit icon to the right of the project name.
 
3. Open a Project

To open the project and edit the projects tasks, you tap on the project so the Quick Action Bar appears. You then Tap on Edit Tasks option.

Alternatively you can swipe across project, from left-to-right or right-to-left.

This will open the page to edit tasks.

4. Delete a Project

To delete a project you tap on the project to open up the Quick Action Bar.

You then tap on the Delete option.

A confirmation dialog box will appear to ask if this is what you really want to do. Select either OK or Cancel.

5. Add a Task

To create a Task, tap on the add icon at the top right of the screen. This will open up the Edit Task dialog as shown below:




Within this dialog you can enter the name of the task, the estimated cost, the actual cost; and how much you have paid so far.

Tap on the OK button to save this information.




6. Edit a Task

To edit the task, from the tasks screen tap on the Task and a quick action bar will appear as shown below:



Tap on the Edit option, this will open Edit Task Dialog where the details can be modified.


7. Complete a Task

You have two options for checking/unchecking a task.
1) Select Check from the Quick Action Bar
2) Swipe over the Task from left-to-right or right-to-left.

8. Delete a Task

To delete a Task you tap on the Task to open up the Quick Action Bar.

You then tap on the Delete option.

A confirmation dialog box will appear to ask if this is what you really want to do. Select either OK or Cancel. 

9. View Reports

To view reports for this project you select the Report Summary Tab at the bottom of the tasks screen.
The following screen will appear:
















If you like this application then please give us a good rating.