mac查看内存使用情况(教你用mac命令行查看内存)

mac查看内存使用情况(教你用mac命令行查看内存)

读取Mac的内存映射过程

2. 找出Ruby二进制文件在内存中加载的位置(来自进程的内存映射);

3. 减去__mh_execute_header符号的值。

00400000-00401000 r-xp 00000000 00:14 13644 /usr/bin/ruby1.9.1

00600000-00601000 r–p 00000000 00:14 13644 /usr/bin/ruby1.9.1

00601000-00602000 rw-p 00001000 00:14 13644 /usr/bin/ruby1.9.1

0060b000-00887000 rw-p 00000000 00:00 0 [heap]

7f1d44648000-7f1d4464a000 r-xp 00000000 00:14 14411 /usr/lib/ruby/1.9.1/x86_64-linux/enc/trans/transdb.so

7f1d4464a000-7f1d4484a000 —p 00002000 00:14 14411 /usr/lib/ruby/1.9.1/x86_64-linux/enc/trans/transdb.so

7f1d4484a000-7f1d4484b000 r–p 00002000 00:14 14411 /usr/lib/ruby/1.9.1/x86_64-linux/enc/trans/transdb.so

7f1d4484b000-7f1d4484c000 rw-p 00003000 00:14 14411 /usr/lib/ruby/1.9.1/x86_64-linux/enc/trans/transdb.so

而在所有版本的Mac上,虽然内存映射的结构基本上是相同的,但是获取它们会相当困难!起初我试图在Mac上使用适用于Linux的方法(就是上文提到的/ proc文件),但花了3天时间都没有得到。为此,我进行了以下2种尝试:

尝试1——使用vmmap

不过,由于某种原因vmmap速度很慢,获取一个进程的内存映射需要2秒,这可能是因为vmmap在获取内存映射之前暂停了这个过程。

我不想直接使用vmma的原因,除了不满意vmmap的速度以外,另外一个原因就是如果vmmap真的是在获取内存映射之前暂停了这个过程,那这就意味着内存映射的分析过程被干扰了。

尝试2——在Rust中重新使用vmmap

Rust是针对多核体系提出的语言,并且吸收一些其他动态语言的重要特性,比如不需要管理内存,比如不会出现Null指针等等。由于不想直接使用vmmap,所以我考虑在Rust中重新实现它的功能(至少是我需要的部分)。我在Rust中写了一个简单的vmmap复制功能,代码就在main.rs。

为了做到这一点,我使用了mach crate,它具有Rust绑定功能,可以调用一些Mac内核函数。我还了解到,在Mac / BSD上有一个“端口(port)”的概念:

‘端口’是一个受保护的消息队列,用于在任务之间进行通信,任务拥有发送权限并接收每个端口的权限

我已经注释了一些代码,它使用https://github.com/andrewdavidmackenzie/libproc-rs crate作为regionfilename函数(它给出了与内存映射关联的库的文件名)。我就不得不在github master上使用该版本的crate,因为其发布的版本有一个Use-After-Free(UAF)漏洞。

fn mach_vm_region(target_task: mach_port_name_t, mut address: mach_vm_address_t) -> Option<Region> {

let mut count = mem::size_of::<vm_region_basic_info_data_64_t>() as mach_msg_type_number_t;

let mut object_name: mach_port_t = 0;

// we need to create new `size` and `info` structs for the function we call to read the data

// into

let mut size = unsafe { mem::zeroed::<mach_vm_size_t>() };

let mut info = unsafe { mem::zeroed::<vm_region_basic_info_data_t>() };

let result = unsafe {

// Call the underlying Mach function

mach::vm::mach_vm_region(

target_task as vm_task_entry_t,

&mut address,

&mut size,

VM_REGION_BASIC_INFO,

&mut info as *mut vm_region_basic_info_data_t as vm_region_info_t,

&mut count,

&mut object_name,

)

};

if result != KERN_SUCCESS {

return None;

}

// this uses

let filename = match regionfilename(41000, address) {

Ok(x) => Some(x),

_ => None,

};

Some(Region {

size: size,

info: info,

address: address,

count: count,

filename: filename,

})

}

以上是我编写的Rust程序,比vmmap要快很多!整个内存映射的时间要在80毫秒左右完成,比vmmap快大约15倍。

在下面的链接中有一堆关于这个“dyld”的代码,我打算试着利用一下。

用于从Mac进程读取内存映射的有用资源

以下是我在Mac上阅读内存映射时发现的4个最有用的资源:

1.来自OS X内部的vmmap.c源代码;

3.来自Chromium的dynamic_images.cc,用它读取Mac进程中的信息共享库;

4.psutil的OS X C代码,ppsutil是一个跨平台库,能够轻松实现获取系统运行的进程和系统利用率(CPU,内存,磁盘,网络等)信息,主要应用于系统监控,分析和限制系统资源及进程的管理,它实现了同等命令行工具提供的功能,所以它的源代码有助于了解Mac内部的结构

发表评论

登录后才能评论