2013-11-26

ADB Lock for KitKat (Android 4.4) [fr / en]


* English Version Below *

  En attendant la publication de la V4, voici les améliorations apportées à l'actuelle V3 en mode normal (root) et système (non-root).

Nouvelle Icône

    On ne peut pas dire que les designers Android se cassent beaucoup la tête pour concevoir les icônes de débogage.  Quatre barres verticales, rappel géométrique des quatre barres de chocolat dans une confiserie KitKat.

Corrections (non sécuritaires):

  • En mode non-root, la surveillance de l'écran lançait inutilement une détection de root.
  • En mode non-root, les appels ne sont plus faits à Settings.Secure mais à Settings.Global.
  • Le hack BillingHack du PlayStore est corrigé. Pour rappel, être sponsor n'active *AUCUNE* fonctionnalité supplémentaire dans l'application.

Compatibilité Dalvik ET ART

ADB-Lock est toujours compatible avec l'actuelle machine virtuelle Dalvik (celle que vous avez actuellement) et est aussi compatible avec la nouvelle : ART (que vous aurez très prochainement).

Attention, les outils SuperUser ne sont pas tous compatibles avec ART, je vous suggère très fortement de passer ADB Lock en mode Système (cf mon précédent billet)!

Mode Système (non-root) : contourner les nouvelles restrictions.

Android 4.4 a de nouvelles sécurités, l'une d'elle enlève systématiquement l'autorisation WRITE_SECURE_SETTINGS aux applications normales et même celles de /system/. Cette sécurité se contourne avec mon zip pour le recovery :




Je ne vous donne pas dans ce billet comment contourner la protection, mais vous laisse trouver par vous-même.

Si vous avez urgemment besoin de la solution, elle est dans le zip :-)



    Until ADB Lock V4 release, I publish an improved V3 on both mode : normal (root) and system (non-root).

New Icon

    I'm not sure Android's designers spend enough time designing ADB notifications icons. This time, they released a four vertical bars supposed to reminds us a KitKat tablet with the four bars candy.

Improvements (not insecure):

  • In non-root mode, screen monitoring switch required unnecessarily root privilege.
  • In non-root mode, too, ADB Lock will no longer calls Settings.Secure instead of Settings.Global.
  • Last, and least, PlayStore Hack BillingHack will not works on ADB Lock. As a reminder, becoming a sponsor *WILL NOT* unlock hidden features. It's only sponsoring.

ART and Dalvik compatibility

ADB-Lock remains fully compatible with the actual runtume (aka Dalvik) and is now compatible with ART (the next runtime).

A lot of SuperUser tools are not compatible with ART, I strongly suggest you to switch in System Mode (see my last post)!

System mode (non-root) : bypass brand new restrictions.

Android 4.4 brings new security enhancement, one of them revoke systematically WRITE_SECURE_SETTINGS permissions to both /data/app AND /system/app. This mechanism is really easy to defeat with my recovery zip :




I will not give you in this post how I bypass the protection, you have to find it by youself.

But if you really need the answer, it's inside the zip, in plaintext :-)

2013-10-02

ADB Lock non-root mode [fr / en]

English version below…

Android réserve ses fonctions les plus sensibles aux applications "système". C'est par exemple le cas de "Paramètres", l'application système que vous utilisez le plus souvent, qui est autorisée à activer ou désactiver ADB sans recourir au root.

Une application Système est une application classique : elle est au format APK, elle doit déclarer ses permissions. LA différence est qu'elle est placée dans /system/ (un dossier spécial et protégé) au lieu de /data/app comme toutes les autres apps.

L'app ADB-Lock est capable de détecter toute seule si elle est Système et dans ce cas cesse d'utiliser le mécanisme ROOT pour permuter l'état de l'ADB.

Il y a au moins 4 manières de passer ADB-Lock en mode Système : avec une app, avec le shell adb, avec un script  ou avec un zip (recovery ou TWRP). Bref vous avez l'embarras du choix.

2013-09-19

ADB Lock v3 ! [en / fr]

