chpwn blog

Dec 21

How to detect screenshots on iOS (like SnapChat)

A number of Stack Overflow questions were having issues with this, so I figured I’d explain. From reverse engineering, this is the exact method used by SnapChat, but it’s also pretty much what I’d have done myself.

The process is pretty simple, and relies on a quirk of iOS: taking a screenshot cancels all touches on the screen. Because of that, anything that you want to protect will require you to have the user to touch the screen to see. If that works for your purposes, the general solution is to simply intercept the touch cancellation, and quickly remove any sensitive information from the screen. If you’re also implementing a screenshot counter, as with SnapChat, you will also need to take into account the other cases when a touch might be cancelled: from a system gesture (Notification Center or the iPad’s multitasking gestures), or by activating other pieces of system UI (the power down menu, or the multitasking switcher).

On a technical level, the two basic pieces are UILongPressGestureRecognizer (or -touchesCancelled:withEvent:, if you want) and UIApplicationDelegate. In your long press handler, you should hide your sensitive information when the gesture recognizer’s state is UIGestureRecognizerStateCancelled, and if you want to track the number of screenshots, increment a counter. Then, in the UIApplicationDelegate, decrement that counter when you receive the -applicationWillEnterBackground: or -applicationDidResignActive: notification to account for the other possibilities for a cancelled touch. You might also need to handle other situations where a touch could be cancelled, if other parts of your app might cause that to happen.

Dec 06

Introducing Infiniapps 2.0

It’s been a long time now, but the first release of Infinidock was almost three years ago. It was only my second tweak for iOS, after ProSwitcher with Ryan Petrich, and my first in the Cydia Store. The first version was built in just one week after coming up with the idea, and only worked on iOS 3.0 and iOS 3.1.

Since then, it’s gained a number of extra features, and I also released Infiniboard that February and Infinifolders later that year. But all three have still been based on the same code I wrote in one week during January 2010. Because of that, adding new features and supporting newer iOS releases was growing more difficult with every update. It was time for a clean slate.

And so today I’m releasing new versions of all of the Infiniapps, rebuilt from the ground up for iOS 5 and iOS 6. But while the core is brand new, all of your favorite features, settings, and purchases are still there, and everything should seamlessly carry over into the new versions. I also added a few new features — scrollbars and bouncing settings are now an option in Infinidock, for example — and new features should be much easier to add in the future.

Another big focus was fixing a number of longstanding bugs, for both stability and performance. Also gone is a little secret I’ll let you in on: until now, the Infiniapps were never really unlimited. There’s always been a hidden cap (for performance reasons), somewhere between 50 and 200 icons. With the new architecture, though, performance is barely affected by the number of icons, and I’ve made it truly unlimited. Compatibility with other extensions should also be better; Gridlock, for example, now works without any special support or cooperation from my other extensions.

Infinidock, Infiniboard, and Infinifolders 2.0 are in Cydia now!

If you’re jailbroken, be sure to go check them out.

As always, if you have any issues or questions, feel free to contact me through the “email author” button in Cydia. I’ll get back to you as quickly as I can.

Besides the Infiniapps, I also have a few other updates to talk about:

Sep 18

Building for armv6 in Xcode 4.5

The original iPhone, iPhone 3G, and first two generations of iPod touch used processors supporting the armv6 instruction set. However, with the iPhone 3GS, Apple moved to the more modern, but backwards compatible, armv7 instruction set, and the iPhone 5 includes armv7s. To support older devices while taking advantage of the capabilities of the newer processors, iOS supports fat binaries, which are multiple executables, each for a separate instruction set, combined into one.

But with the latest release of Xcode (as I write this, version 4.5), Apple removed support for building armv6 components, essentially forcing developers to drop support for iOS releases up through iOS 4.2.1, the last supported version on the armv6 devices. I like supporting older devices for a long time, though, so dropping support for anything before iOS 4.3 so soon isn’t what I would want. Luckily, however, with a minimal amount of hacking, you can convince Xcode 4.5 to build your code for armv6 and for iOS 4.2.1 and below — as long as it doesn’t build against the iOS 6 SDK.

Here’s how to do it:

And that’s all there is to it. It’s not perfect: you can’t use the iOS 6 SDK when using this trick, and you can’t build for armv7s. And you might need to re-add the iOS 5.1 SDK after you update Xcode through the App Store. But you can use one set of developer tools to build both iOS 6 apps and older ones, which is likely enough if you’re bothering to support the iPhone 3G in the first place.

Jun 10

IDA Pro: Lion Fullscreen

I’m a big fan of OS X Lion’s full screen mode, and I run almost all of my apps in full screen. However, until recently, IDA Pro, one my most used apps, has been impossible to get running in full screen — Lion only supports Cocoa apps running in full screen, and through version 6.2, the Mac Qt port of IDA Pro used Qt’s Carbon backend. IDA 6.3’s announcement included a mention of full screen support, but it wasn’t the native Lion full screen that I’ve been wanting.

However, with IDA 6.3, the backend has switched to Cocoa, and so adding support for full screen mode is now possible. While IDA itself does not include the workaround to natively add full screen support, with its plugin support, we can add it ourselves. (I’m pretty sure that my Maximizer would work here, too, but it both requires SIMBL and loads into every app on the system.)

My simple plugin is available for download. It does, however, require a few notes:

The source code is pretty basic (and compiles with quite a few warnings), but I’ll post it if anyone is interested in seeing how this was done.

May 25

iOS 5 Status

Here’s the status of all my stuff on iOS 5 (all versions: iOS 5.0, 5.0.1, 5.1 and 5.1.1). If you haven’t heard of any of these before and want to check them out: search in Cydia, they’ll all show up. 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

Free Extensions

May 07

HTC One X

Since it was released on AT&T this weekend, I was able to try it out at a store today. I only played with it for a few minutes, but here’s what I thought:

Overall, this is the best Android hardware I’ve tried, but the software is even worse than the Galaxy Nexus’ stock Android. The Galaxy S III looks even worse: more awful skin and the usual ugly, creaky Samsung hardware.

Will there ever be an Android phone with hardware and software that anyone would actually want to buy?

Mar 22

How to test your app on older iOS releases

In this week’s Build and Analyze, Marco Arment talks about supporting older iOS versions in Instapaper. As he says, being able to test your app on those versions is not easy, and just getting a device to run a specific iOS release can need “hacky jailbreak tools” or can even be impossible. Since I spend my time with those (admittedly hacky and confusing) tools and have an understanding of how the restrictions here work, I thought I’d write an explanation and a guide on how to successfully test for older iOS releases.

Background

Originally, there weren’t any issues with running any iOS release on your device. You just download the firmware (ipsw) file, open up iTunes, and restore with it. This method worked through iPhone OS 2.0, the iPhone 3G, and the second generation iPod touch.

However, with the iPhone 3GS, Apple changed everything. On that device (as well as the iPod touch (third generation), the original iPad, and the iPhone 4), each and every firmware change must be approved by Apple’s servers, at the time of the install. And Apple will only agree to let you install the current latest release of iOS at that time, which prevents downgrading — as well as any re-installs of the iOS release the device is running, as long as that release is not the absolute latest version available.

The iPad 2, iPhone 4S, and iPad (third generation) all use similar methods, with additional security measures. (I’ll talk about those later.) In addition, with iOS 4, similar protections were added to the iPhone 3G and iPod touch (second generation). While those devices can still be easily restored to pre-iOS 4 releases, it’s no longer easily possible to restore them to any version from iOS 4.0 on.

Why It’s Important

What Apple has done here, essentially, is sacrifice the ability for developers to test code on older versions of iOS, for the sake of increased control of how we use our devices. It’s hard to see a benefit: if someone is knowledgeable to downgrade a device, they probably also have a good reason to.

It’s unclear that Apple realizes what this does to developers. Xcode, even, doesn’t realize that this happens at all: the Organizer still has a file picker and version selector under “Restore”, oblivious to the fact that this option no longer, in fact, works (and hasn’t for almost three years). The enterprise iPhone Configuration Utility and education Apple Configuration tool are similarly confused.

A good, simple solution would be for Apple to simply allow devices registered for development to install older iOS releases, just as they are allowed to install betas. (To encourage Apple to fix this problem for developers, please dupe my radar and help call attention to it. Thanks!)

What To Do

Often, even if Apple doesn’t support it, you still do need to ensure your code runs on older iOS releases. Since you can’t trivially restore your device to an older version, I’ve made a list of the possible workarounds:

Apple, please help!

The only way for this issue to be truly resolved for developers is for Apple to create a supported method to downgrade devices to test apps. While the iOS 5 over-the-air updates do appear to increase update penetration and speed, it’s simply not possible for many apps to only be available (or, worse: only tested) on the very latest version of iOS.

Right now, it does not seem likely that Apple will change anything here, so we are stuck with the workarounds above. However, there’s a chance that they will, and more people letting them know it’s an issue can only help.

Let me know if you know of any other workarounds or things I missed: I’m on Twitter as @chpwn, or you can email me at chpwn@chpwn.com.

Mar 07

Page Turning

This is how you turn the page of a book:


This is how Apple’s iBooks turns the pages of a book:


This is not how you turn the page of a book:


This is how Google Boo— oops, sorry, Google Play Books — turns the pages of a book:


This is a good example of how Google manages to only make it around 70% of the way to a good UI. They often get the basic idea right, but the details (like, for instance, “does anyone actually turn a book this way?”) slip through, and it shows.

It’s why I’ve ditched the new Gmail web UI for Sparrow, even though it’s missing many features I liked and actually runs worse on my laptop. And it’s why I’ve recently switched my browser to (gasp) Safari: after a year from the first betas of OS X Lion, it still only had “most” of what you would want from a full Lion-ready browser.

I certainly hope Google finds a way to solve this issue. Most of their products are ahead of the competition in other respects, and I’d love to use them. But if Google still can’t make it all the way, even with a new focus on design, I’m not going to shove an inferior experience on myself.

See also: ICS Paper Cuts.

Feb 06

Ski Trip to iOS 3.1.2

Last weekend, I went skiing at Northstar — the codename of iOS 3.1. (Each iOS release is codenamed after a ski resort, usually in Tahoe or Colorado.) I don’t have anything to match comex’s awesome PDF slope slope from JailbreakMe 3.0, but it wasn’t all bad:

Springboard ski slope

SpringBoard was there, right near the top of the mountain. Also, there was a new lodge this year, to go with one of my new tweaks:

Zephyr Lodge

But, sadly, it was closed. Maybe that’s because Zephyr doesn’t support iOS 3.1. ;P

Dec 26

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:

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.