def decode(instruction): '''Extract the modrm tuple out of the provided instruction''' modrm = instruction[2] if len(modrm) > 0: modrm = decoder.decodeInteger(modrm) return decoder.extractmodrm(modrm) return None
def promoteBranch_16(instruction): raise NotImplementedError("16-bit absolute branches not implemented really") result = promoteBranch_32(instruction) imm = getImmediate(result) offset = decodeInteger(imm, True) - length(result) # downgrade the opcode prefix = getPrefix(result) if '\x66' not in prefix: prefix += '\x66' result = setPrefix(result, prefix) offset += length(result) return setImmediate(result, encodeInteger(offset, 2))
def promoteBranch_16(instruction): raise NotImplementedError( "16-bit absolute branches not implemented really") result = promoteBranch_32(instruction) imm = getImmediate(result) offset = decodeInteger(imm, True) - length(result) # downgrade the opcode prefix = getPrefix(result) if '\x66' not in prefix: prefix += '\x66' result = setPrefix(result, prefix) offset += length(result) return setImmediate(result, encodeInteger(offset, 2))
def getRelativeAddress(pc, instruction): '''Given the specified instruction and address, will return the target branch address''' imm = getImmediate(instruction) l = len(imm) ofs = decodeInteger(imm) pc += length(instruction) if (l == 4) and (ofs & 0x80000000): return pc - (0x100000000 - ofs) elif (l == 2) and (ofs & 0x8000): return pc - (0x10000 - ofs) elif (l == 1) and (ofs & 0x80): return pc - (0x100 - ofs) # otherwise we're just jumping forward return pc + ofs
def promoteBranch_32(instruction): imm = getImmediate(instruction) offset = decodeInteger(imm, True) + length(instruction) prefix = ''.join([x for x in getPrefix(instruction) if x != '\x66']) if isConditionalBranch8(instruction): column = ord(getOpcode(instruction)) & 0xf result = setOpcode(instruction, '\x0f'+chr(column | 0x80)) elif isUnconditionalBranch8(instruction): result = setOpcode(instruction, '\xe9') elif isRelativeCall(instruction) or isUnconditionalBranch(instruction) or isConditionalBranch(instruction): result = instruction else: raise NotImplementedError('Unable to promote a non-branch instruction to 32-bits: {!r}'.format(n)) result = setPrefix(setImmediate(result, '\x00\x00\x00\x00'), prefix) return setImmediate(result, encodeInteger(offset-length(result), 4))
def promoteBranch_8(instruction): '''Promote(?) instruction to an 8-bit branch''' imm = getImmediate(instruction) offset = decodeInteger(imm, True) prefix = ''.join([x for x in getPrefix(instruction) if x != '\x66']) if isConditionalBranch8(instruction) or isUnconditionalBranch8(instruction) or isRelativeCall(instruction): result = instruction offset += length(result) elif isUnconditionalBranch(instruction): result = setOpcode(instruction, '\xeb') elif isConditionalBranch(instruction): column = ord(getOpcode(instruction)[1]) & 0xf result = setOpcode(instruction, chr(column | 0x70)) else: raise NotImplementedError('Unable to promote a non-branch instruction to 8-bits: {!r}'.format(n)) result = setPrefix(setImmediate(result, '\x00'), prefix) return setImmediate(result, encodeInteger(offset-length(result), 1))
def getDelta(insn): p,o,m,s,d,i = insn opcode = decoder.decodeInteger(o[-1]) if len(o) == 2: opcode = 0x100 + opcode try: return stacktable[opcode](insn) except KeyError: pass if m: mod,reg,rm = modrm.decode(insn) if mod == 3 and reg == 4: raise NotImplementedError("arithmetic instruction references esp, but is not yet implemented") pass if sib: scale,index,base = sib.decode(insn) if base == 4: raise NotImplementedError("read from esp") pass return 0
def promoteBranch_32(instruction): imm = getImmediate(instruction) offset = decodeInteger(imm, True) + length(instruction) prefix = ''.join([x for x in getPrefix(instruction) if x != '\x66']) if isConditionalBranch8(instruction): column = ord(getOpcode(instruction)) & 0xf result = setOpcode(instruction, '\x0f' + chr(column | 0x80)) elif isUnconditionalBranch8(instruction): result = setOpcode(instruction, '\xe9') elif isRelativeCall(instruction) or isUnconditionalBranch( instruction) or isConditionalBranch(instruction): result = instruction else: raise NotImplementedError( 'Unable to promote a non-branch instruction to 32-bits: {!r}'. format(n)) result = setPrefix(setImmediate(result, '\x00\x00\x00\x00'), prefix) return setImmediate(result, encodeInteger(offset - length(result), 4))
def promoteBranch_8(instruction): '''Promote(?) instruction to an 8-bit branch''' imm = getImmediate(instruction) offset = decodeInteger(imm, True) prefix = ''.join([x for x in getPrefix(instruction) if x != '\x66']) if isConditionalBranch8(instruction) or isUnconditionalBranch8( instruction) or isRelativeCall(instruction): result = instruction offset += length(result) elif isUnconditionalBranch(instruction): result = setOpcode(instruction, '\xeb') elif isConditionalBranch(instruction): column = ord(getOpcode(instruction)[1]) & 0xf result = setOpcode(instruction, chr(column | 0x70)) else: raise NotImplementedError( 'Unable to promote a non-branch instruction to 8-bits: {!r}'. format(n)) result = setPrefix(setImmediate(result, '\x00'), prefix) return setImmediate(result, encodeInteger(offset - length(result), 1))
def retn(insn): p,o,m,s,d,i = insn if len(i) == 0: return 4 return 4 + decoder.decodeInteger(i)
def stringToNumber(string): '''This function name is deprecated in favor of encodeInteger''' return decodeInteger(string)
def extractsib(instruction): '''Returns (scale,index,base) of an instruction''' sib = getSib(instruction) return decoder.extractsib( decodeInteger(sib) )
def extractmodrm(instruction): '''Return the (Mod, Reg, r/m) components of an instruction''' modrm = getModrm(instruction) return decoder.extractmodrm( decodeInteger(modrm) )
code = '\xe9\xc1\xfe\xff\xff' test_set(0x101d70e9, code, 0x101d6faf) @TestCase def Test_f(): code = '\xe9\xa6\x00\x00\x00' test_set(0x101dc252, code, 0x101dc2fd) if False: code = '\x0f\x85\x7f\xff\xff\xff' n = setRelativeAddress(0, decode(code), -5) print hex(getRelativeAddress(0, n)) n = setRelativeAddress(0, decode(code), 0x2) print repr(n) print hex(getRelativeAddress(0, n)) print hex(decodeInteger(getImmediate(n)) + length(n)) if False: code = '\x77\x08' code = '\x0f\x87\x04\x00\x00\x00' n = decode(code) x = promoteBranch_8(n) print repr(x) print '%x:%x -> %x' % (0x70, 0x72, 0x7a) @TestCase def Test_10(): res = ''' b8b5000000ba0003fe7fff12c20c00b8b6000000ba0003fe7fff12c21800b8b7000000ba0003fe7fff12c22400b8b8000000ba0003fe7fff12c22400b8b9000000ba0003fe7fff12c21800b8ba000000ba0003fe7fff12c21400b8bb000000ba0003fe7fff12c20400b8bc000000ba0003fe7fff12c20800b8bd000000ba0003fe7fff12c20c00b8be000000ba0003fe7fff12c21400 6a1468082d917ce85cbcffff8a1dc0e1977c8b750c33d23bf20f85f81602008b7d103bfa740289178b4d08f7c1fcffffff0f851cbb02003bfa0f842dbb02008bc183e0020f85d416020084db754a33db4384cb0f84821d00006878e1977c3bc20f8597170200e832e3feff85f60f8536bb020064a118000000b9d8e0977cf00fc1194381e3ffff00008b402425ff0f0000c1e0100bd8891f33f68bc6e802bcffffc20c0090ffffffff43e8937c5ee8937c90909090906a0c68802d917ce8a6bbffff8b5508f7c2feffffff0f85b8bb02008b4d0c85c97436f7c1000000f00f85bebb020064a118000000c1e91033482466f7c1ff0f0f85a7bb0200f6c2010f84107a01006878e1977ce86fe3feff33c0e88ebbffffc208009090909090ffffffff23e9937c3ee9937c90909090908bff558bec8b45145333db3bc3568b75080f8c04b60200895e048bc8c1e1100bc88b
code = '\xe9\xc1\xfe\xff\xff' test_set( 0x101d70e9, code, 0x101d6faf ) @TestCase def Test_f(): code = '\xe9\xa6\x00\x00\x00' test_set( 0x101dc252, code, 0x101dc2fd ) if False: code = '\x0f\x85\x7f\xff\xff\xff' n = setRelativeAddress(0, decode(code), -5) print hex(getRelativeAddress(0, n)) n = setRelativeAddress(0, decode(code), 0x2) print repr(n) print hex(getRelativeAddress(0, n)) print hex(decodeInteger(getImmediate(n)) + length(n)) if False: code = '\x77\x08' code = '\x0f\x87\x04\x00\x00\x00' n = decode(code) x = promoteBranch_8(n) print repr(x) print '%x:%x -> %x'% (0x70, 0x72, 0x7a) @TestCase def Test_10(): res = ''' b8b5000000ba0003fe7fff12c20c00b8b6000000ba0003fe7fff12c21800b8b7000000ba0003fe7fff12c22400b8b8000000ba0003fe7fff12c22400b8b9000000ba0003fe7fff12c21800b8ba000000ba0003fe7fff12c21400b8bb000000ba0003fe7fff12c20400b8bc000000ba0003fe7fff12c20800b8bd000000ba0003fe7fff12c20c00b8be000000ba0003fe7fff12c21400 6a1468082d917ce85cbcffff8a1dc0e1977c8b750c33d23bf20f85f81602008b7d103bfa740289178b4d08f7c1fcffffff0f851cbb02003bfa0f842dbb02008bc183e0020f85d416020084db754a33db4384cb0f84821d00006878e1977c3bc20f8597170200e832e3feff85f60f8536bb020064a118000000b9d8e0977cf00fc1194381e3ffff00008b402425ff0f0000c1e0100bd8891f33f68bc6e802bcffffc20c0090ffffffff43e8937c5ee8937c90909090906a0c68802d917ce8a6bbffff8b5508f7c2feffffff0f85b8bb02008b4d0c85c97436f7c1000000f00f85bebb020064a118000000c1e91033482466f7c1ff0f0f85a7bb0200f6c2010f84107a01006878e1977ce86fe3feff33c0e88ebbffffc208009090909090ffffffff23e9937c3ee9937c90909090908bff558bec8b45145333db3bc3568b75080f8c04b60200895e048bc8c1e1100bc88b
def retf(insn): p,o,m,s,d,i = insn if len(i) == 0: return 6 return 6 + decoder.decodeInteger(i)
def extractsib(instruction): '''Returns (scale,index,base) of an instruction''' sib = getSib(instruction) return decoder.extractsib(decodeInteger(sib))
def extractmodrm(instruction): '''Return the (Mod, Reg, r/m) components of an instruction''' modrm = getModrm(instruction) return decoder.extractmodrm(decodeInteger(modrm))