地址映射与共享

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(使用前将#替换为@)

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

  • GCC 4.7 字符串文字的源字符编码和执行字符编码?

    Linux x86 64 上的 GCC 4 7 是否具有默认字符编码 用于验证和解码 C 源文件中字符串文字的内容 这是可配置的吗 此外 当将字符串数据从字符串文字链接到输出的数据部分时 它是否具有默认的执行字符编码 这是可配置的吗 在任何
  • Amazon EC2 - Apache 服务器重启问题

    当我运行这个命令时 sudo etc init d httpd restart 它给出以下错误 停止 httpd 失败 启动 httpd 98 地址已在使用中 make sock 无法绑定到地址 80 98 地址已在使用 make sock
  • Google PubSub 在阻止和等待消息时没有标准输出

    我正在使用这个问题底部的 Python 代码监听 Google PubSub 消息 它实际上是来自 Google 的异步拉取示例 我运行我的程序并输出到文件 python my script py tee log txt 如果我在接收消息时
  • 使用正在运行的进程的共享内存收集核心转储

    核心转储仅收集进程空间 而不收集为进程间通信创建的共享内存 如何使核心转储也包含正在运行的进程的共享内存 设置核心文件过滤器 proc PID coredump filter per http man7 org linux man page
  • 使用多线程的套接字服务器或文件服务器实现:概念不清楚

    请帮我理清这个概念 假设我们有一个使用线程实现的套接字端口服务器 套接字服务器侦听套接字端口 并在消息到达时创建一个线程来服务该请求 客户端代码向服务器发送给定数量的消息 该客户端代码也可以由多个用户在不同的计算机上运行 我知道客户端代码作
  • 使用openssl从服务器获取证书

    我正在尝试获取远程服务器的证书 然后可以将其添加到我的密钥库中并在我的 Java 应用程序中使用 一位高级开发人员 正在度假 告诉我我可以运行这个 openssl s client connect host host 9999 获取转储的原
  • 什么是接口标识符

    我有一台笔记本电脑 使用一个或多个网络适配器连接到我组织的网络 我正在尝试编写一个工具来持续监控每个网络的连接状态和连接质量 然而 我的网络知识有限 术语让我感到困惑 特别是查找所有网络适配器 有人建议我使用命令ifconfig它给了我所谓
  • 如何重命名共享库以避免同名冲突?

    我找到了一个图书馆 libjson http sourceforge net projects libjson 我正在尝试将其构建为共享库并在项目中使用 建造很简单 修复 Makefile 错误后 SHARED 1 make install
  • 类似 wget 的 BitTorrent 客户端或库? [关闭]

    这个问题不太可能对任何未来的访客有帮助 它只与一个较小的地理区域 一个特定的时间点或一个非常狭窄的情况相关 通常不适用于全世界的互联网受众 为了帮助使这个问题更广泛地适用 访问帮助中心 help reopen questions 是否有任何
  • 在 Linux 2.6.21 (glibc 2.3.5) 上进行 ARP 和反向 ARP

    我需要在任意 IP 网络上存储对第三方设备的持久引用 其中设备的 IP 地址可能是静态的或由 DHCP 随机分配 我不控制网络上的设备 也不能依赖 DNS 和其他现有的或与设备一起使用的临时网络协议 所以我被指示使用硬件地址和 ARP 进行
  • Linux:通过网络进行屏幕桌面视频捕获和 VNC 帧速率

    抱歉 文字墙很长 TL DR VNC 连接的帧速率是多少 以帧 秒为单位 或者更确切地说 由谁决定 客户端还是服务器 对于桌面屏幕捕获的任何其他建议 但 正确的时间编码 具有不抖动的帧速率 具有稳定的周期 并有可能将其作为未压缩 或无损 图
  • 代码::块 - 警告:GDB:无法设置控制终端:不允许操作

    我已经通过官方存储库在 Ubuntu 14 04 中安装了 Code Blocks 13 12 当我编译时 一切正常 但是当我调试时 shell 中会显示以下消息 警告 GDB 无法设置控制终端 操作不正确 允许的 程序执行到断点 但当我执
  • 操作系统崩溃的常见原因[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我有兴趣了解 操作系统崩溃 不限于Windows崩溃 最常见的技术原因 从操作系统编程的角度 有哪些 我正在寻找一个不像 打开太多应用
  • 如何真正释放 Linux 中的大页面以供新进程使用?

    真的找不到太多关于此的信息 希望有人可以提供帮助 我正在假脱机使用 100GB java 堆作为大数据缓存 为了避免与文件系统缓存等内容发生冲突 并且因为它通常性能更好 我将其分配在大页面中 我保留了 51 200 x 2MB 大页面 一切
  • 如何使用sprof?

    请举例说明 从邮件中找到here http sources redhat com ml libc alpha 2003 07 msg00029 html and here http sourceware org ml binutils 20
  • 在单个命令中使用前缀重命名文件夹中的所有文件

    重命名带有前缀的文件夹中的所有文件 Unix 假设一个文件夹有两个文件 a txt b pdf 那么它们都应该从一个命令重命名为 Unix a txt Unix b pdf 如果您的文件名包含没有空格并且你没有任何子目录 你可以使用一个简单
  • bash双括号问题

    我对 bash 脚本非常陌生 在使用双括号时遇到了问题 我似乎无法让它们在 Ubuntu Server 11 10 中工作 我的下面的脚本位于 if test sh 中 bin bash if 14 14 then echo FOO fi
  • 在键盘热插拔上加载模块

    我正在尝试学习如何为 Linux 系统编写模块和驱动程序 类似于this https unix stackexchange com questions 120839 usb kernel module does not load on de
  • 是否可以找到哪个用户位于 localhost TCP 连接的另一端?

    这是一个编程问题 但它是 Linux Unix 特定的 如果我从本地主机获得 TCP 连接 是否有一种简单的方法可以告诉哪个用户在 C 程序内建立了连接而无需 shell 我知道这对于 Unix 域套接字来说并不太难 我已经知道远程 IP
  • 跟踪 pthread 调度

    我想做的是创建某种图表 详细说明 Linux 中 两个 线程的执行情况 我不需要查看线程的作用 只需查看它们何时被安排以及持续多长时间 基本上是一条时间线 在过去的几个小时里 我一直在互联网上搜索跟踪 pthread 调度的方法 不幸的是

随机推荐

  • 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暂停 一般会显示