This python script adds some usefull command to stripped vmlinux
image.
This script adds some usefull commands for debugging kernel without symbols.
The main goal is to obtain a root shell with Android Emulator
using common Google Play Images with the built-in kernel.
I started this little script because I needed a way to easily obtain a root shell in emulated AVD with Google Play (and Services) installed.
The installation is quite straightforward:
- Clone this repo
- Source inside GDB the script (
source <path_to_repo>/root_gdb.py
)
There is only one requirements: ELFFile
pip install elffile
The script adds some usefull command to GDB.
If you only want to root a process, you can use:
escalate <comm>/<pid>/<task_struct address>
and the script will disable selinux
and change the process credentials.
Just a note: comm
is intended as the field in task_struct
kernel structure (char comm[16]
) so it can be different from the real name (you can check the running process with ls-ps
).
ptask <struct task_struct address>
: Print some fields oftask_struct
structure.f_task <comm/pid>
: Search the process (by PID or COMM) and it returns the address oftask_struct
ls-ps
: List all processcurrent
: GDB function. This is the address of thetask_struct
for the current running processsymbs <symbol name>
: Try to find symbols using ksymtab sectionkcall name_or_address(parameter, parameter, ...)
: Create a new stack frame and execute a kernel function. More of this laterklookup <symbs> <symbs> ...
: Callkallsyms_lookup_name
for each symbols passed as argument.escalate
: This command works like a script. It usekcall
in order to disable SELinux and change the credentials of one process.
The main objective of this script is to obtain a root shell in a any AVD without actually rooting the emulator. The steps are simple:
emulator -avd <YourAVD> -ranchu -verbose | grep kernel.path
: with this command you can see where the vmlinux image is located- That image should be a
bzImage
so you should extract it. I use extract-vmlinux. - You can now restart your emulator with:
emulator -avd <YourAVD> -show-kernel -no-snapshot-load -ranchu -qemu -s -append "nokaslr"
. After the boot, open a shell withadb shell
. - Open GDB with
gdb <path/to/extracted/vmlinux> -ex "target remote :1234"
- Source the script
source <path/to/repo/root_gdb.py>
escalate sh
, wait for the completation andcontinue
. This command refuses to execute if it is not in the context ofswapper
process so you shouldcontinue
and break few times before catching the right process.escalate adb
, this allows to have adb rooted.- Enjoy your rooted Google Image emulator (or the panic :D)
The escalate
commands can panic your kernel. You can retry.
At this moment, this script works only with x86_64 image. In particular, I tested only with Android 10. Feedbacks are really appreciated.
There is an medium chance to panic your kernel. Just reboot and retry.
The main command is kcall
because it allows to modify the running kernel and inject the execution of kernel function. The main idea is to create a new stack frame and jump to the new address. The parameters are handled just copying the value to registers one by one.
If you need to pass some pointers, you can use kmalloc, set the value to that memory location and use that pointer as argument.
If you need others memory locations, you can call kallsyms_lookup_name(pointer_to_char*).
The return value is stored in $ret
variable (so x/x $ret
).
This script uses the _ksymtab in order to find init_task address. Then, we can search some fields like comm and the tasks list.
The escalation is made calling some kernel function. In particular, we can disable SELinux searching, thanks to kallsyms_lookup_name, the selinux_enforcing
symbol. Then, we can create a new credential with prepare_cred and change the pointer in the task_struct structure.