System V AMD64 ABI

Windows 逆向、Windows 内核逆向及漏洞研究 + Intel CPU 研究差不多 5 年。计划开始研究 Linux 逆向、内核(一年半),最后研究国产 CPU 和操作系统相关漏洞。

0 基本概念

0.1 名词解释

  • System V:System V,曾经也被称为 AT&T System V,是 Unix 操作系统众多版本中的一支。它最初由 AT&T 开发,在 1983 年第一次发布。一共发行了 4 个 System V 的主要版本:版本1、2、3 和 4。System V Release 4,或者称为 SVR4,是最成功的版本,成为一些 UNIX 共同特性的源头。

  • BSD(Berkeley Software Distribution,伯克利软件套件)是Unix的衍生系统,也是 Unix 操作系统众多版本中的一支,1970年代由伯克利加州大学(Uni Versity of California, Berkeley)开创。BSD用来代表由此派生出的各种套件集合。

  • POSIX(Portable Operating System Interface for Computing Systems)是由IEEE 和ISO/IEC 开发的一簇标准。该标准是基于现有的UNIX 实践和经验,描述了操作系统的调用服务接口,用于保证编制的应用程序可以在源代码一级上在多种操作系统上移植运行。

  • AMD64:首先由 AMD 推出,64 位的 CPU,能够兼容 x86 指令集,将其称之为 x86-64。之后 Intel 也推出可兼容 x86 指令集的 CPU,叫做 Intel 64(非IA-64)。由于历史原因,不同系统软件厂商的称呼不同。Apple、Linux 家族喜欢叫做 x86-64,BSD 家族称为 AMD64。Microsoft 称之为 x64。所以,后面统一将 AMD64 用来表示兼容 x86 指令的 64 位 CPU,它包括 x86-64 和 Intel 64。

  • ABI:Application Binary Interface,是 System V Application Binary Interface 的等众多规范的简称。本文的应用程序二进制接口是一套规范,为符合 X/Open 通用应用程序环境规范和 System V 接口定义的系统详细介绍了调用约定、对象文件格式、可执行文件格式、动态链接语义等。ABI 规范了数据格式和调用约定。今天,它是 Linux、BSD 系统等主要 Unix 操作系统使用的标准 ABI

  • System V AMD64 ABI:就是 x86-64 64 位处理器下 Linux、BSD 等主要 Unix 操作系统使用的标准规范。规范文档在 x86-64 psABI 下载(这里的 ps 指的是 Processor Supplement)。它规范了以下主要内容:

    • Low Level System Information(数据类型、函数调用约定、堆栈对齐与平衡)
    • Object Files(ELF 文件格式)
    • Program Loading and Dynamic Linking
    • Libraries
    • Development Environment
    • Conventions
    • Linux Conventions
  • LP64:long type and all pointer types are 64-bit objects (LP64) at 64-bit model.

  • ILP32:long and all pointer types are 32-bit objects (ILP32) at 32-bit model.

0.2 Unix、Linux 的发展

Unix、Linux、GNU

Linux 是一个可以自由发布的类 UINIX 内核实现,它是一个操作系统的底层核心。几乎所有为 UNIX 编写的程序都可以在Linux上编译运行。

操作系统内核本身仅仅是可用开发系统的一小部分。GNU 项目的宗旨是:试图创建一个与 UNIX 系统兼容,但并不受 UNIX 名字和源代码私有权限制的操作系统和开发环境(即开源的)。GNU 项目己为软件社区提供了许多 UNIX 系统上应用程序的仿制品。所有这些程序,即 GNU 软件,都是在 GNU 通用公共许可证(GPL)的条款下发布的(如 gcc/g++/gdb/bash 等)。现在有这么多自由软件,再加上Linux内核,由于认识到 GNU 软件所做出的贡献,现在许多人通常都把 Linux 系统称为 GNU/Linux

Linux 发行版

正如我们前面提到的,Linux实际上只是一个内核。可以通过编译并安装它,然后获得并安装许多其他自由发布的软件,从而完成一个完整 Linux 系统的安装。系统中大多数的工具都来自于自由软件基金会的 GNU 项目。但是这样通过源码编译之后再安装软件来最终安装的操作系统太过麻烦和复杂,所以就有了 Linux 的许多发行版,如 Red Hat Enterprise Linux(centOS) 及其社区开发版的 Fedora、 Novell SuSE Linux 及其免费的 openSUSE 变体、Ubuntu Linux、 Slackware、 Gentoo 和 Debian GNU/Linux 等。

