Latest Posts

simenableSIM Enable

This is one of those tools that I wrote mainly for my own use, but I’m releasing just for the one guy with the same problem and arriving here via Google (hi). Basically, this creates a new menu item in your iPhone’s Settings app that allows you to switch between the CDMA and GSM networks on an iPhone provided it is activated on a CDMA network (Verizon/Sprint) AND you have a SIM interposer (Gevey/R-SIM) that allows you to use a GSM network (AT&T/T-Mobile).

First, a little backstory. I have a R-SIM v3 for my iPhone 4S Verizon and I also have a month of free 3G internet from AT&T due to a Vita promotion. I do not like browsing the internet on the Vita because the web browser sucks, so I decided to put the SIM in my iPhone. Now, the problem is that the data SIM card does not allow calling, so I would have to remove the SIM card every time I need to make or receive a phone call. I discovered by looking at the package I had to install for R-SIM that all it did was make the Verzion and Sprint carrier bundles on the iPhone unusable (by replacing their carrier data with the one from the Unknown bundle), so the iPhone falls back to the SIM card. So I decided to make a toggle in settings that will do this and restart CommCenter, and have the option to revert the bundle back to their original values (therefore restoring CDMA).

So, because I wrote this for a very specific audience (me), I have only tested it with an iPhone 4S Verizon, activated, running 5.0.1 and a R-SIM v3 with an AT&T SIM card. My CommCenter was also patched using the one provided here: All other configuration are untested and can be used at your own risk. However, I KNOW this will not work for iPhones that do not have two modems, which, at the time of writing, is only the iPhone 4S. You must also have your root password for the phone be ‘alpine’, if you don’t know what that means, you’re fine as that’s the default password. The reason for this is because I hard coded the root password into the app because I was lazy.

To install, add my repo to cydia: and install the package “SIM Enable”. You must have a patched CommCenter (the one I used it provided above) and the root password must be ‘alpine’ (info above). To use, go to the Settings app and find the option “SIM Enable”. After changing the toggle, you might have to wait up to five minutes to see the changes show up. If you get “No Carrier”, turn airplane mode on and off and you should get a carrier.

Here’s a video of it in action. I left in four minutes of the iPhone searching for a network so you have an idea of how long it takes.


  • 2012-04-07: Added a message box to prevent user from exiting screen before the process completes.
  • 2012-04-07: Fixed bug where "load" commcenter runs before "unload" completes.
  • 2012-04-06: Initial release.

[April Fools] Electronic Arts Inc. announces the closing of Yifan Lu

KATY, Texas, Apr 01, 2012 (BUSINESS WIRE) — Electronic Arts Inc. (NASDAQ: ERTS) today announced it will be permanently closing it’s doors at Yifan Lu. “The hardest part of my job is laying off employees. That and making games. Shit’s hard, we should start doing that soon.” commented EA CEO John Riccitiello in an earnings call following the announcement of the cuts. “It was tough having to get rid of such an awesome guy, but because of the drops of profits caused weak game sales (which was in correlation to the increase in the IQ of an average video game buyer), we had to make difficult decisions.” Yifan Lu has been responsible for hit titles such as TBA, Coming Spring 2013, and Project Canceled.

[April Fools] Yifan Lu has been acquired by Electronic Arts Inc.

KATY, Texas, Apr 01, 2012 (BUSINESS WIRE) — Electronic Arts Inc. (NASDAQ: ERTS) today announced it has acquired Yifan Lu, a leading innovator and badass for $4.95 USD and two chicken sandwiches. The acquisition accelerates EA’s position in popular appeal and strengthens its focus on the destruction of gaming. Yifan Lu will operate within EA Sports, a division of EA focused on changing logo text.

Unlocking T-Mobile 4G Hotspot (ZTE MF61): A case study

So, I have one of these MiFi clone from T-Mobile and want to unlock it to use on AT&T (I know that AT&T 4G/3G isn’t supported, but I thought maybe I could fix that later). The first thing I tried to do was contact T-Mobile, as they are usually very liberal concerning unlock codes. However, this time, T-Mobile (or, as they claim, the manufacture) isn’t so generous. So I’ve decided to take it upon myself to do it. I will write down the entire procedure here as a case study on how to “reverse engineer” a new device. However, in no way do I consider myself an expert, so feel free to bash me in the comments on what I did wrong. Also, I have decided against releasing any binaries or patches because phone unlocking is a grey area (although it is legal here), but if you read along you should be able to repeat what I did, even though I will also try to generalize.

