cs 代碼段
ss 堆棧段
ds 數據段
es 擴展段
fs
gs
段選擇符
1. 索引 (3-16) 指向GDT/LDT中的段描述符的偏移
2. 表指示標志 (2)
3. 請求特權集 (0-1)
windbg 中 查看內存數據的指令
dd/dq/dw/db
eg:dd 0x1000 L4 查看內存中0x1000地址開始的4個DWORD數據
ES 0023
CS 001B
SS 0023
DS 0023
FS 003B
GS 0000
通過段選擇子 找到段描述符
段描述符就是給內存里的“段”貼上的一個“標簽”,告訴CPU:
在哪(Base),
多大(Limit+G),
誰可以訪問(DPL+S+Type),
是否在內存(P位)。
0000000000011(偏移) 0(表指示) 11(請求權限標志)
偏移 * 8 + GDT/LDT Address = 段描述符地址
GDT/LDT Address 通過 r gdtr 獲得
段描述符如下:00cffb00`0000ffff
解析:(31->0)
00(base1) c(G-D/B-0-AVL) f(limit1) f(P-DPL[2]-S) b(type) 00(base2) 0000(base3) ffff(limit2)
limit : fffff (從0開始 )
base : 00 00000
base :
s:1
DPL:11
P:1
G:1 (0代表limit的單位是字節,1代表limit的單位是頁)
D/B:1
0
AVL:0
(0xfffff+1) * 0x1000 -1 =0xffffffff = 4G-1
Fs:003b 找到段描述符:
00 40f3 000000 0fff
| 80 | 0 | 0 | 8 | b | b9 | 8c00 | 20ab |
|---|---|---|---|---|---|---|---|
| base1 | G D/B L AVL | limit1 | P DPL S | Type | base2 | base3 | limit2 |
80b98c00
020ab
Type:b
P DPL S 1 00 0
G D/B L AVL 0 0 0 0
段寄存器讀取的時候只能讀出16位
MOV AX,ES
讀寫LDTR的指令為:SLDT/LLDT
讀寫TR的指令為:STR/LTR
寫段寄存器 MOV DS.AX 寫時是96位
但是寫寄存器的時候是寫了96位
證明段寄存器是96位的?
寫段寄存器時,只給了16位,剩下的80位填什么?
struct segment{
WORD Selector;
DWORD Base;
DWORD Limit;
WORD Attribute;
}
GDT是全局進程共享的,不同的進程可以使用同一個段描述符,現代系統主要是利用段的權限控制,而不是用它來尋址,尋址是要頁基址
9035b800 0000000000000000 00cf9b000000ffff
9035b810 00cf93000000ffff 00cffb000000ffff
9035b820 00cff3000000ffff 90008b35bc0020ab
9035b830 9040933520004fff 0040f3000000c000
9035b840 0000f2000400ffff 0000000000000000
9035b850 90008935dd200067 90008935dcb00067
9035b860 0000000000000000 0000000000000000
9035b870 800092b9880003ff 0000000000000000
00cffb00`0000ffff
00000000 base
fffff linmit
c 1100 G D/B L AVL
b TYPE
f
除了MOV 指令還可以使用 LES,LSS,LDS,LFS,LGS指令修改段寄存器
CS不能通過 上述指令進行修改,cs為代碼段,cs的改變會導致EIP的改變
要改cs,必須要保證cs與EIP一起改
js解析段描述符
function resolve(segment){
function transform(segment){
let tmp = [];
segment.split("").forEach(function(item){
if(item != "`"){
tmp.push(item);
}
})
let str= ""
tmp.forEach(function(item){
str+= parseInt(item,16).toString(2).padStart(4,"0")
})
return str
}
segment = transform(segment)
segment = segment.split('').reverse().join('');
console.log(segment);
segment.split('').forEach((item,index)=>{
console.log(index+":"+item);
})
let type = segment.slice(32+8,32+12);
console.log(type,"type");
let base = segment.slice(16,32+8)+segment.slice(32+24,32+32)
console.log(base);
let limit = segment.slice(0,16)+segment.slice(32+16,32+20)
console.log(limit);
let G = segment.slice(32+23,32+24)
console.log(G);
let D = segment.slice(32+22,32+23)
console.log(D);
let L = segment.slice(32+21,32+22)
console.log(L);
let AVl = segment.slice(32+20,32+21)
console.log(AVl);
let P = segment.slice(32+15,32+16)
console.log(P);
let DPL = segment.slice(32+13,32+15)
console.log(DPL);
let S = segment.slice(32+12,32+13)
console.log(S);
let rtn = {
type:type.split("").reverse().join(""),
base:base.split("").reverse().join(""),
limit:limit.split("").reverse().join(""),
G:G.split("").reverse().join(""),
D_B:D.split("").reverse().join(""),
L:L.split("").reverse().join(""),
AVl:AVl.split("").reverse().join(""),
P:P.split("").reverse().join(""),
DPL:DPL.split("").reverse().join(""),
S:S.split("").reverse().join("")
}
return rtn;
}
let r = resolve("00cffb00`0000ffff")
console.log(JSON.stringify(r));
浙公網安備 33010602011771號