1

I'm using the official Android Emulator. When I run this I get:

adb shell getprop | grep hardware

I get

[ro.boot.hardware]: [goldfish]
[ro.hardware]: [goldfish]
[ro.kernel.androidboot.hardware]: [goldfish]

I want to rename goldfish to any other word.

I can run the emulator in debug mode emulator -avd test -show-kernel -verbose to see kernel parameters:

  kernel.path = /home/artyom/android-sdk-linux/system-images/android-19/default/armeabi-v7a//kernel-qemu
  kernel.parameters =  androidboot.hardware=goldfish android.checkjni=1
  kernel.newDeviceNaming = no
  kernel.supportsYaffs2 = yes

So, Android Emulator passes androidboot.hardware=goldfish to the QEMU.

Let's dive into Android source.

In /system/core/init/util.c we can see that passing hardware via kernel command line makes it unchangeable.

void get_hardware_name(char *hardware, unsigned int *revision)
{
    const char *cpuinfo = "/proc/cpuinfo";
    char *data = NULL;
    size_t len = 0, limit = 1024;
    int fd, n;
    char *x, *hw, *rev;

    /* Hardware string was provided on kernel command line */
    if (hardware[0])
        return;

According to the eLinux wiki, hardware name used to init file init.machine_name.rc, so renaming goldfish to any other name must be combined with renaming init.goldfish.rc to init.anyname.rc.

So my question is, how can I force a different hardware name? How I can different androidboot.hardware value to the qemu? What files, other than init.goldfish.rc should I change? Different hardware name must be forced while compiling?

I've tried adding this to the .config file:

CONFIG_CMDLINE="androidboot.hardware=randomname android.checkjni=1"
CONFIG_CMDLINE_EXTRA=y
CONFIG_CMDLINE_FORCE=y

It didn't help.

Related question: android boot - where is the init.%hardware%.rc read in init.c ? where are services started?

Additional info: Initialize Goldfish hardware

0

1 Answer 1

1

Here we can see, that passing hardware via kernel command line makes it unchangable.

The hardware name is indeed changeable. get_hardware_name is only used to set the ro.hardware property in property_service, hosted by init. Everything else, like dalvik vm for android.os.Build.HARDWARE is requesting ro.hardware from property_service.

Ways of changing the hardware name:
  • Recompile the android emulator based on qemu, which sets androidboot.hardware right here: userspace-boot-properties.cpp#265
  • For physical phones, change the kernel cmdline in the boot partition header or for Android 12+ modify bootconfig in the vendor_boot partition
  • Use magisk to patch ro.hardware in the property_service by executing resetprop ro.hardware <hardware_name>. This can be done early in the boot process even before Zygote is started by writing a post-fs-data script

However changing the hardware name before boot is finished will result in a boot loop.

I tried renaming init.<ro.hardware>.rc and fstab.<ro.hardware> but there were still problems like Could not find 'android.hardware.*' that were causing the bootloop.
Even setting ro.hardware right after booting by waiting for resetprop -w sys.boot_completed 0 caused problems in network services that prevented the interface from loading.

The problem is that the dalvik vm is initializing android.os.Build.HARDWARE statically when it's loaded and caches the class. So subsequent changes in the ro.hardware property are ignored.

The trick here is to wait until everything is booted up, then execute resetprop ro.hardware <hardware_name> and then restart Zygote (dalvik/java vm) with setprop ctl.restart zygote.
This will reload the android.os.Build class with the updated ro.hardware property.
Now all requests from getprop, the java/dalvik vm or even native modules will see the updated hardware name.

Here's a startup service script to do this with magisk:

/data/adb/service.d/change_hardware.sh

#!/bin/sh
until pids=$(pidof com.android.systemui)
do
    sleep 1
done
resetprop ro.hardware ranchu
setprop ctl.restart zygote

chmod +x /data/adb/service.d/change_hardware.sh

If you know the process where you have to emulate a different hardware, it's easier to overwrite android.os.Build.HARDWARE in the target process with frida:

Java.perform(() => {
    Java.use("android.os.Build").HARDWARE.value = 'ranchu';
});

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .