How I changed the rotation on my Nook
This was originally posted on my first attempt at a blog, which has since disappeared. It was posted on September 15, 2011.
I really like my nook. It hasn’t been used much recently because I got an android phone, but it still is my favorite tool for reading books.
As someone who loves tinkering with computers, I naturally rooted my nook the day after I got it. Having read all about the things one can do with a rooted phone, I looked around on nookDevs.com to see what was available. Unfortunately, I soon learned that the nook has very little extra to offer post-root. Since it runs a very old version of android (1.5), very few apps can run, and of those only a select few were actually written for the nook. (Unlike most android devices, the nook is completely locked down from the start and does not have the option to install any apps).
Still, I enjoyed the feeling it gave me to know I was “Stickin’ it to the man”, as it were. Sure, I didn’t get much extra use out of it, and the battery life didn’t get better (it actually got worse, sense I had the adb service turned on at bootup and neglected to disable it after root was established). Overall, though, I liked simply having a rooted device.
It wasn’t long, though, until I found a root-only feature that I absolutely had to have. The ability to rotate from portrait to landscape and, more importantly, to get rid of the status bar and progress indicator so that I could read in full-screen mode.
See, Barnes & Noble, in their infinite wisdom, thought that we readers would like to know what page we were on all the time, so they stuck a progress bar at the bottom along with the current and total page numbers. They also knew that we wanted to have the title of the book displayed at all times in the top status bar, along with the battery power left. And they decided to refuse the reader a way to turn these features off!
Not only does the extra information eat up several lines of text, it keeps you from fully immersing yourself into a book by displaying metadata. I found this very annoying, and I had the hacked app installed the instant I heard about it. Thanks to twll.blogspot.com, my nook was now supercharged for reading, exactly how I wanted it.
The fullscreen mode was perfect. The hacked version of the reader app had a preference for enabling and disabling right alongside all the normal preferences. It also let you change from portrait to landscape.
Landscape was nice, though it did have a little quirk. The screen rotated clockwise, so the touchscreen that was on the bottom was now on the right. The quirk was that the keymaps were unchanged. See, on the both sides of the screen are a pair of buttons, one for moving to the previous page and one to the next. The button marked “<” moved to the previous page, and “>” to the next.
When one rotates the device, the previous button now looks like a “V” and next looks like a “^”. Your mind, though, wants to assign an arrow pointing down to the function of the next page, where this setup with unchanged keymapping causes it to go to the previous.
I thought to myself that if the display were to rotate the opposite direction for landscape, the buttons would match up in my mind and in the devices mind as to what they should be doing.
So why was it rotated this way and not that? Who knows. The hacker may have been so excited to have found a way to rotate that he neglected to test what it felt like in real life. Or perhaps he decided it wasn’t worth the trouble to go back and figure out how to rotate it the other way. I never saw a comment about this issue, so maybe he never even knew about it.
I decided I should put my skills to the test. I had the hacked version as well as an original. I decided to compare the differences and see if there existed a simple way to switch things around. Android apps come in a zipped package with the extension “apk”. Open it with any unzipping program, and you’ve got the source code. Wait, I guess you’ve got some resource files and a “classes.dex” file.
A few minutes of google were all I needed to learn about apktool. This little baby can reverse compile any android apk. Running the apk through this gave me a java “jar”. Inside that “classes.dex” file were all the java classes. So I just open them up in a text editor, and...
Rats! It’s a binary. A couple more minutes on google and I found jd-gui, a small app that can read java class files. All right! Now I’ve got the source code open, and I can easily see the precompiled source code. All I have to do is poke around...
There we go. A couple of educated guesses in the search has turned up a couple classes in the hacked version that are missing in the original. And there are two references to a “canvas.rotate” method. This takes in three parameters, and the first on is the number 90. This seems like the perfect parameter to mess with. Assuming the 90 is referring to 90 degrees rotation, lets see what happens when I change it to 270.
Darn it, the jd-gui is a read-only application. In order to modify this value, I’d have to set up an entire workspace, import the project, change this value, recompile, and hope everything works! This does not seem ideal.
I did some more searches and found out that one does not need to convert that dex file into java sources but can be converted into dex “smali” code files using baksmali. Apparently, these are more like assembly than java, but at least the files output by the utility are plaintext and can be edited by hand.
I opened up the class, er, smali file and did a search for “rotate”. The file definitely looked more like assembly, but I wrote some assembly in college and I was easily able to decipher it. I found the three float variables declared right before, with hexadecimal values. A quick conversion in my calculator of 270base10, and I changed that parameter to 10E.
Baksmali comes with the utility “smali”, which is used to recompile the smali files into that classes.dex file I saw earlier. I ran this, put the resulting dex file back into the apk, and then used adb to install the file to my nook.
Success!!!! Woo! I got this baby to rotate the other way, and it took very little coding on my part! Slight problem, though. The text is definitely not centered, and a bunch is chopped off.
Back in the jd-gui class browser, I took a closer look at the other two parameters passed in. I searched on google and found out that these two parameters determine the x,y location on which the rotation occurs. Oddly, rotating 90 degrees and -90 degrees don’t have the same offset result, so I started changing these values and sending the updated apk to my nook.
After much frustration, I realized that changing one value made the text move, not left/right or up/down, but left/right AND up/down. To make the text move only in one direction, I had to add the same amount to each value, or add the amount to one and subtract the same from the other, or the inverse of each.
Eventually I figured out the magic values to make the text center properly after rotating, and I finally have a landscape view that both my brain and my nook can live with.
I learned a lot from this relatively simple fix. First, if you have a small niche that needs filling and you want a task done, you probably are on your own. When something large like the actual process of rooting android exists, you can bet there are a lot of people wanting to make it happen. In that case, you can help or not help and it will probably get done by someone eventually. But when the range of people being affected is very very small like this, if you have the means to do it, get off your butt and do it! Odds are, the venn diagram of “people who care” crossed with “people who can fix it” include only you or, if you’re really lucky, you and a few other people.
I also learned a lot about reverse engineering an android app. For us tinkerers, this is a good thing. But it also shows that apps are somewhat vulnerable. If you rely on the fact that you don’t release your source code in order to keep security, you need to rethink your strategy. A pirate can take your app, remove any locked down restrictions, and release the it to the public.
There are some things you can do, such as code obfuscation. This is something you use before your code gets compiled that changes all your methods and variables to something a first year college programmer would use; That is, your method “printContactInformation” becomes “method1” and your descriptively named “socialSecurityNumber” variable is changed into “a”. When your code is reverse engineered, all the person will see is this type of language, so deciphering the purpose of variables and functions becomes very tedious.
Well, there’s my tiny trip into reverse engineering.
#convert the package into java binary classes
sh ./dex2jar.sh package.apk
#view the classes
#get the classes.dex file out of the apk
Just open it from a zip viewer and extract the file
#reverse compile the classes file into smali files
Edit any files you want in a text editor
smali out -o classes.dex #compile the changed smali files
zip ReaderEpub.apk classes.dex #add the updated classes.dex file to the app
adb push ReaderEpub.apk /system/app/ #push the new app to the nook - no reboot required