Quantcast
Channel: Applidium
Viewing all 64 articles
Browse latest View live

Lively UITableView

$
0
0

Animations are a central part of mobile applications: screen real estate being expensive, they are used to add meaning to the user interface. They are all over the place in the iOS; but after a few years of use, it would be nice to see something new.

Earlier this month Hakim El Hattab wrote an amazing scroll effects in CSS3 demo that you can try in your web browser (if it’s recent enough). While it works tremendously well on a desktop machine, it isn’t quite ready for mobile yet: browsing that page on an iPhone is rather slow, and worse, makes MobileSafari crash if you zoom in.

Still the concept is pretty awesome, and those demos beg to shine on an iPhone. So that’s precisely what we did.

Even better, we wrote all this code as a clean subclass of UITableView. So using it in your own project is as simple as drag’n’dropping two files, and turning any table view you want animated into a subclass (or an instance) of ADLivelyTableView. You can then pick whichever animation you like (or even build your own custom one).

The code is freely available under a BSD license on our GitHub repository.

Be careful though: they’re refreshing eye-candies, but don’t abuse those animations. Depending on the context, they can do more harm than good. Given your use case, you can also write more subtle transitions: for demo purposes the one shown here are rather bold, but it’s very easy to write custom ones that will better fit your app.


An overview of apps monetization

$
0
0

Mobile applications stores, be it Apple’s App Store or Google Play, allow publisher to sell their apps. Although it is an obvious way to monetize an app, it is not the only one. In this article, we will have a look at the various monetization means that are opened to apps developers.

Paid app

This is the classic and proven monetization method, well-known both by users and publishers. Some apps priced below one dollar have had a staggering success.

  • The model is very straightforward, the revenue is propotional to the downloads
  • 70% for the developer / 30% for the platform
  • Pricing can be different from one OS to the other
  • Some users may be reluctant to buy apps, mainly on Android
  • With paid apps, you are less likely to reach a lot of users

Trial version

In order to promote a paid app, a developer may decide to make a trial/lite/free version. Although limited, it should enable the user to make up his mind about the quality of the app and urge him to buy the paid version.

  • It multiplies the chances that your app will be bought (as long as it is worth it)
  • This model is a particularly good fit for games (levels, maps, characters, items, … )
  • Two versions on the store is a bit heavier for the developer

Advertisement

Often in the form of a banner or an interstitial, ads are used by developers who want to spread their app as largely as possible but still get some income.

  • Mobile advertising companies mostly pay by the click
  • Hard to estimate income from ads
  • Ads must not alter user experience (slowness, misclicks)
  • Ads integration should be part of the development process
  • Ads must be well-targeted

Sponsoring

It is a kind of advertisement that prompts the user to carry out an action against a virtual good. This business model, particularly adapted to games, allows to target the audience very well and potentially to increase the revenue of the developer.

  • Business model particularly suited for games
  • Well-targeted audience, thus ads seem less invasive than purely random ones
  • More users reached, thus potentially more income

Freemium app

This very fashionable business model trades digital content for real money. It is based on Apple’s in-app purchase or Google’s in-app billing, which can be implemented in both paid or free apps. Thus, developers can tune their business model at best. According to a study by Distimo, the freemium model is also more effective on Android than on iOS.

  • Quality apps increase loyalty, thus profit
  • In-app content must be worth the price
  • Purchase process must be simple and fast (as few clicks as possible)
  • 70% for the developer / 30% for the platform at each transaction
  • Experience must be limited but not damaged otherwise the user may end up being frustrated

Ask yourself a few questions before starting

Each of these monetization method has its strengths and weaknesses, which must be measured before publishing an app.

Do you target a niche market?

  • Yes: your app should be paid and relatively expensive (> $1)
  • No: you may consider displaying ads

What value would the audience give to this app?

  • < $.99: you may consider displaying ads
  • otherwise: your app may be paid

Which platform is aimed at this app?

  • iOS: a paid app can be successful. Users usually prefer to pay rather than having ads.
  • Android: a paid app will not be as successful as on iOS. Unlike iOS users, Android users mostly prefer to have ads rather than paying their apps.
  • Windows Phone: it is useless to make a trial version. In-app purchases are not yet available.

Is the app modular?

  • Yes: a trial or freemium version is suitable

Does the app have long-term costs? (use of webservices, push notifications, … )

  • Yes: ads can cover operating costs. It is also possible to consider subscription (recently on Android, quite tricky on iOS)

Finally, it is also possible to combine these monetization means. Disney does it with its “Where’s my water?” app: on the one hand a trial version with ads for other Disney apps, on the other hand a paid version with in-app purchase to unlock new levels. The business model should thus be adapted to the app and to the destination platform.

Introducing Shutterbug for Android

$
0
0

Displaying remote images is one of the top request made to a mobile developer. Most applications need it, be it for user profile pictures or news articles thumbnails. There are already a few implementations out there on Android (see LazyList or WebImageLoader). However, we wanted to hit the sweet spot between API simplicity, robustness, and efficiency. To us, SDWebImage hit it on iOS. That’s why we ported it to Android, leading to Shutterbug.

Shutterbug uses the same structure and interface as SDWebImage, with noticeable changes in the implementation to fit Android’s constraints, mainly on the caching part.

Shutterbug lets you fetch remote images and cache them. It is particularly well suited for displaying remote images in lists, grids, and maps as it includes convenience subclasses of ImageView (FetchableImageView) and OverlayItem (FetchableOverlayItem) that make implementation a one-liner.

The code was released as an Android library project. It is freely available under a BSD license on our GitHub repository.

Free those pins!

$
0
0

Six months ago, we wrote on clustering annotations on iOS maps. We described a very efficient technique to handle huge amounts of pins on an MKMapView, while still keeping a very fluid UI. The actual implementation is fairly complex though, and many developers asked us to share our code. Today, we are happy to release the source code to ADClusterMapView, under a BSD license.

Integrating ADClusterMapView into your code is extremely easy since it’s a subclass of MKMapView. Just add our classes to your project, turn your MKMapView instance into an ADClusterMapView instance, and you are mostly good to go! Using ADClusterMapView might even make your code easier since you won’t have to handle pins addition and deletion.

We added the above demo to the repository for you to give it a try. The data sets come from Paris’ Open Data website. Notice how the mapview runs smoothly even though the second data set contains more than 100,000 elements!

Focus On: WebApp vs Native, Performances

$
0
0

In a bit less than a month, Applidium opens its doors! You’re invited to one of our Focus On, our internal trainings. We will present a detailed analysis of native applications’ performances, compared to web applications.

The two technologies have been debated for years mainly on cost, functional or portability concerns but not that much on performances.

The last example of performance issue is well-known: the Facebook app. As a reminder, here is the quote of Mark Zuckerberg when he announced his company would switch back to a full-native app: “When I’m introspective about the last few years I think the biggest mistake that we made, as a company, is betting too much on HTML5 as opposed to native… because it just wasn’t there. And it’s not that HTML5 is bad. I’m actually, on long-term, really excited about it.”

The Focus On will be presented by two of our developers. They will compare the two technologies focusing on performances, illustrated with benchmarks and a few commonly used algorithms. Slides will be in English but speech in French.

It will take place on Tuesday, December 11th at 7:00 PM, in our Paris office (17 rue du faubourg du Temple, Paris, France). There are few seats and limited room so… first-come, first-served!

If you want to register, head this way !

See you there!

Focus On: Sharing time

$
0
0

It’s been already a week since we presented our first public Focus On (see WebApp vs Native, Performance for more details). It was a great success! The event was sold out in a few days and we had some nice feedback from our attendees. We were asked to make the results of our benchmarks public: here they are!

Focus On: The mobile app checklist

$
0
0

For our first talk of 2013 (March, 20th), we decided to answer a recurrent question: “didn’t I miss something important when building my app?” That’s why we created a checklist of what a good app should and shouldn’t do, summarizing our readings and our own experience.

When you create a mobile application, you ask yourself many questions all along the project.
We picked 10 of them, and made our best to answer them. They range from conception to operation, including design and development.

We’ll give our presentation on Wednesday, March 20th at 7:30 PM, in our Paris office (17 rue du faubourg du Temple, Paris, France). Have a seat, take a pen, and check what you can improve on your app!

Registrations are there: there are few seats and limited room so… as usual, first-come, first-served! We hope to see you there!

Writing an evented web server

$
0
0

You may have heard about Node.js, and how it maximizes scalability. But what is the big innovation behind Node? HTTP servers have been around for a very long time (Apache is nearly 20 years old), what have we been missing for so long?

Let’s re-invent it together!

What is an HTTP server

Writing a proof-of-concept web server is easy. All you have to do is follow those steps:

  • Listen on a TCP port
  • Whenever a client tries to open a connection, accept it
  • Parse the text sent by the client (which is actually an HTTP request)
  • Process said request
  • Reply a textual answer (this is your HTTP response)

Let’s build a sample web server: it will reply “Hello” to any incoming request.

// CAUTION: This code is *extremely* dirty, it's aimed at being as compact as possible//   to get straight to the point. We'll kick you if you use it "for real".#include<stdio.h>#include<string.h>#include<stdlib.h>#include<sys/socket.h>#include<sys/types.h>#include<netdb.h>#include<sys/select.h>//void processRequest(int socket) {
  int requestBufferSize = 8096;
  char * request = malloc(requestBufferSize);
  recv(socket, request, requestBufferSize, 0);
  free(request); // Actually we don't care about the client's requestchar * response = "HTTP/1.1 200 OK/nContent-Type: application/json\n\n{\"hello\": \"world\"}\n";
  send(socket, response, strlen(response), 0); // Let's send our static response
  close(socket);
}
//int main(int argc, char * argv[]) {
  struct addrinfo hints;
  memset(&hints, 0, sizeof(hints));
  hints.ai_family = PF_INET;       // We want an IP socket
  hints.ai_protocol = IPPROTO_TCP; // That'll speak TCP
  hints.ai_socktype = SOCK_STREAM; // TCP is stream-based
  hints.ai_flags = AI_PASSIVE;     // We'll want to be a serverstruct addrinfo * res;
  getaddrinfo("localhost", "8080", &hints, &res); // Let's setup our server on "localhost:8080"int serverSocket = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
  int reuse = 1;
  setsockopt(serverSocket, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
  int status = bind(serverSocket, res->ai_addr, res->ai_addrlen); // Let's bind to the actual socket
  listen(serverSocket, 10000); // And listen. We setup a 10'000 clients bufferwhile (1) {
    struct sockaddr clientAddress;
    socklen_t clientAddressLength;
    // The call to "accept" will *wait* until a client actually knocks on the door of our serverint currentClientSocket = accept(serverSocket, &clientAddress, &clientAddressLength);
    processRequest(currentClientSocket); // Let's process that client
  }
}

