Saturday, July 20, 2013

Eliminate ads and custom screen saver on the new Kindle 4



It has been a while since the last time I posted something in this blog.
It's not that there hasn't been something interesting to post - there's simply not enough time.

Let me note here that this post is not intended to be either a step by step guide either a how to and that I'm not interested on writing one in the foreseeable future.
This is just a post with some notes that I am happy to share with the internet.
So no questions in the comments about the procedure itself will be answered (except if I find them interesting / worth the discussion)
You've been warned.

Kindle is a wonderful ebook reader device with the best eink display in the world that happens to run linux in the background. I love mine, and love reading with/on it.

Recently a friend of mine asked me to help him add custom screen savers to his brand new Kindle 4.
I have my own Kindle (a kindle 3 - with a keyboard) which I have already jailbroken and added a symbolic link to the appropriate folder to add custom screensavers on it. This is not a dificult task, you can find detailed guides all over the internet.

But this Kindle came with ads enabled so I was introduced with a new kind of problem.
Having no exact memory of the procedure I followed for my kindle 3, I did what I do most of the times (and try to somehow support with this blog)

I googled :)

What I found was some guides (like this one) which in sort, instructed to replace the %kindle_disk%/system/.assets folder with a file named the same.

There was little success.





The ads where gone, but the banner "please connect wirelessly to download the latest Special Offers" was still there. There were again guides (like this one) that instructed "a new way" of removing the ads AND the banner, by restoring to factory defaults, replacing the %kindle_disk%/system/.assets folder with a file named the same, just before setting up a your account details in the newly restored kindle.

I later found that the new version of the kindle OS (the 4.1.1) had this bug fixed, and since then, no workaround has been posted on the internet (or maybe I haven't found it) although I found some user comments that claimed that they successfully followed the guides.
But in my case nothing seemed to work, so I had to search more.

I wanted some insight/control of the OS so I searched for a way to open a terminal and look around. I remembered creating a file named %kindle_disk%/ENABLE_DIAGS and rebooting the device started the diagnostics mode in which I could find the "usbnet" and connect to the kindle through ssh. Although I could ping the device, the ssh port seemed to be closed and my connection was refused. I found out that these new kindles have the usbnet blocked(/disabled?). So my problem was now enabling the usbnet somehow...

I decided to try and jailbreak it first. I found the latest jailbreak for the previous version of kindle OS (4.1.0) (from here)  and gave it a try. It was successful, but I still couldn't connect with ssh in the diagnostics mode.

I decided to take it home and devote more time to it when I had some.



After a few days, I started trying again.
Now, what the kindle jailbreake actually does is (according to the "kindle-jailbreak-k4-1.6.N.zip" README file) "...NOTHING except open the door for other packages. Do not expect ads to magically disappear or internet to be unrestricted just by jailbreaking. In fact, don't expect those things at all."

Darn it.


Before getting the kindle home with me, I had already planned my next step. I had already found this thread and already downloaded the kindle-usbnetwork-0.49.N.zip file. After reading the README.FIRST file (that was harsh with windows users - and I liked it) and searching what the hell did it mean with "Nothing fancy, as usual, with a jailbroken Kindle, just use the appropriate update file." under the install section I was able to install the package just by placing the "update_usbnetwork_0.49.N_k4_install.bin" file in the  %kindle_disk%/ root folder and set my kindle to update.

Now, after reading some more of the readme file, I discovered that I can send commands through the search bar!

The commands I used:
 ;debugOn  
 ~usbNetwork  

Basically, when you hit enter, each command runs - it took me a while to figure this out...
I read somewhere that while debug mode is on, the power save mode is off and the battery will drain quicker. Anyways...

When I did that, I connected the kindle and voila! My ubuntu machine told me it found a new network connection. I had to set my ip on usb0 at 192.168.2.1

I did it with this command:
  $ ifconfig usb0 192.168.2.1  
Later I used the gui too

After that, when I tried to ssh to 192.168.2.2 I was successful.

I entered "mario" as my password and I connected to a secure shell. But the second time I tried to connect, my password was refused. After wondering for a while, I remembered that there is a way to generate a kindle root password with an algorithm using the device’s serial number.


I found the following python code:
  #!/usr/bin/env python  
 import hashlib  
 print("fiona%s"%hashlib.md5("XXXYOURSERIALXXX\n".encode('utf-8')).hexdigest()[7:11])  
Which gave me the password that logged me in successfully!


So now I started testing and searching all kinds of stuff. For example, I searched for every piece of image inside the kindle just to find the banner and delete it. I found them much later in /mnt/base-mmc/amazon/screen_saver/adunits/600x800/

I have to note here that I was getting tired copying with cp all the images i found in some folder in /mnt/base-us/ and reconnecting with usbNetwork off to see if any of the images had something to do with the banner. So I discovered a command named scp which copies files through ssh!


For example:
  $ scp -r root@192.168.2.2:/mnt/base-mmc/amazon/screen_saver/adunits/600x800 /home/%user%/Desktop  
Copies everything from .../600x800/ to the desktop


Neat!


Of course, amazon  coders had to do it a little harder than that. After deleting these images and connecting to the wifi for a while, the banner redownloaded and I was able to see it again. So I had to search a little more. I searched for "adunits" and found another folder at /var/local/adunits

I renamed the folder and created a file with the same name and chmoded it to 444 so that the system cannot change it

  $ chmod 444 adunits  


Note: I tend to do that to everything I change - that is backup and create a file with the old filename with different rights, because of two reasons:
Firstly, if I brake something, I can always recover it that way and
Secondly, if the system tries to change somthing, most of the time it won't be successfull.
And sometimes, if you're lucky enough, the code will just be satisfied with the existence of the filename itself, whether it is actually a file or a folder and wont sent a crash signal which will result in an unusable system. I found out later, after googling "adunits" that what I did was actually good (here) except I didn't restart the process mentioned. The reason I didn't find this article earlier was that it describes the procedure for kindle touch, which I rejected as non compatible after I clicked in some results and reading some instructions and tips.
I also tested the stop and start "framework" commands from this thread and it seems that the kindle 4 doesn't support these commands or doesn't have the framework process running in the same way.

Anyways

I had Success!!!




The banner was gone from the homescreen and from the screensavers! Now it was a matter of  creating a symlink from the screensavers folder to a folder in the kindle’s root folder /mnt/base-us/

I didn't bother to remember the syntax of  ln, I googled, found the code (here) and changed it a bit

 $ mntroot rw  
 $ mkdir /mnt/base-us/screensaver  
 $ mv /opt/amazon/screen_saver/600x800 /opt/amazon/screen_saver/600x800.old  
 $ ln -sfn /mnt/base-us/screensaver /opt/amazon/screen_saver/600x800  

I also copied the old 600x800 folder with the stock screensavers in another folder in case I wanted to use some of them.

Now, I just rebooted, disconnected, plugged in the kindle and loaded some screensavers in the newly created screensavers folder. After rebooting, the screensavers loaded successfully






So now, the kindle has custom screensavers and no ads!





Moral implications:   Removing ads from kindle is bad, mmkay?

This device is to be used for some free english e-guides and mostly greek e-books. Amazon’s ads clients aren't losing a potential customer.
Also, as it is mentioned here, Amazon is nice enough to sometimes unlock the ads for free to customers outside the ads’s main target countries. So, in a manner, I just made their job a little easier...




TODO:

Make ssh connection wirelessly posible by default

While I was lurking around with the terminal via usbnetwork-ssh, I was trying to get ssh work wirelessly. I wanted this for the following reasons:

1) Every time I had to reboot, I had to enter the commands to the homescreen to enable usbnetwork... a time consuming process since there is no keyboard and the typing is done thtough a keypad! (that's the main reason I got a kindle with a keyboard instead of the 4)
2)Every time I had to send or copy a file, I had to unplug, disable usbnetwork, plug it in, manage the files, unplug it and enable the usb network again...

So enabling wireless ssh by default would be nice and give me more free time to tether the kindle more.
What I've found already (and used) is this

 $ iptables -A INPUT -i wlan0 -p icmp -j ACCEPT  
 $ iptables -A INPUT -i wlan0 -p tcp --dport ssh -j ACCEPT  

Using either of these commands enables ssh over wifi.
Iptables configures firewall options. Porblem is, the firewall options are reset everytime the device reboots.

I stumbled upon an entry in /etc/init.d/network while trying to create a script to be run at startup that stated:

 # Install firewall  
   cat /etc/sysconfig/iptables | iptables-restore  
   msg "Installed Firewall" I  

After some research, I found out that iptables-restore does exactly that - it restores the iptables to its default configuration (I don't know though who and what decides the "default" configuration)

So I commented the lines. No luck...

I decided to ignore this problem and focus to the main one at the time. Now that I finished I will devote time to it again when I have some.

'Till then, thanks for reading!


Update:

So it seems a little more reading would get me through eventually.
 cat /etc/sysconfig/iptables | iptables-restore   
This line pipes the output of cat to iptables-restore...

So whatever I wrote in /etc/sysconfig/iptables would be run if this line was uncommented
So I did.
And I run it just to check it’s output and found that I made a little mistake in the syntax of some iptables configuration.
I fixed that but nothing seemed to work.



So I tried to make my own script that runs at boot

Meanwhile, I found this fellow (seems greek to me) that made a nice startup script and after a little research in linux init.d scripts I made this:
 #!/bin/sh  
 iptables -A INPUT -i wlan0 -p tcp --dport ssh -j ACCEPT  
 exit 0  
and saved it in /etc/init.d/wlanssh and made a symbolic link to /etc/rc0.d/K09wlanssh

After the reboot nothing happened of course.

Then I started understanding, the problem was that sshd wasn't running, because kindle 4 has it disabled by default and only by running usbnet can we enable it and make use of it.

True, running usbnet enabled wifi ssh too. There is a config file in %kindledir%/usbnet/etc/config
But I didn't know that. Or I didn't remembered. It seems that when I was playing around with ssh I first discovered the iptables command and then enabled the wifi in the config file (that runs exactly the same command at startup) but I didn't give it any other attention or meaning (I was propably to tired with the problem already)

I know it seems like a mess. It is.
It happens some times...

Before I re-discovered the config file and its uses, I tried to make a complete copy of the usbnet services and rename every non shared variable to something like "wifinet" I won't go into details here, they are lengthy and this post is already long. I found many things inside the code of usbnet and I have to say the kids that did it did a great job. Note to whom it may concern: Yes I rtfm, thank you.

So the code itself pointed me in the config file in which I found the solution
Simply change the following variable to true in %kindledir%/usbnet/etc/config :
 K3_WIFI_SSHD_ONLY="true"  
The guys who wrote usbnet had already taken care of it.

So,
1) There must be a file named %kindledir%/usbnet/auto
2) %kindledir%/usbnet/etc/config enable wifi and make it wifi only
3) Restart kindle

Note that when the kindle is in sleep mode you cannot ssh to it via wifi and that it is recommended to ssh to your kindle in usb mode first to obtain the key...

So that's it! Now if an update ever occurs that re-enables the ads, I have already set up a simple and easy wifi ssh connection to explore my option further.



Amazon, the next move is yours

6 comments:

  1. Want to make a tut for this?

    ReplyDelete
  2. sorry, I do not understand how you used the search bar for commands. I'm pretty confused from here on out. It is a kindle 4.1.1

    ReplyDelete
  3. if iptables-save exists... after performing: "iptables -A INPUT -i wlan0 -p icmp -j ACCEPT" and
    "iptables -A INPUT -i wlan0 -p tcp --dport ssh -j ACCEPT", you would then perform "iptables-save >> /etc/sysconfig/iptables". This saves your iptables config into the file that gets loaded by default upon reboot... but only if iptables-save exists as a runnable program, else you'd have to edit /etc/sysconfig/iptables manually.

    ReplyDelete
  4. I haven't tried yet, as I just got a hand-me-down K4 a week ago. I will be trying soon.

    ReplyDelete
  5. the simplest way is this: https://www.reddit.com/r/kindle/comments/3peym3/never_pay_to_remove_kindle_promotionsads/
    you don't have to risk your kindle!!!
    it worked for me!

    ReplyDelete