How to decompile apk from Play Store

This is how you can decompile an application you have installed on your phone. My phone is rooted, uses RootBox 3.5 and has BusyBox installed. You may need to have that too if you want to follow my steps completly. Let's start: 1. Install application from market 2. Download apk to computer First you need to locate the apk on the phone. Connect to the phone: adb shell Find the apk in the folder the apk are downloaded to. It is ussualy in '/data/app/' or '/system/app/'. The apk is called as the id from the Play Store, for example 'com.something.someapp.apk'. You can see this in the url from Play. Next you need to pull it to the computer. Once you have located the apk and know it's name exit adb. On your PC execute: adb pull /data/app/com.something.someapp.apk 3. Transform apk to jar I use dex2jar dex2jar-0.0.9.11/d2j-dex2jar.sh com.something.someapp.apk 4. See the code inside the jar I use Java Decompiler Just open the ...

JSecurity and active directory in grails

This was done as a way to force domain users to log in before using the applications.
The old implementation used the jcifs library with jetty, but after upgrading to glashfish, jcifs started to fail randomly, especially when the application was accessed using IE.
And, after reading on their web site that the httpfilter is no longer supported, I started looking for free alternatives to Jcifs.
On the JSecurity plugin home it said it works with ldap, but the configuration they gave seemed complicated and I didn't really get it.
On the other hand I found this nice blog entry of how to use java/jndi and active directory.
http://mhimu.wordpress.com/2009/03/18/active-directory-authentication-using-javajndi/

This is how o put them together:

1. install the jsecurity plugin in your grails app
1
2
3
grails install-plugin jsecurity


2. generate the ldap realm and the auth controller. This comes default with jsecurity.
1
2
3
4
grails create-ldap-realm
grails create-auth-controller


3. Create a filter to redirect all the anonymous request to the login.
It might look like this and should be placed in your-app/grails-app/conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class SecurityADFilters {
 
  def filters = {
    loginCheck(controller: '*', action: '*') {
      before = {
         if (controllerName == "auth") return true
        accessControl { true }
      }
 
    }
  }
}


4. Modify the generated JsecLdapRealm based on the example above. It could look like this. This is a mock, some lines of code can be removed, if you don't need to get info about the user.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
class JsecLdapRealm {
  static authTokenClass = org.jsecurity.authc.UsernamePasswordToken
 
  def grailsApplication
 
  def authenticate(authToken) {
    log.info "Attempting to authenticate ${authToken.username} in LDAP realm..."
    def username = authToken.username
    def password = new String(authToken.password)
 
    // Get LDAP config for application. Use defaults when no config
    // is provided.
    def appConfig = grailsApplication.config
    def ldapHost = appConfig.ldap.ldapHost ?: ["ldap://localhost:389/"]
    def searchBase = appConfig.ldap.searchBase ?: ""
    def domain = appConfig.ldap.domain ?: ""
    def usernameAttribute = appConfig.ldap.username.attribute ?: "uid"
    def skipAuthc = appConfig.ldap.skip.authentication ?: false
    def skipCredChk = appConfig.ldap.skip.credentialsCheck ?: false
    def allowEmptyPass = appConfig.ldap.allowEmptyPasswords != [:] ? appConfig.ldap.allowEmptyPasswords : true
 
    // Skip authentication ?
    if (skipAuthc) {
      log.info "Skipping authentication in development mode."
      return username
    }
 
    // Null username is invalid
    if (username == null) {
      throw new AccountException("Null usernames are not allowed by this realm.")
    }
 
    // Empty username is invalid
    if (username == "") {
      throw new AccountException("Empty usernames are not allowed by this realm.")
    }
 
    // Allow empty passwords ?
    if (!allowEmptyPass) {
      // Null password is invalid
      if (password == null) {
        throw new CredentialsException("Null password are not allowed by this realm.")
      }
 
      // empty password is invalid
      if (password == "") {
        throw new CredentialsException("Empty passwords are not allowed by this realm.")
      }
    }
 
    String[] returnedAtts = ["sn", "givenName", "mail"];
    String searchFilter = "(&(objectClass=user)(sAMAccountName=" + username + "))";
 
    //Create the search controls
    SearchControls searchCtls = new SearchControls();
    searchCtls.setReturningAttributes(returnedAtts);
 
    //Specify the search scope
    searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
 
    Hashtable env = new Hashtable();
    env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
    env.put(Context.PROVIDER_URL, ldapHost);
    env.put(Context.SECURITY_AUTHENTICATION, "simple");
    env.put(Context.SECURITY_PRINCIPAL, username + "@" + domain);
    env.put(Context.SECURITY_CREDENTIALS, password);
 
    LdapContext ctxGC = null;
    try {
      ctxGC = new InitialLdapContext(env, null);
      //Search objects in GC using filters
      NamingEnumeration answer = ctxGC.search(searchBase, searchFilter, searchCtls);
      while (answer.hasMoreElements()) {
        SearchResult sr = (SearchResult) answer.next();
        Attributes attrs = sr.getAttributes();
        Map amap = null;
        if (attrs != null) {
          amap = new HashMap();
          NamingEnumeration ne = attrs.getAll();
          while (ne.hasMore()) {
            Attribute attr = (Attribute) ne.next();
            amap.put(attr.getID(), attr.get());
          }
          ne.close();
        }
        if (amap != null) return username
        else return false
      }
    }
    catch (NamingException ex) {
      ex.printStackTrace();
    }
}
}


5. Notice that above we are using some properties from appConfig so we shall add them. In grails-app/conf/Config.groovy add
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// configure the ldap realm
 
ldap.domain = 'domain'
ldap.ldapHost = 'ldap://ldaphost'
ldap.searchBase = 'DC=***,DC=***' //or whatever is suitable for you
 
ldap.skip.authentication = false
ldap.skip.credentialsCheck = false
ldap.allowEmptyPasswords = false
 
//consult your LDAP admin
 
jsecurity.authentication.strategy = new org.jsecurity.authc.pam.AtLeastOneSuccessfulModularAuthenticationStrategy()


That is about it. I hope I did not forget anything.
Now every time you access the application you will have to log in using your domain account.

Comments

Popular posts from this blog

Update: Intellij 12 + Android Annotations 2.7 + maven

Ways to map and query many-to-many in GORM

How to decompile apk from Play Store