Created
May 6, 2016 13:02
-
-
Save Konctantin/1c8ad484b484b5a4831ba049693418b2 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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