📜 ⬆️ ⬇️

Development and modification of firmware for Android phones. Part 2

In the first part, we learned how to repack official firmware from RUU format into the update package format, which gave us the opportunity to use the firmware we created without fear of overwriting the modified recovery rom . And in the meantime, while HTC is fighting with good resources , we will continue to study and improve the firmware.
In the previous part, even though we created a firmware that loads and works like a clock, we would like to extend the basic functionality of it. One of the most sought-after extensions is support for working with root privileges ( root ). Also here is the integration of busybox . In addition, we will learn how to run arbitrary scripts at system startup and adapt ramdisk to fit our needs.

Busybox



busybox is a set of console unix utilities , focused on small size and performance, which is so important for mobile systems. Together with the android system comes its own set of utilities - a toolbox , which provides the minimum necessary functionality for the system, and as a result, is simpler in terms of quantity and function. The presence of busybox in the system, on the one hand, will allow us, as developers, to feel more comfortable when working remotely on the device, on the other hand, will allow us to write complex scripts, and, for example, implement a mechanism to run our own scripts at boot time using run-parts . Also it is worth considering that for some android applications (especially those that use root ) the presence of busybox is mandatory.
')
In order to simplify your life, we will use the already collected by the busybox under our platform. For example, 1.16.0 from the well-known modaco can be picked up here . Whoever has the courage, and has too much time, can collect the busybox from the official tree (a bit of the adaptation file for the Androids toolchain , and the bionic - android libc implementation), or use the XVilka assembly instructions with crosstool-ng and uCLibc , or assemble from branches cyanogenmod , where bionic problems have already been solved.
So, before we add busybox , we need to solve a few ideological points in the system:

To find out which applets are supported by busybox , just run it on the device with no parameters:
  1. $ adb remount && adb push busybox / cache / $ adb shell chmod 0755 / cache / busybox $ adb shell / cache / busybox | tail tcpsvd, tee , telnet, telnetd, test , tftp, tftpd, time , timeout, top, touch , tr , traceroute, true , tty, ttysize, tunctl, udpsvd, umount , uname , uncompress, unexpand, uniq , unix2dos, unlzma, unlzop, unzip , uptime , usleep, uudecode, uuencode, vconfig, vi , vlock, volname, watch, watchdog, wc , wget , which , who , whoami , xargs , yes , zcat , zcip
  2. $ adb remount && adb push busybox / cache / $ adb shell chmod 0755 / cache / busybox $ adb shell / cache / busybox | tail tcpsvd, tee , telnet, telnetd, test , tftp, tftpd, time , timeout, top, touch , tr , traceroute, true , tty, ttysize, tunctl, udpsvd, umount , uname , uncompress, unexpand, uniq , unix2dos, unlzma, unlzop, unzip , uptime , usleep, uudecode, uuencode, vconfig, vi , vlock, volname, watch, watchdog, wc , wget , which , who , whoami , xargs , yes , zcat , zcip
  3. $ adb remount && adb push busybox / cache / $ adb shell chmod 0755 / cache / busybox $ adb shell / cache / busybox | tail tcpsvd, tee , telnet, telnetd, test , tftp, tftpd, time , timeout, top, touch , tr , traceroute, true , tty, ttysize, tunctl, udpsvd, umount , uname , uncompress, unexpand, uniq , unix2dos, unlzma, unlzop, unzip , uptime , usleep, uudecode, uuencode, vconfig, vi , vlock, volname, watch, watchdog, wc , wget , which , who , whoami , xargs , yes , zcat , zcip
  4. $ adb remount && adb push busybox / cache / $ adb shell chmod 0755 / cache / busybox $ adb shell / cache / busybox | tail tcpsvd, tee , telnet, telnetd, test , tftp, tftpd, time , timeout, top, touch , tr , traceroute, true , tty, ttysize, tunctl, udpsvd, umount , uname , uncompress, unexpand, uniq , unix2dos, unlzma, unlzop, unzip , uptime , usleep, uudecode, uuencode, vconfig, vi , vlock, volname, watch, watchdog, wc , wget , which , who , whoami , xargs , yes , zcat , zcip
  5. $ adb remount && adb push busybox / cache / $ adb shell chmod 0755 / cache / busybox $ adb shell / cache / busybox | tail tcpsvd, tee , telnet, telnetd, test , tftp, tftpd, time , timeout, top, touch , tr , traceroute, true , tty, ttysize, tunctl, udpsvd, umount , uname , uncompress, unexpand, uniq , unix2dos, unlzma, unlzop, unzip , uptime , usleep, uudecode, uuencode, vconfig, vi , vlock, volname, watch, watchdog, wc , wget , which , who , whoami , xargs , yes , zcat , zcip
  6. $ adb remount && adb push busybox / cache / $ adb shell chmod 0755 / cache / busybox $ adb shell / cache / busybox | tail tcpsvd, tee , telnet, telnetd, test , tftp, tftpd, time , timeout, top, touch , tr , traceroute, true , tty, ttysize, tunctl, udpsvd, umount , uname , uncompress, unexpand, uniq , unix2dos, unlzma, unlzop, unzip , uptime , usleep, uudecode, uuencode, vconfig, vi , vlock, volname, watch, watchdog, wc , wget , which , who , whoami , xargs , yes , zcat , zcip
  7. $ adb remount && adb push busybox / cache / $ adb shell chmod 0755 / cache / busybox $ adb shell / cache / busybox | tail tcpsvd, tee , telnet, telnetd, test , tftp, tftpd, time , timeout, top, touch , tr , traceroute, true , tty, ttysize, tunctl, udpsvd, umount , uname , uncompress, unexpand, uniq , unix2dos, unlzma, unlzop, unzip , uptime , usleep, uudecode, uuencode, vconfig, vi , vlock, volname, watch, watchdog, wc , wget , which , who , whoami , xargs , yes , zcat , zcip
  8. $ adb remount && adb push busybox / cache / $ adb shell chmod 0755 / cache / busybox $ adb shell / cache / busybox | tail tcpsvd, tee , telnet, telnetd, test , tftp, tftpd, time , timeout, top, touch , tr , traceroute, true , tty, ttysize, tunctl, udpsvd, umount , uname , uncompress, unexpand, uniq , unix2dos, unlzma, unlzop, unzip , uptime , usleep, uudecode, uuencode, vconfig, vi , vlock, volname, watch, watchdog, wc , wget , which , who , whoami , xargs , yes , zcat , zcip

For a list of available applets for the toolbox, we will focus on those links that were created in the original firmware.
  1. $ find habrrom / system / bin / -type l -printf '% f,' | tail
  2. getprop, insmod, ifconfig , setprop, wipe, watchprops, log, sync , schedtop, ioctl, rm ,
  3. sleep , notify, sendevent, dmesg , df , route, vmstat , mv , iftop, rmmod,
  4. dd , renice, kill , mount , start, rmdir , ps , ln , cmp , dumpcrash, top, getevent,
  5. umount , mkdir , setconsole, printenv, newfs_msdos, chown , cat , hd, chmod , date ,
  6. stop, smd, netstat , ls , lsmod , id ,

The only link pointing not to the toolbox is dumpcrash :
  1. $ ls -o habrrom / system / bin / | grep dumpstate
  2. lrwxrwxrwx 1 astar 9 2010 -06- 16 03: 59 dumpcrash - > dumpstate
  3. -rwxr-xr-x 1 astar 14296 2010 -06- 16 03: 55 dumpstate

This is also worth considering when building the update script.
Suppose we decided that the main thing we will have is busybox . I found that the following toolbox applets are unique:
  1. getevent, getprop, iftop, ioctl, log, newfs_msdos, notify, schedtop, sendevent, setprop, smd, start, stop, top, umount , vmstat , watchprops, wipe
  2. getevent, getprop, iftop, ioctl, log, newfs_msdos, notify, schedtop, sendevent, setprop, smd, start, stop, top, umount , vmstat , watchprops, wipe
And suppose that we want to create links during the installation of the firmware, for this we need to add the following lines to the update script:
  1. symlink dumpstate SYSTEM: bin / dumpcrash
  2. #
  3. symlink toolbox SYSTEM: bin / getprop
  4. # repeat the procedure for the necessary toolbox applets
  5. symlink busybox SYSTEM: xbin / [
  6. # repeat procedure for all busybox applets

Do not forget to remove links from the firmware itself.
  1. $ rm ` find habrrom / system / bin / -type l `
Plus, we need to set the correct rights to busybox.
  1. set_perm 0 0 04755 SYSTEM:xbin/busybox
Let's try to complicate your task. Let's place links for busybox in a separate directory, for example / system / xbin / bb . To do this, we need to add a non-empty folder in the firmware structure (an empty folder, will refuse to copy the update script):
  1. $ mkdir habrrom / system / xbin / bb
  2. $ touch habrrom / system / xbin / bb / placeholder

Now we can safely place our links to the specified path, for which we will update the update script:
  1. symlink ../busybox SYSTEM: xbin / bb / [
  2. # and so on


Ramdisk modification



However, simply placing the links in a separate folder is not enough. We need to expand the search path for executable files for the system. To do this, we need to add the $ PATH variable, which in the case of the android on HTC Hero is defined in /init.rc
  1. $ adb shell cat /init.rc | grep "export PATH"
  2. export PATH / sbin: / system / sbin: / system / bin: / system / xbin

All files in the root directory are part of ramdisk (as well as some other subdirectories). Let's use the knowledge from the first part : unpack the boot , after which we can change the PATH variable
  1. $ cat habrrom.boot / ramdisk / init.rc | grep "export PATH"
  2. export PATH / sbin: / system / sbin: / system / bin: / system / xbin: / system / xbin / bb

Before we collect ramdisk back, let's do some more useful things.
To simplify life, we would like to have the following:
  1. The ability to mount the file system with write permissions
  2. USB debugging enabled by default. Otherwise, if something goes wrong, we will not be able to get at least some useful information about the causes, since the adbd service will be disabled and, as a result, adb logcat will be unavailable during the download.
  3. Run arbitrary scripts when the system boots (the most popular use cases are: enable app2sd , transfer dalvik-cache to / cache )

To do this, look at /default.prop , which among other things stores the following settings:


Initialization scripts



To implement the third item, we need to modify the initialization script /init.rc . This script as usual, is a bike of your own android script on Android Init Language . I propose to familiarize with the format in the source code android . We are also interested in the ability to add our own service (we cannot add our commands directly to the trigger, because there the command set is strictly limited):
  1. service sysinit /system/bin/logwrapper /system/xbin/busybox run-parts /system/etc/init.d disabled oneshot
  2. service sysinit /system/bin/logwrapper /system/xbin/busybox run-parts /system/etc/init.d disabled oneshot
  3. service sysinit /system/bin/logwrapper /system/xbin/busybox run-parts /system/etc/init.d disabled oneshot
Those. we called our service sysinit , which, when it starts, will run run-parts /system/etc/init.d, which in turn will run all the scripts from the corresponding folder in alphabetical order. we need logwrapper in order to redirect the output instead of / dev / null (by default) to the logging system (accessible by logcat ).
It remains to start our service (the option is disabled , it says that this service will not start automatically). To do this, move the last command from the on boot trigger to our own trigger for the end of the scripts and call our service.
  1. # not now
  2. # class_start default
  3. start sysinit
  4. on property: habr.sysinit.done = 1
  5. # now
  6. class_start default

We will also create two simple scripts in /system/etc/init.d to demonstrate that this all works. The first one will do the standard echo ( Hello World!, As without it), and the second will clear the cache, and inform the init script that we have already finished and we can continue to load further.
  1. $ cat habrrom / system / etc / init.d / 00banner
  2. #! / system / bin / sh
  3. echo "Hello habrahabr!";
  4. $ cat habrrom / system / etc / init.d / 99complete
  5. #! / system / bin / sh
  6. sync;
  7. setprop habr.sysinit.done 1

And the final touch - we will install them the right to run (all the same - in the firmware update script)
  1. set_perm_recursive 0 2000 0755 0755 SYSTEM:etc/init.d

Superuser rights Root.



For many, probably the most pressing question. For those patient who read it.
Despite the fact that the source has its own implementation of su , it does not suit us, because its main goal is to launch applications as a superuser (or from adb shell ) with the rights of other user s.
We will use the development of ChainsDD - Superuser 2.1 application. The essence of the application is similar to the familiar sudo , or even Admin Approval Mode from the Windows system. If the application wants to elevate its rights to superuser rights (and not only), permission is requested from the user. You can also remember the accepted rule and automatically apply to all future calls.
We use the already assembled application for Android 2.1, although there is always the opportunity to study and compile most of the sources .
The application consists of two components:
  1. native module su . Which, when requesting a change of rights, redirects the request to its own Activity and waits for the user to respond
  2. Superuser.apk application - a set of interfaces ( Activity ) responsible for user interaction, storage of settings.



In order to add the specified functionality to our firmware - we will add modules to the appropriate sections of the system,
  1. $ cp su habrrom / system / xbin /
  2. $ cp Superuser.apk habrrom / system / app /

and configure permissions for the executable file (plus a link to / system / bin / , since some applications may call su in an absolute path)
  1. symlink ../xbin/su SYSTEM:bin/su set_perm 0 0 06755 SYSTEM:xbin/su
  2. symlink ../xbin/su SYSTEM:bin/su set_perm 0 0 06755 SYSTEM:xbin/su

That's all.
I am enclosing a small archive , as a final summary of what has been done in this article. Scripts, busybox , Superuser, and more. For the curious.
This time it turned out to be somehow very Linux-like, and dumb. But next time we consider the topic more fun - repackaging system applications. In the meantime, the final point:



In previous and future series
  1. Part 1. Creating firmware in update.zip format based on RUU. Unpacking / packing boot. Update script. Sign service pack and applications.
  2. Part 2. Adding busybox. Adding root. Mount to write. Initialization script Editing ramdisk.

Source: https://habr.com/ru/post/97169/


All Articles