用户栈和核心栈的物理位置

大致思路:

一.先在gdb中设置断点到第二次进程调度后,查看0号和1号进程控制块的地址。再分别设置断点找到执行task0、0号进程执行sys_pause、执行task1、1号进程执行sys_pause四个时候的段寄存器ss和寄存器esp的值,这样就得到了用户/核心栈的逻辑地址:ss:esp,再查找对应的gdt或ldt即可计算出用户/核心栈的线性地址。

二.在终端找出schedule、task0、task1、sys_puase函数的地址,用于dbg调试。

三.在dbg中根据第一步计算的线性地址来查找相应的页目录和页表得到四个时候的物理地址。

实际上第一步得到线性地址后就可以直接在gdb里找出物理地址得到最终答案,这样方便得多。但平台会检测dbg的操作,个人感觉dbg不如gdb方便(除了能查看一些gdb不能查看的寄存器值),但为了通关不得不用它,用它又必须要gdb的协助,因此特别麻烦。

第一步

先调试到第二次进程调度后,查看0号和1号进程控制块的地址

(gdb)b schedule
(gdb)c
(gdb)c
(gdb)n
(gdb)p/x task

分别为0x1ea20,0xfff000 

关闭schedule处的断点,在task0处设置断点并跳转,通过current->pid可以找到当前是0号进程

(gdb)disable 2
(gdb)b task0
(gdb)c

然后查找段寄存器ss和寄存器esp的值(也可以直接p $ss和p $esp)

ss、esp寄存器值分别为0x17和0x2573c,所以用户栈栈顶的逻辑地址为0x17:0x0002573c。0x17化为二进制为10111,倒数第3位为1,应该查ldt,右移3位化为十进制为2,即索引为2,因此对应的段内偏移为0x00000000,所以用户栈栈顶的线性地址为0x00000000+0x0002573c=0002573c

同理,关闭在task0处断点,在sys_pause处设置断点并跳转,当前仍是0号进程,计算出核心栈线性地址为0x0001f9f0

(gdb)disable 3
(gdb)b sys_pause
(gdb)c

关闭在sys_pause处断点,在task1处设置断点并跳转,当前进程变为1号,计算出用户栈线性地址为0x0402573c

(gdb)disable 4
(gdb)b task1
(gdb)c

关闭在task1处断点,在sys_pause处设置断点并跳转,当前进程仍为1号,计算出用户栈线性地址为0x00ffffd0 

(gdb)disable 5
(gdb)b sys_pause
(gdb)c

 退出gdb

第二步

第三步 

打开dbg,跳到第二次进程调度后,删除在schedule处的断点,在task0处设置断点并跳转,使用sreg和reg来查找ss和esp寄存器的值(注意:虽然在gdb中已经找到,但平台会检测在dbg中是否显示,所以这一步不能省,后面三个也一样),然后根据线性地址查看页目录和页表来求出物理地址(具体方法参见之前的文章,不在赘述了)

<bochs:1> b 0x6d93
<bochs:2> c
<bochs:3> c
<bochs:4> n
<bochs:5> delete 1
<bochs:6> b 0x7963

 后面三个和第一步的gdb完全类似,先删除上一个断点,再设置新的,再查找

退出dbg 

最终结果如下 :

 

 

 

 

 

 

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值