mirror of
https://github.com/hakril/PythonForWindows
synced 2026-06-08 14:31:45 +00:00
REAME / TODO / AUTHORS
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
# PythonForWindows
|
||||
|
||||
PythonForWindows is a base of code aimed to make interaction with Windows (on X86/X64) easier (with both 32 and 64 bits Python).
|
||||
It's goal is to offer abstractions around some of the OS features in a (I hope) pythonic way.
|
||||
It also tries to make the barrier between python and native execution thiner in both ways.
|
||||
There is no external dependencies but it relies heavily on the ctypes modules.
|
||||
|
||||
|
||||
Some of this code is clean (IMHO) and some parts are just a wreck that work for now.
|
||||
Let say that the codebase evolves with my needs and my curiosity.
|
||||
|
||||
You can find some examples of code in the `sample/` directory.
|
||||
|
||||
## Overview
|
||||
|
||||
### Processes / Threads
|
||||
|
||||
PythonForWindows offer a object oriented around processes of the system and allow you to:
|
||||
- Retrieve basic process informations (pid, name, ppid, bitness, ...)
|
||||
- Perform basic interprocess operation (alloc, create thread, read/write memory)
|
||||
- Explore the PEB (Process Environment Block)
|
||||
- Execute native and python code in the context of the process.
|
||||
|
||||
I try by best to make those features available for every cross-bitness processes (32 <-> 64 in both ways).
|
||||
This involve relying on non-documented Windows function/behaviour and also injecting code in the 64bits world of a Syswow64 process.
|
||||
All those operations are also available for the `current_process`.
|
||||
|
||||
You can also make some operation of threads (suspend/resume/wait/get( or set) context/ kill)
|
||||
|
||||
|
||||
### IAT Hook
|
||||
|
||||
This codebase is born from my need to have IAT hooks implemented in Python.
|
||||
So the features is present (see `sample`)
|
||||
|
||||
|
||||
### Winproxy
|
||||
|
||||
A pythonic wrapper around some Windows functions. Arguments name and order are the same,
|
||||
but some have default values and the functions raise exception on call error (I don't like 'if' around all my call).
|
||||
|
||||
|
||||
### Native execution
|
||||
|
||||
To make the barrier beetwen native and python code,
|
||||
PythonForWindows allows you to create native function callable from Python (thanks ctypes) and also embded
|
||||
a simple x86/x64 assembler.
|
||||
|
||||
|
||||
### COM on Python
|
||||
|
||||
Some code to call a COM interface from Python or create a COM object implemented in Python.
|
||||
|
||||
|
||||
### Other stuff
|
||||
|
||||
Some code are just exploration and need improvement like:
|
||||
- Wintrust
|
||||
- WMI
|
||||
- Registry access
|
||||
- Exception
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
TODO:
|
||||
- ProcessMemory object ? (metasm like)
|
||||
|
||||
FIXME:
|
||||
- WMI
|
||||
- COM initialisation when injected in another process
|
||||
- The CoInitialize might be already called
|
||||
- Fix that
|
||||
+32
-1
@@ -27,7 +27,6 @@ class Kernel32Error(WindowsError):
|
||||
|
||||
|
||||
class IphlpapiError(Kernel32Error):
|
||||
|
||||
def __new__(cls, func_name, code):
|
||||
win_error = ctypes.WinError(code)
|
||||
api_error = super(Kernel32Error, cls).__new__(cls)
|
||||
@@ -146,6 +145,11 @@ class Advapi32Proxy(ApiProxy):
|
||||
default_error_check = staticmethod(kernel32_error_check)
|
||||
|
||||
|
||||
class User32Proxy(ApiProxy):
|
||||
APIDLL = "user32"
|
||||
default_error_check = staticmethod(kernel32_error_check)
|
||||
|
||||
|
||||
class IphlpapiProxy(ApiProxy):
|
||||
APIDLL = "iphlpapi"
|
||||
default_error_check = staticmethod(iphlpapi_error_check)
|
||||
@@ -199,6 +203,7 @@ class TransparentApiProxy(object):
|
||||
|
||||
TransparentKernel32Proxy = lambda func_name, error_check=kernel32_error_check: TransparentApiProxy("kernel32", func_name, error_check)
|
||||
TransparentAdvapi32Proxy = lambda func_name, error_check=kernel32_error_check: TransparentApiProxy("advapi32", func_name, error_check)
|
||||
TransparentUser32Proxy = lambda func_name, error_check=kernel32_error_check: TransparentApiProxy("user32", func_name, error_check)
|
||||
TransparentIphlpapiProxy = lambda func_name, error_check=iphlpapi_error_check: TransparentApiProxy("iphlpapi", func_name, error_check)
|
||||
|
||||
|
||||
@@ -238,6 +243,11 @@ VirtualQueryEx = TransparentKernel32Proxy("VirtualQueryEx")
|
||||
GetExitCodeThread = TransparentKernel32Proxy("GetExitCodeThread")
|
||||
GetExitCodeProcess = TransparentKernel32Proxy("GetExitCodeProcess")
|
||||
|
||||
GlobalAlloc = TransparentKernel32Proxy("GlobalAlloc")
|
||||
GlobalFree = TransparentKernel32Proxy("GlobalFree")
|
||||
GlobalLock = TransparentKernel32Proxy("GlobalLock")
|
||||
GlobalUnlock = TransparentKernel32Proxy("GlobalUnlock", error_check=no_error_check)
|
||||
|
||||
Wow64DisableWow64FsRedirection = OptionalExport(TransparentKernel32Proxy)("Wow64DisableWow64FsRedirection")
|
||||
Wow64RevertWow64FsRedirection = OptionalExport(TransparentKernel32Proxy)("Wow64RevertWow64FsRedirection")
|
||||
Wow64EnableWow64FsRedirection = OptionalExport(TransparentKernel32Proxy)("Wow64EnableWow64FsRedirection")
|
||||
@@ -583,3 +593,24 @@ def GetExtendedTcpTable(pTcpTable, pdwSize=None, bOrder=True, ulAf=NeededParamet
|
||||
if pdwSize is None:
|
||||
ctypes.sizeof(pTcpTable)
|
||||
return GetExtendedTcpTable.ctypes_function(pTcpTable, pdwSize, bOrder, ulAf, TableClass, Reserved)
|
||||
|
||||
|
||||
# User32 #
|
||||
|
||||
EmptyClipboard = TransparentUser32Proxy("EmptyClipboard")
|
||||
CloseClipboard = TransparentUser32Proxy("CloseClipboard")
|
||||
SetClipboardData = TransparentUser32Proxy("SetClipboardData")
|
||||
GetClipboardData = TransparentUser32Proxy("GetClipboardData")
|
||||
GetClipboardFormatNameA = TransparentUser32Proxy("GetClipboardFormatNameA")
|
||||
GetClipboardFormatNameW = TransparentUser32Proxy("GetClipboardFormatNameW")
|
||||
|
||||
def check_zero_and_getlasterror(func_name, result, func, args):
|
||||
if not result and GetLastError() != 0:
|
||||
raise Kernel32Error(func_name)
|
||||
return args
|
||||
|
||||
EnumClipboardFormats = TransparentUser32Proxy("EnumClipboardFormats", error_check=check_zero_and_getlasterror)
|
||||
|
||||
@User32Proxy("OpenClipboard")
|
||||
def OpenClipboard(hWndNewOwner=None):
|
||||
return OpenClipboard.ctypes_function(hWndNewOwner)
|
||||
Reference in New Issue
Block a user