writing some doc

This commit is contained in:
Clement Rouault
2016-04-18 23:09:26 +02:00
parent 4ab9e97667
commit 5b66242680
15 changed files with 258 additions and 12 deletions
+3 -3
View File
@@ -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
+1
View File
@@ -17,6 +17,7 @@ Contents:
native_exec.rst
winproxy.rst
utils.rst
wintrust.rst
debug.rst
iat_hook.rst
wip.rst
+9 -1
View File
@@ -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
""""""""
+68
View File
@@ -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
View File
@@ -1,2 +1,12 @@
Volume -- The logical drives
============================
============================
.. module:: windows.winobject.volume
.. autoclass:: LogicalDrive
.. data:: name
Name of the logical drive
:type: :class:`str`
+40
View File
@@ -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
-2
View File
@@ -3,10 +3,8 @@ WMI -- Make request to WMI
.. module:: windows.winobject.wmi
.. note::
See sample :ref:`wmi_request`
.. autoclass:: WmiRequester
+1
View File
@@ -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):
+41
View File
@@ -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
View File
@@ -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 *
+29
View File
@@ -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]))
+1
View File
@@ -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)
+1 -1
View File
@@ -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`"""
+20 -1
View File
@@ -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
View File
@@ -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