(c) 2014-2018 Paul Sokolovsky. Portions of content (c) by their respective authors.
If that kernel is booted and you have access to console:
uname -a
Alternatively:
cat /proc/version
If you have only kernel image file ... (tba).
mount
Alternatively:
cat /proc/mounts
dmesg
Kernel log contains all messages from the beginning of kernel boot, but it is implemented as a circular buffer (of configurable size), so newer messages may replace older.
cat /proc/kmsg
will block and dump ''new'' kernel messages. This
will work reliably only if there are no other consumer(s) of
/proc/kmsg
(note: on typical fully booted Linux system there's -
syslogd, etc.), otherwise the output may be garbled.
On a full-fledged Linux system, system log is usually accessible as
/var/log/messages
. Recently, some particular distributions started
to play original, for example, in Ubuntu 12.04 /var/log/messages
is
empty and instead /var/log/syslog
may contain some, or all, of
system log messages.
On an embedded system, a busybox syslogs may be used, providing
circular buffer without file backing storage. It can be accessed using
logread
command.
logger
command does that.
With a running kernel, if it was built with CONFIG_IKCONFIG_PROC, the
config can be read as /proc/config.gz
. For a zImage file,
scripts/extract-ikconfig
can be used to extract it (just
CONFIG_IKCONFIG is required for this).
lsmod
Alternatively:
cat /proc/modules
Low-level command to load a specific filename is:
insmod /path/<module>.ko
Higher level command is:
modprobe <module>
This will look for modules located in /lib/modules/<kernel_version>
and requires support files generated by depmod
.
Module loading is subject to many checks (see below), so and kernel
may refuse to load improper one. If CONFIG_MODULE_FORCE_LOAD is
defined, it is possible to force-load module nonetheless.
Unfortunately, it's not possible to force load with (recent) insmod
.
It can be done with modprobe -f
(modprobe ---help
for other force
options).
rmmod <module>
Module unloading usually available, but still depends on
CONFIG_MODULE_UNLOAD. Module may refuse to unload if other modules
depend on it, or if it's in particular state (which also includes
states like "hanged" and "gone awry"), in which case it's possible to
force unload (rmmod -f
), if CONFIG_MODULE_FORCE_UNLOAD was defined.
In general, this is not possible. With Linux kernel's "stable API is nonsense" attitude, anything in the kernel can be changed at any time
- this includes APIs which can be called by a module, module format and layout itself, etc. Not only that, same kernel version built with different configuration options may have differences in these aspects (it's possible to #ifdef some fields in structures and even parameters to function calls).
That said, for close kernel versions and small differences in configuration, chances of fatal incompatibilities of modules are low. However, kernel itself has "helpful guards" to preclude usage of modules with different kernel version. By default (CONFIG_MODVERSIONS is not defined), kernel's and module's vermagic strings are compared, which are of the form: "3.2.0-32-generic SMP mod_unload modversions 686", i.e. include kernel version, extraversion, then tags for most important configuration params. If vermagics don't match, module loading fails.
Even more annoying "protection" is employed if CONFIG_MODVERSIONS is defined. In this case, each kernel exported symbol gets hash (CRC) signature based on the parameter signature on the underlying C function, stored both in kernel and module. These signatures are compared, and on any mismatch, loading fails. The only easing with this is that when vermagics comparison is done, kernel versions are ignored, i.e. if different kernel versions don't have param signature changes and have same core config params, a module will work across such versions.
There's also support for forced module load, but that will work only if enabled in kernel config (CONFIG_MODULE_FORCE_LOAD).
modinfo <module>
This will dump main module properties and vermagic string. As a parameter, both a filename and system module name (as available in /lib/modules) can be given.
To dump modversions hashes:
modprobe --dump-modversions <module>.ko
From official kernel docs: Documentation/kbuild/modules.txt, for a module source in current dir:
make -C <path_to_kernel_src> M=$PWD
Build against currently running kernel (requires linux-headers package installed):
make -C /lib/modules/$(uname -r)/build M=$PWD
Useful when cross-compiling, etc.
make modules_install INSTALL_MOD_PATH=/path/where
More details: Documentation/kbuild/modules.txt.
If you have another host/embedded device/QEMU connected to a local host interface, and you would like to let that device connect to the Internet, masquerading should be set up for device's IP address:
iptables -t nat -A POSTROUTING -j MASQUERADE -s 192.168.2.2
(This assumes that the host has Internet connection and has IP forwarding enabled).
If you're not on bare command-line, make sure you killed already running wpa_supplicant as well as other daemons which may respawn it (e.g. NetworkManager on Ubuntu).
Make sure that WiFi interface is up. It otherwise doesn't need to have any special configuration:
ifconfig wlan0 up
Run:
wpa_supplicant -i wlan0 -g /tmp/wpa -C /tmp
-g
specifies "global control socket". The caveat about is that many
commands are not supported via it, issuing them via it leads to obfuscated
"UNKNOWN COMMAND" reply. So, it's important to specify -C
switch, which
takes directory path under which individual control sockets for each
WiFi interface will be stored.
In another window, run:
wpa_cli -p /tmp
-p
option gives path to per-WiFi-interface control socket dir (-C
of
wpa_supplicant). Issue following commands in wpa_cli interactive session
(ignore # lines):
# Scan for available APs
> scan
OK
# Wait a bit, then view results
<3>CTRL-EVENT-SCAN-STARTED
<3>CTRL-EVENT-SCAN-RESULTS
> scan_results
...
# Create new AP entry, returned is ID of new entry
> add_network
0
# Start setting AP parameters
> set_network 0 ssid "MY_AP"
OK
> set_network 0 psk "password"
OK
# These should be all params requires for WPA
# Activate network
> select_network 0
OK
# Trigger connection
> reconnect
OK
<3>SME: Trying to authenticate with xx:xx:xx:xx:xx:xx (SSID='MY_AP' freq=2462 MHz)
<3>Trying to associate with xx:xx:xx:xx:xx:xx (SSID='MY_AP' freq=2462 MHz)
<3>Associated with xx:xx:xx:xx:xx:xx
This will have wlan0 connected to AP. Then get IP address via DHCP:
dhclient wlan0
And configure /etc/resolv.conf to suitable DNS address (e.g. 8.8.8.8 to be monitored by Google):
nameserver 8.8.8.8
The instructions above show how to run wpa_supplicant without any stored configuration, and instead configure it dynamically (e.g., programmatically). Alternatively, using config:
# Create simple config file
wpa_passphrase MY_AP >wpa.conf
# Enter password
...
wpa_supplicant -i wlan0 -c wpa.conf
Multicasting is basis of many usability protocols and services (e.g. mDNS, UPNP, DLNA, etc.), and yet means to query/test/diagnose it are not widely known, if not to say obfuscated. At the same time, multicasting has known andregular issues, when used on network interfaces differing from Ethernet, for which it was initially conceived (these other networking types include WiFi/other wireless, loopback, etc.)
Multicast is similar to broadcast, except individual hosts don't receive datagrams unconditionally, but need to join "multicast group" (other way to think about it is a PubSub pattern). Multicast groups are represented by special IP addresses, e.g. for IPv4 it's 224.0.0.0 to 239.255.255.255. Some multicast IPs have predefined (STD/RFC) meaning, other are supposedly can be (dynamically) allocated per purpose.
224.0.0.1 is a "local network" predefined address. All hosts on current subnetwork are supposed to (auto)join it. In this regard, that address is similar to local network broadcast, 255.255.255.255. The basic means to test multicasting is ping this address:
ping 224.0.0.1
The expected outcome is that each host which is member of multicast group will respond (ping thus will receive duplicate responses and will report so).
However:
- A firewall will likely interfere. Note that broadcast/multicast pings are especially not firewall friendly, as replies are not received from destination of packet (ping packets are sent to 224.0.0.1, but received from individual host IPs). The easiest way to deal with this is usually to disable firewall during testing.
- Besides firewall, modern Linux kernels ignore broadcast/multicast pings by default. To enable responses to such pings use:
echo "0" >/proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
(needs to be done on each machine from which you want to receive responses of course).
- The network interface used should have multicast support enabled, and e.g. loopback (lo) is notoriously known to not have it enabled by distros by default.
If you have a normal Ethernet/WiFi interface, following first 2 suggestions
should lead to ping 224.0.0.1
to get responses at least from the host
you run it on.
For other multicast groups, they should be pingable as long as a socket bound to that group is active on a host.
To further diagnose multicast settings, refer to following /proc files:
/proc/net/igmp
(IP-level multicast)/proc/net/dev_mcast
(Physical-level multicast)
Few other points:
- It's not required to be a member of multicast group to send a datagram to it.
- To send a datagram to multicast address, sendto() call should be used, if reply is expected to be received on the same socket. connect() + send() won't work, because reply won't come from a multicast address, but reather from a real host address.
This is called "USB debugging" and is available in Settings -> Developer options. Developer options themselves are concealed by default in Android 4.2 and higher. From https://developer.android.com/studio/debug/dev-options:
On Android 4.1 and lower, the Developer options screen is available by default. On Android 4.2 and higher, you must enable this screen. To enable developer options, tap the Build Number option 7 times. You can find this option in one of the following locations, depending on your Android version:
- Android 9 (API level 28) and higher: Settings > About Phone > Build Number
- Android 8.0.0 (API level 26) and Android 8.1.0 (API level 26): Settings > System > About Phone > Build Number
- Android 7.1 (API level 25) and lower: Settings > About Phone > Build Number
Create /etc/udev/rules.d/99-android.rules
with content:
SUBSYSTEM=="usb", ATTR{idVendor}=="0bb4", MODE="0660", GROUP="plugdev"
Here, 0bb4
is a USB vendor ID, you may need to adjust it for your device;
plugdev
- is typical pluggable device access group on most modern Linux
distros.
Based on: http://developer.android.com/tools/device.html
On Android command line:
su
stop adbd
setprop service.adb.tcp.port 6565
start adbd
Use netcfg
to check device IP. (In newer Android versions, standard
ifconfig
or ip addr
may work.)
Per above (su
), this requires a rooted device. An alternative is to
connect device using USB first, and run adb tcpip 6565
, after which
USB cable can be disconnected.
After that, on host:
adb connect <IP>:6565
adb shell
ADB protocol does not seem to support encryption (protocol description: https://android.googlesource.com/platform/system/core/+/master/adb/protocol.txt). This means that using it over broadcasting non-encrypted physical medium (like Ethernet or public WiFi) is insecure.
Until Android 4.2.2, protocol did not support authentication, which made it highly insecure. There are known exploits of trojan "charging stations" used to break into devices.
In Android 4.2.1_r1, public key authentication was added to adb protocol:
https://github.com/android/platform_system_core/commit/d5fcafaf41f8ec90986c813f75ec78402096af2d
This requires ADB version 1.0.31 (available in SDK Platform-tools r16.0.1 or
higher). User is required to confirm connection to a new ADB host on a device
itself, for one time connection or to remember the approval. In the latter
case, host key(s) are saved in /data/misc/adb/adb_keys
. There can be
pre-installed keys in /adb_keys
.
When connecting to a new ADB host, an Android device shows an RSA fingerprint, however, it takes some effort to check that this fingerprint actually belongs to a host.
On a host, ADB public key is in $HOME/.android/adb_key.pub. To get its fingerprint:
awk '{print $1}' < adbkey.pub|openssl base64 -A -d -a | openssl md5 -c
Based on: http://nelenkov.blogspot.de/2013/02/secure-usb-debugging-in-android-422.html
On Android command line:
logcat
See logcat --help
From host:
adb logcat
On device:
pm list packages
On device:
pm install app.apk
From host:
adb install app.apk
To force install even if already exists:
adb install -r app.apk
adb --help
for more.
On device:
pm uninstall <package.name>
This won't work for system packages located in /system/app
, see
question below on how to remove them.
Try:
cat /path/from >/path/to
First of all, there's /mnt/sdcard
, which is accessible to default
adb
user. However, that filesystem is mounted noexec
, so it's not
possible to run any executables from there. However, there's
/data/local
which is both writable and executable. On newer Android
versions (checked with Android 7), only /data/local/tmp
is such.
An exploit executable is needed. For Android 2.x, zergRush is a well-known app. On host:
unzip zergRush.zip
adb push zergRush /data/local
adb shell
cd /data/local
chmod 770 zergRush
./zergRush
If you get error like [-] Cannot copy boomsh.: Permission denied
,
it's likely zergRush was already run previously and left some cruft,
remove it and retry (on device):
rm tmp/sh
rm tmp/boomsh
./zergRush
Get root shell as described above. Then (you can get newer versions than 3.0.7, but they're kinda bloat):
http://downloads.noshufou.netdna-cdn.com/superuser/Superuser-3.0.7-efghi-signed.zip
unzip Superuser-3.0.7-efghi-signed.zip
adb push system/bin/su /system/bin/
adb push system/app/Superuser.apk /system/app/
adb shell chmod 06755 /system/bin/su
Preinstalled application are in /system/app
, unlike user-installed
applications, which are in /data/app
.
This requires root.
On host:
adb remount
adb shell
Then on device:
cd /system/app
rm bloatware.apk
sync
You may want to reboot to clear app cache, though apps should be gone immediately.
These are defined in system/core/include/private/android_filesystem_config.h
Reference: http://developer.android.com/tools/debugging/debugging-log.html#viewingStd
By default, Android redirects stdout, etc. to /dev/null. However,
log.redirect-stdio
system property can be set to true
to redirect
to system log (logcat) instead. This takes effect after system restart
(and has effect during current system session), so the complete command
sequence to enable stdout logging is:
stop
setprop log.redirect-stdio true
start
service list
Based on http://www.slideshare.net/jserv/android-ipc-mechanism
Getting Java class implementing service:
service call activity 1598968902
1598968902 (0x5f4e5446) is INTERFACE_TRANSACTION.
Prepare to dial number "123":
service call phone 1 s16 123
"1" is a method #1 per
ITelephony.aidl,
i.e. dial()
.
start
& stop
commands do that. E.g.:
stop vold
Alternatively, this can be done by setting system properties:
setprop ctl.stop vold
setprop ctl.start vold
For this, zygote
daemon should be stopped:
stop zygote
zygote is also a default argument for start
/stop
, so following
will work too:
stop
dumpsys <service>
dumps loadsome of information about internal
service state. Omit service name to dump state of all services.
Edit /system/etc/permissions/platform.xml
to add <group gid="media_rw" />
to WRITE_EXTERNALS_STORAGE permission:
<permission name="android.permission.WRITE_EXTERNAL_STORAGE">
<group gid="sdcard_rw" />
<group gid="media_rw" />
</permission>
Reboot required. Tested with Android 4.
make modules
Yes, actually "am", "pm" and few other standard Android tools are actually such, and are run via shell wrapper: https://android.googlesource.com/platform/frameworks/base/+/gingerbread/cmds/am/
hello-world.html from platform/dalvik/docs/ explains how:
# Create file Foo.java
class Foo {
public static void main(String[] args) {
System.out.println("Hello, world");
}
}
javac Foo.java
dx --dex --output=foo.jar Foo.class
adb push foo.jar /sdcard
adb shell dalvikvm -cp /sdcard/foo.jar Foo
I tried to flash a custom image to recovery partition (Android 4.x), however it doesn't boot and instead "red triangle of doom" is shown
Assuming the image is correct for your type of device and flashed into right place for it, known "feature" which causes this behavior is Android 4.x "recovery from boot". The idea is following: Recovery allows you to restore main Android install if something goes wrong. But what if recovery itself gets corrupted? Then if main image gets corrupted too, the device is bricked. So, main image and recovery were made to "watch after another". In particular, during boot of main image, recovery partition is checked, and if it doesn't contain "know good" image, it gets silently reflashed with copy of such image kept in main partition.
The backup of recovery image is commonly held in /system/recovery-from-boot.p . Actual boot-time checking and reflashing is handled by /system/etc/install-recovery.sh . Thus, to disable this behavior which gets into way of advanced Android usage, do following:
mv /system/recovery-from-boot.p /system/recovery-from-boot.p.old
or:
chmod 644 /system/etc/install-recovery.sh
Also, "red triangle of doom" is actually how a stock recovery of Android 4.x looks - while previous versions offered interactive means to investigate and fix your device, that's what to it was reduced in Android 4.x.
Based on: http://android.stackexchange.com/questions/18932/why-isnt-clockworkmod-recovery-sticking , http://androtab.info/clockworkmod/rockchip/install/