地址映射与共享

2023-11-20

跟踪地址映射过程

1.通过命令./dbg-asm启动调试器,在linux-0.11运行test.c文件,使其进入死循环,我们的任务就是找到i的地址并将其修改为0使test.c程序退出循环。

2.在命令行输入crit+c使Boch暂停,一般会显示下列信息

(0) [0x00fc8031] 000f:00000031 (unk. ctxt): cmp dword ptr ds:0x3004, 0x00000000 ; 833d0430000000

其中的 000f 如果是 0008,则说明中断在了内核里。那么就要 c,然后再 ctrl+c,直到变为 000f 为止。

如果显示的下一条指令不是 cmp …(这里指语句以 cmp 开头),就用 n 命令单步运行几步,直到停在 cmp …。

3.使用命令 u /8,显示从当前位置开始 8 条指令的反汇编代码,从反汇编代码可以看到,变量i保存在ds:0x3004地址上。

接下来,开始寻找ds:0x3004对应的物理地址

ds:0x3004为虚拟地址,我们首先找到段表,根据ds的值在段表中找到ds段的具体信息。

段表保存在ldtr寄存器中,我们在调试窗口输入sreg命令就会得到

<bochs:4> sreg
cs:s=0x000f, dl=0x00000002, dh=0x10c0fa00, valid=1
ds:s=0x0017, dl=0x00003fff, dh=0x10c0f300, valid=3
ss:s=0x0017, dl=0x00003fff, dh=0x10c0f300, valid=1
es:s=0x0017, dl=0x00003fff, dh=0x10c0f300, valid=1
fs:s=0x0017, dl=0x00003fff, dh=0x10c0f300, valid=1
gs:s=0x0017, dl=0x00003fff, dh=0x10c0f300, valid=1
ldtr:s=0x0068, dl=0xa2d00068, dh=0x000082fa, valid=1
tr:s=0x0060, dl=0xa2e80068, dh=0x00008bfa, valid=1
gdtr:base=0x00005cb8, limit=0x7ff
idtr:base=0x000054b8, limit=0x7ff

