mirror of
https://github.com/hakril/PythonForWindows
synced 2026-06-08 14:31:45 +00:00
Fix some docstring + re-add windows.test.pop_proc_[32|64] + fix all samples + few doc adapt
This commit is contained in:
@@ -14,6 +14,9 @@ You can find some examples of code in the [samples directory][SAMPLE_DIR] or [on
|
||||
|
||||
Parts of PythonForWindows are used in the [LKD project][LKD_GITHUB].
|
||||
|
||||
If you have any issue, question, suggestion do not hesitate to contact me.
|
||||
I am always glad to have feedbacks from people using this project.
|
||||
|
||||
## Overview
|
||||
|
||||
### Processes / Threads
|
||||
@@ -102,7 +105,7 @@ So the features is present (See [online documentation][ONLINE_IATHOOK] about IAT
|
||||
### Winproxy
|
||||
|
||||
A 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).
|
||||
but some have default values and the functions raise exception on call error (I don't like `if` around all my call).
|
||||
|
||||
```python
|
||||
>>> import windows
|
||||
@@ -150,8 +153,8 @@ windows.winproxy.Kernel32Error: VirtualAlloc: [Error 8] Not enough storage is av
|
||||
|
||||
### Native execution
|
||||
|
||||
To make the barrier between `native` and `Python` code,
|
||||
PythonForWindows allows you to create native function callable from Python (thanks `ctypes`) and also embed
|
||||
To make the barrier between `native` and `Python` code thinner,
|
||||
PythonForWindows allows you to create native function callable from Python (thanks to `ctypes`) and also embed
|
||||
a simple x86/x64 assembler.
|
||||
|
||||
```python
|
||||
|
||||
@@ -489,13 +489,6 @@ typedef enum _SID_NAME_USE {
|
||||
SidTypeLabel = 10
|
||||
} SID_NAME_USE, *PSID_NAME_USE;
|
||||
|
||||
typedef enum NET_FW_PROFILE_TYPE2_ {
|
||||
NET_FW_PROFILE2_DOMAIN = 0x1,
|
||||
NET_FW_PROFILE2_PRIVATE = 0x2,
|
||||
NET_FW_PROFILE2_PUBLIC = 0x4,
|
||||
NET_FW_PROFILE2_ALL = 0x7fffffff
|
||||
} NET_FW_PROFILE_TYPE2;
|
||||
|
||||
typedef enum NET_FW_ACTION_ {
|
||||
NET_FW_ACTION_BLOCK = 0,
|
||||
NET_FW_ACTION_ALLOW = 1,
|
||||
@@ -508,13 +501,6 @@ typedef enum NET_FW_MODIFY_STATE_ {
|
||||
NET_FW_MODIFY_STATE_INBOUND_BLOCKED = 2
|
||||
} NET_FW_MODIFY_STATE;
|
||||
|
||||
typedef enum NET_FW_RULE_DIRECTION_ {
|
||||
NET_FW_RULE_DIR_IN = 1,
|
||||
NET_FW_RULE_DIR_OUT = 2 ,
|
||||
NET_FW_RULE_DIR_MAX = 3
|
||||
} NET_FW_RULE_DIRECTION;
|
||||
|
||||
|
||||
|
||||
typedef enum tag_WBEMSTATUS {
|
||||
WBEM_NO_ERROR = 0,
|
||||
|
||||
@@ -252,7 +252,7 @@ class InitialDefGenerator(CtypesGenerator):
|
||||
return ctypes_code
|
||||
|
||||
def generate_doc(self, target_file):
|
||||
all_lines = [".. currentmodule:: windows.generated_def\n"
|
||||
all_lines = [".. currentmodule:: windows.generated_def\n\n"
|
||||
"Windef\n"
|
||||
"------\n"]
|
||||
all_lines += [".. autodata:: {windef.name}\n".format(windef=windef) for windef in self.parse()]
|
||||
@@ -356,7 +356,7 @@ class StructGenerator(CtypesGenerator):
|
||||
self.check_dependances()
|
||||
|
||||
def generate_doc(self, target_file):
|
||||
all_lines = [".. currentmodule:: windows.generated_def\n"
|
||||
all_lines = [".. currentmodule:: windows.generated_def\n\n"
|
||||
"Winstructs\n"
|
||||
"----------\n"]
|
||||
struct_separator = "'"
|
||||
@@ -494,7 +494,7 @@ class NtStatusGenerator(CtypesGenerator):
|
||||
return ctypes_code
|
||||
|
||||
def generate_doc(self, target_file):
|
||||
all_lines = [".. currentmodule:: windows.generated_def\n"
|
||||
all_lines = [".. currentmodule:: windows.generated_def\n\n"
|
||||
"Ntstatus\n"
|
||||
"--------\n"]
|
||||
all_lines += [".. autodata:: {nstatus_name}\n".format(nstatus_name=nstatus[1]) for nstatus in self.parse()]
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
LOOL
|
||||
****
|
||||
|
||||
.. module:: windows.generated_def
|
||||
|
||||
.. class:: windows.generated_def.IMAGE_FILE_HEADER
|
||||
|
||||
public name of :class:`windows.generated_def.winstructs._IMAGE_FILE_HEADER`
|
||||
|
||||
|
||||
.. autoclass:: windows.generated_def.winstructs._PEB
|
||||
|
||||
.. autoclass:: windows.generated_def.winstructs._PEB_LDR_DATA
|
||||
|
||||
|
||||
yolo :class:`windows.generated_def.ERROR_RXACT_STATE_CREATED`
|
||||
|
||||
:class:`windows.generated_def._ALPC_PORT_INFORMATION_CLASS`
|
||||
|
||||
|
||||
:class:`windows.generated_def._ALPC_PORT_INFORMATION_CLASS.AlpcServerInformation`
|
||||
@@ -67,6 +67,7 @@ else:
|
||||
print("Not found :(")
|
||||
|
||||
## Extract certificates of a PE file
|
||||
## This code is not a fixed API and the current state of my tests
|
||||
|
||||
print ("")
|
||||
print ("== PE Analysis ==")
|
||||
@@ -74,15 +75,15 @@ TARGET_FILE = r"C:\windows\system32\ntdll.dll"
|
||||
print("Target sha1 = <{0}>".format(hashlib.sha1(open(TARGET_FILE, "rb").read()).hexdigest()))
|
||||
cryptobj = windows.crypto.CryptObject(TARGET_FILE)
|
||||
print("Analysing {0}".format(cryptobj))
|
||||
print("File has {0} signer(s):".format(cryptobj.nb_signer))
|
||||
for i, signer in ((i, cryptobj.get_signer_data(i)) for i in range(cryptobj.nb_signer)):
|
||||
print("File has {0} signer(s):".format(cryptobj.crypt_msg.nb_signer))
|
||||
for i, signer in enumerate(cryptobj.crypt_msg.signers):
|
||||
print("Signer {0}:".format(i))
|
||||
print(" * Issuer: {0!r}".format(windows.crypto.ECRYPT_DATA_BLOB(signer.Issuer.cbData, signer.Issuer.pbData).data))
|
||||
print(" * HashAlgorithme: {0}".format(signer.HashAlgorithm.pszObjId))
|
||||
cert = cryptobj.get_signer_certificate(i)
|
||||
cert = cryptobj.cert_store.find(signer.Issuer, signer.SerialNumber)
|
||||
print(" * Certificate: {0}".format(cert))
|
||||
|
||||
print("")
|
||||
print("File embdeds {0} certificate(s):".format(cryptobj.nb_cert))
|
||||
for i, certificate in ((i, cryptobj.get_cert(i)) for i in range(cryptobj.nb_cert)):
|
||||
print("File embdeds {0} certificate(s):".format(cryptobj.crypt_msg.nb_cert))
|
||||
for i, certificate in enumerate(cryptobj.crypt_msg.certs):
|
||||
print(" * {0}) {1}".format(i, certificate))
|
||||
@@ -25,6 +25,6 @@ def follow_create_file(pid):
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Create a non-debugged process safe to debug
|
||||
calc = windows.test.pop_calc_32(dwCreationFlags=0)
|
||||
calc = windows.test.pop_proc_32(dwCreationFlags=0)
|
||||
# Give ovnly the PID to follow_create_file
|
||||
follow_create_file(calc.pid)
|
||||
|
||||
@@ -42,7 +42,7 @@ class FollowNtCreateFile(windows.debug.FunctionBP):
|
||||
self.COUNTER -= 1
|
||||
|
||||
if __name__ == "__main__":
|
||||
calc = windows.test.pop_calc_32(dwCreationFlags=DEBUG_PROCESS)
|
||||
calc = windows.test.pop_proc_32(dwCreationFlags=DEBUG_PROCESS)
|
||||
d = windows.debug.Debugger(calc)
|
||||
d.add_bp(FollowNtCreateFile())
|
||||
d.loop()
|
||||
@@ -71,6 +71,6 @@ class MyDebugger(windows.debug.Debugger):
|
||||
pass
|
||||
|
||||
|
||||
calc = windows.test.pop_calc_32(dwCreationFlags=DEBUG_PROCESS)
|
||||
calc = windows.test.pop_proc_32(dwCreationFlags=DEBUG_PROCESS)
|
||||
d = MyDebugger(calc)
|
||||
d.loop()
|
||||
|
||||
@@ -43,7 +43,7 @@ class SingleStepOnWrite(windows.debug.MemoryBreakpoint):
|
||||
return dbg.single_step()
|
||||
|
||||
|
||||
calc = windows.test.pop_calc_32(dwCreationFlags=DEBUG_PROCESS)
|
||||
calc = windows.test.pop_proc_32(dwCreationFlags=DEBUG_PROCESS)
|
||||
d = MyDebugger(calc)
|
||||
|
||||
code = calc.virtual_alloc(0x1000)
|
||||
|
||||
@@ -39,7 +39,7 @@ class PrintUnicodeString(windows.debug.Breakpoint):
|
||||
dbg.current_process.exit()
|
||||
|
||||
|
||||
calc = windows.test.pop_calc_32(dwCreationFlags=DEBUG_PROCESS)
|
||||
calc = windows.test.pop_proc_32(dwCreationFlags=DEBUG_PROCESS)
|
||||
d = MyDebugger(calc)
|
||||
d.add_bp(PrintUnicodeString("ntdll!LdrLoadDll", argument_position=2))
|
||||
d.loop()
|
||||
|
||||
@@ -35,7 +35,7 @@ d.add_bp(YOLOHXBP(ldr))
|
||||
|
||||
"""
|
||||
|
||||
c = windows.test.pop_calc_32(dwCreationFlags=CREATE_SUSPENDED)
|
||||
c = windows.test.pop_proc_32(dwCreationFlags=CREATE_SUSPENDED)
|
||||
c.execute_python(remote_code)
|
||||
c.threads[0].resume()
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ c += x64.Ret()
|
||||
RemoteManualLoadLibray += GetProcAddress64
|
||||
|
||||
|
||||
calc= windows.test.pop_calc_64(dwCreationFlags=CREATE_SUSPENDED)
|
||||
calc= windows.test.pop_proc_64(dwCreationFlags=CREATE_SUSPENDED)
|
||||
|
||||
addr = calc.virtual_alloc(0x1000)
|
||||
addr2 = addr + len(dll)
|
||||
|
||||
@@ -53,7 +53,7 @@ print("Protected page is at {0}".format(hex(target_page)))
|
||||
windows.winproxy.VirtualProtect(target_page, code_size, windef.PAGE_READWRITE)
|
||||
"""
|
||||
|
||||
c = windows.test.pop_calc_64(dwCreationFlags=CREATE_SUSPENDED)
|
||||
c = windows.test.pop_proc_64(dwCreationFlags=CREATE_SUSPENDED)
|
||||
x = c.execute_python(python_code)
|
||||
|
||||
c.threads[0].resume()
|
||||
|
||||
@@ -116,7 +116,7 @@ class CodeTesteur(dbg.Debugger):
|
||||
|
||||
def test_code_x86(code, regs=None, raw=False, **kwargs):
|
||||
print("Testing x86 code")
|
||||
process = windows.test.pop_calc_32(dwCreationFlags=DEBUG_PROCESS)
|
||||
process = windows.test.pop_proc_32(dwCreationFlags=DEBUG_PROCESS)
|
||||
if raw:
|
||||
code = code.replace(" ", "").decode('hex')
|
||||
else:
|
||||
@@ -140,7 +140,7 @@ def test_code_x64(code, regs=None, raw=False, **kwargs):
|
||||
print("Testing x64 code")
|
||||
if windows.current_process.bitness == 32:
|
||||
raise ValueError("Cannot debug a 64b process from 32b python")
|
||||
process = windows.test.pop_calc_64(dwCreationFlags=DEBUG_PROCESS)
|
||||
process = windows.test.pop_proc_64(dwCreationFlags=DEBUG_PROCESS)
|
||||
if raw:
|
||||
code = code.replace(" ", "").decode('hex')
|
||||
else:
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
import windows
|
||||
import windows.generated_def as gdef
|
||||
|
||||
def test_ipv4_connection():
|
||||
windows.system.network.ipv4 # Better idea ?
|
||||
|
||||
def test_ipv6_connection():
|
||||
windows.system.network.ipv6 # Better idea ?
|
||||
|
||||
def test_firewall():
|
||||
firewall = windows.system.network.firewall
|
||||
assert firewall.enabled # Its a dict that should not be empty
|
||||
assert firewall.rules # Its a list that should not be empty
|
||||
# Just check that fields exists and do not crash for now
|
||||
rule = firewall.rules[0]
|
||||
rule.name
|
||||
rule.description
|
||||
rule.protocol
|
||||
rule.remote_port
|
||||
rule.local_port
|
||||
rule.local_address
|
||||
rule.remote_address
|
||||
rule.application_name
|
||||
rule.direction
|
||||
rule.enabled
|
||||
+1
-1
@@ -61,7 +61,7 @@ class AlpcMessage(object):
|
||||
@property
|
||||
def security_attribute(self):
|
||||
"""The :data:`~windows.generated_def.ALPC_MESSAGE_SECURITY_ATTRIBUTE` of the message
|
||||
:
|
||||
|
||||
:type: :class:`ALPC_SECURITY_ATTR`
|
||||
"""
|
||||
return self.attributes.get_attribute(gdef.ALPC_MESSAGE_SECURITY_ATTRIBUTE)
|
||||
|
||||
@@ -430,7 +430,7 @@ class CryptContext(gdef.HCRYPTPROV):
|
||||
except WindowsError as e:
|
||||
if not self.retrycreate:
|
||||
raise
|
||||
return winproxy.CryptAcquireContextW(self, self.pszContainer, self.pszProvider, self.dwProvType, self.dwFlags | CRYPT_NEWKEYSET)
|
||||
return winproxy.CryptAcquireContextW(self, self.pszContainer, self.pszProvider, self.dwProvType, self.dwFlags | gdef.CRYPT_NEWKEYSET)
|
||||
|
||||
def release(self):
|
||||
return winproxy.CryptReleaseContext(self, False)
|
||||
@@ -1,3 +1,4 @@
|
||||
import windows
|
||||
from windows import winproxy
|
||||
from windows.generated_def import *
|
||||
|
||||
|
||||
@@ -587,16 +587,6 @@ SID_NAME_USE = _SID_NAME_USE
|
||||
PSID_NAME_USE = POINTER(_SID_NAME_USE)
|
||||
|
||||
|
||||
NET_FW_PROFILE2_DOMAIN = EnumValue("NET_FW_PROFILE_TYPE2_", "NET_FW_PROFILE2_DOMAIN", 0x1)
|
||||
NET_FW_PROFILE2_PRIVATE = EnumValue("NET_FW_PROFILE_TYPE2_", "NET_FW_PROFILE2_PRIVATE", 0x2)
|
||||
NET_FW_PROFILE2_PUBLIC = EnumValue("NET_FW_PROFILE_TYPE2_", "NET_FW_PROFILE2_PUBLIC", 0x4)
|
||||
NET_FW_PROFILE2_ALL = EnumValue("NET_FW_PROFILE_TYPE2_", "NET_FW_PROFILE2_ALL", 0x7fffffff)
|
||||
class NET_FW_PROFILE_TYPE2_(EnumType):
|
||||
values = [NET_FW_PROFILE2_DOMAIN, NET_FW_PROFILE2_PRIVATE, NET_FW_PROFILE2_PUBLIC, NET_FW_PROFILE2_ALL]
|
||||
mapper = {x:x for x in values}
|
||||
NET_FW_PROFILE_TYPE2 = NET_FW_PROFILE_TYPE2_
|
||||
|
||||
|
||||
NET_FW_ACTION_BLOCK = EnumValue("NET_FW_ACTION_", "NET_FW_ACTION_BLOCK", 0x0)
|
||||
NET_FW_ACTION_ALLOW = EnumValue("NET_FW_ACTION_", "NET_FW_ACTION_ALLOW", 0x1)
|
||||
NET_FW_ACTION_MAX = EnumValue("NET_FW_ACTION_", "NET_FW_ACTION_MAX", 0x2)
|
||||
@@ -615,15 +605,6 @@ class NET_FW_MODIFY_STATE_(EnumType):
|
||||
NET_FW_MODIFY_STATE = NET_FW_MODIFY_STATE_
|
||||
|
||||
|
||||
NET_FW_RULE_DIR_IN = EnumValue("NET_FW_RULE_DIRECTION_", "NET_FW_RULE_DIR_IN", 0x1)
|
||||
NET_FW_RULE_DIR_OUT = EnumValue("NET_FW_RULE_DIRECTION_", "NET_FW_RULE_DIR_OUT", 0x2)
|
||||
NET_FW_RULE_DIR_MAX = EnumValue("NET_FW_RULE_DIRECTION_", "NET_FW_RULE_DIR_MAX", 0x3)
|
||||
class NET_FW_RULE_DIRECTION_(EnumType):
|
||||
values = [NET_FW_RULE_DIR_IN, NET_FW_RULE_DIR_OUT, NET_FW_RULE_DIR_MAX]
|
||||
mapper = {x:x for x in values}
|
||||
NET_FW_RULE_DIRECTION = NET_FW_RULE_DIRECTION_
|
||||
|
||||
|
||||
WBEM_NO_ERROR = EnumValue("tag_WBEMSTATUS", "WBEM_NO_ERROR", 0x0)
|
||||
WBEM_S_NO_ERROR = EnumValue("tag_WBEMSTATUS", "WBEM_S_NO_ERROR", 0x0)
|
||||
WBEM_S_SAME = EnumValue("tag_WBEMSTATUS", "WBEM_S_SAME", 0x0)
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
import windows
|
||||
import windows.generated_def as gdef
|
||||
from windows.utils import create_process, DisableWow64FsRedirection
|
||||
|
||||
|
||||
test_binary_name = "notepad.exe"
|
||||
DEFAULT_CREATION_FLAGS = gdef.CREATE_NEW_CONSOLE
|
||||
|
||||
if windows.system.bitness == 32:
|
||||
def pop_proc_32(dwCreationFlags=DEFAULT_CREATION_FLAGS):
|
||||
return create_process(r"C:\Windows\system32\{0}".format(test_binary_name), dwCreationFlags=dwCreationFlags, show_windows=True)
|
||||
|
||||
def pop_proc_64(dwCreationFlags=DEFAULT_CREATION_FLAGS):
|
||||
raise WindowsError("Cannot create calc64 in 32bits system")
|
||||
else:
|
||||
def pop_proc_32(dwCreationFlags=DEFAULT_CREATION_FLAGS):
|
||||
return create_process(r"C:\Windows\syswow64\{0}".format(test_binary_name), dwCreationFlags=dwCreationFlags, show_windows=True)
|
||||
|
||||
if windows.current_process.bitness == 32:
|
||||
def pop_proc_64(dwCreationFlags=DEFAULT_CREATION_FLAGS):
|
||||
with DisableWow64FsRedirection():
|
||||
return create_process(r"C:\Windows\system32\{0}".format(test_binary_name), dwCreationFlags=dwCreationFlags, show_windows=True)
|
||||
else:
|
||||
def pop_proc_64(dwCreationFlags=DEFAULT_CREATION_FLAGS):
|
||||
return create_process(r"C:\Windows\system32\{0}".format(test_binary_name), dwCreationFlags=dwCreationFlags, show_windows=True)
|
||||
@@ -192,7 +192,6 @@ def pop_shell(locs=None):
|
||||
create_console()
|
||||
FixedInteractiveConsole(locs).interact()
|
||||
|
||||
|
||||
def get_kernel_modules():
|
||||
if windows.current_process.is_wow_64:
|
||||
return get_kernel_modules_syswow64()
|
||||
|
||||
Reference in New Issue
Block a user