64位机器上/proc/kcore的结构与物理内存的关系

hft*_*hft 5 linux 64bit memory gdb

让我先说这个问题,我已经找到了很多与我的问题类似但针对 32 位机器的问题的答案。但是,我找不到 64 位机器的任何东西。请不要回答有关 32 位机器的问题。

据对堆栈交换许多来源,/proc/kcore可以从字面上倾倒(例如,使用dd)的文件,以获得的物理内存副本...但是,这显然不适合一个64位的机器,对于这工作/proc/kcore是128TB在尺寸。

顺便说一句,我注意到可以通过/dev/mem. 这是出于安全原因。解决这个问题涉及重新编译内核,我不想这样做......我也不能这样做(我必须使用正在运行的内核)。

好的...所以,/proc/kcore是物理内存的 ELF 核心文件转储,可以使用gdb. 例如,与:

gdb /usr/[blah]/vmlinux /proc/kcore
Run Code Online (Sandbox Code Playgroud)

这个我可以做……但是,这不是我想做的。我想将物理内存导出到文件以进行离线分析。但我遇到了问题。

一方面,我不能只是转储/proc/kcore到一个文件,因为它是 128TB。我想转储所有的物理内存,但我不知道在那里它是/proc/kcore。我只看到非零数据直到字节 3600,然后就我所见(大约 40GB)而言,它全为零。我认为这可能与内存映射到 的方式有关/proc/kcore,但我不了解结构,需要一些指导。

我想我知道的更多东西:我知道只有 48 位用于寻址,而不是 64 位。这意味着应该有 2 48 = 256TB 的可用内存......但/proc/kcore只有 128TB,我认为这是因为寻址被进一步分为从 0x0000000000000000 到 0x00007fffffffffff (128TB) 的块和从 0xffff80000ff0ff (128TB) 到 0xffff8000ff0ff 到 0xffff80000ff0ff 的块. 所以,不知何故,这使得/proc/kcore128TB ......但这是因为这些块之一被映射到/proc/kcore一个不是吗?还是其他什么原因?

所以,作为一个例子,我可以gdb用来分析/proc/kcore和查找,例如,sys_call_table 的位置(?):

(gdb) p (unsigned long*) sys_call_table
$1 = (unsigned long *) 0xffffffff811a4f20 <sys_read>
Run Code Online (Sandbox Code Playgroud)

这是否意味着从 0xffff8000000000000 到 0xffffffffffffffff 的内存块是什么/proc/kcore?如果是这样,它是如何映射到的/proc/kcore?例如使用

dd if=/proc/kcore bs=1 skip=2128982200 count=100 | xxd
Run Code Online (Sandbox Code Playgroud)

仅显示零(2128982200 稍早于 0xffffffffffffffff-0xffffffff811a4f20)...

此外,我知道如何使用gcore转储给定进程的内存进行分析。而且我也知道,我可以看看,看看有什么进程内存的模样......但尽管如此,我仍然不知道如何转储整个物理内存......这是一种我发疯的。请帮助我避免发疯......;)/proc/PID/maps

hft*_*hft 4

经过大量搜索后,我想我已经说服自己,没有简单的方法可以得到我想要的东西。

那么,我最终做了什么?我从 github 安装了 LiME ( https://github.com/504ensicsLabs/LiME )

git clone https://github.com/504ensicsLabs/LiMe
cd /LiME/src
make -C /lib/modules/`uname -r`/build M=$PWD modules
Run Code Online (Sandbox Code Playgroud)

上面的命令创建了lim.ko内核模块。然后运行以下命令可以获得内存的完整转储:

insmod ./lime.ko "path=/root/temp/outputDump.bin format=raw dio=0"
Run Code Online (Sandbox Code Playgroud)

它只是插入内核模块,字符串是指定输出文件位置和格式的参数......并且它有效!耶。