mirror of
https://github.com/hakril/PythonForWindows
synced 2026-06-08 14:31:45 +00:00
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:
@@ -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
@@ -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())
|
||||
|
||||
Reference in New Issue
Block a user