一、Unix 的发展

1.gif

二、Linux 的发展

2.png

参考:Linux系统发行版大全(历史大全含发展图)

1 标准定义

本文主要参考:

注意:AMD64 ABI 仅适用于 Long 模式的 AMD 处理器、IA-32e 模式的 Intel 处理器。32 位处理器的 ABI 规范,见《System V Application Binary Interface Intel386 Architecture Processor Supplement Version 1.0》

本章节根据不同的编译器规范,指出不同操作系统平台下的数据格式和函数调用约定。目前官方标准中,使用 Microsoft 编译器作为 Windows 系统的参考,使用 Gnu 编译器作为类 UNIX 系统的参考

1.1 数据类型

说明Segment word size 表示硬件平台(Hardware platform)。

3.png

1.2 数据对齐

表 2 显示了静态数据的默认对齐方式(以字节为单位)。 对齐会影响性能,但不会影响兼容性。

4.png

表 3 显示了结构和类的数据成员的字节对齐方式。 编译器将根据需要在成员之间插入未使用的字节以获得这种对齐方式。 编译器还会在结构体末尾插入未使用的字节,以便结构体的总大小是需要最高对齐的元素的对齐方式的倍数。 许多编译器都有更改默认对齐方式的选项。

5.png

为了节约空间,《CSAPP》这本书中通过实验指出,在一个结构提供定义成员时,按照数据成员所占空间从小到大的顺序定义较好。

1.3 堆栈对齐

  • 32 位 Mac OS X、Linux、Windows 系统下的编译器都使进程堆栈以 16 bytes 对齐。
  • 64 位 Windows、Linux、BSD 系统下的编译器都使进程堆栈以 16 bytes 对齐。

如果至少有一个 __m256 类型的函数参数在堆栈上传输,Unix 系统(32 和 64 位)会将参数按 32 对齐,并且被调用的函数可以依赖于在调用之前按 32 对齐的堆栈(即堆栈指针是 32 减去函数入口处的字长模 32)。 如果参数在寄存器中传输,则这不适用。

Intel 详细的对齐方式参见 Intel SDM。

1.4 寄存器的用途

6.png

7.png

1.5 函数调用约定

说明Segment word size 表示硬件平台(Hardware platform)。

8.png

  • 32-bit 平台:
    • Windows:__cdecl 为应用层函数默认调用约定,__stdcall 为系统 API、内核函数调用约定。__thiscall 为类成员函数调用约定。__cdecl__stdcall 都是使用堆栈传参,没有使用寄存器。
    • Linux:使用 Gnu 调用约定,类似于 __stdcall,使用堆栈传参,由被调用函数平衡堆栈。
  • 64-bit 平台
    • Windows:只能使用 4 个寄存器传参,其余参数从右至左压入堆栈。整数按顺序用 rcxrdxr8r9 寄存器传递,浮点参数由 xmm0-xmm3 来传递。只能使用这 8 个寄存器中的 4 个,具体看参数类型使用哪 4 个。
    • Linux:整数参数按顺序由 rdirsirsxrcxr8r9 来传递,浮点参数按顺序由 xmm0-xmm7 来传递,其余参数从右至左压入堆栈。

64-bit 平台 Windows 和 Linux 程序的区别:

平台 Windows Linux/BSD/Mac
传参寄存器个数 4 个。只能使用 rcxrdxr8r9xmm0-xmm3 中 4 个寄存器传参。 14 个。可使用 rdirsirsxrcxr8r9xmm0-xmm7 共 14 个寄存器传参。使用对应的哪一类看参数类型。
shadow space 。调用子函数时,返回地址之前(高地址)会给 4 个传参寄存器预留 32 bytes 大小空间给子函数使用。 没有。但是有 red zone 区域用作临时存储数据,该区域在每个函数的堆栈中,该区域在 [rsp-128][rsp-8] 之间,大小为 120 bytes。如调用函数使用 sub $0x10, %rsp 开辟 red zone 区域。
Hot patching support 支持。热补丁是Windows中的一种机制,允许用安全补丁替换任何功能,而无需重新启动使用该功能的进程。
如果需要支持热补丁,则函数入口之前必须至少有 6 个未使用的字节,并且函数中的第一条指令必须至少有 2 个字节长。
在 32 位Windows中,编译器可能会在函数的开头插入2个字节的 NOP(MOV EDI,EDI)。
在 64 位 Windows 中,如果第一条指令是推送指令,则编译器会在第一条指令之前插入 REX.W 前缀,以使其长度为两个字节。
不支持

32-bit 平台下 __cdecl__stdcall:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// __cdecl,由调用者函数来平衡堆栈
.text:0040122D push ebx
.text:0040122E call __global_unwind2
.text:00401233 add esp, 4 // 调用者平衡堆栈
.text:00401236 lea ebp, [ebx+10h]
.text:00401239 push esi
.text:0040123A push ebx
.text:0040123B call __local_unwind2
.text:00401240 add esp, 8 // 调用者平衡堆栈

// __stdcall,由被调用函数来平衡堆栈
.text:7C8021D0 mov edi, edi
.text:7C8021D2 push ebp
.text:7C8021D3 mov ebp, esp
.text:7C8021D5 lea eax, [ebp+nSize] // 下面压入 5 个参数
.text:7C8021D8 push eax ; NumberOfBytesRead
.text:7C8021D9 push [ebp+nSize] ; NumberOfBytesToRead
.text:7C8021DC push [ebp+lpBuffer] ; Buffer
.text:7C8021DF push [ebp+lpBaseAddress] ; BaseAddress
.text:7C8021E2 push [ebp+hProcess] ; ProcessHandle
.text:7C8021E5 call ds:__imp__NtReadVirtualMemory@20
//------------------------------------------------------------------------------
.text:7C92D9E0 ; __stdcall NtReadVirtualMemory(x, x, x, x, x)
.text:7C92D9E0 public _NtReadVirtualMemory@20
.text:7C92D9E0 _NtReadVirtualMemory@20 proc near ; CODE XREF: LdrFindCreateProcessManifest(x,x,x,x,x)+1CC↓p
.text:7C92D9E0 ; LdrCreateOutOfProcessImage(x,x,x,x)+7C↓p ...
.text:7C92D9E0 mov eax, 0BAh ; NtReadVirtualMemory
.text:7C92D9E5 mov edx, 7FFE0300h
.text:7C92D9EA call dword ptr [edx]
.text:7C92D9EC retn 14h // 被调用者平衡堆栈,共 20 字节参数空间
.text:7C92D9EC _NtReadVirtualMemory@20 endp

1.6 数据类型和作用域

变量、函数定义:

1
2
变量定义:存储类型,类型修饰符 数据类型 变量名
函数定义:存储类型 返回数据类型 函数名(参数列表)
  • 存储类型:autoexternregisterstatic
  • 类型修饰符:longshortsignedunsignedvoidconstvolatile 等。
  • 数据类型:char doubleintfloatstructenumtypedefunion 等。

作用域(参考《Linux 高级程序设计第三版 3.1.3》):

28.png

2 地址空间布局

2.1 系统地址空间

系统地址空间布局整体上和 Windows x64 差不多,中间大区域是非规范地址空间,不可用。

address_spacce

方法一,通过查看内核使用的符号表在地址空间的映射,即查看 System.map 文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
[root@centos-7 ~]# uname -r
3.10.0-1160.71.1.el7.x86_64
[root@centos-7 /]# hostnamectl
Static hostname: localhost.localdomain
Transient hostname: centos-7.9.shared
Icon name: computer-vm
Chassis: vm
Machine ID: 32ced81c668fc14fba8ae988c2f1b506
Boot ID: a37fab19ea7e4cce876f0110861e3d9b
Virtualization: kvm
Operating System: CentOS Linux 7 (Core)
CPE OS Name: cpe:/o:centos:centos:7
Kernel: Linux 3.10.0-1160.71.1.el7.x86_64
Architecture: x86-64
...
// 以下几个文件内容是一样的
[root@centos-7 /]# locate System.map
/boot/System.map-3.10.0-1160.71.1.el7.x86_64
/usr/src/kernels/3.10.0-1160.71.1.el7.x86_64/System.map
/usr/src/kernels/3.10.0-1160.90.1.el7.x86_64/System.map
...
[root@centos-7 ~]# less /usr/src/kernels/3.10.0-1160.71.1.el7.x86_64/System.map | grep -i syscall
0000000000000040 A VDSO32_vsyscall_eh_frame_size
0000000000000420 A VDSO32_vsyscall
ffffffff8101c100 T xen_enable_syscall
ffffffff810222d0 T xen_syscall_target
ffffffff810222f0 T xen_syscall32_target
ffffffff81032410 t cpu_vsyscall_init
...

