背景
在学习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_pos
与maps_line
则这是上面两个字符串的地址,那么这两个地址相减,就是5da215f000
字符串的大小,正好是10
个字节。
所以就认为计算出来的地址长度为10。而对于字符char
而言,一个字符占一个字节,所以也就是10个字节。
privbits
相应的,在获取到addr_size
的大小之后,通过first_bar_pos+addr_size+1+1
,获取到的字符数组首地址指向的就是r-xp
这一段文本了。所以,根据该权限标志位来判断该内存页是否可读,可执行
网友评论