查找X86_64下内核代码段物理地址的方法
时间:2009-12-31
来源:互联网
查找X86_64下内核代码段物理地址的方法
一. 目标: 我想找出X86_64 LINUX 2.6.18的内核代码段的物理地址. 找出这个地址有什么用呢? 一般人是用不到的. 不过如果你知道什么是DMA ATTACK. 同时又想用这个方法来攻击X86_64 LINUX的话, 你也许就会用到内核的物理地址了.
二. 方法:
错误的方法:
在最开始的时候, 我一下子就想到了内核里面提供的VIRT_TO_PHYS函数. 看它的名字,就是把虚拟地址转成物理地址的. 同时,内核代码段的虚拟地址很容易获得,直接 grep _text System 就可以了.
但是当我按照上面的思路写了一个kernel module之后,发现得到的地址明显不对. 因为得到的物理地址已经超过了我机器上已经插的内存条的总量. 后来仔细看了下VIRT_TO_PHYS的说明,发现它只是对KMALLOC() 分配的内存有效. 不过在X86-32 体系下, 它好像是可以用在内核代码段上的了 .
不管怎么说,此路不通. 那么只好用其他办法了. 在大概20多天的时间里,我一直没找到好的方法, 直到今天偶然看到了ZX_WING 大侠的这篇文章: http://linux.chinaunix.net/bbs/thread-1032711-1-1.html
(btw:同时要感谢把这篇文章顶起来的兄弟)
正确的方法:
看了ZX_WING老大的LINKER SCRIPT一文之后, 你就会发现, 内核加载的物理地址是在LINKER SCRIPT里面指定的. 那么接下来就是看这个SCRIPT了.
首先找X86_64的连接文件, 在2.6.32里面的时候,X86 32 和64的已经合并成一个文件了. 不过在我用的2.6.18里面还是分开的2个文件. 他的位置在ARCH/KERNEL/X86_64 (或者X86)/下面.
下面是其中的一小段:
http://lxr.linux.no/#linux+v2.6. ... ernel/vmlinux.lds.S
SECTIONS
17{
18 . = __START_KERNEL;
19 phys_startup_64 = startup_64 - LOAD_OFFSET;
20 _text = .; /* Text and read-only data */
21 .text : AT(ADDR(.text) - LOAD_OFFSET) {
明显用到了宏__START_KERNEL, 那么就把它相关的找出来吧. 分散在几个.H文件里面, 如下:
#define __PHYSICAL_START CONFIG_PHYSICAL_START
#define __START_KERNEL (__START_KERNEL_map + __PHYSICAL_START)
#define __START_KERNEL_map 0xffffffff80000000UL
#define LOAD_OFFSET __START_KERNEL_map
关于CONFIG_PHYSICAL_START的说明如下:
http://lxr.linux.no/#linux+v2.6.18/arch/x86_64/Kconfig#L493
config PHYSICAL_START
494 hex "Physical address where the kernel is loaded" if (EMBEDDED || CRASH_DUMP)
495 default "0x1000000" if CRASH_DUMP
496 default "0x200000"
497 help
498 This gives the physical address where the kernel is loaded. Normally
499 for regular kernels this value is 0x200000 (2MB). But in the case
500 of kexec on panic the fail safe kernel needs to run at a different
501 address than the panic-ed kernel.
从上面可以看出PHYSICAL_START 的默认地址是 0X200000. 同时KERNEL 代码的起始虚拟地址是0XFFFFFFFF80000000. 那么这2个地址对应的内容应该是一样的. 只不过前者是物理地址,后者是虚拟地址.
最后, 装个X86_64的QEMU虚拟机验证下(我用的是QEMU版本是0.11.91,老的版本,比如0.9.x, 0.10等好像支持的不好, 我总是装不上X86_64版本的CENTOS 5.1).
按ALT+CTL+2, 切换到QEMU MONITOR, 然后输入下面2个命令:
x /10x 0xffffffff80000000
xp /10x 0x200000
发现内容是一样的. 证明前面的推理完全正确.
不过还是有个地方不太明白:
从下面三行来看:
. = __START_KERNEL;
phys_startup_64 = startup_64 - LOAD_OFFSET;
_text = .;
_text的其实地址似乎应该是__START_KERNEL, 也就是0XFFFFFFFF80000000+0X200000 = 0XFFFFFFFF80200000. 但是我用GREP _TEXT SYMBOL 得到的结果是0XFFFFFFFF80000000. 没有用到PHYSICAL_START. 不知道为什么会这样? 哪位可以解释下? 多谢
[ 本帖最后由 accessory 于 2009-12-31 06:26 编辑 ]
一. 目标: 我想找出X86_64 LINUX 2.6.18的内核代码段的物理地址. 找出这个地址有什么用呢? 一般人是用不到的. 不过如果你知道什么是DMA ATTACK. 同时又想用这个方法来攻击X86_64 LINUX的话, 你也许就会用到内核的物理地址了.
二. 方法:
错误的方法:
在最开始的时候, 我一下子就想到了内核里面提供的VIRT_TO_PHYS函数. 看它的名字,就是把虚拟地址转成物理地址的. 同时,内核代码段的虚拟地址很容易获得,直接 grep _text System 就可以了.
但是当我按照上面的思路写了一个kernel module之后,发现得到的地址明显不对. 因为得到的物理地址已经超过了我机器上已经插的内存条的总量. 后来仔细看了下VIRT_TO_PHYS的说明,发现它只是对KMALLOC() 分配的内存有效. 不过在X86-32 体系下, 它好像是可以用在内核代码段上的了 .
不管怎么说,此路不通. 那么只好用其他办法了. 在大概20多天的时间里,我一直没找到好的方法, 直到今天偶然看到了ZX_WING 大侠的这篇文章: http://linux.chinaunix.net/bbs/thread-1032711-1-1.html
(btw:同时要感谢把这篇文章顶起来的兄弟)
正确的方法:
看了ZX_WING老大的LINKER SCRIPT一文之后, 你就会发现, 内核加载的物理地址是在LINKER SCRIPT里面指定的. 那么接下来就是看这个SCRIPT了.
首先找X86_64的连接文件, 在2.6.32里面的时候,X86 32 和64的已经合并成一个文件了. 不过在我用的2.6.18里面还是分开的2个文件. 他的位置在ARCH/KERNEL/X86_64 (或者X86)/下面.
下面是其中的一小段:
http://lxr.linux.no/#linux+v2.6. ... ernel/vmlinux.lds.S
SECTIONS
17{
18 . = __START_KERNEL;
19 phys_startup_64 = startup_64 - LOAD_OFFSET;
20 _text = .; /* Text and read-only data */
21 .text : AT(ADDR(.text) - LOAD_OFFSET) {
明显用到了宏__START_KERNEL, 那么就把它相关的找出来吧. 分散在几个.H文件里面, 如下:
#define __PHYSICAL_START CONFIG_PHYSICAL_START
#define __START_KERNEL (__START_KERNEL_map + __PHYSICAL_START)
#define __START_KERNEL_map 0xffffffff80000000UL
#define LOAD_OFFSET __START_KERNEL_map
关于CONFIG_PHYSICAL_START的说明如下:
http://lxr.linux.no/#linux+v2.6.18/arch/x86_64/Kconfig#L493
config PHYSICAL_START
494 hex "Physical address where the kernel is loaded" if (EMBEDDED || CRASH_DUMP)
495 default "0x1000000" if CRASH_DUMP
496 default "0x200000"
497 help
498 This gives the physical address where the kernel is loaded. Normally
499 for regular kernels this value is 0x200000 (2MB). But in the case
500 of kexec on panic the fail safe kernel needs to run at a different
501 address than the panic-ed kernel.
从上面可以看出PHYSICAL_START 的默认地址是 0X200000. 同时KERNEL 代码的起始虚拟地址是0XFFFFFFFF80000000. 那么这2个地址对应的内容应该是一样的. 只不过前者是物理地址,后者是虚拟地址.
最后, 装个X86_64的QEMU虚拟机验证下(我用的是QEMU版本是0.11.91,老的版本,比如0.9.x, 0.10等好像支持的不好, 我总是装不上X86_64版本的CENTOS 5.1).
按ALT+CTL+2, 切换到QEMU MONITOR, 然后输入下面2个命令:
x /10x 0xffffffff80000000
xp /10x 0x200000
发现内容是一样的. 证明前面的推理完全正确.
不过还是有个地方不太明白:
从下面三行来看:
. = __START_KERNEL;
phys_startup_64 = startup_64 - LOAD_OFFSET;
_text = .;
_text的其实地址似乎应该是__START_KERNEL, 也就是0XFFFFFFFF80000000+0X200000 = 0XFFFFFFFF80200000. 但是我用GREP _TEXT SYMBOL 得到的结果是0XFFFFFFFF80000000. 没有用到PHYSICAL_START. 不知道为什么会这样? 哪位可以解释下? 多谢
[ 本帖最后由 accessory 于 2009-12-31 06:26 编辑 ]
作者: accessory 发布时间: 2009-12-31
呵呵 研究一下去
作者: Godbach: 发布时间: 2010-01-01
QUOTE:
[root@localhost boot]# grep "\b_text\b" System.map-2.6.18-128.el5
ffffffff80000000 A _text
[root@localhost boot]# grep "\b_text\b" System.map-2.6.33
ffffffff81000000 T _text
[root@localhost boot]# grep "\b_text\b" System.map-2.6.30.10
ffffffff80200000 T _text
ffffffff80000000 A _text
[root@localhost boot]# grep "\b_text\b" System.map-2.6.33
ffffffff81000000 T _text
[root@localhost boot]# grep "\b_text\b" System.map-2.6.30.10
ffffffff80200000 T _text
回复 accessory
这个是我的结果,貌似不同内核版本的都不一样?
作者: flydream81 发布时间: 2010-07-12
有可能. 即使是X86-32, 不同的机器便宜出来的内核地址也可能不一样.
作者: kgn28 发布时间: 2010-07-12
按ALT+CTL+2, 切换到QEMU MONITOR, 然后输入下面2个命令:
x /10x 0xffffffff80000000
xp /10x 0x200000
在linux终端下,如何查看这两个地址的内容呢?
貌似在linux下无法直接访问物理地址的呀
x /10x 0xffffffff80000000
xp /10x 0x200000
在linux终端下,如何查看这两个地址的内容呢?
貌似在linux下无法直接访问物理地址的呀
作者: accessory 发布时间: 2010-11-10
在这个帖子中的图片我这边都打不开,不知哪位朋友那可以打开?能否帮忙转载过来下
作者: lofeng410 发布时间: 2010-11-10
相关阅读 更多
热门阅读
-
office 2019专业增强版最新2021版激活秘钥/序列号/激活码推荐 附激活工具
阅读:74
-
如何安装mysql8.0
阅读:31
-
Word快速设置标题样式步骤详解
阅读:28
-
20+道必知必会的Vue面试题(附答案解析)
阅读:37
-
HTML如何制作表单
阅读:22
-
百词斩可以改天数吗?当然可以,4个步骤轻松修改天数!
阅读:31
-
ET文件格式和XLS格式文件之间如何转化?
阅读:24
-
react和vue的区别及优缺点是什么
阅读:121
-
支付宝人脸识别如何关闭?
阅读:21
-
腾讯微云怎么修改照片或视频备份路径?
阅读:28