戏说fs和fs:0

本文探讨fs 是否等于fs:0

fs是段选择子,16位。

fs:x 是段寻址,寻找到的地址为32位,此值为fs指向的段段内偏移x处的地址。

根据已知FS:0指向TEB

以此源码为例,windbg双调。

.386
.model flat,stdcall
option casemap:none

.code
start:
int 3
nop
nop
end start

windbg捕获断点

kd> !teb
TEB at 7ffde000
    ExceptionList:        0012ffe0
    StackBase:            00130000
    StackLimit:           0012e000
    SubSystemTib:         00000000
    FiberData:            00001e00
    ArbitraryUserPointer: 00000000
    Self:                 7ffde000
    EnvironmentPointer:   00000000
    ClientId:             00000404 . 00000528
    RpcHandle:            00000000
    Tls Storage:          00000000
    PEB Address:          7ffdf000
    LastErrorValue:       0
    LastStatusValue:      0
    Count Owned Locks:    0
    HardErrorMode:        0

为了dump 描述表GDT,查看GDTR寄存器,当然还有fs寄存器

kd> rm ?
       1 - Integer state (32-bit) or
       2 - Integer state (64-bit), 64-bit takes precedence
       4 - Floating-point state
       8 - Segment registers
      10 - MMX registers
      20 - Debug registers and, in kernel, CR4
      40 - SSE XMM registers
      80 - CR0, CR2 and CR3
     100 - Descriptor and task state

kd> rm 100|1
kd> r
eax=00000000 ebx=7ffdf000 ecx=0012ffb0 edx=7c92e4f4 esi=00360036 edi=00360033
eip=00401000 esp=0012ffc4 ebp=0012fff0 iopl=0         nv up ei pl zr na pe nc
gdtr=8003f000   gdtl=03ff idtr=8003f400   idtl=07ff tr=0028  ldtr=0000
001b:00401000 cc              int     3

查看fs寄存器

kd> .formats fs
Evaluate expression:
  Hex:     0000003b
  Decimal: 59
  Octal:   00000000073
  Binary:  00000000 00000000 00000000 00111011
  Chars:   ...;
  Time:    Thu Jan 01 08:00:59 1970
  Float:   low 8.26766e-044 high 0
  Double:  2.91499e-322

fs的结构划分:

按照intel文档的说明,最低的2位表示将要访问的段的权限级为0,第3位这里是0,表示将要访问的段的段描述符从全局描述符表(即GDT)里面取得,剩下的高13位是所为索引值用的

16位fs按照说明应该分为:(0000000000111)(0)(11)

对应结构为(高13位-GDT索引值) (第3位-段描述符获取位置) (低2位-段权限)

GDT中每个索引所占地址为qword

kd> r gdtr
gdtr=8003f000

kd> dw gdtr+7*8 l4
8003f038  0fff e000 f3fd 7f40

段描述符(qword)与段地址相关的部分:

第4个word的高8位为段起始地址的高8位,第3个word的低8位为段起始地址的高 8-15位,第2个word为段起始地址的低16位

cpu从后往前扫 7f40 取7f, f3fd取fd,e000取e000

我们关心的地址结构为:32bit=8+8+16=(7f)+(fd)+(e000)=7ffde000

kd> dq gdtr+7*8 l1
8003f038  7f40f3fd`e0000fff       7f-fd-e000
kd> dd 7ffde000 l1
7ffde000  0012ffe0
kd> !teb
TEB at 7ffde000
    ExceptionList:        0012ffe0
    StackBase:            00130000
    StackLimit:           0012e000
    SubSystemTib:         00000000
    FiberData:            00001e00
    ArbitraryUserPointer: 00000000
    Self:                 7ffde000
    EnvironmentPointer:   00000000
    ClientId:             00000404 . 00000528
    RpcHandle:            00000000
    Tls Storage:          00000000
    PEB Address:          7ffdf000
    LastErrorValue:       0
    LastStatusValue:      0
    Count Owned Locks:    0
    HardErrorMode:        0

也就是说:fs:0 的过程为:

1.寻找gdt起始地址 通过gdtr

2.通过fs寻找到在gdt中的地址, 以fs的高13位为索引,地址为gdtr+index*8

3.得到的地址存放的是段描述符,该描述符长度为QWORD。

4.得到fs:0地址。从段地址符中取出高8位+高24位~到低12位前 (8+24)

时间: 2024-08-29 21:04:48

戏说fs和fs:0的相关文章

Virtual Machine Kernel Panic : Not Syncing : VFS : Unable To Mount Root FS On Unknown-Block (0,0)

Virtual Machine Kernel Panic : Not Syncing : VFS : Unable To Mount Root FS On Unknown-Block (0,0) 33192 Share on FacebookShare on Twitter This issue appeared in the Linux virtual machines in the VMware environment after upgrading the guest os, Virtua

node中fs模块 - fs.open() fs.read() fs.write() fs.close()

var fs = require('fs') fs.open('./a.txt', 'a+', function(err, fd) { // 打开文件后 创建缓冲区放置数据 var readBuf = Buffer.alloc(1024), // 读取多少字节 bufOffset = 0, readbufLength = readBuf.length, filePosition = 50; // 提供缓冲区的第50个字节开始 // 读取文件 fs.read(fd, readBuf, bufOff

Node+fs+定时器(node-schedule)+MySql

目标:将本人写博客时候的截图保存到桌面的图片 执行保存到指定文件进行整理 并写入数据库 先看最终的目录结构: package.json文件: { "name": "zqz", "dependencies": { "mysql": "^2.10.2", "node-schedule": "^1.1.0" } } 通过npm install node-schedule -

Node.js文件模块fs监视文件变化

Node.js文件模块fs监视文件变化 Node中文件模块fs监视文件的函数源码如下: fs.watch = function(filename) { nullCheck(filename); var watcher; var options; var listener; if (util.isObject(arguments[1])) { options = arguments[1]; listener = arguments[2]; } else { options = {}; listen

node.js模块之fs文件系统

fs 模块是文件操作的封装,它提供了文件的读取.写入.更名.删除.遍历目录.链接等 POSIX 文件系统操作.与其他模块不同的是,fs 模块中所有的操作都提供了异步的和同步的两个版本, 例如读取文件内容的函数有异步的 fs.readFile() 和同步的fs.readFileSync().我们以几个函数为代表,介绍 fs 常用的功能,并列出 fs 所有函数的定义和功能. fs.readFile(filename,[encoding],[callback(err,data)])是最简单的读取文件的

nodejs 文件系统(fs) 删除文件夹 及 子文件夹下的所有内容

http://blog.163.com/hule_sky/blog/static/2091622452015112821829773/ node 文件系统fs 为我们提供了一些方法 进行文件和文件夹的读写删除等操作 下边将介绍删除文件夹及子文件夹下的所有内容的相关命令(均含有同步和异步方法) 1. fs.stat && fs.statSync 提供了访问文件的属性信息 2. fs.readdir && fs.readdirSync 提供读取文件目录信息 3. fs.unli

Node.js 初识 fs 模块

fs 模块是文件操作的封装,它提供了文件的读取.写入.更名.删除.遍历目录.链接等 Unix 文件系统操作.与其他模块不同的是,fs 模块中所有的操作都提供了 同步 和 异步 两个版本,比如读取文件内容的函数有 异步的 fs.readFile() 和 同步的 fs.readFileSync(). Node.js 导入文件系统模块的语法如下: var fs = require('fs'); 1.异步和同步读取文件 fs.readFile(file[, options], callback(err,

node.js的fs核心模块读写文件操作 -----由浅入深

node.js 里fs模块 常用的功能 实现文件的读写 目录的操作 - 同步和异步共存 ,有异步不用同步 - fs.readFile 都不能读取比运行内存大的文件,如果文件偏大也不会使用readFile方法- 文件大分流读取,stream - 引入fs模块 - let fs=require('fs') 同步读取文件 -fs.readFileSync('路径',utf8); let result=fs.readFileSync('./1.txt','utf8'); 异步读取文件,用参数err捕获错

nodeJS之fs文件系统

前面的话 fs文件系统用于对系统文件及目录进行读写操作,本文将详细介绍js文件系统 概述 文件 I/O 是由简单封装的标准 POSIX 函数提供的. 通过 require('fs') 使用该模块. 所有的方法都有异步和同步的形式. 异步形式始终以完成回调作为它最后一个参数. 传给完成回调的参数取决于具体方法,但第一个参数总是留给异常. 如果操作成功完成,则第一个参数会是 null 或 undefined //异步示例 var fs = require('fs'); fs.unlink('/tmp