Getting information

The hardest part of any hack is the figuring-out-how-to-start phase. That’s always tricky. But… let the games begin.

-Wheatley, Portal 2

So before we can do anything, we need to know what to do. The best place to begin is to look at the updater. A quick look at the extracted files, we find that the files being flashed have names such as “amss.mbn”, “dsp1.mbn”, and such. A quick scan with a hex editor, we see that the files are unencrypted and unsigned. That’s good news because it means we have the ability to change the code. A quick Google search shows us that these files are firmware files for Qualcomm basebands. Now, we need to find more information on this Qualcomm chip. You may try some more Google-fu, but I took another path and took apart the device (not recommended if it’s any more complicated). In this case, I found that we are dealing with a Qualcomm MDM8200A device. Google that and you’ll find more information such as there are two DSP processors for the modem and on “apps” ARM processor (presumably for T-Mobile’s custom firmare, and is what you see as the web interface). We want to unlock the device, so I assume the work is done in the DSP processor. That’s the first problem. QDSP6 (I found this name through more Google skills) is not a supported processor in IDA Pro, my go-to tool, so we need another way to disassemble it.


Some more Googling (I’m sure you can see a pattern on how this works now) leads me to this. QDSP6 is actually called “Hexagon” by Qualcomm and they kindly provided an EBI and programmer’s guide. I guessed from the documents that there is a toolchain, but no more information is provided about it. More searching lead me to believe that the in-house toolchain is proprietary, but luckily, there is an open source implementation that is being worked on. Having the toolchain means that we can use “objdump”, the 2nd most popular disassembly tool [Citation Needed]. So, it’s just a matter of sending dsp1.mbn and dsp2.mbn into objdump -x? Nope. It seems that our friends at ZTE either purposely or automatically (as part of the linker) stripped the “section headers” of the ELF file. I did a quick read of the ELF specifications and found that the “section headers” are not required for the program to run, but provides information for linking and such. What we did have was the “program headers”, which is sort of a stripped down version of the section headers. (Program headers only tell: 1) where each “section” is located in file and where to load it in memory, 2) is it program or data?, 3) readable? writable?, while section headers give more information like the name of each section and more on what the program/data section’s purpose is). What I then did is wrote my own section headers using the program headers as a guide and made up the names and other information (because they are not used in the actual disassembling anyways) with a hex editor. Then I pasted my headers into the file, changed some offsets, and objdump -x surrendered the assembly code. 180MB worth of it.


So we have 180MB worth of code written in a language that could very well be greek. Luckily, as I’ve mentioned earlier, Qualcomm released a document detailing the QDSP assembly language and how it’s used. Most likely, you would be dealing with a more “popular” processor like ARM or x86 and would have access to more resources. However, for QDSP6/Hexagon, we have two PDF documents and that is basically the Bible that we need to memorize. I then spend a couple of hours learning this new assembly language (assembly isn’t that hard once you embrace it) and figured out the basics needed to reverse engineer (that is: jumps, store/loads, and arithmetic). Now, another problem arises. We have literally 3 million lines of assembly code with no function names, no symbols, and no “sections”. How do we find where the goal (the function that checks the NCK key and unlocks the device accordantly) without spending the next two years decoding this mess? Here, we need to do some assumptions. First, we know   (through Google) that the AT modem command for inputting the NCK key is AT+ZNCK=”keyhere” for ZTE devices. So, let’s look for “ZNCK” in the hex editor of dsp1.mbn and dsp2.mbn. (If you are not as lucky and don’t know what the AT command is, I would put money that the command will contain the word NCK, so just search that). In dsp2.mbn, we find a couple of results. One of the results is in a group of other AT commands. Each command is next to a 4-byte hex value and a bunch of zero padding. I would guess that it is a jump table and the hex values are the memory locations of the functions to jump to. Doing a quick memory to file offset conversion (from our ELF program header), we locate the offset in our disassembly dump to find that it starts an “allocframe” instruction. That means we are at the beginning of a function so our assumptions must be right. Now, we can get to the crux of the problem, which is figuring out how the keycheck works.

Mapping out the functions

We now know where the function of interest starts, but we don’t know where it ends. It’s easy to find out though, look for a jump to lr (in this case for this processor, it’s a instruction to jump r31). We start at the beginning of the function and we copy all the instruction until we see a non-conditional jump. We paste the data into another text file (for easier reference). Then we go to the next location in the disassembly (where it would have jumped to) and copy the instruction until we see another non-conditional jump, and then paste them into the second text file. Keep doing this until you see a jump to r31. We now have most of the function. Notice I kept saying “non-conditional” jumps. That’s because first, we just need the code that ALWAYS runs, just to filter out stuff we don’t need. Now, we should get the other branches just so we have more information. To do this, just follow each jump or function call in the same way as we did for the main function. I would also recommend writing some labels like “branch1″ and “func1″ for each jump just so you can easily locate two jumps to the same location and such. I would also recommend only doing this up to three “levels” max (three function calls or three jumps) because it could get real messy real quick, and we will need more information so we can filter out un-needed code, as I will detail in the next section.

Finding data references

Right now, we are almost completely blind. All we know is what code is run. We don’t know the names of functions or what they do, and it would take forever to “map” every function and every function every function calls (and so on). So we need to obtain some information. The best would be to see what data the code is using. For this processor (and likely many others), a “global pointer” is used to refer to some constant data. So, look for references to “gp” in the disassembly. Searching from the very beginning of the program, we find that the global pointer is set to 0x3500000, and according to the ELF headers, that is a section of the dsp2.mbn file at some file offset. In the section we care about, look for references to “gp” and use the offsets you find to locate the data they refer to. I would recommend adding some comments about them in the code so we don’t forget about them. Now, the global pointer isn’t everything, we can have regular hard-coded pointers to constant areas of memory. Look for setting of registers to large numbers. These are likely parameters to function calls that are too big to be just numerical data and are more likely pointers. Use the ELF header to translate the memory locations to file offsets. In this case (for this processor), some values may be split into rS.h and rS.l, these are memory locations that are too “large” to be set in the register at once. Just convert rS.h into a 16 bit integer, rS.l into a 16 bit integer (both might require zero padding in front), then combine them into one 32 bit integer where rS.h’s value is in front of rS.l’s value. For example, we have: r1.h = #384; r1.l = #4624. That will make r1 == 0x1801210. You should also make some comments in the code about the data that is being used. Now, predict standard library calls. This may be the hardest step because it involves guessing and incorrect guessing may make other guess more wrong. You don’t have much information to go by, but you know 1) the values of some of the data being passed into function calls, and 2) library calls will usually be near the start of the program, or at least very far away from the current function. This will be harder if the function you are trying to map is already near the beginning of the program. The function I’m mapping is found at 0xf84c54, and most function calls are close to it. When I see a function call to 0xb02760, I know that it might be a library call. 3) Some of the more “common” functions and the types of parameters they accept. You don’t need to figure out all of the library calls, just enough to get an idea of what the code is doing so you don’t try to map out these functions (trying to map out strcpy, for example will get messy real quick). For example, one function call, I see is taking in a data pointer from a “gp” offset, a string that contains “%s: %d”, and some more data. I will assume it is calling fprintf(). I see another function is being called many times throughout the code, and it always accepts two pointers where the second one may be a constant and a number. I will assume it is calling memcpy().


This may be the most boring part. You should have enough information now to try to write a higher language code that does what the assembly code says. I would recommend doing this because it is much easier to see logic this way. I used C and started by doing a “literal” transcription using stuff like “r0-r31″ as variable names and using goto. Then go back and try to simplify each section. In my process, I found that how the unlock key is checked is though sort of a hash function. It takes the user input, passes it through a huge algorithm of and/or/add/sub of more than 1000 lines and takes the result and compares it to a hard coded value in the NV ram (storage area for the device). Here, I made a choice to not go through and re-code this algorithm for two reasons. First, it would be of little use, as the key check doesn’t use a known value like the IMEI and relies on a hard coded value in the NV ram that you need to extract (which a regular user might have trouble doing). Second, after decoding it, we would have to do the algorithm backwards to find the key from the “known value” in the NV ram (and it could be that it would be impossible to work backwards). So I took the easy way out and made a 4-byte patch in where I let the program compare the known value to itself instead of to the generated hash from the input and flashed it to the device. Then I inputted a random key, and the device was unlocked.

