Regaining access to a passcode-disabled iOS device

Update 2019-12-16: Seriously, this is VERY OUTDATED and I cannot help you. I will still approve comments in case anyone else wants to chime in. I have no reason to study this, as I don’t deal with any form of iPhone servicing these days. This post was for iPhone 3GS with iOS 5.0.1. That’s ancient, very exploited hardware with ancient, very exploited OS. I don’t follow jailbreak scene in 2019 at all. I don’t know if working around passcode lock is remotely possible these days.

Update 2016-03-16: This 2012 post discussed iOS 5 on iPhone 3GS. Both the iOS hardware and software are more secure these days. I don’t use iOS much these days either. I’m keeping the post up for archival, but chances that I can help you are very low.


You have a passcode-disabled iOS device? You get a message similar to “iPhone disabled for XYZ minutes”? Especially if the message mentions millions of minutes, this may be a problem. Or if the iPhone instructs you to plug it in iTunes, and then iTunes says that you need to unlock the passcode, without a way for you to enter it?

One way is to restore the device. Unacceptable if you have important info on the device.

Let’s instead destroy the passwords and Springboard settings. You’ll still need to enter your passcode, but at least you’ll be able to unlock the device. If you forgot the passcode, you’ll at least have SSH installed and a way to connect to the device. If you find the instructions on how to remove the passcode completely, leave a comment below.

Instructions for OS X. Tested on iPhone 3GS with 5.0.1. You’re expected to have at least a brain, some experience with jailbreaking, and understanding of UNIX systems.

  1. Grab latest redsn0w. (At the time of writing, redsn0w 0.9.11b4)
  2. Grab “SSH_bundle.tgz“.
  3. Run redsn0w and click “Jailbreak”.
  4. Follow instructions and choose “Install custom bundle”
  5. Wait until device reboots.
  6. Grab “usbmuxd”. Tested with “usbmuxd-1.0.7.tar.gz
  7. Unpack it, open Terminal, and go into the newly created “usbmuxd-1.0.7” folder.
  8. Go to “python-client” subfolder. Type “python tcprelay.py 22:2023”. This allows you to connect to the device via the USB cable.
  9. In a new Terminal window or tab, type “ssh root@localhost -p 2023”. This’ll work about 30 seconds after the device boots successfully.
  10. Try typing “alpine” as the password. If it works, congratulations! Let’s move on.
  11. In terminal that is connected via SSH to your iPhone, type “rm /var/mobile/Library/Preferences/com.apple.springboard.plist”.
  12. In terminal that is connected via SSH to your iPhone, type “rm /var/Keychains/keychain-2.db”.
  13. Just to be sure, let’s check your date. In your local Mac terminal, type “date”. Copy the result to the clipboard. In terminal that is connected via SSH to your iPhone, type “date”. If the dates aren’t reasonably close (a couple of hours of difference max), type “date -s PASTETHEDATEFROMYOURMAC” into terminal for your iPhone. Now type “date” on iPhone terminal just to be sure.
  14. Reboot the device. Enter the passcode.

Congratulations!

Information source: this post, research

 

Again, if you are able to remove the passcode completely, tell me. Thread in which the post I linked to is located contains some info, but I haven’t been able to verify it. (I don’t plan on locking customer’s iPhone again just to check, thank you very much ;))

Figuring out software version of a passcode-disabled iPhone

If you have an iPhone that’s passcode-locked, especially with message that iPhone needs to be connected to iTunes, you may want to try to unlock it by jailbreaking, installing SSH and messing with the filesystem. (tcprelay.py from usbmuxd is very helpful for SSHing if the iPhone doesn’t connect to a known wireless network.) There’s this tutorial on installing SSH on a disabled iPod, which doesn’t use tcprelay.py and is targeted for Windows users, but it should nonetheless give you the starting info.

Before you start you may want to discover which software version is installed on the iPhone.

Current redsn0w, 0.9.11b4, displays the device name, ECID, and software build when you use the “Fetch SHSH” functionality. There’s also “Identify” functionality which should do the same thing, but you won’t be collecting SHSH blob (it’s a good idea if you want to downgrade in the future.) Build name is a string similar to iPhone2,1_5.0.1_9A405 and can be used to obtain the correct .IPSW for your device, enabling you to jailbreak the device and to install contents of “SSH Bundle.tgz”. Most important thing is – fetching SHSH blobs is a non-destructive operation.

You’re welcome.

(All files mentioned are googleable.)

OS X's Terminal: Getting Home, End, PgUp, PgDn to work

Apple’s Terminal on a Macbook requires a weird combination of fn+shift+left/right, fn+shift+up/down to get Home, End, PgUp and PgDn to work. And that still causes issues in a couple of places.

Despite maintaining my philosophy of “use defaults wherever possible”, I’ve decided to ditch iTerm and iTerm2 for a simple reason: after quitting from Apple’s Terminal, upon restart in Lion I get a screenful of information from my previous session. Quite handy if I had to restart a machine for some reason, but I don’t want to lose the context!

Here are two fixes found Francois Planque’s post.

First part involves fixing the escape sequences sent by the Terminal. Open Preferences (for example, by hitting Cmd+,), and navigate to Settings tab, then for the profile you want to adjust, navigate to Keyboard tab.

Over there, define the following escape sequences upon pressing home, end, page up and page down:

home: \033[1~
end: \033[4~
page up: \033[5~
page down: \033[6~

If you mess up something during input, use your mouse to hit the button “Delete one character”. To get \033 in the dialog box, just press the Escape key instead of typing backslash, zero, three, three.

After applying this, voila! vim and mc now type these keys correctly.

But, you’ve just messed up bash.

Second fix involves editing ~/.inputrc (or /etc/inputrc). Neither of these rc files existed on my machine. From Garret LeSage‘s blog post (and as suggested in a comment on Francois’s blog), I simply copy pasted the following:

"\e[1~": beginning-of-line
"\e[4~": end-of-line
"\e[5~": beginning-of-history
"\e[6~": end-of-history
"\e[3~": delete-char
"\e[2~": quoted-insert
"\e[5C": forward-word
"\e[5D": backward-word
"\e\e[C": forward-word
"\e\e[D": backward-word
set completion-ignore-case On

It’s nice to see an OS X-related tech post that’s still as useful in 2012 as it was in 2005. And it’s even nicer to see that it was originally intended for other UNIX and UNIX-style systems.

By the way: this post’s ID is 2 * 333. Make of it whatever you want. 🙂

Saving PC sales

So today I’m reading that Dell may be stepping away from the consumer PC arena. What could a prospective PC retailer do to save sales?

While I’ll be ranting about Canonical, Ubuntu, Linux and GNOME a lot, please note that this is just a mention of a possible platform a device maker could have opted for. Same goes for Dell: I’m talking about them, but it mostly applies to others. And what I’m talking about is that people want an integrated (but powerful) solution that ‘just works’.

Figure out that people want the sleek and fancy. Steam is fancy. App Store is fancy. iTunes is fancy. Intel AppUp from 2011 was decidedly not fancy, and in fact, it was a prime example of the “old” way of doing things one the PC: let’s just pack random garbage in front of the customer and hope he’ll not only bite it, but happily chew it. (Just remember all the “photo handling” software that shipped with your digital camera, or “antivirus protection” demo software shipping with your shiny new PC.)

Thankfully, the latest version of AppUp from 2012 is a bit fancier, although still somewhat weird.

Figure out that people want to do things differently. How happy are users with the operating system you’re shipping? I personally like Windows 7 a lot lately (more on that later). But how integrated it is with your product? What does your product do? Is it just another box? Admittedly, it may be a neat, shiny box, but what does it do? Oh — this thing on it isn’t your product? Uh-huh, so you’re just another box-maker?

Hint-hint: end users like custom (but usable) stuff. At one point, aforementioned Dell has promoted Ubuntu on its machines. What they haven’t done is sit with Canonical and decide how to make Ubuntu the operating system for their machines. Not only that — they should have thought about how to make Dell’s laptop the machine for running Ubuntu.

Dell and Canonical could have figured out what exactly people want and how they want it done. In my previous life as a Linux user, I was quite “needy” and I desired customizability, shunning Ubuntu for Debian. But that’s not what people want. People want stuff to “just work”. I want it too nowadays. I also want a company to figure out how the user interface should work, and make it work that way instead of me. I want them to figure out what is the best way for me to achieve my goals.

And then I want them to proscribe that as sacred rules to developers on their platform. Then I want them to justify why those sacred rules exist. (The way NSDocument class works in Cocoa frameworks has recently allowed Apple to introduce “recent files” list for an application in Lion’s Expose for an application’s windows, as well in the Dock icon menu.)

I want those sacred rules to be sane and enabling to the developers, instead of arbitrary decisions slapped together by a bunch of monkeys. (And I’m not pointing fingers at a single platform or library here — but pretty much at most platforms and libraries out there.)

Figure out that people want to do stuff with their machines. After securing a deal with Canonical, Dell should have attempted to secure a deal with, for example, Adobe to port at least their flagship product Photoshop to Linux (or more specifically Ubuntu). There are bound to be many, many hurdles along the way. But instead of toying with The Gimp and waiting for them to actually make a tool that is usable by real people, getting Adobe to bring their product over would make the platform (and products) stand out and appeal to an audience. And if Adobe doesn’t want to cooperate, invest those profits in your long-term gain: look at Photoshop and replicate it under Linux, including keyboard shortcuts and whatnot.

Go and fix OpenOffice’s interface, or at least lift what you can in designing an office suite that works and looks as an office suite should. Or write your own — Apple surely did with iWork, and they worked on that even before iPhone and iPad were insanely profitable like today. Compared to today, iPhone was only mildly popular.

Can you see the big picture now? Can you see how a platform could have and should have come together to save, for example, Dell?

As Apple has built their OS on the strong base of BSD userland and Mach kernel, Dell and Canonical could have delivered integrated products based on GNU userland and Linux kernel. They should have worked on securing partnerships to deliver key products to what was (and is) a nascent desktop environment.

Apple did not use window compositing to bring you toys like a 3D cube, but to bring you tools to switch between windows and apps. Dell and Canonical should have and could have slimmed down Compiz. GNOME 3’s window manager is a nice experiment in this direction, but on the first look at it, it lifts off of Apple so blatantly in some ways that I can’t help think they should have and could have done better. It could have and should have been better than what Apple does.

Figure out how to cut the stuff out. As mentioned, I personally like Windows 7 a lot lately, but it hasn’t struck the good balance between exposing whatever a power user needs and hiding anything that a common user doesn’t need. It’s still too complex for a common user, and at the same time, any attempt at simplification and hiding stuff just means the actual stuff you need is now hidden behind menus and behind more menus and behind more menus. See: attempting to configure just slightly more complex wi-fi setup in Windows 7. Something is seriously wrong if it’s easier to change resolution and color depth in Windows 95 than it is in Windows 7.

Compiz needed to be cut and configured to sane defaults. Or it should have been thrown away and a custom manager should have been written.

As long as we stick to the UNIX principles wherever possible, I can take your window manager and throw it away. Or I could write my own settings app. But if you do a good enough job, I will not want to.

I currently am not inclined to go away from Mac, and the amount of customizations I do is minimal. Some people use custom app launchers, I’m satisfied with launching apps through Dock or Spotlight.

But in case I want to move away, I’m hoping GNUstep takes off and provides a viable way for people to port their OS X apps to other platforms. I hope for a healthy GNUstep ecosystem where people are free to share code, but also to sell the fruit of their labors.

But I am not really interested in moving away right now, because Apple delivers a good, complete, healthy ecosystem today, along with an integrated hardware+software stack where things like driver issues are rare and shocking events happening mostly to early adopters — definitely they are not common daily appearance for most users.

To save your sales, deliver a healthy, integrated hardware+platform+applications ecosystem. For a corporation as big as Dell, any investment into their own platform would have been an investment into long term future. It would have been diversification and it would be a way to stay unique long-term. And not doing a good job on creating a platform when you’re a multi-billion dollar company, especially in cases where you can already take other people’s work, should be inexcusable. In fact — I’m not sure if not even attempting to do it may be an even greater sin.

Make yourself stand out with an outstanding product that “just works”. Half-assed experiments with Linux just because it’s Linux and “free” won’t save you and will flop.

Delivering a complete product starting with a laptop designed around a platform (which may be based on Linux), and delivering a complete platform designed around your laptop is a good way to start.

NSMutableDictionary without automatic retaining of contained objects

There may arise a situation where you absolutely can’t do something without either doing ugly hacks with overriding -release (which you should never, ever do), or using non-Objective-C constructs such as C++’s std::map (shudder), or rolling out your own key-value storage data structure (evil NIH syndrome strikes again).

The Reason

The only valid reason I can think of for doing this is to avoid a cyclic reference. For example, an object must be stored in a dictionary, but should be automatically removed from it upon being -dealloc‘ed. This is exactly what I’m doing in a game I’m slowly working on in order to cache OpenGL textures. I tried hacking this by overriding -release and monitoring -retainCount. Any Objective-C developer worth the name will know that’s a pretty dumb thing to do: -retainCount is a pretty shaky thing to depend on, due to various compiler optimizations, and overriding -release can only cause issues. (Yes, that includes overriding -release to force yourself and your teammates never to destroy a singleton. I actually saw that being done in production code. Pretty nasty stuff.)

Pretty much invalid reasons are:

  • storing non-Objective-C pointers or data types. If you’re making use of NSMutableDictionary, you’re probably making use of Objective-C and Foundation. So make use of the reference counting mechanism built into the framework by wrapping the non-Objective-C data type into something that can be swallowed by the framework nice and easy. Create a thin wrapper around this data by subclassing NSObject
  • not wanting to deal with the reference counting system. Oh, so you’re one of those people who don’t like to use -retain/-release/-autorelease? You find them abhorrent? Go and cry to your mommy; the reference counting system is one of the most powerful mechanisms enabled by Objective-C and provided by Foundation. Shunning it is no good.

Oh, and if you’re one of the ARC-loving pansies developers, sorry; I have no idea what effect this’ll have on your funny-colored little world. Because we’re about to dive into the mean world of Core Foundation.

This also, sadly, means I have no idea how this’ll work with GNUstep.

The Explanation

So you may have heard that Core Foundation equivalents of Foundation classes are “toll-free bridged”. What does this mean?

This means that if you create a CFArray, you can use the resulting pointer as an NSArray, and vice versa. This is pretty handy if you’re writing code that interacts with Mac OS X’s kernel. When writing something that talks to Bluetooth subsystem (say, a new Bluetooth service), you will use C functions that accept and return CFDictionary instances. Oh, sir, yes they do.

So to clean up your code of all those nasty CFDictionary*() function calls, and make it look all nice and Objective-C-ish, what can you do? You just pass the resulting CFDictionary pointer as the first thing in the brackets (you know, where you usually put an Objective-C message target?) and you use plain old Foundation message sends to do operations with the dictionary. To get rid of the warning, you can cast it either prior to the message send or in-line when performing the send.

  CFDictionaryRef dict; // same as CFDictionary *
  
  // . . . initialize it here . . .

  [((NSDictionary*)dict) valueForKey:@"someKey"];
  // ...or alternatively:
  NSDictionary * theDict = (NSDictionary*)dict;
  [dict valueForKey:@"someKey"];

And you can also do the opposite thing! You can create an NSDictionary and pass it off as a CFDictionary.

  NSDictionary * dict = [[NSDictionary alloc] initWithObjectsAndKeys:@"value", @"key", nil];

  // . . . use it here . . .

  // now we'd have to do [dict release].
  // or, we could have autoreleased the object right after
  // initializing it.
  // but let's be fancy.
  CFDictionaryRef cfDict = (CFDictionaryRef)dict;
  CFRelease(cfDict);

The Solution

So how do we actually create a NSMutableDictionary whose objects won’t be retained nor released?

It turns out to be wonderfully simple. You see, CFDictionaryCreateMutable() is a C function. And C doesn’t have a concept of reference counting built deep down into its core. So when you create a dictionary for use with C code, in a C-only program, you probably don’t want the dictionary to try to send messages to pointers which are not really Objective-C objects.

And as we have demonstrated each CFDictionary is actually an NSDictionary.

If you are using a C function, it’s a good idea to actually default to C behavior: no retaining and no releasing. It might also be a good idea to allow one to use a third-party reference counting mechanism?

That’s exactly what was done here. When calling CFDictionaryCreateMutable(), you feed it an allocator which can be used to allocate memory instead of the default one, the default capacity (just like -initWithCapacity:), and two pointers which describe just how the dictionary should behave when retaining, releasing, describing, copying, hashing and comparing values and keys.

First thing I did, and that seems to work quite well, is just pass NULL for the last two pointers. That is, it works quite well when your keys are constant strings which won’t be released that easily. I haven’t experienced a crash even when they aren’t, but let’s not risk it.

So let’s see.

NSMutableDictionary * ourDictionary = (NSMutableDictionary*)CFDictionaryCreateMutable(nil, 0, NULL, NULL);

Good, but let’s improve it by passing a pointer to a default structure for copying and releasing keys. Note that NSMutableDictionary also copies its keys. Exploring why it does so should be an exercise for the reader.

NSMutableDictionary * ourDictionary = (NSMutableDictionary*)CFDictionaryCreateMutable(nil, 0, &kCFCopyStringDictionaryKeyCallBacks, NULL);

Now our keys are copied and released where appropriate, while the values are left untouched.

Optionally, explore using kCFTypeDictionaryKeyCallBacks in situations where your keys may be other CFType-derived objects. (That is, not just CFStrings/NSStrings.) Don’t use this if there is even a remote chance of your key being a mutable object.