Spire Proxy “FAQ”

Spire needs a proxy!? It’s useless!

As has been noted, my recently released tweak Spire requires a proxy and data from an iPhone 4S to operate. As the point of Spire is to get Siri on devices that aren’t the iPhone 4S, this might at first seem to imply that Spire is useless.

However, this is not because I hate you or because I’m lazy, it’s because Apple has made it very likely impossible to defeat the authorization requirement. I reverse engineered it, and it does not appear possible to connect Siri to the cloud without information from an iPhone 4S.

However, that doesn’t necessarily mean that Spire is therefore useless.

So, how do I get a proxy?

There’s any number of ways for you to get a proxy that will help you connect Siri to Apple. Here’s a few of my ideas:

  • westbaer’s SiriProxy fork
    • Own an iPhone 4S too: Maybe you already own an iPhone 4S, and just want Siri on another device of yours. This is simple; you can just use the above proxy yourself.
    • Find a friend: Maybe your friend has an iPhone 4S and will let you use their authentication tokens (maybe in exchange for some cool SiriProxy plugins). Then, you can share the authentication. Or, maybe you gave your relative your old iPhone when you got your iPhone 4S: now you can share your token and give them Siri.
  • Pay up: It’s very likely that soon we will see for-pay services online to rent you some space on a Siri proxy, attached to one of their iPhone 4S devices. I haven’t seen anything like this yet, but I’ll keep my eye out, and I would encourage anyone who is interested to set something like this up.
  • And now for something completely different: As I suggested earlier, you might be able to replace Siri entirely. A simple method might be to use Google Chrome’s speech “API” hooked up to some code to decode the Siri requests and parse Google’s result. Or, someone could hook it up to some logic backends like many of the clones available on Android: the possibilities are endless.

Okay, I’ll find something!

Good! Spire is far from perfect, but at least at this point in time, it’s the best that I can do. Maybe in the future someone will find a way to evade the authorization requirement, but from my position here that’s unlikely. Hopefully, however, you’ll be able to figure something out.

Introducing Spire

Spire is my (along with Ryan Petrich) new tool for installing Siri on previously unsupported, but jailbroken, devices. Spire is a small download, but while installing it will download Siri itself (directly from Apple). Spire is available in Cydia right now — go get it! This will use about 100 MB of data, so please connect to Wi-Fi before installing.

However, Spire is not a complete solution. Apple still requires authorization to use Siri, so information from an iPhone 4S is still required. To insert this information, Spire allows you to enter your own proxy server address. I’ve put up a list of my ideas on how you might get access to a proxy; hopefully you can figure something out.

Spire uses a new method to obtain the files necessary for Siri, so it doesn’t have the copyright issues encountered by previous attempts. Similarly, rather than directing all traffic through a specific proxy server (and the associated privacy issues), Spire allows you to specify your own proxy server.

Thanks to planetbeing for PartialZip and Ryan Petrich for his fixes and improvements.

Siri Authentication

Siri may be specific to the iPhone 4S, but very little of the actual processing takes place on the iPhone. Rather, Siri streams the voice data to Apple, and then displays the response from Apple and renders it. So, to even simply transcribe your voice into text, Siri needs to be able to contact Apple.

Siri requires authentication to connect to Apple. This is likely to prevent unauthorized use: I’m sure Siri takes a lot of computing power to run, as voice transcription, looking up responses, and bandwidth aren’t free. However, if your goal is to run Siri on a device which isn’t officially supported, you need to bypass this authentication requirement in some way.

The authentication is based on what I’m going to call “tokens”, which are signed by Apple. If I remember correctly (I haven’t looked at this for a month or so, and this is from memory), Siri (through the assistantd binary) first asks Apple for certificate data. This is then used to sign a blob of data generated by the iPhone and encrypted using AES. That signed data is then sent back to Apple, processed. If that was found to be valid, the device receives the “token” (called sessionInfo in the code) and an expiration date (the token is generally renewed daily).

The interesting part here is the AES-encrypted and signed data that is submitted to Apple for validation. The code that generates this is obfuscated (similar to FairPlay), but the general gist of what it does is reasonably simple. Firstly, assistantd calls out to the obfuscated absinthed, a part of the iPhone’s FairPlay subsystem. That then asks libMobileGestalt for both the UniqueDeviceID (the same UDID used for provisioning) and SerialNumber (the device’s serial number), and reads four bytes from a shared memory region. I currently do not know the source of these four byes (although I suspect the FairPlay daemon) or the purpose. This is then AES encrypted and sent back to assistantd to send to Apple, and (if valid) is exchanged for the session info.