Now, remember at the beginning I said the code was unsigned? Because of that I could easily have reflashed the firmware with my “custom” code. However, if your device has some way of preventing modified code from running, you may have no choice but to decode the algorithm.

Playstation Vita’s USB MTP Connection Analyzed

This is the first of (hopefully) many posts on the PS Vita. Before I attempt anything drastic with the device, such as getting unsigned code to run, I hope I can try something easy (well, easier) to get used to the device. Ultimately, I want to make a content manager for the PS Vita for Linux. Unlike the PSP, the Vita does not export the memory card as a USB storage device, but instead relies on their custom application to copy content to and from the device. This post will give just a peek into how the communication between the Vita and the PC works.

There are two ways of approaching this. One is to sniff the USB packets to figure out what data gets sent to and from the device, and second is to disassemble the content manager application to find out how it communicates with the device. I tried both methods.

Reverse engineering the Content Manager

The biggest problem here is that the PC version of Sony’s content manager has its symbols removed. This makes everything a hundred times harder as you would have a harder time guessing what each function does. Luckily, the OSX version of the content manager does have the symbols intact. The problem here is that IDA does not work perfectly with Objective-C (it works, but you get a C++ish interpretation of Objective-C). I have a good idea of how the application is laid out, but there isn’t much point giving all the details (not useful). I will give some important points:

  • The Vita uses the Media Transfer Protocol, however I am not sure if it adheres completely to standards or if it uses a custom implementation
  • USB endpoint 0x2 is for input, while 0x81 is for data output, and 0x83 is for MTP event output
  • There is support for passing PSN account information to and from the Vita (password would be in plain text!), but it is unimplemented
  • CMA uses a SQLite database to index media information and licenses
Also, I’ve compiled a list of MTP operation codes for the Vita that are referenced in CMA (and therefore implemented in the Vita). Note that some of the codes are not in the standards while others are. For events, the second number is for reference with regards to the jump-table inside CMA only.

0xC104 0: RequestSendNumOfObject
0xC105 1: RequestSendObjectMetadata
0xC107 3: RequestSendObject
0xC108 4: RequestCancelTask
0xC10B 7: RequestSendHttpObjectFromURL
0xC10F 11: RequestSendObjectStatus
0xC110 12: RequestSendObjectThumb
0xC111 13: RequestDeleteObject
0xC112 14: RequestGetSettingInfo
0xC113 15: RequestSendHttpObjectPropFromURL
0xC115 17: RequestSendPartOfObject
0xC117 19: RequestOperateObject
0xC118 20: RequestGetPartOfObject
0xC119 21: RequestSendStorageSize
0xC120 28: RequestCheckExistance
0xC122 30: RequestGetTreatObject
0xC123 31: RequestSendCopyConfirmationInfo
0xC124 32: RequestSendObjectMetadataItems
0xC125 33: RequestSendNPAccountInfo
0xC801 1789: Unimplemented (seen when getting object from Vita)

0x1001: GetDeviceInfo
0x1002: OpenSession
0x1007: GetObjectHandles
0x1008: GetObjectInfo
0x1009: GetObject
0x100C: SendObjectInfo
0x100D: SendObject
0x101B: GetPartialObject
0x9511: GetVitaInfo
0x9513: SendNumOfObject
0x9514: GetBrowseInfo
0x9515: SendObjectMetadata
0x9516: SendObjectThumb
0x9518: ReportResult
0x951C: SendInitiatorInfo
0x951F: GetUrl
0x9520: SendHttpObjectFromURL
0x9523: SendNPAccountInfo
0x9524: GetSettingInfo
0x9528: SendObjectStatus
0x9529: SendHttpObjectPropFromUR
0x952A: SendHostStatus
0x952B: SendPartOfObject (?)
0x952C: SendPartOfObject (?)
0x952E: OperateObject
0x952F: GetPartOfObject
0x9533: SendStorageSize
0x9534: GetTreatObject
0x9535: SendCopyConfirmationInfo (?)
0x9536: SendObjectMetadataItems
0x9537: SendCopyConfirmationInfo (?)
0x9538: KeepAlive
0x9802: ?
0x9803: GetObjectPropValue
0x9805: GetObjectPropList

