Added mov REG/SEGREG in simple_x86 + fix a bug in syswow64 on AMD do to a processor bug (Issue10)

This commit is contained in:
hakril
2020-02-02 17:49:42 +01:00
parent 2e1043ead4
commit f2a6489463
2 changed files with 60 additions and 3 deletions
+52 -1
View File
@@ -1,6 +1,11 @@
import sys
import collections
import struct
# py3
is_py3 = (sys.version_info.major >= 3)
if is_py3:
basestring = str
class BitArray(object):
def __init__(self, size, bits):
@@ -72,9 +77,15 @@ class Prefix(object):
def __add__(self, other):
return type(self)(other)
def get_code_py3(self):
return bytes([self.PREFIX_VALUE]) + self.next.get_code()
def get_code(self):
return chr(self.PREFIX_VALUE) + self.next.get_code()
if is_py3:
get_code = get_code_py3
def create_prefix(name, value):
prefix_type = type(name + "Type", (Prefix,), {'PREFIX_VALUE': value})
@@ -100,6 +111,15 @@ x86_16bits_regs = ['AX', 'CX', 'DX', 'BX', 'SP', 'BP', 'SI', 'DI']
x86_segment_selectors = {'CS': CSPrefix, 'DS': DSPrefix, 'ES': ESPrefix, 'SS': SSPrefix,
'FS': FSPrefix, 'GS': GSPrefix}
# Man intel -> Sreg (Vol 2.a 3-6)
x86_segment_selectors_number = {
"ES": "000",
"CS": "001",
"SS": "010",
"DS": "011",
"FS": "100",
"GS": "101",
}
class X86(object):
@staticmethod
@@ -109,6 +129,13 @@ class X86(object):
except AttributeError: # Not a string
return False
@staticmethod
def is_seg_reg(name):
try:
return name.upper() in x86_segment_selectors_number
except AttributeError:
return False
@staticmethod
def reg_size(name):
if name.upper() in x86_regs:
@@ -372,6 +399,9 @@ class SegmentSelectorAbsoluteAddr(object):
return (sizess + sizeabs, dataabs + datass)
class ModRM(object):
def __init__(self, sub_modrm, accept_reverse=True, has_direction_bit=True):
self.accept_reverse = accept_reverse
@@ -404,6 +434,7 @@ class ModRM_REG__REG(object):
def match(cls, arg1, arg2):
return X86.is_reg(arg1) and X86.is_reg(arg2)
def __init__(self, arg1, arg2, reversed, instr_state):
self.mod = BitArray(2, "11")
if X86.reg_size(arg1) != X86.reg_size(arg2):
@@ -415,6 +446,18 @@ class ModRM_REG__REG(object):
self.after = BitArray(0, "")
self.direction = 0
class ModRM_REG__SEGREG(object):
@classmethod
def match(cls, arg1, arg2):
return X86.is_reg(arg1) and X86.is_seg_reg(arg2)
def __init__(self, arg1, arg2, reversed, instr_state):
self.mod = BitArray(2, "11")
self.rm = X86RegisterSelector.get_reg_bits(arg1)
self.reg = BitArray(3, x86_segment_selectors_number[arg2.upper()])
self.after = BitArray(0, "")
self.direction = reversed
class ModRM_REG__MEM(object):
@@ -576,6 +619,13 @@ class Instruction(object):
prefix_opcode = b"".join(chr(p.PREFIX_VALUE) for p in self.prefix)
return prefix_opcode + bytes(self.value.dump())
def get_code_py3(self):
prefix_opcode = b"".join(bytes([p.PREFIX_VALUE]) for p in self.prefix)
return prefix_opcode + bytes(self.value.dump())
if is_py3:
get_code = get_code_py3
#def __add__(self, other):
# res = MultipleInstr()
# res += self
@@ -720,7 +770,8 @@ class Sub(Instruction):
class Mov(Instruction):
encoding = [(RawBits.from_int(8, 0x89), ModRM([ModRM_REG__REG, ModRM_REG__MEM])),
(RawBits.from_int(8, 0xc7), Slash(0), Imm32()),
(RawBits.from_int(5, 0xb8 >> 3), X86RegisterSelector(), Imm32()),
(RawBits.from_int(5, 0xB8 >> 3), X86RegisterSelector(), Imm32()),
(RawBits.from_int(8, 0x8C), ModRM([ModRM_REG__SEGREG])),
(RawBits.from_int(16, 0x0f20), ControlRegisterModRM(writecr=False)),
(RawBits.from_int(16, 0x0f22), ControlRegisterModRM(writecr=True))]
+8 -2
View File
@@ -7,10 +7,10 @@ import functools
import windows
import windows.native_exec.simple_x86 as x86
import windows.native_exec.simple_x64 as x64
from generated_def.winstructs import *
from .generated_def.winstructs import *
from windows.winobject import process
from windows import winproxy
from winproxy import NeededParameter
from .winproxy import NeededParameter
# Special code for syswow64 process
CS_32bits = 0x23
@@ -33,6 +33,12 @@ def generate_64bits_execution_stub_from_syswow(x64shellcode):
transition = x86.MultipleInstr()
transition += x86.Call(CS_64bits, x64shellcodeaddr)
# Reset the SS segment selector.
# We need to do that due to a bug in AMD CPUs with RETF & SS
# https://github.com/hakril/PythonForWindows/issues/10
# http://blog.rewolf.pl/blog/?p=1484
transition += x86.Mov("ECX", "SS")
transition += x86.Mov("SS", "ECX")
transition += x86.Ret()
stubaddr = windows.current_process.allocator.write_code(transition.get_code())