mirror of
https://github.com/hakril/PythonForWindows
synced 2026-06-08 14:31:45 +00:00
More doc (registry / network)
This commit is contained in:
@@ -139,9 +139,6 @@ Another example from a project::
|
||||
out_ioctl += x86.Mov('EAX', 0x0C000000D)
|
||||
out_ioctl += x86.Ret()
|
||||
|
||||
.. note::
|
||||
|
||||
TODO: prefix
|
||||
|
||||
:mod:`windows.native_exec.simple_x64` -- X64 Assembler
|
||||
""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
Network
|
||||
=======
|
||||
|
||||
.. module:: windows.network
|
||||
|
||||
.. note::
|
||||
|
||||
See sample :ref:`sample_network_exploration`
|
||||
|
||||
|
||||
:class:`Network` class
|
||||
""""""""""""""""""""""
|
||||
|
||||
.. autoclass:: windows.network.Network
|
||||
|
||||
Connection classes
|
||||
""""""""""""""""""
|
||||
|
||||
.. autoclass:: windows.network.TCP4Connection
|
||||
|
||||
.. autoclass:: windows.network.TCP6Connection
|
||||
+11
-7
@@ -13,7 +13,7 @@ CurrentProcess
|
||||
.. autoclass:: CurrentProcess
|
||||
:members:
|
||||
:inherited-members:
|
||||
|
||||
|
||||
CurrentThread
|
||||
'''''''''''''
|
||||
|
||||
@@ -39,13 +39,13 @@ WinThread
|
||||
.. autoclass:: WinThread
|
||||
:members:
|
||||
:inherited-members:
|
||||
|
||||
|
||||
|
||||
.. autoclass:: DeadThread
|
||||
:members:
|
||||
:inherited-members:
|
||||
|
||||
|
||||
|
||||
|
||||
PEB Exploration
|
||||
"""""""""""""""
|
||||
|
||||
@@ -59,10 +59,14 @@ The :class:`PEB` is accessible via ``process.peb`` and is of type :class:`PEB`.
|
||||
.. autoclass:: PEB
|
||||
:members:
|
||||
:inherited-members:
|
||||
|
||||
|
||||
.. autoclass:: WinUnicodeString
|
||||
|
||||
.. autoclass:: LoadedModule
|
||||
|
||||
.. autoclass:: LoadedModule
|
||||
|
||||
|
||||
.. warning::
|
||||
|
||||
TODO: pe_parse.PEFile (sorry) but example at :ref:`sample_peb_exploration`
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
Registry
|
||||
""""""""
|
||||
========
|
||||
|
||||
.. module:: windows.registry
|
||||
|
||||
REGISTRY
|
||||
|
||||
.. class:: Registry
|
||||
.. autoclass:: Registry
|
||||
:special-members: __getitem__
|
||||
|
||||
.. autoclass:: PyHKey
|
||||
+37
-10
@@ -1,7 +1,7 @@
|
||||
Samples of code
|
||||
===============
|
||||
|
||||
.. _sample_current_process:
|
||||
.. _sample_current_process:
|
||||
|
||||
``windows.current_process``
|
||||
"""""""""""""""""""""""""""
|
||||
@@ -23,9 +23,9 @@ Output::
|
||||
Allocated memory is at <0x3f0000>
|
||||
Writing 'SOME STUFF' in allocation memory
|
||||
Reading memory : <'SOME STUFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'>
|
||||
|
||||
.. _sample_remote_process:
|
||||
|
||||
|
||||
.. _sample_remote_process:
|
||||
|
||||
Remote process : :class:`WinProcess`
|
||||
""""""""""""""""""""""""""""""""""""
|
||||
|
||||
@@ -61,12 +61,12 @@ Output::
|
||||
File "<string>", line 3, in <module>
|
||||
File "<string>", line 2, in func
|
||||
ImportError: No module named FAKE_MODULE
|
||||
|
||||
|
||||
That's all ! killing the calc
|
||||
|
||||
|
||||
.. _sample_peb_exploration:
|
||||
|
||||
|
||||
|
||||
.. _sample_peb_exploration:
|
||||
|
||||
:class:`PEB` exploration
|
||||
""""""""""""""""""""""""
|
||||
|
||||
@@ -96,4 +96,31 @@ Output::
|
||||
Here are some exports {0: 2001566688L, u'CreateFileA': 2001635616L, 42: 2001647872L, u'VirtualAlloc': 2001570704L}
|
||||
Import DLL dependancies are (without api-*): [u'ntdll.dll', u'kernelbase.dll']
|
||||
IAT Entry for ntdll!NtCreateFile = <IATEntry "NtCreateFile" ordinal 253> | addr = 0x77541128L
|
||||
Sections: [<PESection ".text">, <PESection ".rdata">, <PESection ".data">, <PESection ".rsrc">, <PESection ".reloc">]
|
||||
Sections: [<PESection ".text">, <PESection ".rdata">, <PESection ".data">, <PESection ".rsrc">, <PESection ".reloc">]
|
||||
|
||||
|
||||
.. _sample_network_exploration:
|
||||
|
||||
:class:`Network` - socket exploration
|
||||
"""""""""""""""""""""""""""""""""""""
|
||||
|
||||
.. literalinclude:: ..\..\samples\network.py
|
||||
|
||||
Output::
|
||||
|
||||
(cmd λ) python.exe network.py
|
||||
Working on ipv4
|
||||
== Listening ==
|
||||
Some listening connections: [<TCP IPV4 Listening socket on 0.0.0.0:80>, <TCP IPV4 Listening socket on 0.0.0.0:135>, <TCP IPV4 Listening socket on 0.0.0.0:443>]
|
||||
Listening ports are : [80, 135, 443, 445, 902, 912, 5357, 49152, 49153, 49154, 49155, 49157, 49159, 8307, 25340, 139, 139]
|
||||
== Established ==
|
||||
Some established connections: [<TCP IPV4 Connection 127.0.0.1:25340 -> 127.0.0.1:49472>, <TCP IPV4 Connection 127.0.0.1:49173 -> 127.0.0.1:49174>, <TCP IPV4 Connection 127.0.0.1:49174 -> 127.0.0.1:49173>]
|
||||
== connection to localhost:80 ==
|
||||
Our connection is [<TCP IPV4 Connection 127.0.0.1:49616 -> 127.0.0.1:80>]
|
||||
Sending YOP
|
||||
Closing socket
|
||||
Sending LAIT
|
||||
Traceback (most recent call last):
|
||||
File ".\network.py", line 45, in <module>
|
||||
s.send("LAIT")
|
||||
socket.error: [Errno 10054] An existing connection was forcibly closed by the remote host
|
||||
@@ -10,4 +10,5 @@ This sections describes them by group of relation.
|
||||
:maxdepth: 2
|
||||
|
||||
process.rst
|
||||
registry.rst
|
||||
registry.rst
|
||||
network.rst
|
||||
@@ -0,0 +1,42 @@
|
||||
import sys
|
||||
import os.path
|
||||
import socket
|
||||
|
||||
sys.path.append(os.path.abspath(__file__ + "\..\.."))
|
||||
|
||||
import windows
|
||||
|
||||
if not windows.utils.check_is_elevated():
|
||||
print("!!! Demo will fail because closing a connection require elevated process !!!")
|
||||
|
||||
print("Working on ipv4")
|
||||
|
||||
conns = windows.system.network.ipv4
|
||||
print("== Listening ==")
|
||||
|
||||
print("Some listening connections: {0}".format([c for c in conns if not c.established][:3]))
|
||||
print("Listening ports are : {0}".format([c.local_port for c in conns if not c.established]))
|
||||
|
||||
|
||||
print("== Established ==")
|
||||
|
||||
print("Some established connections: {0}".format([c for c in conns if c.established][:3]))
|
||||
|
||||
TARGET_HOST = "localhost"
|
||||
TARGET_PORT = 80
|
||||
|
||||
print("== connection to {0}:{1} ==".format(TARGET_HOST, TARGET_PORT))
|
||||
|
||||
s = socket.create_connection((TARGET_HOST, TARGET_PORT))
|
||||
|
||||
|
||||
our_connection = [c for c in windows.system.network.ipv4 if c.established and c.remote_port == TARGET_PORT and c.remote_addr == s.getpeername()[0]]
|
||||
|
||||
print("Our connection is {0}".format(our_connection))
|
||||
|
||||
print("Sending YOP")
|
||||
s.send("YOP")
|
||||
print("Closing socket")
|
||||
our_connection[0].close()
|
||||
print("Sending LAIT")
|
||||
s.send("LAIT")
|
||||
@@ -12,26 +12,44 @@ class TCP4Connection(MIB_TCPROW_OWNER_PID):
|
||||
|
||||
@property
|
||||
def established(self):
|
||||
"""``True`` if connection is established else it's a listening socket"""
|
||||
return self.dwState == MIB_TCP_STATE_ESTAB
|
||||
|
||||
@property
|
||||
def remote_port(self):
|
||||
""":type: :class:`int`"""
|
||||
if not self.established:
|
||||
return None
|
||||
return socket.ntohs(self.dwRemotePort)
|
||||
|
||||
@property
|
||||
def local_port(self):
|
||||
""":type: :class:`int`"""
|
||||
return socket.ntohs(self.dwLocalPort)
|
||||
|
||||
@property
|
||||
def local_addr(self):
|
||||
"""Local address IP (x.x.x.x)
|
||||
|
||||
:type: :class:`str`"""
|
||||
return socket.inet_ntoa(struct.pack("<I", self.dwLocalAddr))
|
||||
|
||||
@property
|
||||
def remote_addr(self):
|
||||
"""remote address IP (x.x.x.x)
|
||||
|
||||
:type: :class:`str`"""
|
||||
if not self.established:
|
||||
return None
|
||||
return socket.inet_ntoa(struct.pack("<I", self.dwRemoteAddr))
|
||||
|
||||
@property
|
||||
def remote_proto(self):
|
||||
"""Identification of the protocol associated with the remote port.
|
||||
Equals ``remote_port`` if no protocol is associated with it.
|
||||
|
||||
:type: :class:`str` or :class:`int`
|
||||
"""
|
||||
try:
|
||||
return socket.getservbyport(self.remote_port, 'tcp')
|
||||
except socket.error:
|
||||
@@ -39,12 +57,19 @@ class TCP4Connection(MIB_TCPROW_OWNER_PID):
|
||||
|
||||
@property
|
||||
def remote_host(self):
|
||||
"""Identification of the remote hostname.
|
||||
Equals ``remote_addr`` if resolution fail
|
||||
|
||||
:type: :class:`str` or :class:`int`
|
||||
"""
|
||||
|
||||
try:
|
||||
return socket.gethostbyaddr(self.remote_addr)
|
||||
except socket.error:
|
||||
return self.remote_addr
|
||||
|
||||
def close(self):
|
||||
"""Close the connection <require elevated process>"""
|
||||
closing = MIB_TCPROW()
|
||||
closing.dwState = MIB_TCP_STATE_DELETE_TCB
|
||||
closing.dwLocalAddr = self.dwLocalAddr
|
||||
@@ -66,30 +91,45 @@ class TCP6Connection(MIB_TCP6ROW_OWNER_PID):
|
||||
|
||||
@property
|
||||
def established(self):
|
||||
"""``True`` if connection is established else it's a listening socket"""
|
||||
return self.dwState == MIB_TCP_STATE_ESTAB
|
||||
|
||||
@property
|
||||
def remote_port(self):
|
||||
""":type: :class:`int`"""
|
||||
if not self.established:
|
||||
return None
|
||||
return socket.ntohs(self.dwRemotePort)
|
||||
|
||||
@property
|
||||
def local_port(self):
|
||||
""":type: :class:`int`"""
|
||||
return socket.ntohs(self.dwLocalPort)
|
||||
|
||||
@property
|
||||
def local_addr(self):
|
||||
"""Local address IP
|
||||
|
||||
:type: :class:`str`"""
|
||||
return self._str_ipv6_addr(self.ucLocalAddr)
|
||||
|
||||
@property
|
||||
def remote_addr(self):
|
||||
"""remote address IP
|
||||
|
||||
:type: :class:`str`"""
|
||||
if not self.established:
|
||||
return None
|
||||
return self._str_ipv6_addr(self.ucRemoteAddr)
|
||||
|
||||
@property
|
||||
def remote_proto(self):
|
||||
"""Equals to self.remote_port for Ipv6"""
|
||||
return self.remote_port
|
||||
|
||||
@property
|
||||
def remote_host(self):
|
||||
"""Equals to self.remote_addr for Ipv6"""
|
||||
return self.remote_addr
|
||||
|
||||
def close(self):
|
||||
@@ -157,4 +197,12 @@ class Network(object):
|
||||
|
||||
|
||||
ipv4 = property(lambda self: self._get_tcp_ipv4_sockets())
|
||||
"""List of TCP IPv4 socket (connection and listening)
|
||||
|
||||
:type: [:class:`TCP4Connection`]"""
|
||||
|
||||
ipv6 = property(lambda self: self._get_tcp_ipv6_sockets())
|
||||
"""List of TCP IPv6 socket (connection and listening)
|
||||
|
||||
:type: [:class:`TCP6Connection`]
|
||||
"""
|
||||
|
||||
@@ -17,6 +17,7 @@ class ExpectWindowsError(object):
|
||||
KeyValue = collections.namedtuple("KeyValue", ["name", "value", "type"])
|
||||
|
||||
class PyHKey(object):
|
||||
"""A windows registry key"""
|
||||
def __init__(self, surkey, name, sam=_winreg.KEY_READ):
|
||||
self.surkey = surkey
|
||||
self.name = name
|
||||
@@ -77,6 +78,7 @@ HKEY_USERS = PyHKey(DummyPHKEY(_winreg.HKEY_USERS, "HKEY_USERS"), "", _winreg.KE
|
||||
|
||||
|
||||
class Registry(object):
|
||||
"""The ``Windows`` registry: a read only mapping"""
|
||||
|
||||
registry_base_keys = {
|
||||
"HKEY_LOCAL_MACHINE" : HKEY_LOCAL_MACHINE,
|
||||
@@ -88,6 +90,14 @@ class Registry(object):
|
||||
}
|
||||
|
||||
def __getitem__(self, name):
|
||||
"""Get a registry key::
|
||||
|
||||
registry[r"HKEY_LOCAL_MACHINE\\Software"]
|
||||
registry["HKEY_LOCAL_MACHINE"]["Software"]
|
||||
|
||||
:rtype: :class:`PyHKey`
|
||||
"""
|
||||
|
||||
if name in self.registry_base_keys:
|
||||
return self.registry_base_keys[name]
|
||||
if "\\" not in name:
|
||||
|
||||
+17
-5
@@ -28,16 +28,19 @@ class Kernel32Error(WindowsError):
|
||||
|
||||
class IphlpapiError(Kernel32Error):
|
||||
|
||||
def __new__(cls, func_name, code):
|
||||
def __new__(cls, func_name, code, strerror=None):
|
||||
win_error = ctypes.WinError(code)
|
||||
api_error = super(Kernel32Error, cls).__new__(cls)
|
||||
api_error.api_name = func_name
|
||||
api_error.winerror = win_error.winerror
|
||||
api_error.strerror = win_error.strerror
|
||||
api_error.args = (func_name, win_error.winerror, win_error.strerror)
|
||||
if strerror is not None:
|
||||
api_error.strerror = strerror
|
||||
else:
|
||||
api_error.strerror = win_error.strerror
|
||||
api_error.args = (func_name, api_error.winerror, api_error.strerror)
|
||||
return api_error
|
||||
|
||||
def __init__(self, func_name, code):
|
||||
def __init__(self, func_name, code, strerror=None):
|
||||
pass
|
||||
|
||||
|
||||
@@ -580,7 +583,16 @@ def RegCloseKey(hKey):
|
||||
|
||||
|
||||
# ##### Iphlpapi (network list and stuff) ###### #
|
||||
SetTcpEntry = TransparentIphlpapiProxy('SetTcpEntry')
|
||||
|
||||
def set_tcp_entry_error_check(func_name, result, func, args):
|
||||
"""raise IphlpapiError if result is NOT 0 -- pretty print error 317"""
|
||||
if result:
|
||||
if result == 317:
|
||||
raise IphlpapiError(func_name, result, "<require elevated process>".format(func_name))
|
||||
raise IphlpapiError(func_name, result)
|
||||
return args
|
||||
|
||||
SetTcpEntry = TransparentIphlpapiProxy('SetTcpEntry', error_check=set_tcp_entry_error_check)
|
||||
|
||||
|
||||
@OptionalExport(IphlpapiProxy('GetExtendedTcpTable'))
|
||||
|
||||
Reference in New Issue
Block a user