Access denied!
Warning: Cannot modify header information - headers already sent by (output started at /homepages/19/d27199060/htdocs/typo3/fileadmin/j-asm/download.php:4) in /homepages/19/d27199060/htdocs/typo3/fileadmin/j-asm/download.php on line 9
#!/usr/bin/python2 #
# Copyright (c) 2012 Jakob Heinemann 

from util import chexdump, hexdump, pad
from struct import unpack, pack
from sys import exit

base = 0x00000000
addressbase = 0x00000000
codebase = 0x00000000
codesize = 0
database = 0x00000000
datasize = 0
bitmode = 64
debugmode = False
verbose = False
withrawdata = False
#_unanalysedCalls=[]

calltables = {}

def debug(string1, string2="", string3=""):
    if debugmode: print string1, string2, string3
def loud(string1, string2="", string3=""):
    if verbose: print string1, string2, string3

def getIMM(p, data, off):
    if p.word:
        if p.sizeOverride:
            p.length+=2
            return unpack("> 6
        self.index = (byte & 0x38) >> 3
        self.base  = (byte & 0x07)
    def __repr__(self):
        rindex = 0
        if self.op.modrm.mod == 0:
            rindex = -2
        if self.op.rex:
            self.r1 = SIBREGS[64+rindex+self.op.rex.B][self.base]
            self.r2 = SIBREGS[66+self.op.rex.X][self.index]
        else:
            self.r1 = SIBREGS[bitmode+rindex][self.base]
            self.r2 = SIBREGS[bitmode+2][self.index]
        if not self.r1.find("disp"):
            self.r1reg = self.r1
        if not self.r2.find("disp"):
            self.r2reg = self.r2
        if self.r1.find("*s"):
            repl = ""
            if self.scale:
                self.r1scale = 2**self.scale
                repl = "*"+str(self.r1scale)
            self.r1reg = self.r1.replace("*s", "")
            self.r1 = self.r1.replace("*s", repl)
        if self.r2.find("*s"):
            repl = ""
            if self.scale:
                self.r2scale = 2**self.scale
                repl = "*"+str(self.r2scale)
            self.r2reg = self.r2.replace("*s", "")
            self.r2 = self.r2.replace("*s", repl)
        debug("SIBr1: %s"%self.r1)
        debug("SIBr2: %s"%self.r2)
        debug(str(self))
        if self.r2:
            return self.r1+"+"+self.r2
        else:
            return self.r1
    def __str__(self):
        return "SIB{scale:%d index:%d base:%d, r1=%s, r2=%s}"%(self.scale,self.index,self.base, self.r1, self.r2)

def getExt(byte): return (ord(byte) & 0x38) >> 3

class modRM():
    mod = 0
    reg = 0
    rm = 0
    sOp = None
    tOp = None
    byte = None
    ext = None
    isExt = False
    sib = None
    length = 0
    mem_imm = None
    mem_imm_isPtr = False
    def __str__(self):
        if self.sib:
            sibstr = " "+str(self.sib)
        else:
            sibstr = ""
        return "MODRM%s: reg=%s, rm=%s%s"%([""," isExt"][self.isExt], self.regstr, self.rmstr, sibstr) 
    def __init__(self, op, data=None, off=0, isExt = False, opbits=0, addressbits=0):
        op.modrm = self        
        self.isExt = isExt
        if data == None:
            return
        byte = ord(data[off])
        self.length = 0-op.length
        debug("OpLen: %d"%op.length)
        off += 1
        op.length += 1
        self.mod = (byte & 0xc0) >> 6
        self.ext = (byte & 0x38) >> 3
        self.reg = self.ext
        self.rm  = (byte & 0x07)
        self.regstr = "INVALID"
        self.rmstr  = "INVALID"
        if not opbits:
            if op.sizeOverride:
                opsize = 16
            else:
                opsize = 8 << (op.word*2) 
        else: opsize = opbits        
        if not addressbits: addresssize = bitmode
        else: addresssize = addressbits
        regti = opsize
        regsi = addresssize
        if self.mod == 3:
            regti = regsi = opsize
        debug("WordMode:",op.word)
        debug("SizeOverride:",op.sizeOverride)
        debug("Mode: %d"%(self.mod))
        if op.rex:
            debug(op.rex)
            if op.rex.W:
                if not op.sizeOverride:
                    opsize = 64
                    regsi = 64
                regti = 64
            if op.rex.R:
                regti += 4
            if op.rex.B:
                regsi += 4
        regti += 3
        regsi += self.mod

        self.rmstr = REGS[regsi][self.rm]
        if not isExt:
            self.regstr = REGS[regti][self.reg]
        ptrstr = PTRSTR[opsize/8]
        debug(ptrstr)
        debug("reg: %s, rm: %s"%(self.regstr, self.rmstr))        
        if self.rmstr:
            rip = False
            if self.rmstr.find("RIP") >= 0:
                rip = True
                self.rmstr = self.rmstr.replace("RIP", "")
            if self.rmstr.find("SIB") >= 0:
                self.sib = SIB(op,data,off)
                self.rmstr=self.rmstr.replace("SIB", repr(self.sib))
                off += 1
                op.length+=1
            if self.rmstr.find("disp8")>-1:
                self.mem_imm = unpack("= 0:
                if rip:
                    self.mem_imm = base+off+4+unpack("=0],self.mem_imm)
            off += 1
            op.length+=1
        elif self.mod == 2:
            self.mem_imm_isPtr = True
            self.mem_imm = unpack("=0],self.mem_imm)
            off += 4
            op.length+=4
        if isExt:
            self.tOp = self.rmstr
        elif op.direction:
            self.tOp = self.regstr
            self.sOp = self.rmstr
        else:
            self.sOp = self.regstr
            self.tOp = self.rmstr
        self.length += op.length
        debug("OpLen: %d, modRM-Len: %d"%(op.length, self.length))

class pre():
    is64 = False
    name = ""
    def __repr__(self): return ""
    def __str__(self): return ""
    
class preREP(pre):
    name = ""
    def __init__(self, data, off):
        self.name = "REP"
    def __repr__(self):
        return "rep"

class preREX(pre):
    name = "REX"
    opCodes = {
    0x40:"",
    0x41:"B",
    0x42:"X",
    0x43:"XB",
    0x44:"R",
    0x45:"RB",
    0x46:"RX",
    0x47:"RXB",
    0x48:"W",
    0x49:"WB",
    0x4A:"WX",
    0x4B:"WXB",
    0x4C:"WR",
    0x4D:"WRB",
    0x4E:"WRX",
    0x4F:"WRXB",
    }    
    R = 0
    B = 0
    W = 0
    X = 0
    def __init__(self, data, off):
        r = self.opCodes[ord(data[off])]
        self.W = "W" in r
        self.B = "B" in r
        self.X = "X" in r
        self.R = "R" in r
    def __str__(self):
        return "REX{R:%d X:%d W:%d B:%d}"%(self.R,self.X,self.W,self.B)

class preTB(pre):
    name = "TB"
    def __init__(self, data, off):
        pass
    def __str__(self):
        return "TB{}"
class preSIZE(pre):
    name = "SIZE"
    def __init__(self, data, off):
        pass
    def __str__(self):
        return "SIZE{}"

class op():
    comment = ""
    length = 1
    rawdata = None
    op = None
    modrm = None
    data = None
    name = "None"
    offset = 0x00000000
    rex = None
    sizeOverride = 0
    isTwoByte=0
    direction = 1
    word = 1
    rep = 0
    def __init__(self, data, off, proc=None):
        self.offset = off
        startoff = off
        byte = ord(data[off])
        while byte in PREFIXES and not self.isTwoByte:
            prefixCls = PREFIXES[byte]
            p = prefixCls(data, off)
            if p.name == "REP":
                self.rep = 1
            if p.name == "TB":
                self.isTwoByte = 1
            elif p.name == "REX":
                self.rex = p
            elif p.name == "SIZE":
                self.sizeOverride = 1
            debug("Prefix found: %s"%p.name)
            off += 1
            self.length += 1
            byte = ord(data[off])
        self.direction = (byte & 2) >> 1
        self.word = (byte & 1)
        if self.isTwoByte:
            if byte in OPCODES_TB:
                OPCODES_TB[byte](self, data, off, proc)
        else:
            if byte in OPCODES:
                OPCODES[byte](self, data, off, proc)
        if self.op == None:
            print "OpCode not implemented: %s0x%X"%(["","0x0F "][self.isTwoByte], byte)
            exit(-2)
        if withrawdata:
            self.rawdata = data[startoff:startoff+self.length]
        print self
    def __repr__(self):
        return str(self)
    def __str__(self):
        repstring = ""
        if self.modrm != None:
            if self.modrm.sOp:
                repstring = "%s, %s"%(self.modrm.tOp, self.modrm.sOp)
            else:
                repstring = "%s"%self.modrm.tOp
        if self.data != None:
            if repstring != "": repstring += ", "
            repstring += self.data
        if withrawdata:
            hexdata = pad(hexdump(self.rawdata,' ')," ",32)
        else:
            hexdata = ""
        if self.comment: repstring = pad(repstring, " ", 32) + ";"+self.comment
        return "0x%08X: %s%s%s %s"%(base + self.offset, hexdata, ["","rep "][self.rep], self.name, repstring)

class opInvalid():
    def __init__(self, p, data,off, proc=None):
        p.name = "invalid"        
        assert True

class opNull():
    def __init__(self, p, data,off, proc=None):
        p.name = "null"        
        p.op = ord(data[off])        

class opRet():
    def __init__(self, p, data, off, proc=None):
        p.name = "ret"
        p.op = ord(data[off])

class opTest():
    def __init__(self, p, data, off, proc=None):
        p.name = "test"        
        p.op = ord(data[off])
        off += 1
        p.direction = 1
        p.modrm = modRM(p, data, off)
class opTestA():
    def __init__(self, p, data, off, proc=None):
        p.name = "test"        
        p.op = ord(data[off])
        off += 1
        setAX_imm_mem(p, data, off, True)

class opInt3():
    def __init__(self, p, data, off, proc=None):
        p.name = "Int 3"        
        p.op = ord(data[off])

class opGroupJMP():
    def __init__(self, p, data, off, proc=None):
        opnames = ["jo", "jno", "jb", "jnb", "jz", "jnz", "jbe", "ja", "js", "jns", "jp", "jnp", "jl", "jnl", "jle", "jg"]
        p.op = ord(data[off])
        off += 1
        p.name = opnames[p.op&0x0F]
        jump = (base + off + (1<<(p.isTwoByte*2)) + unpack("<%s"%(["b","l"][p.isTwoByte]),data[off:off+(1<<(p.isTwoByte*2))])[0])
        p.data = "0x%08X"%jump
        p.length += (1<<(p.isTwoByte*2))
        if proc and proc._lastjump < jump:            
            proc._lastjump = jump
class opGroupMOV():
    def __init__(self, p, data, off, proc=None):
        opnames = ["cmov0", "cmovn0", "cmovb", "cmovnb", "cmovz", "cmovnz", "cmovbe", "cmova", "cmovs", "cmovns", "cmovp", "cmovnp", "cmovl", "cmovnl", "cmovle", "cmovg"]
        p.op = ord(data[off])
        off += 1
        p.name = opnames[p.op&0x0F]
        p.modrm = modRM(p, data, off)
class opGroupSET():
    def __init__(self, p, data, off, proc=None):
        opnames = ["set0", "setn0", "setb", "setnb", "setz", "setnz", "setbe", "seta", "sets", "setns", "setp", "setnp", "setl", "setnl", "setle", "setg"]
        p.op = ord(data[off])
        p.word = 0
        off += 1
        p.name = opnames[p.op&0x0F]
        p.modrm = modRM(p, data, off, True)

class opLea():
    def __init__(self, p, data, off, proc=None):
        p.name = "lea"        
        p.op = ord(data[off])
        off += 1
        p.direction = 1
        self.modrm = modRM(p, data, off)

class opXOR():
    def __init__(self, p, data, off, proc=None):
        p.name = "xor"        
        p.op = ord(data[off])
        off += 1
        if p.op & 4: 
            setAX_imm_mem(p, data, off)
        else:
            p.modrm = modRM(p, data, off)

class opMov(op):
    def __init__(self, p, data, off, proc=None):
        p.name = "mov"   
        p.op = ord(data[off])
        off += 1
        p.modrm = modRM(p, data, off, False)
        if not p.modrm.mem_imm_isPtr:
            sm.setReg(p.modrm.tOp, p.modrm.mem_imm)
        if proc and p.modrm.mem_imm_isPtr:
            c = p.modrm.mem_imm
            if c > base and c < (base+codesize):
                self.callbacks.append(c)

class opMovA(op):
    def __init__(self, p, data, off, proc=None):
        p.name = "mov"   
        p.op = ord(data[off])
        off += 1
        setAX_imm_mem(p, data, off)
        if not p.modrm.mem_imm_isPtr:
            sm.setReg(p.modrm.tOp, p.modrm.mem_imm)
        if proc and p.modrm.mem_imm_isPtr:
            c = p.modrm.mem_imm
            if c > base and c < (base+codesize):
                self.callbacks.append(c)

class opMovRB(op):
    def __init__(self, p, data, off, proc=None):
        p.name = "mov"   
        p.op = ord(data[off])
        off += 1
        p.modrm = modRM(p)
        p.modrm.tOp = REGS[8][p.op-0xB0]
        p.modrm.mem_imm = ord(data[off])
        sm.setReg(p.modrm.tOp, p.modrm.mem_imm)
        p.modrm.sOp = "%02Xh"%p.modrm.mem_imm
        p.length += 1
class opMovRW(op):
    def __init__(self, p, data, off, proc=None):
        p.name = "mov"
        p.op = ord(data[off])
        off += 1
        p.modrm = modRM(p)
        regindex = 32+3
        if p.sizeOverride:
            regindex = 16+3
            p.modrm.mem_imm = unpack(" 32 and p.name in ["jmp","call","push"]:
            p.modrm = modRM(p, data, off, True, bitmode)
        else:
            p.modrm = modRM(p, data, off, True)
        #calltables
        if p.modrm.mem_imm_isPtr:
            c = p.modrm.mem_imm
            if p.name in ["jmp", "call"]:
                if c > base and c < (base+codesize):
                    if p.modrm.sib:
                        entrycount = sm.getCmp(p.modrm.sib.r2reg)
                        if entrycount: 
                            entrycount += 1
                            entrysize = p.modrm.sib.r2scale
                            size = entrysize * entrycount
                            if not c in calltables.keys():
                                calltables[c] = [size, p.modrm.sib.r2scale, entrycount]
                            loud("Found calltable at 0x%08X"%c)
                            loud("%d elements of size %d (total calltable size: %d)"%(entrycount, entrysize, size))
                else:
                    p.comment = "cannot follow call/jmp (external?)"

class opCONVERT(op):
    def __init__(self, p, data, off, proc=None):
        p.op = ord(data[off])
        off += 1
        p.modrm = modRM(p)
        if p.rex:
            p.name = ["cdqe","cqo"][p.op&1]
            p.modrm.sOp=REGS[32][(p.op&1)<<1]
            p.modrm.tOp=REGS[64][0]
        elif p.sizeOverride:
            p.name = ["cbw","cwd"][p.op&1]
            p.modrm.sOp=REGS[8][(p.op&1)<<1]
            p.modrm.tOp=REGS[16][0]
        else:
            p.name = ["cwde","cdq"][p.op&1]
            p.modrm.sOp=REGS[16][(p.op&1)<<1]
            p.modrm.tOp=REGS[32][0]

class opMOVZX(op):
    def __init__(self, p, data, off, proc=None):
        p.name = "movzx"   
        p.op = ord(data[off])
        off += 1
        p.direction = 1
        p.modrm = modRM(p, data, off, False, 8 << p.word)
class opMOVSX(op):
    def __init__(self, p, data, off, proc=None):
        p.name = "movsx"   
        p.op = ord(data[off])
        off += 1
        p.direction = 1
        p.modrm = modRM(p, data, off, False, 8 << p.word)

class opGroup80(op):
    def __init__(self, p, data, off, proc=None):
        opnames = ["add", "or", "adc", "sbb", "and", "sub", "xor", "cmp"]
        p.op = ord(data[off])
        off += 1
        p.modrm = modRM(p, data, off, True)
        p.name = opnames[p.modrm.ext]
        value = ord(data[off+p.modrm.length])
        p.modrm.sOp = "%Xh"%value
        p.length += 1
        if p.name == "cmp":
            sm.setCmp(p.modrm.tOp, value)
class opGroup81(op):
    def __init__(self, p, data, off, proc=None):
        opnames = ["add", "or", "adc", "sbb", "and", "sub", "xor", "cmp"]
        p.op = ord(data[off])
        off += 1
        p.modrm = modRM(p, data, off, True)
        p.name = opnames[p.modrm.ext]
        if not (p.op & 2):
            value = unpack("<%s"%(["L","H"][p.sizeOverride]), data[off+p.modrm.length:off+p.modrm.length+(4>>p.sizeOverride)])
            p.modrm.sOp = "%Xh"%value
            p.length += (4>>p.sizeOverride)
        else:
            value = ord(data[off+p.modrm.length])
            p.modrm.sOp = "%Xh"%value
            p.length += 1
        if p.name == "cmp":
            sm.setCmp(p.modrm.tOp, value)
#class opGroup83(): moved to group81
#    def __init__(self, p, data, off, proc=None):
#        opnames = ["add", "or", "adc", "sbb", "and", "sub", "xor", "cmp"]        
#        p.op = ord(data[off])
#        off += 1
#        p.modrm = modRM(p, data, off, True)
#        p.name = opnames[p.modrm.ext]
#        p.modrm.sOp = "%Xh"%ord(data[off+p.modrm.length])
#        p.length += 1
class opGroupSHIFT(op):
    def __init__(self, p, data, off, proc=None):
        opnames = ["rol", "ror", "rcl", "rcr", "shl", "shr", "sal", "sar"]
        p.op = ord(data[off])
        off += 1
        p.modrm = modRM(p, data, off, True)
        p.name = opnames[p.modrm.ext]
        off += p.modrm.length
        if p.op&0xF0 == 0xC0:
            p.modrm.sOp = "%Xh"%ord(data[off])
            p.length += 1
        elif p.op&0xF2 == 0xD2:
            p.modrm.sOp = REGS[8][1]

class opGroupD8(op):
    def __init__(self, p, data, off, proc=None):
        opnames = ["fadd", "fmul", "fcomp", "fsub", "fsubr", "fdiv", "fdivr"]
        p.op = ord(data[off])
        off += 1
        p.modrm = modRM(p, data, off)
        p.name = opnames[p.modrm.ext]
        print "groupD8 not fully implemented!"
        assert False
        p.data = "0x%08X"%(base + off + 4 + unpack(" base and c < (base+codesize):
            if not p.modrm.mem_imm_isPtr:
                if proc:
                    proc.callees.append(c)
            else:
                loud("Found possible calltable at 0x%08X"%c)
                loud("Calltables not implemented yet!")
        else:
            loud("External function call at 0x%08X"%c)

class opGroupF6(op):
    def __init__(self, p, data, off, proc=None):
        opnames = ["test", "test", "not", "neg", "mul", "imul", "div", "idiv"]
        p.op = ord(data[off])
        off += 1
        p.modrm = modRM(p, data, off, True)
        p.name = opnames[p.modrm.ext]
        off += p.modrm.length
        if p.name == "test":
            p.modrm.sOp = "%Xh"%getIMM(p, data, off)
        elif p.name in ["not","neg"]:
            pass
        else:
            p.comment = "<-- CHECK THIS! GroupF6 not fully implemented!"
            pass

class opJmp(op):
    def __init__(self, p, data, off, proc=None):
        p.name = "jmp"   
        p.op = ord(data[off])
        off += 1
        p.data = "0x%08X"%(base + off + unpack(">p.sizeOverride)][0]
        else:
            p.modrm.sOp = REGS[16+3][2]
            p.modrm.tOp = REGS[(8<<(p.word*2)>>p.sizeOverride)][0]

class opIMUL(op):
    def __init__(self, p, data, off, proc=None):
        p.name = "imul"
        p.op = ord(data[off])
        off += 1
        p.modrm = modRM(p, data, off)
        off += p.modrm.length
        if not p.isTwoByte:
            if p.op == 0x69:
                opsize = bitmode>>4
                p.modrm.sOp = "%Xh"%(unpack(FRMSTR[opsize],(data[off:off+opsize]))[0])
                p.length += opsize
            else:
                p.modrm.sOp = "%Xh"%ord(data[off])
                p.length += 1

PREFIXES = {
0x0F:preTB,
0x40:preREX,
0x41:preREX,
0x42:preREX,
0x43:preREX,
0x44:preREX,
0x45:preREX,
0x46:preREX,
0x47:preREX,
0x48:preREX,
0x49:preREX,
0x4A:preREX,
0x4B:preREX,
0x4C:preREX,
0x4D:preREX,
0x4E:preREX,
0x4F:preREX,
0x66:preSIZE,
0xF2:preREP,
0xF3:preREP,
}

OPCODES = {
0x00:opAdd,
0x01:opAdd,
0x02:opAdd,
0x03:opAdd,
0x04:opAdd,
0x05:opAdd,
0x06:opInvalid,
0x07:opInvalid,
0x08:opOr,
0x09:opOr,
0x0A:opOr,
0x0B:opOr,
0x0C:opOr,
0x0D:opOr,
0x0E:opInvalid,
0x10:opADC,
0x11:opADC,
0x12:opADC,
0x13:opADC,
0x14:opADC,
0x15:opADC,
0x16:opInvalid,
0x17:opInvalid,
0x18:opSBB,
0x19:opSBB,
0x1A:opSBB,
0x1B:opSBB,
0x1C:opSBB,
0x1D:opSBB,
0x1E:opInvalid,
0x1F:opInvalid,
0x20:opAnd,
0x21:opAnd,
0x22:opAnd,
0x23:opAnd,
0x24:opAnd,
0x25:opAnd,
0x28:opSub,
0x29:opSub,
0x2A:opSub,
0x2B:opSub,
0x2C:opSub,
0x2D:opSub,
0x30:opXOR,
0x31:opXOR,
0x32:opXOR,
0x33:opXOR,
0x34:opXOR,
0x35:opXOR,
0x36:opNull,
0x35:opInvalid,
0x38:opCmp,
0x39:opCmp,
0x3A:opCmp,
0x3B:opCmp,
0x3C:opCmp,
0x3D:opCmp,
0x3E:opNull,
0x3F:opInvalid,
0x50:opPush,
0x51:opPush,
0x52:opPush,
0x53:opPush,
0x54:opPush,
0x55:opPush,
0x56:opPush,
0x57:opPush,
0x58:opPop,
0x59:opPop,
0x5A:opPop,
0x5B:opPop,
0x5C:opPop,
0x5D:opPop,
0x5E:opPop,
0x5F:opPop,
0x60:opPushaPopa,
0x61:opPushaPopa,
0x62:opInvalid,
0x63:opMOVSXD,
0x68:opPush,
0x69:opIMUL,
0x6A:opPush,
0x6B:opIMUL,
0x70:opGroupJMP,
0x71:opGroupJMP,
0x72:opGroupJMP,
0x73:opGroupJMP,
0x74:opGroupJMP,
0x75:opGroupJMP,
0x76:opGroupJMP,
0x77:opGroupJMP,
0x78:opGroupJMP,
0x79:opGroupJMP,
0x7A:opGroupJMP,
0x7B:opGroupJMP,
0x7C:opGroupJMP,
0x7D:opGroupJMP,
0x7E:opGroupJMP,
0x7F:opGroupJMP,
0x80:opGroup80,
0x81:opGroup81,
0x82:opInvalid,
0x83:opGroup81,
0x84:opTest,
0x85:opTest,
0x88:opMov,
0x89:opMov,
0x8A:opMov,
0x8B:opMov,
0x8D:opLea,
0x90:opNOP,
0x98:opCONVERT,
0x99:opCONVERT,
0xA0:opMovA,
0xA1:opMovA,
0xA2:opMovA,
0xA3:opMovA,
0xA4:opCMPSMOVS,
0xA5:opCMPSMOVS,
0xA6:opCMPSMOVS,
0xA7:opCMPSMOVS,
0xA8:opTestA,
0xA9:opTestA,
0xAA:opSTOLODS,
0xAB:opSTOLODS,
0xAC:opSTOLODS,
0xAD:opSTOLODS,
0xB0:opMovRB,
0xB1:opMovRB,
0xB2:opMovRB,
0xB3:opMovRB,
0xB4:opMovRB,
0xB5:opMovRB,
0xB6:opMovRB,
0xB7:opMovRB,
0xB8:opMovRW,
0xB9:opMovRW,
0xBA:opMovRW,
0xBB:opMovRW,
0xBC:opMovRW,
0xBD:opMovRW,
0xBE:opMovRW,
0xBF:opMovRW,
0xC0:opGroupSHIFT,
0xC1:opGroupSHIFT,
0xC3:opRet,
0xC6:opGroupC6,
0xC7:opGroupC7,
0xC9:opLeave,
0xCC:opInt3,
0xD0:opGroupSHIFT,
0xD1:opGroupSHIFT,
0xD2:opGroupSHIFT,
0xD3:opGroupSHIFT,
0xD8:opGroupD8,
0xE0:opLoopJmp,
0xE1:opLoopJmp,
0xE2:opLoopJmp,
0xE3:opLoopJmp,
0xE8:opGroupE8,
0xE9:opGroupE8,
0xEB:opJmp,
0xEC:opIO,
0xED:opIO,
0xEE:opIO,
0xEF:opIO,
0xF6:opGroupF6,
0xF7:opGroupF6,
0xFE:opGroupFF,
0xFF:opGroupFF,
}

OPCODES_TB = {
0x40:opGroupMOV,
0x41:opGroupMOV,
0x42:opGroupMOV,
0x43:opGroupMOV,
0x44:opGroupMOV,
0x45:opGroupMOV,
0x46:opGroupMOV,
0x47:opGroupMOV,
0x48:opGroupMOV,
0x49:opGroupMOV,
0x4A:opGroupMOV,
0x4B:opGroupMOV,
0x4C:opGroupMOV,
0x4D:opGroupMOV,
0x4E:opGroupMOV,
0x4F:opGroupMOV,
0x80:opGroupJMP,
0x81:opGroupJMP,
0x82:opGroupJMP,
0x83:opGroupJMP,
0x84:opGroupJMP,
0x85:opGroupJMP,
0x86:opGroupJMP,
0x87:opGroupJMP,
0x88:opGroupJMP,
0x89:opGroupJMP,
0x8A:opGroupJMP,
0x8B:opGroupJMP,
0x8C:opGroupJMP,
0x8D:opGroupJMP,
0x8E:opGroupJMP,
0x8F:opGroupJMP,
0x90:opGroupSET,
0x91:opGroupSET,
0x92:opGroupSET,
0x93:opGroupSET,
0x94:opGroupSET,
0x95:opGroupSET,
0x96:opGroupSET,
0x97:opGroupSET,
0x98:opGroupSET,
0x99:opGroupSET,
0x9A:opGroupSET,
0x9B:opGroupSET,
0x9C:opGroupSET,
0x9D:opGroupSET,
0x9E:opGroupSET,
0x9F:opGroupSET,
0xAC:opSHRD,
0xAD:opSHRD,
0xAF:opIMUL,
0xB6:opMOVZX,
0xB7:opMOVZX,
0xBA:opBT,
0xBE:opMOVSX,
0xBF:opMOVSX,
}


procs = {}
datas = {}

_rawdata = None
_rawcode = None


class proc():
    _lastjump = 0
    callees = []
    callbacks = []
    callers = []
    ops = []
    name = "proc_"
    entryPoint = 0
    def __init__(self, data, ep):
        l = len(data)
        entryPoint = ep
        if not (ep) in procs.keys():
            procs[ep] = self 
        self.name = self.name + "0x%08X"%ep
        print "%s:"%self.name
        off = ep-base
        while (off+1)< l:
            if (off+base) in calltables.keys():
                print_calltable(data, off+base)
                off += calltables[off+base][0]
            o = op(data, off, self)
            self.ops.append(o)
            off += o.length
            if o.name == "ret" and (self._lastjump < (off+base)):
                break
            #elif o.name in ["mov"]:
            #    if o.modrm.mem_imm_isPtr:
            #        c = o.modrm.mem_imm
            #        if c > base and c < (base+codesize):
            #            self.callbacks.append(c)

class DISASM:
    code = None
    data = None

    def setBitmode(self, bm):
        global bitmode
        bitmode = bm
    def setCodesegment(self, cb, cs=None):
        global codebase
        global codesize
        codebase = cb
        if cs:
            codesize = cs
        else:
            codesize = len(self.code)
    def setDatasegment(self, db, ds=None):
        global database
        global datasize
        database = db
        if ds:
            datasize = cs
        else:
            datasize = len(self.code)

    def __init__(self,code,data,baseOfImage=0, baseOfCode=0, baseOfData=0, bm=64, entryPoint=0, smart=True, loglevel=0, withraw=False):
        global imagebase
        global codebase
        global codesize
        global database
        global datasize
        global base
        global bitmode
        global debugmode
        global withrawdata
        global verbose
        global _rawdata
        global _rawcode
        global calltables
        withrawdata = withraw
        imagebase = baseOfImage
        codebase = baseOfImage+baseOfCode
        database = baseOfImage+baseOfData
        base = codebase

        print "Base: 0x%08X"%base
        debugmode = loglevel==2
        verbose = loglevel > 0
        bitmode = bm
        codesize = len(code)
        datasize = len(data)
        print "CodeLen: 0x%08X"%codesize
        print "DataLen: 0x%08X"%datasize
        _rawcode = code
        _rawdata = data
        if smart:
            mainProc = proc(code, entryPoint+imagebase)
            len1 = len(procs)
            len2 = 0
            orgprocs = procs.keys()
            while(len1 != len2):
                for p in orgprocs:
                    for c in procs[p].callees:
                        if not c in procs: 
                            proc(code, c)
                    for c in procs[p].callbacks:
                        if not c in procs: 
                            proc(code, c)
                orgprocs = procs.keys()
                len2 = len1
                len1 = len(procs)
        else:
            offset = 0
            ops = []
            end = codesize
            while (offset+1)