mirror of
https://github.com/hakril/PythonForWindows
synced 2026-06-08 14:31:45 +00:00
Big commit <3
This commit is contained in:
+6
-3
@@ -11,12 +11,15 @@ Exported:
|
||||
current_thread : :class:`windows.winobject.CurrentThread`
|
||||
"""
|
||||
|
||||
import k32testing
|
||||
from winobject import System, CurrentProcess, CurrentThread
|
||||
from utils import VirtualProtected
|
||||
import windows.k32testing
|
||||
from .utils import VirtualProtected
|
||||
from .winobject import System, CurrentProcess, CurrentThread
|
||||
|
||||
|
||||
system = System()
|
||||
current_process = CurrentProcess()
|
||||
current_thread = CurrentThread()
|
||||
|
||||
import windows.vectored_exception
|
||||
|
||||
__all__ = ["system", "VirtualProtected", 'current_process', 'current_thread']
|
||||
@@ -1,5 +1,5 @@
|
||||
import windows
|
||||
import winstructs
|
||||
from . import winstructs
|
||||
|
||||
def bitness():
|
||||
"""Return 32 or 64"""
|
||||
@@ -23,5 +23,7 @@ else:
|
||||
winstructs.EXCEPTION_POINTERS = winstructs.EXCEPTION_POINTERS64
|
||||
winstructs.PEXCEPTION_POINTERS = winstructs.PEXCEPTION_POINTERS64
|
||||
|
||||
import winfuncs
|
||||
from . import winfuncs
|
||||
|
||||
|
||||
|
||||
|
||||
+149
-72
@@ -1,5 +1,9 @@
|
||||
#Generated file
|
||||
|
||||
import sys
|
||||
if sys.version_info.major == 3:
|
||||
long = int
|
||||
|
||||
class Flag(long):
|
||||
def __new__(cls, name, value):
|
||||
return super(Flag, cls).__new__(cls, value)
|
||||
@@ -79,59 +83,59 @@ PROFILE_USER = Flag("PROFILE_USER", 0x10000000)
|
||||
PROFILE_KERNEL = Flag("PROFILE_KERNEL", 0x20000000)
|
||||
PROFILE_SERVER = Flag("PROFILE_SERVER", 0x40000000)
|
||||
CREATE_IGNORE_SYSTEM_DEFAULT = Flag("CREATE_IGNORE_SYSTEM_DEFAULT", 0x80000000)
|
||||
STATUS_WAIT_0 = Flag("STATUS_WAIT_0", ( 0x00000000L ))
|
||||
STATUS_ABANDONED_WAIT_0 = Flag("STATUS_ABANDONED_WAIT_0", ( 0x00000080L ))
|
||||
STATUS_USER_APC = Flag("STATUS_USER_APC", ( 0x000000C0L ))
|
||||
STATUS_TIMEOUT = Flag("STATUS_TIMEOUT", ( 0x00000102L ))
|
||||
STATUS_PENDING = Flag("STATUS_PENDING", ( 0x00000103L ))
|
||||
DBG_EXCEPTION_HANDLED = Flag("DBG_EXCEPTION_HANDLED", ( 0x00010001L ))
|
||||
DBG_CONTINUE = Flag("DBG_CONTINUE", ( 0x00010002L ))
|
||||
STATUS_SEGMENT_NOTIFICATION = Flag("STATUS_SEGMENT_NOTIFICATION", ( 0x40000005L ))
|
||||
DBG_TERMINATE_THREAD = Flag("DBG_TERMINATE_THREAD", ( 0x40010003L ))
|
||||
DBG_TERMINATE_PROCESS = Flag("DBG_TERMINATE_PROCESS", ( 0x40010004L ))
|
||||
DBG_CONTROL_C = Flag("DBG_CONTROL_C", ( 0x40010005L ))
|
||||
DBG_PRINTEXCEPTION_C = Flag("DBG_PRINTEXCEPTION_C", ( 0x40010006L ))
|
||||
DBG_RIPEXCEPTION = Flag("DBG_RIPEXCEPTION", ( 0x40010007L ))
|
||||
DBG_CONTROL_BREAK = Flag("DBG_CONTROL_BREAK", ( 0x40010008L ))
|
||||
DBG_COMMAND_EXCEPTION = Flag("DBG_COMMAND_EXCEPTION", ( 0x40010009L ))
|
||||
STATUS_GUARD_PAGE_VIOLATION = Flag("STATUS_GUARD_PAGE_VIOLATION", ( 0x80000001L ))
|
||||
STATUS_DATATYPE_MISALIGNMENT = Flag("STATUS_DATATYPE_MISALIGNMENT", ( 0x80000002L ))
|
||||
STATUS_BREAKPOINT = Flag("STATUS_BREAKPOINT", ( 0x80000003L ))
|
||||
STATUS_SINGLE_STEP = Flag("STATUS_SINGLE_STEP", ( 0x80000004L ))
|
||||
STATUS_LONGJUMP = Flag("STATUS_LONGJUMP", ( 0x80000026L ))
|
||||
STATUS_UNWIND_CONSOLIDATE = Flag("STATUS_UNWIND_CONSOLIDATE", ( 0x80000029L ))
|
||||
DBG_EXCEPTION_NOT_HANDLED = Flag("DBG_EXCEPTION_NOT_HANDLED", ( 0x80010001L ))
|
||||
STATUS_ACCESS_VIOLATION = Flag("STATUS_ACCESS_VIOLATION", ( 0xC0000005L ))
|
||||
STATUS_IN_PAGE_ERROR = Flag("STATUS_IN_PAGE_ERROR", ( 0xC0000006L ))
|
||||
STATUS_INVALID_HANDLE = Flag("STATUS_INVALID_HANDLE", ( 0xC0000008L ))
|
||||
STATUS_INVALID_PARAMETER = Flag("STATUS_INVALID_PARAMETER", ( 0xC000000DL ))
|
||||
STATUS_NO_MEMORY = Flag("STATUS_NO_MEMORY", ( 0xC0000017L ))
|
||||
STATUS_ILLEGAL_INSTRUCTION = Flag("STATUS_ILLEGAL_INSTRUCTION", ( 0xC000001DL ))
|
||||
STATUS_NONCONTINUABLE_EXCEPTION = Flag("STATUS_NONCONTINUABLE_EXCEPTION", ( 0xC0000025L ))
|
||||
STATUS_INVALID_DISPOSITION = Flag("STATUS_INVALID_DISPOSITION", ( 0xC0000026L ))
|
||||
STATUS_ARRAY_BOUNDS_EXCEEDED = Flag("STATUS_ARRAY_BOUNDS_EXCEEDED", ( 0xC000008CL ))
|
||||
STATUS_FLOAT_DENORMAL_OPERAND = Flag("STATUS_FLOAT_DENORMAL_OPERAND", ( 0xC000008DL ))
|
||||
STATUS_FLOAT_DIVIDE_BY_ZERO = Flag("STATUS_FLOAT_DIVIDE_BY_ZERO", ( 0xC000008EL ))
|
||||
STATUS_FLOAT_INEXACT_RESULT = Flag("STATUS_FLOAT_INEXACT_RESULT", ( 0xC000008FL ))
|
||||
STATUS_FLOAT_INVALID_OPERATION = Flag("STATUS_FLOAT_INVALID_OPERATION", ( 0xC0000090L ))
|
||||
STATUS_FLOAT_OVERFLOW = Flag("STATUS_FLOAT_OVERFLOW", ( 0xC0000091L ))
|
||||
STATUS_FLOAT_STACK_CHECK = Flag("STATUS_FLOAT_STACK_CHECK", ( 0xC0000092L ))
|
||||
STATUS_FLOAT_UNDERFLOW = Flag("STATUS_FLOAT_UNDERFLOW", ( 0xC0000093L ))
|
||||
STATUS_INTEGER_DIVIDE_BY_ZERO = Flag("STATUS_INTEGER_DIVIDE_BY_ZERO", ( 0xC0000094L ))
|
||||
STATUS_INTEGER_OVERFLOW = Flag("STATUS_INTEGER_OVERFLOW", ( 0xC0000095L ))
|
||||
STATUS_PRIVILEGED_INSTRUCTION = Flag("STATUS_PRIVILEGED_INSTRUCTION", ( 0xC0000096L ))
|
||||
STATUS_STACK_OVERFLOW = Flag("STATUS_STACK_OVERFLOW", ( 0xC00000FDL ))
|
||||
STATUS_DLL_NOT_FOUND = Flag("STATUS_DLL_NOT_FOUND", ( 0xC0000135L ))
|
||||
STATUS_ORDINAL_NOT_FOUND = Flag("STATUS_ORDINAL_NOT_FOUND", ( 0xC0000138L ))
|
||||
STATUS_ENTRYPOINT_NOT_FOUND = Flag("STATUS_ENTRYPOINT_NOT_FOUND", ( 0xC0000139L ))
|
||||
STATUS_CONTROL_C_EXIT = Flag("STATUS_CONTROL_C_EXIT", ( 0xC000013AL ))
|
||||
STATUS_DLL_INIT_FAILED = Flag("STATUS_DLL_INIT_FAILED", ( 0xC0000142L ))
|
||||
STATUS_FLOAT_MULTIPLE_FAULTS = Flag("STATUS_FLOAT_MULTIPLE_FAULTS", ( 0xC00002B4L ))
|
||||
STATUS_FLOAT_MULTIPLE_TRAPS = Flag("STATUS_FLOAT_MULTIPLE_TRAPS", ( 0xC00002B5L ))
|
||||
STATUS_REG_NAT_CONSUMPTION = Flag("STATUS_REG_NAT_CONSUMPTION", ( 0xC00002C9L ))
|
||||
STATUS_STACK_BUFFER_OVERRUN = Flag("STATUS_STACK_BUFFER_OVERRUN", ( 0xC0000409L ))
|
||||
STATUS_INVALID_CRUNTIME_PARAMETER = Flag("STATUS_INVALID_CRUNTIME_PARAMETER", ( 0xC0000417L ))
|
||||
STATUS_ASSERTION_FAILURE = Flag("STATUS_ASSERTION_FAILURE", ( 0xC0000420L ))
|
||||
STATUS_WAIT_0 = Flag("STATUS_WAIT_0", ( 0x00000000 ))
|
||||
STATUS_ABANDONED_WAIT_0 = Flag("STATUS_ABANDONED_WAIT_0", ( 0x00000080 ))
|
||||
STATUS_USER_APC = Flag("STATUS_USER_APC", ( 0x000000C0 ))
|
||||
STATUS_TIMEOUT = Flag("STATUS_TIMEOUT", ( 0x00000102 ))
|
||||
STATUS_PENDING = Flag("STATUS_PENDING", ( 0x00000103 ))
|
||||
DBG_EXCEPTION_HANDLED = Flag("DBG_EXCEPTION_HANDLED", ( 0x00010001 ))
|
||||
DBG_CONTINUE = Flag("DBG_CONTINUE", ( 0x00010002 ))
|
||||
STATUS_SEGMENT_NOTIFICATION = Flag("STATUS_SEGMENT_NOTIFICATION", ( 0x40000005 ))
|
||||
DBG_TERMINATE_THREAD = Flag("DBG_TERMINATE_THREAD", ( 0x40010003 ))
|
||||
DBG_TERMINATE_PROCESS = Flag("DBG_TERMINATE_PROCESS", ( 0x40010004 ))
|
||||
DBG_CONTROL_C = Flag("DBG_CONTROL_C", ( 0x40010005 ))
|
||||
DBG_PRINTEXCEPTION_C = Flag("DBG_PRINTEXCEPTION_C", ( 0x40010006 ))
|
||||
DBG_RIPEXCEPTION = Flag("DBG_RIPEXCEPTION", ( 0x40010007 ))
|
||||
DBG_CONTROL_BREAK = Flag("DBG_CONTROL_BREAK", ( 0x40010008 ))
|
||||
DBG_COMMAND_EXCEPTION = Flag("DBG_COMMAND_EXCEPTION", ( 0x40010009 ))
|
||||
STATUS_GUARD_PAGE_VIOLATION = Flag("STATUS_GUARD_PAGE_VIOLATION", ( 0x80000001 ))
|
||||
STATUS_DATATYPE_MISALIGNMENT = Flag("STATUS_DATATYPE_MISALIGNMENT", ( 0x80000002 ))
|
||||
STATUS_BREAKPOINT = Flag("STATUS_BREAKPOINT", ( 0x80000003 ))
|
||||
STATUS_SINGLE_STEP = Flag("STATUS_SINGLE_STEP", ( 0x80000004 ))
|
||||
STATUS_LONGJUMP = Flag("STATUS_LONGJUMP", ( 0x80000026 ))
|
||||
STATUS_UNWIND_CONSOLIDATE = Flag("STATUS_UNWIND_CONSOLIDATE", ( 0x80000029 ))
|
||||
DBG_EXCEPTION_NOT_HANDLED = Flag("DBG_EXCEPTION_NOT_HANDLED", ( 0x80010001 ))
|
||||
STATUS_ACCESS_VIOLATION = Flag("STATUS_ACCESS_VIOLATION", ( 0xC0000005 ))
|
||||
STATUS_IN_PAGE_ERROR = Flag("STATUS_IN_PAGE_ERROR", ( 0xC0000006 ))
|
||||
STATUS_INVALID_HANDLE = Flag("STATUS_INVALID_HANDLE", ( 0xC0000008 ))
|
||||
STATUS_INVALID_PARAMETER = Flag("STATUS_INVALID_PARAMETER", ( 0xC000000D ))
|
||||
STATUS_NO_MEMORY = Flag("STATUS_NO_MEMORY", ( 0xC0000017 ))
|
||||
STATUS_ILLEGAL_INSTRUCTION = Flag("STATUS_ILLEGAL_INSTRUCTION", ( 0xC000001D ))
|
||||
STATUS_NONCONTINUABLE_EXCEPTION = Flag("STATUS_NONCONTINUABLE_EXCEPTION", ( 0xC0000025 ))
|
||||
STATUS_INVALID_DISPOSITION = Flag("STATUS_INVALID_DISPOSITION", ( 0xC0000026 ))
|
||||
STATUS_ARRAY_BOUNDS_EXCEEDED = Flag("STATUS_ARRAY_BOUNDS_EXCEEDED", ( 0xC000008C ))
|
||||
STATUS_FLOAT_DENORMAL_OPERAND = Flag("STATUS_FLOAT_DENORMAL_OPERAND", ( 0xC000008D ))
|
||||
STATUS_FLOAT_DIVIDE_BY_ZERO = Flag("STATUS_FLOAT_DIVIDE_BY_ZERO", ( 0xC000008E ))
|
||||
STATUS_FLOAT_INEXACT_RESULT = Flag("STATUS_FLOAT_INEXACT_RESULT", ( 0xC000008F ))
|
||||
STATUS_FLOAT_INVALID_OPERATION = Flag("STATUS_FLOAT_INVALID_OPERATION", ( 0xC0000090 ))
|
||||
STATUS_FLOAT_OVERFLOW = Flag("STATUS_FLOAT_OVERFLOW", ( 0xC0000091 ))
|
||||
STATUS_FLOAT_STACK_CHECK = Flag("STATUS_FLOAT_STACK_CHECK", ( 0xC0000092 ))
|
||||
STATUS_FLOAT_UNDERFLOW = Flag("STATUS_FLOAT_UNDERFLOW", ( 0xC0000093 ))
|
||||
STATUS_INTEGER_DIVIDE_BY_ZERO = Flag("STATUS_INTEGER_DIVIDE_BY_ZERO", ( 0xC0000094 ))
|
||||
STATUS_INTEGER_OVERFLOW = Flag("STATUS_INTEGER_OVERFLOW", ( 0xC0000095 ))
|
||||
STATUS_PRIVILEGED_INSTRUCTION = Flag("STATUS_PRIVILEGED_INSTRUCTION", ( 0xC0000096 ))
|
||||
STATUS_STACK_OVERFLOW = Flag("STATUS_STACK_OVERFLOW", ( 0xC00000FD ))
|
||||
STATUS_DLL_NOT_FOUND = Flag("STATUS_DLL_NOT_FOUND", ( 0xC0000135 ))
|
||||
STATUS_ORDINAL_NOT_FOUND = Flag("STATUS_ORDINAL_NOT_FOUND", ( 0xC0000138 ))
|
||||
STATUS_ENTRYPOINT_NOT_FOUND = Flag("STATUS_ENTRYPOINT_NOT_FOUND", ( 0xC0000139 ))
|
||||
STATUS_CONTROL_C_EXIT = Flag("STATUS_CONTROL_C_EXIT", ( 0xC000013A ))
|
||||
STATUS_DLL_INIT_FAILED = Flag("STATUS_DLL_INIT_FAILED", ( 0xC0000142 ))
|
||||
STATUS_FLOAT_MULTIPLE_FAULTS = Flag("STATUS_FLOAT_MULTIPLE_FAULTS", ( 0xC00002B4 ))
|
||||
STATUS_FLOAT_MULTIPLE_TRAPS = Flag("STATUS_FLOAT_MULTIPLE_TRAPS", ( 0xC00002B5 ))
|
||||
STATUS_REG_NAT_CONSUMPTION = Flag("STATUS_REG_NAT_CONSUMPTION", ( 0xC00002C9 ))
|
||||
STATUS_STACK_BUFFER_OVERRUN = Flag("STATUS_STACK_BUFFER_OVERRUN", ( 0xC0000409 ))
|
||||
STATUS_INVALID_CRUNTIME_PARAMETER = Flag("STATUS_INVALID_CRUNTIME_PARAMETER", ( 0xC0000417 ))
|
||||
STATUS_ASSERTION_FAILURE = Flag("STATUS_ASSERTION_FAILURE", ( 0xC0000420 ))
|
||||
STATUS_POSSIBLE_DEADLOCK = Flag("STATUS_POSSIBLE_DEADLOCK", ( 0xC0000194 ))
|
||||
WAIT_IO_COMPLETION = Flag("WAIT_IO_COMPLETION", STATUS_USER_APC)
|
||||
STILL_ACTIVE = Flag("STILL_ACTIVE", STATUS_PENDING)
|
||||
@@ -176,12 +180,12 @@ TH32CS_SNAPMODULE32 = Flag("TH32CS_SNAPMODULE32", 0x00000010)
|
||||
TH32CS_SNAPALL = Flag("TH32CS_SNAPALL", ( TH32CS_SNAPHEAPLIST | TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD | TH32CS_SNAPMODULE ))
|
||||
TH32CS_INHERIT = Flag("TH32CS_INHERIT", 0x80000000)
|
||||
CONTEXT_I386 = Flag("CONTEXT_I386", 0x00010000)
|
||||
CONTEXT_CONTROL = Flag("CONTEXT_CONTROL", 0x00000001L)
|
||||
CONTEXT_INTEGER = Flag("CONTEXT_INTEGER", 0x00000002L)
|
||||
CONTEXT_SEGMENTS = Flag("CONTEXT_SEGMENTS", 0x00000004L)
|
||||
CONTEXT_FLOATING_POINT = Flag("CONTEXT_FLOATING_POINT", 0x00000008L)
|
||||
CONTEXT_DEBUG_REGISTERS = Flag("CONTEXT_DEBUG_REGISTERS", 0x00000010L)
|
||||
CONTEXT_EXTENDED_REGISTERS = Flag("CONTEXT_EXTENDED_REGISTERS", 0x00000020L)
|
||||
CONTEXT_CONTROL = Flag("CONTEXT_CONTROL", 0x00000001)
|
||||
CONTEXT_INTEGER = Flag("CONTEXT_INTEGER", 0x00000002)
|
||||
CONTEXT_SEGMENTS = Flag("CONTEXT_SEGMENTS", 0x00000004)
|
||||
CONTEXT_FLOATING_POINT = Flag("CONTEXT_FLOATING_POINT", 0x00000008)
|
||||
CONTEXT_DEBUG_REGISTERS = Flag("CONTEXT_DEBUG_REGISTERS", 0x00000010)
|
||||
CONTEXT_EXTENDED_REGISTERS = Flag("CONTEXT_EXTENDED_REGISTERS", 0x00000020)
|
||||
CONTEXT_FULL = Flag("CONTEXT_FULL", ( CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS ))
|
||||
CONTEXT_ALL = Flag("CONTEXT_ALL", ( CONTEXT_FULL | CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS | CONTEXT_EXTENDED_REGISTERS ))
|
||||
CONTEXT_FULL = Flag("CONTEXT_FULL", CONTEXT_I386 | CONTEXT_FULL)
|
||||
@@ -221,17 +225,17 @@ SEC_WRITECOMBINE = Flag("SEC_WRITECOMBINE", 0x40000000)
|
||||
SEC_LARGE_PAGES = Flag("SEC_LARGE_PAGES", 0x80000000)
|
||||
MEM_IMAGE = Flag("MEM_IMAGE", SEC_IMAGE)
|
||||
WRITE_WATCH_FLAG_RESET = Flag("WRITE_WATCH_FLAG_RESET", 0x01)
|
||||
DELETE = Flag("DELETE", ( 0x00010000L ))
|
||||
READ_CONTROL = Flag("READ_CONTROL", ( 0x00020000L ))
|
||||
WRITE_DAC = Flag("WRITE_DAC", ( 0x00040000L ))
|
||||
WRITE_OWNER = Flag("WRITE_OWNER", ( 0x00080000L ))
|
||||
SYNCHRONIZE = Flag("SYNCHRONIZE", ( 0x00100000L ))
|
||||
STANDARD_RIGHTS_REQUIRED = Flag("STANDARD_RIGHTS_REQUIRED", ( 0x000F0000L ))
|
||||
DELETE = Flag("DELETE", ( 0x00010000 ))
|
||||
READ_CONTROL = Flag("READ_CONTROL", ( 0x00020000 ))
|
||||
WRITE_DAC = Flag("WRITE_DAC", ( 0x00040000 ))
|
||||
WRITE_OWNER = Flag("WRITE_OWNER", ( 0x00080000 ))
|
||||
SYNCHRONIZE = Flag("SYNCHRONIZE", ( 0x00100000 ))
|
||||
STANDARD_RIGHTS_REQUIRED = Flag("STANDARD_RIGHTS_REQUIRED", ( 0x000F0000 ))
|
||||
STANDARD_RIGHTS_READ = Flag("STANDARD_RIGHTS_READ", ( READ_CONTROL ))
|
||||
STANDARD_RIGHTS_WRITE = Flag("STANDARD_RIGHTS_WRITE", ( READ_CONTROL ))
|
||||
STANDARD_RIGHTS_EXECUTE = Flag("STANDARD_RIGHTS_EXECUTE", ( READ_CONTROL ))
|
||||
STANDARD_RIGHTS_ALL = Flag("STANDARD_RIGHTS_ALL", ( 0x001F0000L ))
|
||||
SPECIFIC_RIGHTS_ALL = Flag("SPECIFIC_RIGHTS_ALL", ( 0x0000FFFFL ))
|
||||
STANDARD_RIGHTS_ALL = Flag("STANDARD_RIGHTS_ALL", ( 0x001F0000 ))
|
||||
SPECIFIC_RIGHTS_ALL = Flag("SPECIFIC_RIGHTS_ALL", ( 0x0000FFFF ))
|
||||
TOKEN_ASSIGN_PRIMARY = Flag("TOKEN_ASSIGN_PRIMARY", ( 0x0001 ))
|
||||
TOKEN_DUPLICATE = Flag("TOKEN_DUPLICATE", ( 0x0002 ))
|
||||
TOKEN_IMPERSONATE = Flag("TOKEN_IMPERSONATE", ( 0x0004 ))
|
||||
@@ -243,10 +247,10 @@ TOKEN_ADJUST_DEFAULT = Flag("TOKEN_ADJUST_DEFAULT", ( 0x0080 ))
|
||||
TOKEN_ADJUST_SESSIONID = Flag("TOKEN_ADJUST_SESSIONID", ( 0x0100 ))
|
||||
TOKEN_ALL_ACCESS_P = Flag("TOKEN_ALL_ACCESS_P", ( STANDARD_RIGHTS_REQUIRED | TOKEN_ASSIGN_PRIMARY | TOKEN_DUPLICATE | TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_QUERY_SOURCE | TOKEN_ADJUST_PRIVILEGES | TOKEN_ADJUST_GROUPS | TOKEN_ADJUST_DEFAULT ))
|
||||
TOKEN_ALL_ACCESS = Flag("TOKEN_ALL_ACCESS", ( TOKEN_ALL_ACCESS_P | TOKEN_ADJUST_SESSIONID ))
|
||||
SE_PRIVILEGE_ENABLED_BY_DEFAULT = Flag("SE_PRIVILEGE_ENABLED_BY_DEFAULT", ( 0x00000001L ))
|
||||
SE_PRIVILEGE_ENABLED = Flag("SE_PRIVILEGE_ENABLED", ( 0x00000002L ))
|
||||
SE_PRIVILEGE_REMOVED = Flag("SE_PRIVILEGE_REMOVED", ( 0X00000004L ))
|
||||
SE_PRIVILEGE_USED_FOR_ACCESS = Flag("SE_PRIVILEGE_USED_FOR_ACCESS", ( 0x80000000L ))
|
||||
SE_PRIVILEGE_ENABLED_BY_DEFAULT = Flag("SE_PRIVILEGE_ENABLED_BY_DEFAULT", ( 0x00000001 ))
|
||||
SE_PRIVILEGE_ENABLED = Flag("SE_PRIVILEGE_ENABLED", ( 0x00000002 ))
|
||||
SE_PRIVILEGE_REMOVED = Flag("SE_PRIVILEGE_REMOVED", ( 0X00000004 ))
|
||||
SE_PRIVILEGE_USED_FOR_ACCESS = Flag("SE_PRIVILEGE_USED_FOR_ACCESS", ( 0x80000000 ))
|
||||
AF_UNSPEC = Flag("AF_UNSPEC", 0)
|
||||
AF_UNIX = Flag("AF_UNIX", 1)
|
||||
AF_INET = Flag("AF_INET", 2)
|
||||
@@ -360,4 +364,77 @@ EXCEPTION_POSSIBLE_DEADLOCK = Flag("EXCEPTION_POSSIBLE_DEADLOCK", STATUS_POSSIBL
|
||||
CONTROL_C_EXIT = Flag("CONTROL_C_EXIT", STATUS_CONTROL_C_EXIT)
|
||||
EXCEPTION_EXECUTE_HANDLER = Flag("EXCEPTION_EXECUTE_HANDLER", 1)
|
||||
EXCEPTION_CONTINUE_SEARCH = Flag("EXCEPTION_CONTINUE_SEARCH", 0)
|
||||
EXCEPTION_CONTINUE_EXECUTION = Flag("EXCEPTION_CONTINUE_EXECUTION", -1)
|
||||
EXCEPTION_CONTINUE_EXECUTION = Flag("EXCEPTION_CONTINUE_EXECUTION", -1)
|
||||
GENERIC_READ = Flag("GENERIC_READ", ( 0x80000000 ))
|
||||
GENERIC_WRITE = Flag("GENERIC_WRITE", ( 0x40000000 ))
|
||||
GENERIC_EXECUTE = Flag("GENERIC_EXECUTE", ( 0x20000000 ))
|
||||
GENERIC_ALL = Flag("GENERIC_ALL", ( 0x10000000 ))
|
||||
FILE_FLAG_WRITE_THROUGH = Flag("FILE_FLAG_WRITE_THROUGH", 0x80000000)
|
||||
FILE_FLAG_OVERLAPPED = Flag("FILE_FLAG_OVERLAPPED", 0x40000000)
|
||||
FILE_FLAG_NO_BUFFERING = Flag("FILE_FLAG_NO_BUFFERING", 0x20000000)
|
||||
FILE_FLAG_RANDOM_ACCESS = Flag("FILE_FLAG_RANDOM_ACCESS", 0x10000000)
|
||||
FILE_FLAG_SEQUENTIAL_SCAN = Flag("FILE_FLAG_SEQUENTIAL_SCAN", 0x08000000)
|
||||
FILE_FLAG_DELETE_ON_CLOSE = Flag("FILE_FLAG_DELETE_ON_CLOSE", 0x04000000)
|
||||
FILE_FLAG_BACKUP_SEMANTICS = Flag("FILE_FLAG_BACKUP_SEMANTICS", 0x02000000)
|
||||
FILE_FLAG_POSIX_SEMANTICS = Flag("FILE_FLAG_POSIX_SEMANTICS", 0x01000000)
|
||||
FILE_FLAG_OPEN_REPARSE_POINT = Flag("FILE_FLAG_OPEN_REPARSE_POINT", 0x00200000)
|
||||
FILE_FLAG_OPEN_NO_RECALL = Flag("FILE_FLAG_OPEN_NO_RECALL", 0x00100000)
|
||||
FILE_FLAG_FIRST_PIPE_INSTANCE = Flag("FILE_FLAG_FIRST_PIPE_INSTANCE", 0x00080000)
|
||||
CREATE_NEW = Flag("CREATE_NEW", 1)
|
||||
CREATE_ALWAYS = Flag("CREATE_ALWAYS", 2)
|
||||
OPEN_EXISTING = Flag("OPEN_EXISTING", 3)
|
||||
OPEN_ALWAYS = Flag("OPEN_ALWAYS", 4)
|
||||
TRUNCATE_EXISTING = Flag("TRUNCATE_EXISTING", 5)
|
||||
FILE_SHARE_READ = Flag("FILE_SHARE_READ", 0x00000001)
|
||||
FILE_SHARE_WRITE = Flag("FILE_SHARE_WRITE", 0x00000002)
|
||||
FILE_SHARE_DELETE = Flag("FILE_SHARE_DELETE", 0x00000004)
|
||||
FILE_ATTRIBUTE_READONLY = Flag("FILE_ATTRIBUTE_READONLY", 0x00000001)
|
||||
FILE_ATTRIBUTE_HIDDEN = Flag("FILE_ATTRIBUTE_HIDDEN", 0x00000002)
|
||||
FILE_ATTRIBUTE_SYSTEM = Flag("FILE_ATTRIBUTE_SYSTEM", 0x00000004)
|
||||
FILE_ATTRIBUTE_DIRECTORY = Flag("FILE_ATTRIBUTE_DIRECTORY", 0x00000010)
|
||||
FILE_ATTRIBUTE_ARCHIVE = Flag("FILE_ATTRIBUTE_ARCHIVE", 0x00000020)
|
||||
FILE_ATTRIBUTE_DEVICE = Flag("FILE_ATTRIBUTE_DEVICE", 0x00000040)
|
||||
FILE_ATTRIBUTE_NORMAL = Flag("FILE_ATTRIBUTE_NORMAL", 0x00000080)
|
||||
FILE_ATTRIBUTE_TEMPORARY = Flag("FILE_ATTRIBUTE_TEMPORARY", 0x00000100)
|
||||
FILE_ATTRIBUTE_SPARSE_FILE = Flag("FILE_ATTRIBUTE_SPARSE_FILE", 0x00000200)
|
||||
FILE_ATTRIBUTE_REPARSE_POINT = Flag("FILE_ATTRIBUTE_REPARSE_POINT", 0x00000400)
|
||||
FILE_ATTRIBUTE_COMPRESSED = Flag("FILE_ATTRIBUTE_COMPRESSED", 0x00000800)
|
||||
FILE_ATTRIBUTE_OFFLINE = Flag("FILE_ATTRIBUTE_OFFLINE", 0x00001000)
|
||||
FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = Flag("FILE_ATTRIBUTE_NOT_CONTENT_INDEXED", 0x00002000)
|
||||
FILE_ATTRIBUTE_ENCRYPTED = Flag("FILE_ATTRIBUTE_ENCRYPTED", 0x00004000)
|
||||
FILE_ATTRIBUTE_VIRTUAL = Flag("FILE_ATTRIBUTE_VIRTUAL", 0x00010000)
|
||||
FILE_NOTIFY_CHANGE_FILE_NAME = Flag("FILE_NOTIFY_CHANGE_FILE_NAME", 0x00000001)
|
||||
FILE_NOTIFY_CHANGE_DIR_NAME = Flag("FILE_NOTIFY_CHANGE_DIR_NAME", 0x00000002)
|
||||
FILE_NOTIFY_CHANGE_ATTRIBUTES = Flag("FILE_NOTIFY_CHANGE_ATTRIBUTES", 0x00000004)
|
||||
FILE_NOTIFY_CHANGE_SIZE = Flag("FILE_NOTIFY_CHANGE_SIZE", 0x00000008)
|
||||
FILE_NOTIFY_CHANGE_LAST_WRITE = Flag("FILE_NOTIFY_CHANGE_LAST_WRITE", 0x00000010)
|
||||
FILE_NOTIFY_CHANGE_LAST_ACCESS = Flag("FILE_NOTIFY_CHANGE_LAST_ACCESS", 0x00000020)
|
||||
FILE_NOTIFY_CHANGE_CREATION = Flag("FILE_NOTIFY_CHANGE_CREATION", 0x00000040)
|
||||
FILE_NOTIFY_CHANGE_SECURITY = Flag("FILE_NOTIFY_CHANGE_SECURITY", 0x00000100)
|
||||
FILE_ACTION_ADDED = Flag("FILE_ACTION_ADDED", 0x00000001)
|
||||
FILE_ACTION_REMOVED = Flag("FILE_ACTION_REMOVED", 0x00000002)
|
||||
FILE_ACTION_MODIFIED = Flag("FILE_ACTION_MODIFIED", 0x00000003)
|
||||
FILE_ACTION_RENAMED_OLD_NAME = Flag("FILE_ACTION_RENAMED_OLD_NAME", 0x00000004)
|
||||
FILE_ACTION_RENAMED_NEW_NAME = Flag("FILE_ACTION_RENAMED_NEW_NAME", 0x00000005)
|
||||
MAILSLOT_NO_MESSAGE = Flag("MAILSLOT_NO_MESSAGE", ( -1 ))
|
||||
MAILSLOT_WAIT_FOREVER = Flag("MAILSLOT_WAIT_FOREVER", ( -1 ))
|
||||
FILE_CASE_SENSITIVE_SEARCH = Flag("FILE_CASE_SENSITIVE_SEARCH", 0x00000001)
|
||||
FILE_CASE_PRESERVED_NAMES = Flag("FILE_CASE_PRESERVED_NAMES", 0x00000002)
|
||||
FILE_UNICODE_ON_DISK = Flag("FILE_UNICODE_ON_DISK", 0x00000004)
|
||||
FILE_PERSISTENT_ACLS = Flag("FILE_PERSISTENT_ACLS", 0x00000008)
|
||||
FILE_FILE_COMPRESSION = Flag("FILE_FILE_COMPRESSION", 0x00000010)
|
||||
FILE_VOLUME_QUOTAS = Flag("FILE_VOLUME_QUOTAS", 0x00000020)
|
||||
FILE_SUPPORTS_SPARSE_FILES = Flag("FILE_SUPPORTS_SPARSE_FILES", 0x00000040)
|
||||
FILE_SUPPORTS_REPARSE_POINTS = Flag("FILE_SUPPORTS_REPARSE_POINTS", 0x00000080)
|
||||
FILE_SUPPORTS_REMOTE_STORAGE = Flag("FILE_SUPPORTS_REMOTE_STORAGE", 0x00000100)
|
||||
FILE_VOLUME_IS_COMPRESSED = Flag("FILE_VOLUME_IS_COMPRESSED", 0x00008000)
|
||||
FILE_SUPPORTS_OBJECT_IDS = Flag("FILE_SUPPORTS_OBJECT_IDS", 0x00010000)
|
||||
FILE_SUPPORTS_ENCRYPTION = Flag("FILE_SUPPORTS_ENCRYPTION", 0x00020000)
|
||||
FILE_NAMED_STREAMS = Flag("FILE_NAMED_STREAMS", 0x00040000)
|
||||
FILE_READ_ONLY_VOLUME = Flag("FILE_READ_ONLY_VOLUME", 0x00080000)
|
||||
FILE_SEQUENTIAL_WRITE_ONCE = Flag("FILE_SEQUENTIAL_WRITE_ONCE", 0x00100000)
|
||||
FILE_SUPPORTS_TRANSACTIONS = Flag("FILE_SUPPORTS_TRANSACTIONS", 0x00200000)
|
||||
FILE_SUPPORTS_HARD_LINKS = Flag("FILE_SUPPORTS_HARD_LINKS", 0x00400000)
|
||||
FILE_SUPPORTS_EXTENDED_ATTRIBUTES = Flag("FILE_SUPPORTS_EXTENDED_ATTRIBUTES", 0x00800000)
|
||||
FILE_SUPPORTS_OPEN_BY_FILE_ID = Flag("FILE_SUPPORTS_OPEN_BY_FILE_ID", 0x01000000)
|
||||
FILE_SUPPORTS_USN_JOURNAL = Flag("FILE_SUPPORTS_USN_JOURNAL", 0x02000000)
|
||||
@@ -1,9 +1,9 @@
|
||||
#Generated file
|
||||
from ctypes import *
|
||||
from ctypes.wintypes import *
|
||||
from winstructs import *
|
||||
from .winstructs import *
|
||||
|
||||
functions = ['ExitProcess', 'GetLastError', 'GetCurrentProcess', 'CreateFileA', 'CreateFileW', 'NtQuerySystemInformation', 'VirtualAlloc', 'VirtualAllocEx', 'VirtualProtect', 'VirtualQuery', 'GetModuleFileNameA', 'GetModuleFileNameW', 'CreateThread', 'CreateRemoteThread', 'VirtualProtect', 'CreateProcessA', 'CreateProcessW', 'GetThreadContext', 'SetThreadContext', 'OpenThread', 'OpenProcess', 'CloseHandle', 'ReadProcessMemory', 'WriteProcessMemory', 'CreateToolhelp32Snapshot', 'Thread32First', 'Thread32Next', 'Process32First', 'Process32Next', 'Process32FirstW', 'Process32NextW', 'GetProcAddress', 'LoadLibraryA', 'LoadLibraryW', 'OpenProcessToken', 'LookupPrivilegeValueA', 'LookupPrivilegeValueW', 'AdjustTokenPrivileges', 'FindResourceA', 'FindResourceW', 'SizeofResource', 'LoadResource', 'LockResource', 'GetVersionExA', 'GetVersionExW', 'GetVersion', 'GetCurrentThread', 'GetCurrentThreadId', 'GetCurrentProcessorNumber', 'AllocConsole', 'GetStdHandle', 'SetStdHandle', 'SetThreadAffinityMask', 'WriteFile', 'GetExtendedTcpTable', 'GetExtendedUdpTable', 'SetTcpEntry', 'AddVectoredContinueHandler', 'AddVectoredExceptionHandler', 'TerminateThread', 'ExitThread', 'RemoveVectoredExceptionHandler', 'ResumeThread', 'SuspendThread', 'WaitForSingleObject']
|
||||
functions = ['ExitProcess', 'GetLastError', 'GetCurrentProcess', 'CreateFileA', 'CreateFileW', 'NtQuerySystemInformation', 'VirtualAlloc', 'VirtualAllocEx', 'VirtualProtect', 'VirtualQuery', 'GetModuleFileNameA', 'GetModuleFileNameW', 'CreateThread', 'CreateRemoteThread', 'VirtualProtect', 'CreateProcessA', 'CreateProcessW', 'GetThreadContext', 'SetThreadContext', 'OpenThread', 'OpenProcess', 'CloseHandle', 'ReadProcessMemory', 'WriteProcessMemory', 'CreateToolhelp32Snapshot', 'Thread32First', 'Thread32Next', 'Process32First', 'Process32Next', 'Process32FirstW', 'Process32NextW', 'GetProcAddress', 'LoadLibraryA', 'LoadLibraryW', 'OpenProcessToken', 'LookupPrivilegeValueA', 'LookupPrivilegeValueW', 'AdjustTokenPrivileges', 'FindResourceA', 'FindResourceW', 'SizeofResource', 'LoadResource', 'LockResource', 'GetVersionExA', 'GetVersionExW', 'GetVersion', 'GetCurrentThread', 'GetCurrentThreadId', 'GetCurrentProcessorNumber', 'AllocConsole', 'GetStdHandle', 'SetStdHandle', 'SetThreadAffinityMask', 'WriteFile', 'GetExtendedTcpTable', 'GetExtendedUdpTable', 'SetTcpEntry', 'AddVectoredContinueHandler', 'AddVectoredExceptionHandler', 'TerminateThread', 'ExitThread', 'RemoveVectoredExceptionHandler', 'ResumeThread', 'SuspendThread', 'WaitForSingleObject', 'GetThreadId']
|
||||
|
||||
# ExitProcess(uExitCode):
|
||||
ExitProcessPrototype = WINFUNCTYPE(VOID, UINT)
|
||||
@@ -265,3 +265,7 @@ SuspendThreadParams = ((1, 'hThread'),)
|
||||
WaitForSingleObjectPrototype = WINFUNCTYPE(DWORD, HANDLE, DWORD)
|
||||
WaitForSingleObjectParams = ((1, 'hHandle'), (1, 'dwMilliseconds'))
|
||||
|
||||
# GetThreadId(Thread):
|
||||
GetThreadIdPrototype = WINFUNCTYPE(DWORD, HANDLE)
|
||||
GetThreadIdParams = ((1, 'Thread'),)
|
||||
|
||||
|
||||
+32
-35
@@ -1,7 +1,7 @@
|
||||
#Generated file
|
||||
from ctypes import *
|
||||
from ctypes.wintypes import *
|
||||
from windef import *
|
||||
from .windef import *
|
||||
|
||||
PWSTR = LPWSTR
|
||||
SIZE_T = c_ulong
|
||||
@@ -28,7 +28,7 @@ PHANDLE = POINTER(HANDLE)
|
||||
LPCONTEXT = PVOID
|
||||
VOID = DWORD
|
||||
|
||||
structs = ['_LIST_ENTRY', '_PEB_LDR_DATA', '_LSA_UNICODE_STRING', '_RTL_USER_PROCESS_PARAMETERS', '_PEB', '_SECURITY_ATTRIBUTES', '_SYSTEM_VERIFIER_INFORMATION', '_LDR_DATA_TABLE_ENTRY', '_IMAGE_FILE_HEADER', '_IMAGE_DATA_DIRECTORY', '_IMAGE_SECTION_HEADER', '_IMAGE_OPTIONAL_HEADER64', '_IMAGE_OPTIONAL_HEADER', '_IMAGE_NT_HEADERS64', '_IMAGE_NT_HEADERS', '_IMAGE_IMPORT_DESCRIPTOR', '_IMAGE_IMPORT_BY_NAME', '_MEMORY_BASIC_INFORMATION', '_STARTUPINFOA', '_STARTUPINFOW', '_PROCESS_INFORMATION', '_FLOATING_SAVE_AREA', '_CONTEXT32', '_M128A', '_CONTEXT64', 'tagPROCESSENTRY32W', 'tagPROCESSENTRY32', 'tagTHREADENTRY32', '_LUID', '_LUID_AND_ATTRIBUTES', '_TOKEN_PRIVILEGES', '_OSVERSIONINFOA', '_OSVERSIONINFOW', '_OSVERSIONINFOEXA', '_OSVERSIONINFOEXW', '_OVERLAPPED', '_MIB_TCPROW_OWNER_PID', '_MIB_TCPTABLE_OWNER_PID', '_MIB_UDPROW_OWNER_PID', '_MIB_UDPTABLE_OWNER_PID', '_MIB_UDP6ROW_OWNER_PID', '_MIB_UDP6TABLE_OWNER_PID', '_MIB_TCP6ROW_OWNER_PID', '_MIB_TCP6TABLE_OWNER_PID', '_MIB_TCPROW', '_EXCEPTION_RECORD', '_EXCEPTION_POINTERS64', '_EXCEPTION_POINTERS32']
|
||||
structs = ['_LIST_ENTRY', '_PEB_LDR_DATA', '_LSA_UNICODE_STRING', '_RTL_USER_PROCESS_PARAMETERS', '_PEB', '_SECURITY_ATTRIBUTES', '_SYSTEM_VERIFIER_INFORMATION', '_LDR_DATA_TABLE_ENTRY', '_IMAGE_FILE_HEADER', '_IMAGE_DATA_DIRECTORY', '_IMAGE_SECTION_HEADER', '_IMAGE_OPTIONAL_HEADER64', '_IMAGE_OPTIONAL_HEADER', '_IMAGE_NT_HEADERS64', '_IMAGE_NT_HEADERS', '_IMAGE_IMPORT_DESCRIPTOR', '_IMAGE_IMPORT_BY_NAME', '_IMAGE_EXPORT_DIRECTORY', '_MEMORY_BASIC_INFORMATION', '_STARTUPINFOA', '_STARTUPINFOW', '_PROCESS_INFORMATION', '_FLOATING_SAVE_AREA', '_CONTEXT32', '_M128A', '_CONTEXT64', 'tagPROCESSENTRY32W', 'tagPROCESSENTRY32', 'tagTHREADENTRY32', '_LUID', '_LUID_AND_ATTRIBUTES', '_TOKEN_PRIVILEGES', '_OSVERSIONINFOA', '_OSVERSIONINFOW', '_OSVERSIONINFOEXA', '_OSVERSIONINFOEXW', '_OVERLAPPED', '_MIB_TCPROW_OWNER_PID', '_MIB_TCPTABLE_OWNER_PID', '_MIB_UDPROW_OWNER_PID', '_MIB_UDPTABLE_OWNER_PID', '_MIB_UDP6ROW_OWNER_PID', '_MIB_UDP6TABLE_OWNER_PID', '_MIB_TCP6ROW_OWNER_PID', '_MIB_TCP6TABLE_OWNER_PID', '_MIB_TCPROW', '_EXCEPTION_RECORD', '_EXCEPTION_POINTERS64', '_EXCEPTION_POINTERS32', '_DEBUG_PROCESSOR_IDENTIFICATION_X86']
|
||||
|
||||
enums = ['_SYSTEM_INFORMATION_CLASS', '_TCP_TABLE_CLASS', '_UDP_TABLE_CLASS', '_MIB_TCP_STATE']
|
||||
|
||||
@@ -157,53 +157,22 @@ MIB_TCP_STATE_TIME_WAIT = 0xb
|
||||
MIB_TCP_STATE_DELETE_TCB = 0xc
|
||||
# Struct _LIST_ENTRY definitions
|
||||
# Self referencing struct tricks
|
||||
|
||||
import ctypes
|
||||
|
||||
def pretty_print_ctypes_type(t):
|
||||
format = "{0}"
|
||||
if issubclass(t, ctypes.Array):
|
||||
format = "[{0}" + "* {0}]".format(t._length_)
|
||||
t = t._type_
|
||||
|
||||
if issubclass(t, ctypes._Pointer):
|
||||
format = format.format("Pointer({0})")
|
||||
t = t._type_
|
||||
|
||||
if issubclass(t, ctypes.Structure):
|
||||
return format.format(":class:`{0}`".format(t.__name__))
|
||||
return t
|
||||
|
||||
def autodoc_ctypes_struct(struct):
|
||||
doc = ["fields:"]
|
||||
for name, type in struct._fields_:
|
||||
doc.append(" {0} -> {1}".format(name, pretty_print_ctypes_type(type)))
|
||||
|
||||
struct.__doc__ = "\n\n".join(doc)
|
||||
return struct
|
||||
|
||||
|
||||
class _LIST_ENTRY(Structure): pass
|
||||
_LIST_ENTRY._fields_ = [
|
||||
("Flink", POINTER(_LIST_ENTRY)),
|
||||
("Blink", POINTER(_LIST_ENTRY)),
|
||||
]
|
||||
|
||||
_LIST_ENTRY = autodoc_ctypes_struct(_LIST_ENTRY)
|
||||
|
||||
PLIST_ENTRY = POINTER(_LIST_ENTRY)
|
||||
LIST_ENTRY = _LIST_ENTRY
|
||||
PRLIST_ENTRY = POINTER(_LIST_ENTRY)
|
||||
|
||||
# Struct _PEB_LDR_DATA definitions
|
||||
@autodoc_ctypes_struct
|
||||
class _PEB_LDR_DATA(Structure):
|
||||
_fields_ = [
|
||||
_fields_ = [
|
||||
("Reserved1", BYTE * 8),
|
||||
("Reserved2", PVOID * 3),
|
||||
("InMemoryOrderModuleList", LIST_ENTRY),
|
||||
]
|
||||
|
||||
PPEB_LDR_DATA = POINTER(_PEB_LDR_DATA)
|
||||
PEB_LDR_DATA = _PEB_LDR_DATA
|
||||
|
||||
@@ -231,7 +200,6 @@ PRTL_USER_PROCESS_PARAMETERS = POINTER(_RTL_USER_PROCESS_PARAMETERS)
|
||||
RTL_USER_PROCESS_PARAMETERS = _RTL_USER_PROCESS_PARAMETERS
|
||||
|
||||
# Struct _PEB definitions
|
||||
@autodoc_ctypes_struct
|
||||
class _PEB(Structure):
|
||||
_fields_ = [
|
||||
("Reserved1", BYTE * 2),
|
||||
@@ -467,6 +435,24 @@ class _IMAGE_IMPORT_BY_NAME(Structure):
|
||||
PIMAGE_IMPORT_BY_NAME = POINTER(_IMAGE_IMPORT_BY_NAME)
|
||||
IMAGE_IMPORT_BY_NAME = _IMAGE_IMPORT_BY_NAME
|
||||
|
||||
# Struct _IMAGE_EXPORT_DIRECTORY definitions
|
||||
class _IMAGE_EXPORT_DIRECTORY(Structure):
|
||||
_fields_ = [
|
||||
("Characteristics", DWORD),
|
||||
("TimeDateStamp", DWORD),
|
||||
("MajorVersion", WORD),
|
||||
("MinorVersion", WORD),
|
||||
("Name", DWORD),
|
||||
("Base", DWORD),
|
||||
("NumberOfFunctions", DWORD),
|
||||
("NumberOfNames", DWORD),
|
||||
("AddressOfFunctions", DWORD),
|
||||
("AddressOfNames", DWORD),
|
||||
("AddressOfNameOrdinals", DWORD),
|
||||
]
|
||||
IMAGE_EXPORT_DIRECTORY = _IMAGE_EXPORT_DIRECTORY
|
||||
PIMAGE_EXPORT_DIRECTORY = POINTER(_IMAGE_EXPORT_DIRECTORY)
|
||||
|
||||
# Struct _MEMORY_BASIC_INFORMATION definitions
|
||||
class _MEMORY_BASIC_INFORMATION(Structure):
|
||||
_fields_ = [
|
||||
@@ -959,3 +945,14 @@ class _EXCEPTION_POINTERS32(Structure):
|
||||
PEXCEPTION_POINTERS32 = POINTER(_EXCEPTION_POINTERS32)
|
||||
EXCEPTION_POINTERS32 = _EXCEPTION_POINTERS32
|
||||
|
||||
# Struct _DEBUG_PROCESSOR_IDENTIFICATION_X86 definitions
|
||||
class _DEBUG_PROCESSOR_IDENTIFICATION_X86(Structure):
|
||||
_fields_ = [
|
||||
("Family", ULONG),
|
||||
("Model", ULONG),
|
||||
("Stepping", ULONG),
|
||||
("VendorString", CHAR * 16),
|
||||
]
|
||||
DEBUG_PROCESSOR_IDENTIFICATION_X86 = _DEBUG_PROCESSOR_IDENTIFICATION_X86
|
||||
PDEBUG_PROCESSOR_IDENTIFICATION_X86 = POINTER(_DEBUG_PROCESSOR_IDENTIFICATION_X86)
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import sys
|
||||
import utils
|
||||
import native_exec
|
||||
import ctypes
|
||||
import windows.generated_def.winfuncs as winfuncs
|
||||
import windows.generated_def.windef as windef
|
||||
from windows.generated_def.winstructs import *
|
||||
|
||||
import windows.utils as utils
|
||||
from . import native_exec
|
||||
from .generated_def import winfuncs, windef
|
||||
from .generated_def.winstructs import *
|
||||
|
||||
|
||||
class Callback(object):
|
||||
|
||||
+50
-45
@@ -1,86 +1,91 @@
|
||||
import sys
|
||||
import os
|
||||
import utils
|
||||
import windows
|
||||
|
||||
import windows
|
||||
import windows.utils as utils
|
||||
|
||||
from .native_exec import simple_x86 as x86
|
||||
from .native_exec import simple_x64 as x64
|
||||
|
||||
# 32 to 32 injection
|
||||
def generate_python_exec_shellcode_32(PYDLL_addr, PyInit, PyRun, PYCODE_ADDR):
|
||||
from native_exec.simple_x86 import *
|
||||
LoadLibraryA = utils.get_func_addr('kernel32', 'LoadLibraryA')
|
||||
GetProcAddress = utils.get_func_addr('kernel32', 'GetProcAddress')
|
||||
code = MultipleInstr()
|
||||
print("LoadLibraryA = {0}".format(hex(LoadLibraryA)))
|
||||
print("LoadLibraryA = {0}".format(hex(GetProcAddress)))
|
||||
|
||||
code = x86.MultipleInstr()
|
||||
# Load python27.dll
|
||||
code += Push_X(PYDLL_addr)
|
||||
code += Mov_EAX_X(LoadLibraryA)
|
||||
code += Call_EAX()
|
||||
code += x86.Push(PYDLL_addr)
|
||||
code += x86.Mov('EAX', LoadLibraryA)
|
||||
code += x86.Call('EAX')
|
||||
# Get PyInit function into pythondll
|
||||
code += Push_EAX()
|
||||
code += Pop_EDI()
|
||||
code += Push_X(PyInit)
|
||||
code += Push_EDI()
|
||||
code += Mov_EBX_X(GetProcAddress)
|
||||
code += Call_EBX()
|
||||
code += x86.Push('EAX')
|
||||
code += x86.Pop('EDI')
|
||||
code += x86.Push(PyInit)
|
||||
code += x86.Push('EDI')
|
||||
code += x86.Mov('EBX', GetProcAddress)
|
||||
code += x86.Call('EBX')
|
||||
# Call PyInit
|
||||
code += Call_EAX()
|
||||
code += x86.Call('EAX')
|
||||
# Get PyRun function into pythondll
|
||||
code += Push_X(PyRun)
|
||||
code += Push_EDI()
|
||||
code += Call_EBX()
|
||||
code += x86.Push(PyRun)
|
||||
code += x86.Push('EDI')
|
||||
code += x86.Call('EBX')
|
||||
# Call PyRun with python code to exec
|
||||
code += Push_X(PYCODE_ADDR)
|
||||
code += Call_EAX()
|
||||
code += Pop_EDI()
|
||||
code += Ret()
|
||||
code += x86.Push(PYCODE_ADDR)
|
||||
code += x86.Call('EAX')
|
||||
code += x86.Pop('EDI')
|
||||
code += x86.Ret()
|
||||
return code.get_code()
|
||||
|
||||
# 64 to 64 injection
|
||||
def generate_python_exec_shellcode_64(PYDLL_addr, PyInit, PyRun, PYCODE_ADDR):
|
||||
from native_exec.simple_x64 import *
|
||||
|
||||
LoadLibraryA = utils.get_func_addr('kernel32', 'LoadLibraryA')
|
||||
GetProcAddress = utils.get_func_addr('kernel32', 'GetProcAddress')
|
||||
|
||||
Reserve_space_for_call = MultipleInstr([Push_RDI()] * 4)
|
||||
Clean_space_for_call = MultipleInstr([Pop_RDI()] * 4)
|
||||
Reserve_space_for_call = x64.MultipleInstr([x64.Push('RDI')] * 4)
|
||||
Clean_space_for_call = x64.MultipleInstr([x64.Pop('RDI')] * 4)
|
||||
|
||||
code = MultipleInstr()
|
||||
code = x64.MultipleInstr()
|
||||
# Do stack alignement
|
||||
code += Push_RAX()
|
||||
code += x64.Push('RAX')
|
||||
# Load python27.dll
|
||||
code += Mov_RCX_X(PYDLL_addr)
|
||||
code += Mov_RAX_X(LoadLibraryA)
|
||||
code += x64.Mov('RCX', PYDLL_addr)
|
||||
code += x64.Mov('RAX', LoadLibraryA)
|
||||
code += Reserve_space_for_call
|
||||
code += Call_RAX()
|
||||
code += x64.Call('RAX')
|
||||
code += Clean_space_for_call
|
||||
code += Push_RAX()
|
||||
code += Pop_RCX()
|
||||
code += x64.Push('RAX')
|
||||
code += x64.Pop('RCX')
|
||||
# Save RCX
|
||||
code += Push_RCX()
|
||||
code += x64.Push('RCX')
|
||||
# Align stack
|
||||
code += Push_RDI()
|
||||
code += x64.Push('RDI')
|
||||
# Get PyInit function into pythondll
|
||||
code += Reserve_space_for_call
|
||||
code += Mov_RDX_X(PyInit)
|
||||
code += Mov_RBX_X(GetProcAddress)
|
||||
code += Call_RBX()
|
||||
code += x64.Mov('RDX', PyInit)
|
||||
code += x64.Mov('RBX', GetProcAddress)
|
||||
code += x64.Call('RBX')
|
||||
# Call PyInit
|
||||
code += Call_RAX()
|
||||
code += x64.Call('RAX')
|
||||
code += Clean_space_for_call
|
||||
# Remove Stack align
|
||||
code += Pop_RDI()
|
||||
code += x64.Pop('RDI')
|
||||
# Restore pythondll base into rcx
|
||||
code += Pop_RCX()
|
||||
code += x64.Pop('RCX')
|
||||
# Get PyRun function into pythondll
|
||||
code += Mov_RDX_X(PyRun)
|
||||
code += x64.Mov('RDX', PyRun)
|
||||
code += Reserve_space_for_call
|
||||
code += Call_RBX()
|
||||
code += x64.Call('RBX')
|
||||
# Call PyInit with python code to exec
|
||||
code += Mov_RCX_X(PYCODE_ADDR)
|
||||
code += Call_RAX()
|
||||
code += x64.Mov('RCX', PYCODE_ADDR)
|
||||
code += x64.Call('RAX')
|
||||
code += Clean_space_for_call
|
||||
# Remove stack alignement
|
||||
code += Pop_RAX()
|
||||
code += Ret()
|
||||
code += x64.Pop('RAX')
|
||||
code += x64.Ret()
|
||||
return code.get_code()
|
||||
|
||||
|
||||
|
||||
+21
-3
@@ -45,12 +45,24 @@ class IphlpapiError(Kernel32Error):
|
||||
def no_error_check(func_name, result, func, args):
|
||||
"""Nothing special"""
|
||||
return args
|
||||
|
||||
def minus_one_error_check(func_name, result, func, args):
|
||||
if result == -1:
|
||||
raise Kernel32Error(func_name)
|
||||
return args
|
||||
|
||||
|
||||
def kernel32_error_check(func_name, result, func, args):
|
||||
"""raise Kernel32Error if result is 0"""
|
||||
if not result:
|
||||
raise Kernel32Error(func_name)
|
||||
return args
|
||||
|
||||
def kernel32_zero_check(func_name, result, func, args):
|
||||
"""raise Kernel32Error if result is NOT 0"""
|
||||
if result:
|
||||
raise Kernel32Error(func_name)
|
||||
return args
|
||||
|
||||
def iphlpapi_error_check(func_name, result, func, args):
|
||||
"""raise IphlpapiError if result is NOT 0"""
|
||||
@@ -145,8 +157,14 @@ GetCurrentThreadId = TransparentKernel32Proxy("GetCurrentThreadId")
|
||||
|
||||
TerminateThread = TransparentKernel32Proxy("TerminateThread")
|
||||
ExitThread = TransparentKernel32Proxy("ExitThread")
|
||||
SuspendThread = TransparentKernel32Proxy("SuspendThread")
|
||||
ResumeThread = TransparentKernel32Proxy("ResumeThread")
|
||||
SuspendThread = TransparentKernel32Proxy("SuspendThread", minus_one_error_check)
|
||||
ResumeThread = TransparentKernel32Proxy("ResumeThread", minus_one_error_check)
|
||||
GetThreadId = TransparentKernel32Proxy("GetThreadId")
|
||||
|
||||
|
||||
@Kernel32Proxy("CreateFileA")
|
||||
def CreateFileA(lpFileName, dwDesiredAccess, dwShareMode=0, lpSecurityAttributes=None, dwCreationDisposition=OPEN_EXISTING, dwFlagsAndAttributes=FILE_ATTRIBUTE_NORMAL, hTemplateFile=None):
|
||||
return CreateFileA.ctypes_function(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile)
|
||||
|
||||
# This kind of function could be fully done by using paramflags
|
||||
@Kernel32Proxy("VirtualAlloc")
|
||||
@@ -292,7 +310,7 @@ def AddVectoredExceptionHandler(FirstHandler=1, VectoredHandler=NeededParameter)
|
||||
def RemoveVectoredExceptionHandler(Handler):
|
||||
return RemoveVectoredExceptionHandler.ctypes_function(Handler)
|
||||
|
||||
@Kernel32Proxy("WaitForSingleObject", no_error_check)
|
||||
@Kernel32Proxy("WaitForSingleObject", kernel32_zero_check)
|
||||
def WaitForSingleObject(hHandle, dwMilliseconds=INFINITE):
|
||||
return WaitForSingleObject.ctypes_function(hHandle, dwMilliseconds)
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
from native_function import generate_callback_stub, create_function
|
||||
from .native_function import generate_callback_stub, create_function
|
||||
+100
-97
@@ -5,6 +5,9 @@ import platform
|
||||
import windows
|
||||
import windows.k32testing as k32api
|
||||
|
||||
from . import simple_x86 as x86
|
||||
#from . import simple_x64 as x64
|
||||
|
||||
class PyObj(ctypes.Structure):
|
||||
_fields_ = [("ob_refcnt", ctypes.c_size_t),
|
||||
("ob_type", ctypes.c_void_p)] #must be cast
|
||||
@@ -116,7 +119,7 @@ def analyse_callback(callback):
|
||||
|
||||
# For windows 32 bits with stdcall
|
||||
def generate_stub_32(callback):
|
||||
from simple_x86 import *
|
||||
|
||||
allocator = windows.current_process.allocator
|
||||
obj_id = analyse_callback(callback)
|
||||
|
||||
@@ -124,65 +127,64 @@ def generate_stub_32(callback):
|
||||
gstate_save_addr = allocator.reserve_int()
|
||||
return_addr_save_addr = allocator.reserve_int()
|
||||
|
||||
save_ebx = allocator.reserve_int()
|
||||
save_ecx = allocator.reserve_int()
|
||||
save_edx = allocator.reserve_int()
|
||||
save_esi = allocator.reserve_int()
|
||||
save_edi = allocator.reserve_int()
|
||||
save_ebx = x86.create_displacement(disp=allocator.reserve_int())
|
||||
save_ecx = x86.create_displacement(disp=allocator.reserve_int())
|
||||
save_edx = x86.create_displacement(disp=allocator.reserve_int())
|
||||
save_esi = x86.create_displacement(disp=allocator.reserve_int())
|
||||
save_edi = x86.create_displacement(disp=allocator.reserve_int())
|
||||
|
||||
ensure, objcall, release = get_functions()
|
||||
|
||||
code = x86.MultipleInstr()
|
||||
|
||||
### Shellcode ###
|
||||
code = MultipleInstr()
|
||||
|
||||
code += Mov_DX_EBX(save_ebx)
|
||||
code += Mov_DX_ECX(save_ecx)
|
||||
code += Mov_DX_EDX(save_edx)
|
||||
code += Mov_DX_ESI(save_esi)
|
||||
code += Mov_DX_EDI(save_edi)
|
||||
|
||||
code += Mov_EAX_X(ensure)
|
||||
code += Call_EAX()
|
||||
code += Mov_DX_EAX(gstate_save_addr)
|
||||
|
||||
code += x86.Mov(save_ebx, 'EBX')
|
||||
code += x86.Mov(save_ecx, 'ECX')
|
||||
code += x86.Mov(save_edx, 'EDX')
|
||||
code += x86.Mov(save_esi, 'ESI')
|
||||
code += x86.Mov(save_edi, 'EDI')
|
||||
|
||||
code += x86.Mov('EAX', ensure)
|
||||
code += x86.Call('EAX')
|
||||
code += x86.Mov(gstate_save_addr, 'EAX')
|
||||
|
||||
#Save real return addr (for good argument parsing by the callback)
|
||||
|
||||
code += Pop_EAX()
|
||||
code += Mov_DX_EAX(return_addr_save_addr)
|
||||
|
||||
|
||||
code += x86.Pop('EAX')
|
||||
code += x86.Mov(return_addr_save_addr, 'EAX')
|
||||
|
||||
# Set call_real_function to 0 (no call by default)
|
||||
|
||||
code += Mov_EAX_X(c_callback)
|
||||
code += Call_EAX()
|
||||
|
||||
|
||||
code += x86.Mov('EAX', c_callback)
|
||||
code += x86.Call('EAX')
|
||||
|
||||
# Restore real return value
|
||||
code += Mov_EBX_DX(return_addr_save_addr)
|
||||
code += Push_EBX()
|
||||
|
||||
code += x86.Mov('EBX', return_addr_save_addr)
|
||||
code += x86.Push('EBX')
|
||||
|
||||
# Save return value
|
||||
code += Push_EAX()
|
||||
code += Mov_EBX_DX(gstate_save_addr)
|
||||
code += Push_EBX()
|
||||
|
||||
code += Mov_EAX_X(release)
|
||||
code += Call_EAX()
|
||||
|
||||
code += x86.Push('EAX')
|
||||
code += x86.Mov('EBX', gstate_save_addr)
|
||||
code += x86.Push('EBX')
|
||||
|
||||
code += x86.Mov('EAX', release)
|
||||
code += x86.Call('EAX')
|
||||
|
||||
# Discard `release` argument
|
||||
code += Pop_EAX()
|
||||
code += x86.Pop('EAX')
|
||||
# Restore return value
|
||||
code += Pop_EAX()
|
||||
code += Mov_EBX_DX(save_ebx)
|
||||
code += Mov_ECX_DX(save_ecx)
|
||||
code += Mov_EDX_DX(save_edx)
|
||||
code += Mov_ESI_DX(save_esi)
|
||||
code += Mov_EDI_DX(save_edi)
|
||||
code += Ret()
|
||||
code += x86.Pop('EAX')
|
||||
code += x86.Mov('EBX', save_ebx)
|
||||
code += x86.Mov('ECX', save_ecx)
|
||||
code += x86.Mov('EDX', save_edx)
|
||||
code += x86.Mov('ESI', save_esi)
|
||||
code += x86.Mov('EDI', save_edi)
|
||||
code += x86.Ret()
|
||||
return code
|
||||
|
||||
# For windows 32 bits with stdcall
|
||||
def generate_stub_64(callback):
|
||||
import simple_x64 as x64
|
||||
from simple_x64 import *
|
||||
|
||||
allocator = windows.current_process.allocator
|
||||
obj_id = analyse_callback(callback)
|
||||
|
||||
@@ -191,8 +193,9 @@ def generate_stub_64(callback):
|
||||
c_callback = ctypes.c_ulong.from_address(id(callback._objects['0']) + 3 * ctypes.sizeof(ctypes.c_void_p)).value
|
||||
|
||||
register_to_save = ("RBX", "RCX", "RDX", "RSI", "RDI", "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15")
|
||||
push_all_save_register = MultipleInstr([getattr(x64, "Push_" + reg)() for reg in register_to_save])
|
||||
pop_all_save_register = MultipleInstr([getattr(x64, "Pop_" + reg)() for reg in reversed(register_to_save)])
|
||||
|
||||
push_all_save_register = x64.MultipleInstr([x64.Push(reg) for reg in register_to_save])
|
||||
pop_all_save_register = x64.MultipleInstr([x64.Pop(reg) for reg in register_to_save])
|
||||
# Reserve parallel `stack`
|
||||
save_register_space = allocator.reserve_int(len(register_to_save) + 1)
|
||||
save_register_space += REG_LEN # The + 1 is for the second-stack xchg
|
||||
@@ -208,94 +211,94 @@ def generate_stub_64(callback):
|
||||
save_r9 = save_register_space_end - REG_LEN - (REG_LEN * 6)
|
||||
|
||||
|
||||
gstate_save_addr = allocator.reserve_int()
|
||||
return_addr_save_addr = allocator.reserve_int()
|
||||
return_value_save_addr = allocator.reserve_int()
|
||||
|
||||
Reserve_space_for_call = MultipleInstr([Push_RDI()] * 4)
|
||||
Clean_space_for_call = MultipleInstr([Pop_RDI()] * 4)
|
||||
Do_stack_alignement = MultipleInstr([Push_RDI()] * 1)
|
||||
Remove_stack_alignement = MultipleInstr([Pop_RDI()] * 1)
|
||||
gstate_save_addr = create_displacement(disp=allocator.reserve_int())
|
||||
return_addr_save_addr = create_displacement(disp=allocator.reserve_int())
|
||||
return_value_save_addr = create_displacement(disp=allocator.reserve_int())
|
||||
|
||||
Reserve_space_for_call = x64.MultipleInstr([Push('RDI')] * 4)
|
||||
Clean_space_for_call = x64.MultipleInstr([Pop('RDI')] * 4)
|
||||
Do_stack_alignement = MultipleInstr([x64.Push('RDI')] * 1)
|
||||
Remove_stack_alignement = MultipleInstr([x64.Pop('RDI')] * 1)
|
||||
|
||||
|
||||
ensure, objcall, release = get_functions()
|
||||
|
||||
### Shellcode ###
|
||||
code = MultipleInstr()
|
||||
code += Mov_RAX_X(save_register_space_end)
|
||||
code += x64.Mov('RAX', save_register_space_end)
|
||||
# A lazy working xchg RSP <-> RAX
|
||||
code += Push_RAX()
|
||||
code += Push_RSP()
|
||||
code += Pop_RAX()
|
||||
code += Pop_RSP()
|
||||
code += x64.Push('RAX')
|
||||
code += x64.Push('RSP')
|
||||
code += x64.Pop('RAX')
|
||||
code += x64.Pop('RSP')
|
||||
|
||||
code += push_all_save_register
|
||||
|
||||
# Re-set RSP to its real value
|
||||
code += Push_RAX()
|
||||
code += Pop_RSP()
|
||||
code += x64.Push('RAX')
|
||||
code += x64.Pop('RSP')
|
||||
|
||||
|
||||
code += Pop_RAX() # Remove the Push_RAX of lazy xchg
|
||||
code += x64.Pop('RAX') # Remove the Push_RAX of lazy xchg
|
||||
# GOOO
|
||||
code += Mov_RAX_X(ensure)
|
||||
code += x64.Mov('RAX', ensure)
|
||||
code += Reserve_space_for_call
|
||||
code += Do_stack_alignement
|
||||
code += Call_RAX()
|
||||
code += x64.Call('RAX')
|
||||
code += Remove_stack_alignement
|
||||
code += Clean_space_for_call
|
||||
code += Mov_DX_RAX(gstate_save_addr)
|
||||
code += x64.Mov(gstate_save_addr, 'RAX')
|
||||
#Save real return addr (for good argument parsing by the callback)
|
||||
code += Pop_RAX()
|
||||
code += Mov_DX_RAX(return_addr_save_addr)
|
||||
code += x64.Pop('RAX')
|
||||
code += x64.Mov(return_addr_save_addr, 'RAX')
|
||||
# Restore parameters for real function call
|
||||
code += Mov_RAX_X(save_rcx)
|
||||
code += Mov_RCX_DRAX()
|
||||
code += Mov_RAX_X(save_rdx)
|
||||
code += Mov_RDX_DRAX()
|
||||
code += Mov_RAX_X(save_r8)
|
||||
code += Mov_R8_DRAX()
|
||||
code += Mov_RAX_X(save_r9)
|
||||
code += Mov_R9_DRAX()
|
||||
code += x64.Mov('RAX', save_rcx)
|
||||
code += x64.Mov('RCX', x64.create_displacement('RAX'))
|
||||
code += x64.Mov('RAX', save_rdx)
|
||||
code += x64.Mov('RDX', x64.create_displacement('RAX'))
|
||||
code += x64.Mov('RAX', save_r8)
|
||||
code += x64.Mov('R9', x64.create_displacement('RAX'))
|
||||
code += x64.Mov('RAX', save_r9)
|
||||
code += x64.Mov('R8', x64.create_displacement('RAX'))
|
||||
# Call python code
|
||||
code += Mov_RAX_X(c_callback)
|
||||
code += x64.Mov('RAX', c_callback)
|
||||
code += Reserve_space_for_call
|
||||
code += Call_RAX() # no need for stack alignement here as we poped the return addr
|
||||
code += x64.Call('RAX') # no need for stack alignement here as we poped the return addr
|
||||
|
||||
code += Clean_space_for_call
|
||||
# Save return value
|
||||
code += Mov_DX_RAX(return_value_save_addr)
|
||||
code += Mov_RAX_DX(return_addr_save_addr)
|
||||
code += x64.Mov(return_value_save_addr, 'RAX')
|
||||
# Repush real return value
|
||||
code += Push_RAX()
|
||||
code += Mov_RAX_DX(gstate_save_addr)
|
||||
code += Push_RAX()
|
||||
code += Pop_RCX()
|
||||
code += Mov_RAX_X(release)
|
||||
code += x64.Mov('RAX', return_addr_save_addr)
|
||||
code += x64.Push('RAX')
|
||||
# Call release(gstate_save)
|
||||
code += x64.Mov_RAX_DX('RAX', gstate_save_addr)
|
||||
code += x64.Push('RAX')
|
||||
code += x64.Pop('RCX')
|
||||
code += x64.Mov('RAX', release)
|
||||
code += Reserve_space_for_call
|
||||
code += Do_stack_alignement
|
||||
code += Call_RAX()
|
||||
code += x64.Call('RAX')
|
||||
code += Remove_stack_alignement
|
||||
code += Clean_space_for_call
|
||||
# Restore registers
|
||||
code += Mov_RAX_X(save_register_space)
|
||||
code += x64.Mov('RAX', save_register_space)
|
||||
# A lazy working xchg RSP <-> RAX
|
||||
code += Push_RAX()
|
||||
code += Push_RSP()
|
||||
code += Pop_RAX()
|
||||
code += Pop_RSP()
|
||||
code += x64.Push('RAX')
|
||||
code += x64.Push('RSP')
|
||||
code += x64.Pop('RAX')
|
||||
code += x64.Pop('RSP')
|
||||
|
||||
code += pop_all_save_register
|
||||
|
||||
# Re-set RSP to its real value
|
||||
code += Push_RAX()
|
||||
code += Pop_RSP()
|
||||
code += Pop_RAX() # Remove the Push_RAX of lazy xchg
|
||||
code += x64.Push('RAX')
|
||||
code += x64.Pop('RSP')
|
||||
code += x64.Pop('RAX') # Remove the Push_RAX of lazy xchg
|
||||
|
||||
# Restore return value
|
||||
code += Mov_RAX_DX(return_value_save_addr)
|
||||
code += Ret()
|
||||
code += x64.Mov_RAX_DX('RAX', return_value_save_addr)
|
||||
code += x64.Ret()
|
||||
return code
|
||||
|
||||
|
||||
|
||||
+340
-239
@@ -1,254 +1,355 @@
|
||||
# You are going to see the most shameful code ever !
|
||||
# Yes this a a copy of x86 :D
|
||||
|
||||
import collections
|
||||
import struct
|
||||
import sys
|
||||
import codecs
|
||||
from .simple_x86 import MultipleInstr
|
||||
|
||||
# This code should really be rewritten..
|
||||
|
||||
this_module = sys.modules[__name__]
|
||||
|
||||
generated_instruction = []
|
||||
|
||||
long = int
|
||||
|
||||
def add_instruction(name, instruction):
|
||||
generated_instruction.append((name, instruction))
|
||||
setattr(this_module, name, instruction)
|
||||
|
||||
def generate_module_doc():
|
||||
doc_lines = ["Here is the list of instruction in the modules:\n\n"]
|
||||
for name, instruction in generated_instruction:
|
||||
doc_lines.append(" | {0} -> <{1}>".format(name, instruction.mnemo))
|
||||
class BitArray(object):
|
||||
def __init__(self, size, bits):
|
||||
self.size = size
|
||||
if len(bits) > size:
|
||||
raise ValueError("size > len(bits)")
|
||||
|
||||
bits_list = []
|
||||
for bit in bits:
|
||||
x = int(bit)
|
||||
if x not in [0, 1]:
|
||||
raise ValueError("Not expected bits value {0}".format(x))
|
||||
bits_list.append(x)
|
||||
|
||||
self.array = bits_list
|
||||
if size > len(self.array):
|
||||
self.array = ([0] * (size - len(self.array))) + self.array
|
||||
|
||||
def dump(self):
|
||||
res = []
|
||||
for i in range(self.size // 8):
|
||||
c = 0
|
||||
for x in (self.array[i * 8: (i + 1) * 8]):
|
||||
c = (c << 1) + x
|
||||
res.append(c)
|
||||
return bytearray((res))
|
||||
|
||||
this_module.__doc__ = "\n".join(doc_lines)
|
||||
|
||||
def decode_hex(s):
|
||||
return codecs.decode(s.encode(), "hex").decode()
|
||||
|
||||
def encode_hex(s):
|
||||
return codecs.encode(s.encode(), "hex").decode()
|
||||
|
||||
reg_order = ['EAX', 'ECX', 'EDX', 'EBX', 'ESP', 'EBP', 'ESI', 'EDI']
|
||||
reg_opcode = {v : format(i, "03b") for i, v in enumerate(reg_order)}
|
||||
def __getitem__(self, slice):
|
||||
return self.array[slice]
|
||||
|
||||
def __setitem__(self, slice, value):
|
||||
self.array[slice] = value
|
||||
return True
|
||||
|
||||
def __repr__(self):
|
||||
return repr(self.array)
|
||||
|
||||
def __add__(self, other):
|
||||
if not isinstance(other, BitArray):
|
||||
return NotImplemented
|
||||
return BitArray(self.size + other.size, self.array + other.array)
|
||||
|
||||
def __or__(self, other):
|
||||
if not isinstance(other, BitArray):
|
||||
return NotImplemented
|
||||
if self.size != other.size:
|
||||
raise ValueError("OR ON DIFF SIZE")
|
||||
new_array = [(x | y) for x,y in zip(self.array, other.array)]
|
||||
return BitArray(self.size, new_array)
|
||||
|
||||
def to_int(self):
|
||||
return int("".join([str(i) for i in self.array]), 2)
|
||||
|
||||
@classmethod
|
||||
def from_string(cls):
|
||||
l = []
|
||||
for c in bytearray(reversed(str_base)):
|
||||
for i in range(8):
|
||||
l.append(c & 1)
|
||||
c = c >> 1
|
||||
self.array = l
|
||||
|
||||
@classmethod
|
||||
def from_int(cls, size, x):
|
||||
if x < 0:
|
||||
x = x & ((2 ** size) - 1)
|
||||
return cls(size, bin(x)[2:])
|
||||
|
||||
# Rules: bytes only !!!!
|
||||
|
||||
reg_order = ['RAX', 'RCX', 'RDX', 'RBX', 'RSP', 'RBP', 'RSI', 'RDI']
|
||||
reg_opcode = {v : format(i, "03b") for i, v in enumerate(reg_order)}
|
||||
|
||||
new_reg_order = ['R8', 'R9', 'R10', 'R11', 'R12', 'R13', 'R14', 'R15']
|
||||
new_reg_opcode = {v : format(i, "03b") for i, v in enumerate(new_reg_order)}
|
||||
|
||||
all_regs = dict(reg_opcode)
|
||||
all_regs.update(new_reg_opcode)
|
||||
|
||||
bin_h48 = bin(0x48)[2:]
|
||||
class X64Instruction(object):
|
||||
mnemo = ""
|
||||
code = ""
|
||||
biding = 0
|
||||
|
||||
x64_regs = reg_order + new_reg_order
|
||||
|
||||
mem_access = collections.namedtuple('mem_access', ['base', 'index', 'squale', 'disp'])
|
||||
|
||||
|
||||
|
||||
def create_displacement(base=None, index=None, squale=None, disp=0):
|
||||
return mem_access(base, index, squale, disp)
|
||||
|
||||
|
||||
class X64RegisterSelector(object):
|
||||
|
||||
reg_opcode = {v : BitArray.from_int(size=3, x=i) for i, v in enumerate(reg_order)}
|
||||
new_reg_opcode = {v : BitArray.from_int(size=3, x=i) for i, v in enumerate(new_reg_order)}
|
||||
|
||||
def __init__(self, *bind_values):
|
||||
if len(bind_values) != self.biding:
|
||||
raise ValueError("{0} expect {1} values got {2}".format(self.__class__.__name__, self.biding, len(bind_values)))
|
||||
self.bind_values = bind_values
|
||||
for i, v in enumerate(bind_values):
|
||||
if not isinstance(v, (int, long)):
|
||||
raise ValueError("{0} bindings must be 'int' got '{1}' instead".format(self.__class__.__name__, type(v).__name__))
|
||||
if not 0 <= v <= 0xffffffffffffffff:
|
||||
raise ValueError("{0} bindings must be between 0 and 0xffffffffffffffff".format(self.__class__.__name__))
|
||||
|
||||
def get_unbinded_code(self):
|
||||
return decode_hex(self.code.replace(" ", ""))
|
||||
def accept_arg(self, previous, args):
|
||||
x = args[0]
|
||||
try:
|
||||
return (1, self.reg_opcode[x], None)
|
||||
except KeyError:
|
||||
pass
|
||||
try:
|
||||
return (1, self.new_reg_opcode[x], BitArray.from_int(8, 0x41))
|
||||
except KeyError:
|
||||
return (None, None, None)
|
||||
|
||||
@classmethod
|
||||
def get_reg_bits(cls, name):
|
||||
try:
|
||||
return cls.reg_opcode[name]
|
||||
except KeyError:
|
||||
return cls.new_reg_opcode[name]
|
||||
|
||||
class RawBits(BitArray):
|
||||
def accept_arg(self, previous, args):
|
||||
return (0, self, None)
|
||||
|
||||
class Imm64(object):
|
||||
def accept_arg(self, previous, args):
|
||||
try:
|
||||
x = int(args[0])
|
||||
return (1, BitArray.from_int(64, X64.to_little_endian(x)), None)
|
||||
except TypeError:
|
||||
return (None, None, None)
|
||||
|
||||
class Mov_RAX_OFF64(object):
|
||||
def accept_arg(self, previous, args):
|
||||
if args[0] != "RAX":
|
||||
return (None, None, None)
|
||||
arg2 = args[1]
|
||||
if not (X64.is_mem_acces(arg2) and X64.mem_access_has_only(arg2, ["disp"])):
|
||||
return (None, None, None)
|
||||
return (2, BitArray.from_int(8, 0xa1) + BitArray.from_int(64, X64.to_little_endian(arg2.disp)) , BitArray.from_int(8, 0x48))
|
||||
|
||||
class Mov_OFF64_RAX(object):
|
||||
def accept_arg(self, previous, args):
|
||||
if args[1] != "RAX":
|
||||
return (None, None, None)
|
||||
arg2 = args[0]
|
||||
if not (X64.is_mem_acces(arg2) and X64.mem_access_has_only(arg2, ["disp"])):
|
||||
return (None, None, None)
|
||||
return (2, BitArray.from_int(8, 0xa3) + BitArray.from_int(64, X64.to_little_endian(arg2.disp)) , BitArray.from_int(8, 0x48))
|
||||
|
||||
|
||||
class ModRM(object):
|
||||
size = 8
|
||||
|
||||
def __init__(self, *sub_modrm):
|
||||
self.sub = sub_modrm
|
||||
|
||||
def accept_arg(self, previous, args):
|
||||
if len(args) < 2:
|
||||
raise ValueError("Missing arg for modrm")
|
||||
arg1 = args[0]
|
||||
arg2 = args[1]
|
||||
for sub in self.sub:
|
||||
#import pdb;pdb.set_trace()
|
||||
if sub.match(arg1, arg2):
|
||||
d = sub(arg1, arg2, 0)
|
||||
previous[0][-2] = d.direction
|
||||
rex = d.rex if d.is_rex_needed else None
|
||||
return (2, d.mod + d.reg + d.rm + d.after, rex)
|
||||
elif (not hasattr(sub, "refuse_reverse")) and sub.match(arg2, arg1):
|
||||
d = sub(arg2, arg1, 1)
|
||||
previous[0][-2] = d.direction
|
||||
rex = d.rex if d.is_rex_needed else None
|
||||
return (2, d.mod + d.reg + d.rm + d.after, rex)
|
||||
return (None, None, None)
|
||||
|
||||
class RexByte(BitArray):
|
||||
def __init__(self):
|
||||
super(RexByte, self).__init__(8, "")
|
||||
self.is_needed = False
|
||||
|
||||
class X64(object):
|
||||
@staticmethod
|
||||
def is_reg(name):
|
||||
return name in x64_regs
|
||||
|
||||
@staticmethod
|
||||
def is_new_reg(name):
|
||||
return name in new_reg_order
|
||||
|
||||
@staticmethod
|
||||
def is_mem_acces(data):
|
||||
return isinstance(data, mem_access)
|
||||
|
||||
@staticmethod
|
||||
def mem_access_has_only(mem_access, names):
|
||||
if not X64.is_mem_acces(mem_access):
|
||||
raise ValueError("mem_access_has_only")
|
||||
for f in mem_access._fields:
|
||||
if getattr(mem_access, f) and f not in names:
|
||||
return False
|
||||
if "base" in names and mem_access.base is None:
|
||||
return False
|
||||
return True
|
||||
|
||||
@staticmethod
|
||||
def to_little_endian(i):
|
||||
i = i & 0xffffffffffffffff
|
||||
return struct.unpack("<Q", struct.pack(">Q", i))[0]
|
||||
|
||||
# Sub ModRM encoding
|
||||
|
||||
class RexByte(object):
|
||||
def __init__(self):
|
||||
self.is_needed = False
|
||||
self.pattern = BitArray(4, "0100")
|
||||
self.w = BitArray(1, "0")
|
||||
self.r = BitArray(1, "0")
|
||||
self.x = BitArray(1, "0")
|
||||
self.b = BitArray(1, "0")
|
||||
|
||||
|
||||
class SubModRM(object):
|
||||
def __init__(self):
|
||||
self.mod = BitArray(2, "")
|
||||
self.reg = BitArray(3, "")
|
||||
self.rm = BitArray(3, "")
|
||||
self.after = BitArray(0, "")
|
||||
self.rex = BitArray(8, "01000000")
|
||||
self.is_rex_needed = False
|
||||
self.direction = 0
|
||||
|
||||
def setup_reg_as_register(self, name):
|
||||
self.reg = X64RegisterSelector.get_reg_bits(name)
|
||||
if X64.is_new_reg(name):
|
||||
self.is_rex_needed = True
|
||||
self.rex[5] = 1
|
||||
|
||||
def setup_rm_as_register(self, name):
|
||||
self.rm = X64RegisterSelector.get_reg_bits(name)
|
||||
if X64.is_new_reg(name):
|
||||
self.is_rex_needed = True
|
||||
self.rex[7] = 1
|
||||
|
||||
class ModRM_REG64__REG64(SubModRM):
|
||||
@classmethod
|
||||
def match(cls, arg1, arg2):
|
||||
return X64.is_reg(arg1) and X64.is_reg(arg2)
|
||||
|
||||
def __init__(self, arg1, arg2, reversed):
|
||||
super(ModRM_REG64__REG64, self).__init__()
|
||||
self.mod = BitArray(2, "11")
|
||||
self.is_rex_needed = True
|
||||
self.rex[4] = 1
|
||||
self.setup_reg_as_register(arg2)
|
||||
self.setup_rm_as_register(arg1)
|
||||
self.direction = 0
|
||||
|
||||
#class ModRM_REG__DEREF_IMM(SubModRM):
|
||||
# @classmethod
|
||||
# def match(cls, arg1, arg2):
|
||||
# return X64.is_reg(arg1) and X64.is_mem_acces(arg2) and X64.mem_access_has_only(arg2, ["disp"])
|
||||
#
|
||||
# def __init__(self, arg1, arg2, reversed):
|
||||
# super(ModRM_REG__DEREF_IMM, self).__init__()
|
||||
# self.mod = BitArray(2, "00")
|
||||
# self.setup_reg_as_register(arg1)
|
||||
# self.rm = BitArray(3, "101")
|
||||
# self.after = BitArray.from_int(64, X64.to_little_endian(arg2.disp))
|
||||
# self.direction = not reversed
|
||||
|
||||
|
||||
class ModRM_REG__DEREF_REG(SubModRM):
|
||||
@classmethod
|
||||
def match(cls, arg1, arg2):
|
||||
return X64.is_reg(arg1) and X64.is_mem_acces(arg2) and X64.mem_access_has_only(arg2, ["base"]) and arg2.base not in ["RSP", "RBP"]
|
||||
|
||||
def __init__(self, arg1, arg2, reversed):
|
||||
super(ModRM_REG__DEREF_REG, self).__init__()
|
||||
self.mod = BitArray(2, "00")
|
||||
self.is_rex_needed = True
|
||||
self.rex[4] = 1
|
||||
self.setup_reg_as_register(arg1)
|
||||
self.setup_rm_as_register(arg2.base)
|
||||
self.after = BitArray(0, "")
|
||||
self.direction = not reversed
|
||||
#
|
||||
#class ModRM_REG__DEREF_REG_IMM(object):
|
||||
# @classmethod
|
||||
# def match(cls, arg1, arg2):
|
||||
# return X86.is_reg(arg1) and X86.is_mem_acces(arg2) and X86.mem_access_has_only(arg2, ["base", "disp"])
|
||||
#
|
||||
# def __init__(self, arg1, arg2, reversed):
|
||||
# self.mod = BitArray(2, "10")
|
||||
# self.reg = X86RegisterSelector.get_reg_bits(arg1)
|
||||
# self.rm = X86RegisterSelector.get_reg_bits(arg2.base)
|
||||
# self.after = BitArray.from_int(32, X86.to_little_endian(arg2.disp))
|
||||
# self.direction = not reversed
|
||||
#
|
||||
|
||||
class Instruction(object):
|
||||
encoding = []
|
||||
|
||||
def __init__(self, *initial_args):
|
||||
for type_encoding in self.encoding:
|
||||
args = list(initial_args)
|
||||
res = []
|
||||
full_rex = BitArray(8, "")
|
||||
if hasattr(self, "default_32_bits") and self.default_32_bits:
|
||||
full_rex = BitArray.from_int(8, 0x48)
|
||||
for element in type_encoding:
|
||||
arg_consum, value, rex = element.accept_arg(res, args)
|
||||
if arg_consum is None:
|
||||
break
|
||||
res.append(value)
|
||||
del args[:arg_consum]
|
||||
if rex is not None:
|
||||
full_rex = full_rex | rex
|
||||
else: # if no break
|
||||
if args: # if still args: fail
|
||||
continue
|
||||
self.value = sum(res, BitArray(0, ""))
|
||||
if any(full_rex.array):
|
||||
self.value = full_rex + self.value
|
||||
return
|
||||
raise ValueError("Cannot encode :(")
|
||||
#
|
||||
#
|
||||
class Push(Instruction):
|
||||
encoding = [(RawBits.from_int(5, 0x50 >> 3), X64RegisterSelector()),]
|
||||
# (RawBits.from_int(8, 0x68), Imm32())]
|
||||
|
||||
class Pop(Instruction):
|
||||
encoding = [(RawBits.from_int(5, 0x58 >> 3), X64RegisterSelector())]
|
||||
|
||||
class Call(Instruction):
|
||||
encoding = [(RawBits.from_int(13, 0xffd0 >> 3), X64RegisterSelector())]
|
||||
|
||||
class Ret(Instruction):
|
||||
encoding = [(RawBits.from_int(8, 0xc3),)]
|
||||
|
||||
class Mov(Instruction):
|
||||
default_32_bits = True
|
||||
encoding = [(RawBits.from_int(8, 0x89), ModRM(ModRM_REG64__REG64, ModRM_REG__DEREF_REG)), (RawBits.from_int(5, 0xb8 >> 3), X64RegisterSelector(), Imm64()),
|
||||
(Mov_RAX_OFF64(),), (Mov_OFF64_RAX(),)]
|
||||
|
||||
class MultipleInstr(object):
|
||||
|
||||
def __init__(self, instrs=()):
|
||||
self.instrs = list(instrs)
|
||||
|
||||
def __iadd__(self, value):
|
||||
if type(value) == MultipleInstr:
|
||||
self.instrs.extend(value.instrs)
|
||||
return self
|
||||
self.instrs.append(value)
|
||||
return self
|
||||
|
||||
def get_code(self):
|
||||
code = self.get_unbinded_code()
|
||||
for i in range(self.biding):
|
||||
to_search = codecs.decode(str(i + 1) * 16, 'hex')
|
||||
import pdb;pdb.set_trace()
|
||||
code = code.replace(to_search, struct.pack("<Q", self.bind_values[i]))
|
||||
return code
|
||||
|
||||
def get_mnemo(self):
|
||||
return self.mnemo.format(*(hex(v) for v in self.bind_values))
|
||||
|
||||
|
||||
class Ret(X64Instruction):
|
||||
mnemo = "ret"
|
||||
code = "C3"
|
||||
|
||||
generated_instruction.append(("Ret", Ret))
|
||||
|
||||
class Int3(X64Instruction):
|
||||
mnemo = "int3"
|
||||
code = "CC"
|
||||
|
||||
generated_instruction.append(("Int3", Int3))
|
||||
|
||||
class Retf(X64Instruction):
|
||||
mnemo = "retf"
|
||||
code = "CB"
|
||||
|
||||
generated_instruction.append(("Retf", Retf))
|
||||
|
||||
|
||||
class SimpleRegInstructionGenerator(object):
|
||||
name = ""
|
||||
instruction_bits = ''
|
||||
|
||||
class OneBindX64Instruction(X64Instruction):
|
||||
biding = 1
|
||||
|
||||
class Mov_RAX_DX(OneBindX64Instruction):
|
||||
name = 'Mov_RAX_DX'
|
||||
mnemo = 'mov rax, [{0}]'
|
||||
code = "48 a1 11 11 11 11 11 11 11 11"
|
||||
|
||||
generated_instruction.append(("Mov_RAX_DX", Mov_RAX_DX))
|
||||
|
||||
class Mov_DX_RAX(OneBindX64Instruction):
|
||||
name = 'Mov_DX_RAX'
|
||||
mnemo = 'mov [{0}], rax'
|
||||
code = "48 a3 11 11 11 11 11 11 11 11"
|
||||
|
||||
generated_instruction.append(("Mov_DX_RAX", Mov_DX_RAX))
|
||||
|
||||
def generate_simple_reg_instruction(instr_cls, include_new_reg=False):
|
||||
for reg_name, reg_bits in reg_opcode.items():
|
||||
class SimpleRegInstruction(X64Instruction):
|
||||
mnemo = "{0} {1}".format(instr_cls.mnemo, reg_name)
|
||||
code = format(int(instr_cls.instruction_bits + reg_bits, 2), 'x')
|
||||
SimpleRegInstruction.__name__ = "{0}_{1}".format(instr_cls.name, reg_name)
|
||||
add_instruction(SimpleRegInstruction.__name__, SimpleRegInstruction)
|
||||
if sys.version_info.major == 3:
|
||||
return b"".join([x.value.dump() for x in self.instrs])
|
||||
return "".join([str(x.value.dump()) for x in self.instrs])
|
||||
|
||||
if not include_new_reg:
|
||||
return None
|
||||
for reg_name, reg_bits in new_reg_opcode.items():
|
||||
class SimpleRegInstruction(X64Instruction):
|
||||
mnemo = "{0} {1}".format(instr_cls.mnemo, reg_name)
|
||||
code = instr_cls.new_reg_prefix + format(int(instr_cls.instruction_bits + reg_bits, 2), 'x')
|
||||
SimpleRegInstruction.__name__ = "{0}_{1}".format(instr_cls.name, reg_name)
|
||||
add_instruction(SimpleRegInstruction.__name__, SimpleRegInstruction)
|
||||
|
||||
|
||||
class Push_Reg(object):
|
||||
name = 'Push'
|
||||
mnemo = "push"
|
||||
instruction_bits = '01010'
|
||||
new_reg_prefix = "41"
|
||||
|
||||
generate_simple_reg_instruction(Push_Reg, True)
|
||||
|
||||
class Pop_Reg(object):
|
||||
name = 'Pop'
|
||||
mnemo = "pop"
|
||||
instruction_bits = '01011'
|
||||
new_reg_prefix = "41"
|
||||
|
||||
generate_simple_reg_instruction(Pop_Reg, True)
|
||||
|
||||
class Call_Reg(object):
|
||||
name = 'Call'
|
||||
mnemo = "call"
|
||||
instruction_bits = '1111111111010'
|
||||
|
||||
generate_simple_reg_instruction(Call_Reg)
|
||||
|
||||
|
||||
|
||||
def generate_reg_instruction_onebind(instr_cls):
|
||||
for reg_name, reg_bits in reg_opcode.items():
|
||||
class OneBindRegInstruction(OneBindX64Instruction):
|
||||
mnemo = instr_cls.mnemo.format(reg_name)
|
||||
code = encode_hex(chr(int(instr_cls.instruction_bits + reg_bits, 2))) + '11 11 11 11 11 11 11 11' # the biding
|
||||
if instr_cls.prefix_bin_h48:
|
||||
code = "48" + code
|
||||
OneBindRegInstruction.__name__ = instr_cls.name.format(reg_name)
|
||||
add_instruction(OneBindRegInstruction.__name__, OneBindRegInstruction)
|
||||
|
||||
class Mov_Reg_X(object):
|
||||
name = 'Mov_{0}_X'
|
||||
mnemo = 'mov {0}, {{0}}'
|
||||
instruction_bits = '10111'
|
||||
prefix_bin_h48 = True
|
||||
|
||||
generate_reg_instruction_onebind(Mov_Reg_X)
|
||||
|
||||
def get_immediat_modr_byte(register_bits):
|
||||
"Generate a modr-reg-r/m indicating a register and an immediat"
|
||||
str_bits = "11000{0}".format(register_bits)
|
||||
return encode_hex(chr(int(str_bits, 2)))
|
||||
|
||||
def get_simple_modr_byte(register_bits):
|
||||
"Generate a simple modr-reg-r/m for a displacement only mode"
|
||||
str_bits = "00{0}101".format(register_bits)
|
||||
return encode_hex(chr(int(str_bits, 2)))
|
||||
|
||||
|
||||
#def generate_reg_indirect_modr_byte(reg_dst_bits, reg_src_bits):
|
||||
# # reg, [reg] or [reg], reg
|
||||
# return "00{0}{1}".format(reg_dst_bits, reg_src_bits)
|
||||
#
|
||||
#def generate_reg_reg_deref(instr_cls, src_first=True):
|
||||
# "generate the Mov_Reg_DReg and Mov_DReg_Reg"
|
||||
# for reg_src_name, reg_src_bits in reg_opcode.items():
|
||||
# for reg_dst_name, reg_dst_bits in reg_opcode.items():
|
||||
# if reg_dst_name in ("RBP", "RSP") or reg_src_name in ("RBP", "RSP"):
|
||||
# # Not same encoding -> Not implemented
|
||||
# continue
|
||||
# class Reg_DReg_instruction(X64Instruction):
|
||||
# mnemo = instr_cls.mnemo.format(reg_dst_name, reg_src_name)
|
||||
# name = instr_cls.name.format(reg_dst_name, reg_src_name)
|
||||
# if src_first:
|
||||
# modr_code = generate_reg_indirect_modr_byte(reg_src_bits, reg_dst_bits)
|
||||
# else:
|
||||
# modr_code = generate_reg_indirect_modr_byte(reg_dst_bits, reg_src_bits)
|
||||
# code = instr_cls.instruction_bits + chr(int(modr_code, 2)).encode("hex")
|
||||
# Reg_DReg_instruction.__name__ = Reg_DReg_instruction.name
|
||||
# add_instruction(Reg_DReg_instruction.__name__, Reg_DReg_instruction)
|
||||
|
||||
|
||||
|
||||
|
||||
def generate_reg_indirect_modr_byte(reg_dst_bits, reg_src_bits, deref_first):
|
||||
# reg, [reg] or [reg], reg
|
||||
if deref_first:
|
||||
return encode_hex(chr(int("00{0}{1}".format(reg_dst_bits, reg_src_bits), 2)))
|
||||
else:
|
||||
return encode_hex(chr(int("00{0}{1}".format(reg_src_bits, reg_dst_bits), 2)))
|
||||
|
||||
def generate_reg_reg_deref():
|
||||
for reg1_name, reg1_bits in all_regs.items():
|
||||
for reg2_name, reg2_bits in all_regs.items():
|
||||
if reg1_name in ("RBP", "RSP", "R12", "R13") or reg2_name in ("RBP", "RSP", "R12", "R13"):
|
||||
continue
|
||||
is_reg1_new = reg1_name in new_reg_opcode
|
||||
is_reg2_new = reg2_name in new_reg_opcode
|
||||
|
||||
first_byte = encode_hex(chr(int("1001{0}0{1}".format(int(is_reg1_new), int(is_reg2_new)), 2)))
|
||||
|
||||
class DReg_Reg_instruction(X64Instruction):
|
||||
mnemo = "mov [{0}], {1}".format(reg1_name, reg2_name)
|
||||
name = 'Mov_D{0}_{1}'.format(reg1_name, reg2_name)
|
||||
modr_code = generate_reg_indirect_modr_byte(reg1_bits, reg2_bits, False)
|
||||
code = first_byte + "89" + modr_code
|
||||
|
||||
DReg_Reg_instruction.__name__ = DReg_Reg_instruction.name
|
||||
add_instruction(DReg_Reg_instruction.__name__, DReg_Reg_instruction)
|
||||
|
||||
class Reg_DReg_instruction(X64Instruction):
|
||||
mnemo = "mov {0}, [{1}]".format(reg1_name, reg2_name)
|
||||
name = 'Mov_{0}_D{1}'.format(reg1_name, reg2_name)
|
||||
modr_code = generate_reg_indirect_modr_byte(reg1_bits, reg2_bits, True)
|
||||
code = first_byte + "8B" + modr_code
|
||||
|
||||
Reg_DReg_instruction.__name__ = Reg_DReg_instruction.name
|
||||
add_instruction(Reg_DReg_instruction.__name__, Reg_DReg_instruction)
|
||||
|
||||
|
||||
generate_reg_reg_deref()
|
||||
|
||||
generate_module_doc()
|
||||
|
||||
|
||||
+218
-275
@@ -1,290 +1,238 @@
|
||||
import collections
|
||||
import struct
|
||||
import sys
|
||||
import codecs
|
||||
# This code should really be rewritten..
|
||||
|
||||
this_module = sys.modules[__name__]
|
||||
|
||||
generated_instruction = []
|
||||
|
||||
long = int
|
||||
|
||||
|
||||
def add_instruction(name, instruction):
|
||||
generated_instruction.append((name, instruction))
|
||||
setattr(this_module, name, instruction)
|
||||
|
||||
def generate_module_doc():
|
||||
doc_lines = ["Here is the list of instruction in the modules:\n\n"]
|
||||
for name, instruction in generated_instruction:
|
||||
doc_lines.append(" | {0} -> <{1}>".format(name, instruction.mnemo))
|
||||
|
||||
this_module.__doc__ = "\n".join(doc_lines)
|
||||
|
||||
def decode_hex(s):
|
||||
return codecs.decode(s.encode(), "hex").decode()
|
||||
|
||||
def encode_hex(s):
|
||||
return codecs.encode(s.encode(), "hex").decode()
|
||||
|
||||
reg_order = ['EAX', 'ECX', 'EDX', 'EBX', 'ESP', 'EBP', 'ESI', 'EDI']
|
||||
reg_opcode = {v : format(i, "03b") for i, v in enumerate(reg_order)}
|
||||
|
||||
|
||||
class X86Instruction(object):
|
||||
mnemo = ""
|
||||
code = ""
|
||||
biding = 0
|
||||
|
||||
def __init__(self, *bind_values):
|
||||
if len(bind_values) != self.biding:
|
||||
raise ValueError("{0} expect {1} values got {2}".format(self.__class__.__name__, self.biding, len(bind_values)))
|
||||
self.bind_values = bind_values
|
||||
for i, v in enumerate(bind_values):
|
||||
if not isinstance(v, (int, long)):
|
||||
raise ValueError("{0} bindings must be 'int' got '{1}' instead".format(self.__class__.__name__, type(v).__name__))
|
||||
if not 0 <= v <= 0xffffffff:
|
||||
raise ValueError("{0} bindings must be between 0 and 0xffffffff".format(self.__class__.__name__))
|
||||
|
||||
def get_unbinded_code(self):
|
||||
print(self.code)
|
||||
return codecs.decode(self.code.replace(" ", ""), 'hex')
|
||||
|
||||
def get_code(self):
|
||||
code = self.get_unbinded_code()
|
||||
for i in range(self.biding):
|
||||
to_search = codecs.decode(str(i + 1) * 8, 'hex')
|
||||
code = code.replace(to_search, struct.pack("<I", self.bind_values[i]))
|
||||
return code
|
||||
|
||||
def get_mnemo(self):
|
||||
return self.mnemo.format(*(hex(v) for v in self.bind_values))
|
||||
|
||||
|
||||
class Ret(X86Instruction):
|
||||
mnemo = "ret"
|
||||
code = "C3"
|
||||
|
||||
generated_instruction.append(("Ret", Ret))
|
||||
|
||||
class Int3(X86Instruction):
|
||||
mnemo = "int3"
|
||||
code = "CC"
|
||||
|
||||
generated_instruction.append(("Int3", Int3))
|
||||
class BitArray(object):
|
||||
def __init__(self, size, bits):
|
||||
self.size = size
|
||||
if len(bits) > size:
|
||||
raise ValueError("size > len(bits)")
|
||||
|
||||
class SimpleRegInstructionGenerator(object):
|
||||
name = ""
|
||||
instruction_bits = ''
|
||||
|
||||
|
||||
class OneBindX86Instruction(X86Instruction):
|
||||
biding = 1
|
||||
|
||||
|
||||
class Push_X(OneBindX86Instruction):
|
||||
mnemo = "push {0}"
|
||||
code = "68 11 11 11 11"
|
||||
|
||||
generated_instruction.append(("Push_X", Push_X))
|
||||
|
||||
def generate_simple_reg_instruction(instr_cls):
|
||||
for reg_name, reg_bits in reg_opcode.items():
|
||||
class SimpleRegInstruction(X86Instruction):
|
||||
mnemo = "{0} {1}".format(instr_cls.mnemo, reg_name)
|
||||
code = format(int(instr_cls.instruction_bits + reg_bits, 2), 'x')
|
||||
bits_list = []
|
||||
for bit in bits:
|
||||
x = int(bit)
|
||||
if x not in [0, 1]:
|
||||
raise ValueError("Not expected bits value {0}".format(x))
|
||||
bits_list.append(x)
|
||||
|
||||
SimpleRegInstruction.__name__ = "{0}_{1}".format(instr_cls.name, reg_name)
|
||||
add_instruction(SimpleRegInstruction.__name__, SimpleRegInstruction)
|
||||
|
||||
|
||||
class Push_Reg(object):
|
||||
name = 'Push'
|
||||
mnemo = "push"
|
||||
instruction_bits = '01010'
|
||||
|
||||
generate_simple_reg_instruction(Push_Reg)
|
||||
|
||||
class Pop_Reg(object):
|
||||
name = 'Pop'
|
||||
mnemo = "pop"
|
||||
instruction_bits = '01011'
|
||||
|
||||
generate_simple_reg_instruction(Pop_Reg)
|
||||
|
||||
class Call_Reg(object):
|
||||
name = 'Call'
|
||||
mnemo = "call"
|
||||
instruction_bits = '1111111111010'
|
||||
|
||||
generate_simple_reg_instruction(Call_Reg)
|
||||
|
||||
|
||||
|
||||
def generate_reg_instruction_onebind(instr_cls):
|
||||
for reg_name, reg_bits in reg_opcode.items():
|
||||
class OneBindRegInstruction(OneBindX86Instruction):
|
||||
mnemo = instr_cls.mnemo.format(reg_name)
|
||||
self.array = bits_list
|
||||
if size > len(self.array):
|
||||
self.array = ([0] * (size - len(self.array))) + self.array
|
||||
|
||||
i = int(instr_cls.instruction_bits + reg_bits, 2)
|
||||
code = bytes([i]) + b'11 11 11 11' # the biding
|
||||
def dump(self):
|
||||
res = []
|
||||
for i in range(self.size // 8):
|
||||
c = 0
|
||||
for x in (self.array[i * 8: (i + 1) * 8]):
|
||||
c = (c << 1) + x
|
||||
res.append(c)
|
||||
return bytearray((res))
|
||||
|
||||
def __getitem__(self, slice):
|
||||
return self.array[slice]
|
||||
|
||||
def __setitem__(self, slice, value):
|
||||
self.array[slice] = value
|
||||
return True
|
||||
|
||||
def __repr__(self):
|
||||
return repr(self.array)
|
||||
|
||||
def __add__(self, other):
|
||||
if not isinstance(other, BitArray):
|
||||
return NotImplemented
|
||||
return BitArray(self.size + other.size, self.array + other.array)
|
||||
|
||||
def to_int(self):
|
||||
return int("".join([str(i) for i in self.array]), 2)
|
||||
|
||||
@classmethod
|
||||
def from_string(cls):
|
||||
l = []
|
||||
for c in bytearray(reversed(str_base)):
|
||||
for i in range(8):
|
||||
l.append(c & 1)
|
||||
c = c >> 1
|
||||
self.array = l
|
||||
|
||||
@classmethod
|
||||
def from_int(cls, size, x):
|
||||
if x < 0:
|
||||
x = x & ((2 ** size) - 1)
|
||||
return cls(size, bin(x)[2:])
|
||||
|
||||
# Rules: bytes only !!!!
|
||||
|
||||
mem_access = collections.namedtuple('mem_access', ['base', 'index', 'squale', 'disp'])
|
||||
x86_regs = ['EAX', 'ECX', 'EDX', 'EBX', 'ESP', 'EBP', 'ESI', 'EDI']
|
||||
|
||||
def create_displacement(base=None, index=None, squale=None, disp=0):
|
||||
return mem_access(base, index, squale, disp)
|
||||
|
||||
|
||||
class X86RegisterSelector(object):
|
||||
size = 3 # bits
|
||||
reg_order = ['EAX', 'ECX', 'EDX', 'EBX', 'ESP', 'EBP', 'ESI', 'EDI']
|
||||
reg_opcode = {v : BitArray.from_int(size=3, x=i) for i, v in enumerate(reg_order)}
|
||||
|
||||
def accept_arg(self, previous, args):
|
||||
x = args[0]
|
||||
try:
|
||||
return (1, self.reg_opcode[x])
|
||||
except KeyError:
|
||||
return (None, None)
|
||||
|
||||
@classmethod
|
||||
def get_reg_bits(cls, name):
|
||||
return cls.reg_opcode[name]
|
||||
|
||||
class RawBits(BitArray):
|
||||
def accept_arg(self, previous, args):
|
||||
return (0, self)
|
||||
|
||||
class Imm32(object):
|
||||
def accept_arg(self, previous, args):
|
||||
x = int(args[0])
|
||||
return (1, BitArray.from_int(32, X86.to_little_endian(x)))
|
||||
|
||||
class ModRM(object):
|
||||
size = 8
|
||||
|
||||
def __init__(self, *sub_modrm):
|
||||
self.sub = sub_modrm
|
||||
|
||||
def accept_arg(self, previous, args):
|
||||
if len(args) < 2:
|
||||
raise ValueError("Missing arg for modrm")
|
||||
arg1 = args[0]
|
||||
arg2 = args[1]
|
||||
for sub in self.sub:
|
||||
#import pdb;pdb.set_trace()
|
||||
#code = encode_hex(chr(int(instr_cls.instruction_bits + reg_bits, 2))) + b'11 11 11 11' # the biding
|
||||
|
||||
OneBindRegInstruction.__name__ = instr_cls.name.format(reg_name)
|
||||
add_instruction(OneBindRegInstruction.__name__, OneBindRegInstruction)
|
||||
|
||||
class Mov_Reg_X(object):
|
||||
name = 'Mov_{0}_X'
|
||||
mnemo = 'mov {0}, {{0}}'
|
||||
instruction_bits = '10111'
|
||||
|
||||
generate_reg_instruction_onebind(Mov_Reg_X)
|
||||
|
||||
def get_immediat_modr_byte(register_bits):
|
||||
"Generate a modr-reg-r/m indicating a register and an immediat"
|
||||
str_bits = "11000{0}".format(register_bits)
|
||||
return encode_hex(chr(int(str_bits, 2)))
|
||||
|
||||
def generate_reg_immediat_modr(instr_cls):
|
||||
for reg_name, reg_bits in reg_opcode.items():
|
||||
class Reg_MEM_Instruction(OneBindX86Instruction):
|
||||
mnemo = instr_cls.mnemo.format(reg_name)
|
||||
code = instr_cls.instruction_bits + get_immediat_modr_byte(reg_bits) + '11 11 11 11' # the biding
|
||||
|
||||
Reg_MEM_Instruction.__name__ = instr_cls.name.format(reg_name)
|
||||
add_instruction(Reg_MEM_Instruction.__name__, Reg_MEM_Instruction)
|
||||
if sub.match(arg1, arg2):
|
||||
d = sub(arg1, arg2, 0)
|
||||
previous[0][-2] = d.direction
|
||||
return (2, d.mod + d.reg + d.rm + d.after)
|
||||
elif sub.match(arg2, arg1):
|
||||
d = sub(arg2, arg1, 1)
|
||||
previous[0][-2] = d.direction
|
||||
return (2, d.mod + d.reg + d.rm + d.after)
|
||||
return (None, None)
|
||||
|
||||
class Add_Reg_X(object):
|
||||
name = 'Add_{0}_X'
|
||||
mnemo = 'add {0}, {{0}}'
|
||||
instruction_bits = '81'
|
||||
class X86(object):
|
||||
@staticmethod
|
||||
def is_reg(name):
|
||||
return name in x86_regs
|
||||
|
||||
@staticmethod
|
||||
def is_mem_acces(data):
|
||||
return isinstance(data, mem_access)
|
||||
|
||||
@staticmethod
|
||||
def mem_access_has_only(mem_access, names):
|
||||
if not X86.is_mem_acces(mem_access):
|
||||
raise ValueError("mem_access_has_only")
|
||||
for f in mem_access._fields:
|
||||
if getattr(mem_access, f) and f not in names:
|
||||
return False
|
||||
return True
|
||||
|
||||
@staticmethod
|
||||
def to_little_endian(i):
|
||||
i = i & 0xffffffff
|
||||
return struct.unpack("<I", struct.pack(">I", i))[0]
|
||||
|
||||
generate_reg_immediat_modr(Add_Reg_X)
|
||||
|
||||
|
||||
def get_simple_modr_byte(register_bits):
|
||||
"Generate a simple modr-reg-r/m for a displacement only mode"
|
||||
str_bits = "00{0}101".format(register_bits)
|
||||
return encode_hex(chr(int(str_bits, 2)))
|
||||
|
||||
|
||||
def generate_reg_modr(instr_cls):
|
||||
for reg_name, reg_bits in reg_opcode.items():
|
||||
class Reg_MEM_Instruction(OneBindX86Instruction):
|
||||
mnemo = instr_cls.mnemo.format(reg_name)
|
||||
code = instr_cls.instruction_bits + get_simple_modr_byte(reg_bits) + '11 11 11 11' # the biding
|
||||
class ModRM_REG__REG(object):
|
||||
@classmethod
|
||||
def match(cls, arg1, arg2):
|
||||
return X86.is_reg(arg1) and X86.is_reg(arg2)
|
||||
|
||||
def __init__(self, arg1, arg2, reversed):
|
||||
self.mod = BitArray(2, "11")
|
||||
self.reg = X86RegisterSelector.get_reg_bits(arg2)
|
||||
self.rm = X86RegisterSelector.get_reg_bits(arg1)
|
||||
self.after = BitArray(0, "")
|
||||
self.direction = 0
|
||||
|
||||
class ModRM_REG__DEREF_REG(object):
|
||||
@classmethod
|
||||
def match(cls, arg1, arg2):
|
||||
return X86.is_reg(arg1) and arg1 not in ["ESP", "EBP"] and X86.is_mem_acces(arg2) and X86.mem_access_has_only(arg2, ["base"])
|
||||
|
||||
def __init__(self, arg1, arg2, reversed):
|
||||
self.mod = BitArray(2, "00")
|
||||
self.reg = X86RegisterSelector.get_reg_bits(arg1)
|
||||
self.rm = X86RegisterSelector.get_reg_bits(arg2.base)
|
||||
self.after = BitArray(0, "")
|
||||
self.direction = not reversed
|
||||
|
||||
class ModRM_REG__DEREF_REG_IMM(object):
|
||||
@classmethod
|
||||
def match(cls, arg1, arg2):
|
||||
return X86.is_reg(arg1) and X86.is_mem_acces(arg2) and X86.mem_access_has_only(arg2, ["base", "disp"])
|
||||
|
||||
def __init__(self, arg1, arg2, reversed):
|
||||
self.mod = BitArray(2, "10")
|
||||
self.reg = X86RegisterSelector.get_reg_bits(arg1)
|
||||
self.rm = X86RegisterSelector.get_reg_bits(arg2.base)
|
||||
self.after = BitArray.from_int(32, X86.to_little_endian(arg2.disp))
|
||||
self.direction = not reversed
|
||||
|
||||
class ModRM_REG_IMM(object):
|
||||
@classmethod
|
||||
def match(cls, arg1, arg2):
|
||||
return arg1 in x86_regs and arg2 in x86_regs
|
||||
|
||||
def __init__(self, arg1, arg2):
|
||||
self.mod = BitArray(2, "11")
|
||||
self.reg = X86RegisterSelector.get_reg_bits(arg2)
|
||||
self.rm = X86RegisterSelector.get_reg_bits(arg1)
|
||||
self.direction = 0
|
||||
|
||||
|
||||
class Instruction(object):
|
||||
encoding = []
|
||||
|
||||
def __init__(self, *initial_args):
|
||||
for type_encoding in self.encoding:
|
||||
args = list(initial_args)
|
||||
res = []
|
||||
for element in type_encoding:
|
||||
arg_consum, value = element.accept_arg(res, args)
|
||||
if arg_consum is None:
|
||||
break
|
||||
res.append(value)
|
||||
del args[:arg_consum]
|
||||
else: # if no break
|
||||
if args: # if still args: fail
|
||||
continue
|
||||
self.value = sum(res, BitArray(0, ""))
|
||||
return
|
||||
raise ValueError("Cannot encode :(")
|
||||
|
||||
Reg_MEM_Instruction.__name__ = instr_cls.name.format(reg_name)
|
||||
add_instruction(Reg_MEM_Instruction.__name__, Reg_MEM_Instruction)
|
||||
|
||||
|
||||
|
||||
|
||||
class Mov_Reg_DX(object):
|
||||
name = 'Mov_{0}_DX'
|
||||
mnemo = 'mov {0}, [{{0}}]'
|
||||
instruction_bits = '8B'
|
||||
|
||||
generate_reg_modr(Mov_Reg_DX)
|
||||
|
||||
class Mov_DX_Reg(object):
|
||||
name = 'Mov_DX_{0}'
|
||||
mnemo = 'mov [{{0}}], {0}'
|
||||
instruction_bits = '89'
|
||||
|
||||
generate_reg_modr(Mov_DX_Reg)
|
||||
|
||||
def generate_reg_indirect_modr_byte(reg_dst_bits, reg_src_bits):
|
||||
# reg, [reg] or [reg], reg
|
||||
return "00{0}{1}".format(reg_dst_bits, reg_src_bits)
|
||||
class Push(Instruction):
|
||||
encoding = [(RawBits.from_int(5, 0x50 >> 3), X86RegisterSelector()),
|
||||
(RawBits.from_int(8, 0x68), Imm32())]
|
||||
|
||||
def generate_reg_reg_deref(instr_cls, src_first=True):
|
||||
"generate the Mov_Reg_DReg and Mov_DReg_Reg"
|
||||
for reg_src_name, reg_src_bits in reg_opcode.items():
|
||||
for reg_dst_name, reg_dst_bits in reg_opcode.items():
|
||||
if reg_dst_name in ("EBP", "ESP") or reg_src_name in ("EBP", "ESP"):
|
||||
# Not same encoding -> Not implemented
|
||||
continue
|
||||
class Reg_DReg_instruction(X86Instruction):
|
||||
mnemo = instr_cls.mnemo.format(reg_dst_name, reg_src_name)
|
||||
name = instr_cls.name.format(reg_dst_name, reg_src_name)
|
||||
if src_first:
|
||||
modr_code = generate_reg_indirect_modr_byte(reg_src_bits, reg_dst_bits)
|
||||
else:
|
||||
modr_code = generate_reg_indirect_modr_byte(reg_dst_bits, reg_src_bits)
|
||||
code = encode_hex(instr_cls.instruction_bits + chr(int(modr_code, 2)))
|
||||
Reg_DReg_instruction.__name__ = Reg_DReg_instruction.name
|
||||
add_instruction(Reg_DReg_instruction.__name__, Reg_DReg_instruction)
|
||||
class Pop(Instruction):
|
||||
encoding = [(RawBits.from_int(5, 0x58 >> 3), X86RegisterSelector())]
|
||||
|
||||
class Mov(Instruction):
|
||||
encoding = [(RawBits.from_int(8, 0x89), ModRM(ModRM_REG__REG, ModRM_REG__DEREF_REG, ModRM_REG__DEREF_REG_IMM)),
|
||||
(RawBits.from_int(5, 0xb8 >> 3), X86RegisterSelector(), Imm32())]
|
||||
|
||||
class Mov_Reg_DReg(object):
|
||||
name = 'Mov_{0}_D{1}'
|
||||
mnemo = 'mov [{0}], {1}'
|
||||
instruction_bits = '8B'
|
||||
class Call(Instruction):
|
||||
encoding = [(RawBits.from_int(13, 0xffd0 >> 3), X86RegisterSelector())]
|
||||
|
||||
generate_reg_reg_deref(Mov_Reg_DReg, False)
|
||||
|
||||
class Mov_DReg_Reg(object):
|
||||
name = 'Mov_D{0}_{1}'
|
||||
mnemo = 'mov {0}, [{1}]'
|
||||
instruction_bits = '89'
|
||||
|
||||
generate_reg_reg_deref(Mov_DReg_Reg, True)
|
||||
|
||||
|
||||
def generate_reg_reg_modr_byte(reg_dst_bits, reg_src_bits):
|
||||
# reg, reg
|
||||
return "11{0}{1}".format(reg_src_bits, reg_dst_bits)
|
||||
class Ret(Instruction):
|
||||
encoding = [(RawBits.from_int(8, 0xc3),)]
|
||||
|
||||
|
||||
def generate_reg_reg_modr(instr_cls):
|
||||
for reg_src_name, reg_src_bits in reg_opcode.items():
|
||||
for reg_dst_name, reg_dst_bits in reg_opcode.items():
|
||||
class Reg_Reg_instruction(X86Instruction):
|
||||
mnemo = "{0} {1},{2}".format(instr_cls.mnemo, reg_dst_name, reg_src_name)
|
||||
modr_code = format(int(generate_reg_reg_modr_byte(reg_dst_bits, reg_src_bits) , 2), 'x')
|
||||
code = instr_cls.instruction_bits + modr_code
|
||||
Reg_Reg_instruction.__name__ = "{0}_{1}_{2}".format(instr_cls.name, reg_dst_name, reg_src_name)
|
||||
add_instruction(Reg_Reg_instruction.__name__, Reg_Reg_instruction)
|
||||
|
||||
class Test_Reg_Reg(object):
|
||||
mnemo = "tst"
|
||||
name = "Tst"
|
||||
instruction_bits = "85"
|
||||
|
||||
generate_reg_reg_modr(Test_Reg_Reg)
|
||||
|
||||
#### JUMP ####
|
||||
|
||||
class JZ(OneBindX86Instruction):
|
||||
code = "0F 84 11 11 11 11"
|
||||
|
||||
def __init__(self, instr_block):
|
||||
self.instr_block = instr_block
|
||||
instr_block_size = len(instr_block.get_code())
|
||||
super(JZ, self).__init__(instr_block_size)
|
||||
|
||||
def get_code(self):
|
||||
return super(JZ, self).get_code() + self.instr_block.get_code()
|
||||
|
||||
class JNZ(OneBindX86Instruction):
|
||||
code = "0F 85 11 11 11 11"
|
||||
|
||||
def __init__(self, instr_block):
|
||||
self.instr_block = instr_block
|
||||
instr_block_size = len(instr_block.get_code())
|
||||
super(JNZ, self).__init__(instr_block_size)
|
||||
|
||||
def get_code(self):
|
||||
return super(JNZ, self).get_code() + self.instr_block.get_code()
|
||||
|
||||
|
||||
|
||||
class MultipleInstr(object):
|
||||
|
||||
def __init__(self, init_instrs=()):
|
||||
self.instrs = list(init_instrs)
|
||||
def __init__(self):
|
||||
self.instrs = []
|
||||
|
||||
def __iadd__(self, value):
|
||||
if type(value) == MultipleInstr:
|
||||
@@ -294,12 +242,7 @@ class MultipleInstr(object):
|
||||
return self
|
||||
|
||||
def get_code(self):
|
||||
return "".join(i.get_code() for i in self.instrs)
|
||||
|
||||
def get_mnemo(self):
|
||||
return "\n".join(i.get_mnemo() for i in self.instrs)
|
||||
|
||||
if sys.version_info.major == 3:
|
||||
return b"".join([x.value.dump() for x in self.instrs])
|
||||
return "".join([str(x.value.dump()) for x in self.instrs])
|
||||
|
||||
|
||||
generate_module_doc()
|
||||
|
||||
+40
-50
@@ -1,8 +1,8 @@
|
||||
import ctypes
|
||||
import windows
|
||||
import hooks
|
||||
import windows.hooks as hooks
|
||||
|
||||
from generated_def.winstructs import *
|
||||
from windows.generated_def.winstructs import *
|
||||
|
||||
# This must go to windefs
|
||||
IMAGE_DIRECTORY_ENTRY_EXPORT = 0
|
||||
@@ -118,14 +118,25 @@ def PEFile(baseaddr):
|
||||
import_descriptor_addr += ctypes.sizeof(self.IMAGE_IMPORT_DESCRIPTOR)
|
||||
current_import_descriptor = self.IMAGE_IMPORT_DESCRIPTOR.from_address(import_descriptor_addr)
|
||||
return res
|
||||
|
||||
def get_EXPORT_DIRECTORY(self):
|
||||
export_directory_rva = self.get_DataDirectory()[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress
|
||||
if export_directory_rva == 0:
|
||||
return None
|
||||
export_directory_addr = baseaddr + export_directory_rva
|
||||
return self._IMAGE_EXPORT_DIRECTORY.from_address(export_directory_addr)
|
||||
|
||||
|
||||
#def get_EXPORT_DIRECTORY(self):
|
||||
# return self.get_OptionalHeader().get_EXPORT_DIRECTORY()
|
||||
|
||||
#@property
|
||||
#def exports(self):
|
||||
# return self.get_EXPORT_DIRECTORY().get_exports()
|
||||
@property
|
||||
def exports(self):
|
||||
res = {}
|
||||
raw_exports = self.get_EXPORT_DIRECTORY().get_exports()
|
||||
for id, rva_addr, rva_name in raw_exports:
|
||||
res[id] = rva_addr.addr
|
||||
if rva_name is not None:
|
||||
res[rva_name.str] = rva_addr.addr
|
||||
return res
|
||||
|
||||
|
||||
# TODO: get imports by parsing other modules exports if no INT
|
||||
@property
|
||||
@@ -141,7 +152,7 @@ def PEFile(baseaddr):
|
||||
res.setdefault(import_descriptor.Name.str.lower(),[]).extend(IAT)
|
||||
return res
|
||||
|
||||
# Will be usable as `self.IMPORT_DESCRIPTOR`
|
||||
# Will be usable as `self.IMAGE_IMPORT_DESCRIPTOR`
|
||||
class IMAGE_IMPORT_DESCRIPTOR(ctypes.Structure):
|
||||
_fields_ = transform_ctypes_fields(IMAGE_IMPORT_DESCRIPTOR, {"Name" : StringRVa, "OriginalFirstThunk" : RVA, "FirstThunk" : RVA})
|
||||
|
||||
@@ -171,7 +182,25 @@ def PEFile(baseaddr):
|
||||
iat_addr += ctypes.sizeof(THUNK_DATA)
|
||||
iat_entry = THUNK_DATA.from_address(iat_addr)
|
||||
return res
|
||||
|
||||
|
||||
# Will be usable as `self._IMAGE_EXPORT_DIRECTORY`
|
||||
class _IMAGE_EXPORT_DIRECTORY(ctypes.Structure):
|
||||
_fields_ = transform_ctypes_fields(IMAGE_EXPORT_DIRECTORY, {"Name" : StringRVa, "AddressOfFunctions" : RVA, "AddressOfNames" : RVA, "AddressOfNameOrdinals": RVA})
|
||||
|
||||
def get_exports(self):
|
||||
NameOrdinals = (WORD * self.NumberOfNames).from_address(self.AddressOfNameOrdinals.addr)
|
||||
NameOrdinals = list(NameOrdinals)
|
||||
Functions = (RVA * self.NumberOfFunctions).from_address(self.AddressOfFunctions.addr)
|
||||
Names = (StringRVa * self.NumberOfNames).from_address(self.AddressOfNames.addr)
|
||||
res = []
|
||||
for nb,func in enumerate(Functions):
|
||||
if nb in NameOrdinals:
|
||||
name = Names[NameOrdinals.index(nb)]
|
||||
else:
|
||||
name = None
|
||||
res.append((nb, func, name))
|
||||
return res
|
||||
|
||||
current_pe = PEFile()
|
||||
|
||||
class IMAGE_DOS_HEADER(ctypes.Structure):
|
||||
@@ -201,46 +230,7 @@ def PEFile(baseaddr):
|
||||
if windows.current_process.bitness == 32:
|
||||
return IMAGE_NT_HEADERS32.from_address(baseaddr + self.e_lfanew)
|
||||
return IMAGE_NT_HEADERS64.from_address(baseaddr + self.e_lfanew)
|
||||
|
||||
#
|
||||
# def get_EXPORT_DIRECTORY(self):
|
||||
# export_directory_rva = self.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress
|
||||
# if export_directory_rva == 0:
|
||||
# return None
|
||||
# export_directory_addr = baseaddr + export_directory_rva
|
||||
# return IMAGE_EXPORT_DIRECTORY.from_address(export_directory_addr)
|
||||
#
|
||||
|
||||
|
||||
#class IMAGE_EXPORT_DIRECTORY(ctypes.Structure):
|
||||
# _fields_ = [
|
||||
# ("Characteristics", DWORD),
|
||||
# ("TimeDateStamp", DWORD),
|
||||
# ("MajorVersion", WORD),
|
||||
# ("MinorVersion", WORD),
|
||||
# ("Name", StringRVa),
|
||||
# ("Base", DWORD),
|
||||
# ("NumberOfFunctions", DWORD),
|
||||
# ("NumberOfNames", DWORD),
|
||||
# ("AddressOfFunctions", RVA),
|
||||
# ("AddressOfNames", RVA),
|
||||
# ("AddressOfNameOrdinals", RVA),
|
||||
# ]
|
||||
#
|
||||
# def get_exports(self):
|
||||
# NameOrdinals = (WORD * self.NumberOfNames).from_address(self.AddressOfNameOrdinals.addr)
|
||||
# NameOrdinals = list(NameOrdinals)
|
||||
# Functions = (RVA * self.NumberOfFunctions).from_address(self.AddressOfFunctions.addr)
|
||||
# Names = (StringRVa * self.NumberOfNames).from_address(self.AddressOfNames.addr)
|
||||
# res = []
|
||||
# for nb,func in enumerate(Functions):
|
||||
# if nb in NameOrdinals:
|
||||
# name = Names[NameOrdinals.index(nb)]
|
||||
# else:
|
||||
# name = None
|
||||
# res.append((nb, func, name))
|
||||
# return res
|
||||
#
|
||||
|
||||
return current_pe
|
||||
|
||||
tst = PEFile.__code__.co_consts[13]
|
||||
@@ -4,11 +4,9 @@ import os
|
||||
import copy
|
||||
import sys
|
||||
|
||||
import k32testing as kernel32proxy
|
||||
import generated_def.windef as windef
|
||||
import winobject
|
||||
import native_exec
|
||||
from generated_def.winstructs import *
|
||||
from . import k32testing as kernel32proxy
|
||||
from .generated_def import windef
|
||||
from .generated_def.winstructs import *
|
||||
|
||||
# Function resolution !
|
||||
|
||||
@@ -21,29 +19,7 @@ def get_func_addr(dll_name, func_name):
|
||||
dll = ctypes.WinDLL(dll_name)
|
||||
return kernel32proxy.GetProcAddress(dll._handle, func_name)
|
||||
|
||||
# Used by system.processes
|
||||
def enumerate_processes():
|
||||
process_entry = winobject.WinProcess()
|
||||
process_entry.dwSize = ctypes.sizeof(process_entry)
|
||||
snap = kernel32proxy.CreateToolhelp32Snapshot(windef.TH32CS_SNAPPROCESS, 0)
|
||||
kernel32proxy.Process32First(snap, process_entry)
|
||||
res = []
|
||||
res.append(swallow_ctypes_copy(process_entry))
|
||||
while kernel32proxy.Process32Next(snap, process_entry):
|
||||
res.append(swallow_ctypes_copy(process_entry))
|
||||
return res
|
||||
|
||||
# Used by system.threads
|
||||
def enumerate_threads():
|
||||
thread_entry = winobject.WinThread()
|
||||
thread_entry.dwSize = ctypes.sizeof(thread_entry)
|
||||
snap = kernel32proxy.CreateToolhelp32Snapshot(windef.TH32CS_SNAPTHREAD, 0)
|
||||
threads = []
|
||||
kernel32proxy.Thread32First(snap, thread_entry)
|
||||
threads.append(copy.copy(thread_entry))
|
||||
while kernel32proxy.Thread32Next(snap, thread_entry):
|
||||
threads.append(copy.copy(thread_entry))
|
||||
return threads
|
||||
|
||||
def is_wow_64(hProcess):
|
||||
try:
|
||||
@@ -81,6 +57,9 @@ def create_console():
|
||||
|
||||
stderr_handle = kernel32proxy.GetStdHandle(windef.STD_ERROR_HANDLE)
|
||||
console_stderr = create_file_from_handle(stderr_handle, "w")
|
||||
#print(stderr_handle, console_stderr)
|
||||
import os
|
||||
#os.dup2(console_stderr.fileno(), 2)
|
||||
sys.stderr = console_stderr
|
||||
|
||||
class VirtualProtected(object):
|
||||
|
||||
+71
-16
@@ -9,7 +9,6 @@ import time
|
||||
EXCEPTION_CONTINUE_SEARCH = (0x0)
|
||||
EXCEPTION_CONTINUE_EXECUTION = (0xffffffff)
|
||||
|
||||
|
||||
exception_type = [
|
||||
"EXCEPTION_ACCESS_VIOLATION",
|
||||
"EXCEPTION_DATATYPE_MISALIGNMENT",
|
||||
@@ -53,36 +52,96 @@ class EnhancedEXCEPTION_RECORD(EXCEPTION_RECORD):
|
||||
if x is None:
|
||||
return 0x0
|
||||
return x
|
||||
|
||||
class Eflags(int):
|
||||
_flags_ = [("CF", 1),
|
||||
("RES_1", 1),
|
||||
("PF", 1),
|
||||
("RES_3", 1),
|
||||
("AF", 1),
|
||||
("RES_5", 1),
|
||||
("ZF", 1),
|
||||
("SF", 1),
|
||||
("TF", 1),
|
||||
("IF", 1),
|
||||
("DF", 1),
|
||||
("OF", 1),
|
||||
("IOPL_1", 1),
|
||||
("IOPL_2", 1),
|
||||
("NT", 1),
|
||||
("RES_15",1),
|
||||
("RF", 1),
|
||||
("VM", 1),
|
||||
("AC", 1),
|
||||
("VIF", 1),
|
||||
("VIP", 1),
|
||||
("ID", 1),
|
||||
]
|
||||
|
||||
_flag_mask_ = dict([(name, 1<< i) for i,(name, size) in enumerate(_flags_)])
|
||||
|
||||
def __getattr__(self, name):
|
||||
if name in self._flag_mask_:
|
||||
return bool(self & self._flag_mask_[name])
|
||||
return super(Eflags, self).__getattr_(name)
|
||||
|
||||
def dump(self):
|
||||
res = []
|
||||
for name in self._flag_mask_:
|
||||
if name.startswith("RES_"):
|
||||
continue
|
||||
if getattr(self, name):
|
||||
res.append(name)
|
||||
return "|".join(res)
|
||||
|
||||
def __repr__(self):
|
||||
return "{0}({1})".format(type(self).__name__, self.dump())
|
||||
|
||||
__str__ = __repr__
|
||||
|
||||
def __hex__(self):
|
||||
return "{0}({1}:{2})".format(type(self).__name__, int.__hex__(self), self.dump())
|
||||
|
||||
class EnhancedCONTEXTBase(CONTEXT):
|
||||
default_dump = ()
|
||||
pc_reg = ''
|
||||
special_reg_type = {}
|
||||
|
||||
def regs(self, to_dump=None):
|
||||
res = []
|
||||
if to_dump is None:
|
||||
to_dump = self.default_dump
|
||||
for name in to_dump:
|
||||
res.append((name, getattr(self, name)))
|
||||
value = getattr(self, name)
|
||||
if name in self.special_reg_type:
|
||||
value = self.special_reg_type[name](value)
|
||||
res.append((name, value))
|
||||
return res
|
||||
|
||||
def dump(self, to_dump=None):
|
||||
regs = self.regs()
|
||||
for name, value in regs:
|
||||
print("{0} -> {1}".format(name, hex(value)))
|
||||
|
||||
@property
|
||||
def pc(self):
|
||||
print("{0} -> {1}".format(name, hex(value)))
|
||||
return None
|
||||
|
||||
def get_pc(self):
|
||||
return getattr(self, self.pc_reg)
|
||||
|
||||
def set_pc(self, value):
|
||||
return setattr(self, self.pc_reg, value)
|
||||
|
||||
pc = property(get_pc, set_pc, None, "Program Counter register (EIP or RIP)")
|
||||
|
||||
class EnhancedCONTEXT32(EnhancedCONTEXTBase):
|
||||
default_dump = ('Eip', 'Esp', 'Eax', 'Ebx', 'Ecx', 'Edx', 'Ebp', 'Edi', 'Esi')
|
||||
default_dump = ('Eip', 'Esp', 'Eax', 'Ebx', 'Ecx', 'Edx', 'Ebp', 'Edi', 'Esi', 'EFlags')
|
||||
pc_reg = 'Eip'
|
||||
special_reg_type = {'EFlags' : Eflags}
|
||||
|
||||
class EnhancedCONTEXT64(EnhancedCONTEXTBase):
|
||||
default_dump = ('Rip', 'Rsp', 'Rax', 'Rbx', 'Rcx', 'Rdx', 'Rbp', 'Rdi', 'Rsi',
|
||||
'R9', 'R10', 'R11', 'R12', 'R13', 'R14', 'R15')
|
||||
'R9', 'R10', 'R11', 'R12', 'R13', 'R14', 'R15', 'EFlags')
|
||||
pc_reg = 'Rip'
|
||||
special_reg_type = {'EFlags' : Eflags}
|
||||
|
||||
if windows.current_process.bitness == 32:
|
||||
EnhancedCONTEXT = EnhancedCONTEXT32
|
||||
@@ -107,10 +166,8 @@ class EnhancedEXCEPTION_POINTERS(ctypes.Structure):
|
||||
class VectoredException(object):
|
||||
func_type = ctypes.WINFUNCTYPE(ctypes.c_uint, ctypes.POINTER(EnhancedEXCEPTION_POINTERS))
|
||||
|
||||
def __init__(self, quit_if_fail=False):
|
||||
pass
|
||||
|
||||
def __call__(self, func):
|
||||
def __new__(cls, func):
|
||||
self = object.__new__(cls)
|
||||
self.func = func
|
||||
return self.func_type(self.decorator)
|
||||
|
||||
@@ -119,14 +176,12 @@ class VectoredException(object):
|
||||
return self.func(exception_pointers)
|
||||
except BaseException as e:
|
||||
print("Ignored Python Exception in Vectored Exception: {0}".format(e))
|
||||
if quit_if_fail:
|
||||
return windows.current_thread.quit()
|
||||
return windef.EXCEPTION_CONTINUE_SEARCH
|
||||
|
||||
|
||||
|
||||
class WithExceptionHandler(object):
|
||||
def __init__(self, handler):
|
||||
self.handler = handler
|
||||
self.handler = VectoredException(handler)
|
||||
|
||||
def __enter__(self):
|
||||
self.value = windows.k32testing.AddVectoredExceptionHandler(0, self.handler)
|
||||
|
||||
+84
-18
@@ -1,14 +1,20 @@
|
||||
import ctypes
|
||||
import os
|
||||
import codecs
|
||||
import copy
|
||||
|
||||
import windows
|
||||
import utils
|
||||
import k32testing as kernel32proxy
|
||||
import injection
|
||||
import native_exec
|
||||
import windows.k32testing as kernel32proxy
|
||||
import windows.injection as injection
|
||||
import windows.native_exec as native_exec
|
||||
|
||||
from . import utils
|
||||
|
||||
from windows.generated_def.winstructs import *
|
||||
from .generated_def import windef
|
||||
|
||||
import windows.pe_parse as pe_parse
|
||||
|
||||
from generated_def.winstructs import *
|
||||
import pe_parse
|
||||
|
||||
|
||||
class AutoHandle(object):
|
||||
@@ -44,7 +50,7 @@ class System(object):
|
||||
:type: [:class:`WinProcess`] -- A list of Process
|
||||
|
||||
"""
|
||||
return utils.enumerate_processes()
|
||||
return self.enumerate_processes()
|
||||
|
||||
@property
|
||||
def threads(self):
|
||||
@@ -53,7 +59,7 @@ class System(object):
|
||||
:type: [:class:`WinThread`] -- A list of Thread
|
||||
|
||||
"""
|
||||
return utils.enumerate_threads()
|
||||
return self.enumerate_threads()
|
||||
|
||||
@property
|
||||
def bitness(self):
|
||||
@@ -67,6 +73,30 @@ class System(object):
|
||||
if "PROCESSOR_ARCHITEW6432" in os.environ:
|
||||
return 64
|
||||
return 32
|
||||
|
||||
@staticmethod
|
||||
def enumerate_processes():
|
||||
process_entry = WinProcess()
|
||||
process_entry.dwSize = ctypes.sizeof(process_entry)
|
||||
snap = kernel32proxy.CreateToolhelp32Snapshot(windef.TH32CS_SNAPPROCESS, 0)
|
||||
kernel32proxy.Process32First(snap, process_entry)
|
||||
res = []
|
||||
res.append(utils.swallow_ctypes_copy(process_entry))
|
||||
while kernel32proxy.Process32Next(snap, process_entry):
|
||||
res.append(utils.swallow_ctypes_copy(process_entry))
|
||||
return res
|
||||
|
||||
@staticmethod
|
||||
def enumerate_threads():
|
||||
thread_entry = WinThread()
|
||||
thread_entry.dwSize = ctypes.sizeof(thread_entry)
|
||||
snap = kernel32proxy.CreateToolhelp32Snapshot(windef.TH32CS_SNAPTHREAD, 0)
|
||||
threads = []
|
||||
kernel32proxy.Thread32First(snap, thread_entry)
|
||||
threads.append(copy.copy(thread_entry))
|
||||
while kernel32proxy.Thread32Next(snap, thread_entry):
|
||||
threads.append(copy.copy(thread_entry))
|
||||
return threads
|
||||
|
||||
|
||||
class WinThread(THREADENTRY32, AutoHandle):
|
||||
@@ -85,15 +115,51 @@ class WinThread(THREADENTRY32, AutoHandle):
|
||||
"""
|
||||
if hasattr(self, "_owner"):
|
||||
return self._owner
|
||||
self._owner = [process for process in utils.enumerate_processes() if process.pid == self.th32OwnerProcessID][0]
|
||||
try:
|
||||
self._owner = [process for process in windows.system.processes if process.pid == self.th32OwnerProcessID][0]
|
||||
except IndexError:
|
||||
return None
|
||||
return self._owner
|
||||
|
||||
@property
|
||||
def context(self):
|
||||
x = windows.vectored_exception.EnhancedCONTEXT()
|
||||
x.ContextFlags = CONTEXT_FULL
|
||||
kernel32proxy.GetThreadContext(self.handle, x)
|
||||
return x
|
||||
|
||||
def set_context(self, context):
|
||||
return kernel32proxy.SetThreadContext(self.handle, context)
|
||||
|
||||
def exit(self, code=0):
|
||||
return kernel32proxy.TerminateThread(self.handle, code)
|
||||
|
||||
def resume(self):
|
||||
return kernel32proxy.ResumeThread(self.handle)
|
||||
|
||||
def suspend(self):
|
||||
return kernel32proxy.SuspendThread(self.handle)
|
||||
|
||||
def _get_handle(self):
|
||||
return kernel32proxy.OpenThread(dwThreadId=self.tid)
|
||||
|
||||
def __repr__(self):
|
||||
return '<{0} {1} owner "{2}" at {3}>'.format(self.__class__.__name__, self.tid, self.owner.name, hex(id(self)))
|
||||
|
||||
owner = self.owner
|
||||
if owner is None:
|
||||
owner_name = "<Dead process with pid {0}>".format(hex(self.th32OwnerProcessID))
|
||||
else:
|
||||
owner_name = owner.name
|
||||
return '<{0} {1} owner "{2}" at {3}>'.format(self.__class__.__name__, self.tid, owner_name, hex(id(self)))
|
||||
|
||||
@staticmethod
|
||||
def _from_handle(handle):
|
||||
tid = kernel32proxy.GetThreadId(handle)
|
||||
print(tid)
|
||||
try:
|
||||
return [t for t in System().threads if t.tid == tid][0]
|
||||
except IndexError:
|
||||
return (tid, handle)
|
||||
|
||||
class Process(AutoHandle):
|
||||
@property
|
||||
def is_wow_64(self):
|
||||
@@ -123,7 +189,7 @@ class Process(AutoHandle):
|
||||
:type: [:class:`WinThread`] -- A list of Thread
|
||||
|
||||
"""
|
||||
return [thread for thread in utils.enumerate_threads() if thread.th32OwnerProcessID == self.pid]
|
||||
return [thread for thread in windows.system.threads if thread.th32OwnerProcessID == self.pid]
|
||||
|
||||
def virtual_alloc(self, size):
|
||||
raise NotImplementedError("virtual_alloc")
|
||||
@@ -160,11 +226,10 @@ class CurrentThread(AutoHandle):
|
||||
class CurrentProcess(Process):
|
||||
"""The current process"""
|
||||
get_peb = None
|
||||
get_peb_32_code = '64a130000000c3'.decode('hex')
|
||||
|
||||
get_peb_32_code = codecs.decode(b'64a130000000c3', 'hex')
|
||||
# mov rax,QWORD PTR gs:0x60
|
||||
# ret
|
||||
get_peb_64_code = "65488B042560000000C3".decode('hex')
|
||||
get_peb_64_code = codecs.decode(b"65488B042560000000C3", 'hex')
|
||||
|
||||
allocator = native_exec.native_function.CustomAllocator()
|
||||
|
||||
@@ -240,7 +305,8 @@ class CurrentProcess(Process):
|
||||
.. note::
|
||||
CreateThread https://msdn.microsoft.com/en-us/library/windows/desktop/ms682453%28v=vs.85%29.aspx
|
||||
"""
|
||||
return kernel32proxy.CreateThread(lpStartAddress=lpStartAddress, lpParameter=lpParameter, dwCreationFlags=dwCreationFlags)
|
||||
handle = kernel32proxy.CreateThread(lpStartAddress=lpStartAddress, lpParameter=lpParameter, dwCreationFlags=dwCreationFlags)
|
||||
return WinThread._from_handle(handle)
|
||||
|
||||
def exit(self, code=0):
|
||||
"""Exit the process"""
|
||||
@@ -257,7 +323,7 @@ class WinProcess(PROCESSENTRY32, Process):
|
||||
|
||||
:type: str
|
||||
"""
|
||||
return self.szExeFile[:]
|
||||
return self.szExeFile[:].decode()
|
||||
|
||||
@property
|
||||
def pid(self):
|
||||
@@ -314,7 +380,7 @@ class WinProcess(PROCESSENTRY32, Process):
|
||||
"""Create a remote thread"""
|
||||
if windows.current_process.bitness == 32 and self.bitness == 64:
|
||||
return windows.syswow64.NtCreateThreadEx_32_to_64(self, addr, param)
|
||||
return kernel32proxy.CreateRemoteThread(hProcess=self.handle, lpStartAddress=addr, lpParameter=param)
|
||||
return WinThread._from_handle(kernel32proxy.CreateRemoteThread(hProcess=self.handle, lpStartAddress=addr, lpParameter=param))
|
||||
|
||||
def load_library(self, dll_path):
|
||||
"""Load the library in remote process"""
|
||||
|
||||
Reference in New Issue
Block a user