forked from BSB-WS23/mpstubs
210 lines
6.3 KiB
Python
210 lines
6.3 KiB
Python
|
|
||
|
from . import helper
|
||
|
|
||
|
class SegmentDescriptor(object):
|
||
|
pass
|
||
|
|
||
|
def __init__(self, memview):
|
||
|
assert (len(memview) > 7)
|
||
|
self.kind = '<generic descriptor>'
|
||
|
|
||
|
raw = int.from_bytes(memview[0:8], byteorder='little')
|
||
|
|
||
|
self.base = helper.bits(raw, 16, 24) \
|
||
|
| helper.bits(raw, 32 + 24, 8) << 24
|
||
|
|
||
|
self.limit = helper.bits(raw, 0, 16) \
|
||
|
| helper.bits(raw, 32 + 16, 4) << 16
|
||
|
|
||
|
self.type = helper.bits(raw, 32 + 8, 4)
|
||
|
|
||
|
self.g = helper.bits(raw, 32 + 23, 1)
|
||
|
self.p = helper.bits(raw, 32 + 15, 1)
|
||
|
self.l = helper.bits(raw, 32 + 21, 1)
|
||
|
self.dpl = helper.bits(raw, 32 + 13, 2)
|
||
|
pass
|
||
|
|
||
|
def create(memview):
|
||
|
raw = int.from_bytes(memview[0:8], byteorder='little')
|
||
|
feature = helper.bits(raw, 32 + 11, 2)
|
||
|
if feature == 2:
|
||
|
return DataSegmentDescriptor(memview)
|
||
|
elif feature == 3:
|
||
|
return CodeSegmentDescriptor(memview)
|
||
|
else:
|
||
|
feature = helper.bits(raw, 32 + 8, 5)
|
||
|
if feature == 0x00:
|
||
|
return NullDescriptor(memview)
|
||
|
elif feature == 0x0f:
|
||
|
return CallGateDescriptor(memview)
|
||
|
else:
|
||
|
return SystemSegmentDescriptor.create(memview)
|
||
|
pass
|
||
|
|
||
|
def __str__(self):
|
||
|
verbose = self.str_verbose()
|
||
|
return f"<{self.kind}> 0x{self.base:x}:{self.limit:x} [{verbose}]"
|
||
|
if verbose:
|
||
|
return f"<{self.kind}> 0x{self.base:x}:{self.limit:x} [{verbose}]"
|
||
|
else:
|
||
|
return f"<{self.kind}> 0x{self.base:x}:{self.limit:x}"
|
||
|
|
||
|
def size(self):
|
||
|
return None
|
||
|
|
||
|
class DataSegmentDescriptor(SegmentDescriptor):
|
||
|
def __init__(self, memview):
|
||
|
super(DataSegmentDescriptor, self).__init__(memview)
|
||
|
self.kind = 'data'
|
||
|
|
||
|
self.raw = int.from_bytes(memview[0:8], byteorder='little')
|
||
|
|
||
|
self.b = helper.bits(self.raw, 32 + 22, 1)
|
||
|
self.avl = helper.bits(self.raw, 32 + 20, 1)
|
||
|
|
||
|
self.e = helper.bits(self.raw, 32 + 10, 1)
|
||
|
self.w = helper.bits(self.raw, 32 + 9, 1)
|
||
|
self.a = helper.bits(self.raw, 32 + 8, 1)
|
||
|
|
||
|
def str_verbose(self):
|
||
|
msg = "|".join([
|
||
|
f"g{self.g}", f"b{self.b}", f"l{self.l}",
|
||
|
f"avl{self.avl}", f"p{self.p}", f"dpl{self.dpl}",
|
||
|
f"e{self.e}", f"w{self.w}", f"a{self.a} {self.raw:x}"
|
||
|
])
|
||
|
if self.l:
|
||
|
msg = msg + '"invalid l"'
|
||
|
pass
|
||
|
return msg
|
||
|
|
||
|
def size(self):
|
||
|
return 8
|
||
|
|
||
|
class CodeSegmentDescriptor(SegmentDescriptor):
|
||
|
def __init__(self, memview):
|
||
|
super(CodeSegmentDescriptor, self).__init__(memview)
|
||
|
self.kind = 'code'
|
||
|
|
||
|
self.raw = int.from_bytes(memview[0:8], byteorder='little')
|
||
|
|
||
|
self.d = helper.bits(self.raw, 32 + 22, 1)
|
||
|
self.avl = helper.bits(self.raw, 32 + 20, 1)
|
||
|
|
||
|
self.c = helper.bits(self.raw, 32 + 10, 1)
|
||
|
self.r = helper.bits(self.raw, 32 + 9, 1)
|
||
|
self.a = helper.bits(self.raw, 32 + 8, 1)
|
||
|
|
||
|
def size(self):
|
||
|
return 8
|
||
|
|
||
|
def str_verbose(self):
|
||
|
return "|".join([
|
||
|
f"g{self.g}", f"d{self.d}", f"l{self.l}",
|
||
|
f"avl{self.avl}", f"p{self.p}", f"dpl{self.dpl}",
|
||
|
f"c{self.c}", f"r{self.r}", f"a{self.a}", f"{self.raw:x}"
|
||
|
])
|
||
|
|
||
|
class SystemSegmentDescriptor(SegmentDescriptor):
|
||
|
|
||
|
def __init__(self, memview):
|
||
|
super(SystemSegmentDescriptor, self).__init__(memview)
|
||
|
self.kind = 'system'
|
||
|
self.raw = int.from_bytes(memview[0:16], byteorder='little')
|
||
|
pass
|
||
|
|
||
|
def create(memview):
|
||
|
raw = int.from_bytes(memview[0:8], byteorder='little')
|
||
|
type = helper.bits(raw, 32 + 8, 4)
|
||
|
masks = [(TSSDescriptor, 0x9)]
|
||
|
for ctor, mask in masks:
|
||
|
if type & mask == mask:
|
||
|
return ctor(memview)
|
||
|
pass
|
||
|
else:
|
||
|
raise Exception("no matching Descriptor")
|
||
|
pass
|
||
|
|
||
|
def size(self):
|
||
|
return 16
|
||
|
|
||
|
def str_verbose(self):
|
||
|
return f"raw: {self.raw}"
|
||
|
|
||
|
class TSSDescriptor(SystemSegmentDescriptor):
|
||
|
|
||
|
def __init__(self, memview):
|
||
|
super(SystemSegmentDescriptor, self).__init__(memview)
|
||
|
self.kind = 'tss'
|
||
|
self.raw = int.from_bytes(memview[0:16], byteorder='little')
|
||
|
|
||
|
self.type = helper.bits(self.raw, 32 + 8, 4)
|
||
|
|
||
|
self.base = helper.bits(self.raw, 16, 24) \
|
||
|
| helper.bits(self.raw, 32 + 24, 8) << 24 \
|
||
|
| helper.bits(self.raw, 64, 32) << 32
|
||
|
|
||
|
self.avl = helper.bits(self.raw, 32 + 20, 1)
|
||
|
|
||
|
self.null = helper.bits(self.raw, 3 * 32 + 8, 5)
|
||
|
self.reserved_a = helper.bits(self.raw, 3 * 32 + 13, 32 - 13)
|
||
|
self.reserved_b = helper.bits(self.raw, 3 * 32, 8)
|
||
|
assert (self.null == 0)
|
||
|
|
||
|
def str_verbose(self):
|
||
|
b = helper.bits(self.raw, 32 + 22, 1)
|
||
|
e = helper.bits(self.raw, 32 + 12, 1)
|
||
|
msg = "|".join([
|
||
|
f"rsvd: {self.reserved_a}", f"0: {self.null}",
|
||
|
f"rsvd: {self.reserved_b}" f"g: {self.g}",
|
||
|
f"0{b}", f"0{self.l}", f"avl{self.avl}",
|
||
|
f"p{self.p}", f"dpl{self.dpl}", f"0{e}",
|
||
|
f"type: {self.type:x}", f"{self.raw:x}"
|
||
|
])
|
||
|
return msg
|
||
|
|
||
|
class NullDescriptor(SystemSegmentDescriptor):
|
||
|
def __init__(self, memview):
|
||
|
super(NullDescriptor, self).__init__(memview)
|
||
|
self.kind = 'call gate'
|
||
|
self.kind = 'null'
|
||
|
self.raw = int.from_bytes(memview[0:8], byteorder='little')
|
||
|
pass
|
||
|
|
||
|
def size(self):
|
||
|
return 8
|
||
|
|
||
|
def str_verbose(self):
|
||
|
return f"{self.raw:x}"
|
||
|
|
||
|
class CallGateDescriptor(SystemSegmentDescriptor):
|
||
|
def __init__(self, mems):
|
||
|
super(CallGateDescriptor, self).__init__(mems)
|
||
|
self.kind = 'call gate'
|
||
|
pass
|
||
|
pass
|
||
|
|
||
|
class GDT:
|
||
|
def __init__(self, mmu, mapping, base, limit):
|
||
|
self.mmu = mmu
|
||
|
self.mapping = mapping
|
||
|
self.limit = limit
|
||
|
self.base = base
|
||
|
pass
|
||
|
|
||
|
def print(self):
|
||
|
offset = 0
|
||
|
print(f"base: 0x{self.base:x}, limit: 0x{self.limit:x}")
|
||
|
while offset < self.limit + 1:
|
||
|
|
||
|
desc_bytes = self.mmu.linear_bytes(
|
||
|
self.mapping,
|
||
|
self.base + offset,
|
||
|
16
|
||
|
)
|
||
|
|
||
|
segment = SegmentDescriptor.create(desc_bytes)
|
||
|
print(f"[0x{offset:x}]: {str(segment)}")
|
||
|
offset += segment.size()
|
||
|
pass
|
||
|
pass
|