可以看到ldtr的值是0x0068=0000000001101000(二进制,表示LDT表存放在GDT表的1101(二进制)=13(十进制号位置(每位数据的意义参考后文叙述的段选择子)。

GDT的位置已经由gdtr明确给出,在物理地址的0x00005cb8

GDT表中的每一项占 64 位(8 个字节),所以我们要查找的项的地址是0x00005cb8+13*8

输入xp /2w 0x00005cb8+13*8,得到:

<bochs:6> xp /2w 0x00005cb8+13*8
[bochs]:
0x00005d20 <bogus+       0>:    0xa2d00068    0x000082fa

“0xa2d00068 0x000082fa”将其中的加粗数字组合为“0x00faa2d0”,这就是 LDT 表的物理地址(为什么这么组合,参考后文介绍的段描述符)。

xp /8w 0x00faa2d0,得到:

<bochs:7> xp /8w 0x00faa2d0
[bochs]:
0x00faa2d0 <bogus+       0>:    0x00000000    0x00000000    0x00000002    0x10c0fa00
0x00faa2e0 <bogus+      16>:    0x00003fff    0x10c0f300    0x00000000    0x00fab000

这就是LDT表的前四项内容了

ds选择子:保存段在段表中的索引值,用这个索引值可以从段表中选择出相应的段描述符

段选择子的结构为

其中 RPL 是请求特权级,当访问一个段时,处理器要检查 RPL 和 CPL(放在 cs 的位 0 和位 1 中,用来表示当前代码的特权级),即使程序有足够的特权级(CPL)来访问一个段,但如果 RPL(如放在 ds 中,表示请求数据段)的特权级不足,则仍然不能访问,即如果 RPL 的数值大于 CPL(数值越大,权限越小),则用 RPL 的值覆盖 CPL 的值。

而段选择子中的 TI 是表指示标记,如果 TI=0,则表示段描述符(段的详细信息)在 GDT(全局描述符表)中,即去 GDT 中去查;而 TI=1,则去 LDT(局部描述符表)中去查。

通过前面的sreg命令我们知道ds=0x0017,展开为二进制为0000000000010111,所以 RPL=11,可见是在最低的特权级(因为在应用程序中执行),TI=1,表示查找 LDT 表,索引值为 10(二进制)= 2(十进制),表示找 LDT 表中的第 3 个段描述符(从 0 开始编号)

LDT 和 GDT 的结构一样,每项占 8 个字节。所以第 3 项 0x00003fff 0x10c0f300(上一步骤的最后一个输出结果中) 就是搜寻好久的 ds 的段描述符了。

段选择符内容

可以看到,段描述符是一个 64 位二进制的数,存放了段基址和段限长等重要的数据。其中位 P(Present)是段是否存在的标记;位 S 用来表示是系统段描述符(S=0)还是代码或数据段描述符(S=1);四位 TYPE 用来表示段的类型,如数据段、代码段、可读、可写等;DPL 是段的权限,和 CPL、RPL 对应使用;位 G 是粒度,G=0 表示段限长以位为单位,G=1 表示段限长以 4KB 为单位;其他内容就不详细解释了。

费了很大的劲,实际上我们需要的只有段基址一项数据,即段描述符 “0x00003fff 0x10c0f300” 中加粗部分组合成的 “0x10000000”。这就是 ds 段在线性地址空间中的起始地址。用同样的方法也可以算算其它段的基址,都是这个数。

段基址+段内偏移,就是线性地址了。所以 ds:0x3004 的线性地址就是:

0x10000000 + 0x3004 = 0x10003004

calc ds:0x3004命令可以验证这个结果.

找到了虚拟内存的线性地址,接下来就是找对应的物理地址,而实际操作系统管理内存使用的是分页机制,因此我们需要查询页表

前面找到的线性地址为0x10003004

首先需要算出线性地址中的页目录号、页表号和页内偏移,它们分别对应了 32 位线性地址的 10 位 + 10 位 + 12 位,所以 0x10003004 的页目录号是 64,页号 3,页内偏移是 4。

通过creg命令可以查看页目录表的位置,页目录表的位置保存在CR3寄存器中

CR0=0x8000001b: PG cd nw ac wp ne ET TS em MP PE
CR2=page fault laddr=0x10002f68
CR3=0x00000000
    PCD=page-level cache disable=0
    PWT=page-level writes transparent=0
CR4=0x00000000: osxmmexcpt osfxsr pce pge mce pae pse de tsd pvi vme

说明页目录表的基址为0,通过xp/68w 0查看其内容

0x00000000 :    0x00001027    0x00002007    0x00003007    0x00004027
0x00000010 :    0x00000000    0x00024764    0x00000000    0x00000000
0x00000020 :    0x00000000    0x00000000    0x00000000    0x00000000
0x00000030 :    0x00000000    0x00000000    0x00000000    0x00000000
0x00000040 :    0x00ffe027    0x00000000    0x00000000    0x00000000
0x00000050 :    0x00000000    0x00000000    0x00000000    0x00000000
0x00000060 :    0x00000000    0x00000000    0x00000000    0x00000000
0x00000070 :    0x00000000    0x00000000    0x00000000    0x00000000
0x00000080 :    0x00ff3027    0x00000000    0x00000000    0x00000000
0x00000090 :    0x00000000    0x00000000    0x00000000    0x00000000
0x000000a0 :    0x00000000    0x00000000    0x00000000    0x00000000
0x000000b0 :    0x00000000    0x00000000    0x00000000    0x00ffb027
0x000000c0 :    0x00ff6027    0x00000000    0x00000000    0x00000000
0x000000d0 :    0x00000000    0x00000000    0x00000000    0x00000000
0x000000e0 :    0x00000000    0x00000000    0x00000000    0x00000000
0x000000f0 :    0x00000000    0x00000000    0x00000000    0x00ffa027
0x00000100 :    0x00faa027    0x00000000    0x00000000    0x00000000

页目录表和页表中的内容很简单,是 1024 个 32 位(正好是 4K)数。这 32 位中前 20 位是物理页框号,后面是一些属性信息(其中最重要的是最后一位 P)。其中第 65 个页目录项就是我们要找的内容,用“xp /w 0+64*4”查看:

0x00000100 :    0x00faa027

其中的 027 是属性,显然 P=1,其他属性实验者自己分析吧。页表所在物理页框号为 0x00faa,即页表在物理内存的 0x00faa000 位置。从该位置开始查找 3 号页表项,得到(xp /w 0x00faa000+3*4):

0x00faa00c :    0x00fa7067

其中067是属性,显然P=1;

线性地址 0x10003004 对应的物理页框号为 0x00fa7,和页内偏移 0x004 接到一起,得到 0x00fa7004,这就是变量 i 的物理地址。可以通过两种方法验证。

第一种方法是用命令 page 0x10003004,可以得到信息:

linear page 0x10003000 maps to physical page 0x00fa7000

第二种方法是用命令 xp /w 0x00fa7004,可以看到:

0x00fa7004 :    0x12345678

现在,通过直接修改内存来改变 i 的值为 0,命令是: setpmem 0x00fa7004 4 0,表示从 0x00fa7004 地址开始的 4 个字节都设为 0。然后再用“c”命令继续 Bochs 的运行,可以看到 test 退出了,说明 i 的修改成功了,此项实验结束。

总结一下求物理地址的步骤

  • 找出LDT在GDT中的位置

  • 根据ds的值得到段描述符索引,TI

  • 在段表中找段描述符,求出线性地址

  • 根据线性地址查页表

    • 线性地址前十位为页目录项,通过CR3寄存器找到页目录的起始地址,然后根据页目录项找到对应的物理页框
    • 线性地址中间十位为页表号,根据页表号在物理页框的位置找到页表号在物理内存的位置
    • 线性地址最后十二位为业内偏移,由前面得到的页表号在物理内存的位置加上业内偏移得到物理内存

性地址前十位为页目录项,通过CR3寄存器找到页目录的起始地址,然后根据页目录项找到对应的物理页框
* 线性地址中间十位为页表号,根据页表号在物理页框的位置找到页表号在物理内存的位置
* 线性地址最后十二位为业内偏移,由前面得到的页表号在物理内存的位置加上业内偏移得到物理内存

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

地址映射与共享 的相关文章

  • 仅使用containerd(不使用Docker)修剪容器镜像

    如果我刚刚containerd安装在 Linux 系统上 即 Docker 是not安装 如何删除未使用的容器映像以节省磁盘空间 Docker 就是这么方便docker system prune https docs docker com
  • 执行命令而不将其保留在历史记录中[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 在进行软件开发时 经常需要在命令行命令中包含机密信息 典型示例是将项目部署到服务器的凭据设置为环境变量 当我不想将某些命令存储在命令历史记
  • Linux 中 m 标志和 o 标志将存储在哪里

    我想知道最近收到的路由器通告的 m 标志和 o 标志的值 从内核源代码中我知道存储了 m 标志和 o 标志 Remember the managed otherconf flags from most recently received R
  • 有没有一种快速方法可以从 Jar/war 中删除文件,而无需提取 jar 并重新创建它?

    所以我需要从 jar war 文件中删除一个文件 我希望有类似 jar d myjar jar file I donot need txt 的内容 但现在我能看到从 Linux 命令行执行此操作的唯一方法 不使用 WinRAR Winzip
  • 适用于 Linux 的轻量级 IDE [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 如何为 Linux 桌面条目文件指定带有相对路径的图标?

    对于我的一个 Linux 应用程序 我有应用程序二进制文件 一个 launcher sh 脚本 针对 LD LIBRARY PATH 和一个 desktop 文件 所有这些都位于同一文件夹中 我想使用图标的相对路径而不是绝对路径 我试过了
  • 如何使用 Cloud Init 挂载未格式化的 EBS 卷

    Context 我正在使用https wiki jenkins io display JENKINS Amazon EC2 Plugin https wiki jenkins io display JENKINS Amazon EC2 Pl
  • tcpdump 是否受 iptables 过滤影响?

    如果我的开发机器有iptables规则到FORWARD一些数据包 这些数据包是否被 tcpdump 捕获 我有这个问题 因为我知道存在其他链称为INPUT如果数据包路由到 它会过滤发往应用程序的数据包FORWARD链 它会到达吗tcpdum
  • 添加文件时运行 shell 命令

    我的 Linux 机器上有一个名为 images 的文件夹 该文件夹连接到一个网站 该网站的管理员可以向该网站添加图片 但是 当添加图片时 我想要一个命令来运行调整目录中所有图片的大小 简而言之 我想知道当新文件添加到特定位置时如何使服务器
  • 为什么 fopen("any_path_name",'r') 不给出 NULL 作为返回值?

    在调试一些代码时 我得到如下内容 include
  • 如何让R使用所有处理器?

    我有一台运行 Windows XP 的四核笔记本电脑 但查看任务管理器 R 似乎一次只使用一个处理器 如何让 R 使用全部四个处理器并加速我的 R 程序 我有一个基本系统 我使用它在 for 循环上并行化我的程序 一旦您了解需要做什么 此方
  • 使用包管理器时如何管理 Perl 模块?

    A 最近的问题 https stackoverflow com questions 397817 unable to find perl modules in intrepid ibex ubuntu这让我开始思考 在我尝试过的大多数 Li
  • 从 Xlib 转换为 xcb

    我目前正在将我的一个应用程序从 Xlib 移植到 libxcb 但在查找有关我有时使用的 XInput2 扩展的信息时遇到了一些麻烦 libxcb 中有 XInput2 实现吗 如果是的话 在哪里可以找到文档 目前我在使用此功能时遇到问题
  • 配置tomat的server.xml文件并自动生成mod_jk.conf

    我在用apache 2 2 15 and tomcat6 6 0 24 on CentOS 6 4并希望使用 tomcat 服务器的功能 通过添加以下内容自动生成 mod jk conf 文件
  • 绕过 dev/urandom|random 进行测试

    我想编写一个功能测试用例 用已知的随机数值来测试程序 我已经在单元测试期间用模拟对其进行了测试 但我也希望用于功能测试 当然不是全部 最简单的方法是什么 dev urandom仅覆盖一个进程 有没有办法做类似的事情chroot对于单个文件并
  • 如何在 *nix 中登录时运行脚本?

    我知道我曾经知道如何做到这一点 但是 如何在 unix 中登录时运行脚本 bash 可以 From 维基百科 Bash http en wikipedia org wiki Bash 28Unix shell 29 当 Bash 启动时 它
  • 如何使用Android获取Linux内核的版本?

    如何在 Android 应用程序中获取 Linux 内核的版本 不是 100 确定 但我认为调用 uname r 需要 root 访问权限 无论如何 有一种不太肮脏的方法可以做到这一点 那就是 System getProperty os v
  • 如何在 Mac OSX Mavericks 中正确运行字符串工具?

    如何在 Mac OSX Mavericks 中正确运行字符串工具 我尝试按照我在网上找到的示例来运行它 strings a UserParser class 但我收到此错误 错误 Applications Xcode app Content
  • 为什么同一个curl命令在windows和linux下输出不同的东西?

    为什么同样的curl o file https www link com 命令输出不同的东西 例如 如果我运行命令curl o source txt https www youtube com playlist list PLIx6Fwnp
  • 从 Linux 内核模块中调用用户空间函数

    我正在编写一个简单的 Linux 字符设备驱动程序 以通过 I O 端口将数据输出到硬件 我有一个执行浮点运算的函数来计算硬件的正确输出 不幸的是 这意味着我需要将此函数保留在用户空间中 因为 Linux 内核不能很好地处理浮点运算 这是设

随机推荐

  • Java中基本类型自动转换与强制转换

    类型转换 Java 语言是一种强类型的语言 强类型的语言有以下几个要求 变量或常量必须有类型 要求声明变量或常量时必须声明类型 而且只能在声明以后才能使用 赋值时类型必须一致 值的类型必须和变量或常量的类型完全一致 运算时类型必须一致 参与
  • Python学习(3):批量修改文件名(以excel文件为例)

    coding utf 8 import os dir input 请输入文件路径 for root dirs files in os walk dir for i in range len files filename files i ne
  • python django 学习第3天 文件长传

    在根目录下新建media目录 在settings py 加入代码 为上传文件操作做准备 MEDIA ROOT os path join BASE DIR media MEDIA URL media 做一个新闻调查页面 在views 中加入
  • bash 括号(小括号,双小括号,中括号,双中括号,大括号)

    小括号 和大括号 主要包括一下几种 var cmd 和 exp var string var string var string var string var pattern var pattern var pattern var patt
  • 计算机网络运输层运输层协议概述

    运输层协议概述 进程之间的通信 下图说明运输层的作用 可以看出网络层为主机之间提供逻辑通信 而运输层为应用进程之间提供端到端的逻辑通信 根据应用程序的不同需求 运输层有两种不同的运输协议 1 面向连接的TCP 2 无连接的UDP 运输层的两
  • Vue-cli3更改项目logo图标

    1 图标切成对应大小 2 图标名称后缀与vue原有图标logo名称 后缀一致 favicon ico 并替换 3 vue项目根目录下 新建 vue config js 添加下列代码 module exports pwa iconPaths
  • 网络爬虫 - 1 网络爬虫基本概念和相关工具

    网络爬虫基本概念和相关工具 1 基本概念 1 什么是网络爬虫 web crawler 以前经常称之为网络蜘蛛 spider 是按照一定的规则自动浏览万维网并获取信息的机器人程序 或脚本 曾经被广泛的应用于互联网搜索引擎 使用过互联网和浏览器
  • Linux环境下的VScode使用教程

    前言 1 对于学习本文需要先有自行安装好VMware 对VMware有简单的了解 2 对于绝大多数使用Linux的人而言 经常在Windows环境下使用source insight进行编译程序 然后利用FileZilla将Windows的文
  • Vue出现弹出层时,禁止底部页面跟随滑动

    背景 最近在写一个vue项目 当出现弹出层时 发现底部页面跟随滚动 但是产品不想要这种效果 于是找各种资料 发现很多说法 但是试了试 发现有的根本就不行 比如说有人提出用vue中提供的 touchmove prevent方法来解决 但是我试
  • 算法设计与分析——算法设计工具Standard Template Library即STL(C++模板库)概述

    算法设计工具 STL 前言 STL是一个功能强大的基于模板的容器库 通过直接使用这些现成的标准化组件可以大大提高算法设计的效率和可靠性 一 STL构成 Container 容器 Algorithm 算法 Iterator 迭代器 二 什么是
  • encoder decoder模型_Transformer 模型的 PyTorch 实现

    Google 2017年的论文 Attention is all you need 阐释了什么叫做大道至简 该论文提出了Transformer模型 完全基于Attention mechanism 抛弃了传统的RNN和CNN 我们根据论文的结
  • 【从零开始学c++】——类和对象(一)

    类和对象 面向过程和面向对象的初步认识 1 类的引入 1 1类的定义 1 2 类的两种定义方式 2 类的访问限定符及封装 2 1 访问限定符 2 2 class定义的类与struct定义的类的区别 2 3 封装 3 类的作用域 4 类的实例
  • 商业模式简单介绍

    商业模式 商业模式 1 B2C 企业对消费者 2 C2B 消费者 对企业 3 B2B 企业对企业 4 C2C 消费者 对消费者 5 o2o 线上线下 6 O2P营销模式 即Online To Place 是本地化的O2O营销模式 一 关联对
  • 1.编译时常量:const

    编译时常量只能在函数之外定义 就可以在编译期间初始了 不能定义在函数方法内 修饰符const不适用于 局部变量 const val PI 3 1415 定义编译时常量 TODO 10 Kotlin语言的编译时常量 编译时常量只能是常用的基本
  • SpringBoot项目多环境配置(亲测有效)

    SpringBoot项目多环境配置 SpringBoot项目在多环境配置上表现的非常优秀 只需要非常简单的操作就可以完成配置 一 认识配置文件 在创建项目后 会看到一个resources目录下有一个application propertie
  • React(6.5)路由系统

    路由系统 单页应用 SPA 的多页面切换 需要使用到路由功能 多个组件的路由和切换 使用路由 React中默认没有安装路由 需要手动安装 安装不指定版本默认是最新版本6 目前大多数项目可能还处于版本5 安装5版本npm install re
  • PCI 原理

    http baike baidu com link url sTevLlZN HI7Ls3 xbui2IvQBjNlTYst1MELXXmChISxZ55VMocg NdNwnCctbLa8RMIDWBw5PxY uvAxhUQ4E8vg8
  • 成功解决FileNotFoundError: [Errno 2] No such file or directory: 'C:\\Users\\DELL\\Anaconda3\\pkgs\\conda

    pycharm导入包总是报错如下 然后查了一下资料发现好像是源的问题 换个源试了一下好了 指令如下 pip install i https pypi tuna tsinghua edu cn simple trusted host pypi
  • Redis高级

    目录 redis介绍安装 介绍 安装 通用命令 五大数据类型 字符串 哈希 列表 集合 有序集合 高级用法 慢查询 pipline与事务 发布订阅 Bitmap HyperLogLog GEO地理位置信息 持久化 RDB方法 AOF方案 r
  • 地址映射与共享

    跟踪地址映射过程 1 通过命令 dbg asm启动调试器 在linux 0 11运行test c文件 使其进入死循环 我们的任务就是找到i的地址并将其修改为0使test c程序退出循环 2 在命令行输入crit c使Boch暂停 一般会显示