Skip to content

Instantly share code, notes, and snippets.

@sparktrend
Created April 15, 2016 06:36
Show Gist options
  • Save sparktrend/4e0f3234449a4524b5a6f30b38d5ebea to your computer and use it in GitHub Desktop.
Save sparktrend/4e0f3234449a4524b5a6f30b38d5ebea to your computer and use it in GitHub Desktop.
from unicorn import *
from unicorn.x86_const import *
from struct import pack
# Constants
F_GRANULARITY = 0x8
F_PROT_32 = 0x4
F_LONG = 0x2
F_AVAILABLE = 0x1
A_PRESENT = 0x80
A_PRIV_3 = 0x60
A_PRIV_2 = 0x40
A_PRIV_1 = 0x20
A_PRIV_0 = 0x0
A_CODE = 0x18
A_DATA = 0x10
A_TSS = 0x0
A_GATE = 0x0
A_DATA_WRITABLE = 0x2
A_CODE_READABLE = 0x2
A_DIRECTION_UP = 0x0
A_DIRECTION_DOWN = 0x4
A_CONFORMING = 0x0
S_GDT = 0x0
S_LDT = 0x4
S_PRIV_3 = 0x3
S_PRIV_2 = 0x2
S_PRIV_1 = 0x1
S_PRIV_0 = 0x0
# What's maximum number of GDT entries?
MAX_GDT = 0x10
class IGdt(object):
def __init__(self, emu, gdt_address, gdt_size):
self.emu = emu
self.emu.mem_map(gdt_address, gdt_size)
self.emu.reg_write(UC_X86_REG_GDTR, (0, gdt_address, gdt_size, 0x0))
self.gdt_address = gdt_address
self.gdt_entry_count = 0
def create_selector(self, idx, flags):
to_ret = flags
to_ret |= idx << 3
return to_ret
def create_gdt_entry(self, base, limit, access, flags):
to_ret = limit & 0xffff;
to_ret |= (base & 0xffffff) << 16;
to_ret |= (access & 0xff) << 40;
to_ret |= ((limit >> 16) & 0xf) << 48;
to_ret |= (flags & 0xff) << 52;
to_ret |= ((base >> 24) & 0xff) << 56;
return pack('<Q',to_ret)
def CreateSegmentSelector(self, seg_reg, seg_addr, seg_size, access):
if self.gdt_entry_count < MAX_GDT:
gdtidx = self.gdt_entry_count+1 # Add a gdt entry from index 1 (because the first entry is reserved?)
gdt_entry = self.create_gdt_entry(seg_addr, seg_size, access, F_PROT_32)
self.emu.mem_write(self.gdt_address + 8*gdtidx, gdt_entry)
selector = self.create_selector(gdtidx, S_GDT | S_PRIV_3)
self.emu.reg_write(seg_reg, selector)
self.gdt_entry_count += 1
return selector
def Setup(self, teb):
ds = self.CreateSegmentSelector(UC_X86_REG_DS, 0x0, 0xffffffff, A_PRESENT | A_PRIV_3 | A_DATA | A_DATA_WRITABLE | A_DIRECTION_UP)
es = self.CreateSegmentSelector(UC_X86_REG_ES, 0x0, 0xffffffff, A_PRESENT | A_PRIV_3 | A_DATA | A_DATA_WRITABLE | A_DIRECTION_UP)
fs = self.CreateSegmentSelector(UC_X86_REG_FS, teb, 0xfff, A_PRESENT | A_PRIV_3 | A_DATA | A_DATA_WRITABLE | A_DIRECTION_UP) # FIXME: Correct the limit
gs = self.CreateSegmentSelector(UC_X86_REG_GS, 0x0, 0xffffffff, A_PRESENT | A_PRIV_3 | A_DATA | A_DATA_WRITABLE | A_DIRECTION_UP)
cs = self.CreateSegmentSelector(UC_X86_REG_CS, 0x0, 0xffffffff, A_PRESENT | A_PRIV_3 | A_CODE | A_CODE_READABLE | A_CONFORMING)
#ss = self.CreateSegmentSelector(UC_X86_REG_SS, 0x0, 0xffffffff, A_PRESENT | A_PRIV_3 | A_DATA | A_DATA_WRITABLE | A_DIRECTION_DOWN)
print ds, es, fs, gs, cs, ss
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment