mirror of
https://github.com/hakril/PythonForWindows
synced 2026-06-08 14:31:45 +00:00
writing some doc
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
TODO:
|
||||
- Documentation
|
||||
- Pass 0.2 when doc is done <3
|
||||
- type pass to dbg callback
|
||||
|
||||
- ProcessMemory object ? (metasm like)
|
||||
|
||||
- remove pe_parse.transform_ctypes_fields (use utils.transform_ctypes_fields)
|
||||
@@ -40,16 +42,14 @@ TODO:
|
||||
CHANGELOG:
|
||||
* NEW REGISTRY -> change examples and documentation
|
||||
* WinProcess is not a PROCESSENTRY32 anymore (change doc)
|
||||
* re-check every sample
|
||||
|
||||
Documentation
|
||||
* Debugger
|
||||
* LocalDebugger
|
||||
* volumes
|
||||
* system.version stuff
|
||||
* windows.com
|
||||
* windows.wintrust
|
||||
* New stuff in exception ?
|
||||
* system.firewall.network
|
||||
* system.services
|
||||
* New stuff in WMI ?(think not just change in internal)
|
||||
* windows.utils
|
||||
|
||||
@@ -17,6 +17,7 @@ Contents:
|
||||
native_exec.rst
|
||||
winproxy.rst
|
||||
utils.rst
|
||||
wintrust.rst
|
||||
debug.rst
|
||||
iat_hook.rst
|
||||
wip.rst
|
||||
|
||||
@@ -19,10 +19,18 @@ PyHKey
|
||||
|
||||
.. autoclass:: PyHKey
|
||||
|
||||
.. function:: __getitem__(name)
|
||||
.. function:: __call__(name)
|
||||
|
||||
Alias for :func:`open_subkey`
|
||||
|
||||
.. function:: __getitem__(name)
|
||||
|
||||
Alias for :func:`get`
|
||||
|
||||
.. function:: __setitem__(name)
|
||||
|
||||
Wrapper for :func:`set`, accept ``value`` or ``(value, type)``
|
||||
|
||||
KeyValue
|
||||
""""""""
|
||||
|
||||
|
||||
@@ -99,6 +99,49 @@ Output::
|
||||
Sections: [<PESection ".text">, <PESection ".rdata">, <PESection ".data">, <PESection ".rsrc">, <PESection ".reloc">]
|
||||
|
||||
|
||||
|
||||
.. _sample_system:
|
||||
|
||||
|
||||
``windows.system``
|
||||
""""""""""""""""""
|
||||
|
||||
.. literalinclude:: ..\..\samples\system.py
|
||||
|
||||
Output::
|
||||
|
||||
(cmd λ) python system.py
|
||||
Basic system infos:
|
||||
version = (6, 3)
|
||||
bitness = 64
|
||||
computer_name = HAKRIL-PC
|
||||
product_type = VER_NT_WORKSTATION(0x1L)
|
||||
version_name = Windows 8.1
|
||||
|
||||
There is 95 processes
|
||||
There is 1021 threads
|
||||
|
||||
Dumping first logical drive:
|
||||
<LogicalDrive "C:\" (DRIVE_FIXED)>
|
||||
name = C:\
|
||||
type = DRIVE_FIXED(0x3L)
|
||||
path = \Device\HarddiskVolume2
|
||||
|
||||
Dumping first service:
|
||||
<ServiceA "ACPI">
|
||||
name = ACPI
|
||||
description = Microsoft ACPI Driver
|
||||
status = ServiceStatus(type=SERVICE_KERNEL_DRIVER(0x1L), state=SERVICE_RUNNING(0x4L), control_accepted=1L, flags=0L)
|
||||
process = None
|
||||
|
||||
Finding a service in a user process:
|
||||
<ServiceA "Appinfo">
|
||||
name = Appinfo
|
||||
description = Application Information
|
||||
status = ServiceStatus(type=SERVICE_WIN32_SHARE_PROCESS(0x20L), state=SERVICE_RUNNING(0x4L), control_accepted=129L, flags=0L)
|
||||
process = <WinProcess "svchost.exe" pid 944 at 0x29d5290>
|
||||
|
||||
|
||||
.. _sample_iat_hook:
|
||||
|
||||
IAT hooking
|
||||
@@ -190,6 +233,31 @@ Output::
|
||||
registered owner = <KeyValue(name='RegisteredOwner', value=u'hakril', type=1)>
|
||||
|
||||
|
||||
.. _sample_wintrust:
|
||||
|
||||
``windows.wintrust``
|
||||
""""""""""""""""""""
|
||||
|
||||
.. literalinclude:: ..\..\samples\wintrust.py
|
||||
|
||||
Output::
|
||||
|
||||
(cmd λ) python .\wintrust.py
|
||||
Checking signature of <C:\windows\system32\ntdll.dll>
|
||||
is_signed: <True>
|
||||
check_signature: <0>
|
||||
full_signature_information:
|
||||
* signed <True>
|
||||
* catalog <C:\Windows\system32\CatRoot\{F750E6C3-38EE-11D1-85E5-00C04FC295EE}\Package_35_for_KB3128650~31bf3856ad364e35~amd64~~6.3.1.2.cat>
|
||||
* catalogsigned <True>
|
||||
* additionalinfo <0>
|
||||
Checking signature of some loaded DLL
|
||||
<c:\python27\python.exe> : False (TRUST_E_NOSIGNATURE(0x800b0100L))
|
||||
<c:\windows\system32\ntdll.dll> : True
|
||||
<c:\windows\system32\kernel32.dll> : True
|
||||
<c:\windows\system32\kernelbase.dll> : True
|
||||
<c:\windows\system32\python27.dll> : False (TRUST_E_NOSIGNATURE(0x800b0100L))
|
||||
|
||||
.. _sample_vectoredexception:
|
||||
|
||||
:func:`VectoredException`
|
||||
|
||||
+11
-1
@@ -1,2 +1,12 @@
|
||||
Volume -- The logical drives
|
||||
============================
|
||||
============================
|
||||
|
||||
.. module:: windows.winobject.volume
|
||||
|
||||
.. autoclass:: LogicalDrive
|
||||
|
||||
.. data:: name
|
||||
|
||||
Name of the logical drive
|
||||
|
||||
:type: :class:`str`
|
||||
@@ -0,0 +1,40 @@
|
||||
``windows.wintrust`` -- Checking signature
|
||||
******************************************
|
||||
|
||||
.. module:: windows.wintrust
|
||||
|
||||
.. note::
|
||||
|
||||
See sample :ref:`sample_wintrust`
|
||||
|
||||
The :mod:`wintrust` module offers wrapper around ``wintrust.dll``.
|
||||
It allows to check the signature of a file.
|
||||
|
||||
The signature of a file can be at two differents place:
|
||||
|
||||
* In the file itself (:func:`check_signature`)
|
||||
* In a catalog file (:func:`full_signature_information`)
|
||||
|
||||
.. note::
|
||||
|
||||
`Explanation about catalog files <https://msdn.microsoft.com/en-us/library/windows/hardware/ff537872(v=vs.85).aspx>`_
|
||||
|
||||
|
||||
API
|
||||
"""
|
||||
|
||||
.. autofunction:: is_signed
|
||||
|
||||
.. autofunction:: full_signature_information
|
||||
|
||||
.. autofunction:: check_signature
|
||||
|
||||
|
||||
SignatureData
|
||||
'''''''''''''
|
||||
|
||||
.. autoclass:: SignatureData
|
||||
:exclude-members: count, index
|
||||
|
||||
|
||||
|
||||
@@ -3,10 +3,8 @@ WMI -- Make request to WMI
|
||||
|
||||
.. module:: windows.winobject.wmi
|
||||
|
||||
|
||||
.. note::
|
||||
|
||||
See sample :ref:`wmi_request`
|
||||
|
||||
|
||||
.. autoclass:: WmiRequester
|
||||
@@ -20,6 +20,7 @@ class YoloDebugger(windows.debug.LocalDebugger):
|
||||
if self.single_step_count:
|
||||
self.single_step_count -= 1
|
||||
return self.single_step()
|
||||
return EXCEPTION_CONTINUE_EXECUTION
|
||||
|
||||
|
||||
class YoloHXBP(windows.debug.HXBreakpoint):
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
import sys
|
||||
import os.path
|
||||
sys.path.append(os.path.abspath(__file__ + "\..\.."))
|
||||
|
||||
import windows
|
||||
system = windows.system
|
||||
|
||||
print("Basic system infos:")
|
||||
print(" version = {0}".format(system.version))
|
||||
print(" bitness = {0}".format(system.bitness))
|
||||
print(" computer_name = {0}".format(system.computer_name))
|
||||
print(" product_type = {0}".format(system.product_type))
|
||||
print(" version_name = {0}".format(system.version_name))
|
||||
print("")
|
||||
print("There is {0} processes".format(len(system.processes)))
|
||||
print("There is {0} threads".format(len(system.threads)))
|
||||
print("")
|
||||
print("Dumping first logical drive:")
|
||||
drive = system.logicaldrives[0]
|
||||
print(" " + str(drive))
|
||||
print((" " * 8) + "name = {0}".format(drive.name))
|
||||
print((" " * 8) + "type = {0}".format(drive.type))
|
||||
print((" " * 8) + "path = {0}".format(drive.path))
|
||||
print("")
|
||||
|
||||
print("Dumping first service:")
|
||||
serv = windows.system.services[0]
|
||||
print(" " + str(serv))
|
||||
print((" " * 8) + "name = {0}".format(serv.name))
|
||||
print((" " * 8) + "description = {0}".format(serv.description))
|
||||
print((" " * 8) + "status = {0}".format(serv.status))
|
||||
print((" " * 8) + "process = {0}".format(repr(serv.process)))
|
||||
print("")
|
||||
|
||||
print("Finding a service in a user process:")
|
||||
serv = [s for s in windows.system.services if s.process][0]
|
||||
print(" " + str(serv))
|
||||
print((" " * 8) + "name = {0}".format(serv.name))
|
||||
print((" " * 8) + "description = {0}".format(serv.description))
|
||||
print((" " * 8) + "status = {0}".format(serv.status))
|
||||
print((" " * 8) + "process = {0}".format(repr(serv.process)))
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import ctypes
|
||||
import windows
|
||||
from windows.exception import VectoredException
|
||||
from windows.winobject.exception import VectoredException
|
||||
import windows.generated_def.windef as windef
|
||||
from windows.generated_def.winstructs import *
|
||||
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
import sys
|
||||
import os.path
|
||||
sys.path.append(os.path.abspath(__file__ + "\..\.."))
|
||||
|
||||
import windows.wintrust
|
||||
|
||||
TARGET_FILE = r"C:\windows\system32\ntdll.dll"
|
||||
print("Checking signature of <{0}>".format(TARGET_FILE))
|
||||
print(" is_signed: <{0}>".format(windows.wintrust.is_signed(TARGET_FILE)))
|
||||
print(" check_signature: <{0}>".format(windows.wintrust.check_signature(TARGET_FILE)))
|
||||
|
||||
sign_info = windows.wintrust.full_signature_information(TARGET_FILE)
|
||||
print(" full_signature_information:")
|
||||
print(" * signed <{0}>".format(sign_info.signed))
|
||||
print(" * catalog <{0}>".format(sign_info.catalog))
|
||||
print(" * catalogsigned <{0}>".format(sign_info.catalogsigned))
|
||||
print(" * additionalinfo <{0}>".format(sign_info.additionalinfo))
|
||||
|
||||
print("Checking signature of some loaded DLL")
|
||||
for module in windows.current_process.peb.modules[:5]:
|
||||
path = module.fullname
|
||||
is_signed = windows.wintrust.is_signed(path)
|
||||
if is_signed:
|
||||
print("<{0}> : {1}".format(path, is_signed))
|
||||
else:
|
||||
sign_info = windows.wintrust.full_signature_information(path)
|
||||
print("<{0}> : {1} ({2})".format(path, is_signed, sign_info[3]))
|
||||
|
||||
|
||||
@@ -93,6 +93,7 @@ class PyHKey(object):
|
||||
|
||||
|
||||
def set(self, name, value, type=None):
|
||||
"""Set the value for ``name`` to ``value``. if ``type`` is None try to guess items"""
|
||||
if type is None:
|
||||
type = self._guess_value_type(value)
|
||||
return _winreg.SetValueEx(self.phkey, name, 0, type, value)
|
||||
|
||||
@@ -20,7 +20,7 @@ from windows.winobject import kernobj
|
||||
from windows.generated_def.winstructs import *
|
||||
|
||||
class System(object):
|
||||
"""Represent the current ``Windows`` system ``Python`` is running on"""
|
||||
"""The state of the current ``Windows`` system ``Python`` is running on"""
|
||||
|
||||
network = network.Network()
|
||||
"""Object of class :class:`windows.winobject.network.Network`"""
|
||||
|
||||
@@ -16,12 +16,31 @@ class LogicalDrive(object):
|
||||
|
||||
@property
|
||||
def type(self):
|
||||
"""The type of drive, values are:
|
||||
|
||||
* DRIVE_UNKNOWN(0x0L)
|
||||
* DRIVE_NO_ROOT_DIR(0x1L)
|
||||
* DRIVE_REMOVABLE(0x2L)
|
||||
* DRIVE_FIXED(0x3L)
|
||||
* DRIVE_REMOTE(0x4L)
|
||||
* DRIVE_CDROM(0x5L)
|
||||
* DRIVE_RAMDISK(0x6L)
|
||||
|
||||
:type: :class:`long` or :class:`int` (or subclass)
|
||||
"""
|
||||
t = winproxy.GetDriveTypeA(self.name)
|
||||
return self.DRIVE_TYPE.get(t,t)
|
||||
|
||||
@property
|
||||
def path(self):
|
||||
return query_dos_device(self.name.strip("\\"))
|
||||
"""The target path of the device
|
||||
|
||||
:type: :class:`str`"""
|
||||
res = query_dos_device(self.name.strip("\\"))
|
||||
if len(res) != 1:
|
||||
raise ValueError("[Unexpected result] query_dos_device(logicaldrive) returned multiple path")
|
||||
return res[0]
|
||||
|
||||
|
||||
def __repr__(self):
|
||||
return """<{0} "{1}" ({2})>""".format(type(self).__name__, self.name, self.type.name)
|
||||
|
||||
+32
-2
@@ -79,9 +79,9 @@ wintrust_return_value_mapper = {x:x for x in wintrust_know_return_value}
|
||||
|
||||
|
||||
def check_signature(filename):
|
||||
"""Check if ``filename`` is a valid signed file
|
||||
"""Check if ``filename`` embeds a valid signature.
|
||||
|
||||
:return: 0 if file have a valid signature
|
||||
:return: ``0`` if ``filename`` have a valid signature else the error
|
||||
"""
|
||||
file_data = WINTRUST_FILE_INFO()
|
||||
file_data.cbStruct = ctypes.sizeof(WINTRUST_FILE_INFO)
|
||||
@@ -155,8 +155,21 @@ def get_catalog_name_from_handle(handle):
|
||||
return cat_info.wszCatalogFile
|
||||
|
||||
SignatureData = namedtuple("SignatureData", ["signed", "catalog", "catalogsigned", "additionalinfo"])
|
||||
"""Signature information for ``FILENAME``:
|
||||
|
||||
* ``signed``: True if ``FILENAME`` embeds a valide signature
|
||||
* ``catalog``: The filename of the catalog ``FILENAME`` is part of (if any)
|
||||
* ``catalogsigned``: True if ``catalog`` embeds a valide signature
|
||||
* ``additionalinfo``: The return error of ``check_signature(FILENAME)``
|
||||
|
||||
``additionalinfo`` is useful to know if ``FILENAME`` signature was rejected for an invalid root / expired cert.
|
||||
"""
|
||||
|
||||
def full_signature_information(filename):
|
||||
"""Returns more information about the signature of ``filename``
|
||||
|
||||
:return: :class:`SignatureData`
|
||||
"""
|
||||
check_sign = check_signature(filename)
|
||||
signed = not bool(check_sign)
|
||||
catalog = get_catalog_for_filename(filename)
|
||||
@@ -164,3 +177,20 @@ def full_signature_information(filename):
|
||||
return SignatureData(signed, None, False, check_sign)
|
||||
catalogsigned = not bool(check_signature(catalog))
|
||||
return SignatureData(signed, catalog, catalogsigned, check_sign)
|
||||
|
||||
def is_signed(filename):
|
||||
"""Check if ``filename`` is signed:
|
||||
|
||||
* File embeds a valid signature
|
||||
* File is part of a signed catalog file
|
||||
|
||||
:return: :class:`bool`
|
||||
"""
|
||||
check_sign = check_signature(filename)
|
||||
if check_sign == 0:
|
||||
return True
|
||||
catalog = get_catalog_for_filename(filename)
|
||||
if catalog is None:
|
||||
return False
|
||||
catalogsigned = not bool(check_signature(catalog))
|
||||
return catalogsigned
|
||||
|
||||
Reference in New Issue
Block a user