方法二,通过查看 Linux 源码 /Documentation/arch/x86/x86_64/mm.rst

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
.. SPDX-License-Identifier: GPL-2.0

=================
Memory Management
=================

Complete virtual memory map with 4-level page tables
====================================================

.. note::

- Negative addresses such as "-23 TB" are absolute addresses in bytes, counted down
from the top of the 64-bit address space. It's easier to understand the layout
when seen both in absolute addresses and in distance-from-top notation.

For example 0xffffe90000000000 == -23 TB, it's 23 TB lower than the top of the
64-bit address space (ffffffffffffffff).

Note that as we get closer to the top of the address space, the notation changes
from TB to GB and then MB/KB.

- "16M TB" might look weird at first sight, but it's an easier way to visualize size
notation than "16 EB", which few will recognize at first sight as 16 exabytes.
It also shows it nicely how incredibly large 64-bit address space is.

::

========================================================================================================================
Start addr | Offset | End addr | Size | VM area description
========================================================================================================================
| | | |
0000000000000000 | 0 | 00007fffffffffff | 128 TB | user-space virtual memory, different per mm
__________________|____________|__________________|_________|___________________________________________________________
| | | |
0000800000000000 | +128 TB | ffff7fffffffffff | ~16M TB | ... huge, almost 64 bits wide hole of non-canonical
| | | | virtual memory addresses up to the -128 TB
| | | | starting offset of kernel mappings.
__________________|____________|__________________|_________|___________________________________________________________
|
| Kernel-space virtual memory, shared between all processes:
____________________________________________________________|___________________________________________________________
| | | |
ffff800000000000 | -128 TB | ffff87ffffffffff | 8 TB | ... guard hole, also reserved for hypervisor
ffff880000000000 | -120 TB | ffff887fffffffff | 0.5 TB | LDT remap for PTI
ffff888000000000 | -119.5 TB | ffffc87fffffffff | 64 TB | direct mapping of all physical memory (page_offset_base)
ffffc88000000000 | -55.5 TB | ffffc8ffffffffff | 0.5 TB | ... unused hole
ffffc90000000000 | -55 TB | ffffe8ffffffffff | 32 TB | vmalloc/ioremap space (vmalloc_base)
ffffe90000000000 | -23 TB | ffffe9ffffffffff | 1 TB | ... unused hole
ffffea0000000000 | -22 TB | ffffeaffffffffff | 1 TB | virtual memory map (vmemmap_base)
ffffeb0000000000 | -21 TB | ffffebffffffffff | 1 TB | ... unused hole
ffffec0000000000 | -20 TB | fffffbffffffffff | 16 TB | KASAN shadow memory
__________________|____________|__________________|_________|____________________________________________________________
|
| Identical layout to the 56-bit one from here on:
____________________________________________________________|____________________________________________________________
| | | |
fffffc0000000000 | -4 TB | fffffdffffffffff | 2 TB | ... unused hole
| | | | vaddr_end for KASLR
fffffe0000000000 | -2 TB | fffffe7fffffffff | 0.5 TB | cpu_entry_area mapping
fffffe8000000000 | -1.5 TB | fffffeffffffffff | 0.5 TB | ... unused hole
ffffff0000000000 | -1 TB | ffffff7fffffffff | 0.5 TB | %esp fixup stacks
ffffff8000000000 | -512 GB | ffffffeeffffffff | 444 GB | ... unused hole
ffffffef00000000 | -68 GB | fffffffeffffffff | 64 GB | EFI region mapping space
ffffffff00000000 | -4 GB | ffffffff7fffffff | 2 GB | ... unused hole
ffffffff80000000 | -2 GB | ffffffff9fffffff | 512 MB | kernel text mapping, mapped to physical address 0
ffffffff80000000 |-2048 MB | | |
ffffffffa0000000 |-1536 MB | fffffffffeffffff | 1520 MB | module mapping space
ffffffffff000000 | -16 MB | | |
FIXADDR_START | ~-11 MB | ffffffffff5fffff | ~0.5 MB | kernel-internal fixmap range, variable size and offset
ffffffffff600000 | -10 MB | ffffffffff600fff | 4 kB | legacy vsyscall ABI
ffffffffffe00000 | -2 MB | ffffffffffffffff | 2 MB | ... unused hole
__________________|____________|__________________|_________|___________________________________________________________


