zoukankan      html  css  js  c++  java
  • Frida Android hook native层__system_property_get的最终方案

    记录这个问题的起因是,在hook时遇到了修改内容长度,超过原长度时,会出现显示不全的问题。

    比如把nexus 5改成nexus 100,只会显示nexus 1。

    所以去读了下源码

    int __system_property_read(const prop_info *pi, char *name, char *value)
    {
        unsigned serial, len;
        for(;;) {
            serial = pi->serial;
            while(SERIAL_DIRTY(serial)) {
                __futex_wait((volatile void *)&pi->serial, serial, 0);
                serial = pi->serial;
            }
            len = SERIAL_VALUE_LEN(serial);
            memcpy(value, pi->value, len + 1);
            if(serial == pi->serial) {
                if(name != 0) {
                    strcpy(name, pi->name);
                }
                return len;
            }
        }
    }
    int __system_property_get(const char *name, char *value)
    {
        const prop_info *pi = __system_property_find(name);
        if(pi != 0) {
            return __system_property_read(pi, 0, value);
        } else {
            value[0] = 0;
            return 0;
        }
    }

    可以看到源码中get调用了read来读value,传进去了find返回的指针,但是name给的是0,所以在read中没法直接判断读的是哪个key,还是要hook get。

    而长度的限制来自read内部的len实现,不能通过改参数的办法修改,所以用了个别扭的方法先修改了read返回值的长度,再修改get的value,脚本如下:

    Interceptor.attach(Module.findExportByName("libc.so", "__system_property_read"), {
            onEnter: function (args) {
                //sLog("__system_property_read onEnter " + Memory.readCString(args[0]));
            },
    
            onLeave: function (retval) {
                //sLog(retval)
                retval.replace(0x5b);//修改read的返回值
            }
        });
    
        var str = ""
        var args2 = "";
        Interceptor.attach(Module.findExportByName("libc.so", "__system_property_get"), {
            onEnter: function (args) {
                str = getStr(args[0]);
                args2 = ptr(args[1]);
            },
    
            onLeave: function (retval) {
                if (str) {
                    if (str.indexOf("ro.serialno") != -1) {
                        var before = getStr(args2)
                        putStr(args2, "05b3c6d30a280000")
                        sLog(str + " " + before + " 改成 " + getStr(args2));
                    }
                }
            }
        });

    其中hook read的返回值长度不是乱写的,因为system_properties.h源码中有限制最大长度

    #define PROP_NAME_MAX   32
    #define PROP_VALUE_MAX  92

    hex(92) = '0x5c'

    所以我把read的返回值改成了0x5b,减了1,肯定也够用了。

    源码全文参考

    https://android.googlesource.com/platform/bionic/+/0d787c1fa18c6a1f29ef9840e28a68cf077be1de/libc/bionic/system_properties.c

    https://android.googlesource.com/platform/bionic/+/49f0a8f23bba188466c6ee3652858ef4da228c6f/libc/include/sys/system_properties.h

  • 相关阅读:
    C++头文件,预处理详解
    在VS2013中查看C/C++预处理后的文件
    使用apache.lang包安全简洁地操作Java时间
    FileInputStream 和 FileOutputStream
    【转】彻底搞清计算结构体大小和数据对齐原则
    NDK学习笔记-gdb调试
    NDK学习笔记-gdb调试
    NDK学习笔记-多线程与生产消费模式
    NDK学习笔记-多线程与生产消费模式
    Android-Makefile
  • 原文地址:https://www.cnblogs.com/xirtam/p/10875993.html
Copyright © 2011-2022 走看看