you're reading...

Decrypting apps on iOS 6 – Part 2: multiple architectures and PIE

Things explained in the part 1 could be skipped.

Multiple architectures and PIE

In case apps support multiple architectures, you need to choose the right architecture working on your device to find the right cryptid/cryptoff/cryptsize. You should also check if an app under test is built with PIE (Position Independent Executables) as the app’s code, data and stack memory addresses are changing every time whenever you load the app. If an app supports PIE, you have to know the exact memory address the app is loaded at to calculate the offset of the decrypted area.

Let’s take a look at a sample app.

Log into your jailbroken device via ssh, and go to the directory where an app you want to decrypt resides. The directory will be under “/var/mobile/Applications/”. Copy the executable to your Mac.

Run otool to see how the app is built on your Mac (see Figure 1).

Screen Shot 2013-01-27 at 12.12.44 AM

Figure 1. Initial analysis with otool

You can find this app supports two architectures (nfat_arch 2) which are armv7 and armv7s. Run the app and attach gdb to see which architecture is used (Figure 2).

Screen Shot 2013-01-26 at 11.21.45 PM

Figure 2. architecture used

If you confirmed armv7 was picked, kill the app and quit gdb.

Run “otool -arch armv7 -l ColorLEDFlashlightPro | grep crypt” to get the encryption data (Figure 3) and confirm this app is encrypted.

Screen Shot 2013-01-26 at 11.49.42 PM

Figure 3. Encryption data

So far we have found which instance of program we should select (Figure 1) and its cryptoff (8192) and cryptsize (3047424).

Let’s check PIE for this app by using otool again (Figure 4).

Screen Shot 2013-01-27 at 12.32.20 AM

Figure 4. PIE check

You can see this app is built with the PIE option.

Check the loading address in the file’s header using “otool -l” (Figure 5).

Screen Shot 2013-01-26 at 11.12.32 PM

Figure 5. base address

Based on Figure 5, you can expect the app will be loaded at 0x1000. Run the app and attach gdb to check if the app is loaded at 0x1000 (see Figure 6).

Screen Shot 2013-01-26 at 11.21.45 PM

Figure 6. attach gdb

Try to read some data at 0x1000, 0x2000 and 0x3000 (Figure 7).

Screen Shot 2013-01-26 at 11.28.49 PM

Figure 7. reading memory 0x1000, 0x2000 and 0x3000

As you see, you can’t access those addresses. Let’s find out where the app is loaded using “info sharedlibrary” (Figure 8). You can see the app is loaded at the address, 0x4f000 not 0x1000.

Screen Shot 2013-01-26 at 11.33.03 PM

Figure 8. info sharedlibrary

Now you can read data from the loading address (Figure 9).

Screen Shot 2013-01-26 at 11.36.19 PM

Figure 9. Reading memory

It’s time to calculate the starting and ending address we will dump. The app’s base address is 0x4f000 and its cryptoff (8192 or 0x2000) and cryptsize (3047424 or 0x2e8000). Hence we should dump memory between 0x51000 (the base address + cryptoff) and 0x339000 (the base address + cryptoff + cryptsize)

Run the following instruction on gdb.

dump memory decrypted2.bin 0x51000 0x339000

Copy the dumped file to your Mac. Before you overwrite the app’s executable, let’s run class-dump-z and confirm it is encrypted (Figure 11).

$ ./class-dump-z ColorLEDFlashlightPro

Screen Shot 2013-01-27 at 12.53.47 AM

Figure 11. class-dump-z result

There is a difference between an app for a single architecture and an app for multiple architectures. A starting offset of a program instance is 0 for a single architecture case, but the starting offsets for the program instances in an app supporting multiple architectures differ. You should check the starting offset of the program instance you deal with.

Overwrite the executable with the dumped file. In this example, the starting offset of the first program instance we deal with is 0x1000 (see Figure 1). Therefore we will overwrite the executable from the offset 0x3000 (0x1000(the starting offset) + 0x2000(cryptoff)).

$ dd seek=0x3000 bs=1 conv=notrunc if=./decrypted2.bin of=./ColorLEDFlashlightPro

Update cryptid as you see in the part 1 (Figure 12, 13).

Screen Shot 2013-01-27 at 1.00.06 AM

Figure 12. cryptid location

Screen Shot 2013-01-27 at 1.03.13 AM

Figure 13. updated cryptid

Confirm if cryptid is changed using otool again (Figure 14).

Screen Shot 2013-01-27 at 1.12.44 AM

Figure 14. Confirmed cryptid

As a final step, run class-dump-z again to see if the app is decrypted successfully.

$ ./class-dump-z ColorLEDFlashlightPro

Screen Shot 2013-01-27 at 1.15.31 AM

Figure 15. Decrypted app

Testing environment

  • OS: iOS 6.01
  • Device: jailbroken iPod 4G
  • tools: otool, gdb, class-dump-z



About DblH

System programmer, kernel mode developer, rce, malcode analyst.


9 thoughts on “Decrypting apps on iOS 6 – Part 2: multiple architectures and PIE

  1. Thank you, for a very easy and understandable tutorial. Worked like a charm.

    Posted by Reb | March 17, 2013, 8:53 am
  2. Thanks for a fantastic guide to decrypting apps.

    I followed the guide and managed to get to the class-dumb-z stage which failed with Segmentation fault: 11.

    This was unexpected as the app still ran once I’d copied the memory dumb into the application binary.

    I hunted around and came across the following article: http://www.peterfillmore.com/2013/01/disabling-aslr-on-individual-ios.html, which discusses the use of ASLR as a means to change memory addresses of libraries during runtime, which may have resulted in the issues I’m having. I followed through this guide and also tried the removePIE (which runs on the device) tool http://www.peterfillmore.com/2013/01/removepie-tool-for-disabling-aslr-on.html, but had the same issues:

    1 – ldid caused the same Segmentation fault: 11 failure.
    2 – removePIE failed with “File is not a Mach_O binary”

    I exported a project from XCode and tried the various tools I’ve come across during my attempt to decrypt an app, and this has been successful. I understand this is because the app hasn’t been encrypted and the PIE setting has not been applied; I just needed a sanity check 🙂

    I have a spare iPhone 4s running 6.0.1, which I aim to jailbreak and try the process again, in case the issue is related to iOS 5.0.1, I’ll report back how I get on, in the meanwhile if do have any suggestions on where I’m going wrong.

    Thanks again.

    Posted by parmyb | April 9, 2013, 8:00 pm
  3. Hi Mate

    Thanks for getting back to me and the kind offer. I’m not sure if you’ll have access to the app, as I think it’s only available in the UK App store. The app is called: Millionaire (as in W:h:o W:a:n:t:s T:o B:e A M:i:l:l:i:o:n:a:i:r:e).

    If you’re unable to get the app, will it help if I package the app for you, or send you the application binary and the dgb memory dump?

    Thanks again, I really appreciate your offer to help, as I’m losing it here 🙂

    Posted by parmyb | April 9, 2013, 9:34 pm
    • Hi

      I solved it. It was me not being able to follow the simple instructions you laid out.

      In the end the error came down to not setting the encryption id for both apps – I only set it for the first (armv7) app. Hence following figures 12 and 13 above, I should have set both encryption id’s to 0.

      Thanks again for your help, please feel free to delete my posts and replace with the summary:

      If the final step: ./class-dumb-z fails with Segmentation fault: 11, make sure both “cryptic” are set to 0; using your example:

      otool -l ColorLEDFlashLightPro | grep crypt

      should return:
      cryptoff 4096
      cryptsize 3027424
      cryptid 0
      cryptoff 8192
      cryptsize 3027424
      cryptid 0

      Thanks again, and a fantastic post 🙂

      Posted by parmyb | April 9, 2013, 10:43 pm
      • It seems you decrypted the code of the second architecture. So you need to set the second cryptid to 0 not the first one. I think when you set both cryptid to 0 and run the app on the first architecture, the app might not be able to run properly.

        Posted by DblH | April 10, 2013, 8:36 pm
  4. Thanks for your brilliant job:

    I also fetch the same problem which class-dumb-z failed with Segmentation fault: 11.

    I hunted around and try to remove ALSR discusses in other articles. But still had the same issues:

    1 – removePIE successed, but l did caused the same Segmentation fault: 11 failure.
    2 – the command “otool -f MyApp” did not output anything.
    3 – when I type in the instruction “otool -l MyApp | grep crypt”, I got the right return i think :

    cryptoff 8192
    cryptsize 5128192
    cryptid 0

    so I think this app has only one architecture, in the meanwhile if do have any suggestions on where I’m going wrong.

    Thanks very much.

    Posted by Geminiv | October 22, 2013, 2:36 am
  5. I’ve got 2 problems and then solved it. First the GDB for my iOS6 did not work so i downloaded the one in here cydia.radare.org and update the one i had. Second i had the Segmentation fault: 11 because of dd seek i used the starting offset + crypt off , then i used only the starting offset and it worked.


    Posted by solees | January 4, 2014, 9:38 pm

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s


%d bloggers like this: