问题慢慢解决-通过android emulator调试android kernel-内核条件断点遇到的问题和临时解决方案

起因

在摸索到这个方案之后,mac m1调试aarch64 android kernel最终方案,就准备调试内核了,预备下断点的地方是

c 复制代码
b binder_poll
b ep_ptable_queue_proc
b remove_wait_queue

但是由于是android系统,上面三个函数会被频繁的触发,不知道哪次断下的是自己提供的进程触发的,所以准备使用条件断点,只在自己的进程触发下断下。这个条件断点的首要目标是获取aarch kernel的current

观察高版本内核gdb相关代码,目标是获取SP_EL0的值

python 复制代码
def get_current_task(cpu):
    task_ptr_type = task_type.get_type().pointer()

    if utils.is_target_arch("x86"):
         var_ptr = gdb.parse_and_eval("&current_task")
         return per_cpu(var_ptr, cpu).dereference()
    elif utils.is_target_arch("aarch64"):
         current_task_addr = gdb.parse_and_eval("$SP_EL0")
         if((current_task_addr >> 63) != 0):
             current_task = current_task_addr.cast(task_ptr_type)
             return current_task.dereference()

困难

狗币google,最新的android emulator使用的qemu版本还是qemu-2.10.0,无法通过gdb获取系统寄存器的值,也就是没办法获取SP_EL0

解决-重编android emulator

重编android kernel

添加CONFIG_GDB_SCRIPTS=y配置,使gdb附加上时,lx-系列命令自动可用

编译android emulator

bash 复制代码
https://android.googlesource.com/platform/external/qemu/+/emu-master-dev/android/docs/LINUX-DEV.md
https://android.googlesource.com/platform/external/qemu/+/emu-master-dev

下载android emulator并编译

bash 复制代码
# 1、环境,以及下载源码
sudo apt-get install -y git build-essential python qemu-kvm ninja-build python-pip ccache

mkdir $HOME/bin
curl http://commondatastorage.googleapis.com/git-repo-downloads/repo > $HOME/bin/repo
chmod 700 $HOME/bin/repo
export PATH=$PATH:$HOME/bin

mkdir -p emu-master-dev && cd emu-master-dev
repo init -u https://android.googlesource.com/platform/manifest -b emu-master-dev
repo sync -j 8
cd external/qemu

# 2、配置ccache

# 3、编译
python3 android/build/python/cmake.py --noqtwebengine --noshowprefixforinfo --target linux_aarch64 --ccache auto

这个时候就知道android emulator使用的版本到底有多老了qemu-img -V

修改qemu - gdbstub64

bash 复制代码
https://stackoverflow.com/questions/46415059/how-to-observe-aarch64-system-registers-in-qemu
https://lists.gnu.org/archive/html/qemu-arm/2020-05/msg00703.html
https://github.com/qemu/qemu/commit/200bf5b7ffe

这里只是做测试,把x1,x2等寄存器替换为了SP_EL0,时间够,以后再改
target/arm/gdbstub64.c

c 复制代码
int aarch64_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
{
    ARMCPU *cpu = ARM_CPU(cs);
    CPUARMState *env = &cpu->env;
	// 这里进行测试 begin
    if (n == 1 || n == 2 || n ==3) {
        return gdb_get_reg64(mem_buf, env->sp_el[0]);
    }
    // 这里进行测试 end

    if (n < 31) {
        /* Core integer register.  */
        return gdb_get_reg64(mem_buf, env->xregs[n]);
    }
    switch (n) {
    case 31:
        return gdb_get_reg64(mem_buf, env->xregs[31]);
    case 32:
        return gdb_get_reg64(mem_buf, env->pc);
    case 33:
        return gdb_get_reg32(mem_buf, pstate_read(env));
    }
    /* Unknown register.  */
    return 0;
}

修改完毕后,继续重编android emulator

修改android-goldfish-4.4-dev gdb相关脚本

goldfish/scripts/gdb/linux/cpus.py

python 复制代码
task_type = utils.CachedType("struct task_struct")

class LxCurrentFunc(gdb.Function):
    """Return current task.

$lx_current([CPU]): Return the per-cpu task variable for the given CPU
number. If CPU is omitted, the CPU of the current context is used."""

    def __init__(self):
        super(LxCurrentFunc, self).__init__("lx_current")

    def invoke(self, cpu=-1):
        task_ptr_type = task_type.get_type().pointer()
        # 我在gdbstub64.c中将x1替换为了SP_EL0
        # 后期再改,这里只实验是能获取current
        current_task_addr = gdb.parse_and_eval("$x1")
        gdb.write(str(hex(current_task_addr)))
        if((current_task_addr >> 63) != 0):
            current_task = current_task_addr.cast(task_ptr_type)
            return current_task.dereference()

使用

下一个断点,在自己的进程运行起来之后断下,目的:通过lx-ps查看该进程的pid

bash 复制代码
pwndbg> lx-ps
0xffffffc02a8f7000 2343 AsyncTask #1
0xffffffc02a8f3800 2345 ExecutorUtils
0xffffffc02d4dd400 2367 android_tese  <<<<<<<<<<< 

下断点,测试
我在gdbstub64.c中将x1替换为了SP_EL0,后期再改,这里只实验是能获取current

bash 复制代码
b binder_poll if ((struct task_struct)(*$x1)).pid == 2367
b ep_ptable_queue_proc if ((struct task_struct)(*$x1)).pid == 2367
b remove_wait_queue if ((struct task_struct)(*$x1)).pid == 2367
相关推荐
无极程序员33 分钟前
PHP常量
android·ide·android studio
萌面小侠Plus2 小时前
Android笔记(三十三):封装设备性能级别判断工具——低端机还是高端机
android·性能优化·kotlin·工具类·低端机
慢慢成长的码农2 小时前
Android Profiler 内存分析
android
大风起兮云飞扬丶2 小时前
Android——多线程、线程通信、handler机制
android
L72562 小时前
Android的Handler
android
清风徐来辽2 小时前
Android HandlerThread 基础
android
HerayChen3 小时前
HbuildderX运行到手机或模拟器的Android App基座识别不到设备 mac
android·macos·智能手机
顾北川_野3 小时前
Android 手机设备的OEM-unlock解锁 和 adb push文件
android·java
hairenjing11233 小时前
在 Android 手机上从SD 卡恢复数据的 6 个有效应用程序
android·人工智能·windows·macos·智能手机
小黄人软件3 小时前
android浏览器源码 可输入地址或关键词搜索 android studio 2024 可开发可改地址
android·ide·android studio