专栏首页Android相关Linux编程--地址计算

Linux编程--地址计算

背景

在学习Matrix的ELF Hook的过程中,发现在查找Library基址指针的时候,对于指针的运算有一些疑惑,特此记录。

问题描述

在获取Library的基址时,有如下代码:

    // 添加b模式因为它是Binary文件,如果不添加则无法打开
    FILE *maps_file = fopen(maps_path, "rbe");
    char maps_line[512];
    // fgets函数可以读取maps_line的大小或者是遇到\n停止,即读一行数据
    while (fgets(maps_line, sizeof(maps_line) - 1, maps_file) != nullptr) {
        // 获取第一个出现`-`位置的字符串
        char *first_bar_pos = strchr(maps_line, '-');
        // 计算maps中的地址大小
        auto addr_size = (unsigned int) (first_bar_pos - (char *) maps_line);
        // 计算该Page的权限位
        char * privbits = first_bar_pos + addr_size 
                +1/* barchar itself*/
                +1/* space before privbit*/;
        // 如果当前内存页不可读,也不可执行的话,也就意味着不是我们要找的ELF文件的内存地址
        if (privbits[0] != 'r' || privbits[2] != 'x') {
            continue;
        }
    }

在计算addr_size的时候,使用的两个(char *)的减进行运算,为何能得到地址的大小?而且获取到privbits有什么用?

日志与截图

首先看一下maps里面的内容:

$cat /proc/self/maps
5da215f000-5da21a3000 r-xp 00000000 fd:01 128                            /vendor/bin/sh
5da21a3000-5da21a5000 r--p 00043000 fd:01 128                            /vendor/bin/sh
5da21a5000-5da21a6000 rw-p 00045000 fd:01 128                            /vendor/bin/sh
5da21a6000-5da21a7000 rw-p 00000000 00:00 0 
7ac0a00000-7ac0e00000 rw-p 00000000 00:00 0                              [anon:libc_malloc]
7ac0f06000-7ac0f26000 r--s 00000000 00:10 3324                           /dev/__properties__/u:object_r:default_prop:s0
7ac0f26000-7ac0f27000 rw-p 00000000 00:00 0                              [anon:linker_alloc_vector]
7ac0f28000-7ac1000000 r-xp 00000000 fd:01 4761                           /vendor/lib64/libc++.so
7ac1000000-7ac1008000 r--p 000d7000 fd:01 4761                           /vendor/lib64/libc++.so
7ac1008000-7ac1009000 rw-p 000df000 fd:01 4761                           /vendor/lib64/libc++.so
7ac1009000-7ac100c000 rw-p 00000000 00:00 0                              [anon:.bss]
7ac100c000-7ac10c8000 r-xp 00000000 fd:00 3463                           /system/lib64/libc.so
7ac10c8000-7ac10c9000 ---p 00000000 00:00 0 
7ac10c9000-7ac10cf000 r--p 000bc000 fd:00 3463                           /system/lib64/libc.so
7ac10cf000-7ac10d1000 rw-p 000c2000 fd:00 3463                           /system/lib64/libc.so

在本地运行后,打印的日志如下,:

first_bar_pos:549218901232
maps_line:549218901222
maps_line:5da215f000-5da21a3000 r-xp 00000000 fd:01 128                            /vendor/bin/sh
first_bar_pos:      -5da21a3000 r-xp 00000000 fd:01 128                            /vendor/bin/sh
addr_size = 10

正好addr_size = maps_line - first_bar_pos

first_bar_posmaps_line则这是上面两个字符串的地址,那么这两个地址相减,就是5da215f000字符串的大小,正好是10个字节。

所以就认为计算出来的地址长度为10。而对于字符char而言,一个字符占一个字节,所以也就是10个字节。

privbits

相应的,在获取到addr_size的大小之后,通过first_bar_pos+addr_size+1+1,获取到的字符数组首地址指向的就是r-xp这一段文本了。所以,根据该权限标志位来判断该内存页是否可读,可执行

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Http1.x与Http2.0的区别

    随着Http协议发展的20年间,从物理带宽、CPU、内存,到软件都有了很大的提升,而原来的协议也具有了很大的局限性:

    None_Ling
  • 跨进程文件锁 - FileChannel

    当有多个进程或者多个应用同时操作文件时 , 会并行往文件中写入字节 , 如何保证多个进程中文件写入或者操作当原子性就很重要.

    None_Ling
  • ViewPager2与Fragment

    在AndroidX之前的Fragment , 由于配合ViewPager使用 , 在Fragment添加到ViewPager上后 , 生命周期会跟Activi...

    None_Ling
  • springboot配置之Profile多环境支持

    Profile是spring对不同环境提供不同配置功能的支持,可以通过激活、指定参数等方式快速切换环境。

    绝命生
  • Altium Dsigner18——PCB与原理图交互式布局设计

    Altium 提供了一个交互式布局的功能,我们在利用这个命令的时候我们在原理图中选中器件的时候,在 PCB 中同样的会被选中,这样可以大大节省我们分模块设计时,...

    Winter_world
  • 迷宫游戏-解谜 攻略

    林万程
  • 你不知道的美团点评技术团队

    高广超
  • 聊聊设计模式之工厂方法模式

    定义:定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法使一个类的实例化延迟到其子类。

    黄泽杰
  • The Clean Architecture in PHP 读书笔记(五)The Clean Architecture in PHP 读书笔记(五)

    上篇最重要的是介绍了去耦的工具之一依赖注入,本篇将继续介绍去耦工具:接口和适配器,本文是The Clean Architecture in PHP的第5篇。

    zhuanxu
  • 为什么 spring 中,不支持 autowired 静态变量?

    因为静态变量是属于本身类的信息,当类加载器加载静态变量时,Spring 的上下文环境还没有被加载,所以不可能为静态变量绑定值。

    水货程序员

扫码关注云+社区

领取腾讯云代金券