Complete virtual memory map with 5-level page tables
====================================================

.. note::

- With 56-bit addresses, user-space memory gets expanded by a factor of 512x,
from 0.125 PB to 64 PB. All kernel mappings shift down to the -64 PB starting
offset and many of the regions expand to support the much larger physical
memory supported.

::

========================================================================================================================
Start addr | Offset | End addr | Size | VM area description
========================================================================================================================
| | | |
0000000000000000 | 0 | 00ffffffffffffff | 64 PB | user-space virtual memory, different per mm
__________________|____________|__________________|_________|___________________________________________________________
| | | |
0100000000000000 | +64 PB | feffffffffffffff | ~16K PB | ... huge, still almost 64 bits wide hole of non-canonical
| | | | virtual memory addresses up to the -64 PB
| | | | starting offset of kernel mappings.
__________________|____________|__________________|_________|___________________________________________________________
|
| Kernel-space virtual memory, shared between all processes:
____________________________________________________________|___________________________________________________________
| | | |
ff00000000000000 | -64 PB | ff0fffffffffffff | 4 PB | ... guard hole, also reserved for hypervisor
ff10000000000000 | -60 PB | ff10ffffffffffff | 0.25 PB | LDT remap for PTI
ff11000000000000 | -59.75 PB | ff90ffffffffffff | 32 PB | direct mapping of all physical memory (page_offset_base)
ff91000000000000 | -27.75 PB | ff9fffffffffffff | 3.75 PB | ... unused hole
ffa0000000000000 | -24 PB | ffd1ffffffffffff | 12.5 PB | vmalloc/ioremap space (vmalloc_base)
ffd2000000000000 | -11.5 PB | ffd3ffffffffffff | 0.5 PB | ... unused hole
ffd4000000000000 | -11 PB | ffd5ffffffffffff | 0.5 PB | virtual memory map (vmemmap_base)
ffd6000000000000 | -10.5 PB | ffdeffffffffffff | 2.25 PB | ... unused hole
ffdf000000000000 | -8.25 PB | fffffbffffffffff | ~8 PB | KASAN shadow memory
__________________|____________|__________________|_________|____________________________________________________________
|
| Identical layout to the 47-bit one from here on:
____________________________________________________________|____________________________________________________________
| | | |
fffffc0000000000 | -4 TB | fffffdffffffffff | 2 TB | ... unused hole
| | | | vaddr_end for KASLR
fffffe0000000000 | -2 TB | fffffe7fffffffff | 0.5 TB | cpu_entry_area mapping
fffffe8000000000 | -1.5 TB | fffffeffffffffff | 0.5 TB | ... unused hole
ffffff0000000000 | -1 TB | ffffff7fffffffff | 0.5 TB | %esp fixup stacks
ffffff8000000000 | -512 GB | ffffffeeffffffff | 444 GB | ... unused hole
ffffffef00000000 | -68 GB | fffffffeffffffff | 64 GB | EFI region mapping space
ffffffff00000000 | -4 GB | ffffffff7fffffff | 2 GB | ... unused hole
ffffffff80000000 | -2 GB | ffffffff9fffffff | 512 MB | kernel text mapping, mapped to physical address 0
ffffffff80000000 |-2048 MB | | |
ffffffffa0000000 |-1536 MB | fffffffffeffffff | 1520 MB | module mapping space
ffffffffff000000 | -16 MB | | |
FIXADDR_START | ~-11 MB | ffffffffff5fffff | ~0.5 MB | kernel-internal fixmap range, variable size and offset
ffffffffff600000 | -10 MB | ffffffffff600fff | 4 kB | legacy vsyscall ABI
ffffffffffe00000 | -2 MB | ffffffffffffffff | 2 MB | ... unused hole
__________________|____________|__________________|_________|___________________________________________________________

Architecture defines a 64-bit virtual address. Implementations can support
less. Currently supported are 48- and 57-bit virtual addresses. Bits 63
through to the most-significant implemented bit are sign extended.
This causes hole between user space and kernel addresses if you interpret them
as unsigned.

The direct mapping covers all memory in the system up to the highest
memory address (this means in some cases it can also include PCI memory
holes).

We map EFI runtime services in the 'efi_pgd' PGD in a 64GB large virtual
memory window (this size is arbitrary, it can be raised later if needed).
The mappings are not part of any other kernel PGD and are only available
during EFI runtime calls.

Note that if CONFIG_RANDOMIZE_MEMORY is enabled, the direct mapping of all
physical memory, vmalloc/ioremap space and virtual memory map are randomized.
Their order is preserved but their base will be offset early at boot time.

Be very careful vs. KASLR when changing anything here. The KASLR address
range must not overlap with anything except the KASAN shadow area, which is
correct as KASAN disables KASLR.

For both 4- and 5-level layouts, the STACKLEAK_POISON value in the last 2MB
hole: ffffffffffff4111

2.2 进程地址空间

可以通过 /proc/<pid>/maps 查看。

/proc/<pid>/maps 文件保存了一个进程镜像的布局,通过展现每个内存映射来实现,展现的内容包括可执行文件、共享库、栈、堆和 VDSO 等。 这个文件对于快速解析一个进程的地址空间分布是至关重要的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
[root@centos-7 /]# ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.4 202264 4840 ? Ss 14:11 0:11 /usr/lib/system
root 2 0.0 0.0 0 0 ? S 14:11 0:00 [kthreadd]
root 4 0.0 0.0 0 0 ? S< 14:11 0:00 [kworker/0:0H]
root 6 0.0 0.0 0 0 ? S 14:11 0:02 [ksoftirqd/0]
root 7 0.0 0.0 0 0 ? S 14:11 0:00 [migration/0]
root 8 0.0 0.0 0 0 ? S 14:11 0:00 [rcu_bh]
root 9 0.0 0.0 0 0 ? R 14:11 0:05 [rcu_sched]
root 10 0.0 0.0 0 0 ? S< 14:11 0:00 [lru-add-drain]
root 11 0.0 0.0 0 0 ? S 14:11 0:00 [watchdog/0]
...

[root@centos-7 /]# more /proc/1/maps
555a43e44000-555a43fa8000 r-xp 00000000 fd:00 67953753 /usr/lib/systemd/systemd
555a441a8000-555a441cb000 r--p 00164000 fd:00 67953753 /usr/lib/systemd/systemd
555a441cb000-555a441cc000 rw-p 00187000 fd:00 67953753 /usr/lib/systemd/systemd
555a453cf000-555a45587000 rw-p 00000000 00:00 0 [heap]
7f9628000000-7f9628029000 rw-p 00000000 00:00 0
7f9628029000-7f962c000000 ---p 00000000 00:00 0
7f9630000000-7f9630029000 rw-p 00000000 00:00 0
7f9630029000-7f9634000000 ---p 00000000 00:00 0
7f963758b000-7f963758c000 ---p 00000000 00:00 0
7f963758c000-7f9637d8c000 rw-p 00000000 00:00 0
7f9637d8c000-7f9637d8d000 ---p 00000000 00:00 0
7f9637d8d000-7f963858d000 rw-p 00000000 00:00 0
7f963858d000-7f963858e000 ---p 00000000 00:00 0
7f963858e000-7f9638e5f000 rw-p 00000000 00:00 0
7f9638ff7000-7f9638ffb000 r-xp 00000000 fd:00 239612 /usr/lib64/libuuid.so.1.3.0
....