1
0
mirror of synced 2024-11-27 23:50:47 +01:00

Support lea, jz, js, jns instructions in emulator to decode more of Sunny Park.

This commit is contained in:
Jennifer Taylor 2021-09-03 04:35:53 +00:00
parent 06d116007e
commit fa69380ebe

View File

@ -37,6 +37,7 @@ class Registers:
self.rsp = 0xFFFFFFFF
self.zf = False
self.sf = False
class PEFile:
@ -165,7 +166,16 @@ class PEFile:
if size is None:
raise Exception(f"Could not determine size of {mnemonic} operation!")
result = fetch(registers, memory, size, op1) & fetch(registers, memory, size, op2)
registers.zf = result == 0
if size == 1:
registers.sf = (result & 0x80) != 0
if size == 2:
registers.sf = (result & 0x8000) != 0
if size == 4:
registers.sf = (result & 0x80000000) != 0
if size == 8:
registers.sf = (result & 0x8000000000000000) != 0
elif mnemonic == "jne":
dest = formatter.format_operand(inst, 0)
@ -187,6 +197,66 @@ class PEFile:
insts = [i for i in decoder]
loc = 0
elif mnemonic == "je":
dest = formatter.format_operand(inst, 0)
vprint(f"jz {dest}")
if registers.zf:
destination = get_value(dest)
if destination is None:
raise Exception(f"Jumping to unsupported destination {dest}")
dest_off = self.virtual_to_physical(destination)
if dest_off == end:
loc = len(insts)
elif dest_off < start or dest_off > end:
raise Exception(f"Jumping to {hex(destination)} which is outside of our evaluation range!")
else:
decoder = Decoder(64 if self.is_64bit() else 32, self.data[dest_off:end], ip=self.physical_to_virtual(dest_off))
insts = [i for i in decoder]
loc = 0
elif mnemonic == "jns":
dest = formatter.format_operand(inst, 0)
vprint(f"jns {dest}")
if not registers.sf:
destination = get_value(dest)
if destination is None:
raise Exception(f"Jumping to unsupported destination {dest}")
dest_off = self.virtual_to_physical(destination)
if dest_off == end:
loc = len(insts)
elif dest_off < start or dest_off > end:
raise Exception(f"Jumping to {hex(destination)} which is outside of our evaluation range!")
else:
decoder = Decoder(64 if self.is_64bit() else 32, self.data[dest_off:end], ip=self.physical_to_virtual(dest_off))
insts = [i for i in decoder]
loc = 0
elif mnemonic == "js":
dest = formatter.format_operand(inst, 0)
vprint(f"js {dest}")
if registers.sf:
destination = get_value(dest)
if destination is None:
raise Exception(f"Jumping to unsupported destination {dest}")
dest_off = self.virtual_to_physical(destination)
if dest_off == end:
loc = len(insts)
elif dest_off < start or dest_off > end:
raise Exception(f"Jumping to {hex(destination)} which is outside of our evaluation range!")
else:
decoder = Decoder(64 if self.is_64bit() else 32, self.data[dest_off:end], ip=self.physical_to_virtual(dest_off))
insts = [i for i in decoder]
loc = 0
elif mnemonic == "jmp":
dest = formatter.format_operand(inst, 0)
@ -230,6 +300,20 @@ class PEFile:
result = fetch(registers, memory, size, dest) ^ fetch(registers, memory, size, src)
assign(registers, memory, size, dest, result)
elif mnemonic == "lea":
dest = formatter.format_operand(inst, 0)
src = formatter.format_operand(inst, 1)
vprint(f"lea {dest}, {src}")
size = get_size(src) or get_size(dest)
if size is None:
raise Exception(f"Could not determine size of {mnemonic} operation!")
result = get_address(registers, src)
if result is None:
raise Exception(f"Could not compute effective address for {mnemonic} operation!")
assign(registers, memory, size, dest, result)
else:
raise Exception(f"Unsupported mnemonic {mnemonic}!")
@ -290,13 +374,60 @@ def get_address(registers: Registers, indirect: str) -> Optional[int]:
indirect = sanitize(indirect)
if indirect[0] == "[" and indirect[-1] == "]":
val = indirect[1:-1]
indirect = indirect[1:-1]
if val[-1] == 'h':
return int(val[:-1], 16)
adjust = 0
if '+' in indirect:
indirect, const = indirect.split('+', 1)
if val in {"rsp", "esp", "sp", "spl"}:
return registers.rsp
if const[-1] == 'h':
adjust = int(const[:-1], 16)
else:
raise Exception(f"Unsupported constant adjustment to indirect address {indirect}")
elif '-' in indirect:
indirect, const = indirect.split('-', 1)
if const[-1] == 'h':
adjust = -int(const[:-1], 16)
else:
raise Exception(f"Unsupported constant adjustment to indirect address {indirect}")
if indirect[-1] == 'h':
return int(indirect[:-1], 16) + adjust
# Register-based indirect modes.
if indirect == "rsp":
return registers.rsp + adjust
if indirect == "esp":
return (registers.rsp & 0xFFFFFFFF) + adjust
if indirect == "sp":
return (registers.rsp & 0xFFFF) + adjust
if indirect == "spl":
return (registers.rsp & 0xFF) + adjust
if indirect == "rbp":
return registers.rbp + adjust
if indirect == "ebp":
return (registers.rbp & 0xFFFFFFFF) + adjust
if indirect == "bp":
return (registers.rbp & 0xFFFF) + adjust
if indirect == "bp":
return (registers.rbp & 0xFF) + adjust
if indirect == "rsi":
return registers.rsi + adjust
if indirect == "esi":
return (registers.rsi & 0xFFFFFFFF) + adjust
if indirect == "si":
return (registers.rsi & 0xFFFF) + adjust
if indirect == "si":
return (registers.rsi & 0xFF) + adjust
if indirect == "rdi":
return registers.rdi + adjust
if indirect == "edi":
return (registers.rdi & 0xFFFFFFFF) + adjust
if indirect == "di":
return (registers.rdi & 0xFFFF) + adjust
if indirect == "di":
return (registers.rdi & 0xFF) + adjust
raise Exception(f"Unsupported indirect address {indirect}!")
return None