Frida Android hook native层__system_property_get的最终方案

摘要:
此问题的原因是在挂钩期间修改了内容长度。当它超过原始长度时,会出现显示不完整的问题。例如,如果将nexus5更改为nexus100,则只显示nexus1。因此,请阅读源代码int__system_property_read{unsignedserial,len;for(;;){serial=pi-˃serial;而{__futex_wait;serial=pi-˃seral;}len=序列_值_长度;memcpy;如果{If(name!=0){return__system_property_read;}否则{value[0]=0;返回0。长度限制来自读取的内部len实现,不能通过更改参数来修改。因此,使用了一种尴尬的方法来修改read的返回值的长度,然后修改get的值。脚本如下:拦截器。贴上varstr=“”varargs2=“”;拦截器附加(模块.findExportByName(“libc.so”,“__system_property_get”),{onEnter:函数(args){str=getStr(args[0]);args2=ptr(args[1]);},onLeave:函数(retval){if(str){if(tr.indexOf(“ro.serialno”)!

记录这个问题的起因是,在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);
            }
            returnlen;
        }
    }
}
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

免责声明:文章转载自《Frida Android hook native层__system_property_get的最终方案》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Mac下也能用抓包工具Fiddlerjavascript加密PHP解密---jsencrypt下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

字节流和字符流的read方法

字节流和字符流的read方法 public class Test { public void fileOutput() throws Exception { File file = new File("D:/2.txt"); FileOutputStream fileOutputStream = new FileOu...

bwa比对软件的使用以及其结果文件(sam)格式说明

一、bwa比对软件的使用 1、对参考基因组构建索引 bwa index -a bwtsw hg19.fa   #  -a 参数:is[默认] or bwtsw,即bwa构建索引的两种算法,两种算法都是基于BWT的(BWT search while the CIGAR string by Smith-Waterman alignment.)。-a bwtsw...

mysql的默认隔离级别:可重复读(Repeatable Read)

原文:https://www.cnblogs.com/rjzheng/p/10510174.html 知识点总结 ----------------------------------------------------------------------------------------------------------------------- 1....

Lua读写文件

文件读写 文件读写对制作游戏很有帮助。可以调用别的文件中的代码,保存最高分、游戏存档、玩家状态等信写到文件中。 首先,让我们看一个简单的命令:dofile。这个命令会读入另一个文件的代码并立即执行。 代码: dofile("./test.lua") 很简单的命令。注意 ./ 是指根目录,不是子目录。如果是子目录,应该这样用: 代码: dofi...

使用http协议下载网络图片

     出于公司的一个需求,我要写一个下载网易微博的一个头像,但是网易微博的的图片是不允许外链的,所以我们只下载它,好了动手了,呵呵     一开始我用这样来读流   using (var stream = response.GetResponseStream())            {                //byte[] bytes...

SQL Server 锁

from:http://www.cnblogs.com/kissdodog/p/3170036.html  锁是一种防止在某对象执行动作的一个进程与已在该对象上执行的其他进行相冲突的机制。也就是说,如果有其他人在操作某个对象,那么你旧不能在该对象上进行操作。你能否执行操作取决于其他用户正在进行的操作。 通过锁可以防止的问题   锁可以解决以下4种主要问题:...