Skip to content

Instantly share code, notes, and snippets.

@Konctantin
Created May 6, 2016 13:02
Show Gist options
  • Select an option

  • Save Konctantin/1c8ad484b484b5a4831ba049693418b2 to your computer and use it in GitHub Desktop.

Select an option

Save Konctantin/1c8ad484b484b5a4831ba049693418b2 to your computer and use it in GitHub Desktop.
import db, sys, re, os
immSizes = { "b":8,"w":16,"d":32,"q":64 };
x86Registers = {
# 8 bit
"AL":(8), "CL":(8), "DL":(8), "BL":(8),
"AH":(8), "CH":(8), "DH":(8), "BH":(8),
# 16 bit
"AX":(16),"CX":(16),"DX":(16),"BX":(16),
"SP":(16),"BP":(16),"SI":(16),"DI":(16),
# Segment
"CS":(16), "DS":(16), "ES":(16), "FS":(16), "GS":(16), "SS":(16),
# 32 bit
"EAX":(32),"ECX":(32),"EDX":(32),"EBX":(32),
"ESP":(32),"EBP":(32),"ESI":(32),"EDI":(32),
# 64 bit
"RAX":(64),"RCX":(64),"RDX":(64),"RBX":(64),
"RSP":(64),"RBP":(64),"RSI":(64),"RDI":(64),
"R8" :(64),"R9" :(64),"R10":(64),"R11":(64),
"R12":(64),"R13":(64),"R14":(64),"R15":(64),
}
def rfind(pattern, text):
""" re """
if text == None or str.strip(text) == "":
return False;
return len(re.findall(pattern, text)) > 0
class Operand():
def __init__(self, raw, enc, index):
self.raw = raw.strip();
self.enc = enc;
self.index = index;
self.size = 0;
self.fixedreg = "";
self.fixedimm = -1;
self.type = "";
self.regtype = "";
self.segment = True;
self.parse();
def __str__(self):
return "INDEX: %i Type: %s, RegType: %s, Size: %i, FImm: %i FReg: %s" % (self.index, self.type, self.regtype, self.size, self.fixedimm, self.fixedreg);
def parse(self):
if x86Registers.has_key(self.raw.upper()):
self.fixedreg = self.raw.upper();
return;
if self.raw.upper() == "SREG":
self.regtype = "Segment";
self.size = 16;
return;
val = re.findall("^(\d+)$" , self.raw)
if len(val) > 0:
self.type = "Imm"
self.fixedimm = int(val[0]);
self.size = 8;
return;
val = re.findall("^r/m(\d+)$" , self.raw)
if len(val) > 0:
self.type = "RegMem";
self.size = int(val[0]);
return;
val = re.findall("^r(\d+)$", self.raw);
if len(val) > 0:
self.type = "Reg";
self.size = int(val[0]);
return;
val = re.findall("^m(\d+)$", self.raw);
if len(val) > 0:
self.type = "Mem";
self.size = int(val[0]);
return;
val = re.findall("^m16\:(\d+)$", self.raw);
if len(val) > 0:
self.type = "Mem";
self.size = int(val[0]);
self.segment = True;
return;
val = re.findall("^moffs(\d+)$", self.raw);
if len(val) > 0:
self.type = "MemOffs";
self.size = int(val[0]);
return;
val = re.findall("^imm(\d+)$", self.raw);
if len(val) > 0:
self.type = "Imm";
self.size = int(val[0]);
return;
val = re.findall("^rel(\d+)$", self.raw);
if len(val) > 0:
self.type = "Rel";
self.size = int(val[0]);
return;
val = re.findall("^r(\d+)/m(\d+)$", self.raw);
if len(val) == 2:
if int(val[0]) != int(val[1]):
raise BaseException("lolololo")
self.type = "RegMem";
self.size = int(val[0]);
return;
raise BaseException("ERR OPERAND", self.raw);
class Instruction():
def __init__(self, raw, mnem, operands):
self.raw = raw;
self.mnem = mnem;
self.rex = 0; # x64 rex prefix (0x48)
self.pref = 0;
self.pref0f = 0; # 0F opcode prefix
self.reg = False; # reg field
self.regField = -1; # reg field index
self.immSize = 0; # immedicate data size
self.opcodeAdd= False;
self.opcode = [];
self.operands = operands
self.parse();
def __str__(self):
return "%s: Rex: %X, Pref: %X, Pref0F: %X, Reg: %s, Field: %i, ImmSize: %i, Add: %s, Opcode: %s" %\
(self.mnem, self.rex, self.pref, self.pref0f, self.reg, self.regField, self.immSize, self.opcodeAdd, self.opcode)
def parse(self):
self.opcodeAdd = rfind("([A-Fa-f0-9]\+)", self.raw);
self.rex = 0x40 if self.raw.find("REX.W+") > -1 else 0;
self.pref0f = 0x0F if self.raw.find("0F") > -1 else 0;
self.reg = self.raw.find("/r") > -1;
val = re.findall("/([0-7])", self.raw);
if len(val) > 0:
self.regField = int(val[0], 10);
val = re.findall("i([bwdq])", self.raw);
if len(val) > 0:
self.immSize = immSizes[val[0]];
val = re.findall("(?:66|F2|F3)", self.raw);
if len(val) > 0:
self.pref = int(val[0], 16)
val = re.findall("(?:[A-F0-9]){2}", self.raw);
for op in val:
if not op in ['66','F2','F3','0F']:
self.opcode.append(int(op, 16))
if len(self.opcode) == 0:
print("ERROR", self.raw);
for row in db.list:
mnem = row[0];
opcode = row[1];
operands = row[2].split(',');
encoding = row[3];
bit64 = row[4];
compat = row[5];
title = row[6];
desc = row[7];
try:
oplist = [];
if len(operands) != len(encoding):
#print("ERROR: enc unmatched ", mnem, opcode, operands, encoding);
continue
for i in range(len(operands)):
o = Operand(operands[i], encoding[i:1], i);
#print(o)
oplist.append(o)
instr = Instruction(opcode, mnem, oplist)
print(instr)
except BaseException as ex:
print(">>>ERR:::", mnem, opcode, ex)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment