在hack kernel的時候,遇到了GDT,GDT descriptor一共有64位,不同的位代表不同的含義。譬如它的值是0x00cf9a000000ffff,那麼具體每位代表什麼呢?
因此寫了個python工具,來解析一個數值每位的含義。文本格式如下:
gdtFmt = [
("0:15,48:51", "limit", "the whole limit"),
("16:31, 32:39, 56:63", "base address", "the whole base address"),
("0:15", "limit", "lower 16-bit limit"),
("16:31", "Base Address", "lower 16-bit base address"),
("32:39", "Base Address", "middle 8-bit base address"),
("40", "A", "access information, whether it was read from(=0) or written to(=1) by the last access"),
("41", "type", "for date/stack segment it can be written to (=1), for code segment it can be read from(=1)"),
("42", "type", "for date/stack segment it indicates expansion direction, it grows downside(=1), for code segment, confirming"),
("43", "type", "whether it is code segment(=1) or it is a date/stack segment(=0)"),
("44", "type", "must be 1 for code/data segment"),
("45:46", "DPL", "descriptor privilege level, we are going to use 0-kernel privilege and 3-user privilege"),
("47", "P", "whether the segment is present"),
("48:51", "Limit", "middle 8-bit limit"),
("52", "U", "user defined"),
("53", "X", "not used"),
("54", "D", "whether handle instructions and data as 32-bit(=1) or 16-bit(=0)"),
("55", "G", "whether the limitation use unit 4K or 1 byte"),
("56:63", "Base Address", "higher 8-bit base address")]
每項格式爲:(位域, 名稱, 描述),譬如 ("0:15,48:51", "limit", "the whole limit"),表示0到15位以及48到51位,表示的是這個描述符所代表的segment的總limit長度,所有格式放在一個python list裏面,對於輸入0x00cf9a000000ffff,輸出結果爲:
解析的數字位數:64, dec:58434644969848831, hex:cf9a000000ffff, bin:0000000011001111100110100000000000000000000000001111111111111111
bitRange:(0:15,48:51), b:11111111111111111111, d:1048575, h:0xfffff, name:limit, desc:the whole limit
bitRange:(16:31, 32:39, 56:63), b:00000000000000000000000000000000, d:0, h:0x0, name:base address, desc:the whole base address
bitRange:(0:15), b:1111111111111111, d:65535, h:0xffff, name:limit, desc:lower 16-bit limit
bitRange:(16:31), b:0000000000000000, d:0, h:0x0, name:Base Address, desc:lower 16-bit base address
bitRange:(32:39), b:00000000, d:0, h:0x0, name:Base Address, desc:middle 8-bit base address
bitRange:(40), b:0, d:0, h:0x0, name:A, desc:access information, whether it was read from(=0) or written to(=1) by the last access
bitRange:(41), b:1, d:1, h:0x1, name:type, desc:for date/stack segment it can be written to (=1), for code segment it can be read from(=1)
bitRange:(42), b:0, d:0, h:0x0, name:type, desc:for date/stack segment it indicates expansion direction, it grows downside(=1), for code segment, confirming
bitRange:(43), b:1, d:1, h:0x1, name:type, desc:whether it is code segment(=1) or it is a date/stack segment(=0)
bitRange:(44), b:1, d:1, h:0x1, name:type, desc:must be 1 for code/data segment
bitRange:(45:46), b:00, d:0, h:0x0, name:DPL, desc:descriptor privilege level, we are going to use 0-kernel privilege and 3-user privilege
bitRange:(47), b:1, d:1, h:0x1, name:P, desc:whether the segment is present
bitRange:(48:51), b:1111, d:15, h:0xf, name:Limit, desc:middle 8-bit limit
bitRange:(52), b:0, d:0, h:0x0, name:U, desc:user defined
bitRange:(53), b:0, d:0, h:0x0, name:X, desc:not used
bitRange:(54), b:1, d:1, h:0x1, name:D, desc:whether handle instructions and data as 32-bit(=1) or 16-bit(=0)
bitRange:(55), b:1, d:1, h:0x1, name:G, desc:whether the limitation use unit 4K or 1 byte
bitRange:(56:63), b:00000000, d:0, h:0x0, name:Base Address, desc:higher 8-bit base address
python代碼如下:
#-*-:coding: utf-8 -*-
import os, sys
class NumUtils:
def __init__(self):
None
def dec2x(self, decNum, base):
if decNum == 0:
return "0"
result = []
while decNum != 0:
remainder = decNum % base
result.append(remainder)
decNum = decNum / base
result.reverse()
retStr = ""
for i in range(len(result)):
retStr += str(result[i])
return retStr
def x2dec(self, xNumStr, base):
return int(xNumStr, base)
class BitFormatParser:
def __init__(self):
None
def Parse(self, num, fmt, bitLen):
numUtils = NumUtils()
binStr = numUtils.dec2x(num, 2)
binStrLen = len(binStr)
lenDiff = bitLen - binStrLen
if lenDiff < 0:
print "err: num len is longer than bitlen!"
return
"補上0"
for i in range(lenDiff):
binStr = "0" + binStr
print "解析的數字位數:%d, dec:%d, hex:%x, bin:%s" % (bitLen, num, num, binStr)
"幹活"
self.do(binStr, num, fmt)
def do(self, binStr, num, fmt):
for item in fmt:
(bitRange, name, description) = item
#print "bitRange:%s, name:%s, description:%s" % (bitRange, name, description)
reverseBinStr = self.ReverseStr(binStr)
(resBinStr, resDecStr, resHexStr) = self.Slice(reverseBinStr, num, bitRange)
print "bitRange:(%s), b:%s, d:%s, h:%s, name:%s, desc:%s/n" % (bitRange, resBinStr, resDecStr, resHexStr, name, description)
def ReverseStr(self, content):
res = ""
for i in range(len(content)):
res = content[i] + res
return res
def Slice(self, binStr, num, bitRange):
results = []
bits = bitRange.split(",")
for item in bits:
item = item.strip()
if item.find(":") != -1:
beginAndEnd = item.split(":")
begin = int(beginAndEnd[0])
end = int(beginAndEnd[1])
"有點像stl的iterator"
partBinStr = binStr[begin:(end+1)]
results.append(self.ReverseStr(partBinStr))
else:
partBinStr = binStr[int(item)]
results.append(partBinStr)
results.reverse()
resBinStr = ""
for i in range(len(results)):
resBinStr += results[i]
intDec = NumUtils().x2dec(resBinStr,2)
resDecStr = str(intDec)
resHexStr = hex(intDec)
return (resBinStr, resDecStr, resHexStr)
strategy = """
將數據轉變成位的字符串,然後依次取值,然後打印出來(值,name, description),值同時轉換成10進制和16進制
"""
if __name__ == "__main__":
"""0:3ver(low ver), 4:10ver(middle ver), 11:ver(highest bit ver)"""
f1 = [
("0:3", "ver", "low ver"),
("4:10", "ver", "middle ver"),
("11", "ver", "highest bit ver"),
("0:3, 4:10, 11", "ver", "the whole ver")]
numUtilsTest = False
if numUtilsTest:
numUtils = NumUtils()
str5 = numUtils.dec2x(5, 2)
str12 = numUtils.dec2x(12, 2)
print "str5:%s, str12:%s" % (str5, str12)
f1UnitTest = False
if f1UnitTest:
parser = BitFormatParser()
parser.Parse(5, f1, 12)
gdtFmt = [
("0:15,48:51", "limit", "the whole limit"),
("16:31, 32:39, 56:63", "base address", "the whole base address"),
("0:15", "limit", "lower 16-bit limit"),
("16:31", "Base Address", "lower 16-bit base address"),
("32:39", "Base Address", "middle 8-bit base address"),
("40", "A", "access information, whether it was read from(=0) or written to(=1) by the last access"),
("41", "type", "for date/stack segment it can be written to (=1), for code segment it can be read from(=1)"),
("42", "type", "for date/stack segment it indicates expansion direction, it grows downside(=1), for code segment, confirming"),
("43", "type", "whether it is code segment(=1) or it is a date/stack segment(=0)"),
("44", "type", "must be 1 for code/data segment"),
("45:46", "DPL", "descriptor privilege level, we are going to use 0-kernel privilege and 3-user privilege"),
("47", "P", "whether the segment is present"),
("48:51", "Limit", "middle 8-bit limit"),
("52", "U", "user defined"),
("53", "X", "not used"),
("54", "D", "whether handle instructions and data as 32-bit(=1) or 16-bit(=0)"),
("55", "G", "whether the limitation use unit 4K or 1 byte"),
("56:63", "Base Address", "higher 8-bit base address")]
gdtUnitTest = True
if gdtUnitTest:
parser = BitFormatParser()
parser.Parse(0x00cf9a000000ffff, gdtFmt, 64)
上面使用的是我已知的所有python知識來寫的,使用的是python2.5, 不是 3k版本。我的python代碼完全可以當作反面例子:)
當時寫這段代碼時身邊沒有網絡,也就不能google了。有一些問題當初沒有解決:
1. string的反轉有沒有系統api?
L[::-1]
http://www.python.org/doc/2.3.5/whatsnew/section-slices.html
2. 類的靜態成員變量和成員函數如何定義和使用?
#-*-:coding:utf-8-*-
2
3 class Test:
4 numInstances = 0
5 def __init__(self):
6 Test.numInstances += 1
7
8 def PrintNumInstances():
9 print "Number of instances:", Test.numInstances
10
11 PrintNumInstances = staticmethod(PrintNumInstances)
12
13 if __name__ == "__main__":
14 a = Test()
15 b = Test()
16 c = Test()
17
18 Test.PrintNumInstances()
19 a.PrintNumInstances()
20 b.PrintNumInstances()
3. 如何將一個str list裏的一行代碼就疊加起來
l = ['a', 'b', 'c', 'd']
print ''.join(l) => "abcd"
print ':".join(l) => "a:b:c:d"
4. 如何更方便的對list做循環操作
這點當初是想幹什麼的有點忘了