[English version below]
-----

Le développement d'ADB Lock se fait sur mon temps libre et la priorité est donnée aux apps qui font rentrer la monnaie. ADB Lock est "financée" par le don, qui à ma grande surprise, fonctionne plutôt bien selon mes critères.

La précédente version, d'octobre 2012, toujours compatible avec Android 4.3, méritait quelques modifications :
  • Android 2.3 et inférieurs (plus suivis par Google) resteront sur la version 1. Le maintien des layout et une partie du code ne se justifie plus.
  • Suppression de la permission Internet et du mécanisme (jamais activé) de publicité via AdMob.
  • Abandon de la bibliothèque RootTools et réecriture des commandes pour ne plus dépendre de busybox.
  • Support des tablettes 10" et 7" (grâce à GenyMotion).
  • Quelques modifications cosmétiques comme l’icône du launcher, suppression des paradigmes d'ordinateurs tels que la fermeture des fenêtres par un click sur une croix et une meilleure harmonie visuelle (padding/margin).
  • La barre du haut initialement occupée par l’icône de l'app, est remplacée par une (fausse et c'est pas bien !) ActionBar qui pointe vers mes profils Twitter, Google+ et ce blog. 
Si vous ne l'utilisez pas encore, installez le SuperUser de koush, qui offre de biens meilleures performances, plus d'options et une plus grande fiabilité que le SuperUser de ChainsDD ou SuperSU de chainfire.

Notez que si vous utilisez Superuser de ChainsDD, il est possible, qu' en arrière plan, ADB Lock ne puisse éteindre adbd car SuperUser demande une confirmation alors que l'écran est éteint.

---

I used to code "ADB Lock" on my spare time, and I must confess the money I do with, is a criterium to prioritize my apps's developpement. Surprisingly, the donation model of this app runs better than I though when I chose this monetization.

The last holo version of ADB-Lock, published a year ago, is still fully compatible with brand new Android 4.3 security models, but it needs a lot of improvements.
  • Android 2.3 and below (not maintained by Google) terminals stay with ADB Lock v1.
    ADB Lock v3 will aims Android 4 and above.
  • The Internet permission is definitively removed. AdMob (never activated) is also removed.
  • RootTools and busybox are no longer needed. They are removed too.
  • Android 10" and 7" are supported. Thanks to GenyMotion !
  • some cosmetic changes concerning launcher icon, computer paradigms (like corner cross to quit) and more efficient visual repartition of widgets (mainly margin & padding stuff)
  • 3 social network icons : Twitter / Google Plus / Blogger to see on what I'm working on. In French.
I can't enough recomand you to use koush's SuperUser instead of chainsDD's SuperUser or chainfire's SuperSU. Koush's has better performances, better options and higher reliability.

For example, ChainsDD's sometimes forgets it has previously (and permanently) allowed ADB Lock and blocks adbd stop mechanism, waiting for another allowance while screen is… off.

2013-09-09

Łǎ łōčǎłé zz_ZZ, ł'ǎűţŕé ƒǎçōи ďé ƒǎìŕé śōи ł33ţ



Tantôt en Anglais, tantôt en Français, je change la langue par défaut de mon terminal assez régulièrement.  Et c'est au cours d'un changement que je suis tombé sur une locale étrange "[Developer] Accented English", que j'ai bien évidemment validé. Je suis curieux.

Probablement qu'un jour ça me perdra, en attendant ça m'amuse.

