mirror of
https://github.com/hakril/PythonForWindows
synced 2026-06-08 14:31:45 +00:00
Add nativeutils.py with GetProcAddress64 + add instr to x86/x64 assembler + add merge of labels in multipleinstr (dummy function support)
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
import windows
|
||||
import windows.test
|
||||
|
||||
import windows.native_exec.simple_x64 as x64
|
||||
import windows.native_exec.nativeutils
|
||||
from windows.generated_def.winstructs import *
|
||||
|
||||
GetProcAddress64 = windows.native_exec.nativeutils.GetProcAddress64
|
||||
|
||||
dll = "KERNEL32.DLL\x00".encode("utf-16-le")
|
||||
api = "LoadLibraryA\x00"
|
||||
dll_to_load = "SUCE"
|
||||
|
||||
|
||||
RemoteManualLoadLibray = x64.MultipleInstr()
|
||||
c = RemoteManualLoadLibray
|
||||
c += x64.Mov("R15", "RCX")
|
||||
c += x64.Mov("RCX", x64.mem("[R15 + 0]"))
|
||||
c += x64.Mov("RDX", x64.mem("[R15 + 8]"))
|
||||
c += x64.Call(":FUNC_GETPROCADDRESS64")
|
||||
c += x64.Mov("RCX", x64.mem("[R15 + 0x10]"))
|
||||
c += x64.Push("RCX")
|
||||
c += x64.Push("RCX")
|
||||
c += x64.Push("RCX")
|
||||
c += x64.Call("RAX")
|
||||
c += x64.Pop("RCX")
|
||||
c += x64.Pop("RCX")
|
||||
c += x64.Pop("RCX")
|
||||
c += x64.Ret()
|
||||
|
||||
RemoteManualLoadLibray += GetProcAddress64
|
||||
|
||||
|
||||
calc= windows.test.pop_calc_64(dwCreationFlags=CREATE_SUSPENDED)
|
||||
|
||||
addr = calc.virtual_alloc(0x1000)
|
||||
addr2 = addr + len(dll)
|
||||
addr3 = addr2 + len(api)
|
||||
addr4 = addr3 + len(dll_to_load)
|
||||
|
||||
calc.write_memory(addr, dll)
|
||||
calc.write_memory(addr2, api)
|
||||
calc.write_memory(addr3, dll_to_load)
|
||||
calc.write_qword(addr4, addr)
|
||||
calc.write_qword(addr4 + 8, addr2)
|
||||
calc.write_qword(addr4 + 0x10, addr3)
|
||||
|
||||
calc.execute(RemoteManualLoadLibray.get_code(), addr4)
|
||||
|
||||
@@ -0,0 +1,138 @@
|
||||
import windows
|
||||
|
||||
import windows.native_exec.simple_x64 as x64
|
||||
from windows.generated_def.winstructs import *
|
||||
|
||||
|
||||
StrlenW64 = x64.MultipleInstr()
|
||||
StrlenW64 += x64.Label(":FUNC_STRLENW64")
|
||||
StrlenW64 += x64.Push("RCX")
|
||||
StrlenW64 += x64.Push("RDI")
|
||||
StrlenW64 += x64.Mov("RDI", "RCX")
|
||||
StrlenW64 += x64.Xor("RAX", "RAX")
|
||||
StrlenW64 += x64.Xor("RCX", "RCX")
|
||||
StrlenW64 += x64.Dec("RCX")
|
||||
StrlenW64 += x64.Repne + x64.ScasW()
|
||||
StrlenW64 += x64.Not("RCX")
|
||||
StrlenW64 += x64.Dec("RCX")
|
||||
StrlenW64 += x64.Mov("RAX", "RCX")
|
||||
StrlenW64 += x64.Pop("RDI")
|
||||
StrlenW64 += x64.Pop("RCX")
|
||||
StrlenW64 += x64.Ret()
|
||||
|
||||
|
||||
StrlenA64 = x64.MultipleInstr()
|
||||
StrlenA64 += x64.Label(":FUNC_STRLENA64")
|
||||
StrlenA64 += x64.Push("RCX")
|
||||
StrlenA64 += x64.Push("RDI")
|
||||
StrlenA64 += x64.Mov("RDI", "RCX")
|
||||
StrlenA64 += x64.Xor("RAX", "rax")
|
||||
StrlenA64 += x64.Xor("RCX", "RCX")
|
||||
StrlenA64 += x64.Dec("RCX")
|
||||
StrlenA64 += x64.Repne + x64.ScasB()
|
||||
StrlenA64 += x64.Not("RCX")
|
||||
StrlenA64 += x64.Dec("RCX")
|
||||
StrlenA64 += x64.Mov("RAX", "RCX")
|
||||
StrlenA64 += x64.Pop("RDI")
|
||||
StrlenA64 += x64.Pop("RCX")
|
||||
StrlenA64 += x64.Ret()
|
||||
|
||||
|
||||
GetProcAddress64 = x64.MultipleInstr()
|
||||
GetProcAddress64 += x64.Label(":FUNC_GETPROCADDRESS64")
|
||||
GetProcAddress64 += x64.Push("RBX")
|
||||
GetProcAddress64 += x64.Push("RCX")
|
||||
GetProcAddress64 += x64.Push("RDX")
|
||||
GetProcAddress64 += x64.Push("RSI")
|
||||
GetProcAddress64 += x64.Push("RDI")
|
||||
GetProcAddress64 += x64.Push("R8")
|
||||
GetProcAddress64 += x64.Push("R9")
|
||||
GetProcAddress64 += x64.Push("R10")
|
||||
GetProcAddress64 += x64.Push("R11")
|
||||
GetProcAddress64 += x64.Push("R12")
|
||||
GetProcAddress64 += x64.Push("R13")
|
||||
# Params : RCX -> libname
|
||||
# Params : RDX -> API Name
|
||||
GetProcAddress64 += x64.Mov("R11", "RCX")
|
||||
GetProcAddress64 += x64.Mov("R12", "RDX")
|
||||
GetProcAddress64 += x64.Mov("RAX", x64.mem("GS:[0x60]")) #PEB !
|
||||
GetProcAddress64 += x64.Mov("RAX", x64.mem("[RAX + 24] ")) # ; RAX = ldr (+ 6 for 64 cause of 2 ptr)
|
||||
GetProcAddress64 += x64.Mov("RAX", x64.mem("[RAX + 32]")) # ; RAX on the first elt of the list (first module)
|
||||
GetProcAddress64 += x64.Mov("RDX", "RAX")
|
||||
GetProcAddress64 += x64.Label(":a_dest")
|
||||
GetProcAddress64 += x64.Mov("RAX", "RDX")
|
||||
GetProcAddress64 += x64.Mov("RBX", x64.mem("[RAX + 32]")) # RBX : first base ! (base of current module)
|
||||
#GetProcAddress64 += x64.Mov("RBX ", x64.mem("[RAX + 32]")) # RBX : first base ! (base of current module)
|
||||
GetProcAddress64 += x64.Cmp("RBX", 0)
|
||||
GetProcAddress64 += x64.Jz(":NOT_FOUND")
|
||||
GetProcAddress64 += x64.Mov("RCX", x64.mem("[RAX + 80]")) # RCX = NAME (UNICODE_STRING.Buffer)
|
||||
GetProcAddress64 += x64.Call(":FUNC_STRLENW64")
|
||||
GetProcAddress64 += x64.Mov("RDI", "RCX")
|
||||
GetProcAddress64 += x64.Mov("RCX", "RAX")
|
||||
GetProcAddress64 += x64.Mov("RSI", "R11")
|
||||
#GetProcAddress64 += x64.Int3()
|
||||
GetProcAddress64 += x64.Rep + x64.CmpsW() #;cmp with current dll name (unicode)
|
||||
GetProcAddress64 += x64.Test("RCX", "RCX")
|
||||
GetProcAddress64 += x64.Jz(":DLL_FOUND")
|
||||
GetProcAddress64 += x64.Mov("RDX", x64.mem("[RDX]"))
|
||||
GetProcAddress64 += x64.Jmp(":a_dest")
|
||||
GetProcAddress64 += x64.Label(":DLL_FOUND") # here rbx = base
|
||||
GetProcAddress64 += x64.Mov("EAX", x64.mem("[RBX + 60]")) # rax = PEBASE RVA
|
||||
GetProcAddress64 += x64.Add("RAX", "RBX") # RAX = PEBASE
|
||||
GetProcAddress64 += x64.Add("RAX", 24) # ;OPTIONAL HEADER
|
||||
GetProcAddress64 += x64.Mov("ECX", x64.mem("[rax + 112]")) # ;rcx = RVA export dir
|
||||
GetProcAddress64 += x64.Add("RCX", "RBX") # ;rcx = export_dir
|
||||
GetProcAddress64 += x64.Mov("RAX", "RCX") # ;RAX = export_dir
|
||||
GetProcAddress64 += x64.Push("RAX") # ;Save it for after function search
|
||||
# ; EBX = BASE | EAX = EXPORT DIR
|
||||
GetProcAddress64 += x64.Mov("ECX", x64.mem("[RAX + 24] ")) # rax = PEBASE RVA
|
||||
GetProcAddress64 += x64.Mov("R13", "RCX") # ;r13 = NB names
|
||||
GetProcAddress64 += x64.Mov("EDX", x64.mem("[RAX + 32] ")) # EDX = names array RVA
|
||||
GetProcAddress64 += x64.Add("RDX", "RBX") # RDX = names array
|
||||
GetProcAddress64 += x64.Xor("RCX", "RCX")
|
||||
GetProcAddress64 += x64.Label(":SEARCH_LOOP")
|
||||
GetProcAddress64 += x64.Mov("ESI", x64.mem("[RDX + RCX * 4]")) # ;Get function name RVA
|
||||
GetProcAddress64 += x64.Add("RSI", "RBX") # ;Get name addr
|
||||
GetProcAddress64 += x64.Push("RCX") # ;Save current index (could use x64 register)
|
||||
GetProcAddress64 += x64.Mov("RCX", "R12")
|
||||
GetProcAddress64 += x64.Call(":FUNC_STRLENA64") # TODO: mov outside the loop :D
|
||||
GetProcAddress64 += x64.Mov("RCX", "RAX")
|
||||
GetProcAddress64 += x64.Mov("RDI", "R12")
|
||||
GetProcAddress64 += x64.Rep + x64.CmpsB()
|
||||
GetProcAddress64 += x64.Mov("EAX", "ECX")
|
||||
GetProcAddress64 += x64.Pop("RCX")
|
||||
GetProcAddress64 += x64.Inc("RCX")
|
||||
GetProcAddress64 += x64.Test("RAX", "RAX")
|
||||
GetProcAddress64 += x64.Jnz(":SEARCH_LOOP")
|
||||
# Func FOUND !
|
||||
GetProcAddress64 += x64.Dec("RCX")
|
||||
GetProcAddress64 += x64.Pop("RAX") # ;Restore export_dir addr
|
||||
GetProcAddress64 += x64.Mov("EDX", x64.mem("[RAX + 36]")) # ;EDX = AddressOfNameOrdinals RVX
|
||||
GetProcAddress64 += x64.Add("RDX", "RBX")
|
||||
GetProcAddress64 += x64.OperandSizeOverride + x64.Mov("ECX", x64.mem("[rdx + rcx * 2]")) # ; ecx = Ieme ordinal (short array)
|
||||
GetProcAddress64 += x64.And('RCX', 0xffff)
|
||||
GetProcAddress64 += x64.Mov("EDX", x64.mem("[RAX + 28]")) # ; AddressOfFunctions RVA
|
||||
GetProcAddress64 += x64.Add("RDX", "RBX")
|
||||
GetProcAddress64 += x64.Mov("EDX", x64.mem("[RDX + RCX * 4]"))
|
||||
GetProcAddress64 += x64.Add("RDX", "RBX")
|
||||
GetProcAddress64 += x64.Mov("RAX", "RDX")
|
||||
GetProcAddress64 += x64.Pop("R13")
|
||||
GetProcAddress64 += x64.Pop("R12")
|
||||
GetProcAddress64 += x64.Pop("R11")
|
||||
GetProcAddress64 += x64.Pop("R10")
|
||||
GetProcAddress64 += x64.Pop("R9")
|
||||
GetProcAddress64 += x64.Pop("R8")
|
||||
GetProcAddress64 += x64.Pop("RDI")
|
||||
GetProcAddress64 += x64.Pop("RSI")
|
||||
GetProcAddress64 += x64.Pop("RDX")
|
||||
GetProcAddress64 += x64.Pop("RCX")
|
||||
GetProcAddress64 += x64.Pop("RBX")
|
||||
GetProcAddress64 += x64.Ret()
|
||||
GetProcAddress64 += x64.Label(":NOT_FOUND")
|
||||
GetProcAddress64 += x64.Xor("RAX", "RAX")
|
||||
GetProcAddress64 += x64.Ret()
|
||||
# Ajout des dependances
|
||||
GetProcAddress64 += StrlenW64
|
||||
GetProcAddress64 += StrlenA64
|
||||
|
||||
|
||||
@@ -722,9 +722,6 @@ class Pop(Instruction):
|
||||
encoding = [(RawBits.from_int(5, 0x58 >> 3), X64RegisterSelector())]
|
||||
|
||||
|
||||
class Call(Instruction):
|
||||
encoding = [(RawBits.from_int(8, 0xff), Slash(2))]
|
||||
|
||||
|
||||
class Xchg(Instruction):
|
||||
default_32_bits = True
|
||||
@@ -820,6 +817,10 @@ class JmpImm8(JmpImm):
|
||||
class JmpImm32(JmpImm):
|
||||
accept_as_Ximmediat = staticmethod(accept_as_32immediat)
|
||||
|
||||
class Call(JmpType):
|
||||
encoding = [(RawBits.from_int(8, 0xe8), JmpImm32(5)),
|
||||
(RawBits.from_int(8, 0xff), Slash(2))]
|
||||
|
||||
|
||||
class Jmp(JmpType):
|
||||
encoding = [(RawBits.from_int(8, 0xeb), JmpImm8(2)),
|
||||
@@ -867,10 +868,17 @@ class Mov(Instruction):
|
||||
|
||||
class Cmp(Instruction):
|
||||
default_32_bits = True
|
||||
|
||||
encoding = [(RawBits.from_int(8, 0x3d), RegisterRax(), Imm32()),
|
||||
(RawBits.from_int(8, 0x81), Slash(7), Imm32()),
|
||||
(RawBits.from_int(8, 0x3b), ModRM([ModRM_REG__REG, ModRM_REG64__MEM]))]
|
||||
|
||||
class Test(Instruction):
|
||||
default_32_bits = True
|
||||
refuse_reverse = True
|
||||
encoding = [(RawBits.from_int(8, 0xf7), Slash(7), Imm32()),
|
||||
(RawBits.from_int(8, 0x85), ModRM([ModRM_REG__REG, ModRM_REG64__MEM], has_direction_bit=False))]
|
||||
|
||||
|
||||
class Xor(Instruction):
|
||||
default_32_bits = True
|
||||
@@ -880,6 +888,47 @@ class Xor(Instruction):
|
||||
class Nop(Instruction):
|
||||
encoding = [(RawBits.from_int(8, 0x90),)]
|
||||
|
||||
class Not(Instruction):
|
||||
default_32_bits = True
|
||||
encoding = [(RawBits.from_int(8, 0xF7), Slash(2))]
|
||||
|
||||
class ScasB(Instruction):
|
||||
default_32_bits = True
|
||||
encoding = [(RawBits.from_int(8, 0xAE),)]
|
||||
|
||||
|
||||
class ScasW(Instruction):
|
||||
default_32_bits = True
|
||||
encoding = [(RawBits.from_int(16, 0x66AF),)]
|
||||
|
||||
|
||||
class ScasD(Instruction):
|
||||
default_32_bits = True
|
||||
encoding = [(RawBits.from_int(8, 0xAF),)]
|
||||
|
||||
class ScasQ(Instruction):
|
||||
encoding = [(RawBits.from_int(16, 0x48AF),)]
|
||||
|
||||
|
||||
class CmpsB(Instruction):
|
||||
default_32_bits = True
|
||||
encoding = [(RawBits.from_int(8, 0xa6),)]
|
||||
|
||||
|
||||
class CmpsW(Instruction):
|
||||
default_32_bits = True
|
||||
encoding = [(RawBits.from_int(16, 0x66A7),)]
|
||||
|
||||
|
||||
class CmpsD(Instruction):
|
||||
default_32_bits = True
|
||||
encoding = [(RawBits.from_int(8, 0xa7),)]
|
||||
|
||||
|
||||
class CmpsQ(Instruction):
|
||||
default_32_bits = True
|
||||
encoding = [(RawBits.from_int(16, 0x48A7),)]
|
||||
|
||||
|
||||
class Retf(Instruction):
|
||||
default_32_bits = True
|
||||
@@ -922,7 +971,7 @@ class MultipleInstr(object):
|
||||
|
||||
def get_code(self):
|
||||
if self.expected_labels:
|
||||
raise ValueError("Unresolved labels: {self.expected_labels}".format(self=self))
|
||||
raise ValueError("Unresolved labels: {0}".format(self.expected_labels.keys()))
|
||||
return b"".join([bytes(x[1].get_code()) for x in sorted(self.instrs.items())])
|
||||
|
||||
def add_instruction(self, instruction):
|
||||
@@ -1036,7 +1085,12 @@ class MultipleInstr(object):
|
||||
self.size -= 1
|
||||
|
||||
def merge_shellcode(self, other):
|
||||
shared_labels = set(self.labels) & set(other.labels)
|
||||
if shared_labels:
|
||||
raise ValueError("Cannot merge shellcode: shared labels {0}".format(shared_labels))
|
||||
for offset, instr in sorted(other.instrs.items()):
|
||||
for label_name in [name for name, label_offset in other.labels.items() if label_offset == offset]:
|
||||
self.add_instruction(Label(label_name))
|
||||
self.add_instruction(instr)
|
||||
|
||||
def __iadd__(self, other):
|
||||
|
||||
@@ -580,6 +580,11 @@ class JmpImm32(JmpImm):
|
||||
|
||||
|
||||
# Instructions
|
||||
|
||||
class Call(JmpType):
|
||||
encoding = [(RawBits.from_int(8, 0xe8), JmpImm32(5)),
|
||||
(RawBits.from_int(8, 0xff), Slash(2))]
|
||||
|
||||
class Jmp(JmpType):
|
||||
encoding = [(RawBits.from_int(8, 0xeb), JmpImm8(2)),
|
||||
(RawBits.from_int(8, 0xe9), JmpImm32(5))]
|
||||
@@ -674,6 +679,11 @@ class Cmp(Instruction):
|
||||
(RawBits.from_int(8, 0x3b), ModRM([ModRM_REG__REG, ModRM_REG__MEM]))]
|
||||
|
||||
|
||||
class Test(Instruction):
|
||||
encoding = [(RawBits.from_int(8, 0xf7), Slash(7), Imm32()),
|
||||
(RawBits.from_int(8, 0x85), ModRM([ModRM_REG__REG, ModRM_REG__MEM], has_direction_bit=False))]
|
||||
|
||||
|
||||
class Out(Instruction):
|
||||
encoding = [(RawBits.from_int(8, 0xee), FixedRegister('DX'), FixedRegister('AL')),
|
||||
(RawBits.from_int(16, 0x66ef), FixedRegister('DX'), FixedRegister('AX')), # Fuck-it hardcoded prefix for now
|
||||
@@ -694,8 +704,7 @@ class Xchg(Instruction):
|
||||
encoding = [(RawBits.from_int(5, 0x90 >> 3), RegisterEax(), X86RegisterSelector()), (RawBits.from_int(5, 0x90 >> 3), X86RegisterSelector(), RegisterEax())]
|
||||
|
||||
|
||||
class Call(Instruction):
|
||||
encoding = [(RawBits.from_int(8, 0xff), Slash(2))]
|
||||
|
||||
|
||||
|
||||
class Cpuid(Instruction):
|
||||
@@ -706,9 +715,36 @@ class Ret(Instruction):
|
||||
encoding = [(RawBits.from_int(8, 0xc3),)]
|
||||
|
||||
|
||||
class ScasB(Instruction):
|
||||
encoding = [(RawBits.from_int(8, 0xAE),)]
|
||||
|
||||
class ScasW(Instruction):
|
||||
encoding = [(RawBits.from_int(16, 0x66AF),)]
|
||||
|
||||
class ScasD(Instruction):
|
||||
encoding = [(RawBits.from_int(8, 0xAF),)]
|
||||
|
||||
|
||||
class CmpsB(Instruction):
|
||||
default_32_bits = True
|
||||
encoding = [(RawBits.from_int(8, 0xa6),)]
|
||||
|
||||
|
||||
class CmpsW(Instruction):
|
||||
default_32_bits = True
|
||||
encoding = [(RawBits.from_int(16, 0x66A7),)]
|
||||
|
||||
|
||||
class CmpsD(Instruction):
|
||||
default_32_bits = True
|
||||
encoding = [(RawBits.from_int(8, 0xa7),)]
|
||||
|
||||
|
||||
class Nop(Instruction):
|
||||
encoding = [(RawBits.from_int(8, 0x90),)]
|
||||
|
||||
class Not(Instruction):
|
||||
encoding = [(RawBits.from_int(8, 0xF7), Slash(2))]
|
||||
|
||||
class Retf(Instruction):
|
||||
encoding = [(RawBits.from_int(8, 0xcb),)]
|
||||
@@ -866,7 +902,12 @@ class MultipleInstr(object):
|
||||
self.size -= 1
|
||||
|
||||
def merge_shellcode(self, other):
|
||||
shared_labels = set(self.labels) & set(other.labels)
|
||||
if shared_labels:
|
||||
raise ValueError("Cannot merge shellcode: shared labels {0}".format(shared_labels))
|
||||
for offset, instr in sorted(other.instrs.items()):
|
||||
for label_name in [name for name, label_offset in other.labels.items() if label_offset == offset]:
|
||||
self.add_instruction(Label(label_name))
|
||||
self.add_instruction(instr)
|
||||
|
||||
def __iadd__(self, other):
|
||||
|
||||
@@ -13,9 +13,10 @@ mnemonic_name_exception = {'movabs': 'mov'}
|
||||
|
||||
|
||||
class TestInstr(object):
|
||||
def __init__(self, instr_to_test, immediat_accepted=None, must_fail=None, debug=False):
|
||||
def __init__(self, instr_to_test, expected_result=None, immediat_accepted=None, must_fail=None, debug=False):
|
||||
self.instr_to_test = instr_to_test
|
||||
self.immediat_accepted = immediat_accepted
|
||||
self.expected_result = expected_result
|
||||
self.must_fail = must_fail
|
||||
self.debug = debug
|
||||
|
||||
@@ -40,6 +41,11 @@ class TestInstr(object):
|
||||
raise AssertionError("Trying to disas an instruction resulted in multiple disassembled instrs")
|
||||
capres = capres_list[0]
|
||||
print("{0} {1}".format(capres.mnemonic, capres.op_str))
|
||||
if self.expected_result is not None:
|
||||
if "{0} {1}".format(capres.mnemonic, capres.op_str) == self.expected_result:
|
||||
return True
|
||||
else:
|
||||
raise AssertionError("Expected result <{0}> got <{1}>".format(self.expected_result, "{0} {1}".format(capres.mnemonic, capres.op_str)))
|
||||
if len(res) != len(capres.bytes):
|
||||
raise AssertionError("Not all bytes have been used by the disassembler")
|
||||
self.compare_mnemo(capres)
|
||||
@@ -128,6 +134,7 @@ TestInstr(Mov, immediat_accepted=-1)('RCX', 0xffffffffffffffff)
|
||||
TestInstr(Mov)(mem('gs:[0x1122334455667788]'), 'RAX')
|
||||
TestInstr(Mov)(mem('[RAX]'), 0x11223344)
|
||||
TestInstr(Mov)(mem('[EAX]'), 0x11223344)
|
||||
TestInstr(Mov)(mem('[RBX]'), 0x11223344)
|
||||
|
||||
TestInstr(And)('RCX', 'RBX')
|
||||
TestInstr(And)('RAX', 0x11223344)
|
||||
@@ -143,6 +150,15 @@ TestInstr(Or)(mem('[RAX + 1]'), 'R8')
|
||||
TestInstr(Or)(mem('[EAX + 1]'), 'R8')
|
||||
TestInstr(Or)(mem('[RAX + 1]'), 'EAX')
|
||||
|
||||
# I really don't know why it's the inverse
|
||||
# But I don't care, it's Test dude..
|
||||
TestInstr(Test, expected_result="test r11, rax")('RAX', 'R11')
|
||||
TestInstr(Test, expected_result="test edi, eax")('EAX', 'EDI')
|
||||
TestInstr(Test)('RCX', 'RCX')
|
||||
|
||||
TestInstr(Test)(mem('[RDI + 0x100]'), 'RCX')
|
||||
|
||||
assert Test(mem('[RDI + 0x100]'), 'RCX').get_code() == Test('RCX', mem('[RDI + 0x100]')).get_code()
|
||||
|
||||
|
||||
TestInstr(Push)('R15')
|
||||
@@ -168,6 +184,21 @@ TestInstr(Mov)(mem('[RBX + RCX + 0x10]'), 'ECX')
|
||||
TestInstr(Mov)(mem('[EBX + ECX + 0x10]'), 'ECX')
|
||||
TestInstr(Mov)(mem('[EBX + ECX + 0x10]'), 'R8')
|
||||
|
||||
TestInstr(Not)('RAX')
|
||||
TestInstr(Not)(mem('[RAX]'))
|
||||
|
||||
|
||||
TestInstr(ScasB, expected_result="scasb al, byte ptr [rdi]")()
|
||||
TestInstr(ScasW, expected_result="scasw ax, word ptr [rdi]")()
|
||||
TestInstr(ScasD, expected_result="scasd eax, dword ptr [rdi]")()
|
||||
TestInstr(ScasQ, expected_result="scasq rax, qword ptr [rdi]")()
|
||||
|
||||
TestInstr(CmpsB, expected_result="cmpsb byte ptr [rsi], byte ptr [rdi]")()
|
||||
TestInstr(CmpsW, expected_result="cmpsw word ptr [rsi], word ptr [rdi]")()
|
||||
TestInstr(CmpsD, expected_result="cmpsd dword ptr [rsi], dword ptr [rdi]")()
|
||||
TestInstr(CmpsQ, expected_result="cmpsq qword ptr [rsi], qword ptr [rdi]")()
|
||||
|
||||
|
||||
|
||||
TestInstr(Mov, must_fail=True)('RCX', 'ECX')
|
||||
TestInstr(Mov, must_fail=True)('RCX', mem('[ECX + RCX]'))
|
||||
|
||||
@@ -140,6 +140,25 @@ TestInstr(Or)('EAX', 0x11223344)
|
||||
TestInstr(Or)('EAX', mem('[EAX + 1]'))
|
||||
TestInstr(Or)(mem('[EAX + EAX]'), 'EDX')
|
||||
|
||||
TestInstr(Not)('EAX')
|
||||
TestInstr(Not)(mem('[EAX]'))
|
||||
|
||||
TestInstr(ScasB, expected_result="scasb al, byte ptr es:[edi]")()
|
||||
TestInstr(ScasW, expected_result="scasw ax, word ptr es:[edi]")()
|
||||
TestInstr(ScasD, expected_result="scasd eax, dword ptr es:[edi]")()
|
||||
|
||||
TestInstr(CmpsB, expected_result="cmpsb byte ptr [esi], byte ptr es:[edi]")()
|
||||
TestInstr(CmpsW, expected_result="cmpsw word ptr [esi], word ptr es:[edi]")()
|
||||
TestInstr(CmpsD, expected_result="cmpsd dword ptr [esi], dword ptr es:[edi]")()
|
||||
|
||||
|
||||
TestInstr(Test)('EAX', 'EAX')
|
||||
TestInstr(Test, expected_result="test edi, ecx ")('ECX', 'EDI')
|
||||
|
||||
TestInstr(Test)(mem('[ECX + 0x100]'), 'ECX')
|
||||
|
||||
assert Test(mem('[ECX + 0x100]'), 'ECX').get_code() == Test('ECX', mem('[ECX + 0x100]')).get_code()
|
||||
|
||||
|
||||
assert Xchg('EAX', 'ECX').get_code() == Xchg('ECX', 'EAX').get_code()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user