As you can see, it’s extremely simple. Granted, we’re doing absolutely no error checking and this code should remain as far as possible from a production environment, yet it does make a point: the core logic of a web server isn’t complicated.

Now, this server makes absolutely no processing whatsoever. Let’s simulate some work: we’re going to write an HTTP server with some delay. Let’s say we’ll answer to clients 5 seconds after we’ve received their request. We won’t do anything at all during said 5 seconds, but it will be a good simulation for some actual work (reading a file from disk for example).

The synchronous model

So, we want to reply 5 seconds after receiving the request. The classical approach is to use the sleep function.

void processRequest(int socket) {
  int requestBufferSize = 8096;
  char * request = malloc(requestBufferSize);
  recv(socket, request, requestBufferSize, 0);
  free(request);
  // And now, some magic...
  sleep(5);
  // Ta-daa! Easy, wasn't it?char * response = "HTTP/1.1 200 OK/nContent-Type: application/json\n\n{\"hello\": \"world\"}\n";
  send(socket, response, strlen(response), 0);
  close(socket);
}

The single process case

Simple, right? Of course. Now what if another client makes a request while we’re still processing the first one? Well, he won’t get any answer: we’re sleeping!

Sub-processes and threads to the rescue

If you ask a developer how to fix this, his answer will most likely be “just fork a thread”. And that does make sense! So our webserver becomes:

pthread_t thread;
while (1) {
  struct sockaddr clientAddress;
  socklen_t clientAddressLength;
  longint currentClientSocket = accept(serverSocket, &clientAddress, &clientAddressLength);
  pthread_create(&thread, NULL, threadRoutine, (void *)currentClientSocket);
  pthread_detach(thread);
}

And it does the job: for each incoming request the server will fork a thread, so it will still be able to process other incoming requests.

This is the way a very large majority of web servers work. Including some refinements of course:

  • To avoid ressource exhaustion, servers generally cap the max number of threads they’ll fork, and they’ll try to re-use threads that are done working (this is called a threadpool).
  • It is also possible to spawn multiple processes, and dispatch the work to said processes.
  • You can even mix’n’match and have multiple processes each having multiple theads.

The asynchronous model

So, problem solved, right? Meh, not really. Turns out using threads and subprocesses comes with a cost. It’s not noticeable at first, but if you use many threads your program will spend a significant part of its time switching contexts, which will end up being a bottleneck. Let’s get back to our “sleep” example: we should be able to handle millions of concurrent users, even with modest hardware, since after all we’re only waiting! But of course if you hit the threaded version of our code with several thousands requests per seconds, it won’t handle the load.

An event loop

Now those of you who have ever done GUI programming will have interacted with an event loop before. This is a programming model that is at the core of iOS and Android development for example. It runs as follow :

  • Your app sets up a bunch of widgets on screen (buttons, text areas, sliders, you name it).
  • And it enters a infinite loop. Inside this loop, it sleeps for a very tiny amount of time. Pretty much like this :
event * queue[100];
int queue_length;
while(TRUE) {
  usleep(1000); // Sleeps for 0.001 secondif (queue_length > 0) { // Check if there is something to do. If there is, do it!
    process_event(queue[0]);
    queue_length--;
  }
}

The process_event function looks at the actual event structure and does the corresponding work. For example, an event could describe the click of a “compute” button, and the corresponding work could be to compute a hash.

On a mobile phone, the magic is in the OS: whenever the user taps the touchscreen, the OS creates an event and adds it to the queue array to be processed by your application.
Notice how most of the time the application uses nearly 0% CPU: every 1/1’000th of a second it awakes for a extremely quick check, sees that the queue is empty, and returns to sleep.

An evented web server

Turns out, that metaphor is a very good fit for web servers! Let’s re-write our sample server using an evented approach:

#include<stdio.h>#include<string.h>#include<stdlib.h>#include<sys/socket.h>#include<sys/types.h>#include<netdb.h>#include<sys/select.h>//void processRequest(int socket) {
  int requestBufferSize = 8096;
  char * request = malloc(requestBufferSize);
  recv(socket, request, requestBufferSize, 0);
  free(request); // Actually we don't care about the client's requestchar * response = "HTTP/1.1 200 OK/nContent-Type: application/json\n\n{\"hello\": \"world\"}\n";
  send(socket, response, strlen(response), 0); // Let's send our static response
  close(socket);
}
//int main(int argc, char * argv[]) {
  // Let's initialize our server. Just like before.struct addrinfo hints;
  memset(&hints, 0, sizeof(hints));
  hints.ai_family = PF_INET;
  hints.ai_protocol = IPPROTO_TCP;
  hints.ai_socktype = SOCK_STREAM;
  hints.ai_flags = AI_PASSIVE;
  struct addrinfo * res;
  getaddrinfo("localhost", "12345", &hints, &res);
  int serverSocket = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
  int reuse = 1;
  setsockopt(serverSocket, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
  int status = bind(serverSocket, res->ai_addr, res->ai_addrlen);
  listen(serverSocket, 10000);
  // So far, no change. Here comes the evented actionstruct timeval timeout;
  timeout.tv_sec = 0;
  timeout.tv_usec = 1000000;
  fd_set readFdSet;
  // Let's define a "responseEvent" structure.// This will store an event describing an HTTP response to be sent.typedefstruct {
    int socket;
    time_t fireTime;
  } responseEvent;
  // And let's create our event queueint eventPoolSize = 1024; // We won't queue more than 1024 events
  responseEvent * eventPool = malloc(sizeof(responseEvent) * eventPoolSize);
  memset(eventPool, 0, sizeof(responseEvent) * eventPoolSize);
  // We're all set. Let's enter our infinite event loop!while (1) {
    FD_ZERO(&readFdSet);
    FD_SET(serverSocket, &readFdSet);
    // The following is equivalent to the "accept" call, except it times out// The "select" call will wait for a new client for 1ms// If none comes in, it'll skip the embedded codeif (select(serverSocket+1, &readFdSet, NULL, NULL, &timeout) > 0) {
      // A new client knocked on our door!// We will *not* answer the client straight away! That's precisely the trick.// Instead, we're going to build a "responseEvent" structure, and process it later on//   when the time will be right.struct sockaddr clientAddress;
      socklen_t clientAddressLength;
      int currentClientSocket = accept(serverSocket, &clientAddress, &clientAddressLength);
      int eventIndex = 0;
      // Let's create a new event. Actually, we're not deleting processed events, we're simply//   setting their "socket" field to zero. So let's just find the first event whose socket//   is equal to zero, and re-use it!for (eventIndex = 0; eventIndex < eventPoolSize; eventIndex++) {
        if (eventPool[eventIndex].socket == 0) {
          break;
        }
      }
      // Mmh, we didn't find any un-used event...if (eventIndex >= eventPoolSize-1) {
        // This may happen if we can't process events as fast as they are created// unfortunately going the evented way won't solve *all* your problems!
        printf("Overflowing queue size !\n");
        return;
      }
      // So, here's our event. We have to populate it with all the data we'll need//  for sending an answer to the client when we'll process it.
      responseEvent * newEvent = &eventPool[eventIndex];
      struct timeval currentTime;
      gettimeofday(&currentTime, NULL);
      newEvent->socket = currentClientSocket; // We'll need that socket to know *where* to reply
      newEvent->fireTime = (currentTime.tv_sec + 5); // And we'll need to know *when* to reply
    }
    // Since "select" times out after 1ms, we'll run this at least once every 1msfor (int i=0; i < eventPoolSize; i++) {
      // We're iterating on all events. We could have sorted them and only process the relevant ones// But we didn't for claritystruct timeval currentTime;
      gettimeofday(&currentTime, NULL);
      responseEvent * event = &(eventPool[i]);
      if (event->socket != 0) { // That event is liveif (event->fireTime <= currentTime.tv_sec) {
          // And it is now the time to reply to that client !
          processRequest(event->socket);
          event->socket = 0; // "Delete" the event
        }
      }
    }
  }
}

This code will perform much, much better under heavy load. Indeed, the only ressource we’re allocating per client is an event structure. Our routine to check for events isn’t the smartest, but it wouldn’t be hard to improve.

Now there is a drawback: as you can see, we’ve significantly refactored our code. No more call to the sleep function: we’re storing an fireTime value, and we regularly check if it matches the current time. This works pretty well in our case, but what if we were doing some actual work?

Let’s elaborate on a more common scenario: a server serving static files. Pretty common, right? Turns out it is strangely similar to our example: most of the time, the CPU is waiting. It’s not sleeping as in our example: it’s waiting for the hard drive to complete its seek operation. But yet, the CPU does pretty much nothing most of the time. So this would be a very nice candidate for an evented web server. But how?

Closure

Turns out the read function call is synchronous. It blocks your process until the data has been read. Exactly like the sleep function did. If you want to go the evented route, you’ll have to use something else: an evented I/O API.

While this is possible in C using callbacks, it is pretty painful to use. Using a language with closure makes it much easier. Think of it this way :

// We're using blocks, which is a proprietary extension made by Apple// to add closure to the C languageint fileDescriptor = open("path/to/my/file.txt", "r");
read_from_file_then(fileDescriptor, ^(char * data){
  // That is a *block*. It represents a piece of code.// That called is called with "data" being equal to the content of the file.// It is called whenever the "read" code has finished
});
// Here is the trick: execution of "read_from_file_then" would return *immediately*// And the call to block would happen "later on", whenever appropriate.

With such an asynchronous API, it becomes much easier to create events that uses blocks to process the response.

So which one should I pick?

Latest doesn’t always mean greatest: evented web servers can be awesome, but they aren’t the answer to every question. Namely, they shine when your CPU stands idle most of the time. Otherwise, if your web server code is CPU-bound, it won’t make a big difference.

Here’s when you should try to use an evented web server:

  • When writing any kind of “proxy” app: retrieving data from an external source, and (quickly) reformatting it.
  • When building a standard DB-backed website, as long as the time taken to generate the view is significantly lower than the time taken to query the database.

Here’s when you should keep away from using an evented web server:

  • When your language doesn’t have closure.
  • When your app is computationally intensive: an image processing webservice for example.

If you have any question or comment, we would be very happy to hear from you : just ping us on Twitter!


Focus On: My app checklist slides

$
0
0

We were really happy to welcome you for our second public Focus On, The mobile app checklist. Thank you for attending! For those of you who couldn’t be there and those who asked for them, you’ll find our slides below.

App Store Apex

$
0
0

Introducing App Store Apex: an awesome visualization of what’s hot on Apple’s App Store!

Aren’t you bored of the old fashionned iTunes ranking? So were we! That’s why we built App Store Apex, a free HTML visualization of the App Store ranking.

It creates a slideshow of the 10 most popular apps on the App Store, and uses the following ones as a background. It’s an enjoyable way to keep an eye on what’s trending on the App Store!

How can I use it?

It’s a very versatile tool. Since it’s a web page, you can use it on your laptop, on your phone, and even make a screensaver out of it since it auto-refreshes every 15 minutes.

It comes with a handy feature: you can pick whichever ranking you’d like. It defaults to the ranking of free apps on the US App Store, but you can easily switch to any other. Just browse to Apple’s RSS generator, pick the feed you’re interested in, then append the URL to http://apex.applidium.com as a “feed” parameter (you’ll have to URL-escape any = sign as %3D).

Here are a few examples:

Why HTML?

Internally we’re displaying this on a flatscreen TV. Using HTML means we can hook up pretty much any hardware to the TV and be pretty confident that it’ll be able to display our visualization.

It’s also been an interesting experiment: even though the performances are good most of the time, the “refresh” action is a bit laggy. Fortunately it only happens once every 15 minutes, but we reached HTML’s limits: no matter how hard we could try, there’s no way to make that reload smooth because JavaScript doesn’t expose any concurrency primitive.

While we’re on the topic of performances, it should be noted that while they’re pretty good on the desktop, we aren’t quite there on mobile yet. Indeed, the animation is kinda smooth on an iPhone 5 (~25fps), but is terribly slow even on the not so old iPad 2.

What’s more?

Last but not least, App Store Apex is open source! We’re eagerly waiting for your pull requests on its GitHub page.

Securing iOS Apps - Debuggers

$
0
0

With about half a billion iOS devices sold across the world, security of iOS applications becomes a major issue. Attacks on an iOS application can be quite rewarding to the hacker, giving him access to secret API keys, disabled functionalities (remember when Skype used to charge a supplement for calling over 3G?), or fake game scores upload.

As mobile developers, we need to have a strong understanding of the way we can protect our applications. That’s why we decided to start a new series of blog posts aimed towards security. Because securing an application implies thinking like an attacker, we will present each subject from both points of view. Today, we will talk about debuggers.

Using GDB to decrypt an application

When an hacker tries to crack an application, he is going to, one way or another, attach a debugger to the running application to interact with it. There are several reasons to use GDB and one of them is to decrypt the binary. In fact, all the apps you download from the App Store are encrypted by Apple and hackers use GDB to decrypt them by dumping the virtual memory of the running app.

In pratice here is what happens if we decide to decrypt an app. First of all, we download the application legally from the App Store and copy it to our computer. Let’s assume here that the name of the application is HackedApp.app. The executable is then HackedApp.app/HackedApp.

This executable is a Mach-O file (see Mach-O File Format Reference) that contains a lot of informations about the application: architecture type, methods virtual addresses, linked dynamic libraries and so on. The otool command line tool is really helpful to disect Mach-O files and to print them in a human readable format. We use the following command to know where the code is located in virtual memory at runtime.

> otool -l HackedApp
HackedApp (architecture armv7):
…
Load command 1
      cmd LC_SEGMENT
  cmdsize 736
  segname __TEXT
   vmaddr 0x00001000
   vmsize 0x0002d000
…

The interesting line here is vmaddr 0x00001000: it means that the application is going to be loaded in virtual memory at address 0x1000.

Then the following command will tell us whether the executable file is encrypted or not, and where the encrypted data for architecture armv7 are:

> otool -arch armv7 -l HackedApp | grep crypt
cryptoff  4096    # offset where encrypted data begin
cryptsize 180224  # size of encrypted data
cryptid   1       # 1 if encrypted, else 0

In this case the encrypted data begin at address 4096 = 0x1000 and have a size of 180224 = 0x2C000 bytes. To compute the range of addresses where the decrypted data are located, we need to do a tiny bit of math. We need to dump the virtual memory between addresses 0x1000 (vmaddr) + 0x1000 (cryptoff) = 0x2000 and 0x1000 (vmaddr) + 0x1000 (cryptoff) + 0x2C000 (cryptsize) = 0x2E000.

In order to do that, we launch the application on a jailbroken device, attach GDB to it and call the dump memory command.

> ps -ax | grep HackedApp
15714 3:14.31 /var/mobile/Applications/UUID/HackedApp.app/HackedApp
> gdb -p 15714
...
Attaching to process 15714.
Reading symbols for shared libraries . done
Reading symbols for shared libraries ..........................................
......................................................................... done
0x39f5cd82 in <redacted> ()
gdb> dump memory dump.bin 0x2000 0x2E000

The dump.bin file now contains the decrypted data of the application.

There are two more steps to finish cracking the application. First, we need to replace encrypted data with decrypted data in the binary. For this, we use the dd command like this:

> dd seek=0x2000 bs=1 conv=notrunc if=./dump.bin of=./HackedApp

Second, we have to change the cryptid value to 0 (this can be easily achieved with an hexadecimal editor).

Once all of these steps performed, the application is totally decrypted and we have access to our ultimate goal: its symbol table. It means that we have access to all the method names and string constants the developer of the application wrote in his code. To extract class interfaces from the symbol table, we use the class-dump-z tool (available here):

> class-dump-z HackedApp
…
@interface XXUnknownSuperclass : MyCustomClass
+(id)customMethod1;
+(id)customMethod2;
@end
@interface XXUnknownSuperclass (MyCategory)
+(id)customMethod:(float)param;
@end
…

Nothing easier for us, at this point, to set breakpoints in GDB on specific methods, intercept function calls, and alter the application behavior. If we know the name of the methods and the classes that the developers used in their code, it will be pretty easy for us to understand what the application does behind the scene and how it does it.

Defeat GDB

There are two things to know when dealing with GDB:

  • First, when an application is being debugged, the kernel is aware of this and changes the state of a specific flag: the P_TRACED flag (declared in proc.h). This flag is set to 1 if a debugger is attached to the process and to 0 if the application runs normally. You can monitor the state of this flag, check if GDB is attached to your application and perform custom actions to limit the features if it is the case.

Here is an example of function that monitors the value of the P_TRACED flag:

#include<sys/sysctl.h>int isDebuggerPerforming() {
    struct kinfo_proc infos_process;
    size_t size_info_proc = sizeof(infos_process);
    pid_t pid_process = getpid(); // pid of the current process//int mib[] = {CTL_KERN,        // Kernel infos
                 KERN_PROC,       // Search in process table
                 KERN_PROC_PID,   // the process with pid =
                 pid_process};    // pid_process////Retrieve infos for current process in infos_process int ret = sysctl(mib, 4, &infos_process, &size_info_proc, NULL, 0);
    if (ret) return0;             // sysctl failed//struct extern_proc process = infos_process.kp_proc;
    int flags_process = process.p_flag;
    return flags & P_TRACED        // value of the debug flag
}
  • Second, we can directly disable any debugger currently or later attached to an application with the ptrace() function and the PT_DENY_ATTACH parameter. If a debugger is being attached to an application, a call to ptrace(PT_DENY_ATTACH, 0, 0, 0) will send a ENOTSUP signal and quit the current process. In the other case, if the application is running and a debugger tries to attach to it, a segmentation fault will occur.

Here is an example of using ptrace on iOS.

#include<dlfcn.h>void disableDebugger() {
    void * handle = dlopen(0, RTLD_GLOBAL | RTLD_NOW); // load dynamic librairiesint (* ptrace_function)(int, pid_t, caddr_t, int); // ptrototype of ptrace function
    ptrace_function = dlsym(handle, string);           // pointer on ptrace function
    ptrace_function(31, 0, 0, 0);                      // PT_DENY_ATTACH == 31, not defined in iOS
    dlclose(handle);
}

What’s next ?

In this article, we saw how hackers decrypt applications with GDB to take control over them and we presented two solutions to prevent debugging of an application. However, an attentive reader will spot that these solutions are not completely flawless: an obstinate hacker will certainly look for ptrace or sysctl calls in your application and set breakpoints in GDB to change their return values, bypassing your protections. This shows that security is basically a cat and mouse game, where we can only complexify the work of the hacker.

We hope you liked this first episode of our new series. We only covered a small part of the subject, debuggers not being the only tools capable of changing the behavior of an application at runtime. Furthermore, there are other approaches like patching the application binary itself, which makes room for future episodes!

Anyway, if you have any question or just want to share a comment, we’ll enjoy to hear from you on Twitter!

Clean up your phone

$
0
0

Our friends from Share your Office are organizing the first Clean your Office International Day on May 24th. As office mates, we would like share this great initiative and spread the word. Feel free to join the movement! (link in French)

Moreover, we decided to contribute to this cause and push the idea to the next level. Nowadays our mobile phones are our first office, so we would like to invite you to clean up your smartphone!

We are constantly swiping through 10 screens on our phone’s springboard to find out the right app (or are bond to using Spotlight anytime we want to reach something). Here is a set of advise to clean up your phone’s homescreen:

  1. Have a deep look at each of your apps and ask this question to yourself “How many times did I use this app during the last month?”. You will delete useless apps at first sight.
  2. Sort and use apps folders for dedicated contexts such as Work, Family, Travel.
  3. Some weird minds sort their apps by the icon color: find out your own mnemonics.
  4. Set yourself a goal: for instance, you aim at reducing the screen number by a factor of 2. If it’s too difficult, iterate during severals days, removing 5 apps per day.

You should be all set! You phone is now fully operational for high productivity! So don’t forget: on May 24th, clean up your phone!

Then, you may find some room for one of our games, who knows ;-)

Discover our showreel 2013!

$
0
0

We’ve been designing and developing fascinating mobile applications for more than 3 years. We’ve worked hard to made them intuitive, useful and responsive and that’s why they’ve convinced millions of users.

We are proud to present some of them through this video: don’t hesitate to share it!

Mobile Design at Web2day

$
0
0

We were kindled invited to the web2day, an annual festival dedicated to the digital world gathering over a thousand attendees in Nantes, France on May 16th & 17th.

Organizers gave us the opportunity to talk about “the future of mobile design”. We asked a pool of experts (that share the ambition to build both effective and innovative interfaces) to join us at the table in order to give a global overview on the topic.

We started by a short history of mobile design, from devices to interfaces, illustrated by practical apps use cases, to set up the global context. Then, we covered the following topics:

Trending topics

Skeuomorphism and flat design are currently the two major trends and a short-sighted analysis would tend to oppose the two currents. After a presentation on their impact on interface design, panelists agreed upon the complementarity of the two movements, as the final objective remains to propose the most convenient interface.

Guidelines compliance

You’ve all heard of the user interface guidelines defined by vendors in their respective SDKs. Guidelines first aimed at simplifying the end user experience by ensuring a global consistency among apps. Nevertheless, as apps are getting popular, users became familiar with mobile interactions, especially the younger folks, and started seeking for novelty. This phenomenon, combined with the developers’ willingness to push more complex and differenting products, turned out to propel new interface paradigms and gimmicks created by the app makers community. For instance, gestures like Twitter’s pull-to-refresh or Facebook’s sidebar menu, now both very popular, were pushed by the community, not OS guidelines.

As the discussion went on, the metaphor of mobile design as a language (with a common grammar and neologisms) appeared to be a shared view within the panel.

The future of mobile design

Internet of things, augmented devices… Will the mobile interface that we know today disappear in the near future? For our panelists, these innovations will definitely bring new opportunities. The mobile interface will be global: on, but also around, the device itself. One scenario could be that the smartphone will become a connection hub linked to our various devices. Nevertheless, panelists all agreed that mobile interfaces would remain for a while.

The video of the session is available online, we’d like to thank Geoffrey Dorne, Jérémie Francone and Olivier Desmoulin for accepting our invitation as well as the web2day team for the organization. See you next year!

App Makeover #01 - iOS 7

$
0
0

As you know it, in a few days Apple will put an end to all rumors about the upcoming iOS 7 design. Just a few days to wait for someones, still a few days for others. For this last ones, and for our pleasure too, we decided to contribute our ideas to what will and should change in the next major release of iOS?

  • Based on Tim Cook announcement at D11 about Apple opening up APIs, we truly believe that widgets should be coming to the dashboard
  • We think that big changes have to be done and will be done on settings management
  • There’s no need to talk again about Flat Design
  • Apple will probably keep a consistency from iOS 6 to iOS 7, both for graphical issues and user experience…

But we are just guessing!


Introducing iOS 7 GUI PSD

$
0
0

Eager to start prototyping your next iOS 7 app? Wait no more! Today we would like to share a first version of our iOS 7 GUIPSD with all the designers and developers who are already working on iOS 7 like we are.

You can download it right here:

ios7_gui_psd_v1.zip

476.88 KoDownload

For this first version, you will find the following elements:

  • Status Bar
  • Navigation Bar
  • Search Bar
  • Tool Bar
  • Tab Bar
  • Scope Bar
  • Segmented Control
  • Progress Bar
  • Slider
  • Switch
  • Stepper
  • Alert Popup
  • Keyboard
  • Control Center
  • List view

So fire up Photoshop and start designing awesome apps! And while we are working on the next version feel free to give us your feedback on Twitter!

UINavigationController with custom transitions

$
0
0

For iOS developers, UINavigationController is a great tool to manage hierarchical content and navigate through an application. However, some of us may get a little bored watching the same classic push/pop animation over and over. Enters ADTransitionController: we’re giving you a drop-in replacement for UINavigationController featuring custom transitions.

Visit the project website for more information about the available transitions and how to include it into your projects. iOS developers will feel at home with ADTransitionController as it provides a similar API to UINavigationController. You can create your own transitions or use one of the transitions we implemented for you.

To create a transition, just subclass the ADTransition class. You can play with opacity, transforms or position animations to create various transitions: 3D, fades in/out, rotations, flip, and so on. The code is freely available under a BSD license on our GitHub repository. We already have some nice ideas to take advantage of the new APIs of iOS 7.

Be creative and imagine new transitions. We’d love to see your ideas!

VLC is back on the App Store!

$
0
0

On October 25th, 2010 we unveiled VLC for the iPhone. Unfortunately, less than 3 months later, Apple pulled VLC off the App Store because of a legal grey area between VLC’s license at the time (the GPL v2) and the App Store Terms of Service.

Fortunately, thanks to the efforts of the community, VLChas recently been re-licensed under a more permissive license, the LGPL v2.1. This is a very significant move, as this required getting the simultaneous authorization from over 500 different contributors. That new license gets rid of the clauses that were problematic with the older one, therefore opening the way for a re-submission of VLC on Apple’s App Store.

We’ve taken our time to get a version two ready, and actually we haven’t been the only ones hard at work since we’ve partnered with members of the open source community to bring you a bunch of very nice improvements. In VLC for iOS, you now can:

  • Password-protect your media library
  • Upload your media files without using iTunes thanks to an embedded web server
  • Sync VLC with Dropbox and get all your content easily
  • Decode your media much, much faster since VLC now uses a multithreaded decoding architecture and offloads parts of the decoding job to the GPU

VLC Media Player

iPhone and iPad, v 2.0.0Download on the App Store

This new version was the opportunity to move the app from our iTunes account to VideoLAN’s, so don’t be surprised if you don’t get an update in the App Store. And last but not least, the source code is publicly available and kindly hosted by VideoLAN in a git repository. Patches are welcome!

HeaderListView for Android

$
0
0

Today we’re open sourcing HeaderListView, a library that adds sections and persistent headers to Android’s ListView. Persistent headers are section headers that stay visible at the top of the ListView when you scroll through its section, then go away when you’ve scrolled past the relevant content, exactly like they do on iOS.

The library comes under a BSD license, and contains two classes: HeaderListView which is a replacement for ListView that has persistent headers and SectionAdapter which is an adapter that you can use with any ListView subclass in order to add sections and sections headers.

Checkout the project website to discover the API and download the demo. You can immediately take advantage of the persistent headers by replacing your ListView with HeaderListView and by implmenting a SectionAdapter subclass.

Android Manifest's impact on the availability of an app

$
0
0

In this blog post we will focus on ensuring that your app is distributed to as many people as possible or at least, know who will not receive it. Indeed, fragmentation is so strong in Android’s ecosystem that a sizeable number of potential users may easily be put aside. Google provides parameters and tools to help prevent both software and hardware fragmentations issues. The Android Manifest is one of these tools, which we will analyze here.

The Android Manifest is a description file containing necessary information for the system. But it also contains parameters impacting the distribution of your app. For example, here is an Android Manifest, shipping with Shutterbug, of our Open Source projects.

Before reading further, bear in mind that an API level is a number identifying the framework API revision. Generally, each new revision adds functionalities. You can find a table indicating the correspondance between the OS version and the API level here. Here are settings likely to reduce the availability of your app.

Minimum API level

<uses-sdkandroid:minSdkVersion="7"android:targetSdkVersion="15"/>

The minSdkVersion parameter specifies the minimum API level on which the application is able to run (default is 1). A specific API level may be required to use functionalities which were not available in older versions of Android. Thus, by choosing a set of functionalities you choose a minimum Android version. If you want your app to be available on a given percentage of devices, you will be limited in terms of functionalities. If not set, the app may be available on devices missing some APIs, resulting in crashes.

Link between API level and functionnalities

Summary of the most important features added by API level

Each API level introduces a bunch of new APIs. Here is a summary of what was added in the most important API levels:

API level Android versionFeatures
Level 8Android 2.2 FroyoApps on external storage, Push notifications
Level 9Android 2.3 GingerbreadNFC reading support
Level 11Android 3.0 HoneycombActivity fragments, Action bar, HTTP Live Streaming
Level 12Android 3.1 HoneycombResizeable home screen widgets
Level 16Android 4.1 Jelly BeanExpandable notifications
level 17Android 4.2 Jelly BeanLock-screen widgets, Miracast support (wireless display)

Examples

For instance, for an application willing to receive push notifications, API level 8 is required. Only 1.5% of devices will not see your app on Google Play, which is very reasonable.

If you want to make an app able to read HLS you will probably need to use features available in API level 13. Thus roughly 40% of people (as of July 2013) will not see your app on Google Play.

That may seem to be a big number but remember:

  • This is a number counting all the connections to Google Play around the world
  • If you begin developing your app now, Android 4.0+ devices will get more and more users
  • If video live streaming is the core feature of your app, you have hardly another choice

Permissions and features

<uses-permissionandroid:name="android.permission.INTERNET"/><uses-permissionandroid:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

Permissions are used to ask access rights to components (e.g camera, bluetooth, internet, …).

Features (available from API level 4) indicate required or facultative features (hardware or software). These are used for filtering on Google Play. It is not mandatory to mention features, since they are often implied by permissions.

Regarding hardware features, Google advises to explicitly declare them rather than relying on Google Play to “discover” them. They even put up a table explaining the relationship between permissions and features. For example, ACCESS FINE LOCATION permission implies the android.hardware.location.gps and android.hardware.location features.

Why is it important to explicitly declare hardware features?

Because permissions can prevent your app from being available on devices you wanted it to be! If you have a feature in your app which is not part of the core experience, make it optional. For example, phone call permission will prevent tablets to see your app in Google Play. A less obvious example is the camera on the Asus Nexus 7: it has a camera in front of the device but not in the back. Thus, camera permission will make your app unavailable for Nexus 7.

Supported screens

You should always indicate the screen sizes your app supports. By default, parameters for small and normal screens are set to true. The definition of small, normal, large and xlarge screens is quite vague because it is defined by OEMs. But you can consider that small, normal are for smartphones and that large, xlarge are for tablets. Here’s a figure from Google to give you an idea of the mapping between size and generalized size.

Depending on your strategy (which you should before starting your project), you may want:

  • the same layout for all screen sizes: simple and fast but you do not take advantage of larger screen real estate. Below is a comparison of the Now Playing screen from Spotify’s app on a LG Nexus 4 and a Asus Nexus 7. It is exactly the same layout, so you can notice a waste of space on the tablet in landscape.
  • a single app handling multiple layouts for different screen sizes: same core but different UI. It also means that it must be an Android 4.x app.
  • multiple apps: smartphones + tablets, or Android 2.x + Android 4.×. The point is to address a maximum of your potential users and propose a fresh UI and new features to Android 4.x users. Development cost is higher and maintenance is made harder since you have two different projects.
Viewing all 64 articles
Browse latest View live