As Apple can simply blacklist any device ID used for mass distribution of Siri, there is no way for a widespread and popular distribution of Siri to piggyback on one valid iPhone 4S identifier. However, a more distributed approach may be possible. A fork of SiriProxy, available here, allows everyone with an iPhone 4S to run their own proxy for their own devices. Or, it may be possible to replace Siri entirely, using something like Google’s speech “API” for speech transcription and logic like Hubot to create something usable for at least simple tasks like dictation.

The above technical info was discovered through a combination of static and dynamic analysis. If anyone would like to see my (not well documented, sadly) .idb or to contribute more to the investigation, just let me know on IRC. Thanks to anyone who helps, in addition to Steven Troughton-Smith and Aman Gupta.

This week, I bought myself a Galaxy Nexus (GSM version, not Verizon, so I can use it on my AT&T contract). I actually generally like the phone and Android 4.0 — shocking, I know — but there are dozens of the “little things” that Google got wrong. I hope this is just growing pains of a completely new design for the software, but in the spirit of Mozilla’s paper cut UI and UX project, I thought I’d document some of them on a new Tumblr.

In the future, I might expand this to just general UI complaints, but for now I’m just going to be discussing Ice Cream Sandwich as I use the Galaxy Nexus as my main phone.

Carrier IQ is on iOS

Carrier IQ, the now infamous “rootkit” or “keylogger”, is not just for Android, Symbian, BlackBerry, and even webOS. In fact, up through and including iOS 5, Apple has included a copy of Carrier IQ on the iPhone. However, it does appears to be disabled along with diagnostics enabled on iOS 5; older versions may send back information in more cases. Because of that, if you want to disable Carrier IQ on your iOS 5 device, turning off “Diagnostics and Usage” in Settings appears to be enough.

I do realize the info below is a bit technical, but that’s the best way for me to share what I’ve figured out so far at this point. Please feel free to let me know if you discover something else here.

Carrier IQ is run from a number of different daemons, depending on the firmware version of the device: (You can view this on a jailbroken iPhone with iFile or extract it from a software update bundle if you want to check the files out yourself.)

  • iOS 3: /usr/bin/IQAgent
  • iOS 4 and 5: /usr/bin/awd_ice2 or /usr/bin/awd_ice3

The startup routine verifies that it is running on either a compatible device and exits if it is not. In addition, and most importantly: it appears it will only run if:

  • iOS 3: The DiagnosticsAllowed key is set to true in the com.apple.iqagent preferences — which it does not appear to be enabled on any of my devices. (If anyone knows what would cause this key to be set to true, please let me know.)
  • iOS 4: Unknown, probably like iOS 3.
  • iOS 5: Copies the ShouldSubmit value from lockdownd, under the domain com.apple.MobileDeviceCrashCopy. I believe this value is set by the “Submit Logs to Apple” option during the iOS 5 setup sequence, and so Carrier IQ logging is toggled with that setting.

There is also a check to ensure that your carrier supports the logging: it appears some carriers support it only over WiFi, others over 3G. However, despite those restrictions and never enabling the above checks, I do see Carrier IQ log files stored on all of the devices I tested:

  • iOS 3: /var/logs/IQAgent
  • iOS 4: /var/wireless/Library/Logs/IQAgent
  • iOS 5: /var/wireless/Library/Logs/awd

But is this version of Carrier IQ the same keylogger/rootkit as on Android? The answer appears to be: not quite. It does access a reasonable amount of information, however: (Be sure to note that I have not confirmed which, if any, of this data is sent remotely.)

  • CoreTelephony
    • your phone number
    • your carrier
    • your country
    • active phone calls
      • (However, I only saw it noting that a phone call was active, not what number was dialed or it was received from. But, I am not going to claim it doesn’t do that: it’s certainly possible, but didn’t see it.)
  • CoreLocation
    • your location (Only, however, if Location Services are enabled.)
  • (Possibly more I haven’t yet found.)

As Carrier IQ claims in their video, communication with the remote server is all done via SSL. Importantly, it does not appear the daemon has any access or communication with the UI layer, where text entry is done. I am reasonably sure it has no access to typed text, web history, passwords, browsing history, or text messages, and as such is not sending any of this data remotely.

It appears that if you really care about this, Windows Phone 7 is the only mobile operating system without this installed. ;P However, I think the blame here really belongs with the US carriers who obviously demanded this: personally, I am completely fine with this data being sent off (especially if it helps AT&T’s network improve), but I would definitely prefer if it was more transparent — even if you can disable it with that toggle, Apple only explains that it “might contain location data”.

Update: From my examinations, Apple’s recent statement on the issue appears to be entirely accurate.

Why not Siri for iPhone 4, iPod touch right now?

As @stroughtonsmith and I demonstrated a few days ago, it is possible to run Siri on iPhone 4 and iPod touch. However, as we are currently unable to distribute the port or the procedure we used, I think I should at least explain the reasons why that isn’t happening.

For a little background information, it’s important to understand the fundamentals of how copyright law works. Apple owns the copyright on the software, images, and data used inside iOS: they created them. Because of that, they have the ability to decide what other people can — are licensed to — do with them: copy, distribute, adapt, modify, or any number of other protections of their works. Pretty simple. But this does lead to one important, if somewhat counterintuitive, fact: just because a piece of data is available freely on the internet does not mean that you have the rights to redistribute that data (or any part of it) without an applicable license. In practice, that means that just because certain files are freely available on a device or inside a firmware (.ispw) file freely downloadable from Apple’s website, it does not imply that those files can legally be distributed by anyone else.

In the context of Siri, this means that the resource files, images, and code that makes up Siri cannot be freely shared. These frameworks and plugins that work together to build Siri are not included on other iOS builds besides the ones running on the iPhone 4S. Therefore, these files must be copied from a running iPhone 4S, or from the iPhone 4S’s firmware (.ipsw) file. The first method requires you to own an iPhone 4S to copy the files from, so it is not useful for most people: if you already own an iPhone 4S, you already have Siri. The issue with the second method is more technical: the firmware files are distributed encrypted, and we do not yet have the decryption key to access the Siri files inside of the iPhone 4S firmware file.

Just from that, you currently must already own an iPhone 4S to install Siri on it without a blatant copyright violation. But even that’s not all: if you do all of that, there’s still a few more reasons why Siri won’t just work.

Many people have managed to display the Siri UI on the iPhone 4; it is, in fact, reasonably trivial with access to the files copied off an iPhone 4S (as explained above). But only Steven and myself — yes, I know there are others that claim to have: I’ll tell you this, they haven’t ;) — have managed to make Siri successfully contact the Apple servers and receive responses. Why? Here, the answers become slightly more murky. Partially this is because I don’t want to reveal too much about the procedure to try and ensure that you all will be able to use it in the future, and partially because it requires a jailbroken iPhone 4S, something which is currently not publicly available. Anyway, the general gist of it is that you almost certainly need the access provided by the a jailbreak to extract all of the information necessary to get Siri working on another device, and that’s not yet availble. (And, no, I don’t know when it will be. You can follow along with me while we wait, though!)

Anyway, I hope that clears up some of the technical and legal reasons why distributing a build (or instructions) to run Siri on older hardware isn’t possible at the moment. When we have the ability to decrypt the encrypted iPhone 4S firmware file — to extract the Siri files legally, without the need for an iPhone 4S — and we have an iPhone 4S jailbreak to obtain the other nececssary information at a mass scale, hopefully this can become a reality and everyone can try out Siri on their older devices. Until then, showing you a video that it is possible is the best we can do.

(Oh, and to answer another popular question: nobody has tried it on an iPhone 3GS or iPod touch 3G or an iPad on iOS 5, so we don’t have any clue if it will work or not there. But we can hope it will!)

iOS 5 Status

Here’s the status of all my stuff on iOS 5. If you haven’t heard of any of these before and want to check them out: search in Cydia, they’ll all show up and should all work on iOS 4.2 or 4.3. Feel free to send me a support email from Cydia if you have any issues or questions, for paid products I try and respond within a few hours if I’m not sleeping.

I’m going to keep this post updated for all the latest status updates to each of them, so be sure to check back here.

Paid Extensions

  • Gridlock: Full iOS 5 support.
  • VoiceActivator: Full iOS 5 support.
  • Infinidock: Full iOS 5 support. (As of version 1.8, available now in Cydia!)
  • Infinifolders: Full iOS 5 support. (As of version 1.4, available now in Cydia!)
  • Infiniboard: Full iOS 5 support. (As of version 1.8, available now in Cydia!)

Free Extensions

  • IconSupport: Full iOS 5 support. (Via @ashikase, who did the iOS 5 work: thanks!)
  • AppSlide: Full iOS 5 support. (As of version 1.1, now available in Cydia!)
  • MobileVolumeSound: Full iOS 5 support.
  • Internalizer: Full iOS 5 support.
  • Five Icon Switcher: Full iOS 5 support.
  • Webscrollian: Full iOS 5 support.
  • No Page Dots: Full iOS 5 support.
  • No Bookmarks: Full iOS 5 support.
  • Full WebClips: Full iOS 5 support.
  • No Folder Badges: Full iOS 5 support.
  • Empty Folder Icons: Unknown. Let me know?
  • Colloquy Tab Complete: Unknown. Let me know?
  • Covert: Does not work, but similar functionality is included in iOS 5.
  • ListLauncher: Does not work.
  • Switcherscape: Does not work.

Blocks for Target/Action?

Blocks are an awesome extension to C. And, since iOS 4 (the first version that supported blocks) now has enough adoption to make it safe to be minimum version that I support, I’ve been checking out blocks quite a bit to see where they could make blocks easier.

Some of the UIKit and Foundation APIs have been updated to use blocks, but many of them are still using the older target/action mechanism or delegation where blocks would probably be a better choice. Lately, there’s been a bunch of projects designed to add block support to the places that Apple hasn’t (or has decided against) adding it.

That got me thinking: blocks are Objective-C objects, why can’t they act as the target, with the body of the block as the action? (Note: I’m not posting this up here as a suggestion that you use this (yet!), but as a way to ask if this makes any sense.)

Since I couldn’t find any documentation on what Objective-C class blocks are (except that they inherit from NSObject), I decided to add a category to NSObject to give me a selector to invoke the block with. To do that, I came up with -[NSObject startBlock], which ended up looking like this: (((void (^)(void)) self)());.

However, when I tried target:^{ NSLog("in a block!"); } action:@selector(startBlock), I got a crash, because the block was never retained (as targets shouldn’t be), so it no longer existed by the time -startBlock was called on it. Just copying it wouldn’t work, either, because it wouldn’t ever be released, and adding an ivar to release it yourself removed any of the advantages of using a block over an additional selector in the first place.

My next idea is when things got a little crazy. Associated objects (added in iOS 3.1) could get around those issues, since they’re automatically released when the object they are attached to is deallocated. I added another method to my NSObject category, -copyWithOwner:, that took advantage of that to force ownership of an object onto another object. Using that, I ended up with something that you use like this: [object addTarget:[^{ NSLog("block!"); } copyWithOwner:self] action:@selector(startBlock)], with the below code used to implement it:

@implementation NSObject (BlockTargetAction)
- (void)startBlock {
    (((void (^)(void)) self)());
}
- (id)copyWithOwner:(NSObject *)owner {
    // copy ourself to the heap
    self = [[self copy] autorelease];

    // this key is unique until self is deallocated,
    // so it should last as long as the owner does
    void *key = (void *) self;

    // automatically released when the owner object is deallocated
    objc_setAssociatedObject(owner, key, self, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    return objc_getAssociatedObject(owner, key);
}
@end

I’m not sure, though, that I’ve fully thought through all the possible implications of using this hack, especially the memory management aspects. Does this make any sense, or am I wasting my time?

Sliding UITableView Header Views

The “dickbar” (as Gruber puts it) may be the big news item lately, from my “Twizzler” to remove it to the various websites springing up about it. But, this post is about something much more mundane and technical in Twitter for iPhone: sliding headers for UITableView.

When you first open Twitter for iPhone, you get this screen. Looks like just a standard UITableView and a custom -tableHeaderView set, yeah? Not quite. There’s actually an interesting effect here: when you scroll, the header actually slides under the table view. If that didn’t make sense (and it’s not a good explanation, sorry) I’ve uploaded a video that demonstrates the effect:

Read More

Moving to Micro USB?

Today, some people began receiving the first of the new, streaming-only, Apple TV. Engadget has a nice review of the device itself here, but the most interesting thing for me was in the ports on the back. It wasn’t the HDMI output, or the Ethernet jack, but the small, unlabeled Micro USB port.

Apple TV's new Micro USB port.

No iOS device, until this one, has had a Micro USB port, especially not one used for restoring (or communicating with iTunes at all). However, that may soon be changing. The new European “universal charger” will require all smartphones sold there, including the iPhone, to use a Micro USB charger rather than the explosion in proprietary chargers we’ve been seeing.

The Apple TV may very well be preparation for what is coming soon for other iOS devices. While it’s not required for any devices outside Europe, Apple has been hesitant, to say the least, to have physical differences in their iOS devices in different regions, so the rest of the world’s devices will probably be moving to Micro USB as well. How this will impact the design — and third part accessories — still isn’t known, but we do know that some major changes will have to be made, and this new Apple TV may be a way for Apple to test those out in a much more controlled environment.

(Unrelated note: I do plan on posting more often to this blog. Maybe if I set a once-a-week post schedule, I can actually keep to it and keep you guys more up to date.)

Update November 2011: Looks like Apple released what they plan to use for Micro USB support. Lame.