Decrypting IOS app to access Class Information

The purpose of this post is to shed some light on the process of accessing the inner details of the source code of an IOS app, any third-party libraries it uses, and how it was designed.

You are probably asking yourself what could be gained from doing so and the answer may differ from one person to another, whether it is pure admiration of a cool app, checking if an app has any malicious or sketchy code that would warrant concern to the user, etc.

For the purpose of this tutorial, I will be using

To begin, we need the following:

  • A Jailbroken idevice
  • Cydia packages
    1. BigBoss Recommended Tools (From BigBoss Repo)
    2. classdumpz (From cydia.radare.org repo)
    3. Core Utilities
    4. GNU Debugger (From cydia.radare.org repo)
    5. OpenSSH
    6. OpenSSL
  • An FTP client on Windows or Mac OS X

If you do not have a jailbroken device, you will need to do so by visiting idownloadblog at the following link

Once you have jailbroken your device, head on to Cydia and install the packages included above, I faced several issues with the decrypting applications in IOS 7 due to some incompatibilities between IOS 7 and the debugging tools in the BigBoss repository which is why I included GNU Debugger from cydia.radare.org even though a version exists in BigBoss.

For example: The GNU Debugger installed with “BigBoss Recommended Tools” is at this moment 1518-12, however, the compatible version that works with IOS 7 is 1708.

Now let’s start decrypting the application:

The first step is to find the application of interest, usually it could be found in /Application but as you can see in the screenshot below, MaaS360 is nowhere to be found:

 ls /Applications 

List Applications

So we will use the find command to locate the app in question:

 find / -name "Gmail*" 

Figure 2 Find ApplicationsNote: A more complex command but more accurate method of finding the application is:

 find / -type d -iname "Gmail*.app" 

Aha we found the directory, under /private/var/mobile/Applications/CAF8206F-8348-4AB4-B167-2FE77D15DDBB/GmailHybrid.app

For those wondering, the “CAF8206F-8348-4AB4-B167-2FE77D15DDBB” is the GUID for the MaaS360 application which is short for “Globally Unique Identifier”, a unique 128-bit number to represent that application.

We would then go into the directory and find what architectures are in the binary and whether the application uses “PIE” (Position Independent Executables) which means the app’s code, data, and stack memory addresses are changing every time you run the app using randomization. This provides an additional layer of security/protection as it makes Return Oriented Programming (ROP) attacks much more difficult to execute reliably and the decryption of these applications difficult as well.

 otool -arch all -Vh GmailHybrid

Figure 3 Find architecturesLuckily the application was only built for one architecture (ARM), otherwise you would need to find and decrypt the architecture that matches the device you are running it on (Possibly a blog post for another day)

It does however show me that the application was packaged using PIE which will affect change how we get the base address later in this article.

Next we will display the status of the application’s encryption

 cd /private/var/mobile/Applications/CAF8206F-8348-4AB4-B167-2FE77D15DDBB/GmailHybrid.app
otool -l GmailHybrid | grep crypt

Figure 4: Show EncryptionThe cryptoff shows that the first byte of encrypted data is 16384 bytes into the file (0x4000 in hexadecimal)

The cryptsize shows 13828096 bytes is the size of the file that is encrypted after the offset defined by the cryptoff

The cryptid shows that the application is indeed encrypted (1 is encrypted, 0 is unencrypted).

If we try to access the class information now, we wouldn’t get much

Figure 5 Encrypted Class Info

Now we will need to determine the base address which we will do by running the application and seeing where it gets loaded into the memory

 # Look for running processes that have GmailHybrid in their name
ps -ax | grep GmailHybrid

This showed that MaaS360 is running under process id 336

336 ??         0:07.74 /var/mobile/Applications/CAF8206F-8348-4AB4-B167-2FE77D15DDBB/GmailHybrid.app/GmailHybrid
478 ttys003    0:00.01 grep GmailHybrid

# Load the process with process id 336 into the debugger tool
gdb -p 336

Figure 5 Get Base AddressNow we will need to find the base address by running “info sharedlibrary” but the output is rather large and will scroll off the screen so we will first set the pager to 20 lines

(gdb) set height 20
(gdb) info sharedlibrary

Figure 6 Get Base Address Part 2So how we know that the base address is 0xb000 (45056), we would then calculate the start and end section of the memory that has the unencrypted version of the application. Remember we had found the cryptoff to be 16384 and cryptsize to be 13828096.

Start address = base address + cryptoff = 45056+16384=61440

End Address =base address + cryptoff + cryptize = 45056+16384+13828096= 13889536

Now we need to dump that memory section:

(gdb) dump memory decrypted.bin 61440 13889536

Congrats, now you have a decrypted version of the application stored in that decrypted.bin file. Since we are done with the application, we can safely kill it and then quit the debugger