0x2001: OK
0x2002: GeneralError
0x2006: ParameterNotSupported
0x2007: IncompleteTransfer
0x200C: StoreFull
0x200D: ObjectWriteProtected
0x2013: StoreNotAvailable
0x201D: InvalidParameter
0xA002: ?
0xA003: ?
0xA004: ?
0xA00A: ?
0xA00D: ?
0xA008: ?
0xA010: ?
0xA012: ?
0xA017: ?
0xA018: ?
0xA01B: ?
0xA01C: ?
0xA01F: ?
0xA020: ?
0xA027: ?

Data Types:
0xDC01: StorageID
0xDC02: ObjectFormat
0xDC03: ProtectionStatus
0xDC04: ObjectSize
0xDC05: AssociationType
0xDC07: ObjectFileName
0xDC08: DateCreated
0xDC09: DateModified
0xDC0A: Keywords
0xDC0B: ParentObject
0xDC0C: AllowedFolderContents
0xDC0D: Hidden
0xDC0E: SystemObject
0xDC41: PersistentUniqueObjectIdentifier
0xDC42: SyncID
0xDC43: PropertyBag
0xDC44: Name
0xDC45: CreatedBy
0xDC46: Artist

Object Formats:
0x3000: Undefined
0x3001: Association
0x3008: WAV
0x3009: MP3
0x3801: EXIF/JPEG
0x3804: BMP
0x3806: UndefinedReserved
0x380A: PICT
0x380B: PNG
0xB007: PSPGame
0xB00A: PSPSave
0xB014: VitaGame
0xB400: ?
0xB411: MNV
0xB984: MNV2
0xB982: MP4/MGV/M4V/MNV3

USB packets

I’ve also captured the USB packets for initializing the device (from device plug-in to Vita displaying the content menu) and gave my best interpretation of it. First line is PC to Vita packet or Vita to PC packet

, followed by packets captured by VMWare running Windows 7, followed by the same action on OSX (dumped from memory using GDB on CMA, not from capturing USB packets), followed by my interpretation of what the packet does (question mark means not sure). EDIT: Some of my comments in the log I know are wrong now.

Next time

I’m hoping to decode these packets and implement them using libusb. I hope Sony is using the MTP standard so I can also make use of libmtp. I also need to be more familiar with how the USB protocol works so I can understand the packet layout better.

EDIT: I’ve begun work on a new project to create an open source content manager for the Vita. As of this post, it can init the device and tell it to show the main menu.

custom-screensaverCustom Screensaver for Kindle Touch

This Kindle Touch modification will allow you to use custom images as screensavers. This is not for Special Offer Kindles, nor does it remove the advertisements. By design, this mod will only work with non-ads Kindle Touches. An improvement of this vs the screensaver hacks of previous devices and the simple screensaver hack I released a while ago includes:

  • No filename constraint (name the images anything you want)
  • Auto update when new files are found
  • Scrolls through in alphabetical order (not random order, so you can manage the order of the images)
  • If no custom images are found, it will default back to Kindle’s original screensavers
  • If an invalid file is found, it will be skipped, after 5 invalid files, it will default back to original screensaver (instead of just crashing and requiring a restart)

In addition, images are auto-scaled and auto-converted, which means you are no longer limited to 600×800 grayscale images. Of course, those are the preferred format, but you can now use any PNG file and it will be sized to fit the screen. The only limitation is the image format must be PNG.

Finally, as an added bonus, I’ve included a custom screensaver, “lockscreen.png”. If you place that image in your screensaver folder (and nothing else), instead of a picture screensaver, the Kindle will keep whatever you are reading as the screensaver with a neat lock icon on the top of the screen.

As always, installation and usage directions are found in the readme after download.

All this is made possible by OpenBlanket, my attempt at reversing the APIs for LibBlanket, Amazon’s library for drawing full screen content on the Kindle Touch. You can check out the source for an almost identical re-implementation of the device’s original screensaver module (decompiled by hand and compiles to almost the exact same machine code). The source for the custom screensaver module is a modification of that source (and is included in the download).

Please note that you must jailbreak your Kindle before installing this package.

My stance on removing ads: First of all, I will never stop anyone from removing ads because I believe that a user should do anything they want on a device they own. It’s very easy to do, and there are many ways of doing it. However, I will never aid anyone in doing so, so please don’t ask me for help. The reason is that our main defense for jailbreaking the device being legal and ethical is that “we aren’t doing anything to hurt amazon.” However, when you remove the ads without paying Amazon $40, they lose money (even if Amazon is a big, evil corporation taking money from anyone is, in my opinion, bad), which means that if enough people start removing ads to make an impact they could take action against people like me who bring you the ability to unlock your devices. Since technically, the TOS for the Kindle states that you cannot modify or reverse engineer the device. No, Amazon is not enforcing it. No, I do not agree with it. But Amazon has always been passive in stopping jailbreaks (removing the exploit but not touching the hacks; not worrying about people who jailbreak; allowing people with jailbroken devices to have support even though you technically broke the TOS and can be denied support), but if they start losing money they could start actively blocking jailbreaks.


  • 2012-01-15: More advanced. Much more features.
  • 2011-01-13: "Simple screensaver" for Kindle Touch. Limited to 99 images of specifically named files.

Welcome to the new!

It’s a new year, and I’m a bit tired of the old design. There were some main problems with it besides the looks though. The biggest one is I never wrote a backend for my “projects” list, so every time I add a new project, I’m doing it manually by uploading the files via FTP and adding the entry in phpmyadmin. In addition, I’m sure there were tons of PHP bugs and security holes that I had in the old script. The old theme was also badly coded with many HTML errors and many WordPress incompatibilities.

On this new version of the site, the first thing I did was integrate my projects list to WordPress. I wrote a custom plugin that allows me to manage and add my projects with ease and manage things like downloads, version/changlog, screenshots, etc. I may release this plugin as open source one day. I also got a new style thanks to CSSHeaven. They provided the free HTML template and I coded it into a WordPress style (and also made it more HTML5 compliant). If you have any complaints or suggestions regarding the new site, feel free to comment.

In addition, I added two new Kindle projects that I’ve been working on.

kindle-touch-jailbreakKindle GUI Launcher

Only compatible with Kindle Touch. This will add a new menu option named “Launcher” on the Kindle’s home screen and inside books. This option will open a menu with options to launch custom scripts and Java apps. Included are two scripts to change screen orientation and to enable/disable usbnetworking.

See the JavaDocs for more information on developing and extending the launcher.

Please note that you must jailbreak your Kindle before installing this package.


  • 2012-01-29: Fixed rotation for 5.0.3
  • 2012-01-12

Additional Information

Project Link

kindle-touch-jailbreakKindle Tool

This is an all-in-one tool that generates Kindle update packages, including support for Kindle 4.0 and 5.0 packages. See the readme or run the application to see usage directions.


  • 2012-01-12

Additional Information

Project Link


archiveKindle Tool

Kindle Touch (5.0) Jailbreak/Root and SSH

Update Kindle 5.0.3 has fixed the hole to allow for jailbreak. Upgrading an already jailbroken Kindle Touch is fine as the update does not remove the custom key to allow custom packages. If you on 5.0.3 and have not already installed the key, there is a new jailbreak.

So long story short, we can run custom code on the Kindle Touch now but because the operating system has changed so much from Kindle 3, most Kindle modifications will not run without changes. I hope developers will jump to this device now that it’s unlocked. See the bottom of the post for download links. The directions for using are in the readme. Keep reading for technical details on how this came about.

Obtaining the root image
Before we can look for vulnerabilities in the system that would allow us to break in, we need to break into the system and obtain the files that might contain vulnerabilities. Yes, this is a chicken-and-egg problem, but fortunately Amazon is nice enough to help us with this. On every Kindle device is a TTL serial port. I found this port on the bottom of the device when the cover is opened. Fortunately, I did not even have to mess with it, as hondamarlboro and ramirami both managed to get the dump before me. Once we have the root image, it was only a matter of painstakingly looking through all the files to see possible injection vectors.

Looking for the needle

At first, I was digging deep into the system, disassembling and maping out various native libraries, looking for stack overflows (I found a couple but none could be accessed efficiently). I found the bootloader was unlocked but it would be a pain and danger for users (and even developers) to flash custom kernels and such. I also found that the Java code (the Kindle’s entire GUI is written in Java) is NOT obfuscated (which means it would be easier to reverse and later modify) and Amazon has left in many places to place plugins. For example, once someone has the time to figure things out, it would be very possible to write a EPUB extension to read EPUBs from the native reader. There are some other hidden secrets in the device too. The Kindle Touch has an accelerometer and proximity sensor (and a mic, but we know that) but they aren’t used in the software (yet). The more I looked into the system, I was aware that because it was such a huge rewrite, I had misjudged when I assumed that it would be harder to break as Amazon had years to fix the holes now. In fact, I would say that the Kindle 4 is more secure until I found out that Amazon left in SSH in diagnostics mode. Anyways, as I searched up the complexity chain from the bootloader to the kernel to the libraries to the Java interface, I found something very curious. Much of the operating system is no longer written in Java, but are now in HTML5 and Javascript. In fact, many of the interfaces on the Touch are actually web pages in disguise. For example: the password entry screen, the search bar, the browser (is just an HTML page with a frame), the Wifi selection screen, and even the music player. Obviously, these can’t all run natively in HTML and JS, or the device will be even slower (and it is pretty damn slow). What Amazon did is write a couple of Javascript hooks that are implemented by native libraries and events are read by these libraries and they perform actions accordantly. In short, Javascript will run native code. This is a goldmine, there could be many possible ways of using this to our advantage. There could be buffer overflows, heap overflows, string formatting bugs, etc. However, I didn’t have to look though much before I found a curious function: nativeBridge.dbgCmd();. It seems too good to be true. This function takes any shell command, and runs it (as root). Yup. The web browser will run as root, any command given to it. Don’t go looking for remote code execution yet (although it is highly possible), as the native bridge seems to be disabled when in web browser mode (it may be able to be bypassed, but I haven’t looked into it).

Calling the debug function

So the normal browser (as the one you can enter URLs into) can’t make use of this native bridge. However, as I’ve mentioned, a large part of the GUI in the Kindle Touch is HTML and JavaScript. All we need to do is inject some HTML into one of these and we would be all set. We need something that takes input and displays it to the user. The first thing I thought of was the media player. The Kindle displays the song title, artist, and album name in the music player, so what if we put some HTML into the ID3 tag? Yup, it works. How about some javascript? Running. Let’s try to call the debug function. It works. Well, that was a freebie.

Having some fun

That was a bit too easy and I was disappointed that I didn’t get to talk about how I whipped out IDA Pro and did some master debugging. So, let’s make things harder. We can use a MP3 with custom ID3 tags to execute any command, but how can we make this into a cool one-click solution? First of all, we should limit ourselves to one file to copy. Why make the user keep track of MP3s and shell scripts and where to put them? I took the shell script payload (which installs a developer key into the device so custom packages can be installed) and placed it into the comments section of the ID3 tag in the MP3. Then I used “dd” to extract the script, chmod it, and execute it. Now, another problem in terms of user friendliness is how to let the user know that the process was successful? I quickly whipped up an awesome looking “splash screen” and planned on displaying it while the magic is taking place. At first I tried to encode it into a variable in the shell script payload and extract it, but it was too slow and memory intensive. Instead, I took the image, raw, and appended it into the end of the MP3 (after all, the file was a bit too small). You can see the result in the video attached.

What’s next?

Just because the device is jailbroken does not mean it can now magically do anything you want. What needs to happen first is that developers need to take the device and write some code for it. This first jailbreak is really for these developers. For regular users, the only use is to preemptively unlock your device now in case the method is patched in an update or something. No mods for older Kindles will work as-is on the Touch. I’ve included a VERY basic usbnetwork package that will allow you to have SSH access to the device. I think that’s as good of a starting point as anything. From there, developers should be able to rip the root filesystem, test modifications, and write useful tweaks. (And in case of a brick, read my previous post on the bootloader access). Some things I would have to see or do is GUI plugins in the device’s operating system. The Java code is easy to decompile and read as the variable names have not been stripped out (like previous models). Hopefully people can write some reader plugins (like X-Ray) or even format plugins for other ebook formats. Being a touch screen device, one could also write games or useful apps (although the speed and eink are limiting). I need to finish writing the update creation tool so developers can package their modifications.


Download the jailbreak here

Simple custom screensaver mod

Simple usbnet update (supports wifi ssh and resetting root password)

GUI menu launcher and screen rotation hack


Page 3 of 1112345...10...Last »