mirror of
https://github.com/hakril/PythonForWindows
synced 2026-06-08 14:31:45 +00:00
Add some functions + utility to create a console into injected process
This commit is contained in:
@@ -15,6 +15,9 @@ MAX_PATH = Flag("MAX_PATH", 260)
|
||||
ANYSIZE_ARRAY = Flag("ANYSIZE_ARRAY", 1)
|
||||
IMAGE_SIZEOF_SHORT_NAME = Flag("IMAGE_SIZEOF_SHORT_NAME", 8)
|
||||
IMAGE_NUMBEROF_DIRECTORY_ENTRIES = Flag("IMAGE_NUMBEROF_DIRECTORY_ENTRIES", 16)
|
||||
STD_INPUT_HANDLE = Flag("STD_INPUT_HANDLE", -10)
|
||||
STD_OUTPUT_HANDLE = Flag("STD_OUTPUT_HANDLE", -11)
|
||||
STD_ERROR_HANDLE = Flag("STD_ERROR_HANDLE", -12)
|
||||
WARMING_NOT_SAME_FLAG_FOR_WINXP = Flag("WARMING_NOT_SAME_FLAG_FOR_WINXP", 0)
|
||||
PROCESS_ALL_ACCESS = Flag("PROCESS_ALL_ACCESS", 0x001F0FFF)
|
||||
THREAD_ALL_ACCESS = Flag("THREAD_ALL_ACCESS", 0x001F03FF)
|
||||
|
||||
@@ -3,7 +3,7 @@ from ctypes import *
|
||||
from ctypes.wintypes import *
|
||||
from winstructs import *
|
||||
|
||||
functions = ['ExitProcess', 'GetLastError', 'GetCurrentProcess', 'CreateFileA', 'CreateFileW', 'NtQuerySystemInformation', 'VirtualAlloc', 'VirtualAllocEx', 'VirtualProtect', 'VirtualQuery', 'GetModuleFileNameA', 'GetModuleFileNameW', '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']
|
||||
functions = ['ExitProcess', 'GetLastError', 'GetCurrentProcess', 'CreateFileA', 'CreateFileW', 'NtQuerySystemInformation', 'VirtualAlloc', 'VirtualAllocEx', 'VirtualProtect', 'VirtualQuery', 'GetModuleFileNameA', 'GetModuleFileNameW', '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', 'GetCurrentProcessorNumber', 'AllocConsole', 'GetStdHandle', 'SetStdHandle', 'SetThreadAffinityMask', 'WriteFile']
|
||||
|
||||
# ExitProcess(uExitCode):
|
||||
ExitProcessPrototype = WINFUNCTYPE(VOID, UINT)
|
||||
@@ -185,3 +185,31 @@ GetVersionExWParams = ((1, 'lpVersionInformation'),)
|
||||
GetVersionPrototype = WINFUNCTYPE(DWORD)
|
||||
GetVersionParams = ()
|
||||
|
||||
# GetCurrentThread():
|
||||
GetCurrentThreadPrototype = WINFUNCTYPE(HANDLE)
|
||||
GetCurrentThreadParams = ()
|
||||
|
||||
# GetCurrentProcessorNumber():
|
||||
GetCurrentProcessorNumberPrototype = WINFUNCTYPE(DWORD)
|
||||
GetCurrentProcessorNumberParams = ()
|
||||
|
||||
# AllocConsole():
|
||||
AllocConsolePrototype = WINFUNCTYPE(BOOL)
|
||||
AllocConsoleParams = ()
|
||||
|
||||
# GetStdHandle(nStdHandle):
|
||||
GetStdHandlePrototype = WINFUNCTYPE(HANDLE, DWORD)
|
||||
GetStdHandleParams = ((1, 'nStdHandle'),)
|
||||
|
||||
# SetStdHandle(nStdHandle, hHandle):
|
||||
SetStdHandlePrototype = WINFUNCTYPE(BOOL, DWORD, HANDLE)
|
||||
SetStdHandleParams = ((1, 'nStdHandle'), (1, 'hHandle'))
|
||||
|
||||
# SetThreadAffinityMask(hThread, dwThreadAffinityMask):
|
||||
SetThreadAffinityMaskPrototype = WINFUNCTYPE(DWORD, HANDLE, DWORD)
|
||||
SetThreadAffinityMaskParams = ((1, 'hThread'), (1, 'dwThreadAffinityMask'))
|
||||
|
||||
# WriteFile(hFile, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, lpOverlapped):
|
||||
WriteFilePrototype = WINFUNCTYPE(BOOL, HANDLE, LPCVOID, DWORD, LPDWORD, LPOVERLAPPED)
|
||||
WriteFileParams = ((1, 'hFile'), (1, 'lpBuffer'), (1, 'nNumberOfBytesToWrite'), (1, 'lpNumberOfBytesWritten'), (1, 'lpOverlapped'))
|
||||
|
||||
|
||||
@@ -17,12 +17,13 @@ ULONG_PTR = PULONG
|
||||
CHAR = c_char
|
||||
FARPROC = PVOID
|
||||
HGLOBAL = PVOID
|
||||
HRESULT = c_long
|
||||
ULONGLONG = c_ulonglong
|
||||
ULONG64 = c_ulonglong
|
||||
PULONG64 = POINTER(ULONG64)
|
||||
PHANDLE = POINTER(HANDLE)
|
||||
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', '_PEB_LDR_DATA', '_IMAGE_FILE_HEADER', '_IMAGE_DATA_DIRECTORY', '_IMAGE_SECTION_HEADER', '_IMAGE_OPTIONAL_HEADER64', '_IMAGE_OPTIONAL_HEADER', '_IMAGE_NT_HEADERS64', '_IMAGE_NT_HEADERS', '_IMAGE_IMPORT_DESCRIPTOR', '_MEMORY_BASIC_INFORMATION', '_STARTUPINFOA', '_STARTUPINFOW', '_PROCESS_INFORMATION', '_FLOATING_SAVE_AREA', '_CONTEXT', 'tagPROCESSENTRY32W', 'tagPROCESSENTRY32', 'tagTHREADENTRY32', '_LUID', '_LUID_AND_ATTRIBUTES', '_TOKEN_PRIVILEGES', '_OSVERSIONINFOA', '_OSVERSIONINFOW', '_OSVERSIONINFOEXA', '_OSVERSIONINFOEXW']
|
||||
structs = ['_LIST_ENTRY', '_PEB_LDR_DATA', '_LSA_UNICODE_STRING', '_RTL_USER_PROCESS_PARAMETERS', '_PEB', '_SECURITY_ATTRIBUTES', '_SYSTEM_VERIFIER_INFORMATION', '_LDR_DATA_TABLE_ENTRY', '_PEB_LDR_DATA', '_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', '_CONTEXT', 'tagPROCESSENTRY32W', 'tagPROCESSENTRY32', 'tagTHREADENTRY32', '_LUID', '_LUID_AND_ATTRIBUTES', '_TOKEN_PRIVILEGES', '_OSVERSIONINFOA', '_OSVERSIONINFOW', '_OSVERSIONINFOEXA', '_OSVERSIONINFOEXW', '_OVERLAPPED']
|
||||
|
||||
enums = ['_SYSTEM_INFORMATION_CLASS']
|
||||
|
||||
@@ -394,6 +395,15 @@ class _IMAGE_IMPORT_DESCRIPTOR(Structure):
|
||||
IMAGE_IMPORT_DESCRIPTOR = _IMAGE_IMPORT_DESCRIPTOR
|
||||
PIMAGE_IMPORT_DESCRIPTOR = POINTER(_IMAGE_IMPORT_DESCRIPTOR)
|
||||
|
||||
# Struct _IMAGE_IMPORT_BY_NAME definitions
|
||||
class _IMAGE_IMPORT_BY_NAME(Structure):
|
||||
_fields_ = [
|
||||
("Hint", WORD),
|
||||
("Name", BYTE * 1),
|
||||
]
|
||||
PIMAGE_IMPORT_BY_NAME = POINTER(_IMAGE_IMPORT_BY_NAME)
|
||||
IMAGE_IMPORT_BY_NAME = _IMAGE_IMPORT_BY_NAME
|
||||
|
||||
# Struct _MEMORY_BASIC_INFORMATION definitions
|
||||
class _MEMORY_BASIC_INFORMATION(Structure):
|
||||
_fields_ = [
|
||||
@@ -666,3 +676,14 @@ OSVERSIONINFOEXW = _OSVERSIONINFOEXW
|
||||
POSVERSIONINFOEXW = POINTER(_OSVERSIONINFOEXW)
|
||||
RTL_OSVERSIONINFOEXW = _OSVERSIONINFOEXW
|
||||
|
||||
# Struct _OVERLAPPED definitions
|
||||
class _OVERLAPPED(Structure):
|
||||
_fields_ = [
|
||||
("Internal", ULONG_PTR),
|
||||
("InternalHigh", ULONG_PTR),
|
||||
("Pointer", PVOID),
|
||||
("hEvent", HANDLE),
|
||||
]
|
||||
LPOVERLAPPED = POINTER(_OVERLAPPED)
|
||||
OVERLAPPED = _OVERLAPPED
|
||||
|
||||
|
||||
@@ -120,6 +120,11 @@ LoadLibraryA = TransparentKernel32Proxy("LoadLibraryA")
|
||||
LoadLibraryW = TransparentKernel32Proxy("LoadLibraryW")
|
||||
GetLastError = TransparentKernel32Proxy("GetLastError", no_error_check)
|
||||
GetCurrentProcess = TransparentKernel32Proxy("GetCurrentProcess")
|
||||
GetCurrentProcessorNumber = TransparentKernel32Proxy("GetCurrentProcessorNumber", no_error_check)
|
||||
GetCurrentThread = TransparentKernel32Proxy("GetCurrentThread")
|
||||
AllocConsole = TransparentKernel32Proxy("AllocConsole")
|
||||
GetStdHandle = TransparentKernel32Proxy("GetStdHandle")
|
||||
SetStdHandle = TransparentKernel32Proxy("SetStdHandle")
|
||||
|
||||
# This kind of function could be fully done by using paramflags
|
||||
@Kernel32Proxy("VirtualAlloc")
|
||||
@@ -202,6 +207,14 @@ def WriteProcessMemory(hProcess, lpBaseAddress, lpBuffer, nSize=None, lpNumberOf
|
||||
nSize = len(lpBuffer)
|
||||
return WriteProcessMemory.ctypes_function(hProcess, lpBaseAddress, lpBuffer, nSize, lpNumberOfBytesWritten)
|
||||
|
||||
@Kernel32Proxy('SetThreadAffinityMask')
|
||||
def SetThreadAffinityMask(hThread=None, dwThreadAffinityMask=NeededParameter):
|
||||
"""If hThread is not given, it will be the current thread"""
|
||||
if hThread is None:
|
||||
hThread = GetCurrentThread()
|
||||
return SetThreadAffinityMask.ctypes_function(hThread, dwThreadAffinityMask)
|
||||
|
||||
|
||||
@Kernel32Proxy("CreateToolhelp32Snapshot")
|
||||
def CreateToolhelp32Snapshot(dwFlags, th32ProcessID=0):
|
||||
return CreateToolhelp32Snapshot.ctypes_function(dwFlags, th32ProcessID)
|
||||
@@ -233,6 +246,16 @@ def Process32Next(hSnapshot, lpte):
|
||||
if type(lpte) == THREADENTRY32:
|
||||
lpte = ctypes.byref(lpte)
|
||||
return Process32Next.ctypes_function(hSnapshot, lpte)
|
||||
|
||||
# File stuff
|
||||
|
||||
@Kernel32Proxy("WriteFile")
|
||||
def WriteFile(hFile, lpBuffer, nNumberOfBytesToWrite=None, lpNumberOfBytesWritten=None, lpOverlapped=None):
|
||||
if nNumberOfBytesToWrite is None:
|
||||
nNumberOfBytesToWrite = len(lpBuffer)
|
||||
if lpOverlapped is None and lpNumberOfBytesWritten is None:
|
||||
lpNumberOfBytesWritten = ctypes.byref(DWORD())
|
||||
return WriteFile.ctypes_function(hFile, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, lpOverlapped)
|
||||
|
||||
|
||||
###### ADVAPI32 ########
|
||||
|
||||
@@ -260,7 +260,6 @@ def generate_stub_64(callback):
|
||||
code += Mov_RAX_X(save_r9)
|
||||
code += Mov_R9_DRAX()
|
||||
# Call python code
|
||||
code += Int3()
|
||||
code += Mov_RAX_X(c_callback)
|
||||
code += Reserve_space_for_call
|
||||
code += Call_RAX() # no need for stack alignement here as we poped the return addr
|
||||
|
||||
+2
-2
@@ -4,13 +4,13 @@ from windows.hooks import *
|
||||
|
||||
# Example of callback for IAT hooks
|
||||
|
||||
@Callback(ctypes.c_ulong, ctypes.c_ulong)
|
||||
@Callback(ctypes.c_void_p, ctypes.c_ulong)
|
||||
def exit_callback(x, real_function):
|
||||
print("Try to quit with {0} | {1}".format(x, type(x)))
|
||||
if x == 3:
|
||||
print("TRYING TO REAL EXIT")
|
||||
return real_function(1234)
|
||||
return 0
|
||||
return 0x4242424243444546
|
||||
|
||||
@CreateFileACallback
|
||||
def createfile_callback(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile, real_function):
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
import ctypes
|
||||
import msvcrt
|
||||
import os
|
||||
import copy
|
||||
import sys
|
||||
|
||||
import k32testing as kernel32proxy
|
||||
import generated_def.windef as windef
|
||||
import winobject
|
||||
import copy
|
||||
import native_exec
|
||||
from generated_def.winstructs import *
|
||||
|
||||
@@ -50,6 +54,27 @@ def is_wow_64(hProcess):
|
||||
if res:
|
||||
return bool(Wow64Process)
|
||||
raise ctypes.WinError()
|
||||
|
||||
def create_file_from_handle(handle, mode="r"):
|
||||
fd = msvcrt.open_osfhandle(handle, os.O_TEXT)
|
||||
return os.fdopen(fd, mode, 0)
|
||||
|
||||
def get_handle_from_file(f):
|
||||
return msvcrt.get_osfhandle(f.fileno())
|
||||
|
||||
def create_console():
|
||||
kernel32proxy.AllocConsole()
|
||||
stdout_handle = kernel32proxy.GetStdHandle(windef.STD_OUTPUT_HANDLE)
|
||||
console_stdout = create_file_from_handle(stdout_handle, "w")
|
||||
sys.stdout = console_stdout
|
||||
|
||||
stdin_handle = kernel32proxy.GetStdHandle(windef.STD_INPUT_HANDLE)
|
||||
console_stdin = create_file_from_handle(stdin_handle, "r+")
|
||||
sys.stdin = console_stdin
|
||||
|
||||
stderr_handle = kernel32proxy.GetStdHandle(windef.STD_ERROR_HANDLE)
|
||||
console_stderr = create_file_from_handle(stderr_handle, "w")
|
||||
sys.stderr = console_stderr
|
||||
|
||||
class VirtualProtected(object):
|
||||
def __init__(self, addr, size, new_protect):
|
||||
|
||||
Reference in New Issue
Block a user