import struct import sys import codecs # This code should really be rewritten.. this_module = sys.modules[__name__] generated_instruction = [] long = int def add_instruction(name, instruction): generated_instruction.append((name, instruction)) setattr(this_module, name, instruction) def generate_module_doc(): doc_lines = ["Here is the list of instruction in the modules:\n\n"] for name, instruction in generated_instruction: doc_lines.append(" | {0} -> <{1}>".format(name, instruction.mnemo)) this_module.__doc__ = "\n".join(doc_lines) def decode_hex(s): return codecs.decode(s.encode(), "hex").decode() def encode_hex(s): return codecs.encode(s.encode(), "hex").decode() reg_order = ['EAX', 'ECX', 'EDX', 'EBX', 'ESP', 'EBP', 'ESI', 'EDI'] reg_opcode = {v : format(i, "03b") for i, v in enumerate(reg_order)} class X86Instruction(object): mnemo = "" code = "" biding = 0 def __init__(self, *bind_values): if len(bind_values) != self.biding: raise ValueError("{0} expect {1} values got {2}".format(self.__class__.__name__, self.biding, len(bind_values))) self.bind_values = bind_values for i, v in enumerate(bind_values): if not isinstance(v, (int, long)): raise ValueError("{0} bindings must be 'int' got '{1}' instead".format(self.__class__.__name__, type(v).__name__)) if not 0 <= v <= 0xffffffff: raise ValueError("{0} bindings must be between 0 and 0xffffffff".format(self.__class__.__name__)) def get_unbinded_code(self): print(self.code) return codecs.decode(self.code.replace(" ", ""), 'hex') def get_code(self): code = self.get_unbinded_code() for i in range(self.biding): to_search = codecs.decode(str(i + 1) * 8, 'hex') code = code.replace(to_search, struct.pack(" Not implemented continue class Reg_DReg_instruction(X86Instruction): mnemo = instr_cls.mnemo.format(reg_dst_name, reg_src_name) name = instr_cls.name.format(reg_dst_name, reg_src_name) if src_first: modr_code = generate_reg_indirect_modr_byte(reg_src_bits, reg_dst_bits) else: modr_code = generate_reg_indirect_modr_byte(reg_dst_bits, reg_src_bits) code = encode_hex(instr_cls.instruction_bits + chr(int(modr_code, 2))) Reg_DReg_instruction.__name__ = Reg_DReg_instruction.name add_instruction(Reg_DReg_instruction.__name__, Reg_DReg_instruction) class Mov_Reg_DReg(object): name = 'Mov_{0}_D{1}' mnemo = 'mov [{0}], {1}' instruction_bits = '8B' generate_reg_reg_deref(Mov_Reg_DReg, False) class Mov_DReg_Reg(object): name = 'Mov_D{0}_{1}' mnemo = 'mov {0}, [{1}]' instruction_bits = '89' generate_reg_reg_deref(Mov_DReg_Reg, True) def generate_reg_reg_modr_byte(reg_dst_bits, reg_src_bits): # reg, reg return "11{0}{1}".format(reg_src_bits, reg_dst_bits) def generate_reg_reg_modr(instr_cls): for reg_src_name, reg_src_bits in reg_opcode.items(): for reg_dst_name, reg_dst_bits in reg_opcode.items(): class Reg_Reg_instruction(X86Instruction): mnemo = "{0} {1},{2}".format(instr_cls.mnemo, reg_dst_name, reg_src_name) modr_code = format(int(generate_reg_reg_modr_byte(reg_dst_bits, reg_src_bits) , 2), 'x') code = instr_cls.instruction_bits + modr_code Reg_Reg_instruction.__name__ = "{0}_{1}_{2}".format(instr_cls.name, reg_dst_name, reg_src_name) add_instruction(Reg_Reg_instruction.__name__, Reg_Reg_instruction) class Test_Reg_Reg(object): mnemo = "tst" name = "Tst" instruction_bits = "85" generate_reg_reg_modr(Test_Reg_Reg) #### JUMP #### class JZ(OneBindX86Instruction): code = "0F 84 11 11 11 11" def __init__(self, instr_block): self.instr_block = instr_block instr_block_size = len(instr_block.get_code()) super(JZ, self).__init__(instr_block_size) def get_code(self): return super(JZ, self).get_code() + self.instr_block.get_code() class JNZ(OneBindX86Instruction): code = "0F 85 11 11 11 11" def __init__(self, instr_block): self.instr_block = instr_block instr_block_size = len(instr_block.get_code()) super(JNZ, self).__init__(instr_block_size) def get_code(self): return super(JNZ, self).get_code() + self.instr_block.get_code() class MultipleInstr(object): def __init__(self, init_instrs=()): self.instrs = list(init_instrs) def __iadd__(self, value): if type(value) == MultipleInstr: self.instrs.extend(value.instrs) return self self.instrs.append(value) return self def get_code(self): return "".join(i.get_code() for i in self.instrs) def get_mnemo(self): return "\n".join(i.get_mnemo() for i in self.instrs) generate_module_doc()