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

 

posted @ 2019-05-16 15:41  带狗狗带  Views(7921)  Comments(0Edit  收藏  举报