Figure 8 Kill ApplicationIt is now a good idea to take a backup of your application file in case something went wrong, you can do so by opening up your favorite ftp client application and browsing the application directory then copying it locally on your PC.

The next step would be to overwrite the decrypted version over the encrypted one inside the application file.

Again remember the cryptoff is 16384 which means we will need to skip those number of bytes when writing back to the application

 dd seek=16384 bs=1 conv=notrunc if=./decrypted.bin of=./GmailHybrid 

If all goes well, you should be able to still use otool on the application, however, the cryptid is still 1 because the application still thinks it is encrypted.

To solve this problem, we will use the ftp client to copy the modified application to your desktop and load it in a hex editor, for the purpose of this part I used “Hex Workshop”.

We will then look for the following hexadecimal value “010000000C00000034” which should be right before “/usr/lib/libresolv.9.dylib” shown in the figures below:

Once found, we will replace the 01 with 00 and try rerunning the otool command

Figure 9 Show Unencrypted

 otool -l GmailHybrid | grep crypt 

Now if we try to access the class information now, we will see a HUGE difference:

Figure 10 Show Class Infomation

Now you can explore the class information of your application to find possible security exploits that you can use to your advantage.

If you have any problems, questions, or concerns please leave a comment below.

Sources:

Decrypting apps on iOS 6 – Part 1: single architecture

Reversing iOS Applications (Part 1)

Dumping Class Information for Encrypted iOS Applications

Found this post useful?

Subscribe to our RSS feed, follow us on Twitter or help us grow by sharing our content using the buttons below

This entry was posted in Apple, iPad, Jailbreak, Security and tagged , , , , , , , , , , . Bookmark the permalink.

23 Responses to Decrypting IOS app to access Class Information

  1. Adam says:

    “/usr/lib/libresolv.9.dylib” does exsist

  2. Adam says:

    where can i found my zhit? all good but what is that We will then look for the following hexadecimal value “010000000C00000034″ which should be right before “/usr/lib/libresolv.9.dylib” shown in the figures below: ?? where u got it??

    • Not sure I understand the exact question but I listed my sources at the end of the article.

      The 010000000C000000034 is a unique location in the hex code of the app file that stores the value for the cryptid (Status of encryption 1 for true and 0 for false) which is why we changed that 01 to 00. It is telling the operating system that the app is not encrypted anymore

  3. Adam says:

    yes i”m suks found all now is criptid 0 but with this line “otool -l “myappname” | grep crypt” got black screen

  4. Adam says:

    all good man 🙂 but this line “otool -l GmailHybrid | grep crypt” show mw black screen

  5. Adam says:

    cryptoff 8192
    cryptsize 4997120
    cryptid 0

    the line class-dump-z “mystuff” | more give me black screen no informations

  6. Adam says:

    can you replay me at alin.adam@gmail.com please

  7. Jeff Neil says:

    I am getting an error on the gdb step that is illegal instruction: 4. I have tried the remedy here:

    http://www.infointox.net/?p=114

    and here:

    http://stackoverflow.com/questions/14710849/get-gnu-c-compiler-working-on-ios-6-x

    With no success, still getting illegal instruction 4. Any thoughts?

    • Hello Jeff,

      Normally, that error is an incompatibility of gdb with the iOS device architecture.

      What version of GNU Debugger do you have installed in cydia? In the beginning of the post, I recommended the one found on GNU Debugger from the cydia.radare.org repo (Version 1708 is the latest as of date)

      If you have a version lower than 1708, I recommend updating to it first and try running gdb again.

      Another possible reason you could be getting that error is due to having a device with A6/A6X Chip or higher (iPhone 5, 5C, and 5S) which supports only ARMv7 and not ARMv6 instruction sets so try running the gdb with the -arch flag (For example “-arch ARMv7”).

      Let me know how it goes and if needed, you can contact me directly via email at tmrashed@gmail.com with the output of the following commands:

      otool -arch all -Vh
      otool -l
      | grep crypt

      Thanks for commenting and hope to hear from you soon

      • Jeff Neil says:

        Updated to version 1708, problem solved. Thanks!

      • Cyb3r says:

        Hello Timour, i have the same problem and i’m searching for 3 days till now, i can’t decrypt any app cause i cannot dump anything, getting error “illegal instruction: 4”, my device is iPhone 5s which an 64-bit, so i think this is the probelm i don’t know, thanks in advance.

  8. vamitrou says:

    Great post, thanks for sharing and please keep up the good work 🙂

    As far as I understood, the encrypted part of the application is decrypted before is loaded into memory, right? But how the application continues working when we replace the encrypted part with the decrypted?

    Regarding your guide, I cannot seem to find the “010000000C00000034” value in the GmailHybrid (not even /usr/lib/libresolv).

    I also noticed that the cryptsize is a lot smaller in my case (~2M, while yours is ~13M).

    Also the first 2.423 bytes of the decrypted.bin is empty, does this make sense?

    I am using 7.0.6 on iPhone 5s.

    Thanks!

    • Hello vamitrou, your welcome. Glad you found the post useful.

      That’s right, the main idea is that the iphone itself can not work with the application until it is decrypted. So what we do is let the iphone do the heavy lifting of decrypting of the application which it then stores a copy of in the memory.

      We then take the opportunity of having a decrypted out for grabs and dump it into a file (Take our own copy for later use)

      We then replace the encrypted part with the decrypted one and then mark the application as not encrypted.

      The reason why the application still works is that when it is loaded, the iphone looks at that 01 or 00 flag header in the value before “/usr/lib/libresolv.9.dylib” and figures out it is not encrypted and copies the application as is into the memory.

      Regarding your concern with not finding the “010000000C00000034″ value in the GmailHybrid nor the /usr/lib/libresolv, please feel free to send me an email with the output of this command “dd seek=16384 bs=1 conv=notrunc if=./decrypted.bin of=./GmailHybrid” and I will take a look at it and resolve the issue.

      Regarding the cyptsize, it doesn’t matter what the actual size is, however, it is important to take a note of it since it is used to calculate the end address as follows:

      End Address =base address + cryptoff + cryptize

      Which will then be used in the dumping of the memory
      (gdb) dump memory decrypted.bin 61440 EndAddress Value

      dd seek=16384 bs=1 conv=notrunc if=./decrypted.bin of=./GmailHybrid

      Hope that helps and if you need to send me a direct email, you can reach me at tmrashed@gmail.com

  9. Ecko says:

    Hello friends,

    for the value “010000000C00000034″ mine is “010000000C00000030″ I’m not sure if it’s the same value for all. keep an eye on “010000000C000000XX″ in the first few lines if u found anything similar change “01” to “00” and test it with otool.
    I need help the decrypted file crash :@ ???!!!
    otool -l GmailHybrid | grep crypt
    cryptoff 16384
    cryptsize 2129920
    cryptid 0

    • Hello Ecko, please share the exact steps you did while decrypting the application.

      A crashing of the decrypted application, may indicate an incorrect dumping and overwriting of the memory.

      Did you make sure to calculate the start and end addresses correctly?

      In your case, it would be:

      Start Address = base address + cryptoff = base address +16384

      End Address =base address + cryptoff + cryptize = 45056+16384+2129920

      Then dump that section of the memory:

      (gdb) dump memory decrypted.bin “Start Address” “End Address”

  10. Ecko says:

    Hello friends again, :p

    I finally solve the brb 😀 I change ACCESS PERMISSIONS in ifile to: READ,WRITE,EXECUTE & it works fine 😀
    ex:
    User ==> READ,WRITE,EXECUTE
    Group ==> READ,WRITE,EXECUTE
    World ==> READ,WRITE,EXECUTE

  11. Eddy says:

    Hey Timour,

    I followed your steps, but got stuck on attaching gdb to my app. I always get an segmentation fault:11?!? Can you tell me how to avoid this and what this for an error is? Google says somthing about bad pointer adresses and so on.
    Thanks for your help.

    Eddy

  12. radj says:

    Thanks for the article! I understand the whole point now especially with your response to @vamitrou.

    Question though: what if it’s a fat binary with multiple architectures? How does the cryptoff/cryptsize factor into that?

  13. Great post! Thank you!

    But I fail in the last step i guess.

    otool arch result:

    magic cputype cpusubtype caps filetype ncmds sizeofcmds flags
    MH_MAGIC ARM 9 0x00 EXECUTE 41 4728 NOUNDEFS DYLDLINK TWOLEVEL PIE

    cryptoff 16384
    cryptsize 6733824
    cryptid 1

    base address = 0x84000 = 540672

    Start address = base address + cryptoff = 540672 + 16384 = 557056
    End Address = base address + cryptoff + cryptize = 540672 + 16384 + 6733824 = 7290880

    dd seek=16384 bs=1 conv=notrunc if=./decrypted.bin of=./iStick
    6733824+0 records in
    6733824+0 records out
    6733824 bytes (6.7 MB) copied, 107.798 s, 62.5 kB/s

    But I can’t seem to find the ‘010000000C00000034’ value in the HEX editor.

    What could I’ve been doing wrong?

  14. GodCoderX says:

    What does the following passage mean?

    Luckily the application was only built for one architecture (ARM), otherwise you would need to find and decrypt the architecture that matches the device you are running it on (Possibly a blog post for another day)

Leave a Reply to Adam Cancel reply