Attention, ce mode rend votre terminal instable éи ρłűś ďé łé ŕéиďŕé ď샃ìčìłéɱéиţ łìśìƃłé !



        Comme vous pouvez le voir sur la vignette ci-contre, cette locale est la locale par défaut, du moins le contenu du texte, sauf que les lettres sont piochées dans les alphabets d'un peu tout le monde.


    Vous reconnaissez le i cyrillique en minuscule (и), le tréma, le circonflexe, le caron, la cédille … et encore plein d'autres cas de la diacritique latine.


    Codons !


    Je n'ai trouvé aucune explication sur cette locale dans la documentation Android, probablement que les cas concrets d'utilisation sont explicités dans les sources.

    En attendant de lui trouver un sens, faisons-en un easter-egg :  si un autre développeur utilise mon app en Accented English, autant lui être agréable et être raccord avec le reste de son terminal.

    Le code de la locale est zz_ZZ (pays région) il convient de créer "values-zz" et d'y placer le bon fichier "strings.xml", fidèle reflet de values/strings.xml !

     En attendant de mettre la main sur la table de conversion, je vous propose celle-ci :
    'a' : "ǎ", 'b' : "ƃ", 'c' : "č", 'd' : "ď", 'e' : "é",
    'f' : "ƒ", 'g' : "ǧ", 'h' : "ℏ", 'i' : "ì", 'j' : "ĵ", 'k' : "ķ", 'l' : "ł",
    'm' : "ɱ", 'n' : "и", 'o' : "ō", 'p' : "ρ", 'q' : "ʠ", 'r' : "ŕ", 's' : "ś",
    't' : "ţ", 'u' : "ű", 'v' : "ʋ", 'w' : "ŵ", 'x' : "ẍ", 'y' : "ẏ", 'z' : "ž",
    
    'A' : "Â", 'B' : "Ɓ", 'C' : "Ç", 'D' : "Ð", 'E' : "Ë", 'F' : "Ƒ", 'G' : "Ǧ",
    'H' : "Ȟ", 'I' : "Í", 'J' : "Ĵ", 'K' : "Ķ", 'L' : "Ł", 'M' : "Ḿ", 'N' : "Ň",
    'O' : "Ô", 'P' : "Ƥ", 'Q' : "Q", 'R' : "Ŕ", 'S' : "Ş", 'T' : "Ť", 'U' : "Ü",
    'V' : "℣", 'W' : "₩", 'X' : "Ẋ", 'Y' : "¥", 'Z' : "Ż"

    Le visuel est cohérent avec les choix faits pour Android.

    Même si la conversion est en fait triviale, il est possible de l'automatiser avec quelques lignes de python :
    Utilisation : ./script.py input.xml output.xml
    #!/usr/bin/env python3
    # -*- coding: utf-8 -*- 
    
    '''
    __author__ = "Cekage"
    __copyright__ = "Copyleft 2013, Cekage Studio"
    __credits__ = ["cekage", "fileformat"]
    __license__ = "WTFPL"
    __version__ = "1"
    __maintainer__ = "cekage"
    __email__ = "android.dev@cekage.net"
    __status__ = "ƤŔÔÐÜÇŤÍÔŇ"
    
    # Ǧŕééţž ţō http://www.fileformat.info/info/unicode/category/Ll/list.htm
    # Ǧŕééţž ţō http://www.fileformat.info/info/unicode/category/Lu/list.htm
    '''
    
    import sys
    import getopt
    import os
    from xml.etree import ElementTree
    
    convert_table = { 'a' : "ǎ", 'b' : "ƃ", 'c' : "č", 'd' : "ď", 'e' : "é",
    'f' : "ƒ", 'g' : "ǧ", 'h' : "ℏ", 'i' : "ì", 'j' : "ĵ", 'k' : "ķ", 'l' : "ł",
    'm' : "ɱ", 'n' : "и", 'o' : "ō", 'p' : "ρ", 'q' : "ʠ", 'r' : "ŕ", 's' : "ś",
    't' : "ţ", 'u' : "ű", 'v' : "ʋ", 'w' : "ŵ", 'x' : "ẍ", 'y' : "ẏ", 'z' : "ž",
    
    'A' : "Â", 'B' : "Ɓ", 'C' : "Ç", 'D' : "Ð", 'E' : "Ë", 'F' : "Ƒ", 'G' : "Ǧ",
    'H' : "Ȟ", 'I' : "Í", 'J' : "Ĵ", 'K' : "Ķ", 'L' : "Ł", 'M' : "Ḿ", 'N' : "Ň",
    'O' : "Ô", 'P' : "Ƥ", 'Q' : "Q", 'R' : "Ŕ", 'S' : "Ş", 'T' : "Ť", 'U' : "Ü",
    'V' : "℣", 'W' : "₩", 'X' : "Ẋ", 'Y' : "¥", 'Z' : "Ż"}
    
    def accentualize(text):
        ''' returns text with all known chars replaced by accented one '''
        
        accentualized=""
        for char in list(text):
            if char in convert_table.keys():
                accentualized += convert_table[char]
            else:
                accentualized += char
        return accentualized
    
    def convertXML(xmlfrom,toxml):
        ''' reads xmlfrom, loads <string>, accentualizes the text and finally writes to toxml '''
        
        document = ElementTree.parse(xmlfrom)
        resroot = document.getroot()
        
        for string in resroot.findall('string'):
            string.text =  accentualize(string.text)
            
        document.write(toxml,encoding='UTF-8',xml_declaration=True)
    
    def main():
        if len(sys.argv) < 3:
            sys.exit('Üśǎǧé: %s ìиρűţ.ẍɱł ōűţρűţ.ẍɱł' % sys.argv[0])
    
        if not os.path.exists(sys.argv[1]):
           sys.exit('ËŔŔÔŔ: %s ŵǎś иōţ ƒōűиď!' % sys.argv[1])
        
        convertXML(sys.argv[1],sys.argv[2])
    
    if __name__ == "__main__":
        main()
    
    Voilà ce que ça donne :

    Quelques limites à cette locale.

    Passer à cette locale va rendre votre terminal instable le temps son utilisation, si vous avez besoin de stabilité ne l'utilisez pas en permanence.

    Voici deux briques de base du système android qui vont tôt ou tard vous poser problème :
    • Settings.apk ( l'application Parametres )
     
    • Google Search




    Enjoy :-)

    2013-07-24

    MasterKey : du cache-cache au root.

    C'est à l'équipe de sécurité BlueBox que l'on doit la paternité du bug MasterKey. Avant que la présentation officielle de la faille à la BlackHat 2013 ne soit faite, les détails donnés ont suffit à d'autres chercheurs chevronnés pour la trouver par leurs propres moyens.

    Si dans un premier le temps le buzz était alimenté par les "99%", il est ensuite un peu retombé car la faille ne semblait destinée qu'au cache-cache. Saurik a dévoilé il y a quelques jours comment chainer MasterKey aux outils de développement d'Android pour cette fois-ci passer root. Du coup, doit-on avoir peur de cette faille ?

    Si vous avez du contenu professionnel sensible sur votre smartphone, il est temps de l'effacer. Si vous avez encore des smartphones sous scellés, il est temps de dumper les bases sqlite !

    2013-06-29

    État de l'art de la triche sur Ruzzle… et plus encore !

    mise à jour 2/07 : Présentation de Ruzzle+GIF et synthèses des manipulations des vidéos.

    Intro

    What you must learn is that these rules are no different than the rules of a computer system...some of them can can be bent. Others...can be broken. Understand?  - Morpheus

    Cette réplique de Matrix illustre assez bien ma conception de l'informatique en général et dans les jeux vidéos en particulier. Je triche, je cheat, je n'ai acun esprit de fair play, je ne respecte pas les règles du ou des développeurs mais je respecte les miennes : utiliser, comprendre, détourner, retourner. Bref … corrompre !

    La première modification que j'ai apporté au Ruzzle concernait l'horloge. Mes manches durent 4 minutes, celles de l'adversaire 2. Malgré cet avantage mes adversaires arrivaient à taper des scores équivalents aux miens. Diable ! MAIS TOUT LE MONDE TRICHE !!!

    2013-06-08

    Listes des raccourcis Emoji/Unicode pour le clavier Android stock.

    Faire un coeur en emoji
    La version 4.2 (JellyBean) d'Android apportait à nos smartphones le support des emojis. Ce sont des icônes, colorées, très populaires au Japon et portée à l'attention du très grand public européen par Apple avec iOS.

    En réalité nous n'avons pas affaire à des vrais emojis, mais à des caractères Unicode (v5/v6). De ce constat découle quatre conséquences, importantes à comprendre:
    • Les caractères sont monochromes
    • Les caractères doivent être dans la police choisie pour l'interface.
    • Les caractères 24bits comme le picto "feu"  sont affichables, copiables et collables. ⚠ Seuls les caractères unicodes 8 et 16 bits sont gérés par le dictionnaire.
    • Les VRAIS emojis ne sont pas gérés par Android de base (mais certaines ROMs comme CyanogenMod savent les afficher).
     Les images affichées dans le tableau qui suit dépendent de la police choisie pour consulter cette page web. Quelques-un de ces caractères sont par exemple invisibles avec un Android AOSP !


    2013-06-06

    Fin de l'ISO, début de l'été ☀

    Comme chaque année un auditeur de chez Bureau Veritas ( pas ce Veritas**** là) vient évaluer la tenue de notre engagement qualité, la tenue de notre engagement ISO 9001.

    Cette année, encore, nous avons une non-conformité mineure. Mineure dans le fond et dans sa forme mais non-conformité quand même.

    Prendre l'engagement dans le Manuel Qualité d'auditer annuellement tout le SMQ ne suffit pas. La réalisation régulière des audits, synthèse à l'appui, ne suffit pas. Me voilà donc quelque peu orienté vers un planning conventionnel en 2 dimensions dont l'intersection processus/chapitre est la date planifiée d'audit. C'est inutilement contraignant pour l'envergure du SMQ, le terrain gagné par le "papier" est au détriment de l'agilité. Passons.

    Autre constat, l'auditeur salue l'engagement du personnel, sa disponibilité et son ouverture d'esprit dans le cadre de l'audit. Je ne le dirais jamais assez, j'ai les meilleurs collègues du monde. Et ouais.

    Maintenant que l'audit est "derrière" pour 2013, les plans d'actions qualité sur les rails, je vais pouvoir me libérer l'esprit.

    Je me réinvesti petit à petit dans les projets perso (SEL, AMAP, Android, bidouillage) et surtout le troll sur Twitter. \o/


    Ouf !

    2013-05-23

    SMS Revealer ✉ sur le PlayStore

    Je vous propose une application illustrant mon dernier billet sur l'extraction des sms envoyés en loucedé :
    • SMS Revealer ✉ : C'est l'application principale qui va extraire directement des journaux Android tous les SMS envoyés par le terminal. Il faut avoir préalablement mis le terminal dans le mode de débogage adéquat.

      L'écran d’accueil prévient si le mode débogage est incomplet et vous rappelle les commandes adb nécessaires (qui vous sont familières) :


      Ensuite l'écran de synthèse des SMS envoyés avec la date et l'heure, le destinataire et le contenu des SMS. Les émojis et les SMS binaires sont supportés, contrairement aux MMS.


      Lien vers l'alpha (gratuit) : https://play.google.com/apps/testing/net.cekage.smsspypoc
      Lien Play Store : https://play.google.com/store/apps/details?id=net.cekage.smsspypoc
    L'application est pour l'instant en Anglais-US. La traduction en français est en cours de tests avec l'outil de traduction intégré au PlayStore.  Notez qu'elle est triviale. 

    2013-02-17

    Lire en loucedé les SMS envoyés par les applications

    Eyes on you, probee ! - © NCIS
    Et si il était possible de lire les SMS envoyés par les applications sans rooter son appareil ?
    Sans décompiler l'application (ça peut mal tourner) !
    Sans installer de coûteux logiciels dédiés aux forensics!
    Sans jouer du fer à souder!

    Et bien, tout cela est possible et c'est même tout à fait simple à faire.

    Cet article, limité à l'envoi d'un SMS texte classique, est en fait de portée générale. En d'autres termes cette note de blog s'articule sur sendTextMessage().

    2013-01-15

    Récupérer les identifiants OMTP/IMAP FreeMobile

    (mise à jour pour les Android récents)




    Plus de 300 téléchargements, un peu plus de 110 installations actives, vous avez rempli votre partie du contrat. À moi de remplir la mienne en vous donnant le modus operandi ET les sources de ce qui est publié sur le PlayStore.

    La récupération est relativement simple:
    1. Envoyer "STATUS:pv=13;ct=free.VVM.10;pt=5499;//VVM" par binarySMS au 2051:5499
    2. Lire les SMS de réponses du 2051
    3. Isoler celui qui match la regexp ".*;u=.*;pw=.*;.*"
    4. Parser les éléments "u", "pw", "srv", "ipt"
    That's all folks !

    Vous pouvez télécharger mon application exemple sur le PlayStore : https://play.google.com/store/apps/details?id=net.cekage.vvmfreemobile


    Le code source est publié sur mon compte github : https://github.com/cekage/net.cekage.vvmfreemobile

    Si vous préférez faire le programme par vous-même, voici le code source :

    La classe principale MainActivity.java

    package net.cekage.vvmfreemobile;
    
    import android.os.Bundle;
    import android.app.Activity;
    import android.content.BroadcastReceiver;
    import android.content.Context;
    import android.content.Intent;
    import android.content.IntentFilter;
    import android.telephony.SmsManager;
    import android.telephony.SmsMessage;
    
    import android.view.View;
    import android.widget.EditText;
    import android.widget.ImageButton;
    import android.widget.ImageView;
    import android.widget.ProgressBar;
    
    /**
     * inspired by
     * http://code.google.com/p/krvarma-android-samples/source/browse/trunk
     * /SMSDemo/?r=37
     */
    
    public class MainActivity extends Activity {
     public static final String TAG = "cekage_FreeVVM";
     EditText etlp;
    
     private String FREEMOBILE_ASKING = "isAsking";
    
     private String FREEMOBILE_DISPLAYED_DATE = "vvminfos";
     ImageButton ibSearch;
     ImageView ivLogo;
     ProgressBar pbAsking;
    
     private BroadcastReceiver smsreceiver = new BroadcastReceiver() {
      @Override
      public void onReceive(Context context, Intent intent) {
       Bundle bundle = intent.getExtras();
       SmsMessage[] msgs = null;
    
       if (null != bundle) {
        String info = "";// "Binary SMS from ";
        Object[] pdus = (Object[]) bundle.get("pdus");
        msgs = new SmsMessage[pdus.length];
        byte[] data = null;
    
        for (int i = 0; i < msgs.length; i++) {
         msgs[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
    
         data = msgs[i].getUserData();
    
         for (int index = 0; index < data.length; ++index) {
          info += Character.toString((char) data[index]);
         }
        }
        updateETLP(info);
        uiAsking(false);
       }
      }
    
     };
    
     public void btnClickFetch(View v) {
    
      SmsManager smsm = SmsManager.getDefault();
      smsm.sendDataMessage("2051", null, (short) 5499,
        "STATUS:pv=13;ct=free.VVM.10;pt=5499;//VVM".getBytes(), null,
        null);
      uiAsking(true);
    
     }
    
     public void btnClickShare(View v) {
      Intent sendIntent = new Intent();
      sendIntent.setAction(Intent.ACTION_SEND);
      sendIntent.putExtra(Intent.EXTRA_TEXT, etlp.getText());
      sendIntent.setType("text/plain");
      startActivity(sendIntent);
    
     }
    
     @Override
     public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
      etlp = (EditText) findViewById(R.id.etLoginPass);
      ibSearch = (ImageButton) findViewById(R.id.btnSearch);
      ivLogo = (ImageView) findViewById(R.id.ivLogo);
      pbAsking = (ProgressBar) findViewById(R.id.pbAsking);
      if (savedInstanceState != null) {
       etlp.setText(savedInstanceState
         .getString(FREEMOBILE_DISPLAYED_DATE));
       uiAsking(savedInstanceState.getBoolean(FREEMOBILE_ASKING, false));
      }
    
      IntentFilter ifDATASMS = new IntentFilter(
        "android.intent.action.DATA_SMS_RECEIVED");
      ifDATASMS.addDataScheme("sms");
      registerReceiver(smsreceiver, ifDATASMS);
    
     }
    
     private void uiAsking(Boolean isAsking) {
      ivLogo.setVisibility(isAsking ? View.GONE : View.VISIBLE);
      pbAsking.setVisibility(!isAsking ? View.GONE : View.VISIBLE);
      ibSearch.setEnabled(!isAsking);
     }
    
     protected void onSaveInstanceState(Bundle bundle) {
      super.onSaveInstanceState(bundle);
      bundle.putString(FREEMOBILE_DISPLAYED_DATE, etlp.getText().toString());
      bundle.putBoolean(FREEMOBILE_ASKING, !ibSearch.isEnabled());
     }
    
     private void updateETLP(String binarymessage) {
    
      String FREEMOBILE_LOGIN = "";
      String FREEMOBILE_PASSWORD = "";
      String FREEMOBILE_SERVER = "";
      String FREEMOBILE_PORT = "";
    
      if (binarymessage.matches(".*;u=.*;pw=.*;.*")) {
    
       String[] separated = binarymessage.split(";");
       for (String param : separated) {
        if (param.startsWith("u="))
         FREEMOBILE_LOGIN = param.substring(2);
        else if (param.startsWith("pw="))
         FREEMOBILE_PASSWORD = param.substring(3);
        else if (param.startsWith("srv="))
         FREEMOBILE_SERVER = param.substring(4);
        else if (param.startsWith("ipt="))
         FREEMOBILE_PORT = param.substring(4);
       }
       etlp.setText(String.format(
         "Login: %s\nPass: %s\nServer: %s\nPort: %s",
         FREEMOBILE_LOGIN, FREEMOBILE_PASSWORD, FREEMOBILE_SERVER,
         FREEMOBILE_PORT));
    
      } else {
    
       etlp.setText(binarymessage);
      }
     }
    
    }
    

    Le layout activity_main.xml:

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:gravity="center_horizontal"
        android:orientation="vertical"
        android:padding="10dp" >
    
        <ImageView
            android:id="@+id/ivLogo"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:src="@drawable/ic_launcher"
            android:visibility="visible" />
    
        <ProgressBar
            android:id="@+id/pbAsking"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:visibility="gone" />
    
        <EditText
            android:id="@+id/etLoginPass"
            android:layout_width="match_parent"
            android:layout_height="0dip"
            android:layout_weight="1"
            android:ems="20"
            android:inputType="textMultiLine"
            android:lines="5"
            android:singleLine="false"
            android:text="@string/et_mask" >
    
            <requestFocus />
        </EditText>
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent" >
    
            <ImageButton
                android:id="@+id/btnSearch"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:background="#0000"
                android:onClick="btnClickFetch"
                android:src="@android:drawable/ic_menu_search"
                android:text="@string/btn_search" />
    
            <ImageButton
                android:id="@+id/btnShare"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:background="#0000"
                android:onClick="btnClickShare"
                android:src="@android:drawable/ic_menu_share" />
        </LinearLayout>
    
    </LinearLayout>
    

    Le manifest AndroidManifest.xml :

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="net.cekage.vvmfreemobile"
        android:versionCode="1"
        android:versionName="1.0" >
    
        <uses-sdk
            android:minSdkVersion="4"
            android:targetSdkVersion="17" />
    
        <uses-permission android:name="android.permission.READ_SMS" />
        <uses-permission android:name="android.permission.SEND_SMS" />
        <uses-permission android:name="android.permission.RECEIVE_SMS" />
    
        <application
            android:allowBackup="false"
            android:icon="@drawable/ic_launcher"
            android:label="@string/app_name"
            android:theme="@style/AppTheme" >
            <activity
                android:name=".MainActivity"
                android:label="@string/title_activity_main" >
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
    
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
    
        </application>
    
    </manifest>