mirror of
https://github.com/hakril/PythonForWindows
synced 2026-06-08 14:31:45 +00:00
Compare commits
81 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| dfdeb82682 | |||
| feeb2e406e | |||
| 3243f6e8fc | |||
| c2c3fe2dc2 | |||
| a988ad03e3 | |||
| 57634f076c | |||
| 085c36c706 | |||
| 09e9b7efbb | |||
| 5b66242680 | |||
| 4ab9e97667 | |||
| cb3c0f20c0 | |||
| b621e6a09f | |||
| 3454801ad0 | |||
| e781e3493f | |||
| 85cb4eef1b | |||
| 18bba9b24e | |||
| ef9b2486ec | |||
| b698b27a6f | |||
| 0e9ec9ed82 | |||
| 6c1b4cf5e6 | |||
| 96c8d68297 | |||
| 53e131831d | |||
| 4c1192bf75 | |||
| da52b1a014 | |||
| cf8386400f | |||
| ff5ce9ae86 | |||
| 480cbcf1dc | |||
| cbd4f0b6b7 | |||
| 9856a1614b | |||
| eadc0c6963 | |||
| 374e842d3d | |||
| 1a85d99b0e | |||
| d794ac8ceb | |||
| 641790f917 | |||
| 1b33bbb025 | |||
| 34ae5084cd | |||
| 3cb8cc6f9e | |||
| c24816f51f | |||
| d096da3709 | |||
| 9cae319c11 | |||
| f06afc9b79 | |||
| db4c51dc67 | |||
| 1422db08ae | |||
| 16ef768f3f | |||
| fb0171b8b9 | |||
| 8628ff5595 | |||
| 5f1c841b75 | |||
| 6a305458d5 | |||
| faa0acd030 | |||
| 78f9733295 | |||
| a4090ea215 | |||
| 9db75b0226 | |||
| 5ffa21cd8a | |||
| 9a1088daab | |||
| f9ce637ffa | |||
| c5e021f10d | |||
| c40cb0c8b0 | |||
| b789a12040 | |||
| 401db9c347 | |||
| 6cf4a9cae4 | |||
| 9fbba331ca | |||
| 3f06e95617 | |||
| 0da86e20aa | |||
| d720170781 | |||
| 5b5db57e17 | |||
| 7be3561ccf | |||
| ee62d6a972 | |||
| f307f8202a | |||
| 38a2298dee | |||
| ec4862439f | |||
| 6d8796f3ed | |||
| 588a1e0461 | |||
| 010453e96d | |||
| 7c35615319 | |||
| cf89d25486 | |||
| 99788d0368 | |||
| f6f206b842 | |||
| 6b75fe3185 | |||
| f43f7c4838 | |||
| fad8121cbf | |||
| c35e517b35 |
@@ -31,6 +31,37 @@ All those operations are also available for the `current_process`.
|
||||
|
||||
You can also make some operation on threads (suspend/resume/wait/get(or set) context/ kill)
|
||||
|
||||
```python
|
||||
>>> import windows
|
||||
>>> windows.current_process.bitness
|
||||
32
|
||||
>>> calc = [p for p in windows.system.processes if p.name == "calc.exe"][0]
|
||||
>>> calc
|
||||
<WinProcess "calc.exe" pid 6960 at 0x37391f0>
|
||||
>>> calc.bitness
|
||||
64
|
||||
>>> calc.peb.modules[:3]
|
||||
[<RemoteLoadedModule64 "calc.exe" at 0x3671e90>, <RemoteLoadedModule64 "ntdll.dll" at 0x3671030>, <RemoteLoadedModule64 "kernel32.dll" at 0x3671080>]
|
||||
>>> k32 = calc.peb.modules[2]
|
||||
>>> hex(k32.pe.exports["CreateFileW"])
|
||||
'0x7ffee6761550L'
|
||||
>>> calc.threads[0]
|
||||
<WinThread 3932 owner "calc.exe" at 0x3646350>
|
||||
>>> hex(calc.threads[0].context.Rip)
|
||||
'0x7ffee68b54b0L'
|
||||
>>> calc.execute_python("import os")
|
||||
True
|
||||
>>> calc.execute_python("exit(os.getpid() + 1)")
|
||||
# execute_python raise if process died
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValueError: Unknown exit code 0xc000004bL
|
||||
>>> calc
|
||||
<WinProcess "calc.exe" pid 6960 (DEAD) at 0x37391f0>
|
||||
>>> calc.exit_code
|
||||
6961L
|
||||
```
|
||||
|
||||
|
||||
### IAT Hook
|
||||
|
||||
@@ -50,14 +81,59 @@ To make the barrier between `native` and `Python` code,
|
||||
PythonForWindows allows you to create native function callable from Python (thanks `ctypes`) and also embed
|
||||
a simple x86/x64 assembler.
|
||||
|
||||
```python
|
||||
>>> import windows.native_exec.simple_x86 as x86
|
||||
>>> code = x86.MultipleInstr()
|
||||
>>> code += x86.Mov("EAX", 41)
|
||||
>>> code += x86.Inc("EAX")
|
||||
>>> code += x86.Ret()
|
||||
>>> code.get_code()
|
||||
'\xc7\xc0)\x00\x00\x00@\xc3'
|
||||
# Create a function that takes no parameters and return an uint
|
||||
>>> f = windows.native_exec.create_function(code.get_code(), [ctypes.c_uint])
|
||||
>>> f()
|
||||
42L
|
||||
```
|
||||
|
||||
## Other stuff
|
||||
### Wintrust
|
||||
|
||||
Some code are just explorations and need improvements like:
|
||||
To easily script some signature check script, PythonForWindows implements some wrapper functions around ``wintrust.dll``
|
||||
|
||||
- Wintrust
|
||||
- WMI
|
||||
- Exception
|
||||
```python
|
||||
>>> import windows.wintrust
|
||||
>>> windows.wintrust.is_signed(r"C:\Windows\system32\ntdll.dll")
|
||||
True
|
||||
>>> windows.wintrust.is_signed(r"C:\Windows\system32\python27.dll")
|
||||
False
|
||||
>>> windows.wintrust.full_signature_information(r"C:\Windows\system32\ntdll.dll")
|
||||
SignatureData(signed=True,
|
||||
catalog=u'C:\\Windows\\system32\\CatRoot\\{F750E6C3-38EE-11D1-85E5-00C04FC295EE}\\Package_35_for_KB3128650~31bf3856ad364e35~amd64~~6.3.1.2.cat',
|
||||
catalogsigned=True, additionalinfo=0L)
|
||||
>>> windows.wintrust.full_signature_information(r"C:\Windows\system32\python27.dll")
|
||||
SignatureData(signed=False, catalog=None, catalogsigned=False, additionalinfo=TRUST_E_NOSIGNATURE(0x800b0100L))
|
||||
```
|
||||
|
||||
### WMI
|
||||
|
||||
To extract/play with even more information about the system, PythonForWindows is able to perform WMI request.
|
||||
|
||||
```python
|
||||
>>> import windows
|
||||
>>> windows.system.wmi.select
|
||||
<bound method WmiRequester.select of <windows.winobject.wmi.WmiRequester object at 0x036BA590>>
|
||||
>>> windows.system.wmi.select("Win32_Process", ["Name", "Handle"])[:4]
|
||||
[{'Handle': u'0', 'Name': u'System Idle Process'}, {'Handle': u'4', 'Name': u'System'}, {'Handle': u'412', 'Name': u'smss.exe'}, {'Handle': u'528', 'Name': u'csrss.exe'}]
|
||||
# Get WMI data for current process
|
||||
>>> wmi_cp = [p for p in windows.system.wmi.select("Win32_Process") if int(p["Handle"]) == windows.current_process.pid][0]
|
||||
>>> wmi_cp["CommandLine"], wmi_cp["HandleCount"]
|
||||
(u'"C:\\Python27\\python.exe"', 227)
|
||||
```
|
||||
|
||||
### Other stuff (see doc / samples)
|
||||
|
||||
- Registry
|
||||
- Network
|
||||
- Services
|
||||
- COM
|
||||
|
||||
|
||||
|
||||
@@ -1,13 +1,55 @@
|
||||
TODO:
|
||||
- Documentation
|
||||
- Pass 0.2 when doc is done <3
|
||||
|
||||
- ProcessMemory object ? (metasm like)
|
||||
- Extend Registry feature (write)
|
||||
|
||||
- remove pe_parse.transform_ctypes_fields (use utils.transform_ctypes_fields)
|
||||
- DBG
|
||||
- Verif multiple bp at same place..
|
||||
- Verif multiple pending at same place
|
||||
- Test !! (bp, BP_HX, bp on only on process, bp_hx on only one thread..)
|
||||
- test breakpoint with specific target
|
||||
|
||||
- Threading
|
||||
- Quid IAT hook stub ? just einit threads and remove this ?
|
||||
|
||||
- Injection
|
||||
- code generated by generate_python_exec_shellcode_64[32] may be reused
|
||||
Just need to pass the address of the python string as argument
|
||||
|
||||
- rewrite generate_stub_64[32] : it's a non-sens to not save stuff on the stack..
|
||||
I can re-copy the args on stack..
|
||||
|
||||
- Winproxy:
|
||||
- rethink OptionalExport ? not useful with lazy resolution (or we need to force resolution..)
|
||||
|
||||
- Readme
|
||||
- Debugger ? Veh ?
|
||||
|
||||
- TransparentApiProxy
|
||||
double name (params and args) for same info..
|
||||
|
||||
- 32 <-> 64
|
||||
* What about ``NtWow64QueryVirtualMemory64`` ?
|
||||
|
||||
- Parse .IDL file for more COM NAME->IID
|
||||
|
||||
- Add test for debugger with breakpoint that add another breakpoint on trigger
|
||||
|
||||
- NtQueryVirtualMemory_32_to_64 (stop using hardcoded value for request type: add it to enum)
|
||||
|
||||
|
||||
CHANGELOG:
|
||||
* re-check every sample
|
||||
|
||||
Documentation
|
||||
* verif samples
|
||||
|
||||
FIXME:
|
||||
- WMI
|
||||
- COM initialisation when injected in another process
|
||||
- The CoInitialize might be already called
|
||||
- Fix that
|
||||
- setup.py build seems to raise an error
|
||||
- winutils.create_process : use WinProcess._from_handle
|
||||
- Push("[ECX]") in simple_x64 as a "H" rex and i think it should not..
|
||||
|
||||
- Add INVALID_HANDLE_VALUE to windef
|
||||
- change error_check of CreateFile(A|W)
|
||||
RESSOURCE
|
||||
* read http://www.codeproject.com/Articles/18975/Listing-Used-Files
|
||||
@@ -0,0 +1,47 @@
|
||||
typedef struct IDispatchVtbl
|
||||
{
|
||||
BEGIN_INTERFACE
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
|
||||
__RPC__in IDispatch * This,
|
||||
/* [in] */ __RPC__in REFIID riid,
|
||||
/* [annotation][iid_is][out] */
|
||||
__RPC__deref_out void **ppvObject);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE *AddRef )(
|
||||
__RPC__in IDispatch * This);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE *Release )(
|
||||
__RPC__in IDispatch * This);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetTypeInfoCount )(
|
||||
__RPC__in IDispatch * This,
|
||||
/* [out] */ __RPC__out UINT *pctinfo);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetTypeInfo )(
|
||||
__RPC__in IDispatch * This,
|
||||
/* [in] */ UINT iTInfo,
|
||||
/* [in] */ LCID lcid,
|
||||
/* [out] */ __RPC__deref_out_opt ITypeInfo **ppTInfo);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetIDsOfNames )(
|
||||
__RPC__in IDispatch * This,
|
||||
/* [in] */ __RPC__in REFIID riid,
|
||||
/* [size_is][in] */ __RPC__in_ecount_full(cNames) LPOLESTR *rgszNames,
|
||||
/* [range][in] */ __RPC__in_range(0,16384) UINT cNames,
|
||||
/* [in] */ LCID lcid,
|
||||
/* [size_is][out] */ __RPC__out_ecount_full(cNames) DISPID *rgDispId);
|
||||
|
||||
/* [local] */ HRESULT ( STDMETHODCALLTYPE *Invoke )(
|
||||
IDispatch * This,
|
||||
/* [in] */ DISPID dispIdMember,
|
||||
/* [in] */ REFIID riid,
|
||||
/* [in] */ LCID lcid,
|
||||
/* [in] */ WORD wFlags,
|
||||
/* [out][in] */ DISPPARAMS *pDispParams,
|
||||
/* [out] */ VARIANT *pVarResult,
|
||||
/* [out] */ EXCEPINFO *pExcepInfo,
|
||||
/* [out] */ UINT *puArgErr);
|
||||
|
||||
END_INTERFACE
|
||||
} IDispatchVtbl;
|
||||
@@ -0,0 +1,35 @@
|
||||
typedef struct IEnumVARIANTVtbl
|
||||
{
|
||||
BEGIN_INTERFACE
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
|
||||
__RPC__in IEnumVARIANT * This,
|
||||
/* [in] */ __RPC__in REFIID riid,
|
||||
/* [annotation][iid_is][out] */
|
||||
__RPC__deref_out void **ppvObject);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE *AddRef )(
|
||||
__RPC__in IEnumVARIANT * This);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE *Release )(
|
||||
__RPC__in IEnumVARIANT * This);
|
||||
|
||||
/* [local] */ HRESULT ( STDMETHODCALLTYPE *Next )(
|
||||
IEnumVARIANT * This,
|
||||
/* [in] */ ULONG celt,
|
||||
/* [length_is][size_is][out] */ VARIANT *rgVar,
|
||||
/* [out] */ ULONG *pCeltFetched);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *Skip )(
|
||||
__RPC__in IEnumVARIANT * This,
|
||||
/* [in] */ ULONG celt);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *Reset )(
|
||||
__RPC__in IEnumVARIANT * This);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *Clone )(
|
||||
__RPC__in IEnumVARIANT * This,
|
||||
/* [out] */ __RPC__deref_out_opt IEnumVARIANT **ppEnum);
|
||||
|
||||
END_INTERFACE
|
||||
} IEnumVARIANTVtbl;
|
||||
@@ -0,0 +1,42 @@
|
||||
typedef struct IEnumWbemClassObjectVtbl
|
||||
{
|
||||
BEGIN_INTERFACE
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
|
||||
__RPC__in IEnumWbemClassObject * This,
|
||||
/* [in] */ __RPC__in REFIID riid,
|
||||
/* [annotation][iid_is][out] */
|
||||
__RPC__deref_out void **ppvObject);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE *AddRef )(
|
||||
__RPC__in IEnumWbemClassObject * This);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE *Release )(
|
||||
__RPC__in IEnumWbemClassObject * This);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *Reset )(
|
||||
__RPC__in IEnumWbemClassObject * This);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *Next )(
|
||||
__RPC__in IEnumWbemClassObject * This,
|
||||
/* [in] */ long lTimeout,
|
||||
/* [in] */ ULONG uCount,
|
||||
/* [length_is][size_is][out] */ __RPC__out_ecount_part(uCount, *puReturned) IWbemClassObject **apObjects,
|
||||
/* [out] */ __RPC__out ULONG *puReturned);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *NextAsync )(
|
||||
__RPC__in IEnumWbemClassObject * This,
|
||||
/* [in] */ ULONG uCount,
|
||||
/* [in] */ __RPC__in_opt IWbemObjectSink *pSink);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *Clone )(
|
||||
__RPC__in IEnumWbemClassObject * This,
|
||||
/* [out] */ __RPC__deref_out_opt IEnumWbemClassObject **ppEnum);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *Skip )(
|
||||
__RPC__in IEnumWbemClassObject * This,
|
||||
/* [in] */ long lTimeout,
|
||||
/* [in] */ ULONG nCount);
|
||||
|
||||
END_INTERFACE
|
||||
} IEnumWbemClassObjectVtbl;
|
||||
@@ -0,0 +1,153 @@
|
||||
typedef struct INetFwPolicy2Vtbl
|
||||
{
|
||||
BEGIN_INTERFACE
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
|
||||
INetFwPolicy2 * This,
|
||||
/* [in] */ REFIID riid,
|
||||
/* [annotation][iid_is][out] */
|
||||
__RPC__deref_out void **ppvObject);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE *AddRef )(
|
||||
INetFwPolicy2 * This);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE *Release )(
|
||||
INetFwPolicy2 * This);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetTypeInfoCount )(
|
||||
INetFwPolicy2 * This,
|
||||
/* [out] */ UINT *pctinfo);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetTypeInfo )(
|
||||
INetFwPolicy2 * This,
|
||||
/* [in] */ UINT iTInfo,
|
||||
/* [in] */ LCID lcid,
|
||||
/* [out] */ ITypeInfo **ppTInfo);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetIDsOfNames )(
|
||||
INetFwPolicy2 * This,
|
||||
/* [in] */ REFIID riid,
|
||||
/* [size_is][in] */ LPOLESTR *rgszNames,
|
||||
/* [range][in] */ UINT cNames,
|
||||
/* [in] */ LCID lcid,
|
||||
/* [size_is][out] */ DISPID *rgDispId);
|
||||
|
||||
/* [local] */ HRESULT ( STDMETHODCALLTYPE *Invoke )(
|
||||
INetFwPolicy2 * This,
|
||||
/* [in] */ DISPID dispIdMember,
|
||||
/* [in] */ REFIID riid,
|
||||
/* [in] */ LCID lcid,
|
||||
/* [in] */ WORD wFlags,
|
||||
/* [out][in] */ DISPPARAMS *pDispParams,
|
||||
/* [out] */ VARIANT *pVarResult,
|
||||
/* [out] */ EXCEPINFO *pExcepInfo,
|
||||
/* [out] */ UINT *puArgErr);
|
||||
|
||||
/* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_CurrentProfileTypes )(
|
||||
INetFwPolicy2 * This,
|
||||
/* [retval][out] */ long *profileTypesBitmask);
|
||||
|
||||
/* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_FirewallEnabled )(
|
||||
INetFwPolicy2 * This,
|
||||
/* [in] */ NET_FW_PROFILE_TYPE2 profileType,
|
||||
/* [retval][out] */ VARIANT_BOOL *enabled);
|
||||
|
||||
/* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_FirewallEnabled )(
|
||||
INetFwPolicy2 * This,
|
||||
/* [in] */ NET_FW_PROFILE_TYPE2 profileType,
|
||||
/* [in] */ VARIANT_BOOL enabled);
|
||||
|
||||
/* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ExcludedInterfaces )(
|
||||
INetFwPolicy2 * This,
|
||||
/* [in] */ NET_FW_PROFILE_TYPE2 profileType,
|
||||
/* [retval][out] */ VARIANT *interfaces);
|
||||
|
||||
/* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ExcludedInterfaces )(
|
||||
INetFwPolicy2 * This,
|
||||
/* [in] */ NET_FW_PROFILE_TYPE2 profileType,
|
||||
/* [in] */ VARIANT interfaces);
|
||||
|
||||
/* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_BlockAllInboundTraffic )(
|
||||
INetFwPolicy2 * This,
|
||||
/* [in] */ NET_FW_PROFILE_TYPE2 profileType,
|
||||
/* [retval][out] */ VARIANT_BOOL *Block);
|
||||
|
||||
/* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_BlockAllInboundTraffic )(
|
||||
INetFwPolicy2 * This,
|
||||
/* [in] */ NET_FW_PROFILE_TYPE2 profileType,
|
||||
/* [in] */ VARIANT_BOOL Block);
|
||||
|
||||
/* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_NotificationsDisabled )(
|
||||
INetFwPolicy2 * This,
|
||||
/* [in] */ NET_FW_PROFILE_TYPE2 profileType,
|
||||
/* [retval][out] */ VARIANT_BOOL *disabled);
|
||||
|
||||
/* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_NotificationsDisabled )(
|
||||
INetFwPolicy2 * This,
|
||||
/* [in] */ NET_FW_PROFILE_TYPE2 profileType,
|
||||
/* [in] */ VARIANT_BOOL disabled);
|
||||
|
||||
/* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_UnicastResponsesToMulticastBroadcastDisabled )(
|
||||
INetFwPolicy2 * This,
|
||||
/* [in] */ NET_FW_PROFILE_TYPE2 profileType,
|
||||
/* [retval][out] */ VARIANT_BOOL *disabled);
|
||||
|
||||
/* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_UnicastResponsesToMulticastBroadcastDisabled )(
|
||||
INetFwPolicy2 * This,
|
||||
/* [in] */ NET_FW_PROFILE_TYPE2 profileType,
|
||||
/* [in] */ VARIANT_BOOL disabled);
|
||||
|
||||
/* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Rules )(
|
||||
INetFwPolicy2 * This,
|
||||
/* [retval][out] */ INetFwRules **rules);
|
||||
|
||||
/* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ServiceRestriction )(
|
||||
INetFwPolicy2 * This,
|
||||
/* [retval][out] */ INetFwServiceRestriction **ServiceRestriction);
|
||||
|
||||
/* [id] */ HRESULT ( STDMETHODCALLTYPE *EnableRuleGroup )(
|
||||
INetFwPolicy2 * This,
|
||||
/* [in] */ long profileTypesBitmask,
|
||||
/* [in] */ BSTR group,
|
||||
/* [in] */ VARIANT_BOOL enable);
|
||||
|
||||
/* [id] */ HRESULT ( STDMETHODCALLTYPE *IsRuleGroupEnabled )(
|
||||
INetFwPolicy2 * This,
|
||||
/* [in] */ long profileTypesBitmask,
|
||||
/* [in] */ BSTR group,
|
||||
/* [retval][out] */ VARIANT_BOOL *enabled);
|
||||
|
||||
/* [id] */ HRESULT ( STDMETHODCALLTYPE *RestoreLocalFirewallDefaults )(
|
||||
INetFwPolicy2 * This);
|
||||
|
||||
/* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DefaultInboundAction )(
|
||||
INetFwPolicy2 * This,
|
||||
/* [in] */ NET_FW_PROFILE_TYPE2 profileType,
|
||||
/* [retval][out] */ NET_FW_ACTION *action);
|
||||
|
||||
/* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DefaultInboundAction )(
|
||||
INetFwPolicy2 * This,
|
||||
/* [in] */ NET_FW_PROFILE_TYPE2 profileType,
|
||||
/* [in] */ NET_FW_ACTION action);
|
||||
|
||||
/* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DefaultOutboundAction )(
|
||||
INetFwPolicy2 * This,
|
||||
/* [in] */ NET_FW_PROFILE_TYPE2 profileType,
|
||||
/* [retval][out] */ NET_FW_ACTION *action);
|
||||
|
||||
/* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DefaultOutboundAction )(
|
||||
INetFwPolicy2 * This,
|
||||
/* [in] */ NET_FW_PROFILE_TYPE2 profileType,
|
||||
/* [in] */ NET_FW_ACTION action);
|
||||
|
||||
/* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_IsRuleGroupCurrentlyEnabled )(
|
||||
INetFwPolicy2 * This,
|
||||
/* [in] */ BSTR group,
|
||||
/* [retval][out] */ VARIANT_BOOL *enabled);
|
||||
|
||||
/* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_LocalPolicyModifyState )(
|
||||
INetFwPolicy2 * This,
|
||||
/* [retval][out] */ NET_FW_MODIFY_STATE *modifyState);
|
||||
|
||||
END_INTERFACE
|
||||
} INetFwPolicy2Vtbl;
|
||||
@@ -0,0 +1,191 @@
|
||||
typedef struct INetFwRuleVtbl
|
||||
{
|
||||
BEGIN_INTERFACE
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
|
||||
INetFwRule * This,
|
||||
/* [in] */ REFIID riid,
|
||||
/* [annotation][iid_is][out] */
|
||||
__RPC__deref_out void **ppvObject);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE *AddRef )(
|
||||
INetFwRule * This);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE *Release )(
|
||||
INetFwRule * This);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetTypeInfoCount )(
|
||||
INetFwRule * This,
|
||||
/* [out] */ UINT *pctinfo);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetTypeInfo )(
|
||||
INetFwRule * This,
|
||||
/* [in] */ UINT iTInfo,
|
||||
/* [in] */ LCID lcid,
|
||||
/* [out] */ ITypeInfo **ppTInfo);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetIDsOfNames )(
|
||||
INetFwRule * This,
|
||||
/* [in] */ REFIID riid,
|
||||
/* [size_is][in] */ LPOLESTR *rgszNames,
|
||||
/* [range][in] */ UINT cNames,
|
||||
/* [in] */ LCID lcid,
|
||||
/* [size_is][out] */ DISPID *rgDispId);
|
||||
|
||||
/* [local] */ HRESULT ( STDMETHODCALLTYPE *Invoke )(
|
||||
INetFwRule * This,
|
||||
/* [in] */ DISPID dispIdMember,
|
||||
/* [in] */ REFIID riid,
|
||||
/* [in] */ LCID lcid,
|
||||
/* [in] */ WORD wFlags,
|
||||
/* [out][in] */ DISPPARAMS *pDispParams,
|
||||
/* [out] */ VARIANT *pVarResult,
|
||||
/* [out] */ EXCEPINFO *pExcepInfo,
|
||||
/* [out] */ UINT *puArgErr);
|
||||
|
||||
/* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Name )(
|
||||
INetFwRule * This,
|
||||
/* [retval][out] */ BSTR *name);
|
||||
|
||||
/* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_Name )(
|
||||
INetFwRule * This,
|
||||
/* [in] */ BSTR name);
|
||||
|
||||
/* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Description )(
|
||||
INetFwRule * This,
|
||||
/* [retval][out] */ BSTR *desc);
|
||||
|
||||
/* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_Description )(
|
||||
INetFwRule * This,
|
||||
/* [in] */ BSTR desc);
|
||||
|
||||
/* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ApplicationName )(
|
||||
INetFwRule * This,
|
||||
/* [retval][out] */ BSTR *imageFileName);
|
||||
|
||||
/* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ApplicationName )(
|
||||
INetFwRule * This,
|
||||
/* [in] */ BSTR imageFileName);
|
||||
|
||||
/* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ServiceName )(
|
||||
INetFwRule * This,
|
||||
/* [retval][out] */ BSTR *serviceName);
|
||||
|
||||
/* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ServiceName )(
|
||||
INetFwRule * This,
|
||||
/* [in] */ BSTR serviceName);
|
||||
|
||||
/* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Protocol )(
|
||||
INetFwRule * This,
|
||||
/* [retval][out] */ LONG *protocol);
|
||||
|
||||
/* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_Protocol )(
|
||||
INetFwRule * This,
|
||||
/* [in] */ LONG protocol);
|
||||
|
||||
/* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_LocalPorts )(
|
||||
INetFwRule * This,
|
||||
/* [retval][out] */ BSTR *portNumbers);
|
||||
|
||||
/* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_LocalPorts )(
|
||||
INetFwRule * This,
|
||||
/* [in] */ BSTR portNumbers);
|
||||
|
||||
/* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_RemotePorts )(
|
||||
INetFwRule * This,
|
||||
/* [retval][out] */ BSTR *portNumbers);
|
||||
|
||||
/* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_RemotePorts )(
|
||||
INetFwRule * This,
|
||||
/* [in] */ BSTR portNumbers);
|
||||
|
||||
/* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_LocalAddresses )(
|
||||
INetFwRule * This,
|
||||
/* [retval][out] */ BSTR *localAddrs);
|
||||
|
||||
/* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_LocalAddresses )(
|
||||
INetFwRule * This,
|
||||
/* [in] */ BSTR localAddrs);
|
||||
|
||||
/* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_RemoteAddresses )(
|
||||
INetFwRule * This,
|
||||
/* [retval][out] */ BSTR *remoteAddrs);
|
||||
|
||||
/* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_RemoteAddresses )(
|
||||
INetFwRule * This,
|
||||
/* [in] */ BSTR remoteAddrs);
|
||||
|
||||
/* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_IcmpTypesAndCodes )(
|
||||
INetFwRule * This,
|
||||
/* [retval][out] */ BSTR *icmpTypesAndCodes);
|
||||
|
||||
/* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_IcmpTypesAndCodes )(
|
||||
INetFwRule * This,
|
||||
/* [in] */ BSTR icmpTypesAndCodes);
|
||||
|
||||
/* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Direction )(
|
||||
INetFwRule * This,
|
||||
/* [retval][out] */ NET_FW_RULE_DIRECTION *dir);
|
||||
|
||||
/* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_Direction )(
|
||||
INetFwRule * This,
|
||||
/* [in] */ NET_FW_RULE_DIRECTION dir);
|
||||
|
||||
/* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Interfaces )(
|
||||
INetFwRule * This,
|
||||
/* [retval][out] */ VARIANT *interfaces);
|
||||
|
||||
/* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_Interfaces )(
|
||||
INetFwRule * This,
|
||||
/* [in] */ VARIANT interfaces);
|
||||
|
||||
/* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_InterfaceTypes )(
|
||||
INetFwRule * This,
|
||||
/* [retval][out] */ BSTR *interfaceTypes);
|
||||
|
||||
/* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_InterfaceTypes )(
|
||||
INetFwRule * This,
|
||||
/* [in] */ BSTR interfaceTypes);
|
||||
|
||||
/* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Enabled )(
|
||||
INetFwRule * This,
|
||||
/* [retval][out] */ VARIANT_BOOL *enabled);
|
||||
|
||||
/* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_Enabled )(
|
||||
INetFwRule * This,
|
||||
/* [in] */ VARIANT_BOOL enabled);
|
||||
|
||||
/* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Grouping )(
|
||||
INetFwRule * This,
|
||||
/* [retval][out] */ BSTR *context);
|
||||
|
||||
/* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_Grouping )(
|
||||
INetFwRule * This,
|
||||
/* [in] */ BSTR context);
|
||||
|
||||
/* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Profiles )(
|
||||
INetFwRule * This,
|
||||
/* [retval][out] */ long *profileTypesBitmask);
|
||||
|
||||
/* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_Profiles )(
|
||||
INetFwRule * This,
|
||||
/* [in] */ long profileTypesBitmask);
|
||||
|
||||
/* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_EdgeTraversal )(
|
||||
INetFwRule * This,
|
||||
/* [retval][out] */ VARIANT_BOOL *enabled);
|
||||
|
||||
/* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_EdgeTraversal )(
|
||||
INetFwRule * This,
|
||||
/* [in] */ VARIANT_BOOL enabled);
|
||||
|
||||
/* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Action )(
|
||||
INetFwRule * This,
|
||||
/* [retval][out] */ NET_FW_ACTION *action);
|
||||
|
||||
/* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_Action )(
|
||||
INetFwRule * This,
|
||||
/* [in] */ NET_FW_ACTION action);
|
||||
|
||||
END_INTERFACE
|
||||
} INetFwRuleVtbl;
|
||||
@@ -0,0 +1,68 @@
|
||||
typedef struct INetFwRulesVtbl
|
||||
{
|
||||
BEGIN_INTERFACE
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
|
||||
INetFwRules * This,
|
||||
/* [in] */ REFIID riid,
|
||||
/* [annotation][iid_is][out] */
|
||||
__RPC__deref_out void **ppvObject);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE *AddRef )(
|
||||
INetFwRules * This);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE *Release )(
|
||||
INetFwRules * This);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetTypeInfoCount )(
|
||||
INetFwRules * This,
|
||||
/* [out] */ UINT *pctinfo);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetTypeInfo )(
|
||||
INetFwRules * This,
|
||||
/* [in] */ UINT iTInfo,
|
||||
/* [in] */ LCID lcid,
|
||||
/* [out] */ ITypeInfo **ppTInfo);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetIDsOfNames )(
|
||||
INetFwRules * This,
|
||||
/* [in] */ REFIID riid,
|
||||
/* [size_is][in] */ LPOLESTR *rgszNames,
|
||||
/* [range][in] */ UINT cNames,
|
||||
/* [in] */ LCID lcid,
|
||||
/* [size_is][out] */ DISPID *rgDispId);
|
||||
|
||||
/* [local] */ HRESULT ( STDMETHODCALLTYPE *Invoke )(
|
||||
INetFwRules * This,
|
||||
/* [in] */ DISPID dispIdMember,
|
||||
/* [in] */ REFIID riid,
|
||||
/* [in] */ LCID lcid,
|
||||
/* [in] */ WORD wFlags,
|
||||
/* [out][in] */ DISPPARAMS *pDispParams,
|
||||
/* [out] */ VARIANT *pVarResult,
|
||||
/* [out] */ EXCEPINFO *pExcepInfo,
|
||||
/* [out] */ UINT *puArgErr);
|
||||
|
||||
/* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Count )(
|
||||
INetFwRules * This,
|
||||
/* [retval][out] */ long *count);
|
||||
|
||||
/* [id] */ HRESULT ( STDMETHODCALLTYPE *Add )(
|
||||
INetFwRules * This,
|
||||
/* [in] */ INetFwRule *rule);
|
||||
|
||||
/* [id] */ HRESULT ( STDMETHODCALLTYPE *Remove )(
|
||||
INetFwRules * This,
|
||||
/* [in] */ BSTR name);
|
||||
|
||||
/* [id] */ HRESULT ( STDMETHODCALLTYPE *Item )(
|
||||
INetFwRules * This,
|
||||
/* [in] */ BSTR name,
|
||||
/* [retval][out] */ INetFwRule **rule);
|
||||
|
||||
/* [restricted][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get__NewEnum )(
|
||||
INetFwRules * This,
|
||||
/* [retval][out] */ IUnknown **newEnum);
|
||||
|
||||
END_INTERFACE
|
||||
} INetFwRulesVtbl;
|
||||
@@ -0,0 +1,64 @@
|
||||
typedef struct INetFwServiceRestrictionVtbl
|
||||
{
|
||||
BEGIN_INTERFACE
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
|
||||
INetFwServiceRestriction * This,
|
||||
/* [in] */ REFIID riid,
|
||||
/* [annotation][iid_is][out] */
|
||||
__RPC__deref_out void **ppvObject);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE *AddRef )(
|
||||
INetFwServiceRestriction * This);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE *Release )(
|
||||
INetFwServiceRestriction * This);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetTypeInfoCount )(
|
||||
INetFwServiceRestriction * This,
|
||||
/* [out] */ UINT *pctinfo);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetTypeInfo )(
|
||||
INetFwServiceRestriction * This,
|
||||
/* [in] */ UINT iTInfo,
|
||||
/* [in] */ LCID lcid,
|
||||
/* [out] */ ITypeInfo **ppTInfo);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetIDsOfNames )(
|
||||
INetFwServiceRestriction * This,
|
||||
/* [in] */ REFIID riid,
|
||||
/* [size_is][in] */ LPOLESTR *rgszNames,
|
||||
/* [range][in] */ UINT cNames,
|
||||
/* [in] */ LCID lcid,
|
||||
/* [size_is][out] */ DISPID *rgDispId);
|
||||
|
||||
/* [local] */ HRESULT ( STDMETHODCALLTYPE *Invoke )(
|
||||
INetFwServiceRestriction * This,
|
||||
/* [in] */ DISPID dispIdMember,
|
||||
/* [in] */ REFIID riid,
|
||||
/* [in] */ LCID lcid,
|
||||
/* [in] */ WORD wFlags,
|
||||
/* [out][in] */ DISPPARAMS *pDispParams,
|
||||
/* [out] */ VARIANT *pVarResult,
|
||||
/* [out] */ EXCEPINFO *pExcepInfo,
|
||||
/* [out] */ UINT *puArgErr);
|
||||
|
||||
/* [id] */ HRESULT ( STDMETHODCALLTYPE *RestrictService )(
|
||||
INetFwServiceRestriction * This,
|
||||
/* [in] */ BSTR serviceName,
|
||||
/* [in] */ BSTR appName,
|
||||
/* [in] */ VARIANT_BOOL restrictService,
|
||||
/* [in] */ VARIANT_BOOL serviceSidRestricted);
|
||||
|
||||
/* [id] */ HRESULT ( STDMETHODCALLTYPE *ServiceRestricted )(
|
||||
INetFwServiceRestriction * This,
|
||||
/* [in] */ BSTR serviceName,
|
||||
/* [in] */ BSTR appName,
|
||||
/* [retval][out] */ VARIANT_BOOL *serviceRestricted);
|
||||
|
||||
/* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Rules )(
|
||||
INetFwServiceRestriction * This,
|
||||
/* [retval][out] */ INetFwRules **rules);
|
||||
|
||||
END_INTERFACE
|
||||
} INetFwServiceRestrictionVtbl;
|
||||
@@ -0,0 +1,18 @@
|
||||
typedef struct IUnknownVtbl
|
||||
{
|
||||
BEGIN_INTERFACE
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
|
||||
IUnknown * This,
|
||||
/* [in] */ REFIID riid,
|
||||
/* [annotation][iid_is][out] */
|
||||
__RPC__deref_out void **ppvObject);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE *AddRef )(
|
||||
IUnknown * This);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE *Release )(
|
||||
IUnknown * This);
|
||||
|
||||
END_INTERFACE
|
||||
} IUnknownVtbl;
|
||||
@@ -0,0 +1,38 @@
|
||||
typedef struct IWbemCallResultVtbl
|
||||
{
|
||||
BEGIN_INTERFACE
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
|
||||
__RPC__in IWbemCallResult * This,
|
||||
/* [in] */ __RPC__in REFIID riid,
|
||||
/* [annotation][iid_is][out] */
|
||||
__RPC__deref_out void **ppvObject);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE *AddRef )(
|
||||
__RPC__in IWbemCallResult * This);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE *Release )(
|
||||
__RPC__in IWbemCallResult * This);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetResultObject )(
|
||||
__RPC__in IWbemCallResult * This,
|
||||
/* [in] */ long lTimeout,
|
||||
/* [out] */ __RPC__deref_out_opt IWbemClassObject **ppResultObject);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetResultString )(
|
||||
__RPC__in IWbemCallResult * This,
|
||||
/* [in] */ long lTimeout,
|
||||
/* [out] */ __RPC__deref_out_opt BSTR *pstrResultString);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetResultServices )(
|
||||
__RPC__in IWbemCallResult * This,
|
||||
/* [in] */ long lTimeout,
|
||||
/* [out] */ __RPC__deref_out_opt IWbemServices **ppServices);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetCallStatus )(
|
||||
__RPC__in IWbemCallResult * This,
|
||||
/* [in] */ long lTimeout,
|
||||
/* [out] */ __RPC__out long *plStatus);
|
||||
|
||||
END_INTERFACE
|
||||
} IWbemCallResultVtbl;
|
||||
@@ -0,0 +1,143 @@
|
||||
typedef struct IWbemClassObjectVtbl
|
||||
{
|
||||
BEGIN_INTERFACE
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
|
||||
IWbemClassObject * This,
|
||||
/* [in] */ REFIID riid,
|
||||
/* [annotation][iid_is][out] */
|
||||
__RPC__deref_out void **ppvObject);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE *AddRef )(
|
||||
IWbemClassObject * This);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE *Release )(
|
||||
IWbemClassObject * This);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetQualifierSet )(
|
||||
IWbemClassObject * This,
|
||||
/* [out] */ IWbemQualifierSet **ppQualSet);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *Get )(
|
||||
IWbemClassObject * This,
|
||||
/* [string][in] */ LPCWSTR wszName,
|
||||
/* [in] */ long lFlags,
|
||||
/* [unique][in][out] */ VARIANT *pVal,
|
||||
/* [unique][in][out] */ CIMTYPE *pType,
|
||||
/* [unique][in][out] */ long *plFlavor);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *Put )(
|
||||
IWbemClassObject * This,
|
||||
/* [string][in] */ LPCWSTR wszName,
|
||||
/* [in] */ long lFlags,
|
||||
/* [in] */ VARIANT *pVal,
|
||||
/* [in] */ CIMTYPE Type);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *Delete )(
|
||||
IWbemClassObject * This,
|
||||
/* [string][in] */ LPCWSTR wszName);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetNames )(
|
||||
IWbemClassObject * This,
|
||||
/* [string][in] */ LPCWSTR wszQualifierName,
|
||||
/* [in] */ long lFlags,
|
||||
/* [in] */ VARIANT *pQualifierVal,
|
||||
/* [out] */ SAFEARRAY * *pNames);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *BeginEnumeration )(
|
||||
IWbemClassObject * This,
|
||||
/* [in] */ long lEnumFlags);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *Next )(
|
||||
IWbemClassObject * This,
|
||||
/* [in] */ long lFlags,
|
||||
/* [unique][in][out] */ BSTR *strName,
|
||||
/* [unique][in][out] */ VARIANT *pVal,
|
||||
/* [unique][in][out] */ CIMTYPE *pType,
|
||||
/* [unique][in][out] */ long *plFlavor);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *EndEnumeration )(
|
||||
IWbemClassObject * This);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetPropertyQualifierSet )(
|
||||
IWbemClassObject * This,
|
||||
/* [string][in] */ LPCWSTR wszProperty,
|
||||
/* [out] */ IWbemQualifierSet **ppQualSet);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *Clone )(
|
||||
IWbemClassObject * This,
|
||||
/* [out] */ IWbemClassObject **ppCopy);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetObjectText )(
|
||||
IWbemClassObject * This,
|
||||
/* [in] */ long lFlags,
|
||||
/* [out] */ BSTR *pstrObjectText);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *SpawnDerivedClass )(
|
||||
IWbemClassObject * This,
|
||||
/* [in] */ long lFlags,
|
||||
/* [out] */ IWbemClassObject **ppNewClass);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *SpawnInstance )(
|
||||
IWbemClassObject * This,
|
||||
/* [in] */ long lFlags,
|
||||
/* [out] */ IWbemClassObject **ppNewInstance);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *CompareTo )(
|
||||
IWbemClassObject * This,
|
||||
/* [in] */ long lFlags,
|
||||
/* [in] */ IWbemClassObject *pCompareTo);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetPropertyOrigin )(
|
||||
IWbemClassObject * This,
|
||||
/* [string][in] */ LPCWSTR wszName,
|
||||
/* [out] */ BSTR *pstrClassName);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *InheritsFrom )(
|
||||
IWbemClassObject * This,
|
||||
/* [in] */ LPCWSTR strAncestor);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetMethod )(
|
||||
IWbemClassObject * This,
|
||||
/* [string][in] */ LPCWSTR wszName,
|
||||
/* [in] */ long lFlags,
|
||||
/* [out] */ IWbemClassObject **ppInSignature,
|
||||
/* [out] */ IWbemClassObject **ppOutSignature);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *PutMethod )(
|
||||
IWbemClassObject * This,
|
||||
/* [string][in] */ LPCWSTR wszName,
|
||||
/* [in] */ long lFlags,
|
||||
/* [in] */ IWbemClassObject *pInSignature,
|
||||
/* [in] */ IWbemClassObject *pOutSignature);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *DeleteMethod )(
|
||||
IWbemClassObject * This,
|
||||
/* [string][in] */ LPCWSTR wszName);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *BeginMethodEnumeration )(
|
||||
IWbemClassObject * This,
|
||||
/* [in] */ long lEnumFlags);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *NextMethod )(
|
||||
IWbemClassObject * This,
|
||||
/* [in] */ long lFlags,
|
||||
/* [unique][in][out] */ BSTR *pstrName,
|
||||
/* [unique][in][out] */ IWbemClassObject **ppInSignature,
|
||||
/* [unique][in][out] */ IWbemClassObject **ppOutSignature);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *EndMethodEnumeration )(
|
||||
IWbemClassObject * This);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetMethodQualifierSet )(
|
||||
IWbemClassObject * This,
|
||||
/* [string][in] */ LPCWSTR wszMethod,
|
||||
/* [out] */ IWbemQualifierSet **ppQualSet);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetMethodOrigin )(
|
||||
IWbemClassObject * This,
|
||||
/* [string][in] */ LPCWSTR wszMethodName,
|
||||
/* [out] */ BSTR *pstrClassName);
|
||||
|
||||
END_INTERFACE
|
||||
} IWbemClassObjectVtbl;
|
||||
@@ -0,0 +1,60 @@
|
||||
typedef struct IWbemContextVtbl
|
||||
{
|
||||
BEGIN_INTERFACE
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
|
||||
IWbemContext * This,
|
||||
/* [in] */ REFIID riid,
|
||||
/* [annotation][iid_is][out] */
|
||||
__RPC__deref_out void **ppvObject);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE *AddRef )(
|
||||
IWbemContext * This);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE *Release )(
|
||||
IWbemContext * This);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *Clone )(
|
||||
IWbemContext * This,
|
||||
/* [out] */ IWbemContext **ppNewCopy);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetNames )(
|
||||
IWbemContext * This,
|
||||
/* [in] */ long lFlags,
|
||||
/* [out] */ SAFEARRAY * *pNames);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *BeginEnumeration )(
|
||||
IWbemContext * This,
|
||||
/* [in] */ long lFlags);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *Next )(
|
||||
IWbemContext * This,
|
||||
/* [in] */ long lFlags,
|
||||
/* [out] */ BSTR *pstrName,
|
||||
/* [out] */ VARIANT *pValue);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *EndEnumeration )(
|
||||
IWbemContext * This);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *SetValue )(
|
||||
IWbemContext * This,
|
||||
/* [string][in] */ LPCWSTR wszName,
|
||||
/* [in] */ long lFlags,
|
||||
/* [in] */ VARIANT *pValue);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetValue )(
|
||||
IWbemContext * This,
|
||||
/* [string][in] */ LPCWSTR wszName,
|
||||
/* [in] */ long lFlags,
|
||||
/* [out] */ VARIANT *pValue);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *DeleteValue )(
|
||||
IWbemContext * This,
|
||||
/* [string][in] */ LPCWSTR wszName,
|
||||
/* [in] */ long lFlags);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *DeleteAll )(
|
||||
IWbemContext * This);
|
||||
|
||||
END_INTERFACE
|
||||
} IWbemContextVtbl;
|
||||
@@ -0,0 +1,29 @@
|
||||
typedef struct IWbemLocatorVtbl
|
||||
{
|
||||
BEGIN_INTERFACE
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
|
||||
IWbemLocator * This,
|
||||
/* [in] */ REFIID riid,
|
||||
/* [annotation][iid_is][out] */
|
||||
__RPC__deref_out void **ppvObject);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE *AddRef )(
|
||||
IWbemLocator * This);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE *Release )(
|
||||
IWbemLocator * This);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *ConnectServer )(
|
||||
IWbemLocator * This,
|
||||
/* [in] */ const BSTR strNetworkResource,
|
||||
/* [in] */ const BSTR strUser,
|
||||
/* [in] */ const BSTR strPassword,
|
||||
/* [in] */ const BSTR strLocale,
|
||||
/* [in] */ long lSecurityFlags,
|
||||
/* [in] */ const BSTR strAuthority,
|
||||
/* [in] */ IWbemContext *pCtx,
|
||||
/* [out] */ IWbemServices **ppNamespace);
|
||||
|
||||
END_INTERFACE
|
||||
} IWbemLocatorVtbl;
|
||||
@@ -0,0 +1,30 @@
|
||||
typedef struct IWbemObjectSinkVtbl
|
||||
{
|
||||
BEGIN_INTERFACE
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
|
||||
__RPC__in IWbemObjectSink * This,
|
||||
/* [in] */ __RPC__in REFIID riid,
|
||||
/* [annotation][iid_is][out] */
|
||||
__RPC__deref_out void **ppvObject);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE *AddRef )(
|
||||
__RPC__in IWbemObjectSink * This);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE *Release )(
|
||||
__RPC__in IWbemObjectSink * This);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *Indicate )(
|
||||
__RPC__in IWbemObjectSink * This,
|
||||
/* [in] */ long lObjectCount,
|
||||
/* [size_is][in] */ __RPC__in_ecount_full(lObjectCount) IWbemClassObject **apObjArray);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *SetStatus )(
|
||||
__RPC__in IWbemObjectSink * This,
|
||||
/* [in] */ long lFlags,
|
||||
/* [in] */ HRESULT hResult,
|
||||
/* [unique][in] */ __RPC__in_opt BSTR strParam,
|
||||
/* [unique][in] */ __RPC__in_opt IWbemClassObject *pObjParam);
|
||||
|
||||
END_INTERFACE
|
||||
} IWbemObjectSinkVtbl;
|
||||
@@ -0,0 +1,54 @@
|
||||
typedef struct IWbemQualifierSetVtbl
|
||||
{
|
||||
BEGIN_INTERFACE
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
|
||||
IWbemQualifierSet * This,
|
||||
/* [in] */ REFIID riid,
|
||||
/* [annotation][iid_is][out] */
|
||||
__RPC__deref_out void **ppvObject);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE *AddRef )(
|
||||
IWbemQualifierSet * This);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE *Release )(
|
||||
IWbemQualifierSet * This);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *Get )(
|
||||
IWbemQualifierSet * This,
|
||||
/* [string][in] */ LPCWSTR wszName,
|
||||
/* [in] */ long lFlags,
|
||||
/* [unique][in][out] */ VARIANT *pVal,
|
||||
/* [unique][in][out] */ long *plFlavor);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *Put )(
|
||||
IWbemQualifierSet * This,
|
||||
/* [string][in] */ LPCWSTR wszName,
|
||||
/* [in] */ VARIANT *pVal,
|
||||
/* [in] */ long lFlavor);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *Delete )(
|
||||
IWbemQualifierSet * This,
|
||||
/* [string][in] */ LPCWSTR wszName);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetNames )(
|
||||
IWbemQualifierSet * This,
|
||||
/* [in] */ long lFlags,
|
||||
/* [out] */ SAFEARRAY * *pNames);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *BeginEnumeration )(
|
||||
IWbemQualifierSet * This,
|
||||
/* [in] */ long lFlags);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *Next )(
|
||||
IWbemQualifierSet * This,
|
||||
/* [in] */ long lFlags,
|
||||
/* [unique][in][out] */ BSTR *pstrName,
|
||||
/* [unique][in][out] */ VARIANT *pVal,
|
||||
/* [unique][in][out] */ long *plFlavor);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *EndEnumeration )(
|
||||
IWbemQualifierSet * This);
|
||||
|
||||
END_INTERFACE
|
||||
} IWbemQualifierSetVtbl;
|
||||
@@ -0,0 +1,185 @@
|
||||
typedef struct IWbemServicesVtbl
|
||||
{
|
||||
BEGIN_INTERFACE
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
|
||||
__RPC__in IWbemServices * This,
|
||||
/* [in] */ __RPC__in REFIID riid,
|
||||
/* [annotation][iid_is][out] */
|
||||
__RPC__deref_out void **ppvObject);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE *AddRef )(
|
||||
__RPC__in IWbemServices * This);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE *Release )(
|
||||
__RPC__in IWbemServices * This);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *OpenNamespace )(
|
||||
__RPC__in IWbemServices * This,
|
||||
/* [in] */ __RPC__in const BSTR strNamespace,
|
||||
/* [in] */ long lFlags,
|
||||
/* [in] */ __RPC__in_opt IWbemContext *pCtx,
|
||||
/* [unique][in][out] */ __RPC__deref_opt_inout_opt IWbemServices **ppWorkingNamespace,
|
||||
/* [unique][in][out] */ __RPC__deref_opt_inout_opt IWbemCallResult **ppResult);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *CancelAsyncCall )(
|
||||
__RPC__in IWbemServices * This,
|
||||
/* [in] */ __RPC__in_opt IWbemObjectSink *pSink);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *QueryObjectSink )(
|
||||
__RPC__in IWbemServices * This,
|
||||
/* [in] */ long lFlags,
|
||||
/* [out] */ __RPC__deref_out_opt IWbemObjectSink **ppResponseHandler);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetObject )(
|
||||
__RPC__in IWbemServices * This,
|
||||
/* [in] */ __RPC__in const BSTR strObjectPath,
|
||||
/* [in] */ long lFlags,
|
||||
/* [in] */ __RPC__in_opt IWbemContext *pCtx,
|
||||
/* [unique][in][out] */ __RPC__deref_opt_inout_opt IWbemClassObject **ppObject,
|
||||
/* [unique][in][out] */ __RPC__deref_opt_inout_opt IWbemCallResult **ppCallResult);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetObjectAsync )(
|
||||
__RPC__in IWbemServices * This,
|
||||
/* [in] */ __RPC__in const BSTR strObjectPath,
|
||||
/* [in] */ long lFlags,
|
||||
/* [in] */ __RPC__in_opt IWbemContext *pCtx,
|
||||
/* [in] */ __RPC__in_opt IWbemObjectSink *pResponseHandler);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *PutClass )(
|
||||
__RPC__in IWbemServices * This,
|
||||
/* [in] */ __RPC__in_opt IWbemClassObject *pObject,
|
||||
/* [in] */ long lFlags,
|
||||
/* [in] */ __RPC__in_opt IWbemContext *pCtx,
|
||||
/* [unique][in][out] */ __RPC__deref_opt_inout_opt IWbemCallResult **ppCallResult);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *PutClassAsync )(
|
||||
__RPC__in IWbemServices * This,
|
||||
/* [in] */ __RPC__in_opt IWbemClassObject *pObject,
|
||||
/* [in] */ long lFlags,
|
||||
/* [in] */ __RPC__in_opt IWbemContext *pCtx,
|
||||
/* [in] */ __RPC__in_opt IWbemObjectSink *pResponseHandler);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *DeleteClass )(
|
||||
__RPC__in IWbemServices * This,
|
||||
/* [in] */ __RPC__in const BSTR strClass,
|
||||
/* [in] */ long lFlags,
|
||||
/* [in] */ __RPC__in_opt IWbemContext *pCtx,
|
||||
/* [unique][in][out] */ __RPC__deref_opt_inout_opt IWbemCallResult **ppCallResult);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *DeleteClassAsync )(
|
||||
__RPC__in IWbemServices * This,
|
||||
/* [in] */ __RPC__in const BSTR strClass,
|
||||
/* [in] */ long lFlags,
|
||||
/* [in] */ __RPC__in_opt IWbemContext *pCtx,
|
||||
/* [in] */ __RPC__in_opt IWbemObjectSink *pResponseHandler);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *CreateClassEnum )(
|
||||
__RPC__in IWbemServices * This,
|
||||
/* [in] */ __RPC__in const BSTR strSuperclass,
|
||||
/* [in] */ long lFlags,
|
||||
/* [in] */ __RPC__in_opt IWbemContext *pCtx,
|
||||
/* [out] */ __RPC__deref_out_opt IEnumWbemClassObject **ppEnum);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *CreateClassEnumAsync )(
|
||||
__RPC__in IWbemServices * This,
|
||||
/* [in] */ __RPC__in const BSTR strSuperclass,
|
||||
/* [in] */ long lFlags,
|
||||
/* [in] */ __RPC__in_opt IWbemContext *pCtx,
|
||||
/* [in] */ __RPC__in_opt IWbemObjectSink *pResponseHandler);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *PutInstance )(
|
||||
__RPC__in IWbemServices * This,
|
||||
/* [in] */ __RPC__in_opt IWbemClassObject *pInst,
|
||||
/* [in] */ long lFlags,
|
||||
/* [in] */ __RPC__in_opt IWbemContext *pCtx,
|
||||
/* [unique][in][out] */ __RPC__deref_opt_inout_opt IWbemCallResult **ppCallResult);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *PutInstanceAsync )(
|
||||
__RPC__in IWbemServices * This,
|
||||
/* [in] */ __RPC__in_opt IWbemClassObject *pInst,
|
||||
/* [in] */ long lFlags,
|
||||
/* [in] */ __RPC__in_opt IWbemContext *pCtx,
|
||||
/* [in] */ __RPC__in_opt IWbemObjectSink *pResponseHandler);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *DeleteInstance )(
|
||||
__RPC__in IWbemServices * This,
|
||||
/* [in] */ __RPC__in const BSTR strObjectPath,
|
||||
/* [in] */ long lFlags,
|
||||
/* [in] */ __RPC__in_opt IWbemContext *pCtx,
|
||||
/* [unique][in][out] */ __RPC__deref_opt_inout_opt IWbemCallResult **ppCallResult);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *DeleteInstanceAsync )(
|
||||
__RPC__in IWbemServices * This,
|
||||
/* [in] */ __RPC__in const BSTR strObjectPath,
|
||||
/* [in] */ long lFlags,
|
||||
/* [in] */ __RPC__in_opt IWbemContext *pCtx,
|
||||
/* [in] */ __RPC__in_opt IWbemObjectSink *pResponseHandler);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *CreateInstanceEnum )(
|
||||
__RPC__in IWbemServices * This,
|
||||
/* [in] */ __RPC__in const BSTR strFilter,
|
||||
/* [in] */ long lFlags,
|
||||
/* [in] */ __RPC__in_opt IWbemContext *pCtx,
|
||||
/* [out] */ __RPC__deref_out_opt IEnumWbemClassObject **ppEnum);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *CreateInstanceEnumAsync )(
|
||||
__RPC__in IWbemServices * This,
|
||||
/* [in] */ __RPC__in const BSTR strFilter,
|
||||
/* [in] */ long lFlags,
|
||||
/* [in] */ __RPC__in_opt IWbemContext *pCtx,
|
||||
/* [in] */ __RPC__in_opt IWbemObjectSink *pResponseHandler);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *ExecQuery )(
|
||||
__RPC__in IWbemServices * This,
|
||||
/* [in] */ __RPC__in const BSTR strQueryLanguage,
|
||||
/* [in] */ __RPC__in const BSTR strQuery,
|
||||
/* [in] */ long lFlags,
|
||||
/* [in] */ __RPC__in_opt IWbemContext *pCtx,
|
||||
/* [out] */ __RPC__deref_out_opt IEnumWbemClassObject **ppEnum);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *ExecQueryAsync )(
|
||||
__RPC__in IWbemServices * This,
|
||||
/* [in] */ __RPC__in const BSTR strQueryLanguage,
|
||||
/* [in] */ __RPC__in const BSTR strQuery,
|
||||
/* [in] */ long lFlags,
|
||||
/* [in] */ __RPC__in_opt IWbemContext *pCtx,
|
||||
/* [in] */ __RPC__in_opt IWbemObjectSink *pResponseHandler);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *ExecNotificationQuery )(
|
||||
__RPC__in IWbemServices * This,
|
||||
/* [in] */ __RPC__in const BSTR strQueryLanguage,
|
||||
/* [in] */ __RPC__in const BSTR strQuery,
|
||||
/* [in] */ long lFlags,
|
||||
/* [in] */ __RPC__in_opt IWbemContext *pCtx,
|
||||
/* [out] */ __RPC__deref_out_opt IEnumWbemClassObject **ppEnum);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *ExecNotificationQueryAsync )(
|
||||
__RPC__in IWbemServices * This,
|
||||
/* [in] */ __RPC__in const BSTR strQueryLanguage,
|
||||
/* [in] */ __RPC__in const BSTR strQuery,
|
||||
/* [in] */ long lFlags,
|
||||
/* [in] */ __RPC__in_opt IWbemContext *pCtx,
|
||||
/* [in] */ __RPC__in_opt IWbemObjectSink *pResponseHandler);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *ExecMethod )(
|
||||
__RPC__in IWbemServices * This,
|
||||
/* [in] */ __RPC__in const BSTR strObjectPath,
|
||||
/* [in] */ __RPC__in const BSTR strMethodName,
|
||||
/* [in] */ long lFlags,
|
||||
/* [in] */ __RPC__in_opt IWbemContext *pCtx,
|
||||
/* [in] */ __RPC__in_opt IWbemClassObject *pInParams,
|
||||
/* [unique][in][out] */ __RPC__deref_opt_inout_opt IWbemClassObject **ppOutParams,
|
||||
/* [unique][in][out] */ __RPC__deref_opt_inout_opt IWbemCallResult **ppCallResult);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *ExecMethodAsync )(
|
||||
__RPC__in IWbemServices * This,
|
||||
/* [in] */ __RPC__in const BSTR strObjectPath,
|
||||
/* [in] */ __RPC__in const BSTR strMethodName,
|
||||
/* [in] */ long lFlags,
|
||||
/* [in] */ __RPC__in_opt IWbemContext *pCtx,
|
||||
/* [in] */ __RPC__in_opt IWbemClassObject *pInParams,
|
||||
/* [in] */ __RPC__in_opt IWbemObjectSink *pResponseHandler);
|
||||
|
||||
END_INTERFACE
|
||||
} IWbemServicesVtbl;
|
||||
@@ -0,0 +1,168 @@
|
||||
import StringIO
|
||||
from collections import namedtuple
|
||||
|
||||
import dummy_wintypes
|
||||
import struct_parser
|
||||
from winstruct import WinStruct, WinUnion, WinStructType, Ptr, WinEnum
|
||||
from simpleparser import *
|
||||
|
||||
|
||||
def initial_processing( data):
|
||||
# https://gcc.gnu.org/onlinedocs/cpp/Initial-processing.html#Initial-processing
|
||||
# Step 1 -> use correct end of line + add last \n if not existing
|
||||
data = data.replace("\r\n", "\n")
|
||||
if not data.endswith("\n"):
|
||||
data = data + "\n"
|
||||
# Step 2: Trigraph : fuck it
|
||||
pass
|
||||
# Step 3: Line merge !
|
||||
data = data.replace("\\\n", "")
|
||||
# Step 4 Remove comments:
|
||||
|
||||
ins = StringIO.StringIO(data)
|
||||
outs = StringIO.StringIO()
|
||||
|
||||
in_str = False
|
||||
res = []
|
||||
while ins.tell() != len(data):
|
||||
c = ins.read(1)
|
||||
if ins.tell() == len(data):
|
||||
outs.write(c)
|
||||
break
|
||||
if not in_str and c == "/":
|
||||
nc = ins.read(1)
|
||||
if nc == "/":
|
||||
while c != "\n":
|
||||
c = ins.read(1)
|
||||
outs.write(c)
|
||||
continue
|
||||
elif nc == "*":
|
||||
while c != "*" or nc != "/":
|
||||
c = nc
|
||||
nc = ins.read(1)
|
||||
if not nc:
|
||||
raise ValueError("Unmatched */")
|
||||
outs.write(" ")
|
||||
continue
|
||||
else:
|
||||
outs.write(c)
|
||||
ins.seek(ins.tell() - 1)
|
||||
continue
|
||||
# TODO: escape in str
|
||||
elif c == '"':
|
||||
in_str = not in_str
|
||||
outs.write(c)
|
||||
outs.seek(0)
|
||||
return outs.read()
|
||||
|
||||
class WinComParser(Parser):
|
||||
PARAM_INFO = ["__RPC__deref_out", "__RPC__in", "__RPC__deref_out_opt", "__RPC__out", "__RPC__in_opt", "__RPC__deref_opt_inout_opt"]
|
||||
PARAM_INFO_WITH_VALUE = ["__RPC__in_ecount", "__RPC__out_ecount_part", "__RPC__in_ecount_full", "__RPC__in_range", "__RPC__out_ecount_full"]
|
||||
|
||||
def __init__(self, data):
|
||||
data = initial_processing(data)
|
||||
#print(data)
|
||||
super(WinComParser, self).__init__(data)
|
||||
|
||||
def assert_name(self, expected_name, n=None):
|
||||
if n is None:
|
||||
n = self.assert_token_type(NameToken)
|
||||
if n.value != expected_name:
|
||||
raise ParsingError("Expected name {0} got {1} instead".format(expected_name, n.value))
|
||||
return n
|
||||
|
||||
def parse_argument(self):
|
||||
byreflevel = 0
|
||||
# Pass __RPC__deref_out
|
||||
while self.peek() in [NameToken(x) for x in self.PARAM_INFO + self.PARAM_INFO_WITH_VALUE]:
|
||||
ign = self.assert_token_type(NameToken)
|
||||
if ign.value in self.PARAM_INFO_WITH_VALUE:
|
||||
# pass __RPC__in_ecount(cNames)
|
||||
self.assert_token_type(OpenParenthesisToken)
|
||||
while type(self.peek()) != CloseParenthesisToken:
|
||||
self.next_token()
|
||||
self.next_token()
|
||||
if self.peek() == KeywordToken("const"):
|
||||
self.next_token()
|
||||
type_name = self.assert_token_type(NameToken)
|
||||
|
||||
while type(self.peek()) == StarToken:
|
||||
byreflevel += 1
|
||||
discard_star = self.next_token()
|
||||
arg_name = self.assert_token_type(NameToken)
|
||||
if type(self.peek()) not in [CommaToken, CloseParenthesisToken]:
|
||||
raise ParsingError("COM PARSING: argument decl should finish by <,> or <)> (arg {0})".format(type_name.value))
|
||||
if type(self.peek()) == CommaToken:
|
||||
self.assert_token_type(CommaToken)
|
||||
return type_name.value, byreflevel, arg_name.value
|
||||
|
||||
def parse_method(self):
|
||||
ret_type = self.assert_token_type(NameToken)
|
||||
#print(ret_type)
|
||||
self.assert_token_type(OpenParenthesisToken)
|
||||
self.assert_name("STDMETHODCALLTYPE")
|
||||
#if type(self.peek()) == StarToken:
|
||||
self.assert_token_type(StarToken)
|
||||
method_name = self.assert_token_type(NameToken)
|
||||
self.assert_token_type(CloseParenthesisToken)
|
||||
|
||||
args = []
|
||||
self.assert_token_type(OpenParenthesisToken)
|
||||
while type(self.peek()) != CloseParenthesisToken:
|
||||
args.append(self.parse_argument())
|
||||
#print("Pass <{0}>".format(p))
|
||||
self.next_token()
|
||||
self.assert_token_type(ColonToken)
|
||||
return ret_type.value, method_name.value, args
|
||||
|
||||
def parse(self):
|
||||
self.assert_keyword("typedef")
|
||||
self.assert_keyword("struct")
|
||||
|
||||
vtable_name = self.assert_token_type(NameToken).value
|
||||
self.assert_token_type(OpenBracketToken)
|
||||
self.assert_name("BEGIN_INTERFACE")
|
||||
|
||||
res = WinCOMVTABLE(vtable_name)
|
||||
|
||||
while self.peek() != NameToken("END_INTERFACE"):
|
||||
ret_type, method_name, args = self.parse_method()
|
||||
#print("Method name is {0}".format(method_name))
|
||||
for arg in args:
|
||||
pass
|
||||
#print(" Param is {0}".format(arg))
|
||||
res.add_method(ret_type, method_name, args)
|
||||
end_interface = self.assert_name("END_INTERFACE")
|
||||
self.assert_token_type(CloseBracketToken)
|
||||
typdef = self.assert_token_type(NameToken)
|
||||
self.assert_token_type(ColonToken)
|
||||
return res
|
||||
|
||||
#print(self.data)
|
||||
|
||||
Method = namedtuple("Method", ["ret_type", "name", "args"])
|
||||
MethodArg = namedtuple("MethodArg", ["type", "byreflevel", "name"])
|
||||
class WinCOMVTABLE(object):
|
||||
def __init__(self, vtbl_name):
|
||||
self.vtbl_name = vtbl_name
|
||||
if not vtbl_name.endswith("Vtbl"):
|
||||
raise ValueError("Com interface are expected to finish by <Vtbl> got <{0}".format(vtbl.name))
|
||||
self.name = vtbl_name[:-len("Vtbl")]
|
||||
self.methods = []
|
||||
|
||||
def add_method(self, ret_type, method_name, args):
|
||||
new_args = []
|
||||
for type, byreflevel, name in args:
|
||||
if type in ["long", "int"]:
|
||||
type = type.upper()
|
||||
new_args.append(MethodArg(type, byreflevel, name))
|
||||
|
||||
if ret_type in ["long", "int"]:
|
||||
ret_type = ret_type.upper()
|
||||
self.methods.append(Method(ret_type, method_name, new_args))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
x = WinComParser(open(sys.argv[1]).read()).parse()
|
||||
print(x)
|
||||
@@ -1 +1 @@
|
||||
names = ['ATOM', 'BOOL', 'BOOLEAN', 'BYTE', 'COLORREF', 'DOUBLE', 'DWORD', 'FILETIME', 'FLOAT', 'HACCEL', 'HANDLE', 'HBITMAP', ' HBRUSH', 'HCOLORSPACE', 'HDC', 'HDESK', 'HDWP', 'HENHMETAFILE', 'HFONT', 'HGDIOBJ', 'HGLOBAL', 'HHOOK', 'HICON', 'HINSTA NCE', 'HKEY', 'HKL', 'HLOCAL', 'HMENU', 'HMETAFILE', 'HMODULE', 'HMONITOR', 'HPALETTE', 'HPEN', 'HRGN', 'HRSRC', 'HSTR', 'HTASK', 'HWINSTA', 'HWND', 'INT', 'LANGID', 'LARGE_INTEGER', 'LCID', 'LCTYPE', 'LGRPID', 'LONG', 'LPARAM', 'LPCOLESTR' , 'LPCSTR', 'LPCVOID', 'LPCWSTR', 'LPOLESTR', 'LPSTR', 'LPVOID', 'LPWSTR', 'MAX_PATH', 'MSG', 'OLESTR', 'POINT', 'POINTL ', 'RECT', 'RECTL', 'RGB', 'SC_HANDLE', 'SERVICE_STATUS_HANDLE', 'SHORT', 'SIZE', 'SIZEL', 'SMALL_RECT', 'UINT', 'ULARGE _INTEGER', 'ULONG', 'USHORT', 'VARIANT_BOOL', 'WCHAR', 'WIN32_FIND_DATAA', 'WIN32_FIND_DATAW', 'WORD', 'WPARAM', '_COORD ', '_FILETIME', '_LARGE_INTEGER', '_POINTL', '_RECTL', '_SMALL_RECT', '_ULARGE_INTEGER', 'tagMSG', 'tagPOINT', 'tagRECT' , 'tagSIZE']
|
||||
names = ['HRESULT', 'ATOM', 'BOOL', 'BOOLEAN', 'BYTE', 'COLORREF', 'DOUBLE', 'DWORD', 'FILETIME', 'FLOAT', 'HACCEL', 'HANDLE', 'HBITMAP', ' HBRUSH', 'HCOLORSPACE', 'HDC', 'HDESK', 'HDWP', 'HENHMETAFILE', 'HFONT', 'HGDIOBJ', 'HGLOBAL', 'HHOOK', 'HICON', 'HINSTA NCE', 'HKEY', 'HKL', 'HLOCAL', 'HMENU', 'HMETAFILE', 'HMODULE', 'HMONITOR', 'HPALETTE', 'HPEN', 'HRGN', 'HRSRC', 'HSTR', 'HTASK', 'HWINSTA', 'HWND', 'INT', 'LANGID', 'LARGE_INTEGER', 'LCID', 'LCTYPE', 'LGRPID', 'LONG', 'LPARAM', 'LPCOLESTR' , 'LPCSTR', 'LPCVOID', 'LPCWSTR', 'LPOLESTR', 'LPSTR', 'LPVOID', 'LPWSTR', 'MAX_PATH', 'MSG', 'OLESTR', 'POINT', 'POINTL ', 'RECT', 'RECTL', 'RGB', 'SC_HANDLE', 'SERVICE_STATUS_HANDLE', 'SHORT', 'SIZE', 'SIZEL', 'SMALL_RECT', 'UINT', 'ULARGE _INTEGER', 'ULONG', 'USHORT', 'VARIANT_BOOL', 'WCHAR', 'WIN32_FIND_DATAA', 'WIN32_FIND_DATAW', 'WORD', 'WPARAM', '_COORD ', '_FILETIME', '_LARGE_INTEGER', '_POINTL', '_RECTL', '_SMALL_RECT', '_ULARGE_INTEGER', 'tagMSG', 'tagPOINT', 'tagRECT' , 'tagSIZE']
|
||||
|
||||
@@ -16,19 +16,19 @@ class WinFunc(object):
|
||||
|
||||
def generate_ctypes(self):
|
||||
return self.generate_comment_ctypes() + "\n" + self.generate_prototype_ctypes() + "\n" + self.generate_paramflags_ctypes() + "\n"
|
||||
|
||||
|
||||
def generate_comment_ctypes(self):
|
||||
model = "# {0}({1}):"
|
||||
model = "#def {0}({1}):\n# return {0}.ctypes_function({1})"
|
||||
ctypes_param = [name for type, name in self.params]
|
||||
ctypes_param_str = ", ".join(ctypes_param)
|
||||
return model.format(self.name, ctypes_param_str)
|
||||
|
||||
|
||||
def generate_prototype_ctypes(self):
|
||||
model = "{0} = WINFUNCTYPE({1})"
|
||||
ctypes_param = [self.return_type] + [type for type, name in self.params]
|
||||
ctypes_param_str = ", ".join(ctypes_param)
|
||||
return model.format(self.name + "Prototype", ctypes_param_str)
|
||||
|
||||
|
||||
def generate_paramflags_ctypes(self):
|
||||
model = "{0} = {1}"
|
||||
ctypes_paramflags = tuple([(1, name) for type, name in self.params])
|
||||
@@ -37,14 +37,14 @@ class WinFunc(object):
|
||||
|
||||
class WinFuncParser(Parser):
|
||||
|
||||
known_io_info_type = ["__in", "__in_opt", "_In_", "_In_opt_", "_Inout_", "_Out_opt_", "_Out_", "_Reserved_", "_Inout_opt_", "__inout_opt", "__out", "__inout"]
|
||||
known_io_info_type = ["__in", "__in_opt", "_In_", "_In_opt_", "_Inout_", "_Out_opt_", "_Out_", "_Reserved_", "_Inout_opt_", "__inout_opt", "__out", "__inout", "__deref_out"]
|
||||
|
||||
def assert_argument_io_info(self):
|
||||
io_info = self.assert_token_type(NameToken)
|
||||
if io_info.value not in self.known_io_info_type:
|
||||
raise ParsingError("Was expection IO_INFO got {0} instead".format(io_info))
|
||||
return io_info
|
||||
|
||||
|
||||
def parse_func_arg(self, has_winapi):
|
||||
type_ptr = False
|
||||
if has_winapi:
|
||||
@@ -52,23 +52,23 @@ class WinFuncParser(Parser):
|
||||
arg_type = self.assert_token_type(NameToken)
|
||||
if arg_type.value.upper() == "CONST":
|
||||
arg_type = self.assert_token_type(NameToken)
|
||||
|
||||
|
||||
if type(self.peek()) == StarToken:
|
||||
type_ptr = True
|
||||
self.assert_token_type(StarToken)
|
||||
self.assert_token_type(StarToken)
|
||||
arg_name = self.assert_token_type(NameToken)
|
||||
if not type(self.peek()) == CloseParenthesisToken:
|
||||
self.assert_token_type(CommaToken)
|
||||
if not type_ptr:
|
||||
return (arg_type.value, arg_name.value)
|
||||
return ("POINTER({0})".format(arg_type.value), arg_name.value)
|
||||
|
||||
|
||||
def assert_winapi_token(self):
|
||||
winapi = self.assert_token_type(NameToken)
|
||||
if winapi.value != "WINAPI":
|
||||
raise ParsingError("Was expection NameToken(WINAPI) got {0} instead".format(winapi))
|
||||
return winapi
|
||||
|
||||
return winapi
|
||||
|
||||
def parse_winfunc(self):
|
||||
has_winapi = False
|
||||
try:
|
||||
@@ -80,7 +80,7 @@ class WinFuncParser(Parser):
|
||||
if func_name.upper() == "WINAPI":
|
||||
has_winapi = True
|
||||
func_name = self.assert_token_type(NameToken).value
|
||||
|
||||
|
||||
self.assert_token_type(OpenParenthesisToken)
|
||||
|
||||
params = []
|
||||
@@ -96,9 +96,9 @@ class WinFuncParser(Parser):
|
||||
while self.peek() is not None:
|
||||
res.append(self.parse_winfunc())
|
||||
return res
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def dbg_lexer(data):
|
||||
for i in Lexer(data).token_generation():
|
||||
@@ -109,11 +109,11 @@ def dbg_parser(data):
|
||||
|
||||
def dbg_validate(data):
|
||||
return validate_structs(Parser(data).parse())
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
data = open(sys.argv[1], 'r').read()
|
||||
funcs = generate_ctypes(data)
|
||||
print(funcs)
|
||||
print(funcs)
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
import sys
|
||||
import os
|
||||
import os.path
|
||||
import re
|
||||
import glob
|
||||
|
||||
import dummy_wintypes
|
||||
import struct_parser
|
||||
import func_parser
|
||||
import def_parser
|
||||
import com_parser
|
||||
|
||||
|
||||
|
||||
TYPE_EQUIVALENCE = [
|
||||
@@ -19,43 +23,84 @@ TYPE_EQUIVALENCE = [
|
||||
('PDWORD', 'POINTER(DWORD)'),
|
||||
('LPDWORD', 'POINTER(DWORD)'),
|
||||
('LPTHREAD_START_ROUTINE', 'PVOID'),
|
||||
('WNDENUMPROC', 'PVOID'),
|
||||
('PHANDLER_ROUTINE', 'PVOID'),
|
||||
('LPBYTE', 'POINTER(BYTE)'),
|
||||
('ULONG_PTR','PULONG'),
|
||||
('ULONG_PTR','PVOID'),
|
||||
('KAFFINITY','ULONG_PTR'),
|
||||
('KPRIORITY','LONG'),
|
||||
('CHAR', 'c_char'),
|
||||
('INT', 'c_int'),
|
||||
('UCHAR', 'c_char'),
|
||||
('CSHORT', 'c_short'),
|
||||
('VARTYPE', 'c_ushort'),
|
||||
('BSTR', 'c_wchar_p'),
|
||||
('OLECHAR', 'c_wchar'),
|
||||
('POLECHAR', 'c_wchar_p'),
|
||||
('PUCHAR', 'POINTER(UCHAR)'),
|
||||
('double', 'c_double'),
|
||||
('FARPROC', 'PVOID'),
|
||||
('HGLOBAL', 'PVOID'),
|
||||
('PSID', 'PVOID'),
|
||||
('PVECTORED_EXCEPTION_HANDLER', 'PVOID'),
|
||||
#('HRESULT', 'c_long'), # VERY BAD : real HRESULT raise by itself -> way better
|
||||
('ULONGLONG', 'c_ulonglong'),
|
||||
('LONGLONG', 'c_longlong'),
|
||||
('ULONG64', 'c_ulonglong'),
|
||||
('LARGE_INTEGER', 'LONGLONG'),
|
||||
('PLARGE_INTEGER', 'POINTER(LARGE_INTEGER)'),
|
||||
('DWORD64', 'ULONG64'),
|
||||
('SCODE', 'LONG'),
|
||||
('CIMTYPE', 'LONG'),
|
||||
('NET_IFINDEX', 'ULONG'),
|
||||
('IF_INDEX', 'NET_IFINDEX'),
|
||||
('IFTYPE', 'ULONG'),
|
||||
('PULONG64', 'POINTER(ULONG64)'),
|
||||
('PUINT', 'POINTER(UINT)'),
|
||||
('PHANDLE', 'POINTER(HANDLE)'),
|
||||
('HKEY', 'HANDLE'),
|
||||
('HCATADMIN', 'HANDLE'),
|
||||
('HCATINFO', 'HANDLE'),
|
||||
('SC_HANDLE', 'HANDLE'),
|
||||
('LPHANDLE', 'POINTER(HANDLE)'),
|
||||
('PHKEY', 'POINTER(HKEY)'),
|
||||
('ACCESS_MASK', 'DWORD'),
|
||||
('REGSAM', 'ACCESS_MASK'),
|
||||
('SECURITY_CONTEXT_TRACKING_MODE', 'BOOLEAN'),
|
||||
("DISPID", "LONG"),
|
||||
("MEMBERID", "DISPID"),
|
||||
('PSECURITY_DESCRIPTOR', 'PVOID'),
|
||||
('LPUNKNOWN', 'POINTER(PVOID)'),
|
||||
# Will be changed at import time
|
||||
('LPCONTEXT', 'PVOID'),
|
||||
('HCERTSTORE', 'PVOID'),
|
||||
('HCRYPTMSG', 'PVOID'),
|
||||
('PALPC_PORT_ATTRIBUTES', 'PVOID'),
|
||||
]
|
||||
|
||||
# For functions returning void
|
||||
TYPE_EQUIVALENCE.append(('VOID', 'DWORD'))
|
||||
# TRICHE
|
||||
TYPE_EQUIVALENCE.append(('ITypeInfo', 'PVOID'))
|
||||
|
||||
|
||||
known_type = dummy_wintypes.names + list([x[0] for x in TYPE_EQUIVALENCE])
|
||||
known_type += ["void"]
|
||||
|
||||
|
||||
FUNC_FILE = "winfunc.txt"
|
||||
STRUCT_FILE = "winstruct.txt"
|
||||
DEF_FILE = "windef.txt"
|
||||
NTSTATUS_FILE = "ntstatus.txt"
|
||||
NAME_TO_IID_FILE = "interface_to_iid.txt"
|
||||
COM_INTERFACE_DIR_GLOB = "com/*.txt"
|
||||
|
||||
GENERATED_STRUCT_FILE = "winstructs"
|
||||
GENERATED_FUNC_FILE = "winfuncs"
|
||||
GENERATED_DEF_FILE = "windef"
|
||||
GENERATED_NTSTATUS_FILE = "ntstatus"
|
||||
GENERATED_COM_FILE = "interfaces"
|
||||
#GENERATED_NAME_TO_IID_FILE = "com_iid"
|
||||
|
||||
OUT_DIRS = ["..\windows\generated_def"]
|
||||
if len(sys.argv) > 1:
|
||||
@@ -80,7 +125,6 @@ def verif_funcs_type(funcs, structs, enums):
|
||||
for f in funcs:
|
||||
ret_type = f.return_type
|
||||
if ret_type not in known_type and ret_type not in all_struct_name:
|
||||
import pdb; pdb.set_trace()
|
||||
raise ValueError("UNKNOW RET TYPE {0}".format(ret_type))
|
||||
|
||||
for param_type, _ in f.params:
|
||||
@@ -88,9 +132,39 @@ def verif_funcs_type(funcs, structs, enums):
|
||||
if param_type.startswith("POINTER(") and param_type.endswith(")"):
|
||||
param_type = param_type[len("POINTER("): -1]
|
||||
if param_type not in known_type and param_type not in all_struct_name:
|
||||
import pdb; pdb.set_trace()
|
||||
raise ValueError("UNKNOW PARAM TYPE {0}".format(param_type))
|
||||
|
||||
|
||||
try:
|
||||
yolo_struct = [x[:-4] for x in os.listdir(r"C:\Users\hakril\Documents\Work\COM\dump")]
|
||||
except WindowsError:
|
||||
yolo_struct = []
|
||||
|
||||
def verif_com_interface_type(vtbls, struc, enum):
|
||||
all_struct_name = get_all_struct_name(structs, enums)
|
||||
all_interface_name = [vtbl.name for vtbl in vtbls]
|
||||
|
||||
for vtbl in vtbls:
|
||||
#print(vtbl)
|
||||
for method in vtbl.methods:
|
||||
#print("Checking ret type <{0}>".format(method.ret_type))
|
||||
ret_type = method.ret_type
|
||||
if ret_type not in known_type and ret_type not in all_struct_name + all_interface_name:
|
||||
raise ValueError("UNKNOW RET TYPE {0}".format(ret_type))
|
||||
for arg in method.args:
|
||||
#print("Checking arg type <{0}>".format(arg.type))
|
||||
param_type = arg.type
|
||||
if param_type not in known_type and param_type not in all_struct_name + all_interface_name:
|
||||
#if param_type != "ITypeInfo":
|
||||
if param_type in yolo_struct:
|
||||
import pdb;pdb.set_trace()
|
||||
print("Ned to extract <{0}> from dump".format(param_type))
|
||||
import shutil
|
||||
#shutil.copy(r"C:\Users\hakril\Documents\Work\COM\dump\{0}.txt".format(param_type), "com")
|
||||
continue
|
||||
raise ValueError("UNKNOW PARAM TYPE {0}".format(param_type))
|
||||
|
||||
|
||||
def check_in_define(name, defs):
|
||||
return any(name == d.name for d in defs)
|
||||
|
||||
@@ -99,7 +173,6 @@ def validate_structs(structs, enums, defs):
|
||||
for struct in structs:
|
||||
for field_type, field_name, nb_rep in struct.fields:
|
||||
if field_type.name not in known_type + all_struct_name:
|
||||
import pdb; pdb.set_trace()
|
||||
raise ValueError("UNKNOW TYPE {0}".format(field_type))
|
||||
try:
|
||||
int(nb_rep)
|
||||
@@ -111,9 +184,15 @@ common_header = "#Generated file\n"
|
||||
|
||||
defs_header = common_header + """
|
||||
import sys
|
||||
import platform
|
||||
if sys.version_info.major == 3:
|
||||
long = int
|
||||
|
||||
bits = platform.architecture()[0]
|
||||
bitness = int(bits[:2])
|
||||
|
||||
NATIVE_WORD_MAX_VALUE = 0xffffffff if bitness == 32 else 0xffffffffffffffff
|
||||
|
||||
class Flag(long):
|
||||
def __new__(cls, name, value):
|
||||
return super(Flag, cls).__new__(cls, value)
|
||||
@@ -154,6 +233,34 @@ from ctypes import *
|
||||
from ctypes.wintypes import *
|
||||
from .windef import *
|
||||
|
||||
class EnumValue(Flag):
|
||||
def __new__(cls, enum_name, name, value):
|
||||
return super(EnumValue, cls).__new__(cls, name, value)
|
||||
|
||||
def __init__(self, enum_name, name, value):
|
||||
self.enum_name = enum_name
|
||||
self.name = name
|
||||
|
||||
def __repr__(self):
|
||||
return "{0}.{1}({2})".format(self.enum_name, self.name, hex(self))
|
||||
|
||||
|
||||
class EnumType(DWORD):
|
||||
values = ()
|
||||
mapper = {}
|
||||
|
||||
@property
|
||||
def value(self):
|
||||
raw_value = super(EnumType, self).value
|
||||
return self.mapper.get(raw_value, raw_value)
|
||||
|
||||
def __repr__(self):
|
||||
raw_value = super(EnumType, self).value
|
||||
if raw_value in self.values:
|
||||
value = self.value
|
||||
return "<{0} {1}({2})>".format(type(self).__name__, value.name, hex(raw_value))
|
||||
return "<{0}({1})>".format(type(self).__name__, hex(self.value))
|
||||
|
||||
"""[1:]
|
||||
|
||||
def generate_struct_ctypes(structs, enums):
|
||||
@@ -178,12 +285,127 @@ def generate_struct_ctypes(structs, enums):
|
||||
|
||||
return ctypes_str
|
||||
|
||||
|
||||
data = open(NAME_TO_IID_FILE).read()
|
||||
iids_def = {}
|
||||
for line in data.split("\n"):
|
||||
name, iid = line.split("|")
|
||||
part_iid = iid.split("-")
|
||||
str_iid = []
|
||||
str_iid.append("0x" + part_iid[0])
|
||||
str_iid.append("0x" + part_iid[1])
|
||||
str_iid.append("0x" + part_iid[2])
|
||||
str_iid.append("0x" + part_iid[3][:2])
|
||||
str_iid.append("0x" + part_iid[3][2:])
|
||||
for i in range(6): str_iid.append("0x" + part_iid[4][i * 2:(i + 1) * 2])
|
||||
iids_def[name] = ", ".join(str_iid), iid
|
||||
#full_name_to_iid = name_to_iid_header + "\n".join(iids_def)
|
||||
|
||||
|
||||
com_interface_header = """
|
||||
import functools
|
||||
import ctypes
|
||||
from winstructs import *
|
||||
|
||||
class IID(IID):
|
||||
def __init__(self, Data1, Data2, Data3, Data4, name=None, strid=None):
|
||||
self.name = name
|
||||
self.strid = strid
|
||||
super(IID, self).__init__(Data1, Data2, Data3, Data4)
|
||||
|
||||
def __repr__(self):
|
||||
if self.strid is None:
|
||||
return super(IID, self).__repr__()
|
||||
if self.name is None:
|
||||
return '<IID "{0}">'.format(self.strid.upper())
|
||||
return '<IID "{0}({1})">'.format(self.strid.upper(), self.name)
|
||||
|
||||
@classmethod
|
||||
def from_string(cls, iid):
|
||||
part_iid = iid.split("-")
|
||||
datas = [int(x, 16) for x in part_iid[:3]]
|
||||
datas.append(int(part_iid[3][:2], 16))
|
||||
datas.append(int(part_iid[3][2:], 16))
|
||||
for i in range(6):
|
||||
datas.append(int(part_iid[4][i * 2:(i + 1) * 2], 16))
|
||||
return cls.from_raw(*datas, strid=iid)
|
||||
|
||||
@classmethod
|
||||
def from_raw(cls, Data1, Data2, Data3, Data41, Data42, Data43, Data44, Data45, Data46, Data47, Data48, **kwargs):
|
||||
return cls(Data1, Data2, Data3, (BYTE*8)(Data41, Data42, Data43, Data44, Data45, Data46, Data47, Data48), **kwargs)
|
||||
|
||||
generate_IID = IID.from_raw
|
||||
|
||||
|
||||
class COMInterface(ctypes.c_void_p):
|
||||
_functions_ = {
|
||||
}
|
||||
|
||||
def __getattr__(self, name):
|
||||
if name in self._functions_:
|
||||
return functools.partial(self._functions_[name], self)
|
||||
return super(COMInterface, self).__getattribute__(name)
|
||||
"""
|
||||
|
||||
com_interface_template = """
|
||||
class {0}(COMInterface):
|
||||
IID = generate_IID({2}, name="{0}", strid="{3}")
|
||||
|
||||
_functions_ = {{
|
||||
{1}
|
||||
}}
|
||||
"""
|
||||
|
||||
com_interface_comment_template = """ #{0} -> {1}"""
|
||||
com_interface_method_template = """ "{0}": ctypes.WINFUNCTYPE({1})({2}, "{0}"),"""
|
||||
|
||||
def generate_com_interface_ctype(vtbls):
|
||||
define = []
|
||||
all_name = [vtbl.name for vtbl in vtbls]
|
||||
for vtbl in vtbls:
|
||||
methods_string = []
|
||||
for method_nb, method in enumerate(vtbl.methods):
|
||||
args_to_define = method.args[1:] #ctypes doesnt not need the This
|
||||
#import pdb;pdb.set_trace()
|
||||
str_args = []
|
||||
methods_string.append(com_interface_comment_template.format(method.name, ", ".join([arg.name +":"+ ("*"* arg.byreflevel) +arg.type for arg in args_to_define])))
|
||||
for arg in args_to_define:
|
||||
type = arg.type
|
||||
byreflevel = arg.byreflevel
|
||||
if type in all_name:
|
||||
type = "PVOID"
|
||||
byreflevel -= 1
|
||||
if type == "void":
|
||||
type = "PVOID"
|
||||
if byreflevel == 0:
|
||||
raise ValueError("{0}.{1} take a parameter <void>".format(vtbl.name, method.name))
|
||||
byreflevel -= 1
|
||||
for i in range(byreflevel):
|
||||
type = "POINTER({0})".format(type)
|
||||
str_args.append(type)
|
||||
methods_string.append(com_interface_method_template.format(method.name, ", ".join([method.ret_type] + str_args), method_nb))
|
||||
#import pdb;pdb.set_trace()
|
||||
iid_python, iid_str = iids_def[vtbl.name]
|
||||
define.append((com_interface_template.format(vtbl.name, "\n".join(methods_string), iid_python, iid_str)))
|
||||
return com_interface_header + "\n".join(define)
|
||||
|
||||
def write_to_out_file(name, data):
|
||||
for out_dir in OUT_DIRS:
|
||||
f = open("{0}/{1}.py".format(out_dir, name), 'w')
|
||||
f.write(data)
|
||||
f.close()
|
||||
|
||||
|
||||
def parse_com_interfaces(filenames):
|
||||
res = []
|
||||
for filename in filenames:
|
||||
print("Parsing COM from <{0}>".format(filename))
|
||||
data = open(filename).read()
|
||||
vtbl = com_parser.WinComParser(data).parse()
|
||||
res.append(vtbl)
|
||||
return res
|
||||
|
||||
|
||||
def_code = open(DEF_FILE, 'r').read()
|
||||
funcs_code = open(FUNC_FILE, 'r').read()
|
||||
structs_code = open(STRUCT_FILE, 'r').read()
|
||||
@@ -191,14 +413,36 @@ structs_code = open(STRUCT_FILE, 'r').read()
|
||||
defs = def_parser.WinDefParser(def_code).parse()
|
||||
funcs = func_parser.WinFuncParser(funcs_code).parse()
|
||||
structs, enums = struct_parser.WinStructParser(structs_code).parse()
|
||||
|
||||
vtbls = parse_com_interfaces(glob.glob(COM_INTERFACE_DIR_GLOB))
|
||||
|
||||
validate_structs(structs, enums, defs)
|
||||
verif_funcs_type(funcs, structs, enums)
|
||||
verif_com_interface_type(vtbls, structs, enums)
|
||||
|
||||
|
||||
# Create Flags for ntstatus
|
||||
nt_status_defs = []
|
||||
for line in open(NTSTATUS_FILE):
|
||||
code, name, descr = line.split("|", 2)
|
||||
nt_status_defs.append(def_parser.WinDef(name, code))
|
||||
defs = nt_status_defs + defs
|
||||
|
||||
defs_ctypes = generate_defs_ctypes(defs)
|
||||
funcs_ctypes = generate_funcs_ctypes(funcs)
|
||||
structs_ctypes = generate_struct_ctypes(structs, enums)
|
||||
com_interface_ctypes = generate_com_interface_ctype(vtbls)
|
||||
|
||||
# Create name -> IID file
|
||||
|
||||
name_to_iid_header = """
|
||||
from winstructs import IID, BYTE
|
||||
|
||||
"""
|
||||
|
||||
|
||||
#f = open("yolo.py", "w")
|
||||
#f.write(com_interface_ctypes)
|
||||
#f.close()
|
||||
|
||||
for out_dir in OUT_DIRS:
|
||||
if not os.path.exists(out_dir):
|
||||
@@ -207,6 +451,44 @@ for out_dir in OUT_DIRS:
|
||||
write_to_out_file(GENERATED_DEF_FILE, defs_ctypes)
|
||||
write_to_out_file(GENERATED_FUNC_FILE, funcs_ctypes)
|
||||
write_to_out_file(GENERATED_STRUCT_FILE, structs_ctypes)
|
||||
write_to_out_file(GENERATED_COM_FILE, com_interface_ctypes)
|
||||
#write_to_out_file(GENERATED_NAME_TO_IID_FILE, full_name_to_iid)
|
||||
|
||||
NTSTATUS_HEAD = """
|
||||
class NtStatusException(Exception):
|
||||
ALL_STATUS = {}
|
||||
def __init__(self , code):
|
||||
try:
|
||||
x = self.ALL_STATUS[code]
|
||||
except KeyError:
|
||||
x = (code, 'UNKNOW_ERROR', 'Error non documented in ntstatus.py')
|
||||
self.code = x[0]
|
||||
self.name = x[1]
|
||||
self.descr = x[2]
|
||||
|
||||
return super(NtStatusException, self).__init__(*x)
|
||||
|
||||
def __str__(self):
|
||||
return "{e.name}(0x{e.code:x}): {e.descr}".format(e=self)
|
||||
|
||||
@classmethod
|
||||
def register_ntstatus(cls, code, name, descr):
|
||||
if code in cls.ALL_STATUS:
|
||||
return # Use the first def
|
||||
cls.ALL_STATUS[code] = (code, name, descr)
|
||||
"""
|
||||
|
||||
nt_status_exceptions = [NTSTATUS_HEAD]
|
||||
for line in open(NTSTATUS_FILE):
|
||||
code, name, descr = line.split("|", 2)
|
||||
code = int(code, 0)
|
||||
b = descr
|
||||
descr = re.sub(" +", " ", descr[:-1]) # remove \n
|
||||
descr = descr.replace('"', "'")
|
||||
nt_status_exceptions.append('NtStatusException.register_ntstatus({0}, "{1}", "{2}")'.format(hex(code), name, descr))
|
||||
|
||||
|
||||
write_to_out_file(GENERATED_NTSTATUS_FILE, "\n".join(nt_status_exceptions))
|
||||
|
||||
for out_dir in OUT_DIRS:
|
||||
print("Files generated in <{0}>".format(os.path.abspath(out_dir)))
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -67,7 +67,7 @@ class EqualToken(NoValueToken):
|
||||
pass
|
||||
|
||||
class Lexer(object):
|
||||
keywords = ["typedef", "struct", "enum", "union"]
|
||||
keywords = ["typedef", "struct", "enum", "union", "const"]
|
||||
|
||||
token_chr = {"*" : StarToken, "[" : OpenSquareBracketToken, "]" : CloseSquareBracketToken,
|
||||
"{" : OpenBracketToken, "}" : CloseBracketToken, ";" : ColonToken,
|
||||
|
||||
@@ -14,7 +14,7 @@ class WinStructParser(Parser):
|
||||
def parse_def(self):
|
||||
if self.peek() == KeywordToken("struct"):
|
||||
discard = self.next_token()
|
||||
|
||||
|
||||
def_type_tok = self.assert_token_type(NameToken)
|
||||
def_type = WinStructType(def_type_tok.value)
|
||||
if type(self.peek()) == StarToken:
|
||||
@@ -26,7 +26,7 @@ class WinStructParser(Parser):
|
||||
if type(self.peek()) == ColonToken:
|
||||
self.next_token()
|
||||
return (def_type, def_name, 1)
|
||||
|
||||
|
||||
number_rep = self.parse_array()
|
||||
self.assert_token_type(ColonToken)
|
||||
return (def_type, def_name, number_rep)
|
||||
@@ -65,7 +65,7 @@ class WinStructParser(Parser):
|
||||
else:
|
||||
if assigned_value:
|
||||
raise ParsingError("Enum {0} mix def with and without equal".format(enum_name))
|
||||
|
||||
|
||||
res_enum.add_enum_entry(i, name.value)
|
||||
if not type(self.peek()) == CloseBracketToken:
|
||||
self.assert_token_type(CommaToken)
|
||||
@@ -75,13 +75,17 @@ class WinStructParser(Parser):
|
||||
#other_name = self.assert_token_type(NameToken).value
|
||||
#res_enum.add_typedef(other_name)
|
||||
#self.assert_token_type(ColonToken)
|
||||
return res_enum
|
||||
|
||||
|
||||
|
||||
return res_enum
|
||||
|
||||
|
||||
|
||||
def parse_winstruct(self):
|
||||
self.assert_keyword("typedef")
|
||||
|
||||
is_typedef = False
|
||||
peeked = self.peek()
|
||||
if peeked == KeywordToken("typedef"):
|
||||
self.assert_keyword("typedef")
|
||||
is_typedef = True
|
||||
|
||||
def_type = self.assert_token_type(KeywordToken)
|
||||
if def_type.value == "enum":
|
||||
return self.parse_enum()
|
||||
@@ -93,14 +97,17 @@ class WinStructParser(Parser):
|
||||
raise ParsingError("Expecting union or struct got <{0}> instead".format(def_type.value))
|
||||
struct_name = self.assert_token_type(NameToken)
|
||||
self.assert_token_type(OpenBracketToken)
|
||||
|
||||
|
||||
result = WinDefType(struct_name.value)
|
||||
|
||||
while type(self.peek()) != CloseBracketToken:
|
||||
tok_type, tok_name, nb_rep = self.parse_def()
|
||||
result.add_field((tok_type, tok_name.value, nb_rep))
|
||||
self.assert_token_type(CloseBracketToken)
|
||||
self.parse_typedef(result)
|
||||
if is_typedef:
|
||||
self.parse_typedef(result)
|
||||
else:
|
||||
self.assert_token_type(ColonToken)
|
||||
return result
|
||||
|
||||
def parse(self):
|
||||
@@ -115,7 +122,7 @@ class WinStructParser(Parser):
|
||||
else:
|
||||
raise ValueError("Unknow returned type {0}".format(x))
|
||||
return strucs, enums
|
||||
|
||||
|
||||
def dbg_lexer(data):
|
||||
for i in Lexer(data).token_generation():
|
||||
print i
|
||||
@@ -125,9 +132,9 @@ def dbg_parser(data):
|
||||
|
||||
def dbg_validate(data):
|
||||
return validate_structs(Parser(data).parse())
|
||||
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
data = open(sys.argv[1], 'r').read()
|
||||
ctypes_code = generate_ctypes(data)
|
||||
#data = open(sys.argv[1], 'r').read()
|
||||
#ctypes_code = generate_ctypes(data)
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#define INVALID_HANDLE_VALUE ((-1) & NATIVE_WORD_MAX_VALUE)
|
||||
#define NULL 0
|
||||
#define MAX_PATH 260
|
||||
#define ANYSIZE_ARRAY 1
|
||||
@@ -11,6 +12,32 @@
|
||||
#define STD_ERROR_HANDLE -12
|
||||
|
||||
#define WARMING_NOT_SAME_FLAG_FOR_WINXP 0
|
||||
|
||||
#define PROCESS_TERMINATE (0x0001)
|
||||
#define PROCESS_CREATE_THREAD (0x0002)
|
||||
#define PROCESS_SET_SESSIONID (0x0004)
|
||||
#define PROCESS_VM_OPERATION (0x0008)
|
||||
#define PROCESS_VM_READ (0x0010)
|
||||
#define PROCESS_VM_WRITE (0x0020)
|
||||
#define PROCESS_DUP_HANDLE (0x0040)
|
||||
#define PROCESS_CREATE_PROCESS (0x0080)
|
||||
#define PROCESS_SET_QUOTA (0x0100)
|
||||
#define PROCESS_SET_INFORMATION (0x0200)
|
||||
#define PROCESS_QUERY_INFORMATION (0x0400)
|
||||
#define PROCESS_SUSPEND_RESUME (0x0800)
|
||||
#define PROCESS_QUERY_LIMITED_INFORMATION (0x1000)
|
||||
|
||||
#define THREAD_TERMINATE (0x0001)
|
||||
#define THREAD_SUSPEND_RESUME (0x0002)
|
||||
#define THREAD_GET_CONTEXT (0x0008)
|
||||
#define THREAD_SET_CONTEXT (0x0010)
|
||||
#define THREAD_QUERY_INFORMATION (0x0040)
|
||||
#define THREAD_SET_INFORMATION (0x0020)
|
||||
#define THREAD_SET_THREAD_TOKEN (0x0080)
|
||||
#define THREAD_IMPERSONATE (0x0100)
|
||||
#define THREAD_DIRECT_IMPERSONATION (0x0200)
|
||||
|
||||
|
||||
#define PROCESS_ALL_ACCESS 0x001F0FFF
|
||||
#define THREAD_ALL_ACCESS 0x001F03FF
|
||||
|
||||
@@ -556,3 +583,425 @@
|
||||
#define REG_RESOURCE_REQUIREMENTS_LIST ( 10 )
|
||||
#define REG_QWORD ( 11 )
|
||||
#define REG_QWORD_LITTLE_ENDIAN ( 11 )
|
||||
|
||||
|
||||
#define IMAGE_FILE_RELOCS_STRIPPED 0x0001
|
||||
#define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002
|
||||
#define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004
|
||||
#define IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008
|
||||
#define IMAGE_FILE_AGGRESIVE_WS_TRIM 0x0010
|
||||
#define IMAGE_FILE_LARGE_ADDRESS_AWARE 0x0020
|
||||
#define IMAGE_FILE_BYTES_REVERSED_LO 0x0080
|
||||
#define IMAGE_FILE_32BIT_MACHINE 0x0100
|
||||
#define IMAGE_FILE_DEBUG_STRIPPED 0x0200
|
||||
#define IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP 0x0400
|
||||
#define IMAGE_FILE_NET_RUN_FROM_SWAP 0x0800
|
||||
#define IMAGE_FILE_SYSTEM 0x1000
|
||||
#define IMAGE_FILE_DLL 0x2000
|
||||
#define IMAGE_FILE_UP_SYSTEM_ONLY 0x4000
|
||||
#define IMAGE_FILE_BYTES_REVERSED_HI 0x8000
|
||||
|
||||
#define IMAGE_FILE_MACHINE_UNKNOWN 0
|
||||
#define IMAGE_FILE_MACHINE_I386 0x014c
|
||||
#define IMAGE_FILE_MACHINE_R3000 0x0162
|
||||
#define IMAGE_FILE_MACHINE_R4000 0x0166
|
||||
#define IMAGE_FILE_MACHINE_R10000 0x0168
|
||||
#define IMAGE_FILE_MACHINE_WCEMIPSV2 0x0169
|
||||
#define IMAGE_FILE_MACHINE_ALPHA 0x0184
|
||||
#define IMAGE_FILE_MACHINE_SH3 0x01a2
|
||||
#define IMAGE_FILE_MACHINE_SH3DSP 0x01a3
|
||||
#define IMAGE_FILE_MACHINE_SH3E 0x01a4
|
||||
#define IMAGE_FILE_MACHINE_SH4 0x01a6
|
||||
#define IMAGE_FILE_MACHINE_SH5 0x01a8
|
||||
#define IMAGE_FILE_MACHINE_ARM 0x01c0
|
||||
#define IMAGE_FILE_MACHINE_THUMB 0x01c2
|
||||
#define IMAGE_FILE_MACHINE_ARMNT 0x01c4
|
||||
#define IMAGE_FILE_MACHINE_AM33 0x01d3
|
||||
#define IMAGE_FILE_MACHINE_POWERPC 0x01F0
|
||||
#define IMAGE_FILE_MACHINE_POWERPCFP 0x01f1
|
||||
#define IMAGE_FILE_MACHINE_IA64 0x0200
|
||||
#define IMAGE_FILE_MACHINE_MIPS16 0x0266
|
||||
#define IMAGE_FILE_MACHINE_ALPHA64 0x0284
|
||||
#define IMAGE_FILE_MACHINE_MIPSFPU 0x0366
|
||||
#define IMAGE_FILE_MACHINE_MIPSFPU16 0x0466
|
||||
#define IMAGE_FILE_MACHINE_AXP64 IMAGE_FILE_MACHINE_ALPHA64
|
||||
#define IMAGE_FILE_MACHINE_TRICORE 0x0520
|
||||
#define IMAGE_FILE_MACHINE_CEF 0x0CEF
|
||||
#define IMAGE_FILE_MACHINE_EBC 0x0EBC
|
||||
#define IMAGE_FILE_MACHINE_AMD64 0x8664
|
||||
#define IMAGE_FILE_MACHINE_M32R 0x9041
|
||||
#define IMAGE_FILE_MACHINE_CEE 0xC0EE
|
||||
|
||||
|
||||
|
||||
#define SECURITY_MANDATORY_UNTRUSTED_RID (0x00000000L)
|
||||
#define SECURITY_MANDATORY_LOW_RID (0x00001000L)
|
||||
#define SECURITY_MANDATORY_MEDIUM_RID (0x00002000L)
|
||||
#define SECURITY_MANDATORY_MEDIUM_PLUS_RID (SECURITY_MANDATORY_MEDIUM_RID + 0x100)
|
||||
#define SECURITY_MANDATORY_HIGH_RID (0x00003000L)
|
||||
#define SECURITY_MANDATORY_SYSTEM_RID (0x00004000L)
|
||||
#define SECURITY_MANDATORY_PROTECTED_PROCESS_RID (0x00005000L)
|
||||
|
||||
#define SECTION_QUERY 0x0001
|
||||
#define SECTION_MAP_WRITE 0x0002
|
||||
#define SECTION_MAP_READ 0x0004
|
||||
#define SECTION_MAP_EXECUTE 0x0008
|
||||
#define SECTION_EXTEND_SIZE 0x0010
|
||||
#define SECTION_MAP_EXECUTE_EXPLICIT 0x0020
|
||||
|
||||
|
||||
#define SECTION_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SECTION_QUERY| SECTION_MAP_WRITE | SECTION_MAP_READ | SECTION_MAP_EXECUTE | SECTION_EXTEND_SIZE)
|
||||
|
||||
#define FILE_MAP_COPY SECTION_QUERY
|
||||
#define FILE_MAP_WRITE SECTION_MAP_WRITE
|
||||
#define FILE_MAP_READ SECTION_MAP_READ
|
||||
#define FILE_MAP_ALL_ACCESS SECTION_ALL_ACCESS
|
||||
#define FILE_MAP_EXECUTE SECTION_MAP_EXECUTE_EXPLICIT
|
||||
|
||||
|
||||
#define SC_MANAGER_CONNECT 0x0001
|
||||
#define SC_MANAGER_CREATE_SERVICE 0x0002
|
||||
#define SC_MANAGER_ENUMERATE_SERVICE 0x0004
|
||||
#define SC_MANAGER_LOCK 0x0008
|
||||
#define SC_MANAGER_QUERY_LOCK_STATUS 0x0010
|
||||
#define SC_MANAGER_MODIFY_BOOT_CONFIG 0x0020
|
||||
|
||||
#define SC_MANAGER_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SC_MANAGER_CONNECT | SC_MANAGER_CREATE_SERVICE | SC_MANAGER_ENUMERATE_SERVICE | SC_MANAGER_LOCK | SC_MANAGER_QUERY_LOCK_STATUS | SC_MANAGER_MODIFY_BOOT_CONFIG)
|
||||
|
||||
#define SERVICE_QUERY_CONFIG 0x0001
|
||||
#define SERVICE_CHANGE_CONFIG 0x0002
|
||||
#define SERVICE_QUERY_STATUS 0x0004
|
||||
#define SERVICE_ENUMERATE_DEPENDENTS 0x0008
|
||||
#define SERVICE_START 0x0010
|
||||
#define SERVICE_STOP 0x0020
|
||||
#define SERVICE_PAUSE_CONTINUE 0x0040
|
||||
#define SERVICE_INTERROGATE 0x0080
|
||||
#define SERVICE_USER_DEFINED_CONTROL 0x0100
|
||||
|
||||
#define SERVICE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SERVICE_QUERY_CONFIG | SERVICE_CHANGE_CONFIG | SERVICE_QUERY_STATUS | SERVICE_ENUMERATE_DEPENDENTS | SERVICE_START | SERVICE_STOP | SERVICE_PAUSE_CONTINUE | SERVICE_INTERROGATE | SERVICE_USER_DEFINED_CONTROL)
|
||||
|
||||
|
||||
#define SERVICE_RUNS_IN_SYSTEM_PROCESS 0x00000001
|
||||
|
||||
|
||||
#define SERVICE_KERNEL_DRIVER 0x00000001
|
||||
#define SERVICE_FILE_SYSTEM_DRIVER 0x00000002
|
||||
#define SERVICE_ADAPTER 0x00000004
|
||||
#define SERVICE_RECOGNIZER_DRIVER 0x00000008
|
||||
|
||||
#define SERVICE_DRIVER (SERVICE_KERNEL_DRIVER | SERVICE_FILE_SYSTEM_DRIVER | SERVICE_RECOGNIZER_DRIVER)
|
||||
|
||||
#define SERVICE_WIN32_OWN_PROCESS 0x00000010
|
||||
#define SERVICE_WIN32_SHARE_PROCESS 0x00000020
|
||||
#define SERVICE_WIN32 (SERVICE_WIN32_OWN_PROCESS | SERVICE_WIN32_SHARE_PROCESS)
|
||||
|
||||
#define SERVICE_INTERACTIVE_PROCESS 0x00000100
|
||||
|
||||
#define SERVICE_TYPE_ALL (SERVICE_WIN32 | SERVICE_ADAPTER | SERVICE_DRIVER | SERVICE_INTERACTIVE_PROCESS)
|
||||
|
||||
|
||||
#define SERVICE_BOOT_START 0x00000000
|
||||
#define SERVICE_SYSTEM_START 0x00000001
|
||||
#define SERVICE_AUTO_START 0x00000002
|
||||
#define SERVICE_DEMAND_START 0x00000003
|
||||
#define SERVICE_DISABLED 0x00000004
|
||||
|
||||
#define SERVICE_ERROR_IGNORE 0x00000000
|
||||
#define SERVICE_ERROR_NORMAL 0x00000001
|
||||
#define SERVICE_ERROR_SEVERE 0x00000002
|
||||
#define SERVICE_ERROR_CRITICAL 0x00000003
|
||||
|
||||
#define SERVICE_ACTIVE 0x00000001
|
||||
#define SERVICE_INACTIVE 0x00000002
|
||||
#define SERVICE_STATE_ALL (SERVICE_ACTIVE | SERVICE_INACTIVE)
|
||||
|
||||
#define SERVICE_CONTROL_STOP 0x00000001
|
||||
#define SERVICE_CONTROL_PAUSE 0x00000002
|
||||
#define SERVICE_CONTROL_CONTINUE 0x00000003
|
||||
#define SERVICE_CONTROL_INTERROGATE 0x00000004
|
||||
#define SERVICE_CONTROL_SHUTDOWN 0x00000005
|
||||
#define SERVICE_CONTROL_PARAMCHANGE 0x00000006
|
||||
#define SERVICE_CONTROL_NETBINDADD 0x00000007
|
||||
#define SERVICE_CONTROL_NETBINDREMOVE 0x00000008
|
||||
#define SERVICE_CONTROL_NETBINDENABLE 0x00000009
|
||||
#define SERVICE_CONTROL_NETBINDDISABLE 0x0000000A
|
||||
#define SERVICE_CONTROL_DEVICEEVENT 0x0000000B
|
||||
#define SERVICE_CONTROL_HARDWAREPROFILECHANGE 0x0000000C
|
||||
#define SERVICE_CONTROL_POWEREVENT 0x0000000D
|
||||
#define SERVICE_CONTROL_SESSIONCHANGE 0x0000000E
|
||||
#define SERVICE_CONTROL_PRESHUTDOWN 0x0000000F
|
||||
#define SERVICE_CONTROL_TIMECHANGE 0x00000010
|
||||
#define SERVICE_CONTROL_TRIGGEREVENT 0x00000020
|
||||
|
||||
#define SERVICE_STOPPED 0x00000001
|
||||
#define SERVICE_START_PENDING 0x00000002
|
||||
#define SERVICE_STOP_PENDING 0x00000003
|
||||
#define SERVICE_RUNNING 0x00000004
|
||||
#define SERVICE_CONTINUE_PENDING 0x00000005
|
||||
#define SERVICE_PAUSE_PENDING 0x00000006
|
||||
#define SERVICE_PAUSED 0x00000007
|
||||
|
||||
|
||||
#define SERVICE_ACCEPT_STOP 0x00000001
|
||||
#define SERVICE_ACCEPT_PAUSE_CONTINUE 0x00000002
|
||||
#define SERVICE_ACCEPT_SHUTDOWN 0x00000004
|
||||
#define SERVICE_ACCEPT_PARAMCHANGE 0x00000008
|
||||
#define SERVICE_ACCEPT_NETBINDCHANGE 0x00000010
|
||||
#define SERVICE_ACCEPT_HARDWAREPROFILECHANGE 0x00000020
|
||||
#define SERVICE_ACCEPT_POWEREVENT 0x00000040
|
||||
#define SERVICE_ACCEPT_SESSIONCHANGE 0x00000080
|
||||
#define SERVICE_ACCEPT_PRESHUTDOWN 0x00000100
|
||||
#define SERVICE_ACCEPT_TIMECHANGE 0x00000200
|
||||
#define SERVICE_ACCEPT_TRIGGEREVENT 0x00000400
|
||||
|
||||
|
||||
#define DRIVE_UNKNOWN 0
|
||||
#define DRIVE_NO_ROOT_DIR 1
|
||||
#define DRIVE_REMOVABLE 2
|
||||
#define DRIVE_FIXED 3
|
||||
#define DRIVE_REMOTE 4
|
||||
#define DRIVE_CDROM 5
|
||||
#define DRIVE_RAMDISK 6
|
||||
|
||||
#define DUPLICATE_CLOSE_SOURCE 0x00000001
|
||||
#define DUPLICATE_SAME_ACCESS 0x00000002
|
||||
|
||||
#define VER_NT_WORKSTATION 0x0000001
|
||||
#define VER_NT_DOMAIN_CONTROLLER 0x0000002
|
||||
#define VER_NT_SERVER 0x0000003
|
||||
|
||||
#define SM_CXSCREEN 0
|
||||
#define SM_CYSCREEN 1
|
||||
#define SM_CXVSCROLL 2
|
||||
#define SM_CYHSCROLL 3
|
||||
#define SM_CYCAPTION 4
|
||||
#define SM_CXBORDER 5
|
||||
#define SM_CYBORDER 6
|
||||
#define SM_CXDLGFRAME 7
|
||||
#define SM_CYDLGFRAME 8
|
||||
#define SM_CYVTHUMB 9
|
||||
#define SM_CXHTHUMB 10
|
||||
#define SM_CXICON 11
|
||||
#define SM_CYICON 12
|
||||
#define SM_CXCURSOR 13
|
||||
#define SM_CYCURSOR 14
|
||||
#define SM_CYMENU 15
|
||||
#define SM_CXFULLSCREEN 16
|
||||
#define SM_CYFULLSCREEN 17
|
||||
#define SM_CYKANJIWINDOW 18
|
||||
#define SM_MOUSEPRESENT 19
|
||||
#define SM_CYVSCROLL 20
|
||||
#define SM_CXHSCROLL 21
|
||||
#define SM_DEBUG 22
|
||||
#define SM_SWAPBUTTON 23
|
||||
#define SM_RESERVED1 24
|
||||
#define SM_RESERVED2 25
|
||||
#define SM_RESERVED3 26
|
||||
#define SM_RESERVED4 27
|
||||
#define SM_CXMIN 28
|
||||
#define SM_CYMIN 29
|
||||
#define SM_CXSIZE 30
|
||||
#define SM_CYSIZE 31
|
||||
#define SM_CXFRAME 32
|
||||
#define SM_CYFRAME 33
|
||||
#define SM_CXMINTRACK 34
|
||||
#define SM_CYMINTRACK 35
|
||||
#define SM_CXDOUBLECLK 36
|
||||
#define SM_CYDOUBLECLK 37
|
||||
#define SM_CXICONSPACING 38
|
||||
#define SM_CYICONSPACING 39
|
||||
#define SM_MENUDROPALIGNMENT 40
|
||||
#define SM_PENWINDOWS 41
|
||||
#define SM_DBCSENABLED 42
|
||||
#define SM_CMOUSEBUTTONS 43
|
||||
#define SM_CXFIXEDFRAME SM_CXDLGFRAME
|
||||
#define SM_CYFIXEDFRAME SM_CYDLGFRAME
|
||||
#define SM_CXSIZEFRAME SM_CXFRAME
|
||||
#define SM_CYSIZEFRAME SM_CYFRAME
|
||||
#define SM_SECURE 44
|
||||
#define SM_CXEDGE 45
|
||||
#define SM_CYEDGE 46
|
||||
#define SM_CXMINSPACING 47
|
||||
#define SM_CYMINSPACING 48
|
||||
#define SM_CXSMICON 49
|
||||
#define SM_CYSMICON 50
|
||||
#define SM_CYSMCAPTION 51
|
||||
#define SM_CXSMSIZE 52
|
||||
#define SM_CYSMSIZE 53
|
||||
#define SM_CXMENUSIZE 54
|
||||
#define SM_CYMENUSIZE 55
|
||||
#define SM_ARRANGE 56
|
||||
#define SM_CXMINIMIZED 57
|
||||
#define SM_CYMINIMIZED 58
|
||||
#define SM_CXMAXTRACK 59
|
||||
#define SM_CYMAXTRACK 60
|
||||
#define SM_CXMAXIMIZED 61
|
||||
#define SM_CYMAXIMIZED 62
|
||||
#define SM_NETWORK 63
|
||||
#define SM_CLEANBOOT 67
|
||||
#define SM_CXDRAG 68
|
||||
#define SM_CYDRAG 69
|
||||
#define SM_SHOWSOUNDS 70
|
||||
#define SM_CXMENUCHECK 71
|
||||
#define SM_CYMENUCHECK 72
|
||||
#define SM_SLOWMACHINE 73
|
||||
#define SM_MIDEASTENABLED 74
|
||||
#define SM_MOUSEWHEELPRESENT 75
|
||||
#define SM_XVIRTUALSCREEN 76
|
||||
#define SM_YVIRTUALSCREEN 77
|
||||
#define SM_CXVIRTUALSCREEN 78
|
||||
#define SM_CYVIRTUALSCREEN 79
|
||||
#define SM_CMONITORS 80
|
||||
#define SM_SAMEDISPLAYFORMAT 81
|
||||
#define SM_IMMENABLED 82
|
||||
#define SM_CXFOCUSBORDER 83
|
||||
#define SM_CYFOCUSBORDER 84
|
||||
#define SM_TABLETPC 86
|
||||
#define SM_MEDIACENTER 87
|
||||
#define SM_STARTER 88
|
||||
#define SM_SERVERR2 89
|
||||
#define SM_MOUSEHORIZONTALWHEELPRESENT 91
|
||||
#define SM_CXPADDEDBORDER 92
|
||||
#define SM_DIGITIZER 94
|
||||
#define SM_MAXIMUMTOUCHES 95
|
||||
#define SM_REMOTESESSION 0x1000
|
||||
#define SM_SHUTTINGDOWN 0x2000
|
||||
#define SM_REMOTECONTROL 0x2001
|
||||
#define SM_CARETBLINKINGENABLED 0x2002
|
||||
|
||||
|
||||
#define RPC_C_AUTHN_LEVEL_DEFAULT 0
|
||||
#define RPC_C_AUTHN_LEVEL_NONE 1
|
||||
#define RPC_C_AUTHN_LEVEL_CONNECT 2
|
||||
#define RPC_C_AUTHN_LEVEL_CALL 3
|
||||
#define RPC_C_AUTHN_LEVEL_PKT 4
|
||||
#define RPC_C_AUTHN_LEVEL_PKT_INTEGRITY 5
|
||||
#define RPC_C_AUTHN_LEVEL_PKT_PRIVACY 6
|
||||
|
||||
#define RPC_C_IMP_LEVEL_DEFAULT 0
|
||||
#define RPC_C_IMP_LEVEL_ANONYMOUS 1
|
||||
#define RPC_C_IMP_LEVEL_IDENTIFY 2
|
||||
#define RPC_C_IMP_LEVEL_IMPERSONATE 3
|
||||
#define RPC_C_IMP_LEVEL_DELEGATE 4
|
||||
|
||||
#define RPC_C_QOS_IDENTITY_STATIC 0
|
||||
#define RPC_C_QOS_IDENTITY_DYNAMIC 1
|
||||
|
||||
#define RPC_C_QOS_CAPABILITIES_DEFAULT 0x0
|
||||
#define RPC_C_QOS_CAPABILITIES_MUTUAL_AUTH 0x1
|
||||
#define RPC_C_QOS_CAPABILITIES_MAKE_FULLSIC 0x2
|
||||
#define RPC_C_QOS_CAPABILITIES_ANY_AUTHORITY 0x4
|
||||
|
||||
#define MAX_ADAPTER_NAME 128
|
||||
|
||||
#define MAXLEN_PHYSADDR 8
|
||||
#define MAXLEN_IFDESCR 256
|
||||
#define MAX_INTERFACE_NAME_LEN 256
|
||||
|
||||
#define DIRECTORY_QUERY (0x0001)
|
||||
#define DIRECTORY_TRAVERSE (0x0002)
|
||||
#define DIRECTORY_CREATE_OBJECT (0x0004)
|
||||
#define DIRECTORY_CREATE_SUBDIRECTORY (0x0008)
|
||||
|
||||
#define DIRECTORY_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | 0xF)
|
||||
|
||||
#define OBJ_INHERIT 0x00000002L
|
||||
#define OBJ_PERMANENT 0x00000010L
|
||||
#define OBJ_EXCLUSIVE 0x00000020L
|
||||
#define OBJ_CASE_INSENSITIVE 0x00000040L
|
||||
#define OBJ_OPENIF 0x00000080L
|
||||
#define OBJ_OPENLINK 0x00000100L
|
||||
#define OBJ_KERNEL_HANDLE 0x00000200L
|
||||
#define OBJ_FORCE_ACCESS_CHECK 0x00000400L
|
||||
#define OBJ_VALID_ATTRIBUTES 0x000007F2L
|
||||
|
||||
|
||||
#define FILE_SUPERSEDE 0x00000000
|
||||
#define FILE_OPEN 0x00000001
|
||||
#define FILE_CREATE 0x00000002
|
||||
#define FILE_OPEN_IF 0x00000003
|
||||
#define FILE_OVERWRITE 0x00000004
|
||||
#define FILE_OVERWRITE_IF 0x00000005
|
||||
#define FILE_MAXIMUM_DISPOSITION 0x00000005
|
||||
|
||||
#define TRUST_E_PROVIDER_UNKNOWN (0x800B0001L)
|
||||
#define TRUST_E_ACTION_UNKNOWN (0x800B0002L)
|
||||
#define TRUST_E_SUBJECT_FORM_UNKNOWN (0x800B0003L)
|
||||
#define DIGSIG_E_ENCODE (0x800B0005L)
|
||||
#define TRUST_E_SUBJECT_NOT_TRUSTED (0x800B0004L)
|
||||
#define DIGSIG_E_DECODE (0x800B0006L)
|
||||
#define DIGSIG_E_EXTENSIBILITY (0x800B0007L)
|
||||
#define PERSIST_E_SIZEDEFINITE (0x800B0009L)
|
||||
#define DIGSIG_E_CRYPTO (0x800B0008L)
|
||||
#define PERSIST_E_SIZEINDEFINITE (0x800B000AL)
|
||||
#define PERSIST_E_NOTSELFSIZING (0x800B000BL)
|
||||
#define TRUST_E_NOSIGNATURE (0x800B0100L)
|
||||
#define CERT_E_EXPIRED (0x800B0101L)
|
||||
#define CERT_E_VALIDITYPERIODNESTING (0x800B0102L)
|
||||
#define CERT_E_PURPOSE (0x800B0106L)
|
||||
#define CERT_E_ISSUERCHAINING (0x800B0107L)
|
||||
#define CERT_E_MALFORMED (0x800B0108L)
|
||||
#define CERT_E_UNTRUSTEDROOT (0x800B0109L)
|
||||
#define CERT_E_CHAINING (0x800B010AL)
|
||||
#define TRUST_E_FAIL (0x800B010BL)
|
||||
#define CERT_E_REVOKED (0x800B010CL)
|
||||
#define CERT_E_UNTRUSTEDTESTROOT (0x800B010DL)
|
||||
#define CERT_E_REVOCATION_FAILURE (0x800B010EL)
|
||||
#define CERT_E_CN_NO_MATCH (0x800B010FL)
|
||||
#define CERT_E_WRONG_USAGE (0x800B0110L)
|
||||
#define TRUST_E_EXPLICIT_DISTRUST (0x800B0111L)
|
||||
#define CERT_E_UNTRUSTEDCA (0x800B0112L)
|
||||
#define CERT_E_INVALID_POLICY (0x800B0113L)
|
||||
#define CERT_E_INVALID_NAME (0x800B0114L)
|
||||
#define CRYPT_E_FILE_ERROR (0x80092003L)
|
||||
|
||||
|
||||
|
||||
#define IMAGE_SCN_TYPE_REG 0x00000000
|
||||
#define IMAGE_SCN_TYPE_DSECT 0x00000001
|
||||
#define IMAGE_SCN_TYPE_NOLOAD 0x00000002
|
||||
#define IMAGE_SCN_TYPE_GROUP 0x00000004
|
||||
#define IMAGE_SCN_TYPE_NO_PAD 0x00000008
|
||||
#define IMAGE_SCN_TYPE_COPY 0x00000010
|
||||
|
||||
#define IMAGE_SCN_CNT_CODE 0x00000020
|
||||
#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040
|
||||
#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080
|
||||
|
||||
#define IMAGE_SCN_LNK_OTHER 0x00000100
|
||||
#define IMAGE_SCN_LNK_INFO 0x00000200
|
||||
#define IMAGE_SCN_TYPE_OVER 0x00000400
|
||||
#define IMAGE_SCN_LNK_REMOVE 0x00000800
|
||||
#define IMAGE_SCN_LNK_COMDAT 0x00001000
|
||||
#define IMAGE_SCN_NO_DEFER_SPEC_EXC 0x00004000
|
||||
#define IMAGE_SCN_GPREL 0x00008000
|
||||
#define IMAGE_SCN_MEM_FARDATA 0x00008000
|
||||
#define IMAGE_SCN_MEM_PURGEABLE 0x00020000
|
||||
#define IMAGE_SCN_MEM_16BIT 0x00020000
|
||||
#define IMAGE_SCN_MEM_LOCKED 0x00040000
|
||||
#define IMAGE_SCN_MEM_PRELOAD 0x00080000
|
||||
|
||||
#define IMAGE_SCN_ALIGN_1BYTES 0x00100000
|
||||
#define IMAGE_SCN_ALIGN_2BYTES 0x00200000
|
||||
#define IMAGE_SCN_ALIGN_4BYTES 0x00300000
|
||||
#define IMAGE_SCN_ALIGN_8BYTES 0x00400000
|
||||
#define IMAGE_SCN_ALIGN_16BYTES 0x00500000
|
||||
#define IMAGE_SCN_ALIGN_32BYTES 0x00600000
|
||||
#define IMAGE_SCN_ALIGN_64BYTES 0x00700000
|
||||
#define IMAGE_SCN_ALIGN_128BYTES 0x00800000
|
||||
#define IMAGE_SCN_ALIGN_256BYTES 0x00900000
|
||||
#define IMAGE_SCN_ALIGN_512BYTES 0x00A00000
|
||||
#define IMAGE_SCN_ALIGN_1024BYTES 0x00B00000
|
||||
#define IMAGE_SCN_ALIGN_2048BYTES 0x00C00000
|
||||
#define IMAGE_SCN_ALIGN_4096BYTES 0x00D00000
|
||||
#define IMAGE_SCN_ALIGN_8192BYTES 0x00E00000
|
||||
#define IMAGE_SCN_ALIGN_MASK 0x00F00000
|
||||
|
||||
#define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000
|
||||
#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000
|
||||
#define IMAGE_SCN_MEM_NOT_CACHED 0x04000000
|
||||
#define IMAGE_SCN_MEM_NOT_PAGED 0x08000000
|
||||
#define IMAGE_SCN_MEM_SHARED 0x10000000
|
||||
#define IMAGE_SCN_MEM_EXECUTE 0x20000000
|
||||
#define IMAGE_SCN_MEM_READ 0x40000000
|
||||
#define IMAGE_SCN_MEM_WRITE 0x80000000
|
||||
@@ -31,6 +31,12 @@ HANDLE WINAPI CreateFileW(
|
||||
__in_opt HANDLE hTemplateFile
|
||||
);
|
||||
|
||||
NTSTATUS WINAPI LdrLoadDll(
|
||||
__in_opt LPCWSTR PathToFile,
|
||||
__in_opt ULONG Flags,
|
||||
_In_ PUNICODE_STRING ModuleFileName,
|
||||
_Out_ PHANDLE ModuleHandle
|
||||
);
|
||||
|
||||
NTSTATUS WINAPI NtQuerySystemInformation(
|
||||
_In_ SYSTEM_INFORMATION_CLASS SystemInformationClass,
|
||||
@@ -39,6 +45,7 @@ NTSTATUS WINAPI NtQuerySystemInformation(
|
||||
_Out_opt_ PULONG ReturnLength
|
||||
);
|
||||
|
||||
|
||||
NTSTATUS WINAPI NtQueryInformationProcess(
|
||||
_In_ HANDLE ProcessHandle,
|
||||
_In_ PROCESSINFOCLASS ProcessInformationClass,
|
||||
@@ -103,6 +110,15 @@ LPVOID WINAPI VirtualAllocEx(
|
||||
_In_ DWORD flProtect
|
||||
);
|
||||
|
||||
NTSTATUS WINAPI NtProtectVirtualMemory(
|
||||
_In_ HANDLE ProcessHandle,
|
||||
_Inout_ PVOID *BaseAddress,
|
||||
_Inout_ PULONG NumberOfBytesToProtect,
|
||||
_In_ ULONG NewAccessProtection,
|
||||
_Out_ PULONG OldAccessProtection
|
||||
);
|
||||
|
||||
|
||||
BOOL WINAPI VirtualFree(
|
||||
_In_ LPVOID lpAddress,
|
||||
_In_ SIZE_T dwSize,
|
||||
@@ -123,6 +139,15 @@ BOOL WINAPI VirtualProtect(
|
||||
_Out_ PDWORD lpflOldProtect
|
||||
);
|
||||
|
||||
BOOL WINAPI VirtualProtectEx(
|
||||
_In_ HANDLE hProcess,
|
||||
_In_ LPVOID lpAddress,
|
||||
_In_ SIZE_T dwSize,
|
||||
_In_ DWORD flNewProtect,
|
||||
_Out_ PDWORD lpflOldProtect
|
||||
);
|
||||
|
||||
|
||||
DWORD VirtualQuery(
|
||||
LPCVOID lpAddress,
|
||||
PMEMORY_BASIC_INFORMATION lpBuffer,
|
||||
@@ -136,6 +161,18 @@ SIZE_T WINAPI VirtualQueryEx(
|
||||
_In_ SIZE_T dwLength
|
||||
);
|
||||
|
||||
BOOL WINAPI QueryWorkingSet(
|
||||
_In_ HANDLE hProcess,
|
||||
_Out_ PVOID pv,
|
||||
_In_ DWORD cb
|
||||
);
|
||||
|
||||
BOOL WINAPI QueryWorkingSetEx(
|
||||
_In_ HANDLE hProcess,
|
||||
_Inout_ PVOID pv,
|
||||
_In_ DWORD cb
|
||||
);
|
||||
|
||||
|
||||
DWORD WINAPI GetModuleFileNameA(
|
||||
_In_opt_ HMODULE hModule,
|
||||
@@ -216,6 +253,12 @@ BOOL WINAPI SetThreadContext(
|
||||
__in CONST LPCONTEXT lpContext
|
||||
);
|
||||
|
||||
BOOL WINAPI NtSetContextThread(
|
||||
__in HANDLE hThread,
|
||||
__in CONST LPCONTEXT lpContext
|
||||
);
|
||||
|
||||
|
||||
HANDLE WINAPI OpenThread(
|
||||
__in DWORD dwDesiredAccess,
|
||||
__in BOOL bInheritHandle,
|
||||
@@ -256,6 +299,14 @@ BOOL WINAPI WriteProcessMemory(
|
||||
_Out_ SIZE_T *lpNumberOfBytesWritten
|
||||
);
|
||||
|
||||
BOOL WINAPI NtWow64WriteVirtualMemory64(
|
||||
_In_ HANDLE hProcess,
|
||||
_In_ ULONG64 lpBaseAddress,
|
||||
_Out_ LPVOID lpBuffer,
|
||||
_In_ ULONG64 nSize,
|
||||
_Out_ PULONG64 *lpNumberOfBytesWritten
|
||||
);
|
||||
|
||||
HANDLE WINAPI CreateToolhelp32Snapshot(
|
||||
_In_ DWORD dwFlags,
|
||||
_In_ DWORD th32ProcessID
|
||||
@@ -653,4 +704,605 @@ LONG WINAPI WinVerifyTrust(
|
||||
_In_ HWND hWnd,
|
||||
_In_ GUID *pgActionID,
|
||||
_In_ LPVOID pWVTData
|
||||
);
|
||||
);
|
||||
|
||||
BOOL WINAPI OpenProcessToken (
|
||||
__in HANDLE ProcessHandle,
|
||||
__in DWORD DesiredAccess,
|
||||
__deref_out PHANDLE TokenHandle
|
||||
);
|
||||
|
||||
BOOL WINAPI OpenThreadToken (
|
||||
__in HANDLE ThreadHandle,
|
||||
__in DWORD DesiredAccess,
|
||||
__in BOOL OpenAsSelf,
|
||||
__deref_out PHANDLE TokenHandle
|
||||
);
|
||||
|
||||
|
||||
BOOL WINAPI GetTokenInformation (
|
||||
__in HANDLE TokenHandle,
|
||||
__in TOKEN_INFORMATION_CLASS TokenInformationClass,
|
||||
__out LPVOID TokenInformation,
|
||||
__in DWORD TokenInformationLength,
|
||||
__out PDWORD ReturnLength
|
||||
);
|
||||
|
||||
BOOL WINAPI SetTokenInformation (
|
||||
__in HANDLE TokenHandle,
|
||||
__in TOKEN_INFORMATION_CLASS TokenInformationClass,
|
||||
__in LPVOID TokenInformation,
|
||||
__in DWORD TokenInformationLength
|
||||
);
|
||||
|
||||
PSID_IDENTIFIER_AUTHORITY WINAPI GetSidIdentifierAuthority (
|
||||
__in PSID pSid
|
||||
);
|
||||
|
||||
PDWORD WINAPI GetSidSubAuthority (
|
||||
__in PSID pSid,
|
||||
__in DWORD nSubAuthority
|
||||
);
|
||||
|
||||
PUCHAR WINAPI GetSidSubAuthorityCount (
|
||||
__in PSID pSid
|
||||
);
|
||||
|
||||
|
||||
VOID DebugBreak();
|
||||
|
||||
BOOL WINAPI WaitForDebugEvent(
|
||||
__in LPDEBUG_EVENT lpDebugEvent,
|
||||
__in DWORD dwMilliseconds
|
||||
);
|
||||
|
||||
BOOL WINAPI ContinueDebugEvent(
|
||||
__in DWORD dwProcessId,
|
||||
__in DWORD dwThreadId,
|
||||
__in DWORD dwContinueStatus
|
||||
);
|
||||
|
||||
BOOL WINAPI DebugActiveProcess(
|
||||
__in DWORD dwProcessId
|
||||
);
|
||||
|
||||
BOOL WINAPI DebugActiveProcessStop(
|
||||
__in DWORD dwProcessId
|
||||
);
|
||||
|
||||
BOOL WINAPI DebugSetProcessKillOnExit(
|
||||
__in BOOL KillOnExit
|
||||
);
|
||||
|
||||
BOOL WINAPI DebugBreakProcess (
|
||||
__in HANDLE Process
|
||||
);
|
||||
|
||||
DWORD WINAPI GetProcessId(
|
||||
_In_ HANDLE Process
|
||||
);
|
||||
|
||||
BOOL WINAPI Wow64SetThreadContext(
|
||||
__in HANDLE hThread,
|
||||
__in CONST WOW64_CONTEXT *lpContext
|
||||
);
|
||||
|
||||
DWORD WINAPI GetMappedFileNameW (
|
||||
__in HANDLE hProcess,
|
||||
__in LPVOID lpv,
|
||||
__out PVOID lpFilename,
|
||||
__in DWORD nSize
|
||||
);
|
||||
|
||||
DWORD WINAPI GetMappedFileNameA (
|
||||
__in HANDLE hProcess,
|
||||
__in LPVOID lpv,
|
||||
__out PVOID lpFilename,
|
||||
__in DWORD nSize
|
||||
);
|
||||
|
||||
VOID RtlInitString (
|
||||
PSTRING DestinationString,
|
||||
LPCSTR SourceString
|
||||
);
|
||||
|
||||
|
||||
VOID RtlInitUnicodeString (
|
||||
PUNICODE_STRING DestinationString,
|
||||
LPCWSTR SourceString
|
||||
);
|
||||
|
||||
NTSTATUS RtlAnsiStringToUnicodeString (
|
||||
PUNICODE_STRING DestinationString,
|
||||
PCANSI_STRING SourceString,
|
||||
BOOLEAN AllocateDestinationString
|
||||
);
|
||||
|
||||
|
||||
HANDLE WINAPI OpenEventA(
|
||||
__in DWORD dwDesiredAccess,
|
||||
__in BOOL bInheritHandle,
|
||||
__in LPCSTR lpName
|
||||
);
|
||||
|
||||
|
||||
HANDLE WINAPI OpenEventW(
|
||||
__in DWORD dwDesiredAccess,
|
||||
__in BOOL bInheritHandle,
|
||||
__in LPCWSTR lpName
|
||||
);
|
||||
|
||||
NTSTATUS WINAPI NtOpenEvent(
|
||||
__out PHANDLE EventHandle,
|
||||
__in ACCESS_MASK DesiredAccess,
|
||||
__in POBJECT_ATTRIBUTES ObjectAttributes
|
||||
);
|
||||
|
||||
|
||||
|
||||
NTSTATUS WINAPI NtAlpcCreatePort(
|
||||
_Out_ PHANDLE PortHandle,
|
||||
_In_opt_ POBJECT_ATTRIBUTES ObjectAttributes,
|
||||
_In_opt_ PALPC_PORT_ATTRIBUTES PortAttributes
|
||||
);
|
||||
|
||||
|
||||
NTSTATUS WINAPI NtAlpcConnectPort(
|
||||
_Out_ PHANDLE PortHandle,
|
||||
_In_ PUNICODE_STRING PortName,
|
||||
_In_opt_ POBJECT_ATTRIBUTES ObjectAttributes,
|
||||
_In_opt_ PALPC_PORT_ATTRIBUTES PortAttributes,
|
||||
_In_ ULONG Flags,
|
||||
_In_opt_ PSID RequiredServerSid,
|
||||
_Inout_opt_ PPORT_MESSAGE ConnectionMessage,
|
||||
_Inout_opt_ PULONG BufferLength,
|
||||
_Inout_opt_ PALPC_MESSAGE_ATTRIBUTES OutMessageAttributes,
|
||||
_Inout_opt_ PALPC_MESSAGE_ATTRIBUTES InMessageAttributes,
|
||||
_In_opt_ PLARGE_INTEGER Timeout
|
||||
);
|
||||
|
||||
|
||||
NTSTATUS WINAPI NtAlpcAcceptConnectPort(
|
||||
_Out_ PHANDLE PortHandle,
|
||||
_In_ HANDLE ConnectionPortHandle,
|
||||
_In_ ULONG Flags,
|
||||
_In_opt_ POBJECT_ATTRIBUTES ObjectAttributes,
|
||||
_In_opt_ PALPC_PORT_ATTRIBUTES PortAttributes,
|
||||
_In_opt_ PVOID PortContext,
|
||||
_In_ PPORT_MESSAGE ConnectionRequest,
|
||||
_Inout_opt_ PALPC_MESSAGE_ATTRIBUTES ConnectionMessageAttributes,
|
||||
_In_ BOOLEAN AcceptConnection
|
||||
);
|
||||
|
||||
NTSTATUS WINAPI AlpcInitializeMessageAttribute(
|
||||
_In_ ULONG AttributeFlags,
|
||||
_Out_opt_ PALPC_MESSAGE_ATTRIBUTES Buffer,
|
||||
_In_ ULONG BufferSize,
|
||||
_Out_ PULONG RequiredBufferSize
|
||||
);
|
||||
|
||||
PVOID WINAPI AlpcGetMessageAttribute(
|
||||
_In_ PALPC_MESSAGE_ATTRIBUTES Buffer,
|
||||
_In_ ULONG AttributeFlag
|
||||
);
|
||||
|
||||
NTSTATUS WINAPI NtAlpcSendWaitReceivePort(
|
||||
_In_ HANDLE PortHandle,
|
||||
_In_ ULONG Flags,
|
||||
_In_opt_ PPORT_MESSAGE SendMessage,
|
||||
_Inout_opt_ PALPC_MESSAGE_ATTRIBUTES SendMessageAttributes,
|
||||
_Out_opt_ PPORT_MESSAGE ReceiveMessage,
|
||||
_Inout_opt_ PSIZE_T BufferLength,
|
||||
_Inout_opt_ PALPC_MESSAGE_ATTRIBUTES ReceiveMessageAttributes,
|
||||
_In_opt_ PLARGE_INTEGER Timeout
|
||||
);
|
||||
|
||||
|
||||
INT WINAPI lstrcmpA(
|
||||
__in LPCSTR lpString1,
|
||||
__in LPCSTR lpString2
|
||||
);
|
||||
|
||||
INT WINAPI lstrcmpW(
|
||||
__in LPCWSTR lpString1,
|
||||
__in LPCWSTR lpString2
|
||||
);
|
||||
|
||||
|
||||
HANDLE WINAPI CreateFileMappingA(
|
||||
__in HANDLE hFile,
|
||||
__in_opt LPSECURITY_ATTRIBUTES lpFileMappingAttributes,
|
||||
__in DWORD flProtect,
|
||||
__in DWORD dwMaximumSizeHigh,
|
||||
__in DWORD dwMaximumSizeLow,
|
||||
__in_opt LPCSTR lpName
|
||||
);
|
||||
|
||||
HANDLE WINAPI CreateFileMappingW(
|
||||
__in HANDLE hFile,
|
||||
__in_opt LPSECURITY_ATTRIBUTES lpFileMappingAttributes,
|
||||
__in DWORD flProtect,
|
||||
__in DWORD dwMaximumSizeHigh,
|
||||
__in DWORD dwMaximumSizeLow,
|
||||
__in_opt LPCWSTR lpName
|
||||
);
|
||||
|
||||
|
||||
LPVOID WINAPI MapViewOfFile(
|
||||
__in HANDLE hFileMappingObject,
|
||||
__in DWORD dwDesiredAccess,
|
||||
__in DWORD dwFileOffsetHigh,
|
||||
__in DWORD dwFileOffsetLow,
|
||||
__in SIZE_T dwNumberOfBytesToMap
|
||||
);
|
||||
|
||||
|
||||
SC_HANDLE WINAPI OpenSCManagerA(
|
||||
__in_opt LPCSTR lpMachineName,
|
||||
__in_opt LPCSTR lpDatabaseName,
|
||||
__in DWORD dwDesiredAccess
|
||||
);
|
||||
|
||||
SC_HANDLE WINAPI OpenSCManagerW(
|
||||
__in_opt LPCWSTR lpMachineName,
|
||||
__in_opt LPCWSTR lpDatabaseName,
|
||||
__in DWORD dwDesiredAccess
|
||||
);
|
||||
|
||||
BOOL WINAPI EnumServicesStatusExA(
|
||||
__in SC_HANDLE hSCManager,
|
||||
__in SC_ENUM_TYPE InfoLevel,
|
||||
__in DWORD dwServiceType,
|
||||
__in DWORD dwServiceState,
|
||||
_Out_opt_ LPBYTE lpServices,
|
||||
__in DWORD cbBufSize,
|
||||
__out LPDWORD pcbBytesNeeded,
|
||||
__out LPDWORD lpServicesReturned,
|
||||
__inout_opt LPDWORD lpResumeHandle,
|
||||
__in_opt LPCSTR pszGroupName
|
||||
);
|
||||
|
||||
|
||||
BOOL WINAPI EnumServicesStatusExW(
|
||||
__in SC_HANDLE hSCManager,
|
||||
__in SC_ENUM_TYPE InfoLevel,
|
||||
__in DWORD dwServiceType,
|
||||
__in DWORD dwServiceState,
|
||||
_Out_opt_ LPBYTE lpServices,
|
||||
__in DWORD cbBufSize,
|
||||
__out LPDWORD pcbBytesNeeded,
|
||||
__out LPDWORD lpServicesReturned,
|
||||
__inout_opt LPDWORD lpResumeHandle,
|
||||
__in_opt LPCWSTR pszGroupName
|
||||
);
|
||||
|
||||
BOOL WINAPI EnumWindows(
|
||||
__in WNDENUMPROC lpEnumFunc,
|
||||
__in LPARAM lParam
|
||||
);
|
||||
|
||||
|
||||
INT WINAPI GetWindowTextA(
|
||||
__in HWND hWnd,
|
||||
__out LPSTR lpString,
|
||||
__in INT nMaxCount
|
||||
);
|
||||
|
||||
INT WINAPI GetWindowTextW(
|
||||
__in HWND hWnd,
|
||||
__out LPWSTR lpString,
|
||||
__in INT nMaxCount
|
||||
);
|
||||
|
||||
UINT WINAPI GetWindowModuleFileNameA(
|
||||
__in HWND hwnd,
|
||||
__out LPSTR pszFileName,
|
||||
__in UINT cchFileNameMax);
|
||||
|
||||
UINT WINAPI GetWindowModuleFileNameW(
|
||||
__in HWND hwnd,
|
||||
__out LPWSTR pszFileName,
|
||||
__in UINT cchFileNameMax);
|
||||
|
||||
|
||||
BOOL WINAPI CryptCATAdminCalcHashFromFileHandle(
|
||||
__in HANDLE hFile,
|
||||
__inout DWORD *pcbHash,
|
||||
_Out_opt_ BYTE *pbHash,
|
||||
__in DWORD dwFlags);
|
||||
|
||||
HCATINFO WINAPI CryptCATAdminEnumCatalogFromHash(
|
||||
__in HCATADMIN hCatAdmin,
|
||||
__in BYTE *pbHash,
|
||||
__in DWORD cbHash,
|
||||
__in DWORD dwFlags,
|
||||
__inout HCATINFO *phPrevCatInfo);
|
||||
|
||||
BOOL WINAPI CryptCATAdminAcquireContext(
|
||||
_Out_ HCATADMIN *phCatAdmin,
|
||||
_In_ GUID *pgSubsystem,
|
||||
_In_ DWORD dwFlags
|
||||
);
|
||||
|
||||
BOOL WINAPI CryptCATCatalogInfoFromContext(
|
||||
_In_ HCATINFO hCatInfo,
|
||||
_Inout_ CATALOG_INFO *psCatInfo,
|
||||
_In_ DWORD dwFlags
|
||||
);
|
||||
|
||||
|
||||
BOOL WINAPI CryptCATAdminReleaseCatalogContext(
|
||||
_In_ HCATADMIN hCatAdmin,
|
||||
_In_ HCATINFO hCatInfo,
|
||||
_In_ DWORD dwFlags
|
||||
);
|
||||
|
||||
BOOL WINAPI CryptCATAdminReleaseContext(
|
||||
_In_ HCATADMIN hCatAdmin,
|
||||
_In_ DWORD dwFlags
|
||||
);
|
||||
|
||||
DWORD WINAPI GetLogicalDriveStringsA(
|
||||
_In_ DWORD nBufferLength,
|
||||
_Out_ LPCSTR lpBuffer
|
||||
);
|
||||
|
||||
|
||||
DWORD WINAPI GetLogicalDriveStringsW(
|
||||
_In_ DWORD nBufferLength,
|
||||
_Out_ LPWSTR lpBuffer
|
||||
);
|
||||
|
||||
|
||||
|
||||
BOOL WINAPI GetVolumeInformationA(
|
||||
_In_opt_ LPCSTR lpRootPathName,
|
||||
_Out_opt_ LPSTR lpVolumeNameBuffer,
|
||||
_In_ DWORD nVolumeNameSize,
|
||||
_Out_opt_ LPDWORD lpVolumeSerialNumber,
|
||||
_Out_opt_ LPDWORD lpMaximumComponentLength,
|
||||
_Out_opt_ LPDWORD lpFileSystemFlags,
|
||||
_Out_opt_ LPSTR lpFileSystemNameBuffer,
|
||||
_In_ DWORD nFileSystemNameSize
|
||||
);
|
||||
|
||||
|
||||
BOOL WINAPI GetVolumeInformationW(
|
||||
_In_opt_ LPWSTR lpRootPathName,
|
||||
_Out_opt_ LPWSTR lpVolumeNameBuffer,
|
||||
_In_ DWORD nVolumeNameSize,
|
||||
_Out_opt_ LPDWORD lpVolumeSerialNumber,
|
||||
_Out_opt_ LPDWORD lpMaximumComponentLength,
|
||||
_Out_opt_ LPDWORD lpFileSystemFlags,
|
||||
_Out_opt_ LPWSTR lpFileSystemNameBuffer,
|
||||
_In_ DWORD nFileSystemNameSize
|
||||
);
|
||||
|
||||
|
||||
BOOL WINAPI GetVolumeNameForVolumeMountPointA(
|
||||
_In_ LPCSTR lpszVolumeMountPoint,
|
||||
_Out_ LPCSTR lpszVolumeName,
|
||||
_In_ DWORD cchBufferLength
|
||||
);
|
||||
|
||||
|
||||
BOOL WINAPI GetVolumeNameForVolumeMountPointW(
|
||||
_In_ LPWSTR lpszVolumeMountPoint,
|
||||
_Out_ LPWSTR lpszVolumeName,
|
||||
_In_ DWORD cchBufferLength
|
||||
);
|
||||
|
||||
UINT WINAPI GetDriveTypeA(
|
||||
_In_opt_ LPCSTR lpRootPathName
|
||||
);
|
||||
|
||||
UINT WINAPI GetDriveTypeW(
|
||||
_In_opt_ LPWSTR lpRootPathName
|
||||
);
|
||||
|
||||
DWORD WINAPI QueryDosDeviceA(
|
||||
_In_opt_ LPCSTR lpDeviceName,
|
||||
_Out_ LPCSTR lpTargetPath,
|
||||
_In_ DWORD ucchMax
|
||||
);
|
||||
|
||||
DWORD WINAPI QueryDosDeviceW(
|
||||
_In_opt_ LPWSTR lpDeviceName,
|
||||
_Out_ LPWSTR lpTargetPath,
|
||||
_In_ DWORD ucchMax
|
||||
);
|
||||
|
||||
NTSTATUS WINAPI NtQueryObject(
|
||||
_In_opt_ HANDLE Handle,
|
||||
_In_ OBJECT_INFORMATION_CLASS ObjectInformationClass,
|
||||
_Out_opt_ PVOID ObjectInformation,
|
||||
_In_ ULONG ObjectInformationLength,
|
||||
_Out_opt_ PULONG ReturnLength
|
||||
);
|
||||
|
||||
BOOL WINAPI DuplicateHandle(
|
||||
_In_ HANDLE hSourceProcessHandle,
|
||||
_In_ HANDLE hSourceHandle,
|
||||
_In_ HANDLE hTargetProcessHandle,
|
||||
_Out_ LPHANDLE lpTargetHandle,
|
||||
_In_ DWORD dwDesiredAccess,
|
||||
_In_ BOOL bInheritHandle,
|
||||
_In_ DWORD dwOptions
|
||||
);
|
||||
|
||||
DWORD WINAPI GetModuleBaseNameA(
|
||||
_In_ HANDLE hProcess,
|
||||
_In_opt_ HMODULE hModule,
|
||||
_Out_ LPCSTR lpBaseName,
|
||||
_In_ DWORD nSize
|
||||
);
|
||||
|
||||
DWORD WINAPI GetModuleBaseNameW(
|
||||
_In_ HANDLE hProcess,
|
||||
_In_opt_ HMODULE hModule,
|
||||
_Out_ LPWSTR lpBaseName,
|
||||
_In_ DWORD nSize
|
||||
);
|
||||
|
||||
DWORD WINAPI GetProcessImageFileNameA(
|
||||
_In_ HANDLE hProcess,
|
||||
_Out_ LPCSTR lpImageFileName,
|
||||
_In_ DWORD nSize
|
||||
);
|
||||
|
||||
DWORD WINAPI GetProcessImageFileNameW(
|
||||
_In_ HANDLE hProcess,
|
||||
_Out_ LPWSTR lpImageFileName,
|
||||
_In_ DWORD nSize
|
||||
);
|
||||
|
||||
BOOL WINAPI GetFileVersionInfoA(
|
||||
_In_ LPCSTR lptstrFilename,
|
||||
_Reserved_ DWORD dwHandle,
|
||||
_In_ DWORD dwLen,
|
||||
_Out_ LPVOID lpData
|
||||
);
|
||||
|
||||
BOOL WINAPI GetFileVersionInfoW(
|
||||
_In_ LPWSTR lptstrFilename,
|
||||
_Reserved_ DWORD dwHandle,
|
||||
_In_ DWORD dwLen,
|
||||
_Out_ LPVOID lpData
|
||||
);
|
||||
|
||||
DWORD WINAPI GetFileVersionInfoSizeA(
|
||||
_In_ LPCSTR lptstrFilename,
|
||||
_Out_opt_ LPDWORD lpdwHandle
|
||||
);
|
||||
|
||||
DWORD WINAPI GetFileVersionInfoSizeW(
|
||||
_In_ LPWSTR lptstrFilename,
|
||||
_Out_opt_ LPDWORD lpdwHandle
|
||||
);
|
||||
|
||||
BOOL WINAPI VerQueryValueA(
|
||||
_In_ LPCVOID pBlock,
|
||||
_In_ LPCSTR lpSubBlock,
|
||||
_Out_ LPVOID *lplpBuffer,
|
||||
_Out_ PUINT puLen
|
||||
);
|
||||
|
||||
BOOL WINAPI VerQueryValueW(
|
||||
_In_ LPCVOID pBlock,
|
||||
_In_ LPWSTR lpSubBlock,
|
||||
_Out_ LPVOID *lplpBuffer,
|
||||
_Out_ PUINT puLen
|
||||
);
|
||||
|
||||
INT WINAPI GetSystemMetrics(
|
||||
_In_ INT nIndex
|
||||
);
|
||||
|
||||
BOOL WINAPI GetComputerNameA(
|
||||
_Out_ LPCSTR lpBuffer,
|
||||
_Inout_ LPDWORD lpnSize
|
||||
);
|
||||
|
||||
BOOL WINAPI GetComputerNameW(
|
||||
_Out_ LPWSTR lpBuffer,
|
||||
_Inout_ LPDWORD lpnSize
|
||||
);
|
||||
|
||||
BOOL WINAPI LookupAccountSidA(
|
||||
_In_opt_ LPCSTR lpSystemName,
|
||||
_In_ PSID lpSid,
|
||||
_Out_opt_ LPCSTR lpName,
|
||||
_Inout_ LPDWORD cchName,
|
||||
_Out_opt_ LPCSTR lpReferencedDomainName,
|
||||
_Inout_ LPDWORD cchReferencedDomainName,
|
||||
_Out_ PSID_NAME_USE peUse
|
||||
);
|
||||
|
||||
BOOL WINAPI LookupAccountSidW(
|
||||
_In_opt_ LPWSTR lpSystemName,
|
||||
_In_ PSID lpSid,
|
||||
_Out_opt_ LPWSTR lpName,
|
||||
_Inout_ LPDWORD cchName,
|
||||
_Out_opt_ LPWSTR lpReferencedDomainName,
|
||||
_Inout_ LPDWORD cchReferencedDomainName,
|
||||
_Out_ PSID_NAME_USE peUse
|
||||
);
|
||||
|
||||
HRESULT WINAPI CoInitializeEx(
|
||||
_In_opt_ LPVOID pvReserved,
|
||||
_In_ DWORD dwCoInit
|
||||
);
|
||||
|
||||
HRESULT WINAPI CoInitializeSecurity(
|
||||
_In_opt_ PSECURITY_DESCRIPTOR pSecDesc,
|
||||
_In_ LONG cAuthSvc,
|
||||
_In_opt_ SOLE_AUTHENTICATION_SERVICE *asAuthSvc,
|
||||
_In_opt_ PVOID pReserved1,
|
||||
_In_ DWORD dwAuthnLevel,
|
||||
_In_ DWORD dwImpLevel,
|
||||
_In_opt_ PVOID pAuthList,
|
||||
_In_ DWORD dwCapabilities,
|
||||
_In_opt_ PVOID pReserved3
|
||||
);
|
||||
|
||||
HRESULT WINAPI CoCreateInstance(
|
||||
_In_ REFCLSID rclsid,
|
||||
_In_ LPUNKNOWN pUnkOuter,
|
||||
_In_ DWORD dwClsContext,
|
||||
_In_ REFIID riid,
|
||||
_Out_ LPVOID *ppv
|
||||
);
|
||||
|
||||
DWORD WINAPI GetInterfaceInfo(
|
||||
_Out_ PIP_INTERFACE_INFO pIfTable,
|
||||
_Inout_ PULONG dwOutBufLen
|
||||
);
|
||||
|
||||
DWORD WINAPI GetIfTable(
|
||||
_Out_ PMIB_IFTABLE pIfTable,
|
||||
_Inout_ PULONG pdwSize,
|
||||
_In_ BOOL bOrder
|
||||
);
|
||||
|
||||
DWORD WINAPI GetIpAddrTable(
|
||||
_Out_ PMIB_IPADDRTABLE pIpAddrTable,
|
||||
_Inout_ PULONG pdwSize,
|
||||
_In_ BOOL bOrder
|
||||
);
|
||||
|
||||
NTSTATUS WINAPI NtOpenDirectoryObject(
|
||||
__out PHANDLE DirectoryHandle,
|
||||
__in ACCESS_MASK DesiredAccess,
|
||||
__in POBJECT_ATTRIBUTES ObjectAttributes
|
||||
);
|
||||
|
||||
|
||||
NTSTATUS WINAPI NtQueryDirectoryObject(
|
||||
__in HANDLE DirectoryHandle,
|
||||
__out PVOID Buffer,
|
||||
__in ULONG Length,
|
||||
__in BOOLEAN ReturnSingleEntry,
|
||||
__in BOOLEAN RestartScan,
|
||||
__inout PULONG Context,
|
||||
_Out_opt_ PULONG ReturnLength
|
||||
);
|
||||
|
||||
NTSTATUS WINAPI NtQuerySymbolicLinkObject(
|
||||
_In_ HANDLE LinkHandle,
|
||||
_Inout_ PUNICODE_STRING LinkTarget,
|
||||
_Out_opt_ PULONG ReturnedLength
|
||||
);
|
||||
|
||||
NTSTATUS WINAPI NtOpenSymbolicLinkObject(
|
||||
_Out_ PHANDLE LinkHandle,
|
||||
_In_ ACCESS_MASK DesiredAccess,
|
||||
_In_ POBJECT_ATTRIBUTES ObjectAttributes
|
||||
);
|
||||
|
||||
BOOL WINAPI GetProcessTimes(
|
||||
_In_ HANDLE hProcess,
|
||||
_Out_ LPFILETIME lpCreationTime,
|
||||
_Out_ LPFILETIME lpExitTime,
|
||||
_Out_ LPFILETIME lpKernelTime,
|
||||
_Out_ LPFILETIME lpUserTime
|
||||
);
|
||||
|
||||
@@ -25,7 +25,7 @@ class Ptr(object):
|
||||
|
||||
def __repr__(self):
|
||||
return "Ptr({0})".format(repr(self.type))
|
||||
|
||||
|
||||
|
||||
class WinStruct(object):
|
||||
ctypes_type = "Structure"
|
||||
@@ -59,9 +59,9 @@ class WinStruct(object):
|
||||
res += "{0}._fields_ = [\n".format(self.name)
|
||||
|
||||
for (ftype, name, nb_rep) in self.fields:
|
||||
if nb_rep == 1:
|
||||
if nb_rep == 1:
|
||||
res+= ' ("{0}", {1}),\n'.format(name, ftype.generate_ctypes())
|
||||
else:
|
||||
else:
|
||||
res+= ' ("{0}", {1} * {2}),\n'.format(name, ftype.generate_ctypes(), nb_rep)
|
||||
res += "]\n"
|
||||
return res
|
||||
@@ -73,9 +73,9 @@ class WinStruct(object):
|
||||
_fields_ = [\n""".format(self.name, self.ctypes_type)
|
||||
|
||||
for (ftype, name, nb_rep) in self.fields:
|
||||
if nb_rep == 1:
|
||||
if nb_rep == 1:
|
||||
res+= ' ("{0}", {1}),\n'.format(name, ftype.generate_ctypes())
|
||||
else:
|
||||
else:
|
||||
res+= ' ("{0}", {1} * {2}),\n'.format(name, ftype.generate_ctypes(), nb_rep)
|
||||
res += " ]\n"
|
||||
return res
|
||||
@@ -88,10 +88,10 @@ class WinStruct(object):
|
||||
str_value = "POINTER({0})".format(self.name)
|
||||
ctypes_class += "{0} = {1}\n".format(typedef_name, str_value)
|
||||
return ctypes_class
|
||||
|
||||
|
||||
class WinUnion(WinStruct):
|
||||
ctypes_type = "Union"
|
||||
|
||||
|
||||
class WinEnum(object):
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
@@ -105,7 +105,7 @@ class WinEnum(object):
|
||||
if name in self.typedef:
|
||||
raise ValueError("nop")
|
||||
self.typedef[name] = self
|
||||
|
||||
|
||||
def add_ptr_typedef(self, name):
|
||||
if name in self.typedef:
|
||||
raise ValueError("nop")
|
||||
@@ -113,7 +113,15 @@ class WinEnum(object):
|
||||
|
||||
# Assert that enum are DWORD
|
||||
def generate_ctypes(self):
|
||||
lines = ["{0} = DWORD".format(self.name)]
|
||||
#lines = ["{0} = DWORD".format(self.name)]
|
||||
lines = []
|
||||
for i, name in self.fields:
|
||||
lines.append('{0} = EnumValue("{2}", "{0}", {1})'.format(name, hex(i), self.name))
|
||||
|
||||
lines += ["class {0}(EnumType):".format(self.name)]
|
||||
lines += [" values = [{0}]".format(", ".join([name for i, name in self.fields]))]
|
||||
lines += [" mapper = {{x:x for x in values}}".format(self.name)]
|
||||
|
||||
for typedef_name, value in self.typedef.items():
|
||||
str_value = self.name
|
||||
if type(value) == Ptr:
|
||||
@@ -121,10 +129,5 @@ class WinEnum(object):
|
||||
lines += ["{0} = {1}".format(typedef_name, str_value)]
|
||||
#lines += ["{0} = {1}".format(t, self.name) for t in self.typedef]
|
||||
lines += [""]
|
||||
|
||||
for i, name in self.fields:
|
||||
lines.append("{0} = {1}".format(name, hex(i)))
|
||||
ctypes_class = "\n".join(lines)
|
||||
|
||||
ctypes_class = "\n".join(lines)
|
||||
return ctypes_class + "\n"
|
||||
|
||||
+1004
-79
File diff suppressed because it is too large
Load Diff
@@ -16,7 +16,7 @@ functions = [f for f in all_in_module if hasattr(f, "prototype") and f not in tr
|
||||
print ("Transparent proxies:")
|
||||
print("")
|
||||
for f in transp:
|
||||
print("* {0}".format(f.func_name))
|
||||
print("* {0}({1})".format(f.func_name, ", ".join([x[1] for x in f.args])))
|
||||
|
||||
print ("Functions:")
|
||||
print("")
|
||||
|
||||
+32
-10
@@ -1,21 +1,43 @@
|
||||
COM - Component Object Model
|
||||
""""""""""""""""""""""""""""
|
||||
:mod:`windows.com` - Component Object Model
|
||||
""""""""""""""""""""""""""""""""""""""""""""
|
||||
|
||||
.. module:: windows.com
|
||||
|
||||
A module to call `COM` interfaces from `Python` or
|
||||
`COM` vtable in python.
|
||||
|
||||
This code is only used in :mod:`windows.wmi`.
|
||||
This code is only used in :mod:`windows.winobject.wmi` and :mod:`windows.winobject.network` for the firewall.
|
||||
The ability to create `COM` vtable is used in the `LKD project <https://github.com/sogeti-esec-lab/LKD/>`_ .
|
||||
|
||||
|
||||
To call a `COM` interface you need to:
|
||||
Using a COM interface
|
||||
'''''''''''''''''''''
|
||||
|
||||
1. Describe the `COM` interface `CODE1 <https://github.com/sogeti-esec-lab/LKD/blob/ba40727d7d257b00f89fc6ca7296c9833b7b75b2/dbginterface/remote.py#L56>`_
|
||||
2. Use an instance (which is a PVOID) to get the interface `CODE2 <https://github.com/sogeti-esec-lab/LKD/blob/ba40727d7d257b00f89fc6ca7296c9833b7b75b2/dbginterface/remote.py#L313>`_
|
||||
3. Use the object ! `CODE3 <https://github.com/sogeti-esec-lab/LKD/blob/ba40727d7d257b00f89fc6ca7296c9833b7b75b2/dbginterface/remote.py#L366>`_
|
||||
It's possible to directly call `COM` interface from python. All you need is the definition of the `COM` interface.
|
||||
|
||||
There are three ways to get the definition of the code interface:
|
||||
|
||||
* By using it from :mod:`windows.generated_def.interfaces`
|
||||
* By writing it yourself : <https://github.com/sogeti-esec-lab/LKD/blob/ba40727d7d257b00f89fc6ca7296c9833b7b75b2/dbginterface/remote.py#L56>`_
|
||||
* By generating it.
|
||||
|
||||
To generate a `COM` interface you need its definition from the ".c" file.
|
||||
Then add thisit to ``PythonForWindows\ctypes_generation\com\MyInterface.txt``.
|
||||
Finally re-generate the interface using ``generate.py``.
|
||||
|
||||
When you have the `COM` interface defintion you can create an instance of it.
|
||||
Then you need to retrieve the interface by using an API returning an object or :func:`window.com.create_instance`.
|
||||
You can then use the instance to call whatever method you need.
|
||||
|
||||
.. note::
|
||||
|
||||
see sample :ref:`sample_com_firewall`
|
||||
|
||||
Implementing a COM interface
|
||||
''''''''''''''''''''''''''''
|
||||
|
||||
To create `COM` object you need to:
|
||||
|
||||
1. Describe your ComVtable `CODE4 <https://github.com/sogeti-esec-lab/LKD/blob/ba40727d7d257b00f89fc6ca7296c9833b7b75b2/simple_com.py#L89>`_
|
||||
2. Implement the python functions described `CODE5 <https://github.com/sogeti-esec-lab/LKD/blob/ba40727d7d257b00f89fc6ca7296c9833b7b75b2/dbginterface/remote.py#L233>`_
|
||||
3. Create an instance and pass it to whatever native function expects it `CODE6 <https://github.com/sogeti-esec-lab/LKD/blob/ba40727d7d257b00f89fc6ca7296c9833b7b75b2/dbginterface/remote.py#L438>`_
|
||||
1. Describe your ComVtable `CODE1 <https://github.com/sogeti-esec-lab/LKD/blob/ba40727d7d257b00f89fc6ca7296c9833b7b75b2/simple_com.py#L89>`_
|
||||
2. Implement the python functions described `CODE2 <https://github.com/sogeti-esec-lab/LKD/blob/ba40727d7d257b00f89fc6ca7296c9833b7b75b2/dbginterface/remote.py#L233>`_
|
||||
3. Create an instance and pass it to whatever native function expects it `CODE3 <https://github.com/sogeti-esec-lab/LKD/blob/ba40727d7d257b00f89fc6ca7296c9833b7b75b2/dbginterface/remote.py#L438>`_
|
||||
+2
-2
@@ -66,9 +66,9 @@ copyright = u'2015, Clement Rouault'
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = '0.1'
|
||||
version = '0.2'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '0.1'
|
||||
release = '0.2'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
:mod:`windows.debug` -- Debugging
|
||||
=================================
|
||||
|
||||
.. module:: windows.debug
|
||||
|
||||
.. note::
|
||||
|
||||
See sample :ref:`sample_debugger`
|
||||
|
||||
:class:`Debugger`
|
||||
"""""""""""""""""
|
||||
|
||||
The :class:`Debugger` is the base class to perform the debugging of a remote process.
|
||||
The :class:`Debugger` have some functions called on given event that can be implemented by subclasses.
|
||||
|
||||
.. autoclass:: Debugger
|
||||
:members:
|
||||
|
||||
.. automethod:: __init__
|
||||
|
||||
|
||||
|
||||
:class:`LocalDebugger`
|
||||
""""""""""""""""""""""
|
||||
|
||||
.. note::
|
||||
|
||||
See sample :ref:`sample_local_debugger`
|
||||
|
||||
The :class:`Debugger` is the base class to perform the debugging the current process.
|
||||
It is based on :func:`VectoredException` (see :ref:`sample_vectoredexception`)
|
||||
|
||||
There is not much documentation for now as the code might change soon.
|
||||
|
||||
|
||||
|
||||
.. autoclass:: LocalDebugger
|
||||
:members:
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
:class:`Breakpoint`
|
||||
"""""""""""""""""""
|
||||
|
||||
Standard breakpoints types expect an address as argument.
|
||||
|
||||
An address can be:
|
||||
|
||||
* An :class:`int`
|
||||
* A :class:`str` of form (breakpoint will be put when ``DLL`` is loaded):
|
||||
|
||||
* ``"DLL!ApiName"``
|
||||
* ``"DLL!Offset"`` where offset is a int ("16", "0x10", ..)
|
||||
|
||||
|
||||
When a breakpoint is hit, its ``trigger`` function is called with the debugger and a
|
||||
``DEBUG_EXECEPTION_EVENT`` structure as argument.
|
||||
|
||||
|
||||
.. autoclass:: Breakpoint
|
||||
:members:
|
||||
|
||||
.. autoclass:: HXBreakpoint
|
||||
:members:
|
||||
:inherited-members:
|
||||
@@ -0,0 +1,99 @@
|
||||
Exception and Context related structures
|
||||
========================================
|
||||
|
||||
.. module:: windows.winobject.exception
|
||||
|
||||
|
||||
This module regroups all the Exception/Context related structures and functions.
|
||||
Most of the structures are the Windows structure with a prefix ``E`` (For enhanced)
|
||||
|
||||
Those structure have the same fields that the normal windows ones but their types might vary for a simpler use.
|
||||
|
||||
|
||||
This module also define the decorator :func:`VectoredException` which allows to play with ``Vectored Exception Handler`` in Python
|
||||
|
||||
.. note::
|
||||
|
||||
See sample :ref:`sample_vectoredexception` samples
|
||||
|
||||
Exception Records
|
||||
'''''''''''''''''
|
||||
|
||||
.. autoclass:: EEXCEPTION_RECORD
|
||||
:members:
|
||||
:inherited-members:
|
||||
|
||||
.. autoclass:: EEXCEPTION_RECORD32
|
||||
:inherited-members:
|
||||
|
||||
.. autoclass:: EEXCEPTION_RECORD64
|
||||
:members:
|
||||
:inherited-members:
|
||||
|
||||
EXCEPTION DEBUG INFO
|
||||
''''''''''''''''''''
|
||||
|
||||
.. autoclass:: EEXCEPTION_DEBUG_INFO32
|
||||
:members:
|
||||
:inherited-members:
|
||||
|
||||
.. data:: ExceptionRecord
|
||||
|
||||
:type: :class:`EEXCEPTION_RECORD32`
|
||||
|
||||
|
||||
.. autoclass:: EEXCEPTION_DEBUG_INFO64
|
||||
:members:
|
||||
:inherited-members:
|
||||
|
||||
.. data:: ExceptionRecord
|
||||
|
||||
:type: :class:`EEXCEPTION_RECORD64`
|
||||
|
||||
Context
|
||||
'''''''
|
||||
|
||||
.. autoclass:: ECONTEXT32
|
||||
:members:
|
||||
:inherited-members:
|
||||
|
||||
.. autoclass:: ECONTEXTWOW64
|
||||
:members:
|
||||
:inherited-members:
|
||||
|
||||
.. autoclass:: ECONTEXT64
|
||||
:members:
|
||||
:inherited-members:
|
||||
|
||||
.. autoclass:: EEflags
|
||||
:members:
|
||||
|
||||
.. autoclass:: EDr7
|
||||
:members:
|
||||
|
||||
EXCEPTION POINTERS
|
||||
''''''''''''''''''
|
||||
|
||||
.. autoclass:: EEXCEPTION_POINTERS
|
||||
:members:
|
||||
|
||||
.. data:: ExceptionRecord
|
||||
|
||||
:type: POINTER to :class:`EEXCEPTION_RECORD`
|
||||
|
||||
.. data:: ContextRecord
|
||||
|
||||
:type: POINTER to :class:`ECONTEXT32` or :class:`ECONTEXT64`
|
||||
|
||||
|
||||
.. _vectoredexception:
|
||||
|
||||
Vectored Exception
|
||||
''''''''''''''''''
|
||||
|
||||
.. note::
|
||||
|
||||
See sample :ref:`sample_vectoredexception`
|
||||
|
||||
.. autoclass:: VectoredException
|
||||
:members:
|
||||
@@ -4,7 +4,7 @@
|
||||
contain the root `toctree` directive.
|
||||
|
||||
Welcome to PythonForWindows's documentation!
|
||||
=====================================
|
||||
============================================
|
||||
|
||||
Contents:
|
||||
|
||||
@@ -17,6 +17,9 @@ Contents:
|
||||
native_exec.rst
|
||||
winproxy.rst
|
||||
utils.rst
|
||||
wintrust.rst
|
||||
debug.rst
|
||||
com.rst
|
||||
iat_hook.rst
|
||||
wip.rst
|
||||
internals.rst
|
||||
|
||||
@@ -120,5 +120,9 @@ Existing function are:
|
||||
|
||||
.. function:: NtGetContextThread_32_to_64
|
||||
|
||||
.. function:: NtSetContextThread_32_to_64
|
||||
|
||||
.. function:: LdrLoadDll_32_to_64
|
||||
|
||||
|
||||
.. _heaven_gate: http://rce.co/knockin-on-heavens-gate-dynamic-processor-mode-switching/
|
||||
@@ -181,3 +181,56 @@ Demo::
|
||||
|
||||
|
||||
|
||||
:mod:`windows.native_exec.nativeutils` -- Native utility functions
|
||||
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
|
||||
.. module:: windows.native_exec.nativeutils
|
||||
|
||||
This module contains some native-code functions that can be used for various purposes.
|
||||
Each function export a label that allow another :class:`MultipleInstr` to call the code of the function.
|
||||
|
||||
The current functions are:
|
||||
|
||||
* ``StrlenW64`` A 64bits wide-string STRLEN (``Label(":FUNC_STRLENW64")``)
|
||||
* ``StrlenA64`` A 64bits ASCII STRLEN (``Label(":FUNC_STRLENA64")``)
|
||||
* ``GetProcAddress64`` A 64bits export resolver (``Label(":FUNC_GETPROCADDRESS64")``)
|
||||
|
||||
* Arg1: The DLL (wstring)
|
||||
* Arg2: The API (string)
|
||||
* Return value:
|
||||
|
||||
* 0xfffffffffffffffe if the DLL is not found
|
||||
* 0xffffffffffffffff if the API is not found
|
||||
* The address of the function
|
||||
|
||||
* ``StrlenW32`` A 32bits wide-string STRLEN (``Label(":FUNC_STRLENW32")``)
|
||||
* ``StrlenA32`` A 32bits ASCII STRLEN (``Label(":FUNC_STRLENA32")``)
|
||||
* ``GetProcAddress32`` A 32bits export resolver (``Label(":FUNC_GETPROCADDRESS32")``)
|
||||
|
||||
* Arg1: The DLL (wstring)
|
||||
* Arg2: The API (string)
|
||||
* Return value:
|
||||
|
||||
* 0xfffffffe if the DLL is not found
|
||||
* 0xffffffff if the API is not found
|
||||
* The address of the function
|
||||
|
||||
To use those functions in a :class:`MultipleInstr` just call the label in your code and append the function at
|
||||
the end of your :class:`MultipleInstr`
|
||||
|
||||
|
||||
Example::
|
||||
|
||||
RemoteManualLoadLibray = x86.MultipleInstr()
|
||||
|
||||
RemoteManualLoadLibray += x86.Mov("ECX", x86.mem("[ESP + 4]"))
|
||||
RemoteManualLoadLibray += x86.Push(x86.mem("[ECX + 4]"))
|
||||
RemoteManualLoadLibray += x86.Push(x86.mem("[ECX]"))
|
||||
RemoteManualLoadLibray += x86.Call(":FUNC_GETPROCADDRESS32")
|
||||
RemoteManualLoadLibray += x86.Push(x86.mem("[ECX + 8]"))
|
||||
RemoteManualLoadLibray += x86.Call("EAX") # LoadLibrary
|
||||
RemoteManualLoadLibray += x86.Pop("ECX")
|
||||
RemoteManualLoadLibray += x86.Pop("ECX")
|
||||
RemoteManualLoadLibray += x86.Ret()
|
||||
|
||||
RemoteManualLoadLibray += GetProcAddress32
|
||||
+12
-4
@@ -1,19 +1,27 @@
|
||||
Network
|
||||
=======
|
||||
|
||||
.. module:: windows.network
|
||||
.. module:: windows.winobject.network
|
||||
|
||||
.. note::
|
||||
|
||||
See sample :ref:`sample_network_exploration`
|
||||
|
||||
|
||||
.. autoclass:: windows.network.Network
|
||||
.. autoclass:: Network
|
||||
|
||||
Connections
|
||||
"""""""""""
|
||||
|
||||
.. autoclass:: windows.network.TCP4Connection
|
||||
.. autoclass:: TCP4Connection
|
||||
|
||||
|
||||
.. autoclass:: windows.network.TCP6Connection
|
||||
.. autoclass:: TCP6Connection
|
||||
|
||||
Firewall
|
||||
""""""""
|
||||
|
||||
.. autoclass:: Firewall
|
||||
|
||||
|
||||
.. autoclass:: FirewallRule
|
||||
@@ -1,7 +1,7 @@
|
||||
Processes and Threads
|
||||
"""""""""""""""""""""
|
||||
|
||||
.. module:: windows.winobject
|
||||
.. module:: windows.winobject.process
|
||||
|
||||
CurrentProcess
|
||||
''''''''''''''
|
||||
@@ -50,6 +50,13 @@ WinThread
|
||||
:show-inheritance:
|
||||
:inherited-members:
|
||||
|
||||
Token
|
||||
'''''
|
||||
|
||||
.. autoclass:: Token
|
||||
:members:
|
||||
:inherited-members:
|
||||
|
||||
|
||||
PEB Exploration
|
||||
"""""""""""""""
|
||||
|
||||
+10
-2
@@ -1,7 +1,7 @@
|
||||
Registry
|
||||
========
|
||||
|
||||
.. module:: windows.registry
|
||||
.. module:: windows.winobject.registry
|
||||
|
||||
.. note::
|
||||
|
||||
@@ -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
|
||||
@@ -188,3 +231,234 @@ Output::
|
||||
...
|
||||
KeyValue(name='PathName', value=u'C:\\Windows', type=1)]
|
||||
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`
|
||||
"""""""""""""""""""""""""
|
||||
|
||||
In local process
|
||||
''''''''''''''''
|
||||
|
||||
.. literalinclude:: ..\..\samples\veh_segv.py
|
||||
|
||||
Output::
|
||||
|
||||
(cmd λ) python.exe veh_segv.py
|
||||
Protected page is at <0x1db0000>
|
||||
Setting page protection to <PAGE_NOACCESS>
|
||||
|
||||
==Entry of VEH handler==
|
||||
Instr at 0x1d1ab574 accessed to addr 0x1db0000
|
||||
Resetting page protection to <PAGE_READWRITE>
|
||||
==Entry of VEH handler==
|
||||
Exception of type EXCEPTION_SINGLE_STEP(0x80000004L)
|
||||
Resetting page protection to <PAGE_NOACCESS>
|
||||
Value 1 read
|
||||
|
||||
==Entry of VEH handler==
|
||||
Instr at 0x1d1ab574 accessed to addr 0x1db0010
|
||||
Resetting page protection to <PAGE_READWRITE>
|
||||
==Entry of VEH handler==
|
||||
Exception of type EXCEPTION_SINGLE_STEP(0x80000004L)
|
||||
Resetting page protection to <PAGE_NOACCESS>
|
||||
Value 2 read
|
||||
|
||||
|
||||
In remote process
|
||||
'''''''''''''''''
|
||||
|
||||
.. literalinclude:: ..\..\samples\remote_veh_segv.py
|
||||
|
||||
Output::
|
||||
|
||||
(cmd λ) python .exe.\samples\remote_veh_segv.py
|
||||
(In another console)
|
||||
|
||||
Tracing execution in module: <gdi32.dll>
|
||||
Protected page is at 0x7ffa3c700000L
|
||||
|
||||
Instr at 0x7ffa3c70f0f0L accessed to addr 0x7ffa3c70f0f0L (gdi32.dll)
|
||||
Exception of type EXCEPTION_SINGLE_STEP(0x80000004L)
|
||||
Resetting page protection to <PAGE_READWRITE>
|
||||
|
||||
Instr at 0x7ffa3c70f0f5L accessed to addr 0x7ffa3c70f0f5L (gdi32.dll)
|
||||
Exception of type EXCEPTION_SINGLE_STEP(0x80000004L)
|
||||
Resetting page protection to <PAGE_READWRITE>
|
||||
|
||||
Instr at 0x7ffa3c70f0faL accessed to addr 0x7ffa3c70f0faL (gdi32.dll)
|
||||
Exception of type EXCEPTION_SINGLE_STEP(0x80000004L)
|
||||
Resetting page protection to <PAGE_READWRITE>
|
||||
|
||||
Instr at 0x7ffa3c70f0ffL accessed to addr 0x7ffa3c70f0ffL (gdi32.dll)
|
||||
Exception of type EXCEPTION_SINGLE_STEP(0x80000004L)
|
||||
Resetting page protection to <PAGE_READWRITE>
|
||||
|
||||
Instr at 0x7ffa3c70f100L accessed to addr 0x7ffa3c70f100L (gdi32.dll)
|
||||
No more tracing !
|
||||
|
||||
|
||||
.. _sample_debugger:
|
||||
|
||||
Debugging
|
||||
"""""""""
|
||||
|
||||
:class:`Debugger`
|
||||
'''''''''''''''''
|
||||
|
||||
.. literalinclude:: ..\..\samples\debugger.py
|
||||
|
||||
Ouput::
|
||||
|
||||
(cmd λ) python.exe .\samples\debugger.py
|
||||
Loading <KERNEL32.DLL>
|
||||
Got exception EXCEPTION_BREAKPOINT(0x80000003L) at 0x77a73bad
|
||||
Loading <C:\Windows\system32\IMM32.DLL>
|
||||
Loading <C:\Windows\system32\uxtheme.dll>
|
||||
Loading <C:\Windows\system32\uxtheme.dll>
|
||||
Loading <C:\Windows\system32\uxtheme.dll>
|
||||
Loading <C:\Windows\system32\uxtheme.dll>
|
||||
Loading <kernel32.dll>
|
||||
Loading <C:\Windows\WinSxS\x86_microsoft.windows.gdiplus_6595b64144ccf1df_1.1.9600.17415_none_dad8722c5bcc2d8f\gdiplus.dll>
|
||||
Loading <comctl32.dll>
|
||||
Loading <comctl32.dll>
|
||||
Loading <comctl32.dll>
|
||||
Loading <C:\Windows\system32\shell32.dll>
|
||||
Loading <C:\Windows\SYSTEM32\WINMM.dll>
|
||||
Loading <C:\Windows\system32\ole32.dll>
|
||||
Ask to load <ole32.dll>: exiting process
|
||||
|
||||
|
||||
.. _sample_local_debugger:
|
||||
|
||||
:class:`LocalDebugger`
|
||||
''''''''''''''''''''''
|
||||
|
||||
In current process
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. literalinclude:: ..\..\samples\local_debugger.py
|
||||
|
||||
Ouput::
|
||||
|
||||
(cmd λ) python.exe .\samples\local_debugger.py
|
||||
Your main thread is 3864
|
||||
Code addr = 0x46000b
|
||||
GOT AN HXBP <3 at 0x46000b
|
||||
EXCEPTION !!!! Got a EXCEPTION_SINGLE_STEP(0x80000004L) at 0x46000c
|
||||
EXCEPTION !!!! Got a EXCEPTION_SINGLE_STEP(0x80000004L) at 0x46000d
|
||||
EXCEPTION !!!! Got a EXCEPTION_SINGLE_STEP(0x80000004L) at 0x46000e
|
||||
EXCEPTION !!!! Got a EXCEPTION_SINGLE_STEP(0x80000004L) at 0x46000f
|
||||
EXCEPTION !!!! Got a EXCEPTION_SINGLE_STEP(0x80000004L) at 0x460010
|
||||
EXCEPTION !!!! Got a EXCEPTION_SINGLE_STEP(0x80000004L) at 0x460011
|
||||
|
||||
|
||||
In remote process
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. literalinclude:: ..\..\samples\local_debugger_remote_process.py
|
||||
|
||||
Ouput::
|
||||
|
||||
(cmd λ) python.exe .\samples\local_debugger_remote_process.py
|
||||
(In another console)
|
||||
I AM LOADING <C:\Windows\system32\uxtheme.dll>
|
||||
I AM LOADING <C:\Windows\system32\uxtheme.dll>
|
||||
I AM LOADING <C:\Windows\system32\uxtheme.dll>
|
||||
I AM LOADING <C:\Windows\system32\uxtheme.dll>
|
||||
I AM LOADING <kernel32.dll>
|
||||
I AM LOADING <C:\Windows\WinSxS\x86_microsoft.windows.gdiplus_6595b64144ccf1df_1.1.9600.17415_none_dad8722c5bcc2d8f\gdiplus.dll>
|
||||
I AM LOADING <comctl32.dll>
|
||||
I AM LOADING <comctl32.dll>
|
||||
I AM LOADING <comctl32.dll>
|
||||
I AM LOADING <comctl32.dll>
|
||||
I AM LOADING <comctl32.dll>
|
||||
I AM LOADING <comctl32>
|
||||
I AM LOADING <C:\Windows\SysWOW64\oleacc.dll>
|
||||
I AM LOADING <OLEAUT32.DLL>
|
||||
I AM LOADING <C:\Windows\system32\ole32.dll>
|
||||
I AM LOADING <C:\Windows\system32\MSCTF.dll>
|
||||
I AM LOADING <C:\Windows\SysWOW64\msxml6.dll>
|
||||
I AM LOADING <C:\Windows\system32\shell32.dll>
|
||||
I AM LOADING <C:\Windows\SYSTEM32\WINMM.dll>
|
||||
I AM LOADING <C:\Windows\system32\ole32.dll>
|
||||
|
||||
|
||||
.. _wmi_request:
|
||||
|
||||
Make WMI requests
|
||||
'''''''''''''''''
|
||||
|
||||
.. literalinclude:: ..\..\samples\wmi_request.py
|
||||
|
||||
|
||||
Ouput::
|
||||
|
||||
(cmd λ) python .\samples\wmi_request.py
|
||||
WMI requester is <windows.winobject.wmi.WmiRequester object at 0x02B37EF0>
|
||||
Selecting * from 'Win32_Process'
|
||||
They are <92> processes
|
||||
Looking for ourself via pid
|
||||
Some info about our process:
|
||||
* Name -> python.exe
|
||||
* ProcessId -> 7968
|
||||
* OSName -> Microsoft Windows 8.1 Pro|C:\Windows|\Device\Harddisk0\Partition2
|
||||
* UserModeTime -> 2812500
|
||||
* WindowsVersion -> 6.3.9600
|
||||
* CommandLine -> python.exe .\samples\wmi_request.py
|
||||
<Select Caption,FileSystem,FreeSpace from Win32_LogicalDisk>:
|
||||
* {'Caption': u'C:', 'FreeSpace': u'43991547904', 'FileSystem': u'NTFS'}
|
||||
* {'Caption': u'E:', 'FreeSpace': u'82776027136', 'FileSystem': u'NTFS'}
|
||||
* {'Caption': u'F:', 'FreeSpace': u'5711265792', 'FileSystem': u'FAT32'}
|
||||
* {'Caption': u'G:', 'FreeSpace': None, 'FileSystem': None}
|
||||
|
||||
.. _sample_com_firewall:
|
||||
|
||||
using COM: ``INetFwPolicy2``
|
||||
''''''''''''''''''''''''''''
|
||||
|
||||
.. literalinclude:: ..\..\samples\com_inetfwpolicy2.py
|
||||
|
||||
Output::
|
||||
|
||||
(cmd λ) python .\samples\com_inetfwpolicy2.py
|
||||
Initialisation of COM
|
||||
Creating INetFwPolicy2 variable
|
||||
<INetFwPolicy2 object at 0x02DC8210> (value = None)
|
||||
|
||||
Generating CLSID
|
||||
<IID "E2B3C97F-6AE1-41AC-817A-F6F92166D7DD">
|
||||
|
||||
Creating COM instance
|
||||
<INetFwPolicy2 object at 0x02DC8210> (value = 0x8984848)
|
||||
|
||||
Checking for enabled profiles
|
||||
* NET_FW_PROFILE2_DOMAIN(0x1L) -> True
|
||||
* NET_FW_PROFILE2_PRIVATE(0x2L) -> True
|
||||
* NET_FW_PROFILE2_PUBLIC(0x4L) -> True
|
||||
@@ -0,0 +1,15 @@
|
||||
Service
|
||||
=======
|
||||
|
||||
.. note::
|
||||
|
||||
See sample :ref:`sample_system`
|
||||
|
||||
.. module:: windows.winobject.service
|
||||
|
||||
.. autoclass:: ServiceStatus
|
||||
:exclude-members: count, index
|
||||
|
||||
.. autoclass:: ServiceA
|
||||
:show-inheritance:
|
||||
:inherited-members:
|
||||
@@ -10,6 +10,9 @@ This sections describes them by group of relation.
|
||||
:maxdepth: 3
|
||||
|
||||
process.rst
|
||||
exception.rst
|
||||
registry.rst
|
||||
network.rst
|
||||
com.rst
|
||||
service.rst
|
||||
volume.rst
|
||||
wmi.rst
|
||||
@@ -0,0 +1,16 @@
|
||||
Volume -- The logical drives
|
||||
============================
|
||||
|
||||
.. note::
|
||||
|
||||
See sample :ref:`sample_system`
|
||||
|
||||
.. module:: windows.winobject.volume
|
||||
|
||||
.. autoclass:: LogicalDrive
|
||||
|
||||
.. data:: name
|
||||
|
||||
Name of the logical drive
|
||||
|
||||
:type: :class:`str`
|
||||
+11
-14
@@ -1,37 +1,34 @@
|
||||
The ``windows`` module
|
||||
**********************
|
||||
|
||||
The ``windows`` module is the module installed by :file:`setup.py` (that does not exists right now).
|
||||
The ``windows`` module is the module installed by :file:`setup.py`.
|
||||
|
||||
This module exports some objects representing the current state of the system.
|
||||
It also offers some submodules aimed to help the interfacing with ``Windows`` and native code execution.
|
||||
|
||||
The defaults objects accessible in ``windows`` are:
|
||||
* ``system`` of type :class:`windows.winobject.System`
|
||||
* ``current_process`` of type :class:`windows.winobject.CurrentProcess`
|
||||
* ``current_thread`` of type :class:`windows.winobject.CurrentThread`
|
||||
* ``system`` of type :class:`windows.winobject.system.System`
|
||||
* ``current_process`` of type :class:`windows.winobject.process.CurrentProcess`
|
||||
* ``current_thread`` of type :class:`windows.winobject.process.CurrentThread`
|
||||
|
||||
The submodules that you might use by themself are:
|
||||
* :mod:`windows.native_exec`
|
||||
* :mod:`windows.winproxy`
|
||||
* :mod:`windows.utils`
|
||||
* :mod:`windows.debug`
|
||||
* :mod:`windows.com`
|
||||
|
||||
.. _object_system:
|
||||
|
||||
The ``system`` object
|
||||
"""""""""""""""""""""
|
||||
|
||||
.. note::
|
||||
|
||||
See sample :ref:`sample_system`
|
||||
|
||||
.. currentmodule:: windows.winobject
|
||||
|
||||
.. autoclass:: windows.winobject.System
|
||||
.. autoclass:: windows.winobject.system.System
|
||||
:no-show-inheritance:
|
||||
|
||||
.. autoattribute:: windows.winobject.System.registry
|
||||
:annotation:
|
||||
|
||||
Object of class :class:`windows.registry.Registry`
|
||||
|
||||
.. autoattribute:: windows.winobject.System.network
|
||||
:annotation:
|
||||
|
||||
Object of class :class:`windows.network.Network`
|
||||
+474
-40
@@ -80,35 +80,63 @@ Functions in :mod:`windows.winproxy`
|
||||
|
||||
Transparent proxies:
|
||||
|
||||
* AllocConsole
|
||||
* CloseHandle
|
||||
* ExitProcess
|
||||
* ExitThread
|
||||
* FreeConsole
|
||||
* GetCurrentProcess
|
||||
* GetCurrentProcessorNumber
|
||||
* GetCurrentThread
|
||||
* GetCurrentThreadId
|
||||
* GetExitCodeProcess
|
||||
* GetExitCodeThread
|
||||
* GetLastError
|
||||
* GetProcAddress
|
||||
* GetStdHandle
|
||||
* GetThreadId
|
||||
* LoadLibraryA
|
||||
* LoadLibraryW
|
||||
* ResumeThread
|
||||
* SetStdHandle
|
||||
* SetTcpEntry
|
||||
* SuspendThread
|
||||
* TerminateProcess
|
||||
* TerminateThread
|
||||
* VirtualQueryEx
|
||||
* Wow64DisableWow64FsRedirection
|
||||
* Wow64EnableWow64FsRedirection
|
||||
* Wow64GetThreadContext
|
||||
* Wow64RevertWow64FsRedirection
|
||||
|
||||
* AllocConsole()
|
||||
* CloseHandle(hObject)
|
||||
* ContinueDebugEvent(dwProcessId, dwThreadId, dwContinueStatus)
|
||||
* DebugActiveProcess(dwProcessId)
|
||||
* DebugActiveProcessStop(dwProcessId)
|
||||
* DebugBreak()
|
||||
* DebugBreakProcess(Process)
|
||||
* DebugSetProcessKillOnExit(KillOnExit)
|
||||
* EnumWindows(lpEnumFunc, lParam)
|
||||
* ExitProcess(uExitCode)
|
||||
* ExitThread(dwExitCode)
|
||||
* FreeConsole()
|
||||
* GetComputerNameA(lpBuffer, lpnSize)
|
||||
* GetComputerNameW(lpBuffer, lpnSize)
|
||||
* GetCurrentProcess()
|
||||
* GetCurrentProcessorNumber()
|
||||
* GetCurrentThread()
|
||||
* GetCurrentThreadId()
|
||||
* GetDriveTypeA(lpRootPathName)
|
||||
* GetDriveTypeW(lpRootPathName)
|
||||
* GetExitCodeProcess(hProcess, lpExitCode)
|
||||
* GetExitCodeThread(hThread, lpExitCode)
|
||||
* GetLastError()
|
||||
* GetLogicalDriveStringsA(nBufferLength, lpBuffer)
|
||||
* GetLogicalDriveStringsW(nBufferLength, lpBuffer)
|
||||
* GetProcAddress(hModule, lpProcName)
|
||||
* GetProcessId(Process)
|
||||
* GetSidSubAuthority(pSid, nSubAuthority)
|
||||
* GetSidSubAuthorityCount(pSid)
|
||||
* GetStdHandle(nStdHandle)
|
||||
* GetSystemMetrics(nIndex)
|
||||
* GetThreadId(Thread)
|
||||
* GetVersionExA(lpVersionInformation)
|
||||
* GetVersionExW(lpVersionInformation)
|
||||
* GetVolumeNameForVolumeMountPointA(lpszVolumeMountPoint, lpszVolumeName, cchBufferLength)
|
||||
* GetVolumeNameForVolumeMountPointW(lpszVolumeMountPoint, lpszVolumeName, cchBufferLength)
|
||||
* GetWindowModuleFileNameA(hwnd, pszFileName, cchFileNameMax)
|
||||
* GetWindowModuleFileNameW(hwnd, pszFileName, cchFileNameMax)
|
||||
* GetWindowTextA(hWnd, lpString, nMaxCount)
|
||||
* GetWindowTextW(hWnd, lpString, nMaxCount)
|
||||
* LoadLibraryA(lpFileName)
|
||||
* LoadLibraryW(lpFileName)
|
||||
* QueryDosDeviceA(lpDeviceName, lpTargetPath, ucchMax)
|
||||
* QueryDosDeviceW(lpDeviceName, lpTargetPath, ucchMax)
|
||||
* ResumeThread(hThread)
|
||||
* SetStdHandle(nStdHandle, hHandle)
|
||||
* SetTcpEntry(pTcpRow)
|
||||
* SuspendThread(hThread)
|
||||
* TerminateProcess(hProcess, uExitCode)
|
||||
* TerminateThread(hThread, dwExitCode)
|
||||
* VirtualQueryEx(hProcess, lpAddress, lpBuffer, dwLength)
|
||||
* Wow64DisableWow64FsRedirection(OldValue)
|
||||
* Wow64EnableWow64FsRedirection(Wow64FsEnableRedirection)
|
||||
* Wow64GetThreadContext(hThread, lpContext)
|
||||
* Wow64RevertWow64FsRedirection(OldValue)
|
||||
* lstrcmpA(lpString1, lpString2)
|
||||
* lstrcmpW(lpString1, lpString2)
|
||||
Functions:
|
||||
|
||||
* AddVectoredContinueHandler::
|
||||
@@ -129,9 +157,49 @@ Functions:
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is 0
|
||||
|
||||
* AlpcGetMessageAttribute::
|
||||
|
||||
AlpcGetMessageAttribute(Buffer, AttributeFlag)
|
||||
Errcheck:
|
||||
Nothing special
|
||||
|
||||
* AlpcInitializeMessageAttribute::
|
||||
|
||||
AlpcInitializeMessageAttribute(AttributeFlags, Buffer, BufferSize, RequiredBufferSize)
|
||||
|
||||
* CoCreateInstance::
|
||||
|
||||
CoCreateInstance(rclsid, pUnkOuter=None, dwClsContext=tagCLSCTX.CLSCTX_INPROC_SERVER(0x1L), riid=NeededParameter, ppv=NeededParameter)
|
||||
Errcheck:
|
||||
Nothing special
|
||||
|
||||
* CoInitializeEx::
|
||||
|
||||
CoInitializeEx(pvReserved=None, dwCoInit=tagCOINIT.COINIT_MULTITHREADED(0x0L))
|
||||
Errcheck:
|
||||
Nothing special
|
||||
|
||||
* CoInitializeSecurity::
|
||||
|
||||
CoInitializeSecurity(pSecDesc, cAuthSvc, asAuthSvc, pReserved1, dwAuthnLevel, dwImpLevel, pAuthList, dwCapabilities, pReserved3)
|
||||
Errcheck:
|
||||
Nothing special
|
||||
|
||||
* CreateFileA::
|
||||
|
||||
CreateFileA(lpFileName, dwDesiredAccess=GENERIC_READ(0x80000000L), dwShareMode=0, lpSecurityAttributes=None, dwCreationDisposition=OPEN_EXISTING(0x3L), dwFlagsAndAttributes=FILE_ATTRIBUTE_NORMAL(0x80L), hTemplateFile=None)
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is NOT 0
|
||||
|
||||
* CreateFileMappingA::
|
||||
|
||||
CreateFileMappingA(hFile, lpFileMappingAttributes=None, flProtect=PAGE_READWRITE(0x4L), dwMaximumSizeHigh=0, dwMaximumSizeLow=NeededParameter, lpName=NeededParameter)
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is 0
|
||||
|
||||
* CreateFileMappingW::
|
||||
|
||||
CreateFileMappingW(hFile, lpFileMappingAttributes=None, flProtect=PAGE_READWRITE(0x4L), dwMaximumSizeHigh=0, dwMaximumSizeLow=0, lpName=NeededParameter)
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is 0
|
||||
|
||||
@@ -139,7 +207,7 @@ Functions:
|
||||
|
||||
CreateFileW(lpFileName, dwDesiredAccess=GENERIC_READ(0x80000000L), dwShareMode=0, lpSecurityAttributes=None, dwCreationDisposition=OPEN_EXISTING(0x3L), dwFlagsAndAttributes=FILE_ATTRIBUTE_NORMAL(0x80L), hTemplateFile=None)
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is 0
|
||||
raise Kernel32Error if result is NOT 0
|
||||
|
||||
* CreateProcessA::
|
||||
|
||||
@@ -171,18 +239,216 @@ Functions:
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is 0
|
||||
|
||||
* CryptCATAdminAcquireContext::
|
||||
|
||||
CryptCATAdminAcquireContext(phCatAdmin, pgSubsystem, dwFlags)
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is 0
|
||||
|
||||
* CryptCATAdminCalcHashFromFileHandle::
|
||||
|
||||
CryptCATAdminCalcHashFromFileHandle(hFile, pcbHash, pbHash, dwFlags)
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is 0
|
||||
|
||||
* CryptCATAdminEnumCatalogFromHash::
|
||||
|
||||
CryptCATAdminEnumCatalogFromHash(hCatAdmin, pbHash, cbHash, dwFlags, phPrevCatInfo)
|
||||
Errcheck:
|
||||
Nothing special
|
||||
|
||||
* CryptCATAdminReleaseCatalogContext::
|
||||
|
||||
CryptCATAdminReleaseCatalogContext(hCatAdmin, hCatInfo, dwFlags)
|
||||
Errcheck:
|
||||
Nothing special
|
||||
|
||||
* CryptCATAdminReleaseContext::
|
||||
|
||||
CryptCATAdminReleaseContext(hCatAdmin, dwFlags)
|
||||
Errcheck:
|
||||
Nothing special
|
||||
|
||||
* CryptCATCatalogInfoFromContext::
|
||||
|
||||
CryptCATCatalogInfoFromContext(hCatInfo, psCatInfo, dwFlags)
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is 0
|
||||
|
||||
* DeviceIoControl::
|
||||
|
||||
DeviceIoControl(hDevice, dwIoControlCode, lpInBuffer, nInBufferSize=None, lpOutBuffer=NeededParameter, nOutBufferSize=None, lpBytesReturned=None, lpOverlapped=None)
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is 0
|
||||
|
||||
* DuplicateHandle::
|
||||
|
||||
DuplicateHandle(hSourceProcessHandle, hSourceHandle, hTargetProcessHandle, lpTargetHandle, dwDesiredAccess=0, bInheritHandle=False, dwOptions=0)
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is 0
|
||||
|
||||
* EnumServicesStatusExA::
|
||||
|
||||
EnumServicesStatusExA(hSCManager, InfoLevel, dwServiceType, dwServiceState, lpServices, cbBufSize, pcbBytesNeeded, lpServicesReturned, lpResumeHandle, pszGroupName)
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is 0
|
||||
|
||||
* EnumServicesStatusExW::
|
||||
|
||||
EnumServicesStatusExW(hSCManager, InfoLevel, dwServiceType, dwServiceState, lpServices, cbBufSize, pcbBytesNeeded, lpServicesReturned, lpResumeHandle, pszGroupName)
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is 0
|
||||
|
||||
* GetExtendedTcpTable::
|
||||
|
||||
GetExtendedTcpTable(pTcpTable, pdwSize=None, bOrder=True, ulAf=NeededParameter, TableClass=5, Reserved=0)
|
||||
GetExtendedTcpTable(pTcpTable, pdwSize=None, bOrder=True, ulAf=NeededParameter, TableClass=_TCP_TABLE_CLASS.TCP_TABLE_OWNER_PID_ALL(0x5L), Reserved=0)
|
||||
Errcheck:
|
||||
raise IphlpapiError if result is NOT 0
|
||||
|
||||
* GetFileVersionInfoA::
|
||||
|
||||
GetFileVersionInfoA(lptstrFilename, dwHandle=0, dwLen=None, lpData=NeededParameter)
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is 0
|
||||
|
||||
* GetFileVersionInfoSizeA::
|
||||
|
||||
GetFileVersionInfoSizeA(lptstrFilename, lpdwHandle=None)
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is 0
|
||||
|
||||
* GetFileVersionInfoSizeW::
|
||||
|
||||
GetFileVersionInfoSizeW(lptstrFilename, lpdwHandle=None)
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is 0
|
||||
|
||||
* GetFileVersionInfoW::
|
||||
|
||||
GetFileVersionInfoW(lptstrFilename, dwHandle=0, dwLen=None, lpData=NeededParameter)
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is 0
|
||||
|
||||
* GetIfTable::
|
||||
|
||||
GetIfTable(pIfTable, pdwSize, bOrder=False)
|
||||
Errcheck:
|
||||
raise IphlpapiError if result is NOT 0
|
||||
|
||||
* GetInterfaceInfo::
|
||||
|
||||
GetInterfaceInfo(pIfTable, dwOutBufLen=None)
|
||||
Errcheck:
|
||||
raise IphlpapiError if result is NOT 0
|
||||
|
||||
* GetIpAddrTable::
|
||||
|
||||
GetIpAddrTable(pIpAddrTable, pdwSize, bOrder=False)
|
||||
Errcheck:
|
||||
raise IphlpapiError if result is NOT 0
|
||||
|
||||
* GetMappedFileNameAWrapper::
|
||||
|
||||
GetMappedFileNameAWrapper(hProcess, lpv, lpFilename, nSize=None)
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is 0
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is 0
|
||||
|
||||
* GetMappedFileNameAWrapper::
|
||||
|
||||
GetMappedFileNameAWrapper(hProcess, lpv, lpFilename, nSize=None)
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is 0
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is 0
|
||||
|
||||
* GetMappedFileNameWWrapper::
|
||||
|
||||
GetMappedFileNameWWrapper(hProcess, lpv, lpFilename, nSize=None)
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is 0
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is 0
|
||||
|
||||
* GetMappedFileNameWWrapper::
|
||||
|
||||
GetMappedFileNameWWrapper(hProcess, lpv, lpFilename, nSize=None)
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is 0
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is 0
|
||||
|
||||
* GetModuleBaseNameAWrapper::
|
||||
|
||||
GetModuleBaseNameAWrapper(hProcess, hModule, lpBaseName, nSize=None)
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is 0
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is 0
|
||||
|
||||
* GetModuleBaseNameAWrapper::
|
||||
|
||||
GetModuleBaseNameAWrapper(hProcess, hModule, lpBaseName, nSize=None)
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is 0
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is 0
|
||||
|
||||
* GetModuleBaseNameWWrapper::
|
||||
|
||||
GetModuleBaseNameWWrapper(hProcess, hModule, lpBaseName, nSize=None)
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is 0
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is 0
|
||||
|
||||
* GetModuleBaseNameWWrapper::
|
||||
|
||||
GetModuleBaseNameWWrapper(hProcess, hModule, lpBaseName, nSize=None)
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is 0
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is 0
|
||||
|
||||
* GetProcessImageFileNameAWrapper::
|
||||
|
||||
GetProcessImageFileNameAWrapper(hProcess, lpImageFileName, nSize=None)
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is 0
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is 0
|
||||
|
||||
* GetProcessImageFileNameAWrapper::
|
||||
|
||||
GetProcessImageFileNameAWrapper(hProcess, lpImageFileName, nSize=None)
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is 0
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is 0
|
||||
|
||||
* GetProcessImageFileNameWWrapper::
|
||||
|
||||
GetProcessImageFileNameWWrapper(hProcess, lpImageFileName, nSize=None)
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is 0
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is 0
|
||||
|
||||
* GetProcessImageFileNameWWrapper::
|
||||
|
||||
GetProcessImageFileNameWWrapper(hProcess, lpImageFileName, nSize=None)
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is 0
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is 0
|
||||
|
||||
* GetProcessTimes::
|
||||
|
||||
GetProcessTimes(hProcess, lpCreationTime, lpExitTime, lpKernelTime, lpUserTime)
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is 0
|
||||
|
||||
* GetThreadContext::
|
||||
|
||||
GetThreadContext(hThread, lpContext=None)
|
||||
@@ -195,6 +461,34 @@ Functions:
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is 0
|
||||
|
||||
* GetVolumeInformationA::
|
||||
|
||||
GetVolumeInformationA(lpRootPathName, lpVolumeNameBuffer, nVolumeNameSize, lpVolumeSerialNumber, lpMaximumComponentLength, lpFileSystemFlags, lpFileSystemNameBuffer, nFileSystemNameSize)
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is 0
|
||||
|
||||
* GetVolumeInformationW::
|
||||
|
||||
GetVolumeInformationW(lpRootPathName, lpVolumeNameBuffer=None, nVolumeNameSize=0, lpVolumeSerialNumber=None, lpMaximumComponentLength=None, lpFileSystemFlags=None, lpFileSystemNameBuffer=None, nFileSystemNameSize=0)
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is 0
|
||||
|
||||
* LdrLoadDll::
|
||||
|
||||
LdrLoadDll(PathToFile, Flags, ModuleFileName, ModuleHandle)
|
||||
|
||||
* LookupAccountSidA::
|
||||
|
||||
LookupAccountSidA(lpSystemName, lpSid, lpName, cchName, lpReferencedDomainName, cchReferencedDomainName, peUse)
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is 0
|
||||
|
||||
* LookupAccountSidW::
|
||||
|
||||
LookupAccountSidW(lpSystemName, lpSid, lpName, cchName, lpReferencedDomainName, cchReferencedDomainName, peUse)
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is 0
|
||||
|
||||
* LookupPrivilegeValueA::
|
||||
|
||||
LookupPrivilegeValueA(lpSystemName=None, lpName=NeededParameter, lpLuid=NeededParameter)
|
||||
@@ -207,6 +501,28 @@ Functions:
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is 0
|
||||
|
||||
* MapViewOfFile::
|
||||
|
||||
MapViewOfFile(hFileMappingObject, dwDesiredAccess=FILE_MAP_ALL_ACCESS(0xf001fL), dwFileOffsetHigh=0, dwFileOffsetLow=0, dwNumberOfBytesToMap=NeededParameter)
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is 0
|
||||
|
||||
* NtAlpcAcceptConnectPort::
|
||||
|
||||
NtAlpcAcceptConnectPort(PortHandle, ConnectionPortHandle, Flags, ObjectAttributes, PortAttributes, PortContext, ConnectionRequest, ConnectionMessageAttributes, AcceptConnection)
|
||||
|
||||
* NtAlpcConnectPort::
|
||||
|
||||
NtAlpcConnectPort(PortHandle, PortName, ObjectAttributes, PortAttributes, Flags, RequiredServerSid, ConnectionMessage, BufferLength, OutMessageAttributes, InMessageAttributes, Timeout)
|
||||
|
||||
* NtAlpcCreatePort::
|
||||
|
||||
NtAlpcCreatePort(PortHandle, ObjectAttributes, PortAttributes)
|
||||
|
||||
* NtAlpcSendWaitReceivePort::
|
||||
|
||||
NtAlpcSendWaitReceivePort(PortHandle, Flags, SendMessage, SendMessageAttributes, ReceiveMessage, BufferLength, ReceiveMessageAttributes, Timeout)
|
||||
|
||||
* NtCreateThreadEx::
|
||||
|
||||
NtCreateThreadEx(ThreadHandle=None, DesiredAccess=2097151, ObjectAttributes=0, ProcessHandle=NeededParameter, lpStartAddress=NeededParameter, lpParameter=NeededParameter, CreateSuspended=0, dwStackSize=0, Unknown1=0, Unknown2=0, Unknown=0)
|
||||
@@ -215,6 +531,26 @@ Functions:
|
||||
|
||||
NtGetContextThread(hThread, lpContext)
|
||||
|
||||
* NtOpenDirectoryObject::
|
||||
|
||||
NtOpenDirectoryObject(DirectoryHandle, DesiredAccess, ObjectAttributes)
|
||||
|
||||
* NtOpenEvent::
|
||||
|
||||
NtOpenEvent(EventHandle, DesiredAccess, ObjectAttributes)
|
||||
|
||||
* NtOpenSymbolicLinkObject::
|
||||
|
||||
NtOpenSymbolicLinkObject(LinkHandle, DesiredAccess, ObjectAttributes)
|
||||
|
||||
* NtProtectVirtualMemory::
|
||||
|
||||
NtProtectVirtualMemory(ProcessHandle, BaseAddress, NumberOfBytesToProtect, NewAccessProtection, OldAccessProtection=None)
|
||||
|
||||
* NtQueryDirectoryObject::
|
||||
|
||||
NtQueryDirectoryObject(DirectoryHandle, Buffer, Length, ReturnSingleEntry, RestartScan, Context, ReturnLength)
|
||||
|
||||
* NtQueryInformationProcess::
|
||||
|
||||
NtQueryInformationProcess(ProcessHandle, ProcessInformationClass, ProcessInformation, ProcessInformationLength=0, ReturnLength=None)
|
||||
@@ -223,6 +559,14 @@ Functions:
|
||||
|
||||
NtQueryInformationThread(ThreadHandle, ThreadInformationClass, ThreadInformation, ThreadInformationLength=0, ReturnLength=None)
|
||||
|
||||
* NtQueryObject::
|
||||
|
||||
NtQueryObject(Handle, ObjectInformationClass, ObjectInformation=None, ObjectInformationLength=0, ReturnLength=NeededParameter)
|
||||
|
||||
* NtQuerySymbolicLinkObject::
|
||||
|
||||
NtQuerySymbolicLinkObject(LinkHandle, LinkTarget, ReturnedLength)
|
||||
|
||||
* NtQuerySystemInformation::
|
||||
|
||||
NtQuerySystemInformation(SystemInformationClass, SystemInformation=None, SystemInformationLength=0, ReturnLength=NeededParameter)
|
||||
@@ -231,10 +575,30 @@ Functions:
|
||||
|
||||
NtQueryVirtualMemory(ProcessHandle, BaseAddress, MemoryInformationClass, MemoryInformation=NeededParameter, MemoryInformationLength=0, ReturnLength=None)
|
||||
|
||||
* NtSetContextThread::
|
||||
|
||||
NtSetContextThread(hThread, lpContext)
|
||||
|
||||
* NtWow64ReadVirtualMemory64::
|
||||
|
||||
NtWow64ReadVirtualMemory64(hProcess, lpBaseAddress, lpBuffer, nSize, lpNumberOfBytesRead=None)
|
||||
|
||||
* NtWow64WriteVirtualMemory64::
|
||||
|
||||
NtWow64WriteVirtualMemory64(hProcess, lpBaseAddress, lpBuffer, nSize, lpNumberOfBytesWritten=None)
|
||||
|
||||
* OpenEventA::
|
||||
|
||||
OpenEventA(dwDesiredAccess, bInheritHandle, lpName)
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is 0
|
||||
|
||||
* OpenEventW::
|
||||
|
||||
OpenEventW(dwDesiredAccess, bInheritHandle, lpName)
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is 0
|
||||
|
||||
* OpenProcess::
|
||||
|
||||
OpenProcess(dwDesiredAccess=PROCESS_ALL_ACCESS(0x1f0fffL), bInheritHandle=0, dwProcessId=NeededParameter)
|
||||
@@ -248,6 +612,18 @@ Functions:
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is 0
|
||||
|
||||
* OpenSCManagerA::
|
||||
|
||||
OpenSCManagerA(lpMachineName=None, lpDatabaseName=None, dwDesiredAccess=SC_MANAGER_ALL_ACCESS(0xf003fL))
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is 0
|
||||
|
||||
* OpenSCManagerW::
|
||||
|
||||
OpenSCManagerW(lpMachineName=None, lpDatabaseName=None, dwDesiredAccess=SC_MANAGER_ALL_ACCESS(0xf003fL))
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is 0
|
||||
|
||||
* OpenThread::
|
||||
|
||||
OpenThread(dwDesiredAccess=THREAD_ALL_ACCESS(0x1f03ffL), bInheritHandle=0, dwThreadId=NeededParameter)
|
||||
@@ -257,17 +633,47 @@ Functions:
|
||||
* Process32First::
|
||||
|
||||
Process32First(hSnapshot, lpte)
|
||||
Set byref(lpte) if needed
|
||||
Errcheck:
|
||||
Nothing special
|
||||
raise Kernel32Error if result is 0
|
||||
|
||||
* Process32Next::
|
||||
|
||||
Process32Next(hSnapshot, lpte)
|
||||
Set byref(lpte) if needed
|
||||
Errcheck:
|
||||
Nothing special
|
||||
|
||||
* QueryWorkingSetWrapper::
|
||||
|
||||
QueryWorkingSetWrapper(hProcess, pv, cb)
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is 0
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is 0
|
||||
|
||||
* QueryWorkingSetExWrapper::
|
||||
|
||||
QueryWorkingSetExWrapper(hProcess, pv, cb)
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is 0
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is 0
|
||||
|
||||
* QueryWorkingSetExWrapper::
|
||||
|
||||
QueryWorkingSetExWrapper(hProcess, pv, cb)
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is 0
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is 0
|
||||
|
||||
* QueryWorkingSetWrapper::
|
||||
|
||||
QueryWorkingSetWrapper(hProcess, pv, cb)
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is 0
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is 0
|
||||
|
||||
* ReadProcessMemory::
|
||||
|
||||
ReadProcessMemory(hProcess, lpBaseAddress, lpBuffer, nSize, lpNumberOfBytesRead=None)
|
||||
@@ -288,7 +694,7 @@ Functions:
|
||||
|
||||
* RegGetValueW::
|
||||
|
||||
RegGetValueW(hkey, lpSubKey, lpValue, dwFlags, pdwType, pvData, pcbData)
|
||||
RegGetValueW(hkey, lpSubKey=None, lpValue=NeededParameter, dwFlags=0, pdwType=None, pvData=None, pcbData=None)
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is NOT 0
|
||||
|
||||
@@ -320,7 +726,6 @@ Functions:
|
||||
* SetThreadContext::
|
||||
|
||||
SetThreadContext(hThread, lpContext)
|
||||
Allows to directly pass a CONTEXT and will call with byref(CONTEXT) by itself
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is 0
|
||||
|
||||
@@ -329,7 +734,7 @@ Functions:
|
||||
Thread32First(hSnapshot, lpte)
|
||||
Set byref(lpte) if needed
|
||||
Errcheck:
|
||||
Nothing special
|
||||
raise Kernel32Error if result is 0
|
||||
|
||||
* Thread32Next::
|
||||
|
||||
@@ -338,6 +743,18 @@ Functions:
|
||||
Errcheck:
|
||||
Nothing special
|
||||
|
||||
* VerQueryValueA::
|
||||
|
||||
VerQueryValueA(pBlock, lpSubBlock, lplpBuffer, puLen)
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is 0
|
||||
|
||||
* VerQueryValueW::
|
||||
|
||||
VerQueryValueW(pBlock, lpSubBlock, lplpBuffer, puLen)
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is 0
|
||||
|
||||
* VirtualAlloc::
|
||||
|
||||
VirtualAlloc(lpAddress=0, dwSize=NeededParameter, flAllocationType=MEM_COMMIT(0x1000L), flProtect=PAGE_EXECUTE_READWRITE(0x40L))
|
||||
@@ -364,7 +781,19 @@ Functions:
|
||||
|
||||
* VirtualProtect::
|
||||
|
||||
VirtualProtect(lpAddress, dwSize, flNewProtect, lpflOldProtect=0)
|
||||
VirtualProtect(lpAddress, dwSize, flNewProtect, lpflOldProtect=None)
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is 0
|
||||
|
||||
* VirtualProtectEx::
|
||||
|
||||
VirtualProtectEx(hProcess, lpAddress, dwSize, flNewProtect, lpflOldProtect=None)
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is 0
|
||||
|
||||
* WaitForDebugEvent::
|
||||
|
||||
WaitForDebugEvent(lpDebugEvent, dwMilliseconds=INFINITE(0xffffffffL))
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is 0
|
||||
|
||||
@@ -380,6 +809,12 @@ Functions:
|
||||
Errcheck:
|
||||
Nothing special
|
||||
|
||||
* Wow64SetThreadContext::
|
||||
|
||||
Wow64SetThreadContext(hThread, lpContext)
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is 0
|
||||
|
||||
* WriteFile::
|
||||
|
||||
WriteFile(hFile, lpBuffer, nNumberOfBytesToWrite=None, lpNumberOfBytesWritten=None, lpOverlapped=None)
|
||||
@@ -391,5 +826,4 @@ Functions:
|
||||
WriteProcessMemory(hProcess, lpBaseAddress, lpBuffer, nSize=None, lpNumberOfBytesWritten=None)
|
||||
Computer nSize with len(lpBuffer) if not given
|
||||
Errcheck:
|
||||
raise Kernel32Error if result is 0
|
||||
|
||||
raise Kernel32Error if result is 0
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
+1
-18
@@ -3,21 +3,4 @@ Early Work In Progress
|
||||
|
||||
Here are some features that are still work in progress. Code might be unstable and/or ultra-ugly.
|
||||
|
||||
Wintrust -- Signature check
|
||||
"""""""""""""""""""""""""""
|
||||
|
||||
Should it juste be part of :mod:`windows.utils` ?
|
||||
|
||||
.. module:: windows.wintrust
|
||||
|
||||
.. autofunction:: windows.wintrust.check_signature
|
||||
|
||||
|
||||
.. module:: windows.wmi
|
||||
|
||||
WMI -- WMI request
|
||||
""""""""""""""""""
|
||||
|
||||
Unstable code: not fully tested, ugly COM initialisation
|
||||
|
||||
.. autoclass:: windows.wmi.WmiRequester
|
||||
<Nothing right now>
|
||||
@@ -0,0 +1,10 @@
|
||||
WMI -- Make request to WMI
|
||||
==========================
|
||||
|
||||
.. module:: windows.winobject.wmi
|
||||
|
||||
.. note::
|
||||
|
||||
See sample :ref:`wmi_request`
|
||||
|
||||
.. autoclass:: WmiRequester
|
||||
@@ -0,0 +1,46 @@
|
||||
import sys
|
||||
import os.path
|
||||
import pprint
|
||||
sys.path.append(os.path.abspath(__file__ + "\..\.."))
|
||||
|
||||
import windows
|
||||
import windows.test
|
||||
import windows.debug
|
||||
|
||||
from windows.generated_def.winstructs import *
|
||||
|
||||
|
||||
|
||||
class MyDebugger(windows.debug.Debugger):
|
||||
def on_exception(self, exception):
|
||||
code = exception.ExceptionRecord.ExceptionCode
|
||||
addr = exception.ExceptionRecord.ExceptionAddress
|
||||
print("Got exception {0} at 0x{1:x}".format(code, addr))
|
||||
|
||||
|
||||
class PrintUnicodeString(windows.debug.Breakpoint):
|
||||
def __init__(self, addr, argument_position):
|
||||
super(PrintUnicodeString, self).__init__(addr)
|
||||
self.arg_pos = argument_position
|
||||
|
||||
|
||||
def trigger(self, dbg, exc):
|
||||
p = dbg.current_process
|
||||
t = dbg.current_thread
|
||||
esp = t.context.Esp
|
||||
|
||||
unicode_string_addr = p.read_ptr(esp + (self.arg_pos + 1) * 4)
|
||||
wstring_addr = p.read_ptr(unicode_string_addr + 4)
|
||||
dll_loaded = p.read_wstring(wstring_addr)
|
||||
print("Loading <{0}>".format(dll_loaded))
|
||||
|
||||
if dll_loaded.endswith("ole32.dll"):
|
||||
print("Ask to load <ole32.dll>: exiting process")
|
||||
dbg.current_process.exit()
|
||||
|
||||
|
||||
calc = windows.test.pop_calc_32(dwCreationFlags=DEBUG_PROCESS)
|
||||
d = MyDebugger(calc, already_debuggable=True)
|
||||
d.add_bp(PrintUnicodeString("ntdll.dll!LdrLoadDll", argument_position=2))
|
||||
d.loop()
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
import sys
|
||||
import os.path
|
||||
import pprint
|
||||
sys.path.append(os.path.abspath(__file__ + "\..\.."))
|
||||
|
||||
import ctypes
|
||||
import windows
|
||||
import windows.debug
|
||||
from windows.generated_def.winstructs import *
|
||||
|
||||
ct = windows.current_thread
|
||||
t = [t for t in windows.current_process.threads if t.tid == ct.tid][0]
|
||||
|
||||
|
||||
|
||||
class YoloDebugger(windows.debug.LocalDebugger):
|
||||
def __init__(self, single_step_count):
|
||||
super(YoloDebugger, self).__init__()
|
||||
self.single_step_count = single_step_count
|
||||
|
||||
def on_exception(self, exc):
|
||||
code = self.get_exception_code()
|
||||
context = self.get_exception_context()
|
||||
print("EXCEPTION !!!! Got a {0} at 0x{1:x}".format(code, context.pc))
|
||||
if self.single_step_count:
|
||||
self.single_step_count -= 1
|
||||
return self.single_step()
|
||||
return EXCEPTION_CONTINUE_EXECUTION
|
||||
|
||||
|
||||
class YoloHXBP(windows.debug.HXBreakpoint):
|
||||
def trigger(self, dbg, exc):
|
||||
context = dbg.get_exception_context()
|
||||
print("GOT AN HXBP <3 at 0x{0:x}".format(context.pc))
|
||||
windows.current_process.write_memory(self.addr, "\x90\x90")
|
||||
return dbg.single_step()
|
||||
|
||||
print("Your main thread is {0}".format(windows.current_thread.tid))
|
||||
|
||||
|
||||
d = YoloDebugger(5)
|
||||
# Infinite loop + nop + ret
|
||||
|
||||
addr = windows.native_exec.native_function.allocator.write_code("\xeb\xfe\x90\x90\x90\x90\xc3")
|
||||
func_type = ctypes.CFUNCTYPE(PVOID)
|
||||
func = func_type(addr)
|
||||
|
||||
print("Code addr = 0x{0:x}".format(addr))
|
||||
|
||||
t = windows.current_process.create_thread(addr, 0)
|
||||
|
||||
d.add_bp(YoloHXBP(addr))
|
||||
|
||||
t.wait()
|
||||
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
import sys
|
||||
import os.path
|
||||
import pprint
|
||||
sys.path.append(os.path.abspath(__file__ + "\..\.."))
|
||||
|
||||
import ctypes
|
||||
import windows
|
||||
import windows.test
|
||||
|
||||
from windows.generated_def.winstructs import *
|
||||
|
||||
remote_code = """
|
||||
import windows
|
||||
from windows.generated_def.winstructs import *
|
||||
|
||||
windows.utils.create_console()
|
||||
|
||||
class YOLOHXBP(windows.debug.HXBreakpoint):
|
||||
def trigger(self, dbg, exc):
|
||||
p = windows.current_process
|
||||
arg_pos = 2
|
||||
context = dbg.get_exception_context()
|
||||
esp = context.Esp
|
||||
unicode_string_addr = p.read_ptr(esp + (arg_pos + 1) * 4)
|
||||
wstring_addr = p.read_ptr(unicode_string_addr + 4)
|
||||
dll_loaded = p.read_wstring(wstring_addr)
|
||||
print("I AM LOADING <{0}>".format(dll_loaded))
|
||||
|
||||
d = windows.debug.LocalDebugger()
|
||||
|
||||
exp = windows.current_process.peb.modules[1].pe.exports
|
||||
#windows.utils.FixedInteractiveConsole(locals()).interact()
|
||||
ldr = exp["LdrLoadDll"]
|
||||
d.add_bp(YOLOHXBP(ldr))
|
||||
|
||||
"""
|
||||
|
||||
c = windows.test.pop_calc_32(dwCreationFlags=CREATE_SUSPENDED)
|
||||
c.execute_python(remote_code)
|
||||
c.threads[0].resume()
|
||||
|
||||
import time
|
||||
time.sleep(2)
|
||||
c.exit()
|
||||
@@ -0,0 +1,54 @@
|
||||
import sys
|
||||
import os.path
|
||||
import pprint
|
||||
sys.path.append(os.path.abspath(__file__ + "\..\.."))
|
||||
|
||||
import windows
|
||||
import windows.test
|
||||
|
||||
import windows.native_exec.simple_x64 as x64
|
||||
import windows.native_exec.nativeutils
|
||||
from windows.generated_def.winstructs import *
|
||||
|
||||
GetProcAddress64 = windows.native_exec.nativeutils.GetProcAddress64
|
||||
|
||||
dll = "KERNEL32.DLL\x00".encode("utf-16-le")
|
||||
api = "LoadLibraryA\x00"
|
||||
dll_to_load = "SUCE"
|
||||
|
||||
|
||||
RemoteManualLoadLibray = x64.MultipleInstr()
|
||||
c = RemoteManualLoadLibray
|
||||
c += x64.Mov("R15", "RCX")
|
||||
c += x64.Mov("RCX", x64.mem("[R15 + 0]"))
|
||||
c += x64.Mov("RDX", x64.mem("[R15 + 8]"))
|
||||
c += x64.Call(":FUNC_GETPROCADDRESS64")
|
||||
c += x64.Mov("RCX", x64.mem("[R15 + 0x10]"))
|
||||
c += x64.Push("RCX")
|
||||
c += x64.Push("RCX")
|
||||
c += x64.Push("RCX")
|
||||
c += x64.Call("RAX")
|
||||
c += x64.Pop("RCX")
|
||||
c += x64.Pop("RCX")
|
||||
c += x64.Pop("RCX")
|
||||
c += x64.Ret()
|
||||
|
||||
RemoteManualLoadLibray += GetProcAddress64
|
||||
|
||||
|
||||
calc= windows.test.pop_calc_64(dwCreationFlags=CREATE_SUSPENDED)
|
||||
|
||||
addr = calc.virtual_alloc(0x1000)
|
||||
addr2 = addr + len(dll)
|
||||
addr3 = addr2 + len(api)
|
||||
addr4 = addr3 + len(dll_to_load)
|
||||
|
||||
calc.write_memory(addr, dll)
|
||||
calc.write_memory(addr2, api)
|
||||
calc.write_memory(addr3, dll_to_load)
|
||||
calc.write_qword(addr4, addr)
|
||||
calc.write_qword(addr4 + 8, addr2)
|
||||
calc.write_qword(addr4 + 0x10, addr3)
|
||||
|
||||
calc.execute(RemoteManualLoadLibray.get_code(), addr4)
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import sys
|
||||
import os.path
|
||||
import socket
|
||||
|
||||
sys.path.append(os.path.abspath(__file__ + "\..\.."))
|
||||
|
||||
import windows
|
||||
|
||||
+5
-5
@@ -8,21 +8,21 @@ import windows
|
||||
registry = windows.system.registry
|
||||
print("Registry is <{0}>".format(registry))
|
||||
|
||||
current_user = registry["HKEY_CURRENT_USER"]
|
||||
current_user = registry("HKEY_CURRENT_USER")
|
||||
print("HKEY_CURRENT_USER is <{0}>".format(current_user))
|
||||
subkeys_name = [s.name for s in current_user.subkeys]
|
||||
print("HKEY_CURRENT_USER subkeys names are:")
|
||||
pprint.pprint(subkeys_name)
|
||||
|
||||
print("Opening 'Software' in HKEY_CURRENT_USER: {0}".format(current_user["Software"]))
|
||||
print("We can also open it in one access: {0}".format(registry[r"HKEY_CURRENT_USER\Sofware"]))
|
||||
print("Opening 'Software' in HKEY_CURRENT_USER: {0}".format(current_user("Software")))
|
||||
print("We can also open it in one access: {0}".format(registry(r"HKEY_CURRENT_USER\Sofware")))
|
||||
print("Looking at CurrentVersion")
|
||||
|
||||
windows_info = registry["HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion"]
|
||||
windows_info = registry("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion")
|
||||
print("Key is {0}".format(windows_info))
|
||||
|
||||
print("values are:")
|
||||
pprint.pprint(windows_info.values)
|
||||
|
||||
registered_owner = windows_info.get("RegisteredOwner")
|
||||
registered_owner = windows_info["RegisteredOwner"]
|
||||
print("registered owner = <{0}>".format(registered_owner))
|
||||
@@ -0,0 +1,69 @@
|
||||
import sys
|
||||
import os.path
|
||||
import pprint
|
||||
sys.path.append(os.path.abspath(__file__ + "\..\.."))
|
||||
|
||||
import windows
|
||||
import windows.test
|
||||
|
||||
from windows.generated_def.winstructs import *
|
||||
|
||||
python_code = """
|
||||
import windows
|
||||
import ctypes
|
||||
import windows
|
||||
from windows.winobject.exception import VectoredException
|
||||
import windows.generated_def.windef as windef
|
||||
from windows.generated_def.winstructs import *
|
||||
|
||||
windows.utils.create_console()
|
||||
|
||||
module_to_trace = "gdi32.dll"
|
||||
nb_repeat = [5]
|
||||
|
||||
@VectoredException
|
||||
def handler(exc):
|
||||
if exc[0].ExceptionRecord[0].ExceptionCode == EXCEPTION_ACCESS_VIOLATION:
|
||||
print("")
|
||||
target_addr = ctypes.cast(exc[0].ExceptionRecord[0].ExceptionInformation[1], ctypes.c_void_p).value
|
||||
print("Instr at {0} accessed to addr {1} ({2})".format(hex(exc[0].ExceptionRecord[0].ExceptionAddress), hex(target_addr), module_to_trace))
|
||||
windows.winproxy.VirtualProtect(target_page, code_size, windef.PAGE_EXECUTE_READWRITE)
|
||||
nb_repeat[0] -= 1
|
||||
if nb_repeat[0]:
|
||||
exc[0].ContextRecord[0].EEFlags.TF = 1
|
||||
else:
|
||||
print("No more tracing !")
|
||||
return windef.EXCEPTION_CONTINUE_EXECUTION
|
||||
else:
|
||||
print("Exception of type {0}".format(exc[0].ExceptionRecord[0].ExceptionCode))
|
||||
print("Resetting page protection to <PAGE_READWRITE>")
|
||||
windows.winproxy.VirtualProtect(target_page, code_size, windef.PAGE_READWRITE)
|
||||
return windef.EXCEPTION_CONTINUE_EXECUTION
|
||||
|
||||
|
||||
windows.winproxy.AddVectoredExceptionHandler(0, handler)
|
||||
|
||||
print("Tracing execution in module: <{0}>".format(module_to_trace))
|
||||
|
||||
module = [x for x in windows.current_process.peb.modules if x.name == module_to_trace][0]
|
||||
target_page = module.baseaddr
|
||||
code_size = module.pe.get_OptionalHeader().SizeOfCode
|
||||
|
||||
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)
|
||||
x = c.execute_python(python_code)
|
||||
|
||||
c.threads[0].resume()
|
||||
|
||||
import time
|
||||
time.sleep(0.1)
|
||||
|
||||
for t in c.threads:
|
||||
t.suspend()
|
||||
|
||||
time.sleep(1)
|
||||
c.exit()
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
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)))
|
||||
@@ -0,0 +1,43 @@
|
||||
import sys
|
||||
import os.path
|
||||
import pprint
|
||||
sys.path.append(os.path.abspath(__file__ + "\..\.."))
|
||||
|
||||
import ctypes
|
||||
import windows
|
||||
from windows.winobject.exception import VectoredException
|
||||
import windows.generated_def.windef as windef
|
||||
from windows.generated_def.winstructs import *
|
||||
|
||||
|
||||
@VectoredException
|
||||
def handler(exc):
|
||||
print("==Entry of VEH handler==")
|
||||
if exc[0].ExceptionRecord[0].ExceptionCode == EXCEPTION_ACCESS_VIOLATION:
|
||||
target_addr = ctypes.cast(exc[0].ExceptionRecord[0].ExceptionInformation[1], ctypes.c_void_p).value
|
||||
print("Instr at {0} accessed to addr {1}".format(hex(exc[0].ExceptionRecord[0].ExceptionAddress), hex(target_addr)))
|
||||
print("Resetting page protection to <PAGE_READWRITE>")
|
||||
windows.winproxy.VirtualProtect(target_page, 0x1000, windef.PAGE_READWRITE)
|
||||
exc[0].ContextRecord[0].EEFlags.TF = 1
|
||||
return windef.EXCEPTION_CONTINUE_EXECUTION
|
||||
else:
|
||||
print("Exception of type {0}".format(exc[0].ExceptionRecord[0].ExceptionCode))
|
||||
print("Resetting page protection to <PAGE_NOACCESS>")
|
||||
windows.winproxy.VirtualProtect(target_page, 0x1000, windef.PAGE_NOACCESS)
|
||||
return windef.EXCEPTION_CONTINUE_EXECUTION
|
||||
|
||||
|
||||
windows.winproxy.AddVectoredExceptionHandler(0, handler)
|
||||
|
||||
target_page = windows.current_process.virtual_alloc(0x1000)
|
||||
print("Protected page is at <{0}>".format(hex(target_page)))
|
||||
print("Setting page protection to <PAGE_NOACCESS>")
|
||||
windows.winproxy.VirtualProtect(target_page, 0x1000, windef.PAGE_NOACCESS)
|
||||
|
||||
print("")
|
||||
v = ctypes.c_uint.from_address(target_page).value
|
||||
print("Value 1 read")
|
||||
|
||||
print("")
|
||||
v = ctypes.c_uint.from_address(target_page + 0x10).value
|
||||
print("Value 2 read")
|
||||
@@ -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]))
|
||||
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
import sys
|
||||
import os.path
|
||||
import pprint
|
||||
sys.path.append(os.path.abspath(__file__ + "\..\.."))
|
||||
|
||||
import windows
|
||||
|
||||
print("WMI requester is {0}".format(windows.system.wmi))
|
||||
|
||||
print("Selecting * from 'Win32_Process'")
|
||||
result = windows.system.wmi.select("Win32_Process")
|
||||
|
||||
print("They are <{0}> processes".format(len(result)))
|
||||
|
||||
print("Looking for ourself via pid")
|
||||
us = [p for p in result if int(p["ProcessId"]) == windows.current_process.pid][0]
|
||||
|
||||
print("Some info about our process:")
|
||||
print(" * {0} -> {1}".format("Name", us["Name"]))
|
||||
print(" * {0} -> {1}".format("ProcessId", us["ProcessId"]))
|
||||
print(" * {0} -> {1}".format("OSName", us["OSName"]))
|
||||
print(" * {0} -> {1}".format("UserModeTime", us["UserModeTime"]))
|
||||
print(" * {0} -> {1}".format("WindowsVersion", us["WindowsVersion"]))
|
||||
print(" * {0} -> {1}".format("CommandLine", us["CommandLine"]))
|
||||
|
||||
print("<Select Caption,FileSystem,FreeSpace from Win32_LogicalDisk>:")
|
||||
for vol in windows.system.wmi.select("Win32_LogicalDisk", ["Caption", "FileSystem", "FreeSpace"]):
|
||||
print(" * " + str(vol))
|
||||
|
||||
|
||||
|
||||
@@ -14,6 +14,10 @@ setup(
|
||||
license = 'BSD',
|
||||
keywords = 'windows python',
|
||||
url = '',
|
||||
py_modules= ['windows'],
|
||||
packages = ['windows'],
|
||||
packages = ['windows',
|
||||
'windows.generated_def',
|
||||
'windows.native_exec',
|
||||
'windows.utils',
|
||||
'windows.winobject',
|
||||
'windows.test'],
|
||||
)
|
||||
@@ -1,8 +0,0 @@
|
||||
TODO:
|
||||
- ProcessMemory object ? (metasm like)
|
||||
|
||||
FIXME:
|
||||
- WMI
|
||||
- COM initialisation when injected in another process
|
||||
- The CoInitialize might be already called
|
||||
- Fix that
|
||||
+17
-8
@@ -11,28 +11,37 @@ Exported:
|
||||
current_thread : :class:`windows.winobject.CurrentThread`
|
||||
"""
|
||||
|
||||
from . import winproxy
|
||||
from .utils import VirtualProtected
|
||||
from .winobject import System, CurrentProcess, CurrentThread
|
||||
|
||||
from windows import winproxy
|
||||
from windows import winobject
|
||||
|
||||
from winobject.system import System
|
||||
from winobject.process import CurrentProcess, CurrentThread
|
||||
|
||||
|
||||
system = System()
|
||||
current_process = CurrentProcess()
|
||||
current_thread = CurrentThread()
|
||||
|
||||
del System
|
||||
del CurrentProcess
|
||||
del CurrentThread
|
||||
|
||||
# Late import: other imports should go here
|
||||
# Do not move it: risk of circular import
|
||||
|
||||
import windows.vectored_exception
|
||||
import windows.wmi
|
||||
import windows.utils
|
||||
import windows.debug
|
||||
import windows.wintrust
|
||||
import windows.syswow64
|
||||
import windows.com
|
||||
|
||||
__all__ = ["system", "VirtualProtected", 'current_process', 'current_thread', 'winproxy']
|
||||
__all__ = ["system", 'current_process', 'current_thread']
|
||||
|
||||
import os
|
||||
|
||||
if bool(os.environ.get("SPHINX_BUILD", 0)):
|
||||
# I know it's shameful
|
||||
# But it's the only way I can think of right know to get a full class
|
||||
# But it's the only way I can think of right now to get a full class
|
||||
# of PEFile for documentation purpose u_u
|
||||
|
||||
ppe = windows.current_process.peb.modules[0].pe
|
||||
|
||||
+176
@@ -0,0 +1,176 @@
|
||||
import struct
|
||||
import ctypes
|
||||
import functools
|
||||
from ctypes.wintypes import HRESULT, byref, pointer, cast
|
||||
|
||||
import windows
|
||||
from windows import winproxy
|
||||
from windows.generated_def.winstructs import *
|
||||
|
||||
from windows.generated_def import RPC_C_IMP_LEVEL_IMPERSONATE, CLSCTX_INPROC_SERVER
|
||||
from windows.generated_def import interfaces
|
||||
from windows.generated_def.interfaces import generate_IID, IID
|
||||
|
||||
|
||||
|
||||
# Simple Implem to create COM Interface in Python (COM -> Python)
|
||||
def create_c_callable(func, types, keepalive=[]):
|
||||
func_type = ctypes.WINFUNCTYPE(*types)
|
||||
c_callable = func_type(func)
|
||||
# Dirty, but the other method require native code execution
|
||||
c_callback_addr = ctypes.c_ulong.from_address(id(c_callable._objects['0']) + 3 * ctypes.sizeof(ctypes.c_void_p)).value
|
||||
keepalive.append(c_callable)
|
||||
return c_callback_addr
|
||||
|
||||
|
||||
def init():
|
||||
t = winproxy.CoInitializeEx()
|
||||
if t:
|
||||
return t
|
||||
return winproxy.CoInitializeSecurity(0, -1, None, 0, 0, RPC_C_IMP_LEVEL_IMPERSONATE, 0,0,0)
|
||||
|
||||
|
||||
class ImprovedSAFEARRAY(SAFEARRAY):
|
||||
@classmethod
|
||||
def of_type(cls, addr, t):
|
||||
self = cls.from_address(addr)
|
||||
self.elt_type = t
|
||||
return self
|
||||
|
||||
@classmethod
|
||||
def from_PSAFEARRAY(self, psafearray):
|
||||
res = cast(psafearray, POINTER(ImprovedSAFEARRAY))[0]
|
||||
return res
|
||||
|
||||
def to_list(self, t=None):
|
||||
if t is None:
|
||||
if hasattr(self, "elt_type"):
|
||||
t = self.elt_type
|
||||
else:
|
||||
raise ValueError("Missing type of the array")
|
||||
if self.cDims != 1:
|
||||
raise NotImplementedError("tagSAFEARRAY if dims != 1")
|
||||
|
||||
nb_element = self.rgsabound[0].cElements
|
||||
llbound = self.rgsabound[0].lLbound
|
||||
if self.cbElements != ctypes.sizeof(t):
|
||||
raise ValueError("Size of elements != sizeof(type)")
|
||||
data = [t.from_address(self.pvData + (i + llbound) * ctypes.sizeof(t)).value for i in range(nb_element)]
|
||||
return data
|
||||
|
||||
#VT_VALUE_TO_TYPE = {
|
||||
#VT_I2 : SHORT,
|
||||
#VT_I4 : LONG,
|
||||
#VT_BSTR : BSTR,
|
||||
#VT_VARIANT : VARIANT,
|
||||
#VT_UI1 : UCHAR,
|
||||
#VT_UI2 : USHORT,
|
||||
#VT_UI4 : DWORD,
|
||||
#VT_I8 : LONGLONG,
|
||||
#VT_UI8 : ULONG64,
|
||||
#VT_INT : INT,
|
||||
#VT_UINT : UINT,
|
||||
#VT_HRESULT : HRESULT,
|
||||
#VT_PTR : PVOID,
|
||||
#VT_LPSTR : LPCSTR,
|
||||
#VT_LPWSTR : LPWSTR,
|
||||
#}
|
||||
|
||||
class ImprovedVariant(VARIANT):
|
||||
@property
|
||||
def asbstr(self):
|
||||
if self.vt != VT_BSTR:
|
||||
raise ValueError("asbstr on non-bstr variant")
|
||||
#import pdb;pdb.set_trace()
|
||||
return self._VARIANT_NAME_3.bstrVal
|
||||
|
||||
@property
|
||||
def aslong(self):
|
||||
if not self.vt in [VT_I4, VT_BOOL]:
|
||||
raise ValueError("aslong on non-long variant")
|
||||
return self._VARIANT_NAME_3.lVal
|
||||
|
||||
@property
|
||||
def asbool(self):
|
||||
if not self.vt in [VT_BOOL]:
|
||||
raise ValueError("get_bstr on non-bool variant")
|
||||
return bool(self.aslong)
|
||||
|
||||
@property
|
||||
def asdispatch(self):
|
||||
if not self.vt in [VT_DISPATCH]:
|
||||
raise ValueError("asdispatch on non-VT_DISPATCH variant")
|
||||
return interfaces.IDispatch(self._VARIANT_NAME_3.pdispVal)
|
||||
|
||||
@property
|
||||
def asshort(self):
|
||||
if not self.vt in [VT_I2]:
|
||||
raise ValueError("asshort on non-VT_I2 variant")
|
||||
return self._VARIANT_NAME_3.iVal
|
||||
|
||||
@property
|
||||
def asbyte(self):
|
||||
if not self.vt in [VT_UI1]:
|
||||
raise ValueError("asbyte on non-VT_UI1 variant")
|
||||
return self._VARIANT_NAME_3.bVal
|
||||
|
||||
@property
|
||||
def asarray(self):
|
||||
if not self.vt & VT_ARRAY:
|
||||
raise ValueError("asarray on non-VT_ARRAY variant")
|
||||
# TODO: auto extract VT_TYPE for the array ?
|
||||
#type = VT_VALUE_TO_TYPE[self.vt & VT_TYPEMASK]
|
||||
return ImprovedSAFEARRAY.from_PSAFEARRAY(self._VARIANT_NAME_3.parray)
|
||||
|
||||
|
||||
|
||||
def create_instance(clsiid, targetinterface, custom_iid=None):
|
||||
if custom_iid is None:
|
||||
custom_iid = targetinterface.IID
|
||||
return winproxy.CoCreateInstance(byref(clsiid), None, CLSCTX_INPROC_SERVER, byref(custom_iid), byref(targetinterface))
|
||||
|
||||
|
||||
class ComVtable(object):
|
||||
# Name, types
|
||||
_funcs_ = [("QueryInterface", [ctypes.HRESULT, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p]),
|
||||
("AddRef", [ctypes.HRESULT, ctypes.c_void_p]),
|
||||
("Release", [ctypes.HRESULT, ctypes.c_void_p])
|
||||
]
|
||||
|
||||
def __init__(self, **implem_overwrite):
|
||||
self.implems = []
|
||||
self.vtable = self._create_vtable(**implem_overwrite)
|
||||
self.vtable_pointer = ctypes.pointer(self.vtable)
|
||||
self._as_parameter_ = ctypes.addressof(self.vtable_pointer)
|
||||
|
||||
def _create_vtable(self, **implem_overwrite):
|
||||
vtables_names = [x[0] for x in self._funcs_]
|
||||
non_expected_args = [func_name for func_name in implem_overwrite if func_name not in vtables_names]
|
||||
if non_expected_args:
|
||||
raise ValueError("Non expected function : {0}".format(non_expected_args))
|
||||
|
||||
for name, types in self._funcs_:
|
||||
func_implem = implem_overwrite.get(name)
|
||||
if func_implem is None:
|
||||
if hasattr(self, name):
|
||||
func_implem = getattr(self, name)
|
||||
else:
|
||||
raise ValueError("Missing implementation for function <{0}>".format(name))
|
||||
|
||||
if isinstance(func_implem, (int, long)):
|
||||
self.implems.append(func_implem)
|
||||
else:
|
||||
self.implems.append(create_c_callable(func_implem, types))
|
||||
|
||||
class Vtable(ctypes.Structure):
|
||||
_fields_ = [(name, ctypes.c_void_p) for name in vtables_names]
|
||||
return Vtable(*self.implems)
|
||||
|
||||
def QueryInterface(self, *args):
|
||||
return 1
|
||||
|
||||
def AddRef(self, *args):
|
||||
return 1
|
||||
|
||||
def Release(self, *args):
|
||||
return 0
|
||||
@@ -0,0 +1,757 @@
|
||||
import os.path
|
||||
from collections import defaultdict
|
||||
|
||||
import windows
|
||||
import windows.winobject.exception as winexception
|
||||
import windows.native_exec.simple_x86 as x86
|
||||
import windows.native_exec.simple_x64 as x64
|
||||
|
||||
from windows.winobject.process import WinProcess, WinThread
|
||||
from windows.dbgprint import dbgprint
|
||||
from windows import winproxy
|
||||
from windows.generated_def.winstructs import *
|
||||
from .generated_def import windef
|
||||
|
||||
|
||||
from windows.winobject.exception import VectoredException
|
||||
|
||||
|
||||
|
||||
STANDARD_BP = "BP"
|
||||
HARDWARE_EXEC_BP = "HXBP"
|
||||
|
||||
class DEBUG_EVENT(DEBUG_EVENT):
|
||||
KNOWN_EVENT_CODE = dict((x,x) for x in [EXCEPTION_DEBUG_EVENT,
|
||||
CREATE_THREAD_DEBUG_EVENT, CREATE_PROCESS_DEBUG_EVENT,
|
||||
EXIT_THREAD_DEBUG_EVENT, EXIT_PROCESS_DEBUG_EVENT, LOAD_DLL_DEBUG_EVENT,
|
||||
UNLOAD_DLL_DEBUG_EVENT, OUTPUT_DEBUG_STRING_EVENT, RIP_EVENT])
|
||||
|
||||
@property
|
||||
def code(self):
|
||||
return self.KNOWN_EVENT_CODE.get(self.dwDebugEventCode, self.dwDebugEventCode)
|
||||
|
||||
class Debugger(object):
|
||||
"""A debugger based on standard Win32 API. Handle standard (int3) and Hardware-Exec Breakpoints"""
|
||||
def __init__(self, target, already_debuggable=False):
|
||||
"""``target`` must be a WinProcess.
|
||||
|
||||
``already_debuggable`` must be set to ``True`` if process is already expecting a debugger (created with ``DEBUG_PROCESS``)"""
|
||||
self._init_dispatch_handlers()
|
||||
self.target = target
|
||||
self.is_target_launched = False
|
||||
if not already_debuggable:
|
||||
winproxy.DebugActiveProcess(target.pid)
|
||||
self.processes = {}
|
||||
self.threads = {}
|
||||
self.current_process = None
|
||||
self.current_thread = None
|
||||
# List of breakpoints
|
||||
self.breakpoints = {}
|
||||
self._pending_breakpoints = {} #Breakpoints to put in new process / threads
|
||||
# Values rewritten by "\xcc"
|
||||
self._memory_save = defaultdict(dict)
|
||||
# Dict of {tid : {drx taken : BP}}
|
||||
self._hardware_breakpoint = defaultdict(dict)
|
||||
# Breakpoints to reput..
|
||||
self._breakpoint_to_reput = {}
|
||||
|
||||
self._module_by_process = {}
|
||||
|
||||
self._pending_breakpoints_new = defaultdict(list)
|
||||
|
||||
|
||||
def _init_dispatch_handlers(self):
|
||||
dbg_evt_dispatch = {}
|
||||
dbg_evt_dispatch[EXCEPTION_DEBUG_EVENT] = self._handle_exception
|
||||
dbg_evt_dispatch[CREATE_THREAD_DEBUG_EVENT] = self._handle_create_thread
|
||||
dbg_evt_dispatch[CREATE_PROCESS_DEBUG_EVENT] = self._handle_create_process
|
||||
dbg_evt_dispatch[EXIT_PROCESS_DEBUG_EVENT] = self._handle_exit_process
|
||||
dbg_evt_dispatch[EXIT_THREAD_DEBUG_EVENT] = self._handle_exit_thread
|
||||
dbg_evt_dispatch[LOAD_DLL_DEBUG_EVENT] = self._handle_load_dll
|
||||
dbg_evt_dispatch[UNLOAD_DLL_DEBUG_EVENT] = self._handle_unload_dll
|
||||
dbg_evt_dispatch[RIP_EVENT] = self._handle_rip
|
||||
dbg_evt_dispatch[OUTPUT_DEBUG_STRING_EVENT] = self._handle_output_debug_string
|
||||
self._DebugEventCode_dispatch = dbg_evt_dispatch
|
||||
|
||||
def _debug_event_generator(self):
|
||||
while True:
|
||||
debug_event = DEBUG_EVENT()
|
||||
winproxy.WaitForDebugEvent(debug_event)
|
||||
yield debug_event
|
||||
|
||||
def _finish_debug_event(self, event, action):
|
||||
if action not in [windef.DBG_CONTINUE, windef.DBG_EXCEPTION_NOT_HANDLED]:
|
||||
raise ValueError('Unknow action : <0>'.format(action))
|
||||
winproxy.ContinueDebugEvent(event.dwProcessId, event.dwThreadId, action)
|
||||
|
||||
def _update_debugger_state(self, debug_event):
|
||||
self.current_process = self.processes[debug_event.dwProcessId]
|
||||
self.current_thread = self.threads[debug_event.dwThreadId]
|
||||
|
||||
def _dispatch_debug_event(self, debug_event):
|
||||
#print("DISPATCH {0}".format(DEBUG_EVENT.KNOWN_EVENT_CODE.get(debug_event.dwDebugEventCode)))
|
||||
handler = self._DebugEventCode_dispatch.get(debug_event.dwDebugEventCode, self._handle_unknown_debug_event)
|
||||
return handler(debug_event)
|
||||
|
||||
def _dispatch_breakpoint(self, exception, addr):
|
||||
bp = self.breakpoints[self.current_process.pid][addr]
|
||||
x = bp.trigger(self, exception)
|
||||
return x
|
||||
|
||||
def _resolve(self, addr, target):
|
||||
if not isinstance(addr, basestring):
|
||||
return addr
|
||||
dll, api = addr.split("!")
|
||||
dll = dll.lower()
|
||||
modules = self._module_by_process[target.pid]
|
||||
mod = None
|
||||
if dll in modules:
|
||||
mod = [modules[dll]]
|
||||
if not mod:
|
||||
return None
|
||||
# TODO: optim exports are the same for whole system (32 vs 64 bits)
|
||||
# I don't have to reparse the exports each time..
|
||||
# Try to interpret api as an int
|
||||
try:
|
||||
api_int = int(api, 0)
|
||||
return mod[0].baseaddr + api_int
|
||||
except ValueError:
|
||||
pass
|
||||
exports = mod[0].exports
|
||||
if api not in exports:
|
||||
raise ValueError("Unknown API <{0}> in DLL {1}".format(api, dll))
|
||||
return exports[api]
|
||||
|
||||
|
||||
def add_pending_breakpoint(self, bp, target):
|
||||
self._pending_breakpoints_new[target].append(bp)
|
||||
|
||||
def _setup_breakpoint(self, bp, target):
|
||||
_setup_method = getattr(self, "_setup_breakpoint_" + bp.type)
|
||||
if target is None:
|
||||
if bp.type == STANDARD_BP: #TODO: better..
|
||||
targets = self.processes.values()
|
||||
else:
|
||||
targets = self.threads.values()
|
||||
else:
|
||||
targets = [target]
|
||||
for target in targets:
|
||||
return _setup_method(bp, target)
|
||||
|
||||
|
||||
def _setup_breakpoint_BP(self, bp, target):
|
||||
if not isinstance(target, WinProcess):
|
||||
raise ValueError("SETUP STANDARD_BP on {0}".format(target))
|
||||
|
||||
addr = self._resolve(bp.addr, target)
|
||||
if addr is None:
|
||||
return False
|
||||
self._memory_save[target.pid][addr] = target.read_memory(addr, 1)
|
||||
self.breakpoints[target.pid][addr] = bp
|
||||
target.write_memory(addr, "\xcc")
|
||||
return True
|
||||
|
||||
def _setup_breakpoint_HXBP(self, bp, target):
|
||||
if not isinstance(target, WinThread):
|
||||
raise ValueError("SETUP HXBP_BP on {0}".format(target))
|
||||
# Todo: opti, not reparse exports for all thread of the same process..
|
||||
addr = self._resolve(bp.addr, target.owner)
|
||||
if addr is None:
|
||||
return False
|
||||
x = self._hardware_breakpoint[target.tid]
|
||||
if all(pos in x for pos in range(4)):
|
||||
raise ValueError("Cannot put {0} in {1} (DRx full)".format(bp, target))
|
||||
empty_drx = str([pos for pos in range(4) if pos not in x][0])
|
||||
ctx = target.context
|
||||
ctx.EDr7.GE = 1
|
||||
ctx.EDr7.LE = 1
|
||||
setattr(ctx.EDr7, "L" + empty_drx, 1)
|
||||
setattr(ctx, "Dr" + empty_drx, addr)
|
||||
x[int(empty_drx)] = bp
|
||||
target.set_context(ctx)
|
||||
self.breakpoints[target.owner.pid][addr] = bp
|
||||
return True
|
||||
|
||||
def _setup_pending_breakpoints_new_process(self, new_process):
|
||||
for bp in self._pending_breakpoints_new[None]:
|
||||
if bp.apply_to_target(new_process): #BP for thread or process ?
|
||||
_setup_method = getattr(self, "_setup_breakpoint_" + bp.type)
|
||||
_setup_method(bp, new_process)
|
||||
|
||||
for bp in list(self._pending_breakpoints_new[new_process.pid]):
|
||||
if bp.apply_to_target(new_process):
|
||||
_setup_method = getattr(self, "_setup_breakpoint_" + bp.type)
|
||||
if _setup_method(bp, new_process):
|
||||
self._pending_breakpoints_new[new_process.pid].remove(bp)
|
||||
|
||||
def _setup_pending_breakpoints_new_thread(self, new_thread):
|
||||
for bp in self._pending_breakpoints_new[None]:
|
||||
if bp.apply_to_target(new_thread): #BP for thread or process ?
|
||||
_setup_method = getattr(self, "_setup_breakpoint_" + bp.type)
|
||||
_setup_method(bp, new_thread)
|
||||
|
||||
for bp in self._pending_breakpoints_new[new_thread.owner.pid]:
|
||||
if bp.apply_to_target(new_thread):
|
||||
_setup_method = getattr(self, "_setup_breakpoint_" + bp.type)
|
||||
_setup_method(bp, new_thread)
|
||||
|
||||
for bp in list(self._pending_breakpoints_new[new_thread.tid]):
|
||||
_setup_method = getattr(self, "_setup_breakpoint_" + bp.type)
|
||||
if _setup_method(bp, new_thread):
|
||||
self._pending_breakpoints_new[new_thread.tid].remove(bp)
|
||||
|
||||
|
||||
def _setup_pending_breakpoints_load_dll(self, dll_name):
|
||||
for bp in self._pending_breakpoints_new[None]:
|
||||
if isinstance(bp.addr, basestring):
|
||||
target_dll = bp.addr.split("!")[0]
|
||||
if target_dll == dll_name:
|
||||
_setup_method = getattr(self, "_setup_breakpoint_" + bp.type)
|
||||
if bp.apply_to_target(self.current_process):
|
||||
_setup_method(bp, self.current_process)
|
||||
else:
|
||||
for t in self.current_process.threads:
|
||||
_setup_method(bp, t)
|
||||
|
||||
for bp in self._pending_breakpoints_new[self.current_process.pid]:
|
||||
if isinstance(bp.addr, basestring):
|
||||
target_dll = bp.addr.split("!")[0]
|
||||
if target_dll == dll_name:
|
||||
_setup_method = getattr(self, "_setup_breakpoint_" + bp.type)
|
||||
_setup_method(bp, self.current_process)
|
||||
|
||||
for thread in self.current_process.threads:
|
||||
for bp in self._pending_breakpoints_new[thread.tid]:
|
||||
if isinstance(bp.addr, basestring):
|
||||
target_dll = bp.addr.split("!")[0]
|
||||
if target_dll == dll_name:
|
||||
_setup_method = getattr(self, "_setup_breakpoint_" + bp.type)
|
||||
_setup_method(bp, self.thread)
|
||||
|
||||
def _pass_breakpoint(self, addr):
|
||||
process = self.current_process
|
||||
thread = self.current_thread
|
||||
process.write_memory(addr, self._memory_save[process.pid][addr])
|
||||
regs = thread.context
|
||||
regs.EFlags |= (1 << 8)
|
||||
regs.pc -= 1
|
||||
thread.set_context(regs)
|
||||
self._breakpoint_to_reput[thread.tid] = addr #Register pending breakpoint for next single step
|
||||
|
||||
# debug event handlers
|
||||
def _handle_unknown_debug_event(self, debug_event):
|
||||
raise NotImplementedError("dwDebugEventCode = {0}".format(debug_event.dwDebugEventCode))
|
||||
|
||||
def _handle_exception(self, debug_event):
|
||||
"""Handle EXCEPTION_DEBUG_EVENT"""
|
||||
exception = debug_event.u.Exception
|
||||
self._update_debugger_state(debug_event)
|
||||
|
||||
if windows.current_process.bitness == 32:
|
||||
exception.__class__ = winexception.EEXCEPTION_DEBUG_INFO32
|
||||
else:
|
||||
exception.__class__ = winexception.EEXCEPTION_DEBUG_INFO64
|
||||
|
||||
excp_code = exception.ExceptionRecord.ExceptionCode
|
||||
excp_addr = exception.ExceptionRecord.ExceptionAddress
|
||||
if excp_code in [EXCEPTION_BREAKPOINT, STATUS_WX86_BREAKPOINT] and excp_addr in self.breakpoints[self.current_process.pid]:
|
||||
continue_flag = self._dispatch_breakpoint(exception, excp_addr)
|
||||
self._pass_breakpoint(excp_addr)
|
||||
return continue_flag
|
||||
elif excp_code in [EXCEPTION_SINGLE_STEP, STATUS_WX86_SINGLE_STEP]:
|
||||
if self.current_thread.tid in self._breakpoint_to_reput:
|
||||
addr = self._breakpoint_to_reput[self.current_thread.tid]
|
||||
del self._breakpoint_to_reput[self.current_thread.tid]
|
||||
# Re-put the breakpoint
|
||||
self.current_process.write_memory(addr, "\xcc")
|
||||
return DBG_CONTINUE
|
||||
elif excp_addr in self.breakpoints[self.current_process.pid]:
|
||||
# Verif that's not a standard BP ?
|
||||
bp = self.breakpoints[self.current_process.pid][excp_addr]
|
||||
#import pdb;pdb.set_trace()
|
||||
bp.trigger(self, exception)
|
||||
ctx = self.current_thread.context
|
||||
ctx.EEFlags.RF = 1
|
||||
self.current_thread.set_context(ctx)
|
||||
return DBG_CONTINUE
|
||||
else:
|
||||
return self.on_exception(exception)
|
||||
else: # Do not trigger self.on_exception if breakpoint was registered
|
||||
return self.on_exception(exception)
|
||||
|
||||
|
||||
def _get_loaded_dll(self, load_dll):
|
||||
name_sufix = ""
|
||||
pe = windows.pe_parse.GetPEFile(load_dll.lpBaseOfDll, self.current_process)
|
||||
if self.current_process.bitness == 32 and pe.bitness == 64:
|
||||
name_sufix = "64"
|
||||
|
||||
if not load_dll.lpImageName:
|
||||
return pe.export_name + name_sufix
|
||||
try:
|
||||
addr = self.current_process.read_ptr(load_dll.lpImageName)
|
||||
except:
|
||||
addr = None
|
||||
|
||||
if not addr:
|
||||
pe = windows.pe_parse.GetPEFile(load_dll.lpBaseOfDll, self.current_process)
|
||||
return pe.export_name + name_sufix
|
||||
|
||||
if load_dll.fUnicode:
|
||||
return self.current_process.read_wstring(addr) + name_sufix
|
||||
return self.current_process.read_string(addr) + name_sufix
|
||||
|
||||
def _handle_create_process(self, debug_event):
|
||||
"""Handle CREATE_PROCESS_DEBUG_EVENT"""
|
||||
create_process = debug_event.u.CreateProcessInfo
|
||||
|
||||
self.current_process = WinProcess._from_handle(create_process.hProcess)
|
||||
self.current_thread = WinThread._from_handle(create_process.hThread)
|
||||
self.threads[self.current_thread.tid] = self.current_thread
|
||||
self.processes[self.current_process.pid] = self.current_process
|
||||
self.breakpoints[self.current_process.pid] = {}
|
||||
self._module_by_process[self.current_process.pid] = {}
|
||||
self._update_debugger_state(debug_event)
|
||||
self._setup_pending_breakpoints_new_process(self.current_process)
|
||||
self._setup_pending_breakpoints_new_thread(self.current_thread)
|
||||
return self.on_create_process(create_process)
|
||||
# TODO: clode hFile
|
||||
|
||||
def _handle_exit_process(self, debug_event):
|
||||
"""Handle EXIT_PROCESS_DEBUG_EVENT"""
|
||||
self._update_debugger_state(debug_event)
|
||||
exit_process = debug_event.u.ExitProcess
|
||||
retvalue = self.on_exit_process(exit_process)
|
||||
del self.threads[self.current_thread.tid]
|
||||
del self.processes[self.current_process.pid]
|
||||
# Hack IT, ContinueDebugEvent will close the HANDLE for us
|
||||
# Should we make another handle instead ?
|
||||
dbgprint("Removing handle {0} for {1} (will be closed by continueDebugEvent".format(hex(self.current_process._handle), self.current_process), "HANDLE")
|
||||
del self.current_process._handle
|
||||
del self.current_thread._handle
|
||||
return retvalue
|
||||
|
||||
def _handle_create_thread(self, debug_event):
|
||||
"""Handle CREATE_THREAD_DEBUG_EVENT"""
|
||||
create_thread = debug_event.u.CreateThread
|
||||
self.current_thread = WinThread._from_handle(create_thread.hThread)
|
||||
self.threads[self.current_thread.tid] = self.current_thread
|
||||
#import pdb;pdb.set_trace()
|
||||
self._setup_pending_breakpoints_new_thread(self.current_thread)
|
||||
return self.on_create_thread(create_thread)
|
||||
|
||||
|
||||
def _handle_exit_thread(self, debug_event):
|
||||
"""Handle EXIT_THREAD_DEBUG_EVENT"""
|
||||
self._update_debugger_state(debug_event)
|
||||
exit_thread = debug_event.u.ExitThread
|
||||
retvalue = self.on_exit_thread(exit_thread)
|
||||
del self.threads[self.current_thread.tid]
|
||||
# Hack IT, ContinueDebugEvent will close the HANDLE for us
|
||||
# Should we make another handle instead ?
|
||||
dbgprint("Removing handle {0} for {1} (will be closed by continueDebugEvent".format(hex(self.current_thread._handle), self.current_thread), "HANDLE")
|
||||
del self.current_thread._handle
|
||||
return retvalue
|
||||
|
||||
def _handle_load_dll(self, debug_event):
|
||||
"""Handle LOAD_DLL_DEBUG_EVENT"""
|
||||
self._update_debugger_state(debug_event)
|
||||
load_dll = debug_event.u.LoadDll
|
||||
dll = self._get_loaded_dll(load_dll)
|
||||
dll_name = os.path.basename(dll).lower()
|
||||
self._module_by_process[self.current_process.pid][dll_name] = windows.pe_parse.GetPEFile(load_dll.lpBaseOfDll, self.current_process)
|
||||
self._setup_pending_breakpoints_load_dll(dll_name)
|
||||
return self.on_load_dll(load_dll)
|
||||
|
||||
def _handle_unload_dll(self, debug_event):
|
||||
"""Handle UNLOAD_DLL_DEBUG_EVENT"""
|
||||
self._update_debugger_state(debug_event)
|
||||
unload_dll = debug_event.u.UnloadDll
|
||||
return self.on_unload_dll(unload_dll)
|
||||
|
||||
def _handle_output_debug_string(self, debug_event):
|
||||
"""Handle OUTPUT_DEBUG_STRING_EVENT"""
|
||||
self._update_debugger_state(debug_event)
|
||||
debug_string = debug_event.u.DebugString
|
||||
return self.on_output_debug_string(debug_string)
|
||||
|
||||
def _handle_rip(self, debug_event):
|
||||
"""Handle RIP_EVENT"""
|
||||
self._update_debugger_state(debug_event)
|
||||
rip_info = debug_event.u.RipInfo
|
||||
return self.on_rip(rip_info)
|
||||
|
||||
# Public API
|
||||
def loop(self):
|
||||
"""Debugging loop: handle event / dispatch to breakpoint. Returns when all targets are dead"""
|
||||
for debug_event in self._debug_event_generator():
|
||||
dbg_continue_flag = self._dispatch_debug_event(debug_event)
|
||||
if dbg_continue_flag is None:
|
||||
dbg_continue_flag = DBG_CONTINUE
|
||||
self._finish_debug_event(debug_event, dbg_continue_flag)
|
||||
if not self.processes:
|
||||
break
|
||||
|
||||
def add_bp(self, bp, addr=None, type=None, target=None):
|
||||
"""Add a breakpoint, bp can be:
|
||||
|
||||
* a :class:`Breakpoint` (addr and type must be None)
|
||||
* any callable (addr and type must NOT be None) (NON-TESTED)
|
||||
|
||||
If the ``bp`` type is ``STANDARD_BP``, target can be None (all targets) or a process.
|
||||
|
||||
If the ``bp`` type is ``HARDWARE_EXEC_BP``, target can be None (all targets), a process or a thread.
|
||||
"""
|
||||
if getattr(bp, "addr", None) is None:
|
||||
if addr is None or type is None:
|
||||
raise ValueError("SUCK YOUR NONE")
|
||||
bp = ProxyBreakpoint(bp, addr, type)
|
||||
else:
|
||||
if addr is not None or type is not None:
|
||||
raise ValueError("Given <addr|type> by parameters but BP object have them")
|
||||
del addr
|
||||
del type
|
||||
|
||||
if target is None:
|
||||
# Need to add it to all other breakpoint
|
||||
self.add_pending_breakpoint(bp, None)
|
||||
elif target is not None:
|
||||
# Check that targets are accepted
|
||||
if target not in self.processes.values() + self.threads.values():
|
||||
if target == self.target: # Original target (that have not been lauched yet)
|
||||
return self.add_pending_breakpoint(bp, target)
|
||||
else:
|
||||
raise ValueError("Unknown target {0}".format(target))
|
||||
return self._setup_breakpoint(bp, target)
|
||||
|
||||
# Public callback
|
||||
def on_exception(self, exception):
|
||||
"""Called on exception event other that known breakpoint. ``exception`` is one of the following type:
|
||||
|
||||
* :class:`windows.winobject.exception.EEXCEPTION_DEBUG_INFO32`
|
||||
* :class:`windows.winobject.exception.EEXCEPTION_DEBUG_INFO64`
|
||||
|
||||
The default behaviour is to return ``DBG_CONTINUE`` for the known exception code
|
||||
and ``DBG_EXCEPTION_NOT_HANDLED`` else
|
||||
"""
|
||||
if not exception.ExceptionRecord.ExceptionCode in winexception.exception_name_by_value:
|
||||
return DBG_EXCEPTION_NOT_HANDLED
|
||||
return DBG_CONTINUE
|
||||
|
||||
def on_create_process(self, create_process):
|
||||
"""Called on create_process event (for param type see https://msdn.microsoft.com/en-us/library/windows/desktop/ms679286(v=vs.85).aspx)"""
|
||||
pass
|
||||
|
||||
def on_exit_process(self, exit_process):
|
||||
"""Called on exit_process event (for param type see https://msdn.microsoft.com/en-us/library/windows/desktop/ms679334(v=vs.85).aspx)"""
|
||||
pass
|
||||
|
||||
def on_create_thread(self, create_thread):
|
||||
"""Called on create_thread event (for param type see https://msdn.microsoft.com/en-us/library/windows/desktop/ms679287(v=vs.85).aspx)"""
|
||||
pass
|
||||
|
||||
def on_exit_thread(self, exit_thread):
|
||||
"""Called on exit_thread event (for param type see https://msdn.microsoft.com/en-us/library/windows/desktop/ms679335(v=vs.85).aspx)"""
|
||||
pass
|
||||
|
||||
def on_load_dll(self, load_dll):
|
||||
"""Called on load_dll event (for param type see https://msdn.microsoft.com/en-us/library/windows/desktop/ms680351(v=vs.85).aspx)"""
|
||||
pass
|
||||
|
||||
def on_unload_dll(self, unload_dll):
|
||||
"""Called on unload_dll event (for param type see https://msdn.microsoft.com/en-us/library/windows/desktop/ms681403(v=vs.85).aspx)"""
|
||||
pass
|
||||
|
||||
def on_output_debug_string(self, debug_string):
|
||||
"""Called on debug_string event (for param type see https://msdn.microsoft.com/en-us/library/windows/desktop/ms680545(v=vs.85).aspx)"""
|
||||
pass
|
||||
|
||||
def on_rip(self, rip_info):
|
||||
"""Called on rip_info event (for param type see https://msdn.microsoft.com/en-us/library/windows/desktop/ms680587(v=vs.85).aspx)"""
|
||||
pass
|
||||
|
||||
def debug(path, args=None, dwCreationFlags=0, show_windows=False):
|
||||
dwCreationFlags |= DEBUG_PROCESS
|
||||
c = windows.utils.create_process(path, args=args, dwCreationFlags=dwCreationFlags, show_windows=show_windows)
|
||||
return Debugger(c, already_debuggable=True)
|
||||
|
||||
|
||||
class Breakpoint(object):
|
||||
"""An standard (Int3) breakpoint (type == ``STANDARD_BP``)"""
|
||||
type = STANDARD_BP # REAL BP
|
||||
def __init__(self, addr):
|
||||
self.addr = addr
|
||||
|
||||
def apply_to_target(self, target):
|
||||
return isinstance(target, WinProcess)
|
||||
|
||||
def trigger(self, dbg, exception):
|
||||
"""Called when breakpoint is hit"""
|
||||
pass
|
||||
|
||||
|
||||
class ProxyBreakpoint(Breakpoint):
|
||||
def __init__(self, target, addr, type):
|
||||
self.target = target
|
||||
self.addr = addr
|
||||
self.type = type
|
||||
|
||||
def trigger(self, dbg, exception):
|
||||
return self.target(dbg, exception)
|
||||
|
||||
|
||||
class HXBreakpoint(Breakpoint):
|
||||
"""An hardware-execution breakpoint (type == ``HARDWARE_EXEC_BP``)"""
|
||||
type = HARDWARE_EXEC_BP
|
||||
|
||||
def apply_to_target(self, target):
|
||||
return isinstance(target, WinThread)
|
||||
|
||||
|
||||
class LocalDebugger(object):
|
||||
"""A debugger interface around :func:`AddVectoredExceptionHandler`"""
|
||||
def __init__(self):
|
||||
self.breakpoints = {}
|
||||
self._memory_save = {}
|
||||
self._reput_breakpoint = {}
|
||||
self._hxbp_breakpoint = defaultdict(dict)
|
||||
|
||||
self.callback_vectored = winexception.VectoredException(self.callback)
|
||||
winproxy.AddVectoredExceptionHandler(0, self.callback_vectored)
|
||||
self.setup_hxbp_callback_vectored = winexception.VectoredException(self.setup_hxbp_callback)
|
||||
self.hxbp_info = None
|
||||
self.code = windows.native_exec.create_function("\xcc\xc3", [PVOID])
|
||||
self.veh_depth = 0
|
||||
self.current_exception = None
|
||||
self.exceptions_stack = [None]
|
||||
|
||||
def get_exception_code(self):
|
||||
"""Return ExceptionCode of current exception"""
|
||||
return self.current_exception[0].ExceptionRecord[0].ExceptionCode
|
||||
|
||||
def get_exception_context(self):
|
||||
"""Return context of current exception"""
|
||||
return self.current_exception[0].ContextRecord[0]
|
||||
|
||||
def single_step(self):
|
||||
"""Make the current thread to single step"""
|
||||
self.get_exception_context().EEFlags.TF = 1
|
||||
return windef.EXCEPTION_CONTINUE_EXECUTION
|
||||
|
||||
def _pass_breakpoint(self, addr, single_step):
|
||||
with windows.utils.VirtualProtected(addr, 1, PAGE_EXECUTE_READWRITE):
|
||||
windows.current_process.write_memory(addr, self._memory_save[addr])
|
||||
self._reput_breakpoint[windows.current_thread.tid] = self.breakpoints[addr], single_step
|
||||
return self.single_step()
|
||||
|
||||
def callback(self, exc):
|
||||
self.exceptions_stack.append(exc)
|
||||
self.current_exception = exc
|
||||
self.veh_depth += 1
|
||||
try:
|
||||
#if hasattr(self, "yolo"):
|
||||
# self.yolo("TST <{0}>".format(self.get_exception_code()))
|
||||
return self.handle_exception(exc)
|
||||
#except Exception as e:
|
||||
# if hasattr(self, "yolo"):
|
||||
# self.yolo(repr(e))
|
||||
# else:
|
||||
# raise
|
||||
# return windef.EXCEPTION_CONTINUE_SEARCH
|
||||
finally:
|
||||
#if hasattr(self, "yolo"):
|
||||
# self.yolo("BYE DBG")
|
||||
self.exceptions_stack.pop()
|
||||
self.current_exception = self.exceptions_stack[-1]
|
||||
self.veh_depth -= 1
|
||||
|
||||
def handle_exception(self, exc):
|
||||
exp_code = self.get_exception_code()
|
||||
context = self.get_exception_context()
|
||||
exp_addr = context.pc
|
||||
|
||||
if exp_code == EXCEPTION_BREAKPOINT and exp_addr in self.breakpoints:
|
||||
res = self.breakpoints[exp_addr].trigger(self, exc)
|
||||
single_step = self.get_exception_context().EEFlags.TF # single step activated by breakpoint
|
||||
if exp_addr in self.breakpoints: # Breakpoint deleted itself ?
|
||||
return self._pass_breakpoint(exp_addr, single_step)
|
||||
return EXCEPTION_CONTINUE_EXECUTION
|
||||
|
||||
if exp_code == EXCEPTION_SINGLE_STEP and windows.current_thread.tid in self._reput_breakpoint:
|
||||
bp, single_step = self._reput_breakpoint[windows.current_thread.tid]
|
||||
self._memory_save[bp.addr] = windows.current_process.read_memory(bp.addr, 1)
|
||||
with windows.utils.VirtualProtected(bp.addr, 1, PAGE_EXECUTE_READWRITE):
|
||||
windows.current_process.write_memory(bp.addr, "\xcc")
|
||||
del self._reput_breakpoint[windows.current_thread.tid]
|
||||
if single_step:
|
||||
return self.on_exception(exc)
|
||||
return windef.EXCEPTION_CONTINUE_EXECUTION
|
||||
elif exp_code == EXCEPTION_SINGLE_STEP and exp_addr in self._hxbp_breakpoint[windows.current_thread.tid]:
|
||||
res = self._hxbp_breakpoint[windows.current_thread.tid][exp_addr].trigger(self, exc)
|
||||
context.EEFlags.RF = 1
|
||||
return EXCEPTION_CONTINUE_EXECUTION
|
||||
return self.on_exception(exc)
|
||||
|
||||
def on_exception(self, exc):
|
||||
"""Called on exception"""
|
||||
print(self.get_exception_code())
|
||||
windows.current_process.exit()
|
||||
if not self.get_exception_code() in winexception.exception_name_by_value:
|
||||
return windef.EXCEPTION_CONTINUE_SEARCH
|
||||
return windef.EXCEPTION_CONTINUE_EXECUTION
|
||||
|
||||
def del_bp(self, bp):
|
||||
if bp.type == STANDARD_BP:
|
||||
with windows.utils.VirtualProtected(bp.addr, 1, PAGE_EXECUTE_READWRITE):
|
||||
windows.current_process.write_memory(bp.addr, self._memory_save[bp.addr])
|
||||
del self._memory_save[bp.addr]
|
||||
del self.breakpoints[bp.addr]
|
||||
return
|
||||
if bp.type == HARDWARE_EXEC_BP:
|
||||
for tid in self._hxbp_breakpoint:
|
||||
if bp.addr in self._hxbp_breakpoint[tid] and self._hxbp_breakpoint[tid][bp.addr] == bp:
|
||||
if tid == windows.current_thread.tid:
|
||||
self.remove_hxbp_self_thread(bp.addr)
|
||||
else:
|
||||
self.remove_hxbp_other_thread(bp.addr)
|
||||
del self._hxbp_breakpoint[tid][bp.addr]
|
||||
#print("Need to remove {0} in {1}".format(self._hxbp_breakpoint[tid][bp.addr], tid))
|
||||
return
|
||||
#raise NotImplementedError("Remove <HARDWARE_EXEC_BP>")
|
||||
raise NotImplementedError("Unknow BP type {0}".format(bp.type))
|
||||
|
||||
def add_bp(self, bp, targets=None):
|
||||
"""Add a breakpoint, bp is a "class:`Breakpoint`
|
||||
|
||||
If the ``bp`` type is ``STANDARD_BP``, target must be None.
|
||||
|
||||
If the ``bp`` type is ``HARDWARE_EXEC_BP``, target can be None (all threads), or some threads of the process
|
||||
"""
|
||||
if bp.type == HARDWARE_EXEC_BP:
|
||||
return self.add_bp_hxbp(bp, targets)
|
||||
if bp.type != STANDARD_BP:
|
||||
raise NotImplementedError("Unknow BP type {0}".format(bp.type))
|
||||
if targets is not None:
|
||||
raise ValueError("LocalDebugger: STANDARD_BP doest not support targets {0}".format(targets))
|
||||
self.breakpoints[bp.addr] = bp
|
||||
self._memory_save[bp.addr] = windows.current_process.read_memory(bp.addr, 1)
|
||||
with windows.utils.VirtualProtected(bp.addr, 1, PAGE_EXECUTE_READWRITE):
|
||||
windows.current_process.write_memory(bp.addr, "\xcc")
|
||||
return
|
||||
|
||||
def add_bp_hxbp(self, bp, targets=None):
|
||||
if bp.type != HARDWARE_EXEC_BP:
|
||||
raise NotImplementedError("Add non standard-BP in LocalDebugger")
|
||||
if targets is None:
|
||||
targets = windows.current_process.threads
|
||||
for thread in targets:
|
||||
if thread.owner.pid != windows.current_process.pid:
|
||||
raise ValueError("Cannot add HXBP to target in remote process {0}".format(thread))
|
||||
if thread.tid == windows.current_thread.tid:
|
||||
self.setup_hxbp_self_thread(bp.addr)
|
||||
else:
|
||||
self.setup_hxbp_other_thread(bp.addr, thread)
|
||||
self._hxbp_breakpoint[thread.tid][bp.addr] = bp
|
||||
|
||||
def setup_hxbp_callback(self, exc):
|
||||
self.current_exception = exc
|
||||
exp_code = self.get_exception_code()
|
||||
context = self.get_exception_context()
|
||||
exp_addr = context.pc
|
||||
hxbp_used = self.setup_hxbp_in_context(context, self.data)
|
||||
windows.current_process.write_memory(exp_addr, "\x90")
|
||||
# Raising in the VEH is a bad idea..
|
||||
# So better give the information to triggerer..
|
||||
if hxbp_used is not None:
|
||||
self.get_exception_context().Eax = exp_addr
|
||||
else:
|
||||
self.get_exception_context().Eax = 0
|
||||
return windef.EXCEPTION_CONTINUE_EXECUTION
|
||||
|
||||
def remove_hxbp_callback(self, exc):
|
||||
self.current_exception = exc
|
||||
exp_code = self.get_exception_code()
|
||||
context = self.get_exception_context()
|
||||
exp_addr = context.pc
|
||||
hxbp_used = self.remove_hxbp_in_context(context, self.data)
|
||||
windows.current_process.write_memory(exp_addr, "\x90")
|
||||
# Raising in the VEH is a bad idea..
|
||||
# So better give the information to triggerer..
|
||||
if hxbp_used is not None:
|
||||
self.get_exception_context().Eax = exp_addr
|
||||
else:
|
||||
self.get_exception_context().Eax = 0
|
||||
return windef.EXCEPTION_CONTINUE_EXECUTION
|
||||
|
||||
def setup_hxbp_in_context(self, context, addr):
|
||||
for i in range(4):
|
||||
is_used = getattr(context.EDr7, "L" + str(i))
|
||||
empty_drx = str(i)
|
||||
if not is_used:
|
||||
context.EDr7.GE = 1
|
||||
context.EDr7.LE = 1
|
||||
setattr(context.EDr7, "L" + empty_drx, 1)
|
||||
setattr(context, "Dr" + empty_drx, addr)
|
||||
return i
|
||||
return None
|
||||
|
||||
def remove_hxbp_in_context(self, context, addr):
|
||||
for i in range(4):
|
||||
target_drx = str(i)
|
||||
is_used = getattr(context.EDr7, "L" + str(i))
|
||||
draddr = getattr(context, "Dr" + target_drx)
|
||||
|
||||
if is_used and draddr == addr:
|
||||
print("RM RD" + target_drx)
|
||||
setattr(context.EDr7, "L" + target_drx, 0)
|
||||
setattr(context, "Dr" + target_drx, 0)
|
||||
return i
|
||||
return None
|
||||
|
||||
def setup_hxbp_self_thread(self, addr):
|
||||
if self.current_exception is not None:
|
||||
x = self.setup_hxbp_in_context(self.get_exception_context(), addr)
|
||||
if x is None:
|
||||
raise ValueError("Could not setup HXBP")
|
||||
return
|
||||
|
||||
self.data = addr
|
||||
with winexception.VectoredExceptionHandler(1, self.setup_hxbp_callback):
|
||||
x = self.code()
|
||||
if x is None:
|
||||
raise ValueError("Could not setup HXBP")
|
||||
windows.current_process.write_memory(x, "\xcc")
|
||||
return
|
||||
|
||||
def setup_hxbp_other_thread(self, addr, thread):
|
||||
thread.suspend()
|
||||
ctx = thread.context
|
||||
x = self.setup_hxbp_in_context(ctx, addr)
|
||||
if x is None:
|
||||
raise ValueError("Could not setup HXBP in {0}".format(thread))
|
||||
thread.set_context(ctx)
|
||||
thread.resume()
|
||||
|
||||
def remove_hxbp_self_thread(self, addr):
|
||||
if self.current_exception is not None:
|
||||
x = self.remove_hxbp_in_context(self.get_exception_context(), addr)
|
||||
if x is None:
|
||||
raise ValueError("Could not setup HXBP")
|
||||
return
|
||||
self.data = addr
|
||||
with winexception.VectoredExceptionHandler(1, self.remove_hxbp_callback):
|
||||
x = self.code()
|
||||
if x is None:
|
||||
raise ValueError("Could not remove HXBP")
|
||||
windows.current_process.write_memory(x, "\xcc")
|
||||
print("BYE")
|
||||
return
|
||||
|
||||
def remove_hxbp_other_thread(self, addr, thread):
|
||||
thread.suspend()
|
||||
ctx = thread.context
|
||||
x = self.remove_hxbp_in_context(ctx, addr)
|
||||
if x is None:
|
||||
raise ValueError("Could not setup HXBP in {0}".format(thread))
|
||||
thread.set_context(ctx)
|
||||
thread.resume()
|
||||
@@ -18,6 +18,10 @@ if bitness() == 32:
|
||||
|
||||
winstructs.SYSTEM_MODULE = winstructs.SYSTEM_MODULE32
|
||||
winstructs.SYSTEM_MODULE_INFORMATION = winstructs.SYSTEM_MODULE_INFORMATION32
|
||||
|
||||
winstructs.PALPC_PORT_ATTRIBUTES = winstructs.PALPC_PORT_ATTRIBUTES32
|
||||
winstructs.ALPC_PORT_ATTRIBUTES = winstructs.ALPC_PORT_ATTRIBUTES32
|
||||
|
||||
else:
|
||||
winstructs.CONTEXT = winstructs.CONTEXT64
|
||||
winstructs.PCONTEXT = winstructs.PCONTEXT64
|
||||
@@ -29,8 +33,19 @@ else:
|
||||
winstructs.SYSTEM_MODULE = winstructs.SYSTEM_MODULE64
|
||||
winstructs.SYSTEM_MODULE_INFORMATION = winstructs.SYSTEM_MODULE_INFORMATION64
|
||||
|
||||
winstructs.PALPC_PORT_ATTRIBUTES = winstructs.PALPC_PORT_ATTRIBUTES64
|
||||
winstructs.ALPC_PORT_ATTRIBUTES = winstructs.ALPC_PORT_ATTRIBUTES64
|
||||
|
||||
|
||||
from . import winfuncs
|
||||
from . import windef
|
||||
from . import interfaces
|
||||
|
||||
# Fuck it
|
||||
from winstructs import *
|
||||
from winfuncs import *
|
||||
from windef import *
|
||||
from interfaces import *
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,567 @@
|
||||
|
||||
import functools
|
||||
import ctypes
|
||||
from winstructs import *
|
||||
|
||||
class IID(IID):
|
||||
def __init__(self, Data1, Data2, Data3, Data4, name=None, strid=None):
|
||||
self.name = name
|
||||
self.strid = strid
|
||||
super(IID, self).__init__(Data1, Data2, Data3, Data4)
|
||||
|
||||
def __repr__(self):
|
||||
if self.strid is None:
|
||||
return super(IID, self).__repr__()
|
||||
if self.name is None:
|
||||
return '<IID "{0}">'.format(self.strid.upper())
|
||||
return '<IID "{0}({1})">'.format(self.strid.upper(), self.name)
|
||||
|
||||
@classmethod
|
||||
def from_string(cls, iid):
|
||||
part_iid = iid.split("-")
|
||||
datas = [int(x, 16) for x in part_iid[:3]]
|
||||
datas.append(int(part_iid[3][:2], 16))
|
||||
datas.append(int(part_iid[3][2:], 16))
|
||||
for i in range(6):
|
||||
datas.append(int(part_iid[4][i * 2:(i + 1) * 2], 16))
|
||||
return cls.from_raw(*datas, strid=iid)
|
||||
|
||||
@classmethod
|
||||
def from_raw(cls, Data1, Data2, Data3, Data41, Data42, Data43, Data44, Data45, Data46, Data47, Data48, **kwargs):
|
||||
return cls(Data1, Data2, Data3, (BYTE*8)(Data41, Data42, Data43, Data44, Data45, Data46, Data47, Data48), **kwargs)
|
||||
|
||||
generate_IID = IID.from_raw
|
||||
|
||||
|
||||
class COMInterface(ctypes.c_void_p):
|
||||
_functions_ = {
|
||||
}
|
||||
|
||||
def __getattr__(self, name):
|
||||
if name in self._functions_:
|
||||
return functools.partial(self._functions_[name], self)
|
||||
return super(COMInterface, self).__getattribute__(name)
|
||||
|
||||
class IDispatch(COMInterface):
|
||||
IID = generate_IID(0x00020400, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, name="IDispatch", strid="00020400-0000-0000-C000-000000000046")
|
||||
|
||||
_functions_ = {
|
||||
#QueryInterface -> riid:REFIID, ppvObject:**void
|
||||
"QueryInterface": ctypes.WINFUNCTYPE(HRESULT, REFIID, POINTER(PVOID))(0, "QueryInterface"),
|
||||
#AddRef ->
|
||||
"AddRef": ctypes.WINFUNCTYPE(ULONG)(1, "AddRef"),
|
||||
#Release ->
|
||||
"Release": ctypes.WINFUNCTYPE(ULONG)(2, "Release"),
|
||||
#GetTypeInfoCount -> pctinfo:*UINT
|
||||
"GetTypeInfoCount": ctypes.WINFUNCTYPE(HRESULT, POINTER(UINT))(3, "GetTypeInfoCount"),
|
||||
#GetTypeInfo -> iTInfo:UINT, lcid:LCID, ppTInfo:**ITypeInfo
|
||||
"GetTypeInfo": ctypes.WINFUNCTYPE(HRESULT, UINT, LCID, POINTER(POINTER(ITypeInfo)))(4, "GetTypeInfo"),
|
||||
#GetIDsOfNames -> riid:REFIID, rgszNames:*LPOLESTR, cNames:UINT, lcid:LCID, rgDispId:*DISPID
|
||||
"GetIDsOfNames": ctypes.WINFUNCTYPE(HRESULT, REFIID, POINTER(LPOLESTR), UINT, LCID, POINTER(DISPID))(5, "GetIDsOfNames"),
|
||||
#Invoke -> dispIdMember:DISPID, riid:REFIID, lcid:LCID, wFlags:WORD, pDispParams:*DISPPARAMS, pVarResult:*VARIANT, pExcepInfo:*EXCEPINFO, puArgErr:*UINT
|
||||
"Invoke": ctypes.WINFUNCTYPE(HRESULT, DISPID, REFIID, LCID, WORD, POINTER(DISPPARAMS), POINTER(VARIANT), POINTER(EXCEPINFO), POINTER(UINT))(6, "Invoke"),
|
||||
}
|
||||
|
||||
|
||||
class IEnumVARIANT(COMInterface):
|
||||
IID = generate_IID(0x00020404, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, name="IEnumVARIANT", strid="00020404-0000-0000-C000-000000000046")
|
||||
|
||||
_functions_ = {
|
||||
#QueryInterface -> riid:REFIID, ppvObject:**void
|
||||
"QueryInterface": ctypes.WINFUNCTYPE(HRESULT, REFIID, POINTER(PVOID))(0, "QueryInterface"),
|
||||
#AddRef ->
|
||||
"AddRef": ctypes.WINFUNCTYPE(ULONG)(1, "AddRef"),
|
||||
#Release ->
|
||||
"Release": ctypes.WINFUNCTYPE(ULONG)(2, "Release"),
|
||||
#Next -> celt:ULONG, rgVar:*VARIANT, pCeltFetched:*ULONG
|
||||
"Next": ctypes.WINFUNCTYPE(HRESULT, ULONG, POINTER(VARIANT), POINTER(ULONG))(3, "Next"),
|
||||
#Skip -> celt:ULONG
|
||||
"Skip": ctypes.WINFUNCTYPE(HRESULT, ULONG)(4, "Skip"),
|
||||
#Reset ->
|
||||
"Reset": ctypes.WINFUNCTYPE(HRESULT)(5, "Reset"),
|
||||
#Clone -> ppEnum:**IEnumVARIANT
|
||||
"Clone": ctypes.WINFUNCTYPE(HRESULT, POINTER(PVOID))(6, "Clone"),
|
||||
}
|
||||
|
||||
|
||||
class IEnumWbemClassObject(COMInterface):
|
||||
IID = generate_IID(0x027947E1, 0xD731, 0x11CE, 0xA3, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, name="IEnumWbemClassObject", strid="027947E1-D731-11CE-A357-000000000001")
|
||||
|
||||
_functions_ = {
|
||||
#QueryInterface -> riid:REFIID, ppvObject:**void
|
||||
"QueryInterface": ctypes.WINFUNCTYPE(HRESULT, REFIID, POINTER(PVOID))(0, "QueryInterface"),
|
||||
#AddRef ->
|
||||
"AddRef": ctypes.WINFUNCTYPE(ULONG)(1, "AddRef"),
|
||||
#Release ->
|
||||
"Release": ctypes.WINFUNCTYPE(ULONG)(2, "Release"),
|
||||
#Reset ->
|
||||
"Reset": ctypes.WINFUNCTYPE(HRESULT)(3, "Reset"),
|
||||
#Next -> lTimeout:LONG, uCount:ULONG, apObjects:**IWbemClassObject, puReturned:*ULONG
|
||||
"Next": ctypes.WINFUNCTYPE(HRESULT, LONG, ULONG, POINTER(PVOID), POINTER(ULONG))(4, "Next"),
|
||||
#NextAsync -> uCount:ULONG, pSink:*IWbemObjectSink
|
||||
"NextAsync": ctypes.WINFUNCTYPE(HRESULT, ULONG, PVOID)(5, "NextAsync"),
|
||||
#Clone -> ppEnum:**IEnumWbemClassObject
|
||||
"Clone": ctypes.WINFUNCTYPE(HRESULT, POINTER(PVOID))(6, "Clone"),
|
||||
#Skip -> lTimeout:LONG, nCount:ULONG
|
||||
"Skip": ctypes.WINFUNCTYPE(HRESULT, LONG, ULONG)(7, "Skip"),
|
||||
}
|
||||
|
||||
|
||||
class INetFwPolicy2(COMInterface):
|
||||
IID = generate_IID(0x98325047, 0xC671, 0x4174, 0x8D, 0x81, 0xDE, 0xFC, 0xD3, 0xF0, 0x31, 0x86, name="INetFwPolicy2", strid="98325047-C671-4174-8D81-DEFCD3F03186")
|
||||
|
||||
_functions_ = {
|
||||
#QueryInterface -> riid:REFIID, ppvObject:**void
|
||||
"QueryInterface": ctypes.WINFUNCTYPE(HRESULT, REFIID, POINTER(PVOID))(0, "QueryInterface"),
|
||||
#AddRef ->
|
||||
"AddRef": ctypes.WINFUNCTYPE(ULONG)(1, "AddRef"),
|
||||
#Release ->
|
||||
"Release": ctypes.WINFUNCTYPE(ULONG)(2, "Release"),
|
||||
#GetTypeInfoCount -> pctinfo:*UINT
|
||||
"GetTypeInfoCount": ctypes.WINFUNCTYPE(HRESULT, POINTER(UINT))(3, "GetTypeInfoCount"),
|
||||
#GetTypeInfo -> iTInfo:UINT, lcid:LCID, ppTInfo:**ITypeInfo
|
||||
"GetTypeInfo": ctypes.WINFUNCTYPE(HRESULT, UINT, LCID, POINTER(POINTER(ITypeInfo)))(4, "GetTypeInfo"),
|
||||
#GetIDsOfNames -> riid:REFIID, rgszNames:*LPOLESTR, cNames:UINT, lcid:LCID, rgDispId:*DISPID
|
||||
"GetIDsOfNames": ctypes.WINFUNCTYPE(HRESULT, REFIID, POINTER(LPOLESTR), UINT, LCID, POINTER(DISPID))(5, "GetIDsOfNames"),
|
||||
#Invoke -> dispIdMember:DISPID, riid:REFIID, lcid:LCID, wFlags:WORD, pDispParams:*DISPPARAMS, pVarResult:*VARIANT, pExcepInfo:*EXCEPINFO, puArgErr:*UINT
|
||||
"Invoke": ctypes.WINFUNCTYPE(HRESULT, DISPID, REFIID, LCID, WORD, POINTER(DISPPARAMS), POINTER(VARIANT), POINTER(EXCEPINFO), POINTER(UINT))(6, "Invoke"),
|
||||
#get_CurrentProfileTypes -> profileTypesBitmask:*LONG
|
||||
"get_CurrentProfileTypes": ctypes.WINFUNCTYPE(HRESULT, POINTER(LONG))(7, "get_CurrentProfileTypes"),
|
||||
#get_FirewallEnabled -> profileType:NET_FW_PROFILE_TYPE2, enabled:*VARIANT_BOOL
|
||||
"get_FirewallEnabled": ctypes.WINFUNCTYPE(HRESULT, NET_FW_PROFILE_TYPE2, POINTER(VARIANT_BOOL))(8, "get_FirewallEnabled"),
|
||||
#put_FirewallEnabled -> profileType:NET_FW_PROFILE_TYPE2, enabled:VARIANT_BOOL
|
||||
"put_FirewallEnabled": ctypes.WINFUNCTYPE(HRESULT, NET_FW_PROFILE_TYPE2, VARIANT_BOOL)(9, "put_FirewallEnabled"),
|
||||
#get_ExcludedInterfaces -> profileType:NET_FW_PROFILE_TYPE2, interfaces:*VARIANT
|
||||
"get_ExcludedInterfaces": ctypes.WINFUNCTYPE(HRESULT, NET_FW_PROFILE_TYPE2, POINTER(VARIANT))(10, "get_ExcludedInterfaces"),
|
||||
#put_ExcludedInterfaces -> profileType:NET_FW_PROFILE_TYPE2, interfaces:VARIANT
|
||||
"put_ExcludedInterfaces": ctypes.WINFUNCTYPE(HRESULT, NET_FW_PROFILE_TYPE2, VARIANT)(11, "put_ExcludedInterfaces"),
|
||||
#get_BlockAllInboundTraffic -> profileType:NET_FW_PROFILE_TYPE2, Block:*VARIANT_BOOL
|
||||
"get_BlockAllInboundTraffic": ctypes.WINFUNCTYPE(HRESULT, NET_FW_PROFILE_TYPE2, POINTER(VARIANT_BOOL))(12, "get_BlockAllInboundTraffic"),
|
||||
#put_BlockAllInboundTraffic -> profileType:NET_FW_PROFILE_TYPE2, Block:VARIANT_BOOL
|
||||
"put_BlockAllInboundTraffic": ctypes.WINFUNCTYPE(HRESULT, NET_FW_PROFILE_TYPE2, VARIANT_BOOL)(13, "put_BlockAllInboundTraffic"),
|
||||
#get_NotificationsDisabled -> profileType:NET_FW_PROFILE_TYPE2, disabled:*VARIANT_BOOL
|
||||
"get_NotificationsDisabled": ctypes.WINFUNCTYPE(HRESULT, NET_FW_PROFILE_TYPE2, POINTER(VARIANT_BOOL))(14, "get_NotificationsDisabled"),
|
||||
#put_NotificationsDisabled -> profileType:NET_FW_PROFILE_TYPE2, disabled:VARIANT_BOOL
|
||||
"put_NotificationsDisabled": ctypes.WINFUNCTYPE(HRESULT, NET_FW_PROFILE_TYPE2, VARIANT_BOOL)(15, "put_NotificationsDisabled"),
|
||||
#get_UnicastResponsesToMulticastBroadcastDisabled -> profileType:NET_FW_PROFILE_TYPE2, disabled:*VARIANT_BOOL
|
||||
"get_UnicastResponsesToMulticastBroadcastDisabled": ctypes.WINFUNCTYPE(HRESULT, NET_FW_PROFILE_TYPE2, POINTER(VARIANT_BOOL))(16, "get_UnicastResponsesToMulticastBroadcastDisabled"),
|
||||
#put_UnicastResponsesToMulticastBroadcastDisabled -> profileType:NET_FW_PROFILE_TYPE2, disabled:VARIANT_BOOL
|
||||
"put_UnicastResponsesToMulticastBroadcastDisabled": ctypes.WINFUNCTYPE(HRESULT, NET_FW_PROFILE_TYPE2, VARIANT_BOOL)(17, "put_UnicastResponsesToMulticastBroadcastDisabled"),
|
||||
#get_Rules -> rules:**INetFwRules
|
||||
"get_Rules": ctypes.WINFUNCTYPE(HRESULT, POINTER(PVOID))(18, "get_Rules"),
|
||||
#get_ServiceRestriction -> ServiceRestriction:**INetFwServiceRestriction
|
||||
"get_ServiceRestriction": ctypes.WINFUNCTYPE(HRESULT, POINTER(PVOID))(19, "get_ServiceRestriction"),
|
||||
#EnableRuleGroup -> profileTypesBitmask:LONG, group:BSTR, enable:VARIANT_BOOL
|
||||
"EnableRuleGroup": ctypes.WINFUNCTYPE(HRESULT, LONG, BSTR, VARIANT_BOOL)(20, "EnableRuleGroup"),
|
||||
#IsRuleGroupEnabled -> profileTypesBitmask:LONG, group:BSTR, enabled:*VARIANT_BOOL
|
||||
"IsRuleGroupEnabled": ctypes.WINFUNCTYPE(HRESULT, LONG, BSTR, POINTER(VARIANT_BOOL))(21, "IsRuleGroupEnabled"),
|
||||
#RestoreLocalFirewallDefaults ->
|
||||
"RestoreLocalFirewallDefaults": ctypes.WINFUNCTYPE(HRESULT)(22, "RestoreLocalFirewallDefaults"),
|
||||
#get_DefaultInboundAction -> profileType:NET_FW_PROFILE_TYPE2, action:*NET_FW_ACTION
|
||||
"get_DefaultInboundAction": ctypes.WINFUNCTYPE(HRESULT, NET_FW_PROFILE_TYPE2, POINTER(NET_FW_ACTION))(23, "get_DefaultInboundAction"),
|
||||
#put_DefaultInboundAction -> profileType:NET_FW_PROFILE_TYPE2, action:NET_FW_ACTION
|
||||
"put_DefaultInboundAction": ctypes.WINFUNCTYPE(HRESULT, NET_FW_PROFILE_TYPE2, NET_FW_ACTION)(24, "put_DefaultInboundAction"),
|
||||
#get_DefaultOutboundAction -> profileType:NET_FW_PROFILE_TYPE2, action:*NET_FW_ACTION
|
||||
"get_DefaultOutboundAction": ctypes.WINFUNCTYPE(HRESULT, NET_FW_PROFILE_TYPE2, POINTER(NET_FW_ACTION))(25, "get_DefaultOutboundAction"),
|
||||
#put_DefaultOutboundAction -> profileType:NET_FW_PROFILE_TYPE2, action:NET_FW_ACTION
|
||||
"put_DefaultOutboundAction": ctypes.WINFUNCTYPE(HRESULT, NET_FW_PROFILE_TYPE2, NET_FW_ACTION)(26, "put_DefaultOutboundAction"),
|
||||
#get_IsRuleGroupCurrentlyEnabled -> group:BSTR, enabled:*VARIANT_BOOL
|
||||
"get_IsRuleGroupCurrentlyEnabled": ctypes.WINFUNCTYPE(HRESULT, BSTR, POINTER(VARIANT_BOOL))(27, "get_IsRuleGroupCurrentlyEnabled"),
|
||||
#get_LocalPolicyModifyState -> modifyState:*NET_FW_MODIFY_STATE
|
||||
"get_LocalPolicyModifyState": ctypes.WINFUNCTYPE(HRESULT, POINTER(NET_FW_MODIFY_STATE))(28, "get_LocalPolicyModifyState"),
|
||||
}
|
||||
|
||||
|
||||
class INetFwRules(COMInterface):
|
||||
IID = generate_IID(0x9C4C6277, 0x5027, 0x441E, 0xAF, 0xAE, 0xCA, 0x1F, 0x54, 0x2D, 0xA0, 0x09, name="INetFwRules", strid="9C4C6277-5027-441E-AFAE-CA1F542DA009")
|
||||
|
||||
_functions_ = {
|
||||
#QueryInterface -> riid:REFIID, ppvObject:**void
|
||||
"QueryInterface": ctypes.WINFUNCTYPE(HRESULT, REFIID, POINTER(PVOID))(0, "QueryInterface"),
|
||||
#AddRef ->
|
||||
"AddRef": ctypes.WINFUNCTYPE(ULONG)(1, "AddRef"),
|
||||
#Release ->
|
||||
"Release": ctypes.WINFUNCTYPE(ULONG)(2, "Release"),
|
||||
#GetTypeInfoCount -> pctinfo:*UINT
|
||||
"GetTypeInfoCount": ctypes.WINFUNCTYPE(HRESULT, POINTER(UINT))(3, "GetTypeInfoCount"),
|
||||
#GetTypeInfo -> iTInfo:UINT, lcid:LCID, ppTInfo:**ITypeInfo
|
||||
"GetTypeInfo": ctypes.WINFUNCTYPE(HRESULT, UINT, LCID, POINTER(POINTER(ITypeInfo)))(4, "GetTypeInfo"),
|
||||
#GetIDsOfNames -> riid:REFIID, rgszNames:*LPOLESTR, cNames:UINT, lcid:LCID, rgDispId:*DISPID
|
||||
"GetIDsOfNames": ctypes.WINFUNCTYPE(HRESULT, REFIID, POINTER(LPOLESTR), UINT, LCID, POINTER(DISPID))(5, "GetIDsOfNames"),
|
||||
#Invoke -> dispIdMember:DISPID, riid:REFIID, lcid:LCID, wFlags:WORD, pDispParams:*DISPPARAMS, pVarResult:*VARIANT, pExcepInfo:*EXCEPINFO, puArgErr:*UINT
|
||||
"Invoke": ctypes.WINFUNCTYPE(HRESULT, DISPID, REFIID, LCID, WORD, POINTER(DISPPARAMS), POINTER(VARIANT), POINTER(EXCEPINFO), POINTER(UINT))(6, "Invoke"),
|
||||
#get_Count -> count:*LONG
|
||||
"get_Count": ctypes.WINFUNCTYPE(HRESULT, POINTER(LONG))(7, "get_Count"),
|
||||
#Add -> rule:*INetFwRule
|
||||
"Add": ctypes.WINFUNCTYPE(HRESULT, PVOID)(8, "Add"),
|
||||
#Remove -> name:BSTR
|
||||
"Remove": ctypes.WINFUNCTYPE(HRESULT, BSTR)(9, "Remove"),
|
||||
#Item -> name:BSTR, rule:**INetFwRule
|
||||
"Item": ctypes.WINFUNCTYPE(HRESULT, BSTR, POINTER(PVOID))(10, "Item"),
|
||||
#get__NewEnum -> newEnum:**IUnknown
|
||||
"get__NewEnum": ctypes.WINFUNCTYPE(HRESULT, POINTER(PVOID))(11, "get__NewEnum"),
|
||||
}
|
||||
|
||||
|
||||
class INetFwRule(COMInterface):
|
||||
IID = generate_IID(0xAF230D27, 0xBABA, 0x4E42, 0xAC, 0xED, 0xF5, 0x24, 0xF2, 0x2C, 0xFC, 0xE2, name="INetFwRule", strid="AF230D27-BABA-4E42-ACED-F524F22CFCE2")
|
||||
|
||||
_functions_ = {
|
||||
#QueryInterface -> riid:REFIID, ppvObject:**void
|
||||
"QueryInterface": ctypes.WINFUNCTYPE(HRESULT, REFIID, POINTER(PVOID))(0, "QueryInterface"),
|
||||
#AddRef ->
|
||||
"AddRef": ctypes.WINFUNCTYPE(ULONG)(1, "AddRef"),
|
||||
#Release ->
|
||||
"Release": ctypes.WINFUNCTYPE(ULONG)(2, "Release"),
|
||||
#GetTypeInfoCount -> pctinfo:*UINT
|
||||
"GetTypeInfoCount": ctypes.WINFUNCTYPE(HRESULT, POINTER(UINT))(3, "GetTypeInfoCount"),
|
||||
#GetTypeInfo -> iTInfo:UINT, lcid:LCID, ppTInfo:**ITypeInfo
|
||||
"GetTypeInfo": ctypes.WINFUNCTYPE(HRESULT, UINT, LCID, POINTER(POINTER(ITypeInfo)))(4, "GetTypeInfo"),
|
||||
#GetIDsOfNames -> riid:REFIID, rgszNames:*LPOLESTR, cNames:UINT, lcid:LCID, rgDispId:*DISPID
|
||||
"GetIDsOfNames": ctypes.WINFUNCTYPE(HRESULT, REFIID, POINTER(LPOLESTR), UINT, LCID, POINTER(DISPID))(5, "GetIDsOfNames"),
|
||||
#Invoke -> dispIdMember:DISPID, riid:REFIID, lcid:LCID, wFlags:WORD, pDispParams:*DISPPARAMS, pVarResult:*VARIANT, pExcepInfo:*EXCEPINFO, puArgErr:*UINT
|
||||
"Invoke": ctypes.WINFUNCTYPE(HRESULT, DISPID, REFIID, LCID, WORD, POINTER(DISPPARAMS), POINTER(VARIANT), POINTER(EXCEPINFO), POINTER(UINT))(6, "Invoke"),
|
||||
#get_Name -> name:*BSTR
|
||||
"get_Name": ctypes.WINFUNCTYPE(HRESULT, POINTER(BSTR))(7, "get_Name"),
|
||||
#put_Name -> name:BSTR
|
||||
"put_Name": ctypes.WINFUNCTYPE(HRESULT, BSTR)(8, "put_Name"),
|
||||
#get_Description -> desc:*BSTR
|
||||
"get_Description": ctypes.WINFUNCTYPE(HRESULT, POINTER(BSTR))(9, "get_Description"),
|
||||
#put_Description -> desc:BSTR
|
||||
"put_Description": ctypes.WINFUNCTYPE(HRESULT, BSTR)(10, "put_Description"),
|
||||
#get_ApplicationName -> imageFileName:*BSTR
|
||||
"get_ApplicationName": ctypes.WINFUNCTYPE(HRESULT, POINTER(BSTR))(11, "get_ApplicationName"),
|
||||
#put_ApplicationName -> imageFileName:BSTR
|
||||
"put_ApplicationName": ctypes.WINFUNCTYPE(HRESULT, BSTR)(12, "put_ApplicationName"),
|
||||
#get_ServiceName -> serviceName:*BSTR
|
||||
"get_ServiceName": ctypes.WINFUNCTYPE(HRESULT, POINTER(BSTR))(13, "get_ServiceName"),
|
||||
#put_ServiceName -> serviceName:BSTR
|
||||
"put_ServiceName": ctypes.WINFUNCTYPE(HRESULT, BSTR)(14, "put_ServiceName"),
|
||||
#get_Protocol -> protocol:*LONG
|
||||
"get_Protocol": ctypes.WINFUNCTYPE(HRESULT, POINTER(LONG))(15, "get_Protocol"),
|
||||
#put_Protocol -> protocol:LONG
|
||||
"put_Protocol": ctypes.WINFUNCTYPE(HRESULT, LONG)(16, "put_Protocol"),
|
||||
#get_LocalPorts -> portNumbers:*BSTR
|
||||
"get_LocalPorts": ctypes.WINFUNCTYPE(HRESULT, POINTER(BSTR))(17, "get_LocalPorts"),
|
||||
#put_LocalPorts -> portNumbers:BSTR
|
||||
"put_LocalPorts": ctypes.WINFUNCTYPE(HRESULT, BSTR)(18, "put_LocalPorts"),
|
||||
#get_RemotePorts -> portNumbers:*BSTR
|
||||
"get_RemotePorts": ctypes.WINFUNCTYPE(HRESULT, POINTER(BSTR))(19, "get_RemotePorts"),
|
||||
#put_RemotePorts -> portNumbers:BSTR
|
||||
"put_RemotePorts": ctypes.WINFUNCTYPE(HRESULT, BSTR)(20, "put_RemotePorts"),
|
||||
#get_LocalAddresses -> localAddrs:*BSTR
|
||||
"get_LocalAddresses": ctypes.WINFUNCTYPE(HRESULT, POINTER(BSTR))(21, "get_LocalAddresses"),
|
||||
#put_LocalAddresses -> localAddrs:BSTR
|
||||
"put_LocalAddresses": ctypes.WINFUNCTYPE(HRESULT, BSTR)(22, "put_LocalAddresses"),
|
||||
#get_RemoteAddresses -> remoteAddrs:*BSTR
|
||||
"get_RemoteAddresses": ctypes.WINFUNCTYPE(HRESULT, POINTER(BSTR))(23, "get_RemoteAddresses"),
|
||||
#put_RemoteAddresses -> remoteAddrs:BSTR
|
||||
"put_RemoteAddresses": ctypes.WINFUNCTYPE(HRESULT, BSTR)(24, "put_RemoteAddresses"),
|
||||
#get_IcmpTypesAndCodes -> icmpTypesAndCodes:*BSTR
|
||||
"get_IcmpTypesAndCodes": ctypes.WINFUNCTYPE(HRESULT, POINTER(BSTR))(25, "get_IcmpTypesAndCodes"),
|
||||
#put_IcmpTypesAndCodes -> icmpTypesAndCodes:BSTR
|
||||
"put_IcmpTypesAndCodes": ctypes.WINFUNCTYPE(HRESULT, BSTR)(26, "put_IcmpTypesAndCodes"),
|
||||
#get_Direction -> dir:*NET_FW_RULE_DIRECTION
|
||||
"get_Direction": ctypes.WINFUNCTYPE(HRESULT, POINTER(NET_FW_RULE_DIRECTION))(27, "get_Direction"),
|
||||
#put_Direction -> dir:NET_FW_RULE_DIRECTION
|
||||
"put_Direction": ctypes.WINFUNCTYPE(HRESULT, NET_FW_RULE_DIRECTION)(28, "put_Direction"),
|
||||
#get_Interfaces -> interfaces:*VARIANT
|
||||
"get_Interfaces": ctypes.WINFUNCTYPE(HRESULT, POINTER(VARIANT))(29, "get_Interfaces"),
|
||||
#put_Interfaces -> interfaces:VARIANT
|
||||
"put_Interfaces": ctypes.WINFUNCTYPE(HRESULT, VARIANT)(30, "put_Interfaces"),
|
||||
#get_InterfaceTypes -> interfaceTypes:*BSTR
|
||||
"get_InterfaceTypes": ctypes.WINFUNCTYPE(HRESULT, POINTER(BSTR))(31, "get_InterfaceTypes"),
|
||||
#put_InterfaceTypes -> interfaceTypes:BSTR
|
||||
"put_InterfaceTypes": ctypes.WINFUNCTYPE(HRESULT, BSTR)(32, "put_InterfaceTypes"),
|
||||
#get_Enabled -> enabled:*VARIANT_BOOL
|
||||
"get_Enabled": ctypes.WINFUNCTYPE(HRESULT, POINTER(VARIANT_BOOL))(33, "get_Enabled"),
|
||||
#put_Enabled -> enabled:VARIANT_BOOL
|
||||
"put_Enabled": ctypes.WINFUNCTYPE(HRESULT, VARIANT_BOOL)(34, "put_Enabled"),
|
||||
#get_Grouping -> context:*BSTR
|
||||
"get_Grouping": ctypes.WINFUNCTYPE(HRESULT, POINTER(BSTR))(35, "get_Grouping"),
|
||||
#put_Grouping -> context:BSTR
|
||||
"put_Grouping": ctypes.WINFUNCTYPE(HRESULT, BSTR)(36, "put_Grouping"),
|
||||
#get_Profiles -> profileTypesBitmask:*LONG
|
||||
"get_Profiles": ctypes.WINFUNCTYPE(HRESULT, POINTER(LONG))(37, "get_Profiles"),
|
||||
#put_Profiles -> profileTypesBitmask:LONG
|
||||
"put_Profiles": ctypes.WINFUNCTYPE(HRESULT, LONG)(38, "put_Profiles"),
|
||||
#get_EdgeTraversal -> enabled:*VARIANT_BOOL
|
||||
"get_EdgeTraversal": ctypes.WINFUNCTYPE(HRESULT, POINTER(VARIANT_BOOL))(39, "get_EdgeTraversal"),
|
||||
#put_EdgeTraversal -> enabled:VARIANT_BOOL
|
||||
"put_EdgeTraversal": ctypes.WINFUNCTYPE(HRESULT, VARIANT_BOOL)(40, "put_EdgeTraversal"),
|
||||
#get_Action -> action:*NET_FW_ACTION
|
||||
"get_Action": ctypes.WINFUNCTYPE(HRESULT, POINTER(NET_FW_ACTION))(41, "get_Action"),
|
||||
#put_Action -> action:NET_FW_ACTION
|
||||
"put_Action": ctypes.WINFUNCTYPE(HRESULT, NET_FW_ACTION)(42, "put_Action"),
|
||||
}
|
||||
|
||||
|
||||
class INetFwServiceRestriction(COMInterface):
|
||||
IID = generate_IID(0x8267BBE3, 0xF890, 0x491C, 0xB7, 0xB6, 0x2D, 0xB1, 0xEF, 0x0E, 0x5D, 0x2B, name="INetFwServiceRestriction", strid="8267BBE3-F890-491C-B7B6-2DB1EF0E5D2B")
|
||||
|
||||
_functions_ = {
|
||||
#QueryInterface -> riid:REFIID, ppvObject:**void
|
||||
"QueryInterface": ctypes.WINFUNCTYPE(HRESULT, REFIID, POINTER(PVOID))(0, "QueryInterface"),
|
||||
#AddRef ->
|
||||
"AddRef": ctypes.WINFUNCTYPE(ULONG)(1, "AddRef"),
|
||||
#Release ->
|
||||
"Release": ctypes.WINFUNCTYPE(ULONG)(2, "Release"),
|
||||
#GetTypeInfoCount -> pctinfo:*UINT
|
||||
"GetTypeInfoCount": ctypes.WINFUNCTYPE(HRESULT, POINTER(UINT))(3, "GetTypeInfoCount"),
|
||||
#GetTypeInfo -> iTInfo:UINT, lcid:LCID, ppTInfo:**ITypeInfo
|
||||
"GetTypeInfo": ctypes.WINFUNCTYPE(HRESULT, UINT, LCID, POINTER(POINTER(ITypeInfo)))(4, "GetTypeInfo"),
|
||||
#GetIDsOfNames -> riid:REFIID, rgszNames:*LPOLESTR, cNames:UINT, lcid:LCID, rgDispId:*DISPID
|
||||
"GetIDsOfNames": ctypes.WINFUNCTYPE(HRESULT, REFIID, POINTER(LPOLESTR), UINT, LCID, POINTER(DISPID))(5, "GetIDsOfNames"),
|
||||
#Invoke -> dispIdMember:DISPID, riid:REFIID, lcid:LCID, wFlags:WORD, pDispParams:*DISPPARAMS, pVarResult:*VARIANT, pExcepInfo:*EXCEPINFO, puArgErr:*UINT
|
||||
"Invoke": ctypes.WINFUNCTYPE(HRESULT, DISPID, REFIID, LCID, WORD, POINTER(DISPPARAMS), POINTER(VARIANT), POINTER(EXCEPINFO), POINTER(UINT))(6, "Invoke"),
|
||||
#RestrictService -> serviceName:BSTR, appName:BSTR, restrictService:VARIANT_BOOL, serviceSidRestricted:VARIANT_BOOL
|
||||
"RestrictService": ctypes.WINFUNCTYPE(HRESULT, BSTR, BSTR, VARIANT_BOOL, VARIANT_BOOL)(7, "RestrictService"),
|
||||
#ServiceRestricted -> serviceName:BSTR, appName:BSTR, serviceRestricted:*VARIANT_BOOL
|
||||
"ServiceRestricted": ctypes.WINFUNCTYPE(HRESULT, BSTR, BSTR, POINTER(VARIANT_BOOL))(8, "ServiceRestricted"),
|
||||
#get_Rules -> rules:**INetFwRules
|
||||
"get_Rules": ctypes.WINFUNCTYPE(HRESULT, POINTER(PVOID))(9, "get_Rules"),
|
||||
}
|
||||
|
||||
|
||||
class IUnknown(COMInterface):
|
||||
IID = generate_IID(0x00000000, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, name="IUnknown", strid="00000000-0000-0000-C000-000000000046")
|
||||
|
||||
_functions_ = {
|
||||
#QueryInterface -> riid:REFIID, ppvObject:**void
|
||||
"QueryInterface": ctypes.WINFUNCTYPE(HRESULT, REFIID, POINTER(PVOID))(0, "QueryInterface"),
|
||||
#AddRef ->
|
||||
"AddRef": ctypes.WINFUNCTYPE(ULONG)(1, "AddRef"),
|
||||
#Release ->
|
||||
"Release": ctypes.WINFUNCTYPE(ULONG)(2, "Release"),
|
||||
}
|
||||
|
||||
|
||||
class IWbemCallResult(COMInterface):
|
||||
IID = generate_IID(0x44ACA675, 0xE8FC, 0x11D0, 0xA0, 0x7C, 0x00, 0xC0, 0x4F, 0xB6, 0x88, 0x20, name="IWbemCallResult", strid="44ACA675-E8FC-11D0-A07C-00C04FB68820")
|
||||
|
||||
_functions_ = {
|
||||
#QueryInterface -> riid:REFIID, ppvObject:**void
|
||||
"QueryInterface": ctypes.WINFUNCTYPE(HRESULT, REFIID, POINTER(PVOID))(0, "QueryInterface"),
|
||||
#AddRef ->
|
||||
"AddRef": ctypes.WINFUNCTYPE(ULONG)(1, "AddRef"),
|
||||
#Release ->
|
||||
"Release": ctypes.WINFUNCTYPE(ULONG)(2, "Release"),
|
||||
#GetResultObject -> lTimeout:LONG, ppResultObject:**IWbemClassObject
|
||||
"GetResultObject": ctypes.WINFUNCTYPE(HRESULT, LONG, POINTER(PVOID))(3, "GetResultObject"),
|
||||
#GetResultString -> lTimeout:LONG, pstrResultString:*BSTR
|
||||
"GetResultString": ctypes.WINFUNCTYPE(HRESULT, LONG, POINTER(BSTR))(4, "GetResultString"),
|
||||
#GetResultServices -> lTimeout:LONG, ppServices:**IWbemServices
|
||||
"GetResultServices": ctypes.WINFUNCTYPE(HRESULT, LONG, POINTER(PVOID))(5, "GetResultServices"),
|
||||
#GetCallStatus -> lTimeout:LONG, plStatus:*LONG
|
||||
"GetCallStatus": ctypes.WINFUNCTYPE(HRESULT, LONG, POINTER(LONG))(6, "GetCallStatus"),
|
||||
}
|
||||
|
||||
|
||||
class IWbemClassObject(COMInterface):
|
||||
IID = generate_IID(0xDC12A681, 0x737F, 0x11CF, 0x88, 0x4D, 0x00, 0xAA, 0x00, 0x4B, 0x2E, 0x24, name="IWbemClassObject", strid="DC12A681-737F-11CF-884D-00AA004B2E24")
|
||||
|
||||
_functions_ = {
|
||||
#QueryInterface -> riid:REFIID, ppvObject:**void
|
||||
"QueryInterface": ctypes.WINFUNCTYPE(HRESULT, REFIID, POINTER(PVOID))(0, "QueryInterface"),
|
||||
#AddRef ->
|
||||
"AddRef": ctypes.WINFUNCTYPE(ULONG)(1, "AddRef"),
|
||||
#Release ->
|
||||
"Release": ctypes.WINFUNCTYPE(ULONG)(2, "Release"),
|
||||
#GetQualifierSet -> ppQualSet:**IWbemQualifierSet
|
||||
"GetQualifierSet": ctypes.WINFUNCTYPE(HRESULT, POINTER(PVOID))(3, "GetQualifierSet"),
|
||||
#Get -> wszName:LPCWSTR, lFlags:LONG, pVal:*VARIANT, pType:*CIMTYPE, plFlavor:*LONG
|
||||
"Get": ctypes.WINFUNCTYPE(HRESULT, LPCWSTR, LONG, POINTER(VARIANT), POINTER(CIMTYPE), POINTER(LONG))(4, "Get"),
|
||||
#Put -> wszName:LPCWSTR, lFlags:LONG, pVal:*VARIANT, Type:CIMTYPE
|
||||
"Put": ctypes.WINFUNCTYPE(HRESULT, LPCWSTR, LONG, POINTER(VARIANT), CIMTYPE)(5, "Put"),
|
||||
#Delete -> wszName:LPCWSTR
|
||||
"Delete": ctypes.WINFUNCTYPE(HRESULT, LPCWSTR)(6, "Delete"),
|
||||
#GetNames -> wszQualifierName:LPCWSTR, lFlags:LONG, pQualifierVal:*VARIANT, pNames:**SAFEARRAY
|
||||
"GetNames": ctypes.WINFUNCTYPE(HRESULT, LPCWSTR, LONG, POINTER(VARIANT), POINTER(POINTER(SAFEARRAY)))(7, "GetNames"),
|
||||
#BeginEnumeration -> lEnumFlags:LONG
|
||||
"BeginEnumeration": ctypes.WINFUNCTYPE(HRESULT, LONG)(8, "BeginEnumeration"),
|
||||
#Next -> lFlags:LONG, strName:*BSTR, pVal:*VARIANT, pType:*CIMTYPE, plFlavor:*LONG
|
||||
"Next": ctypes.WINFUNCTYPE(HRESULT, LONG, POINTER(BSTR), POINTER(VARIANT), POINTER(CIMTYPE), POINTER(LONG))(9, "Next"),
|
||||
#EndEnumeration ->
|
||||
"EndEnumeration": ctypes.WINFUNCTYPE(HRESULT)(10, "EndEnumeration"),
|
||||
#GetPropertyQualifierSet -> wszProperty:LPCWSTR, ppQualSet:**IWbemQualifierSet
|
||||
"GetPropertyQualifierSet": ctypes.WINFUNCTYPE(HRESULT, LPCWSTR, POINTER(PVOID))(11, "GetPropertyQualifierSet"),
|
||||
#Clone -> ppCopy:**IWbemClassObject
|
||||
"Clone": ctypes.WINFUNCTYPE(HRESULT, POINTER(PVOID))(12, "Clone"),
|
||||
#GetObjectText -> lFlags:LONG, pstrObjectText:*BSTR
|
||||
"GetObjectText": ctypes.WINFUNCTYPE(HRESULT, LONG, POINTER(BSTR))(13, "GetObjectText"),
|
||||
#SpawnDerivedClass -> lFlags:LONG, ppNewClass:**IWbemClassObject
|
||||
"SpawnDerivedClass": ctypes.WINFUNCTYPE(HRESULT, LONG, POINTER(PVOID))(14, "SpawnDerivedClass"),
|
||||
#SpawnInstance -> lFlags:LONG, ppNewInstance:**IWbemClassObject
|
||||
"SpawnInstance": ctypes.WINFUNCTYPE(HRESULT, LONG, POINTER(PVOID))(15, "SpawnInstance"),
|
||||
#CompareTo -> lFlags:LONG, pCompareTo:*IWbemClassObject
|
||||
"CompareTo": ctypes.WINFUNCTYPE(HRESULT, LONG, PVOID)(16, "CompareTo"),
|
||||
#GetPropertyOrigin -> wszName:LPCWSTR, pstrClassName:*BSTR
|
||||
"GetPropertyOrigin": ctypes.WINFUNCTYPE(HRESULT, LPCWSTR, POINTER(BSTR))(17, "GetPropertyOrigin"),
|
||||
#InheritsFrom -> strAncestor:LPCWSTR
|
||||
"InheritsFrom": ctypes.WINFUNCTYPE(HRESULT, LPCWSTR)(18, "InheritsFrom"),
|
||||
#GetMethod -> wszName:LPCWSTR, lFlags:LONG, ppInSignature:**IWbemClassObject, ppOutSignature:**IWbemClassObject
|
||||
"GetMethod": ctypes.WINFUNCTYPE(HRESULT, LPCWSTR, LONG, POINTER(PVOID), POINTER(PVOID))(19, "GetMethod"),
|
||||
#PutMethod -> wszName:LPCWSTR, lFlags:LONG, pInSignature:*IWbemClassObject, pOutSignature:*IWbemClassObject
|
||||
"PutMethod": ctypes.WINFUNCTYPE(HRESULT, LPCWSTR, LONG, PVOID, PVOID)(20, "PutMethod"),
|
||||
#DeleteMethod -> wszName:LPCWSTR
|
||||
"DeleteMethod": ctypes.WINFUNCTYPE(HRESULT, LPCWSTR)(21, "DeleteMethod"),
|
||||
#BeginMethodEnumeration -> lEnumFlags:LONG
|
||||
"BeginMethodEnumeration": ctypes.WINFUNCTYPE(HRESULT, LONG)(22, "BeginMethodEnumeration"),
|
||||
#NextMethod -> lFlags:LONG, pstrName:*BSTR, ppInSignature:**IWbemClassObject, ppOutSignature:**IWbemClassObject
|
||||
"NextMethod": ctypes.WINFUNCTYPE(HRESULT, LONG, POINTER(BSTR), POINTER(PVOID), POINTER(PVOID))(23, "NextMethod"),
|
||||
#EndMethodEnumeration ->
|
||||
"EndMethodEnumeration": ctypes.WINFUNCTYPE(HRESULT)(24, "EndMethodEnumeration"),
|
||||
#GetMethodQualifierSet -> wszMethod:LPCWSTR, ppQualSet:**IWbemQualifierSet
|
||||
"GetMethodQualifierSet": ctypes.WINFUNCTYPE(HRESULT, LPCWSTR, POINTER(PVOID))(25, "GetMethodQualifierSet"),
|
||||
#GetMethodOrigin -> wszMethodName:LPCWSTR, pstrClassName:*BSTR
|
||||
"GetMethodOrigin": ctypes.WINFUNCTYPE(HRESULT, LPCWSTR, POINTER(BSTR))(26, "GetMethodOrigin"),
|
||||
}
|
||||
|
||||
|
||||
class IWbemContext(COMInterface):
|
||||
IID = generate_IID(0x44ACA674, 0xE8FC, 0x11D0, 0xA0, 0x7C, 0x00, 0xC0, 0x4F, 0xB6, 0x88, 0x20, name="IWbemContext", strid="44ACA674-E8FC-11D0-A07C-00C04FB68820")
|
||||
|
||||
_functions_ = {
|
||||
#QueryInterface -> riid:REFIID, ppvObject:**void
|
||||
"QueryInterface": ctypes.WINFUNCTYPE(HRESULT, REFIID, POINTER(PVOID))(0, "QueryInterface"),
|
||||
#AddRef ->
|
||||
"AddRef": ctypes.WINFUNCTYPE(ULONG)(1, "AddRef"),
|
||||
#Release ->
|
||||
"Release": ctypes.WINFUNCTYPE(ULONG)(2, "Release"),
|
||||
#Clone -> ppNewCopy:**IWbemContext
|
||||
"Clone": ctypes.WINFUNCTYPE(HRESULT, POINTER(PVOID))(3, "Clone"),
|
||||
#GetNames -> lFlags:LONG, pNames:**SAFEARRAY
|
||||
"GetNames": ctypes.WINFUNCTYPE(HRESULT, LONG, POINTER(POINTER(SAFEARRAY)))(4, "GetNames"),
|
||||
#BeginEnumeration -> lFlags:LONG
|
||||
"BeginEnumeration": ctypes.WINFUNCTYPE(HRESULT, LONG)(5, "BeginEnumeration"),
|
||||
#Next -> lFlags:LONG, pstrName:*BSTR, pValue:*VARIANT
|
||||
"Next": ctypes.WINFUNCTYPE(HRESULT, LONG, POINTER(BSTR), POINTER(VARIANT))(6, "Next"),
|
||||
#EndEnumeration ->
|
||||
"EndEnumeration": ctypes.WINFUNCTYPE(HRESULT)(7, "EndEnumeration"),
|
||||
#SetValue -> wszName:LPCWSTR, lFlags:LONG, pValue:*VARIANT
|
||||
"SetValue": ctypes.WINFUNCTYPE(HRESULT, LPCWSTR, LONG, POINTER(VARIANT))(8, "SetValue"),
|
||||
#GetValue -> wszName:LPCWSTR, lFlags:LONG, pValue:*VARIANT
|
||||
"GetValue": ctypes.WINFUNCTYPE(HRESULT, LPCWSTR, LONG, POINTER(VARIANT))(9, "GetValue"),
|
||||
#DeleteValue -> wszName:LPCWSTR, lFlags:LONG
|
||||
"DeleteValue": ctypes.WINFUNCTYPE(HRESULT, LPCWSTR, LONG)(10, "DeleteValue"),
|
||||
#DeleteAll ->
|
||||
"DeleteAll": ctypes.WINFUNCTYPE(HRESULT)(11, "DeleteAll"),
|
||||
}
|
||||
|
||||
|
||||
class IWbemLocator(COMInterface):
|
||||
IID = generate_IID(0xDC12A687, 0x737F, 0x11CF, 0x88, 0x4D, 0x00, 0xAA, 0x00, 0x4B, 0x2E, 0x24, name="IWbemLocator", strid="DC12A687-737F-11CF-884D-00AA004B2E24")
|
||||
|
||||
_functions_ = {
|
||||
#QueryInterface -> riid:REFIID, ppvObject:**void
|
||||
"QueryInterface": ctypes.WINFUNCTYPE(HRESULT, REFIID, POINTER(PVOID))(0, "QueryInterface"),
|
||||
#AddRef ->
|
||||
"AddRef": ctypes.WINFUNCTYPE(ULONG)(1, "AddRef"),
|
||||
#Release ->
|
||||
"Release": ctypes.WINFUNCTYPE(ULONG)(2, "Release"),
|
||||
#ConnectServer -> strNetworkResource:BSTR, strUser:BSTR, strPassword:BSTR, strLocale:BSTR, lSecurityFlags:LONG, strAuthority:BSTR, pCtx:*IWbemContext, ppNamespace:**IWbemServices
|
||||
"ConnectServer": ctypes.WINFUNCTYPE(HRESULT, BSTR, BSTR, BSTR, BSTR, LONG, BSTR, PVOID, POINTER(PVOID))(3, "ConnectServer"),
|
||||
}
|
||||
|
||||
|
||||
class IWbemObjectSink(COMInterface):
|
||||
IID = generate_IID(0x7C857801, 0x7381, 0x11CF, 0x88, 0x4D, 0x00, 0xAA, 0x00, 0x4B, 0x2E, 0x24, name="IWbemObjectSink", strid="7C857801-7381-11CF-884D-00AA004B2E24")
|
||||
|
||||
_functions_ = {
|
||||
#QueryInterface -> riid:REFIID, ppvObject:**void
|
||||
"QueryInterface": ctypes.WINFUNCTYPE(HRESULT, REFIID, POINTER(PVOID))(0, "QueryInterface"),
|
||||
#AddRef ->
|
||||
"AddRef": ctypes.WINFUNCTYPE(ULONG)(1, "AddRef"),
|
||||
#Release ->
|
||||
"Release": ctypes.WINFUNCTYPE(ULONG)(2, "Release"),
|
||||
#Indicate -> lObjectCount:LONG, apObjArray:**IWbemClassObject
|
||||
"Indicate": ctypes.WINFUNCTYPE(HRESULT, LONG, POINTER(PVOID))(3, "Indicate"),
|
||||
#SetStatus -> lFlags:LONG, hResult:HRESULT, strParam:BSTR, pObjParam:*IWbemClassObject
|
||||
"SetStatus": ctypes.WINFUNCTYPE(HRESULT, LONG, HRESULT, BSTR, PVOID)(4, "SetStatus"),
|
||||
}
|
||||
|
||||
|
||||
class IWbemQualifierSet(COMInterface):
|
||||
IID = generate_IID(0xDC12A680, 0x737F, 0x11CF, 0x88, 0x4D, 0x00, 0xAA, 0x00, 0x4B, 0x2E, 0x24, name="IWbemQualifierSet", strid="DC12A680-737F-11CF-884D-00AA004B2E24")
|
||||
|
||||
_functions_ = {
|
||||
#QueryInterface -> riid:REFIID, ppvObject:**void
|
||||
"QueryInterface": ctypes.WINFUNCTYPE(HRESULT, REFIID, POINTER(PVOID))(0, "QueryInterface"),
|
||||
#AddRef ->
|
||||
"AddRef": ctypes.WINFUNCTYPE(ULONG)(1, "AddRef"),
|
||||
#Release ->
|
||||
"Release": ctypes.WINFUNCTYPE(ULONG)(2, "Release"),
|
||||
#Get -> wszName:LPCWSTR, lFlags:LONG, pVal:*VARIANT, plFlavor:*LONG
|
||||
"Get": ctypes.WINFUNCTYPE(HRESULT, LPCWSTR, LONG, POINTER(VARIANT), POINTER(LONG))(3, "Get"),
|
||||
#Put -> wszName:LPCWSTR, pVal:*VARIANT, lFlavor:LONG
|
||||
"Put": ctypes.WINFUNCTYPE(HRESULT, LPCWSTR, POINTER(VARIANT), LONG)(4, "Put"),
|
||||
#Delete -> wszName:LPCWSTR
|
||||
"Delete": ctypes.WINFUNCTYPE(HRESULT, LPCWSTR)(5, "Delete"),
|
||||
#GetNames -> lFlags:LONG, pNames:**SAFEARRAY
|
||||
"GetNames": ctypes.WINFUNCTYPE(HRESULT, LONG, POINTER(POINTER(SAFEARRAY)))(6, "GetNames"),
|
||||
#BeginEnumeration -> lFlags:LONG
|
||||
"BeginEnumeration": ctypes.WINFUNCTYPE(HRESULT, LONG)(7, "BeginEnumeration"),
|
||||
#Next -> lFlags:LONG, pstrName:*BSTR, pVal:*VARIANT, plFlavor:*LONG
|
||||
"Next": ctypes.WINFUNCTYPE(HRESULT, LONG, POINTER(BSTR), POINTER(VARIANT), POINTER(LONG))(8, "Next"),
|
||||
#EndEnumeration ->
|
||||
"EndEnumeration": ctypes.WINFUNCTYPE(HRESULT)(9, "EndEnumeration"),
|
||||
}
|
||||
|
||||
|
||||
class IWbemServices(COMInterface):
|
||||
IID = generate_IID(0x9556DC99, 0x828C, 0x11CF, 0xA3, 0x7E, 0x00, 0xAA, 0x00, 0x32, 0x40, 0xC7, name="IWbemServices", strid="9556DC99-828C-11CF-A37E-00AA003240C7")
|
||||
|
||||
_functions_ = {
|
||||
#QueryInterface -> riid:REFIID, ppvObject:**void
|
||||
"QueryInterface": ctypes.WINFUNCTYPE(HRESULT, REFIID, POINTER(PVOID))(0, "QueryInterface"),
|
||||
#AddRef ->
|
||||
"AddRef": ctypes.WINFUNCTYPE(ULONG)(1, "AddRef"),
|
||||
#Release ->
|
||||
"Release": ctypes.WINFUNCTYPE(ULONG)(2, "Release"),
|
||||
#OpenNamespace -> strNamespace:BSTR, lFlags:LONG, pCtx:*IWbemContext, ppWorkingNamespace:**IWbemServices, ppResult:**IWbemCallResult
|
||||
"OpenNamespace": ctypes.WINFUNCTYPE(HRESULT, BSTR, LONG, PVOID, POINTER(PVOID), POINTER(PVOID))(3, "OpenNamespace"),
|
||||
#CancelAsyncCall -> pSink:*IWbemObjectSink
|
||||
"CancelAsyncCall": ctypes.WINFUNCTYPE(HRESULT, PVOID)(4, "CancelAsyncCall"),
|
||||
#QueryObjectSink -> lFlags:LONG, ppResponseHandler:**IWbemObjectSink
|
||||
"QueryObjectSink": ctypes.WINFUNCTYPE(HRESULT, LONG, POINTER(PVOID))(5, "QueryObjectSink"),
|
||||
#GetObject -> strObjectPath:BSTR, lFlags:LONG, pCtx:*IWbemContext, ppObject:**IWbemClassObject, ppCallResult:**IWbemCallResult
|
||||
"GetObject": ctypes.WINFUNCTYPE(HRESULT, BSTR, LONG, PVOID, POINTER(PVOID), POINTER(PVOID))(6, "GetObject"),
|
||||
#GetObjectAsync -> strObjectPath:BSTR, lFlags:LONG, pCtx:*IWbemContext, pResponseHandler:*IWbemObjectSink
|
||||
"GetObjectAsync": ctypes.WINFUNCTYPE(HRESULT, BSTR, LONG, PVOID, PVOID)(7, "GetObjectAsync"),
|
||||
#PutClass -> pObject:*IWbemClassObject, lFlags:LONG, pCtx:*IWbemContext, ppCallResult:**IWbemCallResult
|
||||
"PutClass": ctypes.WINFUNCTYPE(HRESULT, PVOID, LONG, PVOID, POINTER(PVOID))(8, "PutClass"),
|
||||
#PutClassAsync -> pObject:*IWbemClassObject, lFlags:LONG, pCtx:*IWbemContext, pResponseHandler:*IWbemObjectSink
|
||||
"PutClassAsync": ctypes.WINFUNCTYPE(HRESULT, PVOID, LONG, PVOID, PVOID)(9, "PutClassAsync"),
|
||||
#DeleteClass -> strClass:BSTR, lFlags:LONG, pCtx:*IWbemContext, ppCallResult:**IWbemCallResult
|
||||
"DeleteClass": ctypes.WINFUNCTYPE(HRESULT, BSTR, LONG, PVOID, POINTER(PVOID))(10, "DeleteClass"),
|
||||
#DeleteClassAsync -> strClass:BSTR, lFlags:LONG, pCtx:*IWbemContext, pResponseHandler:*IWbemObjectSink
|
||||
"DeleteClassAsync": ctypes.WINFUNCTYPE(HRESULT, BSTR, LONG, PVOID, PVOID)(11, "DeleteClassAsync"),
|
||||
#CreateClassEnum -> strSuperclass:BSTR, lFlags:LONG, pCtx:*IWbemContext, ppEnum:**IEnumWbemClassObject
|
||||
"CreateClassEnum": ctypes.WINFUNCTYPE(HRESULT, BSTR, LONG, PVOID, POINTER(PVOID))(12, "CreateClassEnum"),
|
||||
#CreateClassEnumAsync -> strSuperclass:BSTR, lFlags:LONG, pCtx:*IWbemContext, pResponseHandler:*IWbemObjectSink
|
||||
"CreateClassEnumAsync": ctypes.WINFUNCTYPE(HRESULT, BSTR, LONG, PVOID, PVOID)(13, "CreateClassEnumAsync"),
|
||||
#PutInstance -> pInst:*IWbemClassObject, lFlags:LONG, pCtx:*IWbemContext, ppCallResult:**IWbemCallResult
|
||||
"PutInstance": ctypes.WINFUNCTYPE(HRESULT, PVOID, LONG, PVOID, POINTER(PVOID))(14, "PutInstance"),
|
||||
#PutInstanceAsync -> pInst:*IWbemClassObject, lFlags:LONG, pCtx:*IWbemContext, pResponseHandler:*IWbemObjectSink
|
||||
"PutInstanceAsync": ctypes.WINFUNCTYPE(HRESULT, PVOID, LONG, PVOID, PVOID)(15, "PutInstanceAsync"),
|
||||
#DeleteInstance -> strObjectPath:BSTR, lFlags:LONG, pCtx:*IWbemContext, ppCallResult:**IWbemCallResult
|
||||
"DeleteInstance": ctypes.WINFUNCTYPE(HRESULT, BSTR, LONG, PVOID, POINTER(PVOID))(16, "DeleteInstance"),
|
||||
#DeleteInstanceAsync -> strObjectPath:BSTR, lFlags:LONG, pCtx:*IWbemContext, pResponseHandler:*IWbemObjectSink
|
||||
"DeleteInstanceAsync": ctypes.WINFUNCTYPE(HRESULT, BSTR, LONG, PVOID, PVOID)(17, "DeleteInstanceAsync"),
|
||||
#CreateInstanceEnum -> strFilter:BSTR, lFlags:LONG, pCtx:*IWbemContext, ppEnum:**IEnumWbemClassObject
|
||||
"CreateInstanceEnum": ctypes.WINFUNCTYPE(HRESULT, BSTR, LONG, PVOID, POINTER(PVOID))(18, "CreateInstanceEnum"),
|
||||
#CreateInstanceEnumAsync -> strFilter:BSTR, lFlags:LONG, pCtx:*IWbemContext, pResponseHandler:*IWbemObjectSink
|
||||
"CreateInstanceEnumAsync": ctypes.WINFUNCTYPE(HRESULT, BSTR, LONG, PVOID, PVOID)(19, "CreateInstanceEnumAsync"),
|
||||
#ExecQuery -> strQueryLanguage:BSTR, strQuery:BSTR, lFlags:LONG, pCtx:*IWbemContext, ppEnum:**IEnumWbemClassObject
|
||||
"ExecQuery": ctypes.WINFUNCTYPE(HRESULT, BSTR, BSTR, LONG, PVOID, POINTER(PVOID))(20, "ExecQuery"),
|
||||
#ExecQueryAsync -> strQueryLanguage:BSTR, strQuery:BSTR, lFlags:LONG, pCtx:*IWbemContext, pResponseHandler:*IWbemObjectSink
|
||||
"ExecQueryAsync": ctypes.WINFUNCTYPE(HRESULT, BSTR, BSTR, LONG, PVOID, PVOID)(21, "ExecQueryAsync"),
|
||||
#ExecNotificationQuery -> strQueryLanguage:BSTR, strQuery:BSTR, lFlags:LONG, pCtx:*IWbemContext, ppEnum:**IEnumWbemClassObject
|
||||
"ExecNotificationQuery": ctypes.WINFUNCTYPE(HRESULT, BSTR, BSTR, LONG, PVOID, POINTER(PVOID))(22, "ExecNotificationQuery"),
|
||||
#ExecNotificationQueryAsync -> strQueryLanguage:BSTR, strQuery:BSTR, lFlags:LONG, pCtx:*IWbemContext, pResponseHandler:*IWbemObjectSink
|
||||
"ExecNotificationQueryAsync": ctypes.WINFUNCTYPE(HRESULT, BSTR, BSTR, LONG, PVOID, PVOID)(23, "ExecNotificationQueryAsync"),
|
||||
#ExecMethod -> strObjectPath:BSTR, strMethodName:BSTR, lFlags:LONG, pCtx:*IWbemContext, pInParams:*IWbemClassObject, ppOutParams:**IWbemClassObject, ppCallResult:**IWbemCallResult
|
||||
"ExecMethod": ctypes.WINFUNCTYPE(HRESULT, BSTR, BSTR, LONG, PVOID, PVOID, POINTER(PVOID), POINTER(PVOID))(24, "ExecMethod"),
|
||||
#ExecMethodAsync -> strObjectPath:BSTR, strMethodName:BSTR, lFlags:LONG, pCtx:*IWbemContext, pInParams:*IWbemClassObject, pResponseHandler:*IWbemObjectSink
|
||||
"ExecMethodAsync": ctypes.WINFUNCTYPE(HRESULT, BSTR, BSTR, LONG, PVOID, PVOID, PVOID)(25, "ExecMethodAsync"),
|
||||
}
|
||||
+1659
-1659
File diff suppressed because it is too large
Load Diff
+2190
-1
File diff suppressed because it is too large
Load Diff
+700
-113
File diff suppressed because it is too large
Load Diff
+1587
-288
File diff suppressed because one or more lines are too long
+221
-92
@@ -8,130 +8,257 @@ import windows.utils as utils
|
||||
from .native_exec import simple_x86 as x86
|
||||
from .native_exec import simple_x64 as x64
|
||||
|
||||
from windows.native_exec.nativeutils import GetProcAddress64, GetProcAddress32
|
||||
|
||||
def get_loadlib_getproc(target):
|
||||
if windows.current_process.bitness == target.bitness:
|
||||
LoadLibraryA = utils.get_func_addr('kernel32', 'LoadLibraryA')
|
||||
GetProcAddress = utils.get_func_addr('kernel32', 'GetProcAddress')
|
||||
return LoadLibraryA, GetProcAddress
|
||||
else:
|
||||
k32 = [x for x in target.peb.modules if x.name == "kernel32.dll"][0]
|
||||
exp = k32.pe.exports
|
||||
return exp['LoadLibraryA'], exp['GetProcAddress']
|
||||
from windows.dbgprint import dbgprint
|
||||
|
||||
|
||||
def perform_manual_getproc_loadlib_32(target, dll_name):
|
||||
dll = "KERNEL32.DLL\x00".encode("utf-16-le")
|
||||
api = "LoadLibraryA\x00"
|
||||
dll_to_load = dll_name + "\x00"
|
||||
|
||||
RemoteManualLoadLibray = x86.MultipleInstr()
|
||||
code = RemoteManualLoadLibray
|
||||
code += x86.Mov("ECX", x86.mem("[ESP + 4]"))
|
||||
code += x86.Push(x86.mem("[ECX + 4]"))
|
||||
code += x86.Push(x86.mem("[ECX]"))
|
||||
code += x86.Call(":FUNC_GETPROCADDRESS32")
|
||||
code += x86.Push(x86.mem("[ECX + 8]"))
|
||||
code += x86.Call("EAX") # LoadLibrary
|
||||
code += x86.Pop("ECX")
|
||||
code += x86.Pop("ECX")
|
||||
code += x86.Ret()
|
||||
|
||||
RemoteManualLoadLibray += GetProcAddress32
|
||||
|
||||
with target.allocated_memory(0x1000) as addr:
|
||||
addr2 = addr + len(dll)
|
||||
addr3 = addr2 + len(api)
|
||||
addr4 = addr3 + len(dll_to_load)
|
||||
|
||||
target.write_memory(addr, dll)
|
||||
target.write_memory(addr2, api)
|
||||
target.write_memory(addr3, dll_to_load)
|
||||
target.write_qword(addr4, addr)
|
||||
target.write_qword(addr4 + 4, addr2)
|
||||
target.write_qword(addr4 + 0x8, addr3)
|
||||
|
||||
t = target.execute(RemoteManualLoadLibray.get_code(), addr4)
|
||||
t.wait()
|
||||
return True
|
||||
|
||||
def perform_manual_getproc_loadlib_64(target, dll_name):
|
||||
dll = "KERNEL32.DLL\x00".encode("utf-16-le")
|
||||
api = "LoadLibraryA\x00"
|
||||
dll_to_load = dll_name + "\x00"
|
||||
|
||||
RemoteManualLoadLibray = x64.MultipleInstr()
|
||||
code = RemoteManualLoadLibray
|
||||
code += x64.Mov("R15", "RCX")
|
||||
code += x64.Mov("RCX", x64.mem("[R15 + 0]"))
|
||||
code += x64.Mov("RDX", x64.mem("[R15 + 8]"))
|
||||
code += x64.Call(":FUNC_GETPROCADDRESS64")
|
||||
code += x64.Mov("RCX", x64.mem("[R15 + 0x10]"))
|
||||
code += x64.Push("RCX")
|
||||
code += x64.Push("RCX")
|
||||
code += x64.Push("RCX")
|
||||
code += x64.Call("RAX") # LoadLibrary
|
||||
code += x64.Pop("RCX")
|
||||
code += x64.Pop("RCX")
|
||||
code += x64.Pop("RCX")
|
||||
code += x64.Ret()
|
||||
|
||||
RemoteManualLoadLibray += GetProcAddress64
|
||||
|
||||
with target.allocated_memory(0x1000) as addr:
|
||||
addr2 = addr + len(dll)
|
||||
addr3 = addr2 + len(api)
|
||||
addr4 = addr3 + len(dll_to_load)
|
||||
|
||||
target.write_memory(addr, dll)
|
||||
target.write_memory(addr2, api)
|
||||
target.write_memory(addr3, dll_to_load)
|
||||
target.write_qword(addr4, addr)
|
||||
target.write_qword(addr4 + 8, addr2)
|
||||
target.write_qword(addr4 + 0x10, addr3)
|
||||
|
||||
t = target.execute(RemoteManualLoadLibray.get_code(), addr4)
|
||||
t.wait()
|
||||
return True
|
||||
|
||||
|
||||
def load_dll_in_remote_process(target, dll_name):
|
||||
rpeb = target.peb
|
||||
if rpeb.Ldr:
|
||||
# LDR est parcourable, ca va etre deja plus simple..
|
||||
modules = rpeb.modules
|
||||
if any(mod.name == dll_name for mod in modules):
|
||||
# DLL already loaded
|
||||
dbgprint("DLL already present in target", "DLLINJECT")
|
||||
return True
|
||||
k32 = [mod for mod in modules if mod.name.lower() == "kernel32.dll"]
|
||||
if k32:
|
||||
# We have kernel32 \o/
|
||||
k32 = k32[0]
|
||||
try:
|
||||
load_libraryA = k32.pe.exports["LoadLibraryA"]
|
||||
except KeyError:
|
||||
raise ValueError("Kernel32 have no export <LoadLibraryA> (wtf)")
|
||||
|
||||
with target.allocated_memory(0x1000) as addr:
|
||||
target.write_memory(addr, dll_name + "\x00")
|
||||
t = target.create_thread(load_libraryA, addr)
|
||||
t.wait()
|
||||
dbgprint("DLL Injected via LoadLibray", "DLLINJECT")
|
||||
return True
|
||||
# Hardcore mode
|
||||
# We don't have k32 or PEB->Ldr
|
||||
# Go inject a GetProcAddress(LoadLib) + LoadLib shellcode :D
|
||||
if target.bitness == 32:
|
||||
return perform_manual_getproc_loadlib_32(target, dll_name)
|
||||
return perform_manual_getproc_loadlib_64(target, dll_name)
|
||||
|
||||
python_function_32_bits = {}
|
||||
# 32 to 32 injection
|
||||
def generate_python_exec_shellcode_32(target, PYDLL_addr, PyInit, PyRun, PYCODE_ADDR):
|
||||
LoadLibraryA, GetProcAddress = get_loadlib_getproc(target)
|
||||
def generate_python_exec_shellcode_32(target, PYCODE_ADDR, PyDll):
|
||||
if not python_function_32_bits:
|
||||
pymodule = [mod for mod in target.peb.modules if mod.name == PyDll][0]
|
||||
Py_exports = pymodule.pe.exports
|
||||
python_function_32_bits["PyEval_InitThreads"] = Py_exports["PyEval_InitThreads"]
|
||||
python_function_32_bits["Py_IsInitialized"] = Py_exports["Py_IsInitialized"]
|
||||
python_function_32_bits["PyGILState_Release"] = Py_exports["PyGILState_Release"]
|
||||
python_function_32_bits["PyGILState_Ensure"] = Py_exports["PyGILState_Ensure"]
|
||||
python_function_32_bits["PyEval_SaveThread"] = Py_exports["PyEval_SaveThread"]
|
||||
python_function_32_bits["Py_Initialize"] = Py_exports["Py_Initialize"]
|
||||
python_function_32_bits["PyRun_SimpleString"] = Py_exports["PyRun_SimpleString"]
|
||||
Py_exports = python_function_32_bits
|
||||
PyEval_InitThreads = Py_exports["PyEval_InitThreads"]
|
||||
Py_IsInitialized = Py_exports["Py_IsInitialized"]
|
||||
PyGILState_Release = Py_exports["PyGILState_Release"]
|
||||
PyGILState_Ensure = Py_exports["PyGILState_Ensure"]
|
||||
PyEval_SaveThread = Py_exports["PyEval_SaveThread"]
|
||||
Py_Initialize = Py_exports["Py_Initialize"]
|
||||
PyRun_SimpleString = Py_exports["PyRun_SimpleString"]
|
||||
|
||||
code = x86.MultipleInstr()
|
||||
# Load python27.dll
|
||||
code += x86.Push(PYDLL_addr)
|
||||
code += x86.Mov('EAX', LoadLibraryA)
|
||||
code += x86.Mov('EAX', Py_IsInitialized)
|
||||
code += x86.Call('EAX')
|
||||
code += x86.Mov("EDI", "EAX")
|
||||
code += x86.Cmp("EAX", 0)
|
||||
code += x86.Jnz(":DO_ENSURE")
|
||||
# Python Initilisation code
|
||||
# init multithread (for other injection)
|
||||
code += x86.Mov('EAX', PyEval_InitThreads)
|
||||
code += x86.Call('EAX')
|
||||
code += x86.Mov('EAX', Py_Initialize)
|
||||
code += x86.Call('EAX')
|
||||
code += x86.Label(":DO_ENSURE")
|
||||
code += x86.Mov('EAX', PyGILState_Ensure)
|
||||
code += x86.Call('EAX')
|
||||
# Get PyInit function into pythondll
|
||||
code += x86.Push('EAX')
|
||||
code += x86.Pop('EDI')
|
||||
code += x86.Push(PyInit)
|
||||
code += x86.Push('EDI')
|
||||
code += x86.Mov('EBX', GetProcAddress)
|
||||
code += x86.Call('EBX')
|
||||
# Call PyInit
|
||||
code += x86.Call('EAX')
|
||||
# Get PyRun function into pythondll
|
||||
code += x86.Push(PyRun)
|
||||
code += x86.Push('EDI')
|
||||
code += x86.Call('EBX')
|
||||
# Call PyRun with python code to exec
|
||||
code += x86.Push(PYCODE_ADDR)
|
||||
code += x86.Mov('EAX', PyRun_SimpleString)
|
||||
code += x86.Call('EAX')
|
||||
code += x86.Pop('EDI')
|
||||
code += x86.Mov("ESI", "EAX")
|
||||
code += x86.Mov('EAX', PyGILState_Release)
|
||||
code += x86.Call('EAX')
|
||||
code += x86.Pop('EAX')
|
||||
code += x86.Cmp("EDI", 0)
|
||||
code += x86.Jnz(":RETURN")
|
||||
# If PyEval_InitThreads was called (init done in this thread)
|
||||
# We must release the GIL
|
||||
code += x86.Mov('EAX', PyEval_SaveThread)
|
||||
code += x86.Call('EAX')
|
||||
code += x86.Label(":RETURN")
|
||||
code += x86.Mov("EAX", "ESI")
|
||||
code += x86.Pop("EDI")
|
||||
code += x86.Ret()
|
||||
return code.get_code()
|
||||
|
||||
|
||||
python_function_64_bits = {}
|
||||
# 64 to 64 injection
|
||||
def generate_python_exec_shellcode_64(target, PYDLL_addr, PyInit, PyRun, PYCODE_ADDR):
|
||||
|
||||
LoadLibraryA, GetProcAddress = get_loadlib_getproc(target)
|
||||
def generate_python_exec_shellcode_64(target, PYCODE_ADDR, PyDll):
|
||||
if not python_function_64_bits:
|
||||
pymodule = [mod for mod in target.peb.modules if mod.name == PyDll][0]
|
||||
Py_exports = pymodule.pe.exports
|
||||
python_function_64_bits["PyEval_InitThreads"] = Py_exports["PyEval_InitThreads"]
|
||||
python_function_64_bits["Py_IsInitialized"] = Py_exports["Py_IsInitialized"]
|
||||
python_function_64_bits["PyGILState_Release"] = Py_exports["PyGILState_Release"]
|
||||
python_function_64_bits["PyGILState_Ensure"] = Py_exports["PyGILState_Ensure"]
|
||||
python_function_64_bits["PyEval_SaveThread"] = Py_exports["PyEval_SaveThread"]
|
||||
python_function_64_bits["Py_Initialize"] = Py_exports["Py_Initialize"]
|
||||
python_function_64_bits["PyRun_SimpleString"] = Py_exports["PyRun_SimpleString"]
|
||||
Py_exports = python_function_64_bits
|
||||
PyEval_InitThreads = Py_exports["PyEval_InitThreads"]
|
||||
Py_IsInitialized = Py_exports["Py_IsInitialized"]
|
||||
PyGILState_Release = Py_exports["PyGILState_Release"]
|
||||
PyGILState_Ensure = Py_exports["PyGILState_Ensure"]
|
||||
PyEval_SaveThread = Py_exports["PyEval_SaveThread"]
|
||||
Py_Initialize = Py_exports["Py_Initialize"]
|
||||
PyRun_SimpleString = Py_exports["PyRun_SimpleString"]
|
||||
|
||||
Reserve_space_for_call = x64.MultipleInstr([x64.Push('RDI')] * 4)
|
||||
Clean_space_for_call = x64.MultipleInstr([x64.Pop('RDI')] * 4)
|
||||
|
||||
code = x64.MultipleInstr()
|
||||
# Do stack alignement
|
||||
code += x64.Push('RCX')
|
||||
# Load python27.dll
|
||||
code += x64.Mov('RCX', PYDLL_addr)
|
||||
code += x64.Mov('RAX', LoadLibraryA)
|
||||
code += Reserve_space_for_call
|
||||
code += x64.Mov('RAX', Py_IsInitialized)
|
||||
code += x64.Call('RAX')
|
||||
code += Clean_space_for_call
|
||||
code += x64.Push('RAX')
|
||||
code += x64.Pop('RCX')
|
||||
# Save RCX
|
||||
code += x64.Push('RCX')
|
||||
# Align stack
|
||||
code += x64.Push('RDI')
|
||||
# Get PyInit function into pythondll
|
||||
code += Reserve_space_for_call
|
||||
code += x64.Mov('RDX', PyInit)
|
||||
code += x64.Mov('RBX', GetProcAddress)
|
||||
code += x64.Call('RBX')
|
||||
# Call PyInit
|
||||
code += x64.Mov("RDI", "RAX")
|
||||
code += x64.Cmp("RAX", 0)
|
||||
code += x64.Jnz(":DO_ENSURE")
|
||||
code += x64.Mov('RAX', PyEval_InitThreads)
|
||||
code += x64.Call('RAX')
|
||||
code += x64.Mov('RAX', Py_Initialize)
|
||||
code += x64.Call('RAX')
|
||||
code += x64.Label(":DO_ENSURE")
|
||||
code += x64.Mov('RAX', PyGILState_Ensure)
|
||||
code += x64.Call('RAX')
|
||||
code += Clean_space_for_call
|
||||
# Remove Stack align
|
||||
code += x64.Pop('RDI')
|
||||
# Restore pythondll base into rcx
|
||||
code += x64.Pop('RCX')
|
||||
# Get PyRun function into pythondll
|
||||
code += x64.Mov('RDX', PyRun)
|
||||
code += Reserve_space_for_call
|
||||
code += x64.Call('RBX')
|
||||
# Call PyInit with python code to exec
|
||||
code += x64.Mov('R15', 'RAX')
|
||||
code += x64.Mov('RAX', PyRun_SimpleString)
|
||||
code += x64.Mov('RCX', PYCODE_ADDR)
|
||||
code += x64.Call('RAX')
|
||||
code += x64.Mov('RCX', 'R15')
|
||||
code += x64.Mov('R15', 'RAX')
|
||||
code += x64.Mov('RAX', PyGILState_Release)
|
||||
code += x64.Call('RAX')
|
||||
code += x64.Cmp("RDI", 0)
|
||||
code += x64.Jnz(":RETURN")
|
||||
# If PyEval_InitThreads was called (init done in this thread)
|
||||
# We must release the GIL
|
||||
code += x64.Mov('RAX', PyEval_SaveThread)
|
||||
code += x64.Call('RAX')
|
||||
code += x64.Label(":RETURN")
|
||||
code += Clean_space_for_call
|
||||
# Remove stack alignement
|
||||
code += x64.Pop('RCX')
|
||||
code += x64.Mov("RAX", "R15")
|
||||
code += x64.Ret()
|
||||
return code.get_code()
|
||||
|
||||
|
||||
def inject_python_command(process, code_injected, PYDLL="python27.dll\x00"):
|
||||
PyInitT = "Py_Initialize\x00"
|
||||
Pyrun = "PyRun_SimpleString\x00"
|
||||
def inject_python_command(target, code_injected, PYDLL):
|
||||
"""Postulate: PYDLL is already loaded in target process"""
|
||||
PYCODE = code_injected + "\x00"
|
||||
remote_addr_base = process.virtual_alloc(len(code_injected) + 0x100)
|
||||
remote_addr = remote_addr_base
|
||||
# TODO: free this (how ? when ?)
|
||||
remote_addr = target.virtual_alloc(len(PYCODE) + 0x100)
|
||||
target.write_memory(remote_addr, PYCODE)
|
||||
SHELLCODE_ADDR = remote_addr + len(PYCODE)
|
||||
|
||||
PYDLL_addr = remote_addr
|
||||
process.write_memory(remote_addr, PYDLL)
|
||||
remote_addr += len(PYDLL)
|
||||
|
||||
PyInitT_ADDR = remote_addr
|
||||
process.write_memory(remote_addr, PyInitT)
|
||||
remote_addr += len(PyInitT)
|
||||
|
||||
Pyrun_ADDR = remote_addr
|
||||
process.write_memory(remote_addr, Pyrun)
|
||||
remote_addr += len(Pyrun)
|
||||
|
||||
PYCODE_ADDR = remote_addr
|
||||
process.write_memory(remote_addr, PYCODE)
|
||||
remote_addr += len(PYCODE)
|
||||
|
||||
SHELLCODE_ADDR = remote_addr
|
||||
if process.bitness == 32:
|
||||
if target.bitness == 32:
|
||||
shellcode_generator = generate_python_exec_shellcode_32
|
||||
else:
|
||||
shellcode_generator = generate_python_exec_shellcode_64
|
||||
shellcode = shellcode_generator(process, PYDLL_addr, PyInitT_ADDR, Pyrun_ADDR, PYCODE_ADDR)
|
||||
process.write_memory(SHELLCODE_ADDR, shellcode)
|
||||
|
||||
shellcode = shellcode_generator(target, remote_addr, PYDLL)
|
||||
target.write_memory(SHELLCODE_ADDR, shellcode)
|
||||
return SHELLCODE_ADDR
|
||||
|
||||
|
||||
def validate_python_dll_presence(process):
|
||||
def validate_python_dll_presence_on_disk(process):
|
||||
if windows.current_process.bitness == process.bitness:
|
||||
return True
|
||||
if windows.current_process.bitness == 32 and process.bitness == 64:
|
||||
@@ -146,9 +273,12 @@ def validate_python_dll_presence(process):
|
||||
raise NotImplementedError("Unknown bitness")
|
||||
|
||||
def execute_python_code(process, code):
|
||||
validate_python_dll_presence(process)
|
||||
shellcode_remote_addr = inject_python_command(process, code)
|
||||
return process.create_thread(shellcode_remote_addr, 0)
|
||||
validate_python_dll_presence_on_disk(process)
|
||||
load_dll_in_remote_process(process, "python27.dll")
|
||||
addr = inject_python_command(process, code, "python27.dll")
|
||||
t = process.create_thread(addr, 0)
|
||||
return t
|
||||
|
||||
|
||||
retrieve_exc = r"""
|
||||
import traceback
|
||||
@@ -164,11 +294,10 @@ buff[:] = txt
|
||||
"""
|
||||
|
||||
def retrieve_last_exception_data(process):
|
||||
# TODO : FREE THIS
|
||||
mem = process.virtual_alloc(0x1000)
|
||||
execute_python_code(process, retrieve_exc.format(mem))
|
||||
size = struct.unpack("<I", process.read_memory(mem, ctypes.sizeof(ctypes.c_uint)))[0]
|
||||
data = process.read_memory(mem + ctypes.sizeof(ctypes.c_uint), size)
|
||||
with process.allocated_memory(0x1000) as mem:
|
||||
execute_python_code(process, retrieve_exc.format(mem))
|
||||
size = struct.unpack("<I", process.read_memory(mem, ctypes.sizeof(ctypes.c_uint)))[0]
|
||||
data = process.read_memory(mem + ctypes.sizeof(ctypes.c_uint), size)
|
||||
return data
|
||||
|
||||
class RemotePythonError(Exception):
|
||||
|
||||
@@ -0,0 +1,282 @@
|
||||
import windows
|
||||
|
||||
import windows.native_exec.simple_x64 as x64
|
||||
import windows.native_exec.simple_x86 as x86
|
||||
from windows.generated_def.winstructs import *
|
||||
|
||||
|
||||
StrlenW64 = x64.MultipleInstr()
|
||||
StrlenW64 += x64.Label(":FUNC_STRLENW64")
|
||||
StrlenW64 += x64.Push("RCX")
|
||||
StrlenW64 += x64.Push("RDI")
|
||||
StrlenW64 += x64.Mov("RDI", "RCX")
|
||||
StrlenW64 += x64.Xor("RAX", "RAX")
|
||||
StrlenW64 += x64.Xor("RCX", "RCX")
|
||||
StrlenW64 += x64.Dec("RCX")
|
||||
StrlenW64 += x64.Repne + x64.ScasW()
|
||||
StrlenW64 += x64.Not("RCX")
|
||||
StrlenW64 += x64.Dec("RCX")
|
||||
StrlenW64 += x64.Mov("RAX", "RCX")
|
||||
StrlenW64 += x64.Pop("RDI")
|
||||
StrlenW64 += x64.Pop("RCX")
|
||||
StrlenW64 += x64.Ret()
|
||||
|
||||
|
||||
StrlenA64 = x64.MultipleInstr()
|
||||
StrlenA64 += x64.Label(":FUNC_STRLENA64")
|
||||
StrlenA64 += x64.Push("RCX")
|
||||
StrlenA64 += x64.Push("RDI")
|
||||
StrlenA64 += x64.Mov("RDI", "RCX")
|
||||
StrlenA64 += x64.Xor("RAX", "RAX")
|
||||
StrlenA64 += x64.Xor("RCX", "RCX")
|
||||
StrlenA64 += x64.Dec("RCX")
|
||||
StrlenA64 += x64.Repne + x64.ScasB()
|
||||
StrlenA64 += x64.Not("RCX")
|
||||
StrlenA64 += x64.Dec("RCX")
|
||||
StrlenA64 += x64.Mov("RAX", "RCX")
|
||||
StrlenA64 += x64.Pop("RDI")
|
||||
StrlenA64 += x64.Pop("RCX")
|
||||
StrlenA64 += x64.Ret()
|
||||
|
||||
|
||||
GetProcAddress64 = x64.MultipleInstr()
|
||||
GetProcAddress64 += x64.Label(":FUNC_GETPROCADDRESS64")
|
||||
GetProcAddress64 += x64.Push("RBX")
|
||||
GetProcAddress64 += x64.Push("RCX")
|
||||
GetProcAddress64 += x64.Push("RDX")
|
||||
GetProcAddress64 += x64.Push("RSI")
|
||||
GetProcAddress64 += x64.Push("RDI")
|
||||
GetProcAddress64 += x64.Push("R8")
|
||||
GetProcAddress64 += x64.Push("R9")
|
||||
GetProcAddress64 += x64.Push("R10")
|
||||
GetProcAddress64 += x64.Push("R11")
|
||||
GetProcAddress64 += x64.Push("R12")
|
||||
GetProcAddress64 += x64.Push("R13")
|
||||
# Params : RCX -> libname
|
||||
# Params : RDX -> API Name
|
||||
GetProcAddress64 += x64.Mov("R11", "RCX")
|
||||
GetProcAddress64 += x64.Mov("R12", "RDX")
|
||||
GetProcAddress64 += x64.Mov("RAX", x64.mem("GS:[0x60]")) #PEB !
|
||||
GetProcAddress64 += x64.Mov("RAX", x64.mem("[RAX + 24] ")) # ; RAX = ldr (+ 6 for 64 cause of 2 ptr)
|
||||
GetProcAddress64 += x64.Mov("RAX", x64.mem("[RAX + 32]")) # ; RAX on the first elt of the list (first module)
|
||||
GetProcAddress64 += x64.Mov("RDX", "RAX")
|
||||
GetProcAddress64 += x64.Label(":a_dest")
|
||||
GetProcAddress64 += x64.Mov("RAX", "RDX")
|
||||
GetProcAddress64 += x64.Mov("RBX", x64.mem("[RAX + 32]")) # RBX : first base ! (base of current module)
|
||||
#GetProcAddress64 += x64.Mov("RBX ", x64.mem("[RAX + 32]")) # RBX : first base ! (base of current module)
|
||||
GetProcAddress64 += x64.Cmp("RBX", 0)
|
||||
GetProcAddress64 += x64.Jz(":DLL_NOT_FOUND")
|
||||
GetProcAddress64 += x64.Mov("RCX", x64.mem("[RAX + 80]")) # RCX = NAME (UNICODE_STRING.Buffer)
|
||||
GetProcAddress64 += x64.Call(":FUNC_STRLENW64")
|
||||
GetProcAddress64 += x64.Mov("RDI", "RCX")
|
||||
GetProcAddress64 += x64.Mov("RCX", "RAX")
|
||||
GetProcAddress64 += x64.Mov("RSI", "R11")
|
||||
#GetProcAddress64 += x64.Int3()
|
||||
GetProcAddress64 += x64.Rep + x64.CmpsW() #;cmp with current dll name (unicode)
|
||||
GetProcAddress64 += x64.Test("RCX", "RCX")
|
||||
GetProcAddress64 += x64.Jz(":DLL_FOUND")
|
||||
GetProcAddress64 += x64.Mov("RDX", x64.mem("[RDX]"))
|
||||
GetProcAddress64 += x64.Jmp(":a_dest")
|
||||
GetProcAddress64 += x64.Label(":DLL_FOUND") # here rbx = base
|
||||
GetProcAddress64 += x64.Mov("EAX", x64.mem("[RBX + 60]")) # rax = PEBASE RVA
|
||||
GetProcAddress64 += x64.Add("RAX", "RBX") # RAX = PEBASE
|
||||
GetProcAddress64 += x64.Add("RAX", 24) # ;OPTIONAL HEADER
|
||||
GetProcAddress64 += x64.Mov("ECX", x64.mem("[rax + 112]")) # ;rcx = RVA export dir
|
||||
GetProcAddress64 += x64.Add("RCX", "RBX") # ;rcx = export_dir
|
||||
GetProcAddress64 += x64.Mov("RAX", "RCX") # ;RAX = export_dir
|
||||
GetProcAddress64 += x64.Push("RAX") # ;Save it for after function search
|
||||
# ; EBX = BASE | EAX = EXPORT DIR
|
||||
GetProcAddress64 += x64.Mov("ECX", x64.mem("[RAX + 24] "))
|
||||
GetProcAddress64 += x64.Mov("R13", "RCX") # ;r13 = NB names
|
||||
GetProcAddress64 += x64.Mov("EDX", x64.mem("[RAX + 32] ")) # EDX = names array RVA
|
||||
GetProcAddress64 += x64.Add("RDX", "RBX") # RDX = names array
|
||||
GetProcAddress64 += x64.Xor("RCX", "RCX")
|
||||
GetProcAddress64 += x64.Label(":SEARCH_LOOP")
|
||||
GetProcAddress64 += x64.Cmp("RCX", "R13")
|
||||
GetProcAddress64 += x64.Jz(":API_NOT_FOUND")
|
||||
GetProcAddress64 += x64.Mov("ESI", x64.mem("[RDX + RCX * 4]")) # ;Get function name RVA
|
||||
GetProcAddress64 += x64.Add("RSI", "RBX") # ;Get name addr
|
||||
GetProcAddress64 += x64.Push("RCX") # ;Save current index (could use x64 register)
|
||||
GetProcAddress64 += x64.Mov("RCX", "R12")
|
||||
GetProcAddress64 += x64.Call(":FUNC_STRLENA64") # TODO: mov outside the loop :D
|
||||
GetProcAddress64 += x64.Mov("RCX", "RAX")
|
||||
GetProcAddress64 += x64.Mov("RDI", "R12")
|
||||
GetProcAddress64 += x64.Inc("RCX")
|
||||
GetProcAddress64 += x64.Rep + x64.CmpsB()
|
||||
GetProcAddress64 += x64.Mov("EAX", "ECX")
|
||||
GetProcAddress64 += x64.Pop("RCX")
|
||||
GetProcAddress64 += x64.Inc("RCX")
|
||||
GetProcAddress64 += x64.Test("RAX", "RAX")
|
||||
GetProcAddress64 += x64.Jnz(":SEARCH_LOOP")
|
||||
# Func FOUND !
|
||||
GetProcAddress64 += x64.Dec("RCX")
|
||||
GetProcAddress64 += x64.Pop("RAX") # ;Restore export_dir addr
|
||||
GetProcAddress64 += x64.Mov("EDX", x64.mem("[RAX + 36]")) # ;EDX = AddressOfNameOrdinals RVX
|
||||
GetProcAddress64 += x64.Add("RDX", "RBX")
|
||||
GetProcAddress64 += x64.OperandSizeOverride + x64.Mov("ECX", x64.mem("[rdx + rcx * 2]")) # ; ecx = Ieme ordinal (short array)
|
||||
GetProcAddress64 += x64.And('RCX', 0xffff)
|
||||
GetProcAddress64 += x64.Mov("EDX", x64.mem("[RAX + 28]")) # ; AddressOfFunctions RVA
|
||||
GetProcAddress64 += x64.Add("RDX", "RBX")
|
||||
GetProcAddress64 += x64.Mov("EDX", x64.mem("[RDX + RCX * 4]"))
|
||||
GetProcAddress64 += x64.Add("RDX", "RBX")
|
||||
GetProcAddress64 += x64.Mov("RAX", "RDX")
|
||||
GetProcAddress64 += x64.Label(":RETURN")
|
||||
GetProcAddress64 += x64.Pop("R13")
|
||||
GetProcAddress64 += x64.Pop("R12")
|
||||
GetProcAddress64 += x64.Pop("R11")
|
||||
GetProcAddress64 += x64.Pop("R10")
|
||||
GetProcAddress64 += x64.Pop("R9")
|
||||
GetProcAddress64 += x64.Pop("R8")
|
||||
GetProcAddress64 += x64.Pop("RDI")
|
||||
GetProcAddress64 += x64.Pop("RSI")
|
||||
GetProcAddress64 += x64.Pop("RDX")
|
||||
GetProcAddress64 += x64.Pop("RCX")
|
||||
GetProcAddress64 += x64.Pop("RBX")
|
||||
GetProcAddress64 += x64.Ret()
|
||||
GetProcAddress64 += x64.Label(":DLL_NOT_FOUND")
|
||||
GetProcAddress64 += x64.Mov("RAX", 0xfffffffffffffffe)
|
||||
GetProcAddress64 += x64.Jmp(":RETURN")
|
||||
GetProcAddress64 += x64.Label(":API_NOT_FOUND")
|
||||
GetProcAddress64 += x64.Pop("RAX")
|
||||
GetProcAddress64 += x64.Mov("RAX", 0xffffffffffffffff)
|
||||
GetProcAddress64 += x64.Jmp(":RETURN")
|
||||
# Ajout des dependances
|
||||
GetProcAddress64 += StrlenW64
|
||||
GetProcAddress64 += StrlenA64
|
||||
|
||||
|
||||
|
||||
###### 32 bits #######
|
||||
|
||||
|
||||
StrlenW32 = x86.MultipleInstr()
|
||||
StrlenW32 += x86.Label(":FUNC_STRLENW32")
|
||||
StrlenW32 += x86.Push("EDI")
|
||||
StrlenW32 += x86.Mov("EDI", x86.mem("[ESP + 8]"))
|
||||
StrlenW32 += x86.Push("ECX")
|
||||
StrlenW32 += x86.Xor("EAX", "EAX")
|
||||
StrlenW32 += x86.Xor("ECX", "ECX")
|
||||
StrlenW32 += x86.Dec("ECX")
|
||||
StrlenW32 += x86.Repne + x86.ScasW()
|
||||
StrlenW32 += x86.Not("ECX")
|
||||
StrlenW32 += x86.Dec("ECX")
|
||||
StrlenW32 += x86.Mov("EAX", "ECX")
|
||||
StrlenW32 += x86.Pop("ECX")
|
||||
StrlenW32 += x86.Pop("EDI")
|
||||
StrlenW32 += x86.Ret()
|
||||
|
||||
|
||||
StrlenA32 = x86.MultipleInstr()
|
||||
StrlenA32 += x86.Label(":FUNC_STRLENA32")
|
||||
StrlenA32 += x86.Push("EDI")
|
||||
StrlenA32 += x86.Mov("EDI", x86.mem("[ESP + 8]"))
|
||||
StrlenA32 += x86.Push("ECX")
|
||||
StrlenA32 += x86.Xor("EAX", "EAX")
|
||||
StrlenA32 += x86.Xor("ECX", "ECX")
|
||||
StrlenA32 += x86.Dec("ECX")
|
||||
StrlenA32 += x86.Repne + x86.ScasB()
|
||||
StrlenA32 += x86.Not("ECX")
|
||||
StrlenA32 += x86.Dec("ECX")
|
||||
StrlenA32 += x86.Mov("EAX", "ECX")
|
||||
StrlenA32 += x86.Pop("ECX")
|
||||
StrlenA32 += x86.Pop("EDI")
|
||||
StrlenA32 += x86.Ret()
|
||||
|
||||
|
||||
GetProcAddress32 = x86.MultipleInstr()
|
||||
GetProcAddress32 += x86.Label(":FUNC_GETPROCADDRESS32")
|
||||
GetProcAddress32 += x86.Push("EBX")
|
||||
GetProcAddress32 += x86.Push("ECX")
|
||||
GetProcAddress32 += x86.Push("EDI")
|
||||
GetProcAddress32 += x86.Push("ESI")
|
||||
GetProcAddress32 += x86.Push("EBP")
|
||||
GetProcAddress32 += x86.Mov("EAX", x86.mem("FS:[0x30]"))
|
||||
GetProcAddress32 += x86.Mov("EAX", x86.mem("[EAX + 0xC]"))
|
||||
GetProcAddress32 += x86.Mov("EAX", x86.mem("[EAX + 0xC]")) # ; RAX on the first elt of the list (first module)
|
||||
GetProcAddress32 += x86.Mov("EDX", "EAX")
|
||||
GetProcAddress32 += x86.Label(":a_dest")
|
||||
GetProcAddress32 += x86.Mov("EAX", "EDX")
|
||||
GetProcAddress32 += x86.Mov("EBX", x86.mem("[EAX + 0x18]")) # EBX : first base ! (base of current module)
|
||||
GetProcAddress32 += x86.Cmp("EBX", 0)
|
||||
GetProcAddress32 += x86.Jz(":DLL_NOT_FOUND")
|
||||
GetProcAddress32 += x86.Mov("ECX", x86.mem("[EAX + 0x30]")) # RCX = NAME (UNICODE_STRING.Buffer)
|
||||
GetProcAddress32 += x86.Push("ECX")
|
||||
GetProcAddress32 += x86.Call(":FUNC_STRLENW32")
|
||||
GetProcAddress32 += x86.Pop("EDI") # Current name
|
||||
GetProcAddress32 += x86.Mov("ECX", "EAX")
|
||||
GetProcAddress32 += x86.Mov("ESI", x86.mem("[ESP + 0x18]"))
|
||||
GetProcAddress32 += x86.Rep + x86.CmpsW()
|
||||
GetProcAddress32 += x86.Test("ECX", "ECX")
|
||||
GetProcAddress32 += x86.Jz(":DLL_FOUND")
|
||||
GetProcAddress32 += x86.Mov("EDX", x86.mem("[EDX]"))
|
||||
GetProcAddress32 += x86.Jmp(":a_dest")
|
||||
GetProcAddress32 += x86.Label(":DLL_FOUND")
|
||||
GetProcAddress32 += x86.Mov("EAX", x86.mem("[EBX + 0x3c]")) # rax = PEBASE RVA
|
||||
GetProcAddress32 += x86.Add("EAX", "EBX") # RAX = PEBASE
|
||||
GetProcAddress32 += x86.Add("EAX", 0x18) # ;OPTIONAL HEADER
|
||||
GetProcAddress32 += x86.Mov("ECX", x86.mem("[EAX + 0x60]")) # ;ecx = RVA export dir
|
||||
GetProcAddress32 += x86.Add("ECX", "EBX") # ;ecx = export_dir
|
||||
GetProcAddress32 += x86.Mov("EAX", "ECX")
|
||||
GetProcAddress32 += x86.Push("EAX") # Save it
|
||||
# ; EBX = BASE | EAX = EXPORT DIR
|
||||
GetProcAddress32 += x86.Mov("ECX", x86.mem("[EAX + 24] "))
|
||||
GetProcAddress32 += x86.Mov("EBP", "ECX") # ;EBP = NB names
|
||||
GetProcAddress32 += x86.Mov("EDX", x86.mem("[EAX + 32] ")) # EDX = names array RVA
|
||||
GetProcAddress32 += x86.Add("EDX", "EBX") # RDX = names array
|
||||
GetProcAddress32 += x86.Xor("ECX", "ECX")
|
||||
GetProcAddress32 += x86.Mov("ESI", x86.mem("[ESP + 0x20]"))
|
||||
GetProcAddress32 += x86.Label(":SEARCH_LOOP")
|
||||
GetProcAddress32 += x86.Cmp("ECX", "EBP")
|
||||
GetProcAddress32 += x86.Jz(":API_NOT_FOUND")
|
||||
GetProcAddress32 += x86.Mov("EDI", x86.mem("[EDX + ECX * 4]")) # ;Get function name RVA
|
||||
GetProcAddress32 += x86.Add("EDI", "EBX") # ;Get name addr
|
||||
GetProcAddress32 += x86.Push("ECX") # Save current index
|
||||
GetProcAddress32 += x86.Push("ESI")
|
||||
GetProcAddress32 += x86.Call(":FUNC_STRLENA32")
|
||||
GetProcAddress32 += x86.Mov("ECX", "EAX")
|
||||
GetProcAddress32 += x86.Push("EDI")
|
||||
GetProcAddress32 += x86.Call(":FUNC_STRLENA32")
|
||||
GetProcAddress32 += x86.Pop("EDI")
|
||||
GetProcAddress32 += x86.Cmp("EAX", "ECX")
|
||||
GetProcAddress32 += x86.Jnz(":ABORT_STRCMP")
|
||||
GetProcAddress32 += x86.Inc("ECX")
|
||||
GetProcAddress32 += x86.Rep + x86.CmpsB()
|
||||
GetProcAddress32 += x86.Label(":ABORT_STRCMP")
|
||||
GetProcAddress32 += x86.Pop("ESI")
|
||||
GetProcAddress32 += x86.Mov("EAX", "ECX")
|
||||
GetProcAddress32 += x86.Pop("ECX")
|
||||
GetProcAddress32 += x86.Inc("ECX")
|
||||
GetProcAddress32 += x86.Test("EAX", "EAX")
|
||||
GetProcAddress32 += x86.Jnz(":SEARCH_LOOP")
|
||||
|
||||
GetProcAddress32 += x86.Dec("ECX")
|
||||
#GetProcAddress32 += x86.Int3()
|
||||
#GetProcAddress32 += x86.Int3() # da poi(edx + (ecx * 4)) + ebx; da esi
|
||||
GetProcAddress32 += x86.Pop("EAX") # ;Restore export_dir addr
|
||||
GetProcAddress32 += x86.Mov("EDX", x86.mem("[EAX + 36]")) # ;EDX = AddressOfNameOrdinals RVX
|
||||
GetProcAddress32 += x86.Add("EDX", "EBX")
|
||||
#GetProcAddress32 += x86.Mov("ECX", x86.mem("[EDX + ECX * 2]"))
|
||||
GetProcAddress32 += x86.OperandSizeOverride + x86.Mov("ECX", x86.mem("[EDX + ECX * 2]"))
|
||||
# ; ecx = Ieme ordinal (short array)
|
||||
GetProcAddress32 += x86.And('ECX', 0xffff)
|
||||
GetProcAddress32 += x86.Mov("EDX", x86.mem("[EAX + 28]")) # ; AddressOfFunctions RVA
|
||||
GetProcAddress32 += x86.Add("EDX", "EBX")
|
||||
GetProcAddress32 += x86.Mov("EDX", x86.mem("[EDX + ECX * 4]"))
|
||||
GetProcAddress32 += x86.Add("EDX", "EBX")
|
||||
GetProcAddress32 += x86.Mov("EAX", "EDX")
|
||||
GetProcAddress32 += x86.Label(":RETURN")
|
||||
GetProcAddress32 += x86.Pop("EBP")
|
||||
GetProcAddress32 += x86.Pop("ESI")
|
||||
GetProcAddress32 += x86.Pop("EDI")
|
||||
GetProcAddress32 += x86.Pop("ECX")
|
||||
GetProcAddress32 += x86.Pop("EBX")
|
||||
GetProcAddress32 += x86.Ret()
|
||||
GetProcAddress32 += x86.Label(":DLL_NOT_FOUND")
|
||||
GetProcAddress32 += x86.Mov("EAX", 0xfffffffe)
|
||||
GetProcAddress32 += x86.Jmp(":RETURN")
|
||||
GetProcAddress32 += x86.Label(":API_NOT_FOUND")
|
||||
GetProcAddress32 += x86.Pop("EAX")
|
||||
GetProcAddress32 += x86.Mov("EAX", 0xffffffff)
|
||||
GetProcAddress32 += x86.Jmp(":RETURN")
|
||||
GetProcAddress32 += StrlenW32
|
||||
GetProcAddress32 += StrlenA32
|
||||
@@ -715,16 +715,14 @@ class JmpType(Instruction):
|
||||
|
||||
class Push(Instruction):
|
||||
encoding = [(RawBits.from_int(5, 0x50 >> 3), X64RegisterSelector()),
|
||||
(RawBits.from_int(8, 0x68), Imm32())]
|
||||
(RawBits.from_int(8, 0x68), Imm32()),
|
||||
(RawBits.from_int(8, 0xff), Slash(6))]
|
||||
|
||||
|
||||
class Pop(Instruction):
|
||||
encoding = [(RawBits.from_int(5, 0x58 >> 3), X64RegisterSelector())]
|
||||
|
||||
|
||||
class Call(Instruction):
|
||||
encoding = [(RawBits.from_int(8, 0xff), Slash(2))]
|
||||
|
||||
|
||||
class Xchg(Instruction):
|
||||
default_32_bits = True
|
||||
@@ -820,6 +818,10 @@ class JmpImm8(JmpImm):
|
||||
class JmpImm32(JmpImm):
|
||||
accept_as_Ximmediat = staticmethod(accept_as_32immediat)
|
||||
|
||||
class Call(JmpType):
|
||||
encoding = [(RawBits.from_int(8, 0xe8), JmpImm32(5)),
|
||||
(RawBits.from_int(8, 0xff), Slash(2))]
|
||||
|
||||
|
||||
class Jmp(JmpType):
|
||||
encoding = [(RawBits.from_int(8, 0xeb), JmpImm8(2)),
|
||||
@@ -867,10 +869,17 @@ class Mov(Instruction):
|
||||
|
||||
class Cmp(Instruction):
|
||||
default_32_bits = True
|
||||
|
||||
encoding = [(RawBits.from_int(8, 0x3d), RegisterRax(), Imm32()),
|
||||
(RawBits.from_int(8, 0x81), Slash(7), Imm32()),
|
||||
(RawBits.from_int(8, 0x3b), ModRM([ModRM_REG__REG, ModRM_REG64__MEM]))]
|
||||
|
||||
class Test(Instruction):
|
||||
default_32_bits = True
|
||||
refuse_reverse = True
|
||||
encoding = [(RawBits.from_int(8, 0xf7), Slash(7), Imm32()),
|
||||
(RawBits.from_int(8, 0x85), ModRM([ModRM_REG__REG, ModRM_REG64__MEM], has_direction_bit=False))]
|
||||
|
||||
|
||||
class Xor(Instruction):
|
||||
default_32_bits = True
|
||||
@@ -880,6 +889,47 @@ class Xor(Instruction):
|
||||
class Nop(Instruction):
|
||||
encoding = [(RawBits.from_int(8, 0x90),)]
|
||||
|
||||
class Not(Instruction):
|
||||
default_32_bits = True
|
||||
encoding = [(RawBits.from_int(8, 0xF7), Slash(2))]
|
||||
|
||||
class ScasB(Instruction):
|
||||
default_32_bits = True
|
||||
encoding = [(RawBits.from_int(8, 0xAE),)]
|
||||
|
||||
|
||||
class ScasW(Instruction):
|
||||
default_32_bits = True
|
||||
encoding = [(RawBits.from_int(16, 0x66AF),)]
|
||||
|
||||
|
||||
class ScasD(Instruction):
|
||||
default_32_bits = True
|
||||
encoding = [(RawBits.from_int(8, 0xAF),)]
|
||||
|
||||
class ScasQ(Instruction):
|
||||
encoding = [(RawBits.from_int(16, 0x48AF),)]
|
||||
|
||||
|
||||
class CmpsB(Instruction):
|
||||
default_32_bits = True
|
||||
encoding = [(RawBits.from_int(8, 0xa6),)]
|
||||
|
||||
|
||||
class CmpsW(Instruction):
|
||||
default_32_bits = True
|
||||
encoding = [(RawBits.from_int(16, 0x66A7),)]
|
||||
|
||||
|
||||
class CmpsD(Instruction):
|
||||
default_32_bits = True
|
||||
encoding = [(RawBits.from_int(8, 0xa7),)]
|
||||
|
||||
|
||||
class CmpsQ(Instruction):
|
||||
default_32_bits = True
|
||||
encoding = [(RawBits.from_int(16, 0x48A7),)]
|
||||
|
||||
|
||||
class Retf(Instruction):
|
||||
default_32_bits = True
|
||||
@@ -922,7 +972,7 @@ class MultipleInstr(object):
|
||||
|
||||
def get_code(self):
|
||||
if self.expected_labels:
|
||||
raise ValueError("Unresolved labels: {self.expected_labels}".format(self=self))
|
||||
raise ValueError("Unresolved labels: {0}".format(self.expected_labels.keys()))
|
||||
return b"".join([bytes(x[1].get_code()) for x in sorted(self.instrs.items())])
|
||||
|
||||
def add_instruction(self, instruction):
|
||||
@@ -1036,7 +1086,12 @@ class MultipleInstr(object):
|
||||
self.size -= 1
|
||||
|
||||
def merge_shellcode(self, other):
|
||||
shared_labels = set(self.labels) & set(other.labels)
|
||||
if shared_labels:
|
||||
raise ValueError("Cannot merge shellcode: shared labels {0}".format(shared_labels))
|
||||
for offset, instr in sorted(other.instrs.items()):
|
||||
for label_name in [name for name, label_offset in other.labels.items() if label_offset == offset]:
|
||||
self.add_instruction(Label(label_name))
|
||||
self.add_instruction(instr)
|
||||
|
||||
def __iadd__(self, other):
|
||||
|
||||
@@ -580,6 +580,11 @@ class JmpImm32(JmpImm):
|
||||
|
||||
|
||||
# Instructions
|
||||
|
||||
class Call(JmpType):
|
||||
encoding = [(RawBits.from_int(8, 0xe8), JmpImm32(5)),
|
||||
(RawBits.from_int(8, 0xff), Slash(2))]
|
||||
|
||||
class Jmp(JmpType):
|
||||
encoding = [(RawBits.from_int(8, 0xeb), JmpImm8(2)),
|
||||
(RawBits.from_int(8, 0xe9), JmpImm32(5))]
|
||||
@@ -607,7 +612,8 @@ class Jnb(JmpType):
|
||||
|
||||
class Push(Instruction):
|
||||
encoding = [(RawBits.from_int(5, 0x50 >> 3), X86RegisterSelector()),
|
||||
(RawBits.from_int(8, 0x68), Imm32())]
|
||||
(RawBits.from_int(8, 0x68), Imm32()),
|
||||
(RawBits.from_int(8, 0xff), Slash(6))]
|
||||
|
||||
|
||||
class Pop(Instruction):
|
||||
@@ -674,6 +680,11 @@ class Cmp(Instruction):
|
||||
(RawBits.from_int(8, 0x3b), ModRM([ModRM_REG__REG, ModRM_REG__MEM]))]
|
||||
|
||||
|
||||
class Test(Instruction):
|
||||
encoding = [(RawBits.from_int(8, 0xf7), Slash(7), Imm32()),
|
||||
(RawBits.from_int(8, 0x85), ModRM([ModRM_REG__REG, ModRM_REG__MEM], has_direction_bit=False))]
|
||||
|
||||
|
||||
class Out(Instruction):
|
||||
encoding = [(RawBits.from_int(8, 0xee), FixedRegister('DX'), FixedRegister('AL')),
|
||||
(RawBits.from_int(16, 0x66ef), FixedRegister('DX'), FixedRegister('AX')), # Fuck-it hardcoded prefix for now
|
||||
@@ -694,8 +705,7 @@ class Xchg(Instruction):
|
||||
encoding = [(RawBits.from_int(5, 0x90 >> 3), RegisterEax(), X86RegisterSelector()), (RawBits.from_int(5, 0x90 >> 3), X86RegisterSelector(), RegisterEax())]
|
||||
|
||||
|
||||
class Call(Instruction):
|
||||
encoding = [(RawBits.from_int(8, 0xff), Slash(2))]
|
||||
|
||||
|
||||
|
||||
class Cpuid(Instruction):
|
||||
@@ -706,9 +716,36 @@ class Ret(Instruction):
|
||||
encoding = [(RawBits.from_int(8, 0xc3),)]
|
||||
|
||||
|
||||
class ScasB(Instruction):
|
||||
encoding = [(RawBits.from_int(8, 0xAE),)]
|
||||
|
||||
class ScasW(Instruction):
|
||||
encoding = [(RawBits.from_int(16, 0x66AF),)]
|
||||
|
||||
class ScasD(Instruction):
|
||||
encoding = [(RawBits.from_int(8, 0xAF),)]
|
||||
|
||||
|
||||
class CmpsB(Instruction):
|
||||
default_32_bits = True
|
||||
encoding = [(RawBits.from_int(8, 0xa6),)]
|
||||
|
||||
|
||||
class CmpsW(Instruction):
|
||||
default_32_bits = True
|
||||
encoding = [(RawBits.from_int(16, 0x66A7),)]
|
||||
|
||||
|
||||
class CmpsD(Instruction):
|
||||
default_32_bits = True
|
||||
encoding = [(RawBits.from_int(8, 0xa7),)]
|
||||
|
||||
|
||||
class Nop(Instruction):
|
||||
encoding = [(RawBits.from_int(8, 0x90),)]
|
||||
|
||||
class Not(Instruction):
|
||||
encoding = [(RawBits.from_int(8, 0xF7), Slash(2))]
|
||||
|
||||
class Retf(Instruction):
|
||||
encoding = [(RawBits.from_int(8, 0xcb),)]
|
||||
@@ -866,7 +903,12 @@ class MultipleInstr(object):
|
||||
self.size -= 1
|
||||
|
||||
def merge_shellcode(self, other):
|
||||
shared_labels = set(self.labels) & set(other.labels)
|
||||
if shared_labels:
|
||||
raise ValueError("Cannot merge shellcode: shared labels {0}".format(shared_labels))
|
||||
for offset, instr in sorted(other.instrs.items()):
|
||||
for label_name in [name for name, label_offset in other.labels.items() if label_offset == offset]:
|
||||
self.add_instruction(Label(label_name))
|
||||
self.add_instruction(instr)
|
||||
|
||||
def __iadd__(self, other):
|
||||
|
||||
@@ -13,9 +13,10 @@ mnemonic_name_exception = {'movabs': 'mov'}
|
||||
|
||||
|
||||
class TestInstr(object):
|
||||
def __init__(self, instr_to_test, immediat_accepted=None, must_fail=None, debug=False):
|
||||
def __init__(self, instr_to_test, expected_result=None, immediat_accepted=None, must_fail=None, debug=False):
|
||||
self.instr_to_test = instr_to_test
|
||||
self.immediat_accepted = immediat_accepted
|
||||
self.expected_result = expected_result
|
||||
self.must_fail = must_fail
|
||||
self.debug = debug
|
||||
|
||||
@@ -40,6 +41,11 @@ class TestInstr(object):
|
||||
raise AssertionError("Trying to disas an instruction resulted in multiple disassembled instrs")
|
||||
capres = capres_list[0]
|
||||
print("{0} {1}".format(capres.mnemonic, capres.op_str))
|
||||
if self.expected_result is not None:
|
||||
if "{0} {1}".format(capres.mnemonic, capres.op_str) == self.expected_result:
|
||||
return True
|
||||
else:
|
||||
raise AssertionError("Expected result <{0}> got <{1}>".format(self.expected_result, "{0} {1}".format(capres.mnemonic, capres.op_str)))
|
||||
if len(res) != len(capres.bytes):
|
||||
raise AssertionError("Not all bytes have been used by the disassembler")
|
||||
self.compare_mnemo(capres)
|
||||
@@ -128,6 +134,7 @@ TestInstr(Mov, immediat_accepted=-1)('RCX', 0xffffffffffffffff)
|
||||
TestInstr(Mov)(mem('gs:[0x1122334455667788]'), 'RAX')
|
||||
TestInstr(Mov)(mem('[RAX]'), 0x11223344)
|
||||
TestInstr(Mov)(mem('[EAX]'), 0x11223344)
|
||||
TestInstr(Mov)(mem('[RBX]'), 0x11223344)
|
||||
|
||||
TestInstr(And)('RCX', 'RBX')
|
||||
TestInstr(And)('RAX', 0x11223344)
|
||||
@@ -143,11 +150,24 @@ TestInstr(Or)(mem('[RAX + 1]'), 'R8')
|
||||
TestInstr(Or)(mem('[EAX + 1]'), 'R8')
|
||||
TestInstr(Or)(mem('[RAX + 1]'), 'EAX')
|
||||
|
||||
# I really don't know why it's the inverse
|
||||
# But I don't care, it's Test dude..
|
||||
TestInstr(Test, expected_result="test r11, rax")('RAX', 'R11')
|
||||
TestInstr(Test, expected_result="test edi, eax")('EAX', 'EDI')
|
||||
TestInstr(Test)('RCX', 'RCX')
|
||||
|
||||
TestInstr(Test)(mem('[RDI + 0x100]'), 'RCX')
|
||||
|
||||
assert Test(mem('[RDI + 0x100]'), 'RCX').get_code() == Test('RCX', mem('[RDI + 0x100]')).get_code()
|
||||
|
||||
|
||||
TestInstr(Push)('R15')
|
||||
TestInstr(Push)(0x42)
|
||||
TestInstr(Push)(-1)
|
||||
TestInstr(Push)(mem("[ECX]"))
|
||||
TestInstr(Push)(mem("[RCX]"))
|
||||
|
||||
|
||||
TestInstr(Call)('RAX')
|
||||
TestInstr(Call)(mem('[RAX + RCX * 8]'))
|
||||
TestInstr(Cpuid)()
|
||||
@@ -168,6 +188,21 @@ TestInstr(Mov)(mem('[RBX + RCX + 0x10]'), 'ECX')
|
||||
TestInstr(Mov)(mem('[EBX + ECX + 0x10]'), 'ECX')
|
||||
TestInstr(Mov)(mem('[EBX + ECX + 0x10]'), 'R8')
|
||||
|
||||
TestInstr(Not)('RAX')
|
||||
TestInstr(Not)(mem('[RAX]'))
|
||||
|
||||
|
||||
TestInstr(ScasB, expected_result="scasb al, byte ptr [rdi]")()
|
||||
TestInstr(ScasW, expected_result="scasw ax, word ptr [rdi]")()
|
||||
TestInstr(ScasD, expected_result="scasd eax, dword ptr [rdi]")()
|
||||
TestInstr(ScasQ, expected_result="scasq rax, qword ptr [rdi]")()
|
||||
|
||||
TestInstr(CmpsB, expected_result="cmpsb byte ptr [rsi], byte ptr [rdi]")()
|
||||
TestInstr(CmpsW, expected_result="cmpsw word ptr [rsi], word ptr [rdi]")()
|
||||
TestInstr(CmpsD, expected_result="cmpsd dword ptr [rsi], dword ptr [rdi]")()
|
||||
TestInstr(CmpsQ, expected_result="cmpsq qword ptr [rsi], qword ptr [rdi]")()
|
||||
|
||||
|
||||
|
||||
TestInstr(Mov, must_fail=True)('RCX', 'ECX')
|
||||
TestInstr(Mov, must_fail=True)('RCX', mem('[ECX + RCX]'))
|
||||
|
||||
@@ -115,6 +115,8 @@ TestInstr(Add)(mem('[EAX]'), 10)
|
||||
TestInstr(Mov)('EAX', mem('fs:[0xfffc]'))
|
||||
TestInstr(Mov)(mem('fs:[0xfffc]'), 0)
|
||||
|
||||
TestInstr(Push)('ECX')
|
||||
TestInstr(Push)(mem('[ECX + 8]'))
|
||||
|
||||
TestInstr(Sub)('ECX', 'ESP')
|
||||
TestInstr(Sub)('ECX', mem('[ESP]'))
|
||||
@@ -140,6 +142,25 @@ TestInstr(Or)('EAX', 0x11223344)
|
||||
TestInstr(Or)('EAX', mem('[EAX + 1]'))
|
||||
TestInstr(Or)(mem('[EAX + EAX]'), 'EDX')
|
||||
|
||||
TestInstr(Not)('EAX')
|
||||
TestInstr(Not)(mem('[EAX]'))
|
||||
|
||||
TestInstr(ScasB, expected_result="scasb al, byte ptr es:[edi]")()
|
||||
TestInstr(ScasW, expected_result="scasw ax, word ptr es:[edi]")()
|
||||
TestInstr(ScasD, expected_result="scasd eax, dword ptr es:[edi]")()
|
||||
|
||||
TestInstr(CmpsB, expected_result="cmpsb byte ptr [esi], byte ptr es:[edi]")()
|
||||
TestInstr(CmpsW, expected_result="cmpsw word ptr [esi], word ptr es:[edi]")()
|
||||
TestInstr(CmpsD, expected_result="cmpsd dword ptr [esi], dword ptr es:[edi]")()
|
||||
|
||||
|
||||
TestInstr(Test)('EAX', 'EAX')
|
||||
TestInstr(Test, expected_result="test edi, ecx")('ECX', 'EDI')
|
||||
|
||||
TestInstr(Test)(mem('[ECX + 0x100]'), 'ECX')
|
||||
|
||||
assert Test(mem('[ECX + 0x100]'), 'ECX').get_code() == Test('ECX', mem('[ECX + 0x100]')).get_code()
|
||||
|
||||
|
||||
assert Xchg('EAX', 'ECX').get_code() == Xchg('ECX', 'EAX').get_code()
|
||||
|
||||
|
||||
@@ -1,208 +0,0 @@
|
||||
import windows
|
||||
import windows.winproxy
|
||||
import ctypes
|
||||
import socket
|
||||
import struct
|
||||
|
||||
from windows.generated_def.winstructs import *
|
||||
from windows.generated_def.windef import *
|
||||
|
||||
|
||||
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:
|
||||
return self.remote_port
|
||||
|
||||
@property
|
||||
def remote_host(self):
|
||||
"""Identification of the remote hostname.
|
||||
Equals ``remote_addr`` if the resolution fails
|
||||
|
||||
: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
|
||||
closing.dwLocalPort = self.dwLocalPort
|
||||
closing.dwRemoteAddr = self.dwRemoteAddr
|
||||
closing.dwRemotePort = self.dwRemotePort
|
||||
return windows.winproxy.SetTcpEntry(ctypes.byref(closing))
|
||||
|
||||
def __repr__(self):
|
||||
if not self.established:
|
||||
return "<TCP IPV4 Listening socket on {0}:{1}>".format(self.local_addr, self.local_port)
|
||||
return "<TCP IPV4 Connection {s.local_addr}:{s.local_port} -> {s.remote_addr}:{s.remote_port}>".format(s=self)
|
||||
|
||||
|
||||
class TCP6Connection(MIB_TCP6ROW_OWNER_PID):
|
||||
@staticmethod
|
||||
def _str_ipv6_addr(addr):
|
||||
return ":".join(c.encode('hex') for c in addr)
|
||||
|
||||
@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):
|
||||
raise NotImplementedError("Closing IPV6 connection non implemented")
|
||||
|
||||
def __repr__(self):
|
||||
if not self.established:
|
||||
return "<TCP IPV6 Listening socket on {0}:{1}>".format(self.local_addr, self.local_port)
|
||||
return "<TCP IPV6 Connection {0}:{1} -> {2}:{3}>".format(self.local_addr, self.local_port, self.remote_addr, self.remote_port)
|
||||
|
||||
|
||||
def get_MIB_TCPTABLE_OWNER_PID_from_buffer(buffer):
|
||||
x = windows.generated_def.winstructs.MIB_TCPTABLE_OWNER_PID.from_buffer(buffer)
|
||||
nb_entry = x.dwNumEntries
|
||||
|
||||
class _GENERATED_MIB_TCPTABLE_OWNER_PID(ctypes.Structure):
|
||||
_fields_ = [
|
||||
("dwNumEntries", DWORD),
|
||||
("table", TCP4Connection * nb_entry),
|
||||
]
|
||||
|
||||
return _GENERATED_MIB_TCPTABLE_OWNER_PID.from_buffer(buffer)
|
||||
|
||||
|
||||
def get_MIB_TCP6TABLE_OWNER_PID_from_buffer(buffer):
|
||||
x = windows.generated_def.winstructs.MIB_TCP6TABLE_OWNER_PID.from_buffer(buffer)
|
||||
nb_entry = x.dwNumEntries
|
||||
|
||||
# Struct _MIB_TCP6TABLE_OWNER_PID definitions
|
||||
class _GENERATED_MIB_TCP6TABLE_OWNER_PID(Structure):
|
||||
_fields_ = [
|
||||
("dwNumEntries", DWORD),
|
||||
("table", TCP6Connection * nb_entry),
|
||||
]
|
||||
|
||||
return _GENERATED_MIB_TCP6TABLE_OWNER_PID.from_buffer(buffer)
|
||||
|
||||
|
||||
|
||||
|
||||
class Network(object):
|
||||
@staticmethod
|
||||
def _get_tcp_ipv4_sockets():
|
||||
size = ctypes.c_uint(0)
|
||||
try:
|
||||
windows.winproxy.GetExtendedTcpTable(None, ctypes.byref(size), ulAf=AF_INET)
|
||||
except windows.winproxy.IphlpapiError:
|
||||
pass # Allow us to set size to the needed value
|
||||
buffer = (ctypes.c_char * size.value)()
|
||||
windows.winproxy.GetExtendedTcpTable(buffer, ctypes.byref(size), ulAf=AF_INET)
|
||||
t = get_MIB_TCPTABLE_OWNER_PID_from_buffer(buffer)
|
||||
return list(t.table)
|
||||
|
||||
@staticmethod
|
||||
def _get_tcp_ipv6_sockets():
|
||||
size = ctypes.c_uint(0)
|
||||
try:
|
||||
windows.winproxy.GetExtendedTcpTable(None, ctypes.byref(size), ulAf=AF_INET6)
|
||||
except windows.winproxy.IphlpapiError:
|
||||
pass # Allow us to set size to the needed value
|
||||
buffer = (ctypes.c_char * size.value)()
|
||||
windows.winproxy.GetExtendedTcpTable(buffer, ctypes.byref(size), ulAf=AF_INET6)
|
||||
t = get_MIB_TCP6TABLE_OWNER_PID_from_buffer(buffer)
|
||||
return list(t.table)
|
||||
|
||||
|
||||
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`]
|
||||
"""
|
||||
+75
-22
@@ -26,18 +26,21 @@ def transform_ctypes_fields(struct, replacement):
|
||||
return [(name, replacement.get(name, type)) for name, type in struct._fields_]
|
||||
|
||||
|
||||
def get_structure_transformer_for_target(target):
|
||||
def get_structure_transformer_for_target(target, targetbitness=None):
|
||||
current_bitness = windows.current_process.bitness
|
||||
if target is None:
|
||||
ctypes_structure_transformer = lambda x:x
|
||||
create_structure_at = lambda structcls, addr: structcls.from_address(addr)
|
||||
return ctypes_structure_transformer, create_structure_at
|
||||
|
||||
if target.bitness == 32 and current_bitness == 64:
|
||||
if targetbitness is None:
|
||||
targetbitness = target.bitness
|
||||
|
||||
if targetbitness == 32 and current_bitness == 64:
|
||||
ctypes_structure_transformer = rctypes.transform_type_to_remote32bits
|
||||
elif target.bitness == 64 and current_bitness == 32:
|
||||
elif targetbitness == 64 and current_bitness == 32:
|
||||
ctypes_structure_transformer = rctypes.transform_type_to_remote64bits
|
||||
elif target.bitness == current_bitness:
|
||||
elif targetbitness == current_bitness:
|
||||
ctypes_structure_transformer = rctypes.transform_type_to_remote
|
||||
else:
|
||||
raise NotImplementedError("Parsing {0} PE from {1} Process".format(targetedbitness, proc_bitness))
|
||||
@@ -46,8 +49,19 @@ def get_structure_transformer_for_target(target):
|
||||
return ctypes_structure_transformer(structcls)(addr, target)
|
||||
return ctypes_structure_transformer, create_structure_at
|
||||
|
||||
def get_pe_bitness(baseaddr, target):
|
||||
# We can force bitness as the filed we access are bitness-independant
|
||||
pe = GetPEFile(baseaddr, target, force_bitness=32)
|
||||
machine = pe.get_NT_HEADER().FileHeader.Machine
|
||||
if machine == 0x14c:
|
||||
return 32
|
||||
elif machine == 0x8664:
|
||||
return 64
|
||||
else:
|
||||
raise ValueError("Unknow PE target machine <0x{0:x}>".format(machine))
|
||||
|
||||
def GetPEFile(baseaddr, target=None):
|
||||
|
||||
def GetPEFile(baseaddr, target=None, force_bitness=None):
|
||||
"""Returns a :class:`PEFile` to explore a PE loaded at `baseaddr` in process `target`.
|
||||
|
||||
:rtype: :class:`PEFile`
|
||||
@@ -57,20 +71,25 @@ def GetPEFile(baseaddr, target=None):
|
||||
If target is ``None`` it refers to the curent process
|
||||
"""
|
||||
proc_bitness = windows.current_process.bitness
|
||||
if target is None:
|
||||
targetedbitness = proc_bitness
|
||||
|
||||
if force_bitness is None:
|
||||
targetedbitness = get_pe_bitness(baseaddr, target)
|
||||
else:
|
||||
targetedbitness = target.bitness
|
||||
targetedbitness = force_bitness
|
||||
|
||||
transformers = get_structure_transformer_for_target(target)
|
||||
transformers = get_structure_transformer_for_target(target, targetedbitness)
|
||||
ctypes_structure_transformer, create_structure_at = transformers
|
||||
|
||||
|
||||
if targetedbitness == 32:
|
||||
IMAGE_ORDINAL_FLAG = IMAGE_ORDINAL_FLAG32
|
||||
else:
|
||||
IMAGE_ORDINAL_FLAG = IMAGE_ORDINAL_FLAG64
|
||||
|
||||
def get_string(addr):
|
||||
if target is None:
|
||||
return ctypes.c_char_p(addr).value
|
||||
return target.read_string(addr)
|
||||
|
||||
class RVA(DWORD):
|
||||
@property
|
||||
def addr(self):
|
||||
@@ -83,11 +102,11 @@ def GetPEFile(baseaddr, target=None):
|
||||
if target is None:
|
||||
@property
|
||||
def str(self):
|
||||
return ctypes.c_char_p(self.addr).value.decode()
|
||||
return get_string(self.addr).decode()
|
||||
else:
|
||||
@property
|
||||
def str(self):
|
||||
return create_structure_at(ctypes.c_char_p, self.addr).value.decode()
|
||||
return get_string(self.addr).decode()
|
||||
|
||||
def __repr__(self):
|
||||
return "<DWORD {0} (String RVA to '{1}')>".format(self.value, self.str)
|
||||
@@ -164,6 +183,7 @@ def GetPEFile(baseaddr, target=None):
|
||||
"""Represent a PE loaded in a process (current or remote)"""
|
||||
def __init__(self):
|
||||
self.baseaddr = baseaddr
|
||||
self.bitness = targetedbitness
|
||||
|
||||
def get_DOS_HEADER(self):
|
||||
return create_structure_at(IMAGE_DOS_HEADER, baseaddr)
|
||||
@@ -175,7 +195,18 @@ def GetPEFile(baseaddr, target=None):
|
||||
return self.get_NT_HEADER().OptionalHeader
|
||||
|
||||
def get_DataDirectory(self):
|
||||
return self.get_OptionalHeader().DataDirectory
|
||||
# This won't work if we load a PE32 in a 64bit process
|
||||
# PE32 .NET...
|
||||
#return self.get_OptionalHeader().DataDirectory
|
||||
DataDirectory_type = IMAGE_DATA_DIRECTORY * IMAGE_NUMBEROF_DIRECTORY_ENTRIES
|
||||
SizeOfOptionalHeader = self.get_NT_HEADER().FileHeader.SizeOfOptionalHeader
|
||||
if target is None:
|
||||
opt_header_addr = ctypes.addressof(self.get_NT_HEADER().OptionalHeader)
|
||||
else:
|
||||
opt_header_addr = self.get_NT_HEADER().OptionalHeader._base_addr
|
||||
DataDirectory_addr = opt_header_addr + SizeOfOptionalHeader - ctypes.sizeof(DataDirectory_type)
|
||||
return create_structure_at(DataDirectory_type, DataDirectory_addr)
|
||||
|
||||
|
||||
def get_IMPORT_DESCRIPTORS(self):
|
||||
import_datadir = self.get_DataDirectory()[IMAGE_DIRECTORY_ENTRY_IMPORT]
|
||||
@@ -197,10 +228,23 @@ def GetPEFile(baseaddr, target=None):
|
||||
export_directory_addr = baseaddr + export_directory_rva
|
||||
return create_structure_at(self._IMAGE_EXPORT_DIRECTORY, export_directory_addr)
|
||||
|
||||
class PESection(ctypes_structure_transformer(IMAGE_SECTION_HEADER)):
|
||||
@utils.fixedpropety
|
||||
def name(self):
|
||||
return ctypes.c_char_p(ctypes.addressof(self.Name)).value
|
||||
class PESection((IMAGE_SECTION_HEADER)):
|
||||
if target is None:
|
||||
@property
|
||||
def name(self):
|
||||
return get_string(ctypes.addressof(self.Name))[:8]
|
||||
else:
|
||||
@property
|
||||
def name(self):
|
||||
return get_string(self._base_addr)[:8]
|
||||
|
||||
@property
|
||||
def start(self):
|
||||
return baseaddr + self.VirtualAddress
|
||||
|
||||
@property
|
||||
def size(self):
|
||||
return self.VirtualSize
|
||||
|
||||
def __repr__(self):
|
||||
return "<PESection \"{0}\">".format(self.name)
|
||||
@@ -209,8 +253,13 @@ def GetPEFile(baseaddr, target=None):
|
||||
def sections(self):
|
||||
nt_header = self.get_NT_HEADER()
|
||||
nb_section = nt_header.FileHeader.NumberOfSections
|
||||
base_section = ctypes.addressof(nt_header) + ctypes.sizeof(nt_header)
|
||||
sections_array = create_structure_at(self.PESection * nb_section, base_section)
|
||||
SizeOfOptionalHeader = self.get_NT_HEADER().FileHeader.SizeOfOptionalHeader
|
||||
if target is None:
|
||||
opt_header_addr = ctypes.addressof(self.get_NT_HEADER().OptionalHeader)
|
||||
else:
|
||||
opt_header_addr = self.get_NT_HEADER().OptionalHeader._base_addr
|
||||
base_section = opt_header_addr + SizeOfOptionalHeader
|
||||
sections_array = create_structure_at((self.PESection * nb_section), base_section)
|
||||
return list(sections_array)
|
||||
|
||||
@utils.fixedpropety
|
||||
@@ -230,6 +279,11 @@ def GetPEFile(baseaddr, target=None):
|
||||
res[rva_name.str] = rva_addr.addr
|
||||
return res
|
||||
|
||||
@utils.fixedpropety
|
||||
def export_name(self):
|
||||
"""The Name attribute of the ``EXPORT_DIRECTORY``"""
|
||||
return self.get_EXPORT_DIRECTORY().Name.str
|
||||
|
||||
# TODO: get imports by parsing other modules exports if no INT
|
||||
@utils.fixedpropety
|
||||
def imports(self):
|
||||
@@ -267,9 +321,9 @@ def GetPEFile(baseaddr, target=None):
|
||||
import_by_name = create_structure_at(IMPORT_BY_NAME, baseaddr + int_entry.AddressOfData)
|
||||
name_address = baseaddr + int_entry.AddressOfData + type(import_by_name).Name.offset
|
||||
if target is None:
|
||||
name = ctypes.c_char_p(name_address).value
|
||||
name = get_string(name_address)
|
||||
else:
|
||||
name = create_structure_at(ctypes.c_char_p, name_address).value.decode()
|
||||
name = get_string(name_address).decode()
|
||||
res.append((import_by_name.Hint, name))
|
||||
int_addr += ctypes.sizeof(type(int_entry))
|
||||
int_entry = create_structure_at(THUNK_DATA, int_addr)
|
||||
@@ -332,5 +386,4 @@ def GetPEFile(baseaddr, target=None):
|
||||
if targetedbitness == 32:
|
||||
return create_structure_at(IMAGE_NT_HEADERS32, baseaddr + self.e_lfanew)
|
||||
return create_structure_at(IMAGE_NT_HEADERS64, baseaddr + self.e_lfanew)
|
||||
|
||||
return current_pe
|
||||
@@ -1,82 +0,0 @@
|
||||
import struct
|
||||
import ctypes
|
||||
import functools
|
||||
from ctypes.wintypes import HRESULT
|
||||
from windows.generated_def.winstructs import *
|
||||
|
||||
# Simple Abstraction to call COM interface in Python (Python -> COM)
|
||||
IID_PACK = "<I", "<H", "<H", "<B", "<B", "<B", "<B", "<B", "<B", "<B", "<B"
|
||||
|
||||
|
||||
def get_IID_from_raw(raw):
|
||||
return "".join([struct.pack(i, j) for i, j in zip(IID_PACK, raw)])
|
||||
|
||||
|
||||
class COMInterface(ctypes.c_void_p):
|
||||
_functions_ = {
|
||||
"QueryInterface": ctypes.WINFUNCTYPE(HRESULT, ctypes.c_void_p, ctypes.c_void_p)(0, "QueryInterface"),
|
||||
"AddRef": ctypes.WINFUNCTYPE(HRESULT)(1, "AddRef"),
|
||||
"Release": ctypes.WINFUNCTYPE(HRESULT)(2, "Release")
|
||||
}
|
||||
|
||||
def __getattr__(self, name):
|
||||
if name in self._functions_:
|
||||
return functools.partial(self._functions_[name], self)
|
||||
return super(COMInterface, self).__getattribute__(name)
|
||||
|
||||
|
||||
# Simple Implem to create COM Interface in Python (COM -> Python)
|
||||
|
||||
def create_c_callable(func, types, keepalive=[]):
|
||||
func_type = ctypes.WINFUNCTYPE(*types)
|
||||
c_callable = func_type(func)
|
||||
# Dirty, but the other method require native code execution
|
||||
c_callback_addr = ctypes.c_ulong.from_address(id(c_callable._objects['0']) + 3 * ctypes.sizeof(ctypes.c_void_p)).value
|
||||
keepalive.append(c_callable)
|
||||
return c_callback_addr
|
||||
|
||||
|
||||
class ComVtable(object):
|
||||
# Name, types
|
||||
_funcs_ = [("QueryInterface", [ctypes.HRESULT, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p]),
|
||||
("AddRef", [ctypes.HRESULT, ctypes.c_void_p]),
|
||||
("Release", [ctypes.HRESULT, ctypes.c_void_p])
|
||||
]
|
||||
|
||||
def __init__(self, **implem_overwrite):
|
||||
self.implems = []
|
||||
self.vtable = self._create_vtable(**implem_overwrite)
|
||||
self.vtable_pointer = ctypes.pointer(self.vtable)
|
||||
self._as_parameter_ = ctypes.addressof(self.vtable_pointer)
|
||||
|
||||
def _create_vtable(self, **implem_overwrite):
|
||||
vtables_names = [x[0] for x in self._funcs_]
|
||||
non_expected_args = [func_name for func_name in implem_overwrite if func_name not in vtables_names]
|
||||
if non_expected_args:
|
||||
raise ValueError("Non expected function : {0}".format(non_expected_args))
|
||||
|
||||
for name, types in self._funcs_:
|
||||
func_implem = implem_overwrite.get(name)
|
||||
if func_implem is None:
|
||||
if hasattr(self, name):
|
||||
func_implem = getattr(self, name)
|
||||
else:
|
||||
raise ValueError("Missing implementation for function <{0}>".format(name))
|
||||
|
||||
if isinstance(func_implem, (int, long)):
|
||||
self.implems.append(func_implem)
|
||||
else:
|
||||
self.implems.append(create_c_callable(func_implem, types))
|
||||
|
||||
class Vtable(ctypes.Structure):
|
||||
_fields_ = [(name, ctypes.c_void_p) for name in vtables_names]
|
||||
return Vtable(*self.implems)
|
||||
|
||||
def QueryInterface(self, *args):
|
||||
return 1
|
||||
|
||||
def AddRef(self, *args):
|
||||
return 1
|
||||
|
||||
def Release(self, *args):
|
||||
return 0
|
||||
+51
-15
@@ -7,7 +7,9 @@ import functools
|
||||
import windows
|
||||
import windows.native_exec.simple_x64 as x64
|
||||
from generated_def.winstructs import *
|
||||
from windows.winproxy import NeededParameter, OptionalExport, NtdllProxy, error_ntstatus
|
||||
from windows.winobject import process
|
||||
from windows import winproxy
|
||||
from winproxy import NeededParameter, OptionalExport, NtdllProxy, error_ntstatus
|
||||
|
||||
# Special code for syswow64 process
|
||||
CS_32bits = 0x23
|
||||
@@ -148,9 +150,12 @@ def try_generate_stub_target(shellcode, argument_buffer, target):
|
||||
raise ValueError("{0} syswow accept {1} args ({2} given)".format(target.__name__, expected_arguments_number, len(args)))
|
||||
# Transform args (ctypes byref possibly) to int
|
||||
writable_args = []
|
||||
for value in args:
|
||||
for i, value in enumerate(args):
|
||||
if not isinstance(value, (int, long)):
|
||||
value = ctypes.cast(value, ctypes.c_void_p).value
|
||||
try:
|
||||
value = ctypes.cast(value, ctypes.c_void_p).value
|
||||
except ctypes.ArgumentError as e:
|
||||
raise ctypes.ArgumentError("Argument {0}: wrong type <{1}>".format(i, type(value).__name__))
|
||||
writable_args.append(value)
|
||||
|
||||
# Build buffer
|
||||
@@ -177,14 +182,25 @@ def get_current_process_syswow_peb_addr():
|
||||
def get_current_process_syswow_peb():
|
||||
current_process = windows.current_process
|
||||
|
||||
class CurrentProcessReadSyswow():
|
||||
class CurrentProcessReadSyswow(process.Process):
|
||||
bitness = 64
|
||||
def read_memory(self, addr, size):
|
||||
buffer_addr = ctypes.create_string_buffer(size)
|
||||
windows.winproxy.NtWow64ReadVirtualMemory64(current_process.handle, addr, buffer_addr, size)
|
||||
winproxy.NtWow64ReadVirtualMemory64(current_process.handle, addr, buffer_addr, size)
|
||||
return buffer_addr[:]
|
||||
bitness = 64
|
||||
peb_addr = get_current_process_syswow_peb_addr()
|
||||
return windows.winobject.RemotePEB64(peb_addr, CurrentProcessReadSyswow())
|
||||
return windows.winobject.process.RemotePEB64(peb_addr, CurrentProcessReadSyswow())
|
||||
|
||||
|
||||
class ReadSyswow64Process(object):
|
||||
def __init__(self, target):
|
||||
self.target = target
|
||||
self.bitness = target.bitness
|
||||
|
||||
def read_memory(self, addr, size):
|
||||
buffer_addr = ctypes.create_string_buffer(size)
|
||||
winproxy.NtWow64ReadVirtualMemory64(self.target.handle, addr, buffer_addr, size)
|
||||
return buffer_addr[:]
|
||||
|
||||
|
||||
def get_syswow_ntdll_exports():
|
||||
@@ -206,9 +222,13 @@ class Syswow64ApiProxy(object):
|
||||
def __init__(self, winproxy_function):
|
||||
self.winproxy_function = winproxy_function
|
||||
self.raw_call = None
|
||||
self.params_name = [param[1] for param in winproxy_function.params]
|
||||
if winproxy_function is not None:
|
||||
self.params_name = [param[1] for param in winproxy_function.params]
|
||||
|
||||
def __call__(self, python_proxy):
|
||||
# handle winproxy_function is None (OptionalExport)
|
||||
if self.winproxy_function is None:
|
||||
return None
|
||||
def perform_call(*args):
|
||||
if len(self.params_name) != len(args):
|
||||
print("ERROR:")
|
||||
@@ -226,7 +246,8 @@ class Syswow64ApiProxy(object):
|
||||
return python_proxy
|
||||
|
||||
|
||||
@Syswow64ApiProxy(windows.winproxy.NtCreateThreadEx)
|
||||
|
||||
@Syswow64ApiProxy(winproxy.NtCreateThreadEx)
|
||||
def NtCreateThreadEx_32_to_64(ThreadHandle=None, DesiredAccess=0x1fffff, ObjectAttributes=0, ProcessHandle=NeededParameter, lpStartAddress=NeededParameter, lpParameter=NeededParameter, CreateSuspended=0, dwStackSize=0, Unknown1=0, Unknown2=0, Unknown3=0):
|
||||
if ThreadHandle is None:
|
||||
ThreadHandle = byref(HANDLE())
|
||||
@@ -234,7 +255,7 @@ def NtCreateThreadEx_32_to_64(ThreadHandle=None, DesiredAccess=0x1fffff, ObjectA
|
||||
|
||||
|
||||
ProcessBasicInformation = 0
|
||||
@Syswow64ApiProxy(windows.winproxy.NtQueryInformationProcess)
|
||||
@Syswow64ApiProxy(winproxy.NtQueryInformationProcess)
|
||||
def NtQueryInformationProcess_32_to_64(ProcessHandle, ProcessInformationClass=ProcessBasicInformation, ProcessInformation=NeededParameter, ProcessInformationLength=0, ReturnLength=None):
|
||||
if ProcessInformation is not None and ProcessInformationLength == 0:
|
||||
ProcessInformationLength = ctypes.sizeof(ProcessInformation)
|
||||
@@ -245,7 +266,7 @@ def NtQueryInformationProcess_32_to_64(ProcessHandle, ProcessInformationClass=Pr
|
||||
return NtQueryInformationProcess_32_to_64.ctypes_function(ProcessHandle, ProcessInformationClass, ProcessInformation, ProcessInformationLength, ReturnLength)
|
||||
|
||||
|
||||
@Syswow64ApiProxy(windows.winproxy.NtQueryInformationThread)
|
||||
@Syswow64ApiProxy(winproxy.NtQueryInformationThread)
|
||||
def NtQueryInformationThread_32_to_64(ThreadHandle, ThreadInformationClass, ThreadInformation, ThreadInformationLength=0, ReturnLength=None):
|
||||
if ReturnLength is None:
|
||||
ReturnLength = byref(ULONG())
|
||||
@@ -255,21 +276,36 @@ def NtQueryInformationThread_32_to_64(ThreadHandle, ThreadInformationClass, Thre
|
||||
|
||||
|
||||
|
||||
@Syswow64ApiProxy(windows.winproxy.NtQueryVirtualMemory)
|
||||
@Syswow64ApiProxy(winproxy.NtQueryVirtualMemory)
|
||||
def NtQueryVirtualMemory_32_to_64(ProcessHandle, BaseAddress, MemoryInformationClass=MemoryBasicInformation, MemoryInformation=NeededParameter, MemoryInformationLength=0, ReturnLength=None):
|
||||
if ReturnLength is None:
|
||||
ReturnLength = byref(ULONG())
|
||||
if MemoryInformation is not None and MemoryInformationLength == 0:
|
||||
MemoryInformationLength = ctypes.sizeof(MemoryInformation)
|
||||
if type(MemoryInformation) == MEMORY_BASIC_INFORMATION64:
|
||||
if isinstance(MemoryInformation, ctypes.Structure):
|
||||
MemoryInformation = byref(MemoryInformation)
|
||||
return NtQueryVirtualMemory_32_to_64.ctypes_function(ProcessHandle, BaseAddress, MemoryInformationClass, MemoryInformation, MemoryInformationLength, ReturnLength)
|
||||
|
||||
|
||||
@Syswow64ApiProxy(windows.winproxy.NtGetContextThread)
|
||||
@Syswow64ApiProxy(winproxy.NtProtectVirtualMemory)
|
||||
def NtProtectVirtualMemory_32_to_64(ProcessHandle, BaseAddress, NumberOfBytesToProtect, NewAccessProtection, OldAccessProtection=None):
|
||||
if OldAccessProtection is None:
|
||||
XOldAccessProtection = DWORD()
|
||||
OldAccessProtection = ctypes.addressof(XOldAccessProtection)
|
||||
return NtProtectVirtualMemory_32_to_64.ctypes_function(ProcessHandle, BaseAddress, NumberOfBytesToProtect, NewAccessProtection, OldAccessProtection)
|
||||
|
||||
|
||||
|
||||
@Syswow64ApiProxy(winproxy.NtGetContextThread)
|
||||
def NtGetContextThread_32_to_64(hThread, lpContext):
|
||||
if type(lpContext) == windows.vectored_exception.EnhancedCONTEXT64:
|
||||
if type(lpContext) == windows.winobject.exception.ECONTEXT64:
|
||||
lpContext = byref(lpContext)
|
||||
return NtGetContextThread_32_to_64.ctypes_function(hThread, lpContext)
|
||||
|
||||
@Syswow64ApiProxy(winproxy.LdrLoadDll)
|
||||
def LdrLoadDll_32_to_64(PathToFile, Flags, ModuleFileName, ModuleHandle):
|
||||
return LdrLoadDll_32_to_64.ctypes_function(PathToFile, Flags, ModuleFileName, ModuleHandle)
|
||||
|
||||
@Syswow64ApiProxy(winproxy.NtSetContextThread)
|
||||
def NtSetContextThread_32_to_64(hThread, lpContext):
|
||||
return NtSetContextThread_32_to_64.ctypes_function(hThread, lpContext)
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
from mytest import WindowsTestCase, pop_calc_32, pop_calc_64, Calc32, Calc64
|
||||
from mytest import WindowsTestCase, WindowsAPITestCase, DebuggerTestCase, NativeUtilsTestCase, SystemTestCase, pop_calc_32, pop_calc_64, Calc32, Calc64
|
||||
|
||||
__all__ = ["WindowsTestCase"]
|
||||
__all__ = ["SystemTestCase", "WindowsTestCase", "WindowsAPITestCase", "DebuggerTestCase", "NativeUtilsTestCase"]
|
||||
|
||||
+666
-17
@@ -3,13 +3,21 @@ import struct
|
||||
import time
|
||||
import os
|
||||
import textwrap
|
||||
import random
|
||||
from contextlib import contextmanager
|
||||
|
||||
sys.path.append(".")
|
||||
import unittest
|
||||
import windows
|
||||
import windows.debug
|
||||
import windows.native_exec.simple_x86 as x86
|
||||
import windows.native_exec.simple_x64 as x64
|
||||
import windows.native_exec.nativeutils as nativeutils
|
||||
|
||||
from windows.generated_def.winstructs import *
|
||||
|
||||
from windows.native_exec.nativeutils import GetProcAddress64, GetProcAddress32
|
||||
|
||||
|
||||
is_process_32_bits = windows.current_process.bitness == 32
|
||||
is_process_64_bits = windows.current_process.bitness == 64
|
||||
@@ -25,44 +33,73 @@ process_64bit_only = unittest.skipIf(not is_process_64_bits, "Test for 64bits pr
|
||||
|
||||
|
||||
if is_windows_32_bits:
|
||||
def pop_calc_32():
|
||||
return windows.utils.create_process(r"C:\Windows\system32\calc.exe", True)
|
||||
def pop_calc_32(dwCreationFlags=0):
|
||||
return windows.utils.create_process(r"C:\Windows\system32\calc.exe", dwCreationFlags=dwCreationFlags, show_windows=True)
|
||||
|
||||
def pop_calc_64():
|
||||
def pop_calc_64(dwCreationFlags=0):
|
||||
raise WindowsError("Cannot create calc64 in 32bits system")
|
||||
else:
|
||||
def pop_calc_32():
|
||||
return windows.utils.create_process(r"C:\Windows\syswow64\calc.exe", True)
|
||||
def pop_calc_32(dwCreationFlags=0):
|
||||
return windows.utils.create_process(r"C:\Windows\syswow64\calc.exe", dwCreationFlags=dwCreationFlags, show_windows=True)
|
||||
|
||||
if is_process_32_bits:
|
||||
def pop_calc_64():
|
||||
def pop_calc_64(dwCreationFlags=0):
|
||||
with windows.utils.DisableWow64FsRedirection():
|
||||
return windows.utils.create_process(r"C:\Windows\system32\calc.exe", True)
|
||||
return windows.utils.create_process(r"C:\Windows\system32\calc.exe", dwCreationFlags=dwCreationFlags, show_windows=True)
|
||||
else:
|
||||
def pop_calc_64():
|
||||
return windows.utils.create_process(r"C:\Windows\system32\calc.exe", True)
|
||||
def pop_calc_64(dwCreationFlags=0):
|
||||
return windows.utils.create_process(r"C:\Windows\system32\calc.exe", dwCreationFlags=dwCreationFlags, show_windows=True)
|
||||
|
||||
|
||||
@contextmanager
|
||||
def Calc64():
|
||||
def Calc64(dwCreationFlags=0, exit_code=0):
|
||||
try:
|
||||
calc = pop_calc_64()
|
||||
calc = pop_calc_64(dwCreationFlags)
|
||||
yield calc
|
||||
finally:
|
||||
calc.exit()
|
||||
|
||||
if "calc" in locals():
|
||||
calc.exit(exit_code)
|
||||
|
||||
@contextmanager
|
||||
def Calc32():
|
||||
def Calc32(dwCreationFlags=0, exit_code=0):
|
||||
try:
|
||||
calc = pop_calc_32()
|
||||
calc = pop_calc_32(dwCreationFlags)
|
||||
yield calc
|
||||
finally:
|
||||
calc.exit()
|
||||
if "calc" in locals():
|
||||
calc.exit(exit_code)
|
||||
|
||||
class SystemTestCase(unittest.TestCase):
|
||||
def test_version(self):
|
||||
return windows.system.version
|
||||
|
||||
def test_version_name(self):
|
||||
return windows.system.version_name
|
||||
|
||||
def test_computer_name(self):
|
||||
return windows.system.computer_name
|
||||
|
||||
def test_services(self):
|
||||
return windows.system.services
|
||||
|
||||
def test_logicaldrives(self):
|
||||
return windows.system.logicaldrives
|
||||
|
||||
def test_processes(self):
|
||||
return windows.system.processes
|
||||
|
||||
def test_threads(self):
|
||||
return windows.system.threads
|
||||
|
||||
def test_wmi(self):
|
||||
return windows.system.wmi.select("Win32_Process", "*")
|
||||
|
||||
def test_processes(self):
|
||||
procs = windows.system.processes
|
||||
self.assertIn(windows.current_process.pid, [p.pid for p in procs])
|
||||
|
||||
|
||||
class WindowsTestCase(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
pass
|
||||
|
||||
@@ -97,6 +134,44 @@ class WindowsTestCase(unittest.TestCase):
|
||||
k32_base = windows.winproxy.LoadLibraryA("kernel32.dll")
|
||||
self.assertEqual(windows.winproxy.GetProcAddress(k32_base, "GetCurrentProcessId"), get_current_proc_id)
|
||||
|
||||
def test_local_process_pe_sections(self):
|
||||
mods = [m for m in windows.current_process.peb.modules if m.name == "kernel32.dll"]
|
||||
self.assertTrue(mods, 'Could not find "kernel32.dll" in current process modules')
|
||||
k32 = mods[0]
|
||||
sections = k32.pe.sections
|
||||
all_sections_name = [s.name for s in sections]
|
||||
self.assertIn(".text", all_sections_name)
|
||||
sections[0].start
|
||||
sections[0].size
|
||||
|
||||
# Read / write
|
||||
|
||||
def test_read_memory_32(self):
|
||||
with Calc32() as calc:
|
||||
k32 = [m for m in calc.peb.modules if m.name == "kernel32.dll"][0]
|
||||
self.assertEqual(calc.read_memory(k32.baseaddr, 2), "MZ")
|
||||
|
||||
@windows_64bit_only
|
||||
def test_read_memory_64(self):
|
||||
with Calc64() as calc:
|
||||
k32 = [m for m in calc.peb.modules if m.name == "kernel32.dll"][0]
|
||||
self.assertEqual(calc.read_memory(k32.baseaddr, 2), "MZ")
|
||||
|
||||
def test_write_memory_32(self):
|
||||
with Calc32() as calc:
|
||||
k32 = [m for m in calc.peb.modules if m.name == "kernel32.dll"][0]
|
||||
with calc.virtual_protected(k32.baseaddr, 2, PAGE_EXECUTE_READWRITE):
|
||||
calc.write_memory(k32.baseaddr, "XD")
|
||||
self.assertEqual(calc.read_memory(k32.baseaddr, 2), "XD")
|
||||
|
||||
@windows_64bit_only
|
||||
def test_write_memory_64(self):
|
||||
with Calc64() as calc:
|
||||
k32 = [m for m in calc.peb.modules if m.name == "kernel32.dll"][0]
|
||||
with calc.virtual_protected(k32.baseaddr, 2, PAGE_EXECUTE_READWRITE):
|
||||
calc.write_memory(k32.baseaddr, "XD")
|
||||
self.assertEqual(calc.read_memory(k32.baseaddr, 2), "XD")
|
||||
|
||||
# Native execution
|
||||
def test_execute_to_32(self):
|
||||
with Calc32() as calc:
|
||||
@@ -141,6 +216,32 @@ class WindowsTestCase(unittest.TestCase):
|
||||
dword = struct.unpack("<I", calc.read_memory(data, 4))[0]
|
||||
self.assertEqual(dword, 0x42424242)
|
||||
|
||||
def test_execute_python_to_32_suspended(self):
|
||||
with Calc32(dwCreationFlags=CREATE_SUSPENDED) as calc:
|
||||
data = calc.virtual_alloc(0x1000)
|
||||
calc.execute_python('import ctypes; ctypes.c_uint.from_address({0}).value = 0x42424242'.format(data))
|
||||
dword = struct.unpack("<I", calc.read_memory(data, 4))[0]
|
||||
self.assertEqual(dword, 0x42424242)
|
||||
# Check calc32 is still suspended:
|
||||
# 1 thread
|
||||
# suspend count == 1
|
||||
self.assertEqual(len(calc.threads), 1)
|
||||
self.assertEqual(calc.threads[0].suspend(), 1)
|
||||
|
||||
@windows_64bit_only
|
||||
def test_execute_python_to_64_suspended(self):
|
||||
with Calc64(dwCreationFlags=CREATE_SUSPENDED) as calc:
|
||||
data = calc.virtual_alloc(0x1000)
|
||||
calc.execute_python('import ctypes; ctypes.c_uint.from_address({0}).value = 0x42424242'.format(data))
|
||||
dword = struct.unpack("<I", calc.read_memory(data, 4))[0]
|
||||
self.assertEqual(dword, 0x42424242)
|
||||
# Check calc32 is still suspended:
|
||||
# 1 thread
|
||||
# suspend count == 1
|
||||
self.assertEqual(len(calc.threads), 1)
|
||||
self.assertEqual(calc.threads[0].suspend(), 1)
|
||||
|
||||
|
||||
def test_parse_remote_32_peb(self):
|
||||
with Calc32() as calc:
|
||||
# Wait for PEB initialization
|
||||
@@ -163,6 +264,8 @@ class WindowsTestCase(unittest.TestCase):
|
||||
mods = [m for m in calc.peb.modules if m.name == "kernel32.dll"]
|
||||
self.assertTrue(mods, 'Could not find "kernel32.dll" in calc32')
|
||||
k32 = mods[0]
|
||||
mods[0].pe.sections[0].name # Just see if it's parse
|
||||
self.assertEqual(mods[0].pe.export_name.lower(), "kernel32.dll")
|
||||
get_current_proc_id = k32.pe.exports['GetCurrentProcessId']
|
||||
# TODO: check get_current_proc_id value (but we cannot do 64->32 injection for now)
|
||||
#if is_process_64_bits:
|
||||
@@ -187,6 +290,8 @@ class WindowsTestCase(unittest.TestCase):
|
||||
mods = [m for m in calc.peb.modules if m.name == "kernel32.dll"]
|
||||
self.assertTrue(mods, 'Could not find "kernel32.dll" in calc32')
|
||||
k32 = mods[0]
|
||||
mods[0].pe.sections[0].name
|
||||
self.assertEqual(mods[0].pe.export_name.lower(), "kernel32.dll")
|
||||
get_current_proc_id = k32.pe.exports['GetCurrentProcessId']
|
||||
data = calc.virtual_alloc(0x1000)
|
||||
remote_python_code = """
|
||||
@@ -285,10 +390,554 @@ class WindowsTestCase(unittest.TestCase):
|
||||
cont = t.context
|
||||
self.assertEqual(cont.Rax, 0x4242424243434343)
|
||||
|
||||
def test_process_is_exit(self):
|
||||
with Calc32(exit_code=42) as calc:
|
||||
self.assertEqual(calc.is_exit, False)
|
||||
# out of context manager: process is exit
|
||||
self.assertEqual(calc.exit_code, 42)
|
||||
self.assertEqual(calc.is_exit, True)
|
||||
|
||||
def test_set_thread_context_32(self):
|
||||
code = x86.MultipleInstr()
|
||||
code += x86.Label(":LOOP")
|
||||
code += x86.Jmp(":LOOP")
|
||||
data_len = len(code.get_code())
|
||||
code += x86.Ret()
|
||||
|
||||
with Calc32() as calc:
|
||||
t = calc.execute(code.get_code())
|
||||
time.sleep(0.1)
|
||||
self.assertEqual(calc.is_exit, False)
|
||||
t.suspend()
|
||||
ctx = t.context
|
||||
ctx.Eip += data_len
|
||||
ctx.Eax = 0x11223344
|
||||
t.set_context(ctx)
|
||||
t.resume()
|
||||
time.sleep(0.1)
|
||||
self.assertEqual(t.exit_code, 0x11223344)
|
||||
|
||||
|
||||
@windows_64bit_only
|
||||
def test_set_thread_context_64(self):
|
||||
code = x64.MultipleInstr()
|
||||
code += x64.Label(":LOOP")
|
||||
code += x64.Jmp(":LOOP")
|
||||
data_len = len(code.get_code())
|
||||
code += x64.Ret()
|
||||
|
||||
with Calc64() as calc:
|
||||
t = calc.execute(code.get_code())
|
||||
time.sleep(0.1)
|
||||
self.assertEqual(calc.is_exit, False)
|
||||
t.suspend()
|
||||
ctx = t.context
|
||||
ctx.Rip += data_len
|
||||
ctx.Rax = 0x11223344
|
||||
t.set_context(ctx)
|
||||
t.resume()
|
||||
time.sleep(0.1)
|
||||
self.assertEqual(t.exit_code, 0x11223344)
|
||||
|
||||
def test_load_library_32(self):
|
||||
DLL = "wintrust.dll"
|
||||
with Calc32() as calc:
|
||||
calc.load_library(DLL)
|
||||
self.assertIn(DLL, [m.name for m in calc.peb.modules])
|
||||
|
||||
@windows_64bit_only
|
||||
def test_load_library_64(self):
|
||||
DLL = "wintrust.dll"
|
||||
with Calc64() as calc:
|
||||
calc.load_library(DLL)
|
||||
self.assertIn(DLL, [m.name for m in calc.peb.modules])
|
||||
|
||||
def test_token_info(self):
|
||||
token = windows.current_process.token
|
||||
self.assertIsInstance(token.computername, basestring)
|
||||
self.assertIsInstance(token.username, basestring)
|
||||
self.assertIsInstance(token.integrity, (int, long))
|
||||
self.assertIsInstance(token.is_elevated, (bool))
|
||||
|
||||
def test_get_working_set_32(self):
|
||||
with Calc32() as calc:
|
||||
k32 = [m for m in calc.peb.modules if m.name == "kernel32.dll"][0]
|
||||
api_addr = k32.pe.exports["CreateFileA"]
|
||||
data = calc.read_memory(api_addr, 5)
|
||||
page_target = api_addr >> 12
|
||||
for page_info in calc.query_working_set():
|
||||
if page_info.virtualpage == page_target:
|
||||
self.assertEqual(page_info.shared, True)
|
||||
break
|
||||
else:
|
||||
raise ValueError("query_working_set page info for <0x{0:x}> not found".format(page_target))
|
||||
data = calc.write_memory(api_addr, data)
|
||||
for page_info in calc.query_working_set():
|
||||
if page_info.virtualpage == page_target:
|
||||
self.assertEqual(page_info.shared, False)
|
||||
break
|
||||
else:
|
||||
raise ValueError("query_working_set page info for <0x{0:x}> not found".format(page_target))
|
||||
|
||||
@windows_64bit_only
|
||||
def test_get_working_set_64(self):
|
||||
with Calc64() as calc:
|
||||
k32 = [m for m in calc.peb.modules if m.name == "kernel32.dll"][0]
|
||||
api_addr = k32.pe.exports["CreateFileA"]
|
||||
data = calc.read_memory(api_addr, 5)
|
||||
page_target = api_addr >> 12
|
||||
for page_info in calc.query_working_set():
|
||||
if page_info.virtualpage == page_target:
|
||||
self.assertEqual(page_info.shared, True)
|
||||
break
|
||||
else:
|
||||
raise ValueError("query_working_set page info for <0x{0:x}> not found".format(page_target))
|
||||
with calc.virtual_protected(api_addr, 5, PAGE_EXECUTE_READWRITE):
|
||||
data = calc.write_memory(api_addr, data)
|
||||
for page_info in calc.query_working_set():
|
||||
if page_info.virtualpage == page_target:
|
||||
self.assertEqual(page_info.shared, False)
|
||||
break
|
||||
else:
|
||||
raise ValueError("query_working_set page info for <0x{0:x}> not found".format(page_target))
|
||||
|
||||
def test_get_working_setex_32(self):
|
||||
with Calc32() as calc:
|
||||
k32 = [m for m in calc.peb.modules if m.name == "kernel32.dll"][0]
|
||||
|
||||
text = [s for s in k32.pe.sections if s.name == ".text"][0]
|
||||
pages = [text.start + off for off in range(0, text.size, 0x1000)]
|
||||
|
||||
api_addr = k32.pe.exports["CreateFileA"]
|
||||
data = calc.read_memory(api_addr, 5)
|
||||
page_target = (api_addr >> 12) << 12
|
||||
|
||||
for page_info in calc.query_working_setex(pages):
|
||||
self.assertIn(page_info.VirtualAddress, pages)
|
||||
if page_info.VirtualAddress == page_target:
|
||||
self.assertEqual(page_info.VirtualAttributes.shared, True)
|
||||
break
|
||||
else:
|
||||
raise ValueError("query_working_set page info for <0x{0:x}> not found".format(page_target))
|
||||
with calc.virtual_protected(api_addr, 5, PAGE_EXECUTE_READWRITE):
|
||||
data = calc.write_memory(api_addr, data)
|
||||
for page_info in calc.query_working_setex(pages):
|
||||
self.assertIn(page_info.VirtualAddress, pages)
|
||||
if page_info.VirtualAddress == page_target:
|
||||
self.assertEqual(page_info.VirtualAttributes.shared, False)
|
||||
break
|
||||
else:
|
||||
raise ValueError("query_working_set page info for <0x{0:x}> not found".format(page_target))
|
||||
|
||||
@windows_64bit_only
|
||||
def test_get_working_setex_64(self):
|
||||
with Calc64() as calc:
|
||||
k32 = [m for m in calc.peb.modules if m.name == "kernel32.dll"][0]
|
||||
|
||||
text = [s for s in k32.pe.sections if s.name == ".text"][0]
|
||||
pages = [text.start + off for off in range(0, text.size, 0x1000)]
|
||||
|
||||
api_addr = k32.pe.exports["CreateFileA"]
|
||||
|
||||
data = calc.read_memory(api_addr, 5)
|
||||
page_target = (api_addr >> 12) << 12
|
||||
|
||||
for page_info in calc.query_working_setex(pages):
|
||||
self.assertIn(page_info.VirtualAddress, pages)
|
||||
if page_info.VirtualAddress == page_target:
|
||||
self.assertEqual(page_info.VirtualAttributes.shared, True)
|
||||
break
|
||||
else:
|
||||
raise ValueError("query_working_set page info for <0x{0:x}> not found".format(page_target))
|
||||
|
||||
with calc.virtual_protected(api_addr, 5, PAGE_EXECUTE_READWRITE):
|
||||
data = calc.write_memory(api_addr, data)
|
||||
for page_info in calc.query_working_setex(pages):
|
||||
self.assertIn(page_info.VirtualAddress, pages)
|
||||
if page_info.VirtualAddress == page_target:
|
||||
self.assertEqual(page_info.VirtualAttributes.shared, False)
|
||||
break
|
||||
else:
|
||||
raise ValueError("query_working_set page info for <0x{0:x}> not found".format(page_target))
|
||||
|
||||
def test_mapped_filename_32(self):
|
||||
with Calc32() as calc:
|
||||
k32 = [m for m in calc.peb.modules if m.name == "kernel32.dll"][0]
|
||||
mapped_filname = calc.get_mapped_filename(k32.baseaddr)
|
||||
self.assertTrue(mapped_filname.endswith("kernel32.dll"))
|
||||
|
||||
@windows_64bit_only
|
||||
def test_mapped_filename_64(self):
|
||||
with Calc64() as calc:
|
||||
k32 = [m for m in calc.peb.modules if m.name == "kernel32.dll"][0]
|
||||
mapped_filname = calc.get_mapped_filename(k32.baseaddr)
|
||||
self.assertTrue(mapped_filname.endswith("kernel32.dll"))
|
||||
|
||||
def test_thread_teb_base_32(self):
|
||||
with Calc32() as calc:
|
||||
t = calc.threads[0]
|
||||
self.assertNotEqual(t.teb_base, 0)
|
||||
|
||||
@windows_64bit_only
|
||||
def test_thread_teb_base_64(self):
|
||||
with Calc64() as calc:
|
||||
t = calc.threads[0]
|
||||
self.assertNotEqual(t.teb_base, 0)
|
||||
|
||||
class WindowsAPITestCase(unittest.TestCase):
|
||||
def test_createfileA_fail(self):
|
||||
with self.assertRaises(WindowsError) as ar:
|
||||
windows.winproxy.CreateFileA("NONEXISTFILE.FILE")
|
||||
|
||||
class NativeUtilsTestCase(unittest.TestCase):
|
||||
|
||||
@process_64bit_only
|
||||
def test_strlenw64(self):
|
||||
strlenw64 = windows.native_exec.create_function(nativeutils.StrlenW64.get_code(), [UINT, LPCWSTR])
|
||||
self.assertEqual(strlenw64("YOLO"), 4)
|
||||
self.assertEqual(strlenw64(""), 0)
|
||||
|
||||
@process_64bit_only
|
||||
def test_strlena64(self):
|
||||
strlena64 = windows.native_exec.create_function(nativeutils.StrlenA64.get_code(), [UINT, LPCSTR])
|
||||
self.assertEqual(strlena64("YOLO"), 4)
|
||||
self.assertEqual(strlena64(""), 0)
|
||||
|
||||
@process_64bit_only
|
||||
def test_getprocaddr64(self):
|
||||
getprocaddr64 = windows.native_exec.create_function(nativeutils.GetProcAddress64.get_code(), [ULONG64, LPCWSTR, LPCSTR])
|
||||
k32 = [mod for mod in windows.current_process.peb.modules if mod.name == "kernel32.dll"][0]
|
||||
exports = [(x,y) for x,y in k32.pe.exports.items() if isinstance(x, basestring)]
|
||||
|
||||
for name, addr in exports:
|
||||
name = name.encode()
|
||||
compute_addr = getprocaddr64("KERNEL32.DLL", name)
|
||||
# Put name in test to know which function caused the assert fails
|
||||
self.assertEqual((name, hex(addr)), (name, hex(compute_addr)))
|
||||
|
||||
self.assertEqual(getprocaddr64("YOLO.DLL", "whatever"), 0xfffffffffffffffe)
|
||||
self.assertEqual(getprocaddr64("KERNEL32.DLL", "YOLOAPI"), 0xffffffffffffffff)
|
||||
|
||||
@process_32bit_only
|
||||
def test_strlenw32(self):
|
||||
strlenw32 = windows.native_exec.create_function(nativeutils.StrlenW32.get_code(), [UINT, LPCWSTR])
|
||||
self.assertEqual(strlenw32("YOLO"), 4)
|
||||
self.assertEqual(strlenw32(""), 0)
|
||||
|
||||
@process_32bit_only
|
||||
def test_strlena32(self):
|
||||
strlena32 = windows.native_exec.create_function(nativeutils.StrlenA32.get_code(), [UINT, LPCSTR])
|
||||
self.assertEqual(strlena32("YOLO"), 4)
|
||||
self.assertEqual(strlena32(""), 0)
|
||||
|
||||
@process_32bit_only
|
||||
def test_getprocaddr32(self):
|
||||
getprocaddr32 = windows.native_exec.create_function(nativeutils.GetProcAddress32.get_code(), [UINT, LPCWSTR, LPCSTR])
|
||||
k32 = [mod for mod in windows.current_process.peb.modules if mod.name == "kernel32.dll"][0]
|
||||
exports = [(x,y) for x,y in k32.pe.exports.items() if isinstance(x, basestring)]
|
||||
|
||||
for name, addr in exports:
|
||||
name = name.encode()
|
||||
compute_addr = getprocaddr32("KERNEL32.DLL", name)
|
||||
# Put name in test to know which function caused the assert fails
|
||||
self.assertEqual((name, hex(addr)), (name, hex(compute_addr)))
|
||||
|
||||
|
||||
self.assertEqual(getprocaddr32("YOLO.DLL", "whatever"), 0xfffffffe)
|
||||
self.assertEqual(getprocaddr32("KERNEL32.DLL", "YOLOAPI"), 0xffffffff)
|
||||
|
||||
|
||||
class DebuggerTestCase(unittest.TestCase):
|
||||
|
||||
def debuggable_calc_32(self):
|
||||
return windows.utils.create_process(r"C:\python27\python.exe", dwCreationFlags=DEBUG_PROCESS | CREATE_NEW_CONSOLE, show_windows=True)
|
||||
|
||||
def test_init_breakpoint_callback(self):
|
||||
TEST_CASE = self
|
||||
class MyDbg(windows.debug.Debugger):
|
||||
def on_exception(self, exception):
|
||||
TEST_CASE.assertEqual(exception.ExceptionRecord.ExceptionCode, EXCEPTION_BREAKPOINT)
|
||||
self.current_process.exit()
|
||||
|
||||
calc = pop_calc_32(dwCreationFlags=DEBUG_PROCESS)
|
||||
d = MyDbg(calc, already_debuggable=True)
|
||||
d.loop()
|
||||
|
||||
def test_simple_standard_breakpoint(self):
|
||||
TEST_CASE = self
|
||||
|
||||
class TSTBP(windows.debug.Breakpoint):
|
||||
def trigger(self, dbg, exc):
|
||||
TEST_CASE.assertEqual(dbg.current_process.pid, calc.pid)
|
||||
TEST_CASE.assertEqual(dbg.current_process.read_memory(self.addr, 1), "\xcc")
|
||||
TEST_CASE.assertEqual(dbg.current_thread.context.pc - 1, self.addr)
|
||||
d.current_process.exit()
|
||||
|
||||
calc = pop_calc_32(dwCreationFlags=DEBUG_PROCESS)
|
||||
|
||||
if windows.current_process.bitness == 32:
|
||||
LdrLoadDll32 = windows.current_process.peb.modules[1].pe.exports["LdrLoadDll"]
|
||||
else:
|
||||
calcref = pop_calc_32()
|
||||
LdrLoadDll32 = calcref.peb.modules[1].pe.exports["LdrLoadDll"]
|
||||
calcref.exit()
|
||||
|
||||
d = windows.debug.Debugger(calc, already_debuggable=True)
|
||||
d.add_bp(TSTBP(LdrLoadDll32))
|
||||
d.loop()
|
||||
|
||||
def test_standard_breakpoint_multiple_threads(self):
|
||||
TEST_CASE = self
|
||||
data = [0]
|
||||
|
||||
class TSTBP(windows.debug.Breakpoint):
|
||||
def trigger(self, dbg, exc):
|
||||
TEST_CASE.assertEqual(dbg.current_process.pid, calc.pid)
|
||||
TEST_CASE.assertEqual(dbg.current_process.read_memory(self.addr, 1), "\xcc")
|
||||
TEST_CASE.assertEqual(dbg.current_thread.context.pc - 1, self.addr)
|
||||
data[0] += 1
|
||||
d.current_process.exit()
|
||||
|
||||
calc = pop_calc_32(dwCreationFlags=DEBUG_PROCESS)
|
||||
|
||||
if windows.current_process.bitness == 32:
|
||||
LdrLoadDll32 = windows.current_process.peb.modules[1].pe.exports["LdrLoadDll"]
|
||||
else:
|
||||
calcref = pop_calc_32()
|
||||
LdrLoadDll32 = calcref.peb.modules[1].pe.exports["LdrLoadDll"]
|
||||
calcref.exit()
|
||||
|
||||
d = windows.debug.Debugger(calc, already_debuggable=True)
|
||||
calc.execute("\xc3")
|
||||
calc.execute("\xc3")
|
||||
calc.execute("\xc3")
|
||||
d.add_bp(TSTBP(LdrLoadDll32))
|
||||
d.loop()
|
||||
|
||||
def test_simple_hwx_breakpoint(self):
|
||||
TEST_CASE = self
|
||||
|
||||
class TSTBP(windows.debug.HXBreakpoint):
|
||||
def trigger(self, dbg, exc):
|
||||
TEST_CASE.assertEqual(dbg.current_process.pid, calc.pid)
|
||||
TEST_CASE.assertEqual(dbg.current_thread.context.pc, self.addr)
|
||||
TEST_CASE.assertNotEqual(dbg.current_thread.context.Dr7, 0)
|
||||
d.current_process.exit()
|
||||
|
||||
calc = pop_calc_32(dwCreationFlags=DEBUG_PROCESS)
|
||||
|
||||
if windows.current_process.bitness == 32:
|
||||
LdrLoadDll32 = windows.current_process.peb.modules[1].pe.exports["LdrLoadDll"]
|
||||
else:
|
||||
calcref = pop_calc_32()
|
||||
LdrLoadDll32 = calcref.peb.modules[1].pe.exports["LdrLoadDll"]
|
||||
calcref.exit()
|
||||
|
||||
d = windows.debug.Debugger(calc, already_debuggable=True)
|
||||
d.add_bp(TSTBP(LdrLoadDll32))
|
||||
d.loop()
|
||||
|
||||
def test_multiple_hwx_breakpoint(self):
|
||||
TEST_CASE = self
|
||||
data = [0]
|
||||
class TSTBP(windows.debug.HXBreakpoint):
|
||||
def __init__(self, addr, expec_before):
|
||||
self.addr = addr
|
||||
self.expec_before = expec_before
|
||||
|
||||
def trigger(self, dbg, exc):
|
||||
TEST_CASE.assertEqual(dbg.current_process.pid, calc.pid)
|
||||
TEST_CASE.assertEqual(dbg.current_thread.context.pc, self.addr)
|
||||
TEST_CASE.assertNotEqual(dbg.current_thread.context.Dr7, 0)
|
||||
TEST_CASE.assertEqual(data[0], self.expec_before)
|
||||
TEST_CASE.assertNotEqual(dbg.current_process.read_memory(self.addr, 1), "\xcc")
|
||||
data[0] += 1
|
||||
if data[0] == 4:
|
||||
d.current_process.exit()
|
||||
|
||||
calc = pop_calc_32(dwCreationFlags=DEBUG_PROCESS)
|
||||
d = windows.debug.Debugger(calc, already_debuggable=True)
|
||||
addr = calc.virtual_alloc(0x1000)
|
||||
calc.write_memory(addr, "\x90" * 8)
|
||||
d.add_bp(TSTBP(addr, 0))
|
||||
d.add_bp(TSTBP(addr + 1, 1))
|
||||
d.add_bp(TSTBP(addr + 2, 2))
|
||||
d.add_bp(TSTBP(addr + 3, 3))
|
||||
|
||||
calc.create_thread(addr, 0)
|
||||
d.loop()
|
||||
# Used to verif we actually called the Breakpoints
|
||||
TEST_CASE.assertEqual(data[0], 4)
|
||||
|
||||
def test_four_hwx_breakpoint_fail(self):
|
||||
TEST_CASE = self
|
||||
data = [0]
|
||||
|
||||
class TSTBP(windows.debug.HXBreakpoint):
|
||||
def __init__(self, addr, expec_before):
|
||||
self.addr = addr
|
||||
self.expec_before = expec_before
|
||||
|
||||
def trigger(self, dbg, exc):
|
||||
raise NotImplementedError("Should fail before")
|
||||
|
||||
calc = pop_calc_32(dwCreationFlags=DEBUG_PROCESS)
|
||||
d = windows.debug.Debugger(calc, already_debuggable=True)
|
||||
addr = calc.virtual_alloc(0x1000)
|
||||
calc.write_memory(addr, "\x90" * 8 + "\xc3")
|
||||
d.add_bp(TSTBP(addr, 0))
|
||||
d.add_bp(TSTBP(addr + 1, 1))
|
||||
d.add_bp(TSTBP(addr + 2, 2))
|
||||
d.add_bp(TSTBP(addr + 3, 3))
|
||||
d.add_bp(TSTBP(addr + 4, 4))
|
||||
|
||||
calc.create_thread(addr, 0)
|
||||
with self.assertRaises(ValueError) as e:
|
||||
d.loop()
|
||||
self.assertIn("DRx", e.exception.message)
|
||||
# Used to verif we actually NOT called the Breakpoints
|
||||
TEST_CASE.assertEqual(data[0], 0)
|
||||
|
||||
def test_hwx_breakpoint_are_on_all_thread(self):
|
||||
TEST_CASE = self
|
||||
data = [0]
|
||||
|
||||
class MyDbg(windows.debug.Debugger):
|
||||
def on_create_thread(self, exception):
|
||||
# Check that later created thread have their HWX breakpoint :)
|
||||
TEST_CASE.assertNotEqual(self.current_thread.context.Dr7, 0)
|
||||
|
||||
class TSTBP(windows.debug.HXBreakpoint):
|
||||
def __init__(self, addr, expec_before):
|
||||
self.addr = addr
|
||||
self.expec_before = expec_before
|
||||
|
||||
def trigger(self, dbg, exc):
|
||||
TEST_CASE.assertNotEqual(len(dbg.current_process.threads), 1)
|
||||
#for t in dbg.current_process.threads:
|
||||
# TEST_CASE.assertNotEqual(t.context.Dr7, 0)
|
||||
if data[0] == 0: #First time we got it ! create new thread
|
||||
data[0] = 1
|
||||
calc.create_thread(addr, 0)
|
||||
else:
|
||||
d.current_process.exit()
|
||||
|
||||
calc = pop_calc_32(dwCreationFlags=DEBUG_PROCESS)
|
||||
d = MyDbg(calc, already_debuggable=True)
|
||||
addr = calc.virtual_alloc(0x1000)
|
||||
calc.write_memory(addr, "\x90" * 2 + "\xc3")
|
||||
d.add_bp(TSTBP(addr, 0))
|
||||
calc.create_thread(addr, 0)
|
||||
d.loop()
|
||||
# Used to verif we actually called the Breakpoints
|
||||
TEST_CASE.assertEqual(data[0], 1)
|
||||
|
||||
def test_simple_breakpoint_name_addr(self):
|
||||
TEST_CASE = self
|
||||
data = [0]
|
||||
class TSTBP(windows.debug.Breakpoint):
|
||||
def trigger(self, dbg, exc):
|
||||
addr = exc.ExceptionRecord.ExceptionAddress
|
||||
TEST_CASE.assertEqual(dbg.current_process.pid, calc.pid)
|
||||
TEST_CASE.assertEqual(dbg.current_process.read_memory(addr, 1), "\xcc")
|
||||
TEST_CASE.assertEqual(dbg.current_thread.context.pc - 1, addr)
|
||||
data[0] += 1
|
||||
d.current_process.exit()
|
||||
|
||||
calc = pop_calc_32(dwCreationFlags=DEBUG_PROCESS)
|
||||
|
||||
d = windows.debug.Debugger(calc, already_debuggable=True)
|
||||
d.add_bp(TSTBP("ntdll.dll!LdrLoadDll"))
|
||||
d.loop()
|
||||
TEST_CASE.assertEqual(data[0], 1)
|
||||
|
||||
def test_simple_hardware_breakpoint_name_addr(self):
|
||||
TEST_CASE = self
|
||||
data = [0]
|
||||
class TSTBP(windows.debug.HXBreakpoint):
|
||||
def trigger(self, dbg, exc):
|
||||
addr = exc.ExceptionRecord.ExceptionAddress
|
||||
TEST_CASE.assertEqual(dbg.current_process.pid, calc.pid)
|
||||
TEST_CASE.assertEqual(dbg.current_thread.context.pc, dbg._resolve(self.addr, dbg.current_process))
|
||||
TEST_CASE.assertNotEqual(dbg.current_thread.context.Dr7, 0)
|
||||
TEST_CASE.assertNotEqual(dbg.current_process.read_memory(addr, 1), "\xcc")
|
||||
data[0] += 1
|
||||
d.current_process.exit()
|
||||
|
||||
calc = pop_calc_32(dwCreationFlags=DEBUG_PROCESS)
|
||||
d = windows.debug.Debugger(calc, already_debuggable=True)
|
||||
d.add_bp(TSTBP("ntdll.dll!LdrLoadDll"))
|
||||
d.loop()
|
||||
TEST_CASE.assertEqual(data[0], 1)
|
||||
|
||||
def perform_manual_getproc_loadlib_32_yolo(self, target, dll_name):
|
||||
dll = "KERNEL32.DLL\x00".encode("utf-16-le")
|
||||
api = "LoadLibraryA\x00"
|
||||
dll_to_load = dll_name + "\x00"
|
||||
|
||||
RemoteManualLoadLibray = x86.MultipleInstr()
|
||||
code = RemoteManualLoadLibray
|
||||
code += x86.Mov("ECX", x86.mem("[ESP + 4]"))
|
||||
code += x86.Push(x86.mem("[ECX + 4]"))
|
||||
code += x86.Push(x86.mem("[ECX]"))
|
||||
code += x86.Call(":FUNC_GETPROCADDRESS32")
|
||||
code += x86.Push(x86.mem("[ECX + 8]"))
|
||||
code += x86.Call("EAX") # LoadLibrary
|
||||
code += x86.Pop("ECX")
|
||||
code += x86.Pop("ECX")
|
||||
code += x86.Ret()
|
||||
RemoteManualLoadLibray += GetProcAddress32
|
||||
|
||||
addr = target.virtual_alloc(0x1000)
|
||||
addr2 = addr + len(dll)
|
||||
addr3 = addr2 + len(api)
|
||||
addr4 = addr3 + len(dll_to_load)
|
||||
target.write_memory(addr, dll)
|
||||
target.write_memory(addr2, api)
|
||||
target.write_memory(addr3, dll_to_load)
|
||||
target.write_qword(addr4, addr)
|
||||
target.write_qword(addr4 + 4, addr2)
|
||||
target.write_qword(addr4 + 0x8, addr3)
|
||||
t = target.execute(RemoteManualLoadLibray.get_code(), addr4)
|
||||
return t
|
||||
|
||||
|
||||
def test_hardware_breakpoint_name_addr(self):
|
||||
TEST_CASE = self
|
||||
data = [0]
|
||||
class TSTBP(windows.debug.HXBreakpoint):
|
||||
def trigger(self, dbg, exc):
|
||||
addr = exc.ExceptionRecord.ExceptionAddress
|
||||
TEST_CASE.assertEqual(dbg.current_process.pid, calc.pid)
|
||||
TEST_CASE.assertEqual(dbg.current_thread.context.pc, dbg._resolve(self.addr, dbg.current_process))
|
||||
TEST_CASE.assertNotEqual(dbg.current_thread.context.Dr7, 0)
|
||||
TEST_CASE.assertNotEqual(dbg.current_process.read_memory(addr, 1), "\xcc")
|
||||
data[0] += 1
|
||||
if data[0] == 1:
|
||||
# Perform a loaddll in a new thread :)
|
||||
# See if it's trigger a bp
|
||||
t = TEST_CASE.perform_manual_getproc_loadlib_32_yolo(dbg.current_process, "wintrust.dll")
|
||||
self.new_thread = t
|
||||
if hasattr(self, "new_thread") and dbg.current_thread.tid == self.new_thread.tid:
|
||||
for t in dbg.current_process.threads:
|
||||
TEST_CASE.assertNotEqual(t.context.Dr7, 0)
|
||||
d.current_process.exit()
|
||||
|
||||
calc = pop_calc_32(dwCreationFlags=DEBUG_PROCESS)
|
||||
d = windows.debug.Debugger(calc, already_debuggable=True)
|
||||
d.add_bp(TSTBP("ntdll.dll!LdrLoadDll"))
|
||||
# Code that will load wintrust !
|
||||
d.loop()
|
||||
#TEST_CASE.assertEqual(data[0], 1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
alltests = unittest.TestSuite()
|
||||
alltests.addTest(unittest.makeSuite(SystemTestCase))
|
||||
alltests.addTest(unittest.makeSuite(WindowsTestCase))
|
||||
alltests.addTest(unittest.makeSuite(WindowsAPITestCase))
|
||||
alltests.addTest(unittest.makeSuite(DebuggerTestCase))
|
||||
alltests.addTest(unittest.makeSuite(NativeUtilsTestCase))
|
||||
alltests.debug()
|
||||
tester = unittest.TextTestRunner(verbosity=2)
|
||||
tester.run(alltests)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
"""utils fonctions non windows-related"""
|
||||
import ctypes
|
||||
import _ctypes
|
||||
|
||||
|
||||
def fixedpropety(f):
|
||||
@@ -18,3 +19,36 @@ def swallow_ctypes_copy(ctypes_object):
|
||||
new_copy = type(ctypes_object)()
|
||||
ctypes.memmove(ctypes.byref(new_copy), ctypes.byref(ctypes_object), ctypes.sizeof(new_copy))
|
||||
return new_copy
|
||||
|
||||
|
||||
# type replacement based on name
|
||||
def transform_ctypes_fields(struct, replacement):
|
||||
return [(name, replacement.get(name, type)) for name, type in struct._fields_]
|
||||
|
||||
|
||||
def print_ctypes_struct(struct, name="", ident=0, hexa=False):
|
||||
if isinstance(struct, _ctypes._Pointer):
|
||||
if ctypes.cast(struct, ctypes.c_void_p).value is None:
|
||||
print("{0} -> NULL".format(name))
|
||||
return
|
||||
return print_ctypes_struct(struct[0], name + "<deref>", hexa=hexa)
|
||||
|
||||
if not hasattr(struct, "_fields_"):
|
||||
value = struct
|
||||
if hasattr(struct, "value"):
|
||||
value = struct.value
|
||||
|
||||
if isinstance(value, basestring):
|
||||
value = repr(value)
|
||||
if hexa:
|
||||
try:
|
||||
print("{0} -> {1}".format(name, hex(value)))
|
||||
return
|
||||
except TypeError:
|
||||
pass
|
||||
print("{0} -> {1}".format(name, value))
|
||||
return
|
||||
|
||||
for fname, ftype in struct._fields_:
|
||||
value = getattr(struct, fname)
|
||||
print_ctypes_struct(value, "{0}.{1}".format(name, fname), hexa=hexa)
|
||||
@@ -3,6 +3,7 @@ import msvcrt
|
||||
import os
|
||||
import sys
|
||||
import code
|
||||
import datetime
|
||||
|
||||
import windows
|
||||
from .. import winproxy
|
||||
@@ -70,7 +71,7 @@ def create_console():
|
||||
sys.stderr = console_stderr
|
||||
|
||||
|
||||
def create_process(path, show_windows=False):
|
||||
def create_process(path, args=None, dwCreationFlags=0, show_windows=False):
|
||||
"""A convenient wrapper arround :func:`windows.winproxy.CreateProcessA`"""
|
||||
proc_info = PROCESS_INFORMATION()
|
||||
lpStartupInfo = None
|
||||
@@ -79,9 +80,11 @@ def create_process(path, show_windows=False):
|
||||
StartupInfo.cb = ctypes.sizeof(StartupInfo)
|
||||
StartupInfo.dwFlags = 0
|
||||
lpStartupInfo = ctypes.byref(StartupInfo)
|
||||
windows.winproxy.CreateProcessA(path, lpProcessInformation=ctypes.byref(proc_info), lpStartupInfo=lpStartupInfo)
|
||||
proc = [p for p in windows.system.processes if p.pid == proc_info.dwProcessId][0]
|
||||
return proc
|
||||
lpCommandLine = None
|
||||
if args:
|
||||
lpCommandLine = (" ".join([str(a) for a in args]))
|
||||
windows.winproxy.CreateProcessA(path, lpCommandLine=lpCommandLine, dwCreationFlags=dwCreationFlags, lpProcessInformation=ctypes.byref(proc_info), lpStartupInfo=lpStartupInfo)
|
||||
return windows.winobject.process.WinProcess(pid=proc_info.dwProcessId, handle=proc_info.hProcess)
|
||||
|
||||
|
||||
def enable_privilege(lpszPrivilege, bEnablePrivilege):
|
||||
@@ -146,6 +149,15 @@ def check_debug():
|
||||
return True
|
||||
|
||||
|
||||
def datetime_from_filetime(filetime):
|
||||
"""return a :class:`datetime.datetime` from a ``windows`` FILETIME int"""
|
||||
return datetime.datetime(1601,1,1) + datetime.timedelta(microseconds=filetime / 10)
|
||||
|
||||
def filetime_from_datetime(dtime):
|
||||
"""Return the FILETIME value from a :class:`datetime.datetime` in a python :class:`int`"""
|
||||
return int((dtime - datetime.datetime(1601,1,1)).total_seconds() * 1000) * 10000
|
||||
|
||||
|
||||
class FixedInteractiveConsole(code.InteractiveConsole):
|
||||
def raw_input(self, prompt=">>>"):
|
||||
sys.stdout.write(prompt)
|
||||
@@ -169,6 +181,17 @@ def get_kernel_modules():
|
||||
return list(modules)
|
||||
|
||||
|
||||
# String stuff
|
||||
def ntstatus(code):
|
||||
return windows.generated_def.ntstatus.NtStatusException(code)
|
||||
|
||||
|
||||
def get_shared_mapping(name, size=0x1000):
|
||||
# TODO: real cod
|
||||
h = windows.winproxy.CreateFileMappingA(INVALID_HANDLE_VALUE, dwMaximumSizeLow=size, lpName=name)
|
||||
addr = windows.winproxy.MapViewOfFile(h, dwNumberOfBytesToMap=size)
|
||||
return addr
|
||||
|
||||
class VirtualProtected(object):
|
||||
"""
|
||||
A context manager usable like `VirtualProtect` that will restore the old protection at exit ::
|
||||
|
||||
@@ -1,257 +0,0 @@
|
||||
import ctypes
|
||||
import windows
|
||||
from windows.generated_def.winstructs import *
|
||||
import windows.generated_def.windef as windef
|
||||
|
||||
EXCEPTION_CONTINUE_SEARCH = (0x0)
|
||||
EXCEPTION_CONTINUE_EXECUTION = (0xffffffff)
|
||||
|
||||
exception_type = [
|
||||
"EXCEPTION_ACCESS_VIOLATION",
|
||||
"EXCEPTION_DATATYPE_MISALIGNMENT",
|
||||
"EXCEPTION_BREAKPOINT",
|
||||
"EXCEPTION_SINGLE_STEP",
|
||||
"EXCEPTION_ARRAY_BOUNDS_EXCEEDED",
|
||||
"EXCEPTION_FLT_DENORMAL_OPERAND",
|
||||
"EXCEPTION_FLT_DIVIDE_BY_ZERO",
|
||||
"EXCEPTION_FLT_INEXACT_RESULT",
|
||||
"EXCEPTION_FLT_INVALID_OPERATION",
|
||||
"EXCEPTION_FLT_OVERFLOW",
|
||||
"EXCEPTION_FLT_STACK_CHECK",
|
||||
"EXCEPTION_FLT_UNDERFLOW",
|
||||
"EXCEPTION_INT_DIVIDE_BY_ZERO",
|
||||
"EXCEPTION_INT_OVERFLOW",
|
||||
"EXCEPTION_PRIV_INSTRUCTION",
|
||||
"EXCEPTION_IN_PAGE_ERROR",
|
||||
"EXCEPTION_ILLEGAL_INSTRUCTION",
|
||||
"EXCEPTION_NONCONTINUABLE_EXCEPTION",
|
||||
"EXCEPTION_STACK_OVERFLOW",
|
||||
"EXCEPTION_INVALID_DISPOSITION",
|
||||
"EXCEPTION_GUARD_PAGE",
|
||||
"EXCEPTION_INVALID_HANDLE",
|
||||
"EXCEPTION_POSSIBLE_DEADLOCK",
|
||||
]
|
||||
|
||||
# x -> x dict may seems strange but useful to get the Flags (with name) from the int
|
||||
# exception_name_by_value[0x80000001] -> EXCEPTION_GUARD_PAGE(0x80000001L)
|
||||
exception_name_by_value = dict([(x, x) for x in [getattr(windows.generated_def.windef, name) for name in exception_type]])
|
||||
|
||||
def generate_enhanced_exception_record(base, name_suffix=""):
|
||||
class EnhancedEXCEPTION_RECORD(base):
|
||||
@property
|
||||
def ExceptionCode(self):
|
||||
real_code = super(EnhancedEXCEPTION_RECORD, self).ExceptionCode
|
||||
return exception_name_by_value.get(real_code, 'UNKNOW_EXCEPTION({0})'.format(hex(real_code)))
|
||||
|
||||
@property
|
||||
def ExceptionAddress(self):
|
||||
x = super(EnhancedEXCEPTION_RECORD, self).ExceptionAddress
|
||||
if x is None:
|
||||
return 0x0
|
||||
return x
|
||||
EnhancedEXCEPTION_RECORD.__name__ += name_suffix
|
||||
return EnhancedEXCEPTION_RECORD
|
||||
|
||||
EnhancedEXCEPTION_RECORD = generate_enhanced_exception_record(EXCEPTION_RECORD)
|
||||
EnhancedEXCEPTION_RECORD32 = generate_enhanced_exception_record(EXCEPTION_RECORD32, "32")
|
||||
EnhancedEXCEPTION_RECORD64 = generate_enhanced_exception_record(EXCEPTION_RECORD64, "64")
|
||||
|
||||
|
||||
#class EnhancedEXCEPTION_RECORD(EXCEPTION_RECORD):
|
||||
# @property
|
||||
# def ExceptionCode(self):
|
||||
# real_code = super(EnhancedEXCEPTION_RECORD, self).ExceptionCode
|
||||
# return exception_name_by_value.get(real_code, 'UNKNOW_EXCEPTION({0})'.format(hex(real_code)))
|
||||
#
|
||||
# @property
|
||||
# def ExceptionAddress(self):
|
||||
# x = super(EnhancedEXCEPTION_RECORD, self).ExceptionAddress
|
||||
# if x is None:
|
||||
# return 0x0
|
||||
# return x
|
||||
|
||||
|
||||
class Eflags(int):
|
||||
_flags_ = [("CF", 1),
|
||||
("RES_1", 1),
|
||||
("PF", 1),
|
||||
("RES_3", 1),
|
||||
("AF", 1),
|
||||
("RES_5", 1),
|
||||
("ZF", 1),
|
||||
("SF", 1),
|
||||
("TF", 1),
|
||||
("IF", 1),
|
||||
("DF", 1),
|
||||
("OF", 1),
|
||||
("IOPL_1", 1),
|
||||
("IOPL_2", 1),
|
||||
("NT", 1),
|
||||
("RES_15", 1),
|
||||
("RF", 1),
|
||||
("VM", 1),
|
||||
("AC", 1),
|
||||
("VIF", 1),
|
||||
("VIP", 1),
|
||||
("ID", 1),
|
||||
]
|
||||
|
||||
_flag_mask_ = dict([(name, 1 << i) for i, (name, size) in enumerate(_flags_)])
|
||||
|
||||
def __getattr__(self, name):
|
||||
if name in self._flag_mask_:
|
||||
return bool(self & self._flag_mask_[name])
|
||||
return super(Eflags, self).__getattr_(name)
|
||||
|
||||
def dump(self):
|
||||
res = []
|
||||
for name in self._flag_mask_:
|
||||
if name.startswith("RES_"):
|
||||
continue
|
||||
if getattr(self, name):
|
||||
res.append(name)
|
||||
return "|".join(res)
|
||||
|
||||
def __repr__(self):
|
||||
return "{0}({1})".format(type(self).__name__, self.dump())
|
||||
|
||||
__str__ = __repr__
|
||||
|
||||
def __hex__(self):
|
||||
return "{0}({1}:{2})".format(type(self).__name__, int.__hex__(self), self.dump())
|
||||
|
||||
|
||||
class EnhancedCONTEXTBase():
|
||||
default_dump = ()
|
||||
pc_reg = ''
|
||||
special_reg_type = {}
|
||||
|
||||
def regs(self, to_dump=None):
|
||||
res = []
|
||||
if to_dump is None:
|
||||
to_dump = self.default_dump
|
||||
for name in to_dump:
|
||||
value = getattr(self, name)
|
||||
if name in self.special_reg_type:
|
||||
value = self.special_reg_type[name](value)
|
||||
res.append((name, value))
|
||||
return res
|
||||
|
||||
def dump(self, to_dump=None):
|
||||
regs = self.regs()
|
||||
for name, value in regs:
|
||||
print("{0} -> {1}".format(name, hex(value)))
|
||||
return None
|
||||
|
||||
def get_pc(self):
|
||||
return getattr(self, self.pc_reg)
|
||||
|
||||
def set_pc(self, value):
|
||||
return setattr(self, self.pc_reg, value)
|
||||
|
||||
pc = property(get_pc, set_pc, None, "Program Counter register (EIP or RIP)")
|
||||
|
||||
|
||||
class EnhancedCONTEXT32(EnhancedCONTEXTBase, CONTEXT32):
|
||||
default_dump = ('Eip', 'Esp', 'Eax', 'Ebx', 'Ecx', 'Edx', 'Ebp', 'Edi', 'Esi', 'EFlags')
|
||||
pc_reg = 'Eip'
|
||||
special_reg_type = {'EFlags': Eflags}
|
||||
|
||||
class EnhancedCONTEXTWOW64(EnhancedCONTEXTBase, WOW64_CONTEXT):
|
||||
default_dump = ('Eip', 'Esp', 'Eax', 'Ebx', 'Ecx', 'Edx', 'Ebp', 'Edi', 'Esi', 'EFlags')
|
||||
pc_reg = 'Eip'
|
||||
special_reg_type = {'EFlags': Eflags}
|
||||
|
||||
|
||||
class EnhancedCONTEXT64(EnhancedCONTEXTBase, CONTEXT64):
|
||||
default_dump = ('Rip', 'Rsp', 'Rax', 'Rbx', 'Rcx', 'Rdx', 'Rbp', 'Rdi', 'Rsi',
|
||||
'R9', 'R10', 'R11', 'R12', 'R13', 'R14', 'R15', 'EFlags')
|
||||
pc_reg = 'Rip'
|
||||
special_reg_type = {'EFlags': Eflags}
|
||||
|
||||
@classmethod
|
||||
def new_aligned(cls):
|
||||
"""Return a new EnhancedCONTEXT64 aligned on 16 bits
|
||||
temporary workaround or horrible hack ? choose your side
|
||||
"""
|
||||
size = ctypes.sizeof(cls)
|
||||
nb_qword = (size + 8) / ctypes.sizeof(ULONGLONG)
|
||||
buffer = (nb_qword * ULONGLONG)()
|
||||
struct_address = ctypes.addressof(buffer)
|
||||
if (struct_address & 0xf) not in [0, 8]:
|
||||
raise ValueError("ULONGLONG array not aligned on 8")
|
||||
if (struct_address & 0xf) == 8:
|
||||
struct_address += 8
|
||||
self = cls.from_address(struct_address)
|
||||
# Keep the raw buffer alive
|
||||
self._buffer = buffer
|
||||
return self
|
||||
|
||||
def bitness():
|
||||
"""Return 32 or 64"""
|
||||
import platform
|
||||
bits = platform.architecture()[0]
|
||||
return int(bits[:2])
|
||||
|
||||
if bitness() == 32:
|
||||
EnhancedCONTEXT = EnhancedCONTEXT32
|
||||
else:
|
||||
EnhancedCONTEXT = EnhancedCONTEXT64
|
||||
|
||||
|
||||
class EnhancedEXCEPTION_POINTERS(ctypes.Structure):
|
||||
_fields_ = [
|
||||
("ExceptionRecord", ctypes.POINTER(EnhancedEXCEPTION_RECORD)),
|
||||
("ContextRecord", ctypes.POINTER(EnhancedCONTEXT)),
|
||||
]
|
||||
|
||||
def dump(self):
|
||||
record = self.ExceptionRecord[0]
|
||||
print("Dumping Exception: ")
|
||||
print(" ExceptionCode = {0} at {1}".format(record.ExceptionCode, hex(record.ExceptionAddress)))
|
||||
regs = self.ContextRecord[0].regs()
|
||||
for name, value in regs:
|
||||
print(" {0} -> {1}".format(name, hex(value)))
|
||||
|
||||
|
||||
class VectoredException(object):
|
||||
func_type = ctypes.WINFUNCTYPE(ctypes.c_uint, ctypes.POINTER(EnhancedEXCEPTION_POINTERS))
|
||||
|
||||
def __new__(cls, func):
|
||||
self = object.__new__(cls)
|
||||
self.func = func
|
||||
return self.func_type(self.decorator)
|
||||
|
||||
def decorator(self, exception_pointers):
|
||||
try:
|
||||
return self.func(exception_pointers)
|
||||
except BaseException as e:
|
||||
print("Ignored Python Exception in Vectored Exception: {0}".format(e))
|
||||
return windef.EXCEPTION_CONTINUE_SEARCH
|
||||
|
||||
|
||||
class WithExceptionHandler(object):
|
||||
def __init__(self, handler):
|
||||
self.handler = VectoredException(handler)
|
||||
|
||||
def __enter__(self):
|
||||
self.value = windows.winproxy.AddVectoredExceptionHandler(0, self.handler)
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type, exc_value, traceback):
|
||||
windows.winproxy.RemoveVectoredExceptionHandler(self.value)
|
||||
return False
|
||||
|
||||
class DumpContextOnException(WithExceptionHandler):
|
||||
def __init__(self, exit=False):
|
||||
self.exit = exit
|
||||
super(DumpContextOnException, self).__init__(self.print_context_result)
|
||||
|
||||
def print_context_result(self, exception_pointers):
|
||||
except_record = exception_pointers[0].ExceptionRecord[0]
|
||||
exception_pointers[0].dump()
|
||||
sys.stdout.flush()
|
||||
if self.exit:
|
||||
windows.current_process.exit()
|
||||
return 0
|
||||
|
||||
@@ -1,864 +0,0 @@
|
||||
import ctypes
|
||||
import os
|
||||
import copy
|
||||
import time
|
||||
import struct
|
||||
|
||||
import windows
|
||||
import windows.network
|
||||
import windows.registry
|
||||
import windows.syswow64
|
||||
#import windows.vectored_exception
|
||||
import windows.winproxy as winproxy
|
||||
import windows.injection as injection
|
||||
import windows.native_exec as native_exec
|
||||
import windows.native_exec.simple_x86 as x86
|
||||
import windows.native_exec.simple_x64 as x64
|
||||
|
||||
from . import utils
|
||||
from windows.dbgprint import dbgprint
|
||||
from windows.generated_def.winstructs import *
|
||||
from windows.generated_def.ntstatus import NtStatusException
|
||||
from .generated_def import windef
|
||||
|
||||
import windows.pe_parse as pe_parse
|
||||
|
||||
|
||||
|
||||
class AutoHandle(object):
|
||||
"""An abstract class that allow easy handle creation/destruction/wait"""
|
||||
def _get_handle(self):
|
||||
raise NotImplementedError("{0} is abstract".format(type(self).__name__))
|
||||
|
||||
@property
|
||||
def handle(self):
|
||||
"""An handle on the object
|
||||
|
||||
:type: HANDLE
|
||||
|
||||
.. note::
|
||||
The handle is automaticaly closed when the object is destroyed
|
||||
"""
|
||||
if hasattr(self, "_handle"):
|
||||
return self._handle
|
||||
self._handle = self._get_handle()
|
||||
return self._handle
|
||||
|
||||
def wait(self, timeout=INFINITE):
|
||||
"""Wait for the object"""
|
||||
return winproxy.WaitForSingleObject(self.handle, timeout)
|
||||
|
||||
def __del__(self):
|
||||
if hasattr(self, "_handle") and self._handle:
|
||||
winproxy.CloseHandle(self._handle)
|
||||
|
||||
|
||||
class System(object):
|
||||
"""Represent the current ``Windows`` system ``Python`` is running on"""
|
||||
|
||||
network = windows.network.Network() # Object of class :class:`windows.network.Network`
|
||||
registry = windows.registry.Registry() # Object of class :class:`windows.registry.Registry`
|
||||
|
||||
@property
|
||||
def processes(self):
|
||||
"""The list of running processes
|
||||
|
||||
:type: [:class:`WinProcess`] -- A list of Process
|
||||
|
||||
"""
|
||||
return self.enumerate_processes()
|
||||
|
||||
@property
|
||||
def threads(self):
|
||||
"""The list of running threads
|
||||
|
||||
:type: [:class:`WinThread`] -- A list of Thread
|
||||
|
||||
"""
|
||||
return self.enumerate_threads()
|
||||
|
||||
@utils.fixedpropety
|
||||
def bitness(self):
|
||||
"""The bitness of the system
|
||||
|
||||
:type: :class:`int` -- 32 or 64
|
||||
|
||||
"""
|
||||
if os.environ["PROCESSOR_ARCHITECTURE"].lower() != "x86":
|
||||
return 64
|
||||
if "PROCESSOR_ARCHITEW6432" in os.environ:
|
||||
return 64
|
||||
return 32
|
||||
|
||||
@staticmethod
|
||||
def enumerate_processes():
|
||||
process_entry = WinProcess()
|
||||
process_entry.dwSize = ctypes.sizeof(process_entry)
|
||||
snap = winproxy.CreateToolhelp32Snapshot(windef.TH32CS_SNAPPROCESS, 0)
|
||||
winproxy.Process32First(snap, process_entry)
|
||||
res = []
|
||||
res.append(utils.swallow_ctypes_copy(process_entry))
|
||||
while winproxy.Process32Next(snap, process_entry):
|
||||
res.append(utils.swallow_ctypes_copy(process_entry))
|
||||
return res
|
||||
|
||||
@staticmethod
|
||||
def enumerate_threads():
|
||||
thread_entry = WinThread()
|
||||
thread_entry.dwSize = ctypes.sizeof(thread_entry)
|
||||
snap = winproxy.CreateToolhelp32Snapshot(windef.TH32CS_SNAPTHREAD, 0)
|
||||
threads = []
|
||||
winproxy.Thread32First(snap, thread_entry)
|
||||
threads.append(copy.copy(thread_entry))
|
||||
while winproxy.Thread32Next(snap, thread_entry):
|
||||
threads.append(copy.copy(thread_entry))
|
||||
return threads
|
||||
|
||||
|
||||
class WinThread(THREADENTRY32, AutoHandle):
|
||||
"""Represent a thread """
|
||||
@utils.fixedpropety
|
||||
def tid(self):
|
||||
"""Thread ID
|
||||
|
||||
:type: :class:`int`"""
|
||||
return self.th32ThreadID
|
||||
|
||||
@utils.fixedpropety
|
||||
def owner(self):
|
||||
"""The Process owning the thread
|
||||
|
||||
:type: :class:`WinProcess`
|
||||
|
||||
"""
|
||||
if hasattr(self, "_owner"):
|
||||
return self._owner
|
||||
try:
|
||||
self._owner = [process for process in windows.system.processes if process.pid == self.th32OwnerProcessID][0]
|
||||
except IndexError:
|
||||
return None
|
||||
return self._owner
|
||||
|
||||
@property
|
||||
def context(self):
|
||||
if self.owner.bitness == 32 and windows.current_process.bitness == 64:
|
||||
# Wow64
|
||||
x = windows.vectored_exception.EnhancedCONTEXTWOW64()
|
||||
x.ContextFlags = CONTEXT_FULL
|
||||
winproxy.Wow64GetThreadContext(self.handle, x)
|
||||
return x
|
||||
|
||||
if self.owner.bitness == 64 and windows.current_process.bitness == 32:
|
||||
x = windows.vectored_exception.EnhancedCONTEXT64.new_aligned()
|
||||
x.ContextFlags = CONTEXT_FULL
|
||||
windows.syswow64.NtGetContextThread_32_to_64(self.handle, x)
|
||||
return x
|
||||
|
||||
if self.owner.bitness == 32:
|
||||
x = windows.vectored_exception.EnhancedCONTEXT32()
|
||||
else:
|
||||
x = windows.vectored_exception.EnhancedCONTEXT64.new_aligned()
|
||||
x.ContextFlags = CONTEXT_FULL
|
||||
winproxy.GetThreadContext(self.handle, x)
|
||||
return x
|
||||
|
||||
def set_context(self, context):
|
||||
return winproxy.SetThreadContext(self.handle, context)
|
||||
|
||||
@property
|
||||
def start_address(self):
|
||||
"""The start address of the thread
|
||||
|
||||
:type: :class:`int`
|
||||
"""
|
||||
if windows.current_process.bitness == 32 and self.owner.bitness == 64:
|
||||
res = ULONGLONG()
|
||||
windows.syswow64.NtQueryInformationThread_32_to_64(self.handle, ThreadQuerySetWin32StartAddress, byref(res), ctypes.sizeof(res))
|
||||
return res.value
|
||||
res_size = max(self.owner.bitness, windows.current_process.bitness)
|
||||
if res_size == 32:
|
||||
res = ULONG()
|
||||
else:
|
||||
res = ULONGLONG()
|
||||
winproxy.NtQueryInformationThread(self.handle, ThreadQuerySetWin32StartAddress, byref(res), ctypes.sizeof(res))
|
||||
return res.value
|
||||
|
||||
def exit(self, code=0):
|
||||
"""Exit the thread"""
|
||||
return winproxy.TerminateThread(self.handle, code)
|
||||
|
||||
def resume(self):
|
||||
"""Resume the thread"""
|
||||
return winproxy.ResumeThread(self.handle)
|
||||
|
||||
def suspend(self):
|
||||
"""Suspend the thread"""
|
||||
return winproxy.SuspendThread(self.handle)
|
||||
|
||||
def _get_handle(self):
|
||||
return winproxy.OpenThread(dwThreadId=self.tid)
|
||||
|
||||
@property
|
||||
def is_exit(self):
|
||||
"""Is ``True`` if the thread is terminated
|
||||
|
||||
:type: :class:`bool`
|
||||
"""
|
||||
return self.exit_code != STILL_ACTIVE
|
||||
|
||||
@property
|
||||
def exit_code(self):
|
||||
"""The exit code of the thread : ``STILL_ACTIVE`` means the process is not dead
|
||||
|
||||
:type: :class:`int`
|
||||
"""
|
||||
res = DWORD()
|
||||
winproxy.GetExitCodeThread(self.handle, byref(res))
|
||||
return res.value
|
||||
|
||||
def __repr__(self):
|
||||
owner = self.owner
|
||||
if owner is None:
|
||||
owner_name = "<Dead process with pid {0}>".format(hex(self.th32OwnerProcessID))
|
||||
else:
|
||||
owner_name = owner.name
|
||||
return '<{0} {1} owner "{2}" at {3}>'.format(self.__class__.__name__, self.tid, owner_name, hex(id(self)))
|
||||
|
||||
@staticmethod
|
||||
def _from_handle(handle):
|
||||
tid = winproxy.GetThreadId(handle)
|
||||
try:
|
||||
# Really useful ?
|
||||
thread = [t for t in System().threads if t.tid == tid][0]
|
||||
# set AutoHandle _handle
|
||||
thread._handle = handle
|
||||
return thread
|
||||
except IndexError:
|
||||
return DeadThread(handle, tid)
|
||||
|
||||
class DeadThread(AutoHandle):
|
||||
"""An already dead thread"""
|
||||
def __init__(self, handle, tid=None):
|
||||
if tid is None:
|
||||
tid = winproxy.GetThreadId(handle)
|
||||
self.tid = tid
|
||||
# set AutoHandle _handle
|
||||
self._handle = handle
|
||||
|
||||
@property
|
||||
def is_exit(self):
|
||||
"""Is ``True`` if the thread is terminated
|
||||
|
||||
:type: :class:`bool`
|
||||
"""
|
||||
return self.exit_code != STILL_ACTIVE
|
||||
|
||||
@property
|
||||
def exit_code(self):
|
||||
"""The exit code of the thread : ``STILL_ACTIVE`` means the process is not dead
|
||||
|
||||
:type: :class:`int`
|
||||
"""
|
||||
res = DWORD()
|
||||
winproxy.GetExitCodeThread(self.handle, byref(res))
|
||||
return res.value
|
||||
|
||||
|
||||
class Process(AutoHandle):
|
||||
@utils.fixedpropety
|
||||
def is_wow_64(self):
|
||||
"""``True`` if the process is a SysWow64 process (32bit process on 64bits system).
|
||||
|
||||
:type: :class:`bool`
|
||||
"""
|
||||
return utils.is_wow_64(self.handle)
|
||||
|
||||
@utils.fixedpropety
|
||||
def bitness(self):
|
||||
"""The bitness of the process
|
||||
|
||||
:returns: :class:`int` -- 32 or 64"""
|
||||
if windows.system.bitness == 32:
|
||||
return 32
|
||||
if self.is_wow_64:
|
||||
return 32
|
||||
return 64
|
||||
|
||||
@property
|
||||
def threads(self):
|
||||
"""The threads of the process
|
||||
|
||||
:type: [:class:`WinThread`] -- A list of Thread
|
||||
"""
|
||||
return [thread for thread in windows.system.threads if thread.th32OwnerProcessID == self.pid]
|
||||
|
||||
def virtual_alloc(self, size):
|
||||
raise NotImplementedError("virtual_alloc")
|
||||
|
||||
@property
|
||||
def exit_code(self):
|
||||
"""The exit code of the process : ``STILL_ACTIVE`` means the process is not dead
|
||||
|
||||
:type: :class:`int`
|
||||
"""
|
||||
res = DWORD()
|
||||
winproxy.GetExitCodeProcess(self.handle, byref(res))
|
||||
return res.value
|
||||
|
||||
@property
|
||||
def is_exit(self):
|
||||
"""``True`` if the process is terminated
|
||||
|
||||
:type: :class:`bool`
|
||||
"""
|
||||
return self.exit_code == STILL_ACTIVE
|
||||
|
||||
def execute(self, code):
|
||||
"""Execute some native code in the context of the process
|
||||
|
||||
:return: The return value of the native code
|
||||
:rtype: :class:`int`"""
|
||||
x = self.virtual_alloc(len(code))
|
||||
self.write_memory(x, code)
|
||||
return self.create_thread(x, 0)
|
||||
|
||||
def query_memory(self, addr):
|
||||
"""Query the memory informations about page at ``addr``
|
||||
|
||||
:rtype: :class:`MEMORY_BASIC_INFORMATION`
|
||||
"""
|
||||
if windows.current_process.bitness == 32 and self.bitness == 64:
|
||||
res = MEMORY_BASIC_INFORMATION64()
|
||||
try:
|
||||
v = windows.syswow64.NtQueryVirtualMemory_32_to_64(ProcessHandle=self.handle, BaseAddress=addr, MemoryInformation=res)
|
||||
except NtStatusException as e:
|
||||
if e.code & 0xffffffff == 0XC000000D:
|
||||
raise winproxy.Kernel32Error("NtQueryVirtualMemory_32_to_64")
|
||||
raise
|
||||
return res
|
||||
|
||||
info_type = {32 : MEMORY_BASIC_INFORMATION32, 64 : MEMORY_BASIC_INFORMATION64}
|
||||
res = info_type[windows.current_process.bitness]()
|
||||
ptr = ctypes.cast(byref(res), POINTER(MEMORY_BASIC_INFORMATION))
|
||||
winproxy.VirtualQueryEx(self.handle, addr, ptr, sizeof(res))
|
||||
return res
|
||||
|
||||
def memory_state(self):
|
||||
"""Yield the memory information for the whole address space of the process
|
||||
|
||||
:yield: :class:`MEMORY_BASIC_INFORMATION`
|
||||
"""
|
||||
addr = 0
|
||||
res = []
|
||||
while True:
|
||||
try:
|
||||
x = self.query_memory(addr)
|
||||
yield x
|
||||
except winproxy.Kernel32Error:
|
||||
return
|
||||
addr += x.RegionSize
|
||||
|
||||
|
||||
class CurrentThread(AutoHandle):
|
||||
"""The current thread"""
|
||||
@utils.fixedpropety
|
||||
def tid(self):
|
||||
"""Thread ID
|
||||
|
||||
:type: :class:`int`"""
|
||||
return winproxy.GetCurrentThreadId()
|
||||
|
||||
@utils.fixedpropety
|
||||
def owner(self):
|
||||
"""The current process
|
||||
|
||||
:type: :class:`CurrentProcess`
|
||||
"""
|
||||
return windows.current_process
|
||||
|
||||
def _get_handle(self):
|
||||
return winproxy.GetCurrentThread()
|
||||
|
||||
def __del__(self):
|
||||
pass
|
||||
|
||||
def exit(self, code=0):
|
||||
"""Exit the thread"""
|
||||
return winproxy.ExitThread(code)
|
||||
|
||||
def wait(self):
|
||||
"""Raise ``ValueError`` to prevent deadlock :D"""
|
||||
raise ValueError("wait() on current thread")
|
||||
|
||||
|
||||
class CurrentProcess(Process):
|
||||
"""The current process"""
|
||||
get_peb = None
|
||||
|
||||
get_peb_32_code = x86.MultipleInstr()
|
||||
get_peb_32_code += x86.Mov('EAX', x86.mem('fs:[0x30]'))
|
||||
get_peb_32_code += x86.Ret()
|
||||
get_peb_32_code = get_peb_32_code.get_code()
|
||||
|
||||
get_peb_64_code = x64.MultipleInstr()
|
||||
get_peb_64_code += x64.Mov('RAX', x64.mem('gs:[0x60]'))
|
||||
get_peb_64_code += x64.Ret()
|
||||
get_peb_64_code = get_peb_64_code.get_code()
|
||||
|
||||
allocator = native_exec.native_function.allocator
|
||||
|
||||
def get_peb_builtin(self):
|
||||
if self.get_peb is not None:
|
||||
return self.get_peb
|
||||
if self.bitness == 32:
|
||||
get_peb = native_exec.create_function(self.get_peb_32_code, [PVOID])
|
||||
else:
|
||||
get_peb = native_exec.create_function(self.get_peb_64_code, [PVOID])
|
||||
self.get_peb = get_peb
|
||||
return get_peb
|
||||
|
||||
def _get_handle(self):
|
||||
return winproxy.GetCurrentProcess()
|
||||
|
||||
def __del__(self):
|
||||
pass
|
||||
|
||||
@property
|
||||
def pid(self):
|
||||
"""Process ID
|
||||
|
||||
:type: :class:`int`
|
||||
"""
|
||||
return os.getpid()
|
||||
|
||||
# Is there a better way ?
|
||||
@utils.fixedpropety
|
||||
def ppid(self):
|
||||
"""Parent Process ID
|
||||
|
||||
:type: :class:`int`
|
||||
"""
|
||||
return [p for p in windows.system.processes if p.pid == self.pid][0].ppid
|
||||
|
||||
@utils.fixedpropety
|
||||
def peb(self):
|
||||
"""The Process Environment Block of the current process
|
||||
|
||||
:type: :class:`PEB`
|
||||
"""
|
||||
return PEB.from_address(self.get_peb_builtin()())
|
||||
|
||||
@utils.fixedpropety
|
||||
def bitness(self):
|
||||
"""The bitness of the process
|
||||
|
||||
:type: :class:`int` -- 32 or 64"""
|
||||
import platform
|
||||
bits = platform.architecture()[0]
|
||||
return int(bits[:2])
|
||||
|
||||
def virtual_alloc(self, size):
|
||||
"""Allocate memory in the process
|
||||
|
||||
:return: The address of the allocated memory
|
||||
:rtype: :class:`int`
|
||||
"""
|
||||
return winproxy.VirtualAlloc(dwSize=size)
|
||||
|
||||
def write_memory(self, addr, data):
|
||||
"""Write data at addr"""
|
||||
buffertype = (c_char * len(data)).from_address(addr)
|
||||
buffertype[:len(data)] = data
|
||||
return True
|
||||
|
||||
def read_memory(self, addr, size):
|
||||
"""Read ``size`` from ``addr``
|
||||
|
||||
:return: The data read
|
||||
:rtype: :class:`str`
|
||||
"""
|
||||
dbgprint('Read CurrentProcess Memory', 'READMEM')
|
||||
buffer = (c_char * size).from_address(addr)
|
||||
return buffer[:]
|
||||
|
||||
def create_thread(self, lpStartAddress, lpParameter, dwCreationFlags=0):
|
||||
"""Create a new thread
|
||||
|
||||
:rtype: :class:`WinThread` or :class:`DeadThread`
|
||||
"""
|
||||
handle = winproxy.CreateThread(lpStartAddress=lpStartAddress, lpParameter=lpParameter, dwCreationFlags=dwCreationFlags)
|
||||
return WinThread._from_handle(handle)
|
||||
|
||||
def exit(self, code=0):
|
||||
"""Exit the process"""
|
||||
return winproxy.ExitProcess(code)
|
||||
|
||||
def wait(self):
|
||||
"""Raise ``ValueError`` to prevent deadlock :D"""
|
||||
raise ValueError("wait() on current thread")
|
||||
|
||||
|
||||
class WinProcess(PROCESSENTRY32, Process):
|
||||
"""A Process on the system"""
|
||||
is_pythondll_injected = 0
|
||||
is_remote_slave_running = False
|
||||
|
||||
@utils.fixedpropety
|
||||
def name(self):
|
||||
"""Name of the process
|
||||
|
||||
:type: :class:`str`
|
||||
"""
|
||||
return self.szExeFile[:].decode()
|
||||
|
||||
@utils.fixedpropety
|
||||
def pid(self):
|
||||
"""Process ID
|
||||
|
||||
:type: :class:`int`
|
||||
"""
|
||||
return self.th32ProcessID
|
||||
|
||||
@utils.fixedpropety
|
||||
def ppid(self):
|
||||
"""Parent Process ID
|
||||
|
||||
:type: :class:`int`
|
||||
"""
|
||||
return self.th32ParentProcessID
|
||||
|
||||
def _get_handle(self):
|
||||
return winproxy.OpenProcess(dwProcessId=self.pid)
|
||||
|
||||
def __repr__(self):
|
||||
return '<{0} "{1}" pid {2} at {3}>'.format(self.__class__.__name__, self.name, self.pid, hex(id(self)))
|
||||
|
||||
def virtual_alloc(self, size):
|
||||
"""Allocate memory in the process
|
||||
|
||||
:return: The address of the allocated memory
|
||||
:rtype: :class:`int`
|
||||
"""
|
||||
return winproxy.VirtualAllocEx(self.handle, dwSize=size)
|
||||
|
||||
def write_memory(self, addr, data):
|
||||
"""Write `data` at `addr`"""
|
||||
return winproxy.WriteProcessMemory(self.handle, addr, lpBuffer=data)
|
||||
|
||||
def low_read_memory(self, addr, buffer_addr, size):
|
||||
if windows.current_process.bitness == 32 and self.bitness == 64:
|
||||
# OptionalExport can be None (see winproxy.py)
|
||||
if winproxy.NtWow64ReadVirtualMemory64 is None:
|
||||
raise ValueError("NtWow64ReadVirtualMemory64 non available in ntdll: cannot write into 64bits processus")
|
||||
return winproxy.NtWow64ReadVirtualMemory64(self.handle, addr, buffer_addr, size)
|
||||
return winproxy.ReadProcessMemory(self.handle, addr, lpBuffer=buffer_addr, nSize=size)
|
||||
|
||||
def read_memory(self, addr, size):
|
||||
"""Read ``size`` from ``addr``
|
||||
|
||||
:return: The data read
|
||||
:rtype: :class:`str`
|
||||
"""
|
||||
buffer = ctypes.create_string_buffer(size)
|
||||
self.low_read_memory(addr, ctypes.byref(buffer), size)
|
||||
return buffer[:]
|
||||
|
||||
# Simple cache test
|
||||
# real_read = read_memory
|
||||
#
|
||||
# def read_memory(self, addr, size):
|
||||
# """Cached version for test"""
|
||||
# dbgprint('Read remote Memory of {0}'.format(self), 'READMEM')
|
||||
# if not hasattr(self, "_cache_cache"):
|
||||
# self._cache_cache = {}
|
||||
# page_addr = addr & 0xfffffffffffff000
|
||||
# if page_addr in self._cache_cache:
|
||||
# #print("CACHED Read on page {0}".format(hex(page_addr)))
|
||||
# page_data = self._cache_cache[page_addr]
|
||||
# return page_data[addr & 0xfff: (addr & 0xfff) + size]
|
||||
# else:
|
||||
# page_data = self.real_read(page_addr, 0x1000)
|
||||
# self._cache_cache[page_addr] = page_data
|
||||
# return page_data[addr & 0xfff: (addr & 0xfff) + size]
|
||||
|
||||
def read_memory_into(self, addr, struct):
|
||||
"""Read a :mod:`ctypes` struct from `addr`
|
||||
|
||||
:returns: struct"""
|
||||
self.low_read_memory(addr, ctypes.byref(struct), ctypes.sizeof(struct))
|
||||
return struct
|
||||
|
||||
def create_thread(self, addr, param):
|
||||
"""Create a remote thread
|
||||
|
||||
:rtype: :class:`WinThread` or :class:`DeadThread`
|
||||
"""
|
||||
if windows.current_process.bitness == 32 and self.bitness == 64:
|
||||
thread_handle = HANDLE()
|
||||
windows.syswow64.NtCreateThreadEx_32_to_64(ThreadHandle=byref(thread_handle) ,ProcessHandle=self.handle, lpStartAddress=addr, lpParameter=param)
|
||||
return WinThread._from_handle(thread_handle.value)
|
||||
return WinThread._from_handle(winproxy.CreateRemoteThread(hProcess=self.handle, lpStartAddress=addr, lpParameter=param))
|
||||
|
||||
def load_library(self, dll_path):
|
||||
"""Load the library in remote process"""
|
||||
x = self.virtual_alloc(0x1000)
|
||||
self.write_memory(x, dll_path)
|
||||
LoadLibrary = utils.get_func_addr('kernel32', 'LoadLibraryA')
|
||||
return self.create_thread(LoadLibrary, x)
|
||||
|
||||
def execute_python(self, pycode):
|
||||
"""Execute Python code into the remote process.
|
||||
|
||||
This function waits for the remote process to end and
|
||||
raises an exception if the remote thread raised one"""
|
||||
return injection.safe_execute_python(self, pycode)
|
||||
|
||||
def execute_python_unsafe(self, pycode):
|
||||
"""Execute Python code into the remote process.
|
||||
|
||||
Unsafe means that no information are returned about the execution of the thread
|
||||
"""
|
||||
return injection.execute_python_code(self, pycode)
|
||||
|
||||
@utils.fixedpropety
|
||||
def peb_addr(self):
|
||||
"""The address of the PEB
|
||||
|
||||
:type: :class:`int`
|
||||
"""
|
||||
if windows.current_process.bitness == 32 and self.bitness == 64:
|
||||
x = windows.remotectypes.transform_type_to_remote64bits(PROCESS_BASIC_INFORMATION)
|
||||
# Fuck-it <3
|
||||
data = (ctypes.c_char * ctypes.sizeof(x))()
|
||||
windows.syswow64.NtQueryInformationProcess_32_to_64(self.handle, ProcessInformation=data, ProcessInformationLength=ctypes.sizeof(x))
|
||||
peb_offset = x.PebBaseAddress.offset
|
||||
peb_addr = struct.unpack("<Q", data[x.PebBaseAddress.offset: x.PebBaseAddress.offset+8])[0]
|
||||
elif windows.current_process.bitness == 64 and self.bitness == 32:
|
||||
information_type = 26
|
||||
y = ULONGLONG()
|
||||
windows.winproxy.NtQueryInformationProcess(self.handle, information_type, byref(y), sizeof(y))
|
||||
peb_addr = y.value
|
||||
else:
|
||||
information_type = 0
|
||||
x = PROCESS_BASIC_INFORMATION()
|
||||
windows.winproxy.NtQueryInformationProcess(self.handle, information_type, x)
|
||||
peb_addr = ctypes.cast(x.PebBaseAddress, PVOID).value
|
||||
if peb_addr is None:
|
||||
raise ValueError("Could not get peb addr of process {0}".format(self.name))
|
||||
return peb_addr
|
||||
|
||||
@utils.fixedpropety
|
||||
def peb(self):
|
||||
"""The PEB of the remote process (see :mod:`remotectypes`)
|
||||
|
||||
:type: :class:`PEB`
|
||||
"""
|
||||
if windows.current_process.bitness == 32 and self.bitness == 64:
|
||||
return RemotePEB64(self.peb_addr, self)
|
||||
if windows.current_process.bitness == 64 and self.bitness == 32:
|
||||
return RemotePEB32(self.peb_addr, self)
|
||||
return RemotePEB(self.peb_addr, self)
|
||||
|
||||
def exit(self, code=0):
|
||||
"""Exit the process"""
|
||||
return winproxy.TerminateProcess(self.handle, code)
|
||||
|
||||
|
||||
class LoadedModule(LDR_DATA_TABLE_ENTRY):
|
||||
"""An entry in the PEB Ldr list"""
|
||||
@property
|
||||
def baseaddr(self):
|
||||
"""Base address of the module
|
||||
|
||||
:type: :class:`int`
|
||||
"""
|
||||
return self.DllBase
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Name of the module
|
||||
|
||||
:type: :class:`str`
|
||||
"""
|
||||
return str(self.BaseDllName.Buffer).lower()
|
||||
|
||||
@property
|
||||
def fullname(self):
|
||||
"""Full name of the module (path)
|
||||
|
||||
:type: :class:`str`
|
||||
"""
|
||||
return self.FullDllName.Buffer.decode()
|
||||
|
||||
def __repr__(self):
|
||||
return '<{0} "{1}" at {2}>'.format(self.__class__.__name__, self.name, hex(id(self)))
|
||||
|
||||
@property
|
||||
def pe(self):
|
||||
"""A PE representation of the module
|
||||
|
||||
:type: :class:`windows.pe_parse.PEFile`
|
||||
"""
|
||||
return pe_parse.GetPEFile(self.baseaddr)
|
||||
|
||||
|
||||
class WinUnicodeString(LSA_UNICODE_STRING):
|
||||
"""LSA_UNICODE_STRING with a nice `__repr__`"""
|
||||
fields = [f[0] for f in LSA_UNICODE_STRING._fields_]
|
||||
"""The fields of the structure"""
|
||||
|
||||
def __repr__(self):
|
||||
return """<{0} "{1}" at {2}>""".format(type(self).__name__, self.Buffer, hex(id(self)))
|
||||
|
||||
|
||||
class LIST_ENTRY_PTR(PVOID):
|
||||
def TO_LDR_ENTRY(self):
|
||||
return LDR_DATA_TABLE_ENTRY.from_address(self.value - sizeof(PVOID) * 2)
|
||||
|
||||
|
||||
def transform_ctypes_fields(struct, replacement):
|
||||
return [(name, replacement.get(name, type)) for name, type in struct._fields_]
|
||||
|
||||
|
||||
class RTL_USER_PROCESS_PARAMETERS(Structure):
|
||||
_fields_ = transform_ctypes_fields(RTL_USER_PROCESS_PARAMETERS, # The one in generated_def
|
||||
{"ImagePathName": WinUnicodeString,
|
||||
"CommandLine": WinUnicodeString}
|
||||
)
|
||||
|
||||
|
||||
class PEB(Structure):
|
||||
"""The PEB (Process Environment Block) of the current process"""
|
||||
_fields_ = transform_ctypes_fields(PEB, # The one in generated_def
|
||||
{"ProcessParameters": POINTER(RTL_USER_PROCESS_PARAMETERS)}
|
||||
)
|
||||
|
||||
@property
|
||||
def imagepath(self):
|
||||
"""The ImagePathName of the PEB
|
||||
|
||||
:type: :class:`WinUnicodeString`
|
||||
"""
|
||||
return self.ProcessParameters.contents.ImagePathName
|
||||
|
||||
@property
|
||||
def commandline(self):
|
||||
"""The CommandLine of the PEB
|
||||
|
||||
:type: :class:`WinUnicodeString`
|
||||
"""
|
||||
# This or changing the __repr__ of LSA_UNICODE_STRING
|
||||
return self.ProcessParameters.contents.CommandLine
|
||||
|
||||
@property
|
||||
def modules(self):
|
||||
"""The loaded modules present in the PEB
|
||||
|
||||
:type: [:class:`LoadedModule`] -- List of loaded modules
|
||||
"""
|
||||
res = []
|
||||
list_entry_ptr = ctypes.cast(self.Ldr.contents.InMemoryOrderModuleList.Flink, LIST_ENTRY_PTR)
|
||||
current_dll = list_entry_ptr.TO_LDR_ENTRY()
|
||||
while current_dll.DllBase:
|
||||
res.append(current_dll)
|
||||
list_entry_ptr = ctypes.cast(current_dll.InMemoryOrderLinks.Flink, LIST_ENTRY_PTR)
|
||||
current_dll = list_entry_ptr.TO_LDR_ENTRY()
|
||||
return [LoadedModule.from_address(addressof(LDR)) for LDR in res]
|
||||
|
||||
import windows.remotectypes as rctypes
|
||||
|
||||
class RemoteLoadedModule(rctypes.RemoteStructure.from_structure(LoadedModule)):
|
||||
@property
|
||||
def pe(self):
|
||||
"""A PE representation of the module
|
||||
|
||||
:type: :class:`windows.pe_parse.PEFile`
|
||||
"""
|
||||
return pe_parse.GetPEFile(self.baseaddr, target=self._target)
|
||||
|
||||
|
||||
class RemotePEB(rctypes.RemoteStructure.from_structure(PEB)):
|
||||
|
||||
def ptr_flink_to_remote_module(self, ptr_value):
|
||||
return RemoteLoadedModule(ptr_value - ctypes.sizeof(ctypes.c_void_p) * 2, self._target)
|
||||
|
||||
@property
|
||||
def modules(self):
|
||||
"""The loaded modules present in the PEB
|
||||
|
||||
:type: [:class:`LoadedModule`] -- List of loaded modules
|
||||
"""
|
||||
res = []
|
||||
list_entry_ptr = self.Ldr.contents.InMemoryOrderModuleList.Flink.raw_value
|
||||
|
||||
current_dll = self.ptr_flink_to_remote_module(list_entry_ptr)
|
||||
while current_dll.DllBase:
|
||||
res.append(current_dll)
|
||||
list_entry_ptr = current_dll.InMemoryOrderLinks.Flink.raw_value
|
||||
current_dll = self.ptr_flink_to_remote_module(list_entry_ptr)
|
||||
return res
|
||||
|
||||
|
||||
if CurrentProcess().bitness == 32:
|
||||
class RemoteLoadedModule64(rctypes.transform_type_to_remote64bits(LoadedModule)):
|
||||
@property
|
||||
def pe(self):
|
||||
"""A PE representation of the module
|
||||
|
||||
:type: :class:`windows.pe_parse.PEFile`
|
||||
"""
|
||||
return pe_parse.GetPEFile(self.baseaddr, target=self._target)
|
||||
|
||||
class RemotePEB64(rctypes.transform_type_to_remote64bits(PEB)):
|
||||
|
||||
def ptr_flink_to_remote_module(self, ptr_value):
|
||||
return RemoteLoadedModule64(ptr_value - ctypes.sizeof(rctypes.c_void_p64) * 2, self._target)
|
||||
|
||||
@property
|
||||
def modules(self):
|
||||
"""The loaded modules present in the PEB
|
||||
|
||||
:type: [:class:`LoadedModule`] -- List of loaded modules
|
||||
"""
|
||||
res = []
|
||||
list_entry_ptr = self.Ldr.contents.InMemoryOrderModuleList.Flink.raw_value
|
||||
|
||||
current_dll = self.ptr_flink_to_remote_module(list_entry_ptr)
|
||||
while current_dll.DllBase:
|
||||
res.append(current_dll)
|
||||
list_entry_ptr = current_dll.InMemoryOrderLinks.Flink.raw_value
|
||||
current_dll = self.ptr_flink_to_remote_module(list_entry_ptr)
|
||||
return res
|
||||
|
||||
if CurrentProcess().bitness == 64:
|
||||
|
||||
class RemoteLoadedModule32(rctypes.transform_type_to_remote32bits(LoadedModule)):
|
||||
@property
|
||||
def pe(self):
|
||||
"""A PE representation of the module
|
||||
|
||||
:type: :class:`windows.pe_parse.PEFile`
|
||||
"""
|
||||
return pe_parse.GetPEFile(self.baseaddr, target=self._target)
|
||||
|
||||
class RemotePEB32(rctypes.transform_type_to_remote32bits(PEB)):
|
||||
|
||||
def ptr_flink_to_remote_module(self, ptr_value):
|
||||
return RemoteLoadedModule32(ptr_value - ctypes.sizeof(rctypes.c_void_p32) * 2, self._target)
|
||||
|
||||
@property
|
||||
def modules(self):
|
||||
"""The loaded modules present in the PEB
|
||||
|
||||
:type: [:class:`LoadedModule`] -- List of loaded modules
|
||||
"""
|
||||
res = []
|
||||
#import pdb;pdb.set_trace()
|
||||
list_entry_ptr = self.Ldr.contents.InMemoryOrderModuleList.Flink.raw_value
|
||||
|
||||
current_dll = self.ptr_flink_to_remote_module(list_entry_ptr)
|
||||
while current_dll.DllBase:
|
||||
res.append(current_dll)
|
||||
list_entry_ptr = current_dll.InMemoryOrderLinks.Flink.raw_value
|
||||
current_dll = self.ptr_flink_to_remote_module(list_entry_ptr)
|
||||
return res
|
||||
@@ -0,0 +1,353 @@
|
||||
import ctypes
|
||||
import windows
|
||||
from windows.generated_def.winstructs import *
|
||||
import windows.generated_def.windef as windef
|
||||
|
||||
EXCEPTION_CONTINUE_SEARCH = (0x0)
|
||||
EXCEPTION_CONTINUE_EXECUTION = (0xffffffff)
|
||||
|
||||
exception_type = [
|
||||
"EXCEPTION_ACCESS_VIOLATION",
|
||||
"EXCEPTION_DATATYPE_MISALIGNMENT",
|
||||
"EXCEPTION_BREAKPOINT",
|
||||
"EXCEPTION_SINGLE_STEP",
|
||||
"EXCEPTION_ARRAY_BOUNDS_EXCEEDED",
|
||||
"EXCEPTION_FLT_DENORMAL_OPERAND",
|
||||
"EXCEPTION_FLT_DIVIDE_BY_ZERO",
|
||||
"EXCEPTION_FLT_INEXACT_RESULT",
|
||||
"EXCEPTION_FLT_INVALID_OPERATION",
|
||||
"EXCEPTION_FLT_OVERFLOW",
|
||||
"EXCEPTION_FLT_STACK_CHECK",
|
||||
"EXCEPTION_FLT_UNDERFLOW",
|
||||
"EXCEPTION_INT_DIVIDE_BY_ZERO",
|
||||
"EXCEPTION_INT_OVERFLOW",
|
||||
"EXCEPTION_PRIV_INSTRUCTION",
|
||||
"EXCEPTION_IN_PAGE_ERROR",
|
||||
"EXCEPTION_ILLEGAL_INSTRUCTION",
|
||||
"EXCEPTION_NONCONTINUABLE_EXCEPTION",
|
||||
"EXCEPTION_STACK_OVERFLOW",
|
||||
"EXCEPTION_INVALID_DISPOSITION",
|
||||
"EXCEPTION_GUARD_PAGE",
|
||||
"EXCEPTION_INVALID_HANDLE",
|
||||
"EXCEPTION_POSSIBLE_DEADLOCK",
|
||||
]
|
||||
|
||||
# x -> x dict may seems strange but useful to get the Flags (with name) from the int
|
||||
# exception_name_by_value[0x80000001] -> EXCEPTION_GUARD_PAGE(0x80000001L)
|
||||
exception_name_by_value = dict([(x, x) for x in [getattr(windows.generated_def.windef, name) for name in exception_type]])
|
||||
|
||||
class EEXCEPTION_RECORDBase(object):
|
||||
@property
|
||||
def ExceptionCode(self):
|
||||
"""The Exception code
|
||||
|
||||
:type: :class:`int`"""
|
||||
real_code = super(EEXCEPTION_RECORDBase, self).ExceptionCode
|
||||
return exception_name_by_value.get(real_code, windows.generated_def.windef.Flag("UNKNOW_EXCEPTION", real_code))
|
||||
|
||||
@property
|
||||
def ExceptionAddress(self):
|
||||
"""The Exception Address
|
||||
|
||||
:type: :class:`int`"""
|
||||
x = super(EEXCEPTION_RECORDBase, self).ExceptionAddress
|
||||
if x is None:
|
||||
return 0x0
|
||||
return x
|
||||
|
||||
class EEXCEPTION_RECORD(EEXCEPTION_RECORDBase, EXCEPTION_RECORD):
|
||||
"""Enhanced exception record"""
|
||||
|
||||
fields = [f[0] for f in EXCEPTION_RECORD._fields_]
|
||||
"""The fields of the structure"""
|
||||
|
||||
class EEXCEPTION_RECORD32(EEXCEPTION_RECORDBase, EXCEPTION_RECORD32):
|
||||
"""Enhanced exception record (32bits)"""
|
||||
|
||||
fields = [f[0] for f in EXCEPTION_RECORD32._fields_]
|
||||
"""The fields of the structure"""
|
||||
|
||||
class EEXCEPTION_RECORD64(EEXCEPTION_RECORDBase, EXCEPTION_RECORD64):
|
||||
"""Enhanced exception record (64bits)"""
|
||||
|
||||
fields = [f[0] for f in EXCEPTION_RECORD64._fields_]
|
||||
"""The fields of the structure"""
|
||||
|
||||
|
||||
class EEXCEPTION_DEBUG_INFO32(ctypes.Structure):
|
||||
"""Enhanced Debug info"""
|
||||
_fields_ = windows.utils.transform_ctypes_fields(EXCEPTION_DEBUG_INFO, {"ExceptionRecord": EEXCEPTION_RECORD32})
|
||||
|
||||
fields = [f[0] for f in _fields_]
|
||||
"""The fields of the structure"""
|
||||
|
||||
class EEXCEPTION_DEBUG_INFO64(ctypes.Structure):
|
||||
"""Enhanced Debug info"""
|
||||
_fields_ = windows.utils.transform_ctypes_fields(EXCEPTION_DEBUG_INFO, {"ExceptionRecord": EEXCEPTION_RECORD64})
|
||||
|
||||
fields = [f[0] for f in _fields_]
|
||||
"""The fields of the structure"""
|
||||
|
||||
|
||||
class EEflags(ctypes.Structure):
|
||||
"Flag view of the Eflags register"
|
||||
_fields_ = [("CF", DWORD, 1),
|
||||
("RES_1", DWORD, 1),
|
||||
("PF", DWORD, 1),
|
||||
("RES_3", DWORD, 1),
|
||||
("AF", DWORD, 1),
|
||||
("RES_5", DWORD, 1),
|
||||
("ZF", DWORD, 1),
|
||||
("SF", DWORD, 1),
|
||||
("TF", DWORD, 1),
|
||||
("IF", DWORD, 1),
|
||||
("DF", DWORD, 1),
|
||||
("OF", DWORD, 1),
|
||||
("IOPL_1", DWORD, 1),
|
||||
("IOPL_2", DWORD, 1),
|
||||
("NT", DWORD, 1),
|
||||
("RES_15", DWORD, 1),
|
||||
("RF", DWORD, 1),
|
||||
("VM", DWORD, 1),
|
||||
("AC", DWORD, 1),
|
||||
("VIF", DWORD, 1),
|
||||
("VIP", DWORD, 1),
|
||||
("ID", DWORD, 1),
|
||||
]
|
||||
|
||||
fields = [f[0] for f in _fields_]
|
||||
"""The fields of the structure"""
|
||||
|
||||
def get_raw(self):
|
||||
x = DWORD.from_address(ctypes.addressof(self))
|
||||
return x.value
|
||||
|
||||
def set_raw(self, value):
|
||||
x = DWORD.from_address(ctypes.addressof(self))
|
||||
x.value = value
|
||||
return None
|
||||
|
||||
def dump(self):
|
||||
res = []
|
||||
for name in [x[0] for x in self._fields_]:
|
||||
if name.startswith("RES_"):
|
||||
continue
|
||||
if getattr(self, name):
|
||||
res.append(name)
|
||||
return "|".join(res)
|
||||
|
||||
def __repr__(self):
|
||||
return hex(self)
|
||||
|
||||
def __hex__(self):
|
||||
if self.raw == 0:
|
||||
return "{0}({1})".format(type(self).__name__, hex(self.raw))
|
||||
return "{0}({1}:{2})".format(type(self).__name__, hex(self.raw), self.dump())
|
||||
|
||||
raw = property(get_raw, set_raw)
|
||||
"""Raw value of the eflags
|
||||
|
||||
:type: :class:`int`
|
||||
"""
|
||||
|
||||
|
||||
class EDr7(ctypes.Structure):
|
||||
"Flag view of the DR7 register"
|
||||
_fields_ = [("L0", DWORD, 1),
|
||||
("G0", DWORD, 1),
|
||||
("L1", DWORD, 1),
|
||||
("G1", DWORD, 1),
|
||||
("L2", DWORD, 1),
|
||||
("G2", DWORD, 1),
|
||||
("L3", DWORD, 1),
|
||||
("G3", DWORD, 1),
|
||||
("LE", DWORD, 1),
|
||||
("GE", DWORD, 1),
|
||||
("RES_1", DWORD, 3),
|
||||
("GD", DWORD, 1),
|
||||
("RES_1", DWORD, 2),
|
||||
("RW0", DWORD, 2),
|
||||
("LEN0", DWORD, 2),
|
||||
("RW1", DWORD, 2),
|
||||
("LEN1", DWORD, 2),
|
||||
("RW2", DWORD, 2),
|
||||
("LEN2", DWORD, 2),
|
||||
("RW3", DWORD, 2),
|
||||
("LEN3", DWORD, 2),
|
||||
]
|
||||
|
||||
fields = [f[0] for f in _fields_]
|
||||
"""The fields of the structure"""
|
||||
|
||||
class ECONTEXTBase(object):
|
||||
"""DAT CONTEXT"""
|
||||
default_dump = ()
|
||||
pc_reg = ''
|
||||
special_reg_type = {}
|
||||
|
||||
|
||||
def regs(self, to_dump=None):
|
||||
"""Return the name and values of the registers
|
||||
|
||||
:returns: [(reg_name, value)] -- A :class:`list` of :class:`tuple`"""
|
||||
res = []
|
||||
if to_dump is None:
|
||||
to_dump = self.default_dump
|
||||
for name in to_dump:
|
||||
value = getattr(self, name)
|
||||
if name in self.special_reg_type:
|
||||
value = self.special_reg_type[name](value)
|
||||
res.append((name, value))
|
||||
return res
|
||||
|
||||
def dump(self, to_dump=None):
|
||||
"""Dump (print) the current context"""
|
||||
regs = self.regs()
|
||||
for name, value in regs:
|
||||
print("{0} -> {1}".format(name, hex(value)))
|
||||
return None
|
||||
|
||||
def get_pc(self):
|
||||
return getattr(self, self.pc_reg)
|
||||
|
||||
def set_pc(self, value):
|
||||
return setattr(self, self.pc_reg, value)
|
||||
|
||||
pc = property(get_pc, set_pc, None, "Program Counter register (EIP or RIP)")
|
||||
|
||||
@property
|
||||
def EEFlags(self):
|
||||
"""Enhanced view of the Eflags (you also have ``EFlags`` for the raw value)
|
||||
|
||||
:type: :class:`EEflags`
|
||||
"""
|
||||
off = type(self).EFlags.offset
|
||||
x = EEflags.from_address(ctypes.addressof(self) + off)
|
||||
x.self = self
|
||||
return x
|
||||
|
||||
@property
|
||||
def EDr7(self):
|
||||
"""Enhanced view of the DR7 register (you also have ``Dr7`` for the raw value)
|
||||
|
||||
:type: :class:`EDr7`
|
||||
"""
|
||||
off = type(self).Dr7.offset
|
||||
x = EDr7.from_address(ctypes.addressof(self) + off)
|
||||
x.self = self
|
||||
return x
|
||||
|
||||
class ECONTEXT32(ECONTEXTBase, CONTEXT32):
|
||||
default_dump = ('Eip', 'Esp', 'Eax', 'Ebx', 'Ecx', 'Edx', 'Ebp', 'Edi', 'Esi', 'EFlags')
|
||||
pc_reg = 'Eip'
|
||||
fields = [f[0] for f in CONTEXT32._fields_]
|
||||
"""The fields of the structure"""
|
||||
|
||||
class ECONTEXTWOW64(ECONTEXTBase, WOW64_CONTEXT):
|
||||
default_dump = ('Eip', 'Esp', 'Eax', 'Ebx', 'Ecx', 'Edx', 'Ebp', 'Edi', 'Esi', 'EFlags')
|
||||
pc_reg = 'Eip'
|
||||
fields = [f[0] for f in WOW64_CONTEXT._fields_]
|
||||
"""The fields of the structure"""
|
||||
|
||||
|
||||
class ECONTEXT64(ECONTEXTBase, CONTEXT64):
|
||||
default_dump = ('Rip', 'Rsp', 'Rax', 'Rbx', 'Rcx', 'Rdx', 'Rbp', 'Rdi', 'Rsi',
|
||||
'R9', 'R10', 'R11', 'R12', 'R13', 'R14', 'R15', 'EFlags')
|
||||
pc_reg = 'Rip'
|
||||
fields = [f[0] for f in CONTEXT64._fields_]
|
||||
"""The fields of the structure"""
|
||||
|
||||
@classmethod
|
||||
def new_aligned(cls):
|
||||
"""Return a new :class:`ECONTEXT64` aligned on 16 bits
|
||||
|
||||
temporary workaround or horrible hack ? choose your side
|
||||
"""
|
||||
size = ctypes.sizeof(cls)
|
||||
nb_qword = (size + 8) / ctypes.sizeof(ULONGLONG)
|
||||
buffer = (nb_qword * ULONGLONG)()
|
||||
struct_address = ctypes.addressof(buffer)
|
||||
if (struct_address & 0xf) not in [0, 8]:
|
||||
raise ValueError("ULONGLONG array not aligned on 8")
|
||||
if (struct_address & 0xf) == 8:
|
||||
struct_address += 8
|
||||
self = cls.from_address(struct_address)
|
||||
# Keep the raw buffer alive
|
||||
self._buffer = buffer
|
||||
return self
|
||||
|
||||
def bitness():
|
||||
"""Return 32 or 64"""
|
||||
import platform
|
||||
bits = platform.architecture()[0]
|
||||
return int(bits[:2])
|
||||
|
||||
if bitness() == 32:
|
||||
ECONTEXT = ECONTEXT32
|
||||
else:
|
||||
ECONTEXT = ECONTEXT64
|
||||
|
||||
|
||||
class EEXCEPTION_POINTERS(ctypes.Structure):
|
||||
_fields_ = [
|
||||
("ExceptionRecord", ctypes.POINTER(EEXCEPTION_RECORD)),
|
||||
("ContextRecord", ctypes.POINTER(ECONTEXT)),
|
||||
]
|
||||
|
||||
def dump(self):
|
||||
"""Dump (print) the EEXCEPTION_POINTERS"""
|
||||
record = self.ExceptionRecord[0]
|
||||
print("Dumping Exception: ")
|
||||
print(" ExceptionCode = {0} at {1}".format(record.ExceptionCode, hex(record.ExceptionAddress)))
|
||||
regs = self.ContextRecord[0].regs()
|
||||
for name, value in regs:
|
||||
print(" {0} -> {1}".format(name, hex(value)))
|
||||
|
||||
|
||||
class VectoredException(object):
|
||||
"""A decorator that create a callable which can be passed to :func:`AddVectoredExceptionHandler`"""
|
||||
func_type = ctypes.WINFUNCTYPE(ctypes.c_uint, ctypes.POINTER(EEXCEPTION_POINTERS))
|
||||
|
||||
def __new__(cls, func):
|
||||
self = object.__new__(cls)
|
||||
self.func = func
|
||||
v = self.func_type(self.decorator)
|
||||
v.self = self
|
||||
return v
|
||||
|
||||
def decorator(self, exception_pointers):
|
||||
try:
|
||||
return self.func(exception_pointers)
|
||||
except BaseException as e:
|
||||
import traceback
|
||||
print("Ignored Python Exception in Vectored Exception: {0}".format(e))
|
||||
traceback.print_exc()
|
||||
return windef.EXCEPTION_CONTINUE_SEARCH
|
||||
|
||||
|
||||
class VectoredExceptionHandler(object):
|
||||
def __init__(self, pos, handler):
|
||||
self.handler = VectoredException(handler)
|
||||
self.pos = pos
|
||||
|
||||
def __enter__(self):
|
||||
self.value = windows.winproxy.AddVectoredExceptionHandler(self.pos, self.handler)
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type, exc_value, traceback):
|
||||
windows.winproxy.RemoveVectoredExceptionHandler(self.value)
|
||||
return False
|
||||
|
||||
class DumpContextOnException(VectoredExceptionHandler):
|
||||
def __init__(self, exit=False):
|
||||
self.exit = exit
|
||||
super(DumpContextOnException, self).__init__(self.print_context_result)
|
||||
|
||||
def print_context_result(self, exception_pointers):
|
||||
except_record = exception_pointers[0].ExceptionRecord[0]
|
||||
exception_pointers[0].dump()
|
||||
sys.stdout.flush()
|
||||
if self.exit:
|
||||
windows.current_process.exit()
|
||||
return 0
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
import os.path
|
||||
import ctypes
|
||||
from collections import namedtuple
|
||||
|
||||
import windows
|
||||
from windows import winproxy
|
||||
from windows.generated_def.winstructs import *
|
||||
|
||||
|
||||
def query_link(linkpath):
|
||||
utf16_len = len(linkpath) * 2
|
||||
obj_attr = OBJECT_ATTRIBUTES()
|
||||
obj_attr.Length = ctypes.sizeof(obj_attr)
|
||||
obj_attr.RootDirectory = 0
|
||||
obj_attr.ObjectName = pointer(LSA_UNICODE_STRING(utf16_len, utf16_len, linkpath))
|
||||
obj_attr.Attributes = OBJ_CASE_INSENSITIVE
|
||||
obj_attr.SecurityDescriptor = 0
|
||||
obj_attr.SecurityQualityOfService = 0
|
||||
|
||||
res = HANDLE()
|
||||
x = winproxy.NtOpenSymbolicLinkObject(res, DIRECTORY_QUERY | READ_CONTROL , obj_attr)
|
||||
v = LSA_UNICODE_STRING(0x1000, 0x1000, ctypes.cast(ctypes.c_buffer(0x1000), ctypes.c_wchar_p))
|
||||
s = ULONG()
|
||||
winproxy.NtQuerySymbolicLinkObject(res, v, s)
|
||||
return v.Buffer
|
||||
|
||||
|
||||
class KernelObject(object):
|
||||
def __init__(self, path, name, type):
|
||||
self.path = path
|
||||
self.name = name
|
||||
if path and not path.endswith("\\"):
|
||||
path += "\\"
|
||||
self.fullname = path + name
|
||||
self.type = type
|
||||
|
||||
@property
|
||||
def target(self):
|
||||
try:
|
||||
return query_link(self.fullname)
|
||||
except windows.generated_def.ntstatus.NtStatusException as e:
|
||||
return None
|
||||
|
||||
@property
|
||||
def entries(self):
|
||||
"""Todo: better name ?"""
|
||||
path = self.fullname
|
||||
utf16_len = len(path) * 2
|
||||
obj_attr = OBJECT_ATTRIBUTES()
|
||||
obj_attr.Length = ctypes.sizeof(obj_attr)
|
||||
obj_attr.RootDirectory = None
|
||||
obj_attr.ObjectName = pointer(LSA_UNICODE_STRING(utf16_len, utf16_len, path))
|
||||
obj_attr.Attributes = OBJ_CASE_INSENSITIVE
|
||||
obj_attr.SecurityDescriptor = 0
|
||||
obj_attr.SecurityQualityOfService = 0
|
||||
|
||||
res = HANDLE()
|
||||
x = winproxy.NtOpenDirectoryObject(res, DIRECTORY_QUERY | READ_CONTROL , obj_attr)
|
||||
size = 0x1000
|
||||
buf = ctypes.c_buffer(size)
|
||||
rres = ULONG()
|
||||
ctx = ULONG()
|
||||
while True:
|
||||
try:
|
||||
winproxy.NtQueryDirectoryObject(res, buf, size, False, False, ctx, rres)
|
||||
break
|
||||
except windows.generated_def.ntstatus.NtStatusException as e:
|
||||
if e.code == STATUS_NO_MORE_ENTRIES:
|
||||
return {}
|
||||
if e.code == STATUS_MORE_ENTRIES:
|
||||
size *= 2
|
||||
buf = ctypes.c_buffer(size)
|
||||
continue
|
||||
raise
|
||||
|
||||
t = OBJECT_DIRECTORY_INFORMATION.from_buffer(buf)
|
||||
t = POBJECT_DIRECTORY_INFORMATION(t)
|
||||
res = {}
|
||||
for v in t:
|
||||
if v.Name.Buffer is None:
|
||||
break
|
||||
x = KernelObject(path, v.Name.Buffer, v.TypeName.Buffer)
|
||||
res[x.name] = x
|
||||
return res
|
||||
|
||||
def __repr__(self):
|
||||
return """<{0} "{1}" (type="{2}")>""".format(type(self).__name__, self.fullname, self.type)
|
||||
|
||||
|
||||
root = KernelObject("", "\\", "Directory")
|
||||
|
||||
#def full_explore(start):
|
||||
# TODO = [start]
|
||||
# while TODO:
|
||||
# path = TODO.pop()
|
||||
# print("Explore <{0}>".format(path))
|
||||
# try:
|
||||
# for obj in path.subobjects.values():
|
||||
# print("{0} -> {1}".format(obj.fullname, obj.type))
|
||||
# if obj.type == "Directory":
|
||||
# TODO.append(obj)
|
||||
# if obj.type == "SymbolicLink":
|
||||
# print("* Symblink target -> {0}".format(obj.target))
|
||||
# except windows.generated_def.ntstatus.NtStatusException as e:
|
||||
# print(repr(e))
|
||||
#full_explore(yolo)
|
||||
@@ -0,0 +1,447 @@
|
||||
import windows
|
||||
import ctypes
|
||||
import socket
|
||||
import struct
|
||||
|
||||
from windows import winproxy
|
||||
import windows.generated_def as gdef
|
||||
from windows.com import interfaces as cominterfaces
|
||||
from windows.generated_def.winstructs import *
|
||||
from windows.generated_def.windef import *
|
||||
|
||||
|
||||
class TCP4Connection(MIB_TCPROW_OWNER_PID):
|
||||
"""A TCP4 socket (connected or listening)"""
|
||||
@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:
|
||||
return self.remote_port
|
||||
|
||||
@property
|
||||
def remote_host(self):
|
||||
"""Identification of the remote hostname.
|
||||
Equals ``remote_addr`` if the resolution fails
|
||||
|
||||
: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
|
||||
closing.dwLocalPort = self.dwLocalPort
|
||||
closing.dwRemoteAddr = self.dwRemoteAddr
|
||||
closing.dwRemotePort = self.dwRemotePort
|
||||
return winproxy.SetTcpEntry(ctypes.byref(closing))
|
||||
|
||||
def __repr__(self):
|
||||
if not self.established:
|
||||
return "<TCP IPV4 Listening socket on {0}:{1}>".format(self.local_addr, self.local_port)
|
||||
return "<TCP IPV4 Connection {s.local_addr}:{s.local_port} -> {s.remote_addr}:{s.remote_port}>".format(s=self)
|
||||
|
||||
|
||||
class TCP6Connection(MIB_TCP6ROW_OWNER_PID):
|
||||
"""A TCP6 socket (connected or listening)"""
|
||||
@staticmethod
|
||||
def _str_ipv6_addr(addr):
|
||||
return ":".join(c.encode('hex') for c in addr)
|
||||
|
||||
@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):
|
||||
raise NotImplementedError("Closing IPV6 connection non implemented")
|
||||
|
||||
def __repr__(self):
|
||||
if not self.established:
|
||||
return "<TCP IPV6 Listening socket on {0}:{1}>".format(self.local_addr, self.local_port)
|
||||
return "<TCP IPV6 Connection {0}:{1} -> {2}:{3}>".format(self.local_addr, self.local_port, self.remote_addr, self.remote_port)
|
||||
|
||||
|
||||
def get_MIB_TCPTABLE_OWNER_PID_from_buffer(buffer):
|
||||
x = windows.generated_def.winstructs.MIB_TCPTABLE_OWNER_PID.from_buffer(buffer)
|
||||
nb_entry = x.dwNumEntries
|
||||
|
||||
class _GENERATED_MIB_TCPTABLE_OWNER_PID(ctypes.Structure):
|
||||
_fields_ = [
|
||||
("dwNumEntries", DWORD),
|
||||
("table", TCP4Connection * nb_entry),
|
||||
]
|
||||
|
||||
return _GENERATED_MIB_TCPTABLE_OWNER_PID.from_buffer(buffer)
|
||||
|
||||
|
||||
def get_MIB_TCP6TABLE_OWNER_PID_from_buffer(buffer):
|
||||
x = windows.generated_def.winstructs.MIB_TCP6TABLE_OWNER_PID.from_buffer(buffer)
|
||||
nb_entry = x.dwNumEntries
|
||||
|
||||
# Struct _MIB_TCP6TABLE_OWNER_PID definitions
|
||||
class _GENERATED_MIB_TCP6TABLE_OWNER_PID(Structure):
|
||||
_fields_ = [
|
||||
("dwNumEntries", DWORD),
|
||||
("table", TCP6Connection * nb_entry),
|
||||
]
|
||||
|
||||
return _GENERATED_MIB_TCP6TABLE_OWNER_PID.from_buffer(buffer)
|
||||
|
||||
class Firewall(cominterfaces.INetFwPolicy2):
|
||||
"""The windows firewall"""
|
||||
@property
|
||||
def rules(self):
|
||||
"""The rules of the firewall
|
||||
|
||||
:type: [:class:`FirewallRule`] -- A list of rule
|
||||
"""
|
||||
ifw_rules = cominterfaces.INetFwRules()
|
||||
self.get_Rules(ifw_rules)
|
||||
|
||||
nb_rules = gdef.LONG()
|
||||
ifw_rules.get_Count(nb_rules)
|
||||
|
||||
unknw = cominterfaces.IUnknown()
|
||||
ifw_rules.get__NewEnum(unknw)
|
||||
|
||||
pVariant = cominterfaces.IEnumVARIANT()
|
||||
unknw.QueryInterface(pVariant.IID, pVariant)
|
||||
|
||||
count = gdef.ULONG()
|
||||
var = windows.com.ImprovedVariant()
|
||||
|
||||
rules = []
|
||||
for i in range(nb_rules.value):
|
||||
pVariant.Next(1, var, count)
|
||||
if not count.value:
|
||||
break
|
||||
rule = FirewallRule()
|
||||
idisp = var.asdispatch
|
||||
idisp.QueryInterface(rule.IID, rule)
|
||||
rules.append(rule)
|
||||
return rules
|
||||
|
||||
@property
|
||||
def current_profile_types(self):
|
||||
"""Mask of the profiles currently enabled
|
||||
|
||||
:type: :class:`long`
|
||||
"""
|
||||
cpt = gdef.LONG()
|
||||
self.get_CurrentProfileTypes(cpt)
|
||||
return cpt.value
|
||||
|
||||
@property
|
||||
def enabled(self):
|
||||
"""A maping of the active firewall profiles
|
||||
|
||||
{
|
||||
|
||||
``NET_FW_PROFILE_TYPE2_.NET_FW_PROFILE2_DOMAIN(0x1L)``: ``True`` or ``False``,
|
||||
|
||||
``NET_FW_PROFILE_TYPE2_.NET_FW_PROFILE2_PRIVATE(0x2L)``: ``True`` or ``False``,
|
||||
|
||||
``NET_FW_PROFILE_TYPE2_.NET_FW_PROFILE2_PUBLIC(0x4L)``: ``True`` or ``False``,
|
||||
|
||||
}
|
||||
|
||||
|
||||
:type: :class:`dict`
|
||||
"""
|
||||
profiles = [gdef.NET_FW_PROFILE2_DOMAIN, gdef.NET_FW_PROFILE2_PRIVATE, gdef.NET_FW_PROFILE2_PUBLIC]
|
||||
return {prof: self.enabled_for_profile_type(prof) for prof in profiles}
|
||||
|
||||
|
||||
def enabled_for_profile_type(self, profile_type):
|
||||
enabled = gdef.VARIANT_BOOL()
|
||||
self.get_FirewallEnabled(profile_type, enabled)
|
||||
return enabled.value
|
||||
|
||||
|
||||
|
||||
class FirewallRule(cominterfaces.INetFwRule):
|
||||
"""A rule of the firewall"""
|
||||
@property
|
||||
def name(self):
|
||||
"""Name of the rule
|
||||
|
||||
:type: :class:`unicode`
|
||||
"""
|
||||
name = gdef.BSTR()
|
||||
self.get_Name(name)
|
||||
return name.value
|
||||
|
||||
@property
|
||||
def description(self):
|
||||
"""Description of the rule
|
||||
|
||||
:type: :class:`unicode`
|
||||
"""
|
||||
description = gdef.BSTR()
|
||||
self.get_Description(description)
|
||||
return description.value
|
||||
|
||||
@property
|
||||
def application_name(self):
|
||||
"""Name of the application to which apply the rule
|
||||
|
||||
:type: :class:`unicode`
|
||||
"""
|
||||
applicationname = gdef.BSTR()
|
||||
self.get_ApplicationName(applicationname)
|
||||
return applicationname.value
|
||||
|
||||
@property
|
||||
def service_name(self):
|
||||
"""Name of the service to which apply the rule
|
||||
|
||||
:type: :class:`unicode`
|
||||
"""
|
||||
servicename = gdef.BSTR()
|
||||
self.get_ServiceName(servicename)
|
||||
return servicename.value
|
||||
|
||||
@property
|
||||
def protocol(self):
|
||||
"""Protocol to which apply the rule
|
||||
|
||||
:type: :class:`long`
|
||||
"""
|
||||
protocol = gdef.LONG()
|
||||
self.get_Protocol(protocol)
|
||||
return protocol.value
|
||||
|
||||
@property
|
||||
def local_address(self):
|
||||
"""Local address of the rule
|
||||
|
||||
:type: :class:`unicode`
|
||||
"""
|
||||
local_address = gdef.BSTR()
|
||||
self.get_LocalAddresses(local_address)
|
||||
return local_address.value
|
||||
|
||||
@property
|
||||
def remote_address(self):
|
||||
"""Remote address of the rule
|
||||
|
||||
:type: :class:`unicode`
|
||||
"""
|
||||
remote_address = gdef.BSTR()
|
||||
self.get_RemoteAddresses(remote_address)
|
||||
return remote_address.value
|
||||
|
||||
@property
|
||||
def direction(self):
|
||||
"""Direction of the rule, values might be:
|
||||
|
||||
* ``NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_IN(0x1L)``
|
||||
* ``NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_OUT(0x2L)``
|
||||
|
||||
subclass of :class:`long`
|
||||
"""
|
||||
direction = gdef.NET_FW_RULE_DIRECTION()
|
||||
self.get_Direction(direction)
|
||||
return direction.value
|
||||
|
||||
@property
|
||||
def interface_types(self):
|
||||
"""Types of interface of the rule
|
||||
|
||||
:type: :class:`unicode`
|
||||
"""
|
||||
interface_type = gdef.BSTR()
|
||||
self.get_InterfaceTypes(interface_type)
|
||||
return interface_type.value
|
||||
|
||||
@property
|
||||
def local_port(self):
|
||||
"""Local port of the rule
|
||||
|
||||
:type: :class:`unicode`
|
||||
"""
|
||||
local_port = gdef.BSTR()
|
||||
self.get_LocalPorts(local_port)
|
||||
return local_port.value
|
||||
|
||||
@property
|
||||
def remote_port(self):
|
||||
"""Remote port of the rule
|
||||
|
||||
:type: :class:`unicode`
|
||||
"""
|
||||
remote_port = gdef.BSTR()
|
||||
self.get_RemotePorts(remote_port)
|
||||
return remote_port.value
|
||||
|
||||
@property
|
||||
def action(self):
|
||||
"""Action of the rule, values might be:
|
||||
|
||||
* ``NET_FW_ACTION_.NET_FW_ACTION_BLOCK(0x0L)``
|
||||
* ``NET_FW_ACTION_.NET_FW_ACTION_ALLOW(0x1L)``
|
||||
|
||||
subclass of :class:`long`
|
||||
"""
|
||||
action = gdef.NET_FW_ACTION()
|
||||
self.get_Action(action)
|
||||
return action.value
|
||||
|
||||
@property
|
||||
def enabled(self):
|
||||
"""``True`` if rule is enabled"""
|
||||
enabled = gdef.VARIANT_BOOL()
|
||||
self.get_Enabled(enabled)
|
||||
return enabled.value
|
||||
|
||||
@property
|
||||
def grouping(self):
|
||||
"""Grouping of the rule
|
||||
|
||||
:type: :class:`unicode`
|
||||
"""
|
||||
grouping = gdef.BSTR()
|
||||
self.get_RemotePorts(grouping)
|
||||
return grouping.value
|
||||
|
||||
@property
|
||||
def icmp_type_and_code(self):
|
||||
icmp_type_and_code = gdef.BSTR()
|
||||
self.get_RemotePorts(icmp_type_and_code)
|
||||
return icmp_type_and_code.value
|
||||
|
||||
def __repr__(self):
|
||||
return '<{0} "{1}">'.format(type(self).__name__, self.name)
|
||||
|
||||
class Network(object):
|
||||
NetFwPolicy2 = windows.com.IID.from_string("E2B3C97F-6AE1-41AC-817A-F6F92166D7DD")
|
||||
|
||||
@property
|
||||
def firewall(self):
|
||||
"""The firewall of the system
|
||||
|
||||
:type: :class:`Firewall`
|
||||
"""
|
||||
windows.com.init()
|
||||
firewall = Firewall()
|
||||
windows.com.create_instance(self.NetFwPolicy2, firewall)
|
||||
return firewall
|
||||
|
||||
@staticmethod
|
||||
def _get_tcp_ipv4_sockets():
|
||||
size = ctypes.c_uint(0)
|
||||
try:
|
||||
winproxy.GetExtendedTcpTable(None, ctypes.byref(size), ulAf=AF_INET)
|
||||
except winproxy.IphlpapiError:
|
||||
pass # Allow us to set size to the needed value
|
||||
buffer = (ctypes.c_char * size.value)()
|
||||
winproxy.GetExtendedTcpTable(buffer, ctypes.byref(size), ulAf=AF_INET)
|
||||
t = get_MIB_TCPTABLE_OWNER_PID_from_buffer(buffer)
|
||||
return list(t.table)
|
||||
|
||||
@staticmethod
|
||||
def _get_tcp_ipv6_sockets():
|
||||
size = ctypes.c_uint(0)
|
||||
try:
|
||||
winproxy.GetExtendedTcpTable(None, ctypes.byref(size), ulAf=AF_INET6)
|
||||
except winproxy.IphlpapiError:
|
||||
pass # Allow us to set size to the needed value
|
||||
buffer = (ctypes.c_char * size.value)()
|
||||
winproxy.GetExtendedTcpTable(buffer, ctypes.byref(size), ulAf=AF_INET6)
|
||||
t = get_MIB_TCP6TABLE_OWNER_PID_from_buffer(buffer)
|
||||
return list(t.table)
|
||||
|
||||
|
||||
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`]
|
||||
"""
|
||||
File diff suppressed because it is too large
Load Diff
@@ -30,6 +30,7 @@ class PyHKey(object):
|
||||
self.fullname = self.surkey.fullname + "\\" + self.name if self.name else self.surkey.name
|
||||
self.sam = sam
|
||||
self._phkey = None
|
||||
#self.phkey
|
||||
|
||||
def __repr__(self):
|
||||
return '<PyHKey "{0}">'.format(self.fullname)
|
||||
@@ -44,6 +45,7 @@ class PyHKey(object):
|
||||
raise WindowsError("Could not open registry key <{0}>".format(self.fullname))
|
||||
return self._phkey
|
||||
|
||||
|
||||
@property
|
||||
def subkeys(self):
|
||||
"""The subkeys of the registry key
|
||||
@@ -66,6 +68,14 @@ class PyHKey(object):
|
||||
res.append(_winreg.EnumValue(self.phkey, i))
|
||||
return [KeyValue(*r) for r in res]
|
||||
|
||||
@property
|
||||
def info(self):
|
||||
return _winreg.QueryInfoKey(self.phkey)
|
||||
|
||||
@property
|
||||
def last_write(self):
|
||||
return self.info[2]
|
||||
|
||||
def get(self, value_name):
|
||||
"""Retrieves the value ``value_name``
|
||||
|
||||
@@ -74,17 +84,43 @@ class PyHKey(object):
|
||||
data = _winreg.QueryValueEx(self.phkey, value_name)
|
||||
return KeyValue(value_name, data[0], data[1])
|
||||
|
||||
def open_subkey(self, name):
|
||||
def _guess_value_type(self, value):
|
||||
if isinstance(value, basestring):
|
||||
return _winreg.REG_SZ
|
||||
elif isinstance(value, [int, long]):
|
||||
return _winreg.REG_DWORD
|
||||
raise ValueError("Cannot guest registry type of value to set <{0}>".format(value))
|
||||
|
||||
|
||||
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)
|
||||
|
||||
|
||||
def open_subkey(self, name, sam=None):
|
||||
"""Open the subkey ``name``
|
||||
|
||||
:rtype: :class:`PyHKey`
|
||||
"""
|
||||
return PyHKey(self, name, self.sam)
|
||||
if sam is None:
|
||||
sam = self.sam
|
||||
return PyHKey(self, name, sam)
|
||||
|
||||
def reopen(self, new_sam):
|
||||
return PyHKey(self.surkey, self.name, new_sam)
|
||||
|
||||
__getitem__ = open_subkey
|
||||
|
||||
def __setitem__(self, name, value):
|
||||
rtype = None
|
||||
if not isinstance(value, (int, long, basestring)):
|
||||
value, rtype = value
|
||||
return self.set(name, value, rtype)
|
||||
|
||||
__getitem__ = get
|
||||
|
||||
__call__ = open_subkey
|
||||
|
||||
|
||||
class DummyPHKEY(object):
|
||||
@@ -113,7 +149,7 @@ class Registry(object):
|
||||
"HKEY_USERS" : HKEY_USERS
|
||||
}
|
||||
|
||||
def __getitem__(self, name):
|
||||
def __call__(self, name, sam=KEY_READ):
|
||||
"""Get a registry key::
|
||||
|
||||
registry[r"HKEY_LOCAL_MACHINE\\Software"]
|
||||
@@ -123,10 +159,13 @@ class Registry(object):
|
||||
"""
|
||||
|
||||
if name in self.registry_base_keys:
|
||||
return self.registry_base_keys[name]
|
||||
key = self.registry_base_keys[name]
|
||||
if sam != key.sam:
|
||||
key = key.reopen(sam)
|
||||
return key
|
||||
if "\\" not in name:
|
||||
raise ValueError("Unknow registry base key <{0}>".format(name))
|
||||
base_name, subkey = name.split("\\", 1)
|
||||
if base_name not in self.registry_base_keys:
|
||||
raise ValueError("Unknow registry base key <{0}>".format(base_name))
|
||||
return self.registry_base_keys[base_name][subkey]
|
||||
return self.registry_base_keys[base_name](subkey, sam)
|
||||
@@ -0,0 +1,116 @@
|
||||
import ctypes
|
||||
import windows
|
||||
|
||||
from collections import namedtuple
|
||||
|
||||
from windows import utils
|
||||
from windows.generated_def import *
|
||||
|
||||
|
||||
SERVICE_TYPE = {x:x for x in [SERVICE_KERNEL_DRIVER, SERVICE_FILE_SYSTEM_DRIVER, SERVICE_WIN32_OWN_PROCESS, SERVICE_WIN32_SHARE_PROCESS, SERVICE_INTERACTIVE_PROCESS]}
|
||||
SERVICE_STATE = {x:x for x in [SERVICE_STOPPED, SERVICE_START_PENDING, SERVICE_STOP_PENDING, SERVICE_RUNNING, SERVICE_CONTINUE_PENDING, SERVICE_PAUSE_PENDING, SERVICE_PAUSED]}
|
||||
SERVICE_CONTROLE_ACCEPTED = {x:x for x in []}
|
||||
SERVICE_FLAGS = {x:x for x in [SERVICE_RUNS_IN_SYSTEM_PROCESS]}
|
||||
|
||||
|
||||
ServiceStatus = namedtuple("ServiceStatus", ["type", "state", "control_accepted", "flags"])
|
||||
"""
|
||||
``type`` might be one of:
|
||||
|
||||
* ``SERVICE_KERNEL_DRIVER(0x1L)``
|
||||
* ``SERVICE_FILE_SYSTEM_DRIVER(0x2L)``
|
||||
* ``SERVICE_WIN32_OWN_PROCESS(0x10L)``
|
||||
* ``SERVICE_WIN32_SHARE_PROCESS(0x20L)``
|
||||
* ``SERVICE_INTERACTIVE_PROCESS(0x100L)``
|
||||
|
||||
``state`` might be one of:
|
||||
|
||||
* ``SERVICE_STOPPED(0x1L)``
|
||||
* ``SERVICE_START_PENDING(0x2L)``
|
||||
* ``SERVICE_STOP_PENDING(0x3L)``
|
||||
* ``SERVICE_RUNNING(0x4L)``
|
||||
* ``SERVICE_CONTINUE_PENDING(0x5L)``
|
||||
* ``SERVICE_PAUSE_PENDING(0x6L)``
|
||||
* ``SERVICE_PAUSED(0x7L)``
|
||||
|
||||
``flags`` might be one of:
|
||||
|
||||
* ``0``
|
||||
* ``SERVICE_RUNS_IN_SYSTEM_PROCESS(0x1L)``
|
||||
|
||||
"""
|
||||
|
||||
class Service(object):
|
||||
def __repr__(self):
|
||||
return '<{0} "{1}">'.format(type(self).__name__, self.name)
|
||||
|
||||
@utils.fixedpropety
|
||||
def name(self):
|
||||
"""The name of the service
|
||||
|
||||
:type: :class:`str`
|
||||
"""
|
||||
return self.lpServiceName
|
||||
|
||||
@utils.fixedpropety
|
||||
def description(self):
|
||||
"""The description of the service
|
||||
|
||||
:type: :class:`str`
|
||||
"""
|
||||
return self.lpDisplayName
|
||||
|
||||
@utils.fixedpropety
|
||||
def status(self):
|
||||
"""The status of the service
|
||||
|
||||
:type: :class:`ServiceStatus`
|
||||
"""
|
||||
status = self.ServiceStatusProcess
|
||||
stype = SERVICE_TYPE.get(status.dwServiceType, status.dwServiceType)
|
||||
sstate = SERVICE_STATE.get(status.dwCurrentState, status.dwCurrentState)
|
||||
scontrol = status.dwControlsAccepted
|
||||
sflags = SERVICE_FLAGS.get(status.dwServiceFlags, status.dwServiceFlags)
|
||||
return ServiceStatus(stype, sstate, scontrol, sflags)
|
||||
|
||||
@utils.fixedpropety
|
||||
def process(self):
|
||||
"""The process running the service (if any)
|
||||
|
||||
:type: :class:`WinProcess <windows.winobject.process.WinProcess>` or ``None``
|
||||
"""
|
||||
pid = self.ServiceStatusProcess.dwProcessId
|
||||
if not pid:
|
||||
return None
|
||||
l = [p for p in windows.system.processes if p.pid == pid]
|
||||
if not l:
|
||||
return None # Other thing ?
|
||||
return l[0]
|
||||
|
||||
|
||||
class ServiceA(Service, ENUM_SERVICE_STATUS_PROCESSA):
|
||||
"""A Service object with ascii data"""
|
||||
pass
|
||||
|
||||
def enumerate_services():
|
||||
scmanager = windows.winproxy.OpenSCManagerA(dwDesiredAccess=SC_MANAGER_ENUMERATE_SERVICE)
|
||||
|
||||
size_needed = DWORD()
|
||||
nb_services = DWORD()
|
||||
counter = DWORD()
|
||||
try:
|
||||
windows.winproxy.EnumServicesStatusExA(scmanager, SC_ENUM_PROCESS_INFO, SERVICE_TYPE_ALL, SERVICE_ACTIVE, None, 0, ctypes.byref(size_needed), ctypes.byref(nb_services), byref(counter), None)
|
||||
except WindowsError:
|
||||
pass
|
||||
|
||||
while True:
|
||||
size = size_needed.value
|
||||
buffer = (ctypes.c_byte * size)()
|
||||
|
||||
try:
|
||||
windows.winproxy.EnumServicesStatusExA(scmanager, SC_ENUM_PROCESS_INFO, SERVICE_TYPE_ALL, SERVICE_ACTIVE, buffer, size, ctypes.byref(size_needed), ctypes.byref(nb_services), byref(counter), None)
|
||||
except WindowsError as e:
|
||||
continue
|
||||
|
||||
return_type = (ServiceA * nb_services.value)
|
||||
return list(return_type.from_buffer(buffer))
|
||||
@@ -0,0 +1,241 @@
|
||||
import os
|
||||
import ctypes
|
||||
import copy
|
||||
import struct
|
||||
|
||||
import windows
|
||||
from windows import winproxy
|
||||
from windows import utils
|
||||
from windows.generated_def import windef
|
||||
|
||||
from windows.winobject import process
|
||||
from windows.winobject import network
|
||||
from windows.winobject import registry
|
||||
from windows.winobject import exception
|
||||
from windows.winobject import service
|
||||
from windows.winobject import volume
|
||||
from windows.winobject import wmi
|
||||
from windows.winobject import kernobj
|
||||
|
||||
from windows.generated_def.winstructs import *
|
||||
|
||||
class System(object):
|
||||
"""The state of the current ``Windows`` system ``Python`` is running on"""
|
||||
|
||||
network = network.Network()
|
||||
"""Object of class :class:`windows.winobject.network.Network`"""
|
||||
registry = registry.Registry()
|
||||
"""Object of class :class:`windows.winobject.registry.Registry`"""
|
||||
|
||||
@property
|
||||
def processes(self):
|
||||
"""The list of running processes
|
||||
|
||||
:type: [:class:`process.WinProcess`] -- A list of Process
|
||||
"""
|
||||
return self.enumerate_processes()
|
||||
|
||||
@property
|
||||
def threads(self):
|
||||
"""The list of running threads
|
||||
|
||||
:type: [:class:`process.WinThread`] -- A list of Thread
|
||||
"""
|
||||
return self.enumerate_threads()
|
||||
|
||||
@property
|
||||
def logicaldrives(self):
|
||||
"""List of logical drives [C:\, ...]
|
||||
|
||||
:type: [:class:`volume.LogicalDrive`] -- A list of LogicalDrive
|
||||
"""
|
||||
return volume.enum_logical_drive()
|
||||
|
||||
@property
|
||||
def services(self):
|
||||
"""The list of services
|
||||
|
||||
:type: [:class:`service.ServiceA`] -- A list of Service"""
|
||||
return service.enumerate_services()
|
||||
|
||||
#@property
|
||||
#def handles(self):
|
||||
# size_needed = ULONG()
|
||||
# size = 0x1000
|
||||
# buffer = ctypes.c_buffer(size)
|
||||
#
|
||||
# try:
|
||||
# winproxy.NtQuerySystemInformation(16, buffer, size, ReturnLength=ctypes.byref(size_needed))
|
||||
# except WindowsError as e:
|
||||
# pass
|
||||
#
|
||||
# size = size_needed.value + 0x1000
|
||||
# buffer = ctypes.c_buffer(size)
|
||||
# winproxy.NtQuerySystemInformation(16, buffer, size, ReturnLength=ctypes.byref(size_needed))
|
||||
#
|
||||
# x = SYSTEM_HANDLE_INFORMATION.from_buffer(buffer)
|
||||
#
|
||||
# class _GENERATED_SYSTEM_HANDLE_INFORMATION(ctypes.Structure):
|
||||
# _fields_ = [
|
||||
# ("HandleCount", ULONG),
|
||||
# ("Handles", SYSTEM_HANDLE * x.HandleCount),
|
||||
# ]
|
||||
# return _GENERATED_SYSTEM_HANDLE_INFORMATION.from_buffer_copy(buffer[:size_needed.value]).Handles[:]
|
||||
|
||||
@utils.fixedpropety
|
||||
def bitness(self):
|
||||
"""The bitness of the system
|
||||
|
||||
:type: :class:`int` -- 32 or 64
|
||||
"""
|
||||
if os.environ["PROCESSOR_ARCHITECTURE"].lower() != "x86":
|
||||
return 64
|
||||
if "PROCESSOR_ARCHITEW6432" in os.environ:
|
||||
return 64
|
||||
return 32
|
||||
|
||||
@utils.fixedpropety
|
||||
def wmi(self):
|
||||
r"""An object to perform wmi request to "root\\cimv2"
|
||||
|
||||
:type: :class:`windows.winobject.wmi.WmiRequester`"""
|
||||
return wmi.WmiRequester()
|
||||
|
||||
#TODO: use GetComputerNameExA ? and recover other names ?
|
||||
@utils.fixedpropety
|
||||
def computer_name(self):
|
||||
"""The name of the computer
|
||||
|
||||
:type: :class:`str`
|
||||
"""
|
||||
size = DWORD(0x1000)
|
||||
buf = ctypes.c_buffer(size.value)
|
||||
winproxy.GetComputerNameA(buf, ctypes.byref(size))
|
||||
return buf[:size.value]
|
||||
|
||||
@utils.fixedpropety
|
||||
def version(self):
|
||||
"""The version of the system
|
||||
|
||||
:type: (:class:`int`, :class:`int`) -- (Major, Minor)
|
||||
"""
|
||||
data = self.get_version()
|
||||
result = data.dwMajorVersion, data.dwMinorVersion
|
||||
if result == (6,2):
|
||||
result_str = self.get_file_version("kernel32")
|
||||
result_tup = [int(x) for x in result_str.split(".")]
|
||||
result = tuple(result_tup[:2])
|
||||
return result
|
||||
|
||||
@utils.fixedpropety
|
||||
def version_name(self):
|
||||
"""The name of the system version, values are:
|
||||
|
||||
* Windows Server 2016
|
||||
* Windows 10
|
||||
* Windows Server 2012 R2
|
||||
* Windows 8.1
|
||||
* Windows Server 2012
|
||||
* Windows 8
|
||||
* Windows Server 2008
|
||||
* Windows 7
|
||||
* Windows Server 2008
|
||||
* Windows Vista
|
||||
* Windows XP Professional x64 Edition
|
||||
* TODO: version (5.2) + is_workstation + bitness == 32 (don't even know if possible..)
|
||||
* Windows Server 2003 R2
|
||||
* Windows Server 2003
|
||||
* Windows XP
|
||||
* Windows 2000
|
||||
* "Unknow Windows <version={0} | is_workstation={1}>".format(version, is_workstation)
|
||||
|
||||
:type: :class:`str`
|
||||
"""
|
||||
version = self.version
|
||||
is_workstation = self.product_type == VER_NT_WORKSTATION
|
||||
if version == (10, 0):
|
||||
return ["Windows Server 2016, ""Windows 10"][is_workstation]
|
||||
elif version == (6, 3):
|
||||
return ["Windows Server 2012 R2", "Windows 8.1"][is_workstation]
|
||||
elif version == (6, 2):
|
||||
return ["Windows Server 2012", "Windows 8"][is_workstation]
|
||||
elif version == (6, 1):
|
||||
return ["Windows Server 2008 R2", "Windows 7"][is_workstation]
|
||||
elif version == (6, 0):
|
||||
return ["Windows Server 2008", "Windows Vista"][is_workstation]
|
||||
elif version == (5, 2):
|
||||
metric = winproxy.GetSystemMetrics(SM_SERVERR2)
|
||||
if is_workstation:
|
||||
if self.bitness == 64:
|
||||
return "Windows XP Professional x64 Edition"
|
||||
else:
|
||||
return "TODO: version (5.2) + is_workstation + bitness == 32"
|
||||
elif metric != 0:
|
||||
return "Windows Server 2003 R2"
|
||||
else:
|
||||
return "Windows Server 2003"
|
||||
elif version == (5, 1):
|
||||
return "Windows XP"
|
||||
elif version == (5, 0):
|
||||
return "Windows 2000"
|
||||
else:
|
||||
return "Unknow Windows <version={0} | is_workstation={1}>".format(version, is_workstation)
|
||||
|
||||
@utils.fixedpropety
|
||||
def product_type(self):
|
||||
"""The product type, value might be:
|
||||
|
||||
* VER_NT_WORKSTATION(0x1L)
|
||||
* VER_NT_DOMAIN_CONTROLLER(0x2L)
|
||||
* VER_NT_SERVER(0x3L)
|
||||
|
||||
:type: :class:`long` or :class:`int` (or subclass)
|
||||
"""
|
||||
version_map = {x:x for x in [VER_NT_WORKSTATION, VER_NT_DOMAIN_CONTROLLER, VER_NT_SERVER]}
|
||||
version = self.get_version()
|
||||
return version_map.get(version.wProductType, version.wProductType)
|
||||
|
||||
def get_version(self):
|
||||
data = windows.generated_def.OSVERSIONINFOEXA()
|
||||
data.dwOSVersionInfoSize = ctypes.sizeof(data)
|
||||
winproxy.GetVersionExA(ctypes.cast(ctypes.pointer(data), ctypes.POINTER(windows.generated_def.OSVERSIONINFOA)))
|
||||
return data
|
||||
|
||||
def get_file_version(self, name):
|
||||
size = winproxy.GetFileVersionInfoSizeA(name)
|
||||
buf = ctypes.c_buffer(size)
|
||||
winproxy.GetFileVersionInfoA(name, 0, size, buf)
|
||||
|
||||
bufptr = PVOID()
|
||||
bufsize = UINT()
|
||||
winproxy.VerQueryValueA(buf, "\\VarFileInfo\\Translation", ctypes.byref(bufptr), ctypes.byref(bufsize))
|
||||
bufstr = ctypes.cast(bufptr, LPCSTR)
|
||||
tup = struct.unpack("<HH", bufstr.value[:4])
|
||||
req = "{0:04x}{1:04x}".format(*tup)
|
||||
winproxy.VerQueryValueA(buf, "\\StringFileInfo\\{0}\\ProductVersion".format(req), ctypes.byref(bufptr), ctypes.byref(bufsize))
|
||||
bufstr = ctypes.cast(bufptr, LPCSTR)
|
||||
return bufstr.value
|
||||
|
||||
@staticmethod
|
||||
def enumerate_processes():
|
||||
process_entry = PROCESSENTRY32()
|
||||
process_entry.dwSize = ctypes.sizeof(process_entry)
|
||||
snap = winproxy.CreateToolhelp32Snapshot(windef.TH32CS_SNAPPROCESS, 0)
|
||||
winproxy.Process32First(snap, process_entry)
|
||||
res = []
|
||||
res.append(process.WinProcess._from_PROCESSENTRY32(process_entry))
|
||||
while winproxy.Process32Next(snap, process_entry):
|
||||
res.append(process.WinProcess._from_PROCESSENTRY32(process_entry))
|
||||
return res
|
||||
|
||||
@staticmethod
|
||||
def enumerate_threads():
|
||||
thread_entry = process.WinThread()
|
||||
thread_entry.dwSize = ctypes.sizeof(thread_entry)
|
||||
snap = winproxy.CreateToolhelp32Snapshot(windef.TH32CS_SNAPTHREAD, 0)
|
||||
threads = []
|
||||
winproxy.Thread32First(snap, thread_entry)
|
||||
threads.append(copy.copy(thread_entry))
|
||||
while winproxy.Thread32Next(snap, thread_entry):
|
||||
threads.append(copy.copy(thread_entry))
|
||||
return threads
|
||||
@@ -0,0 +1,71 @@
|
||||
import ctypes
|
||||
|
||||
import windows
|
||||
from windows import winproxy
|
||||
from windows.generated_def.winstructs import *
|
||||
|
||||
|
||||
|
||||
|
||||
class LogicalDrive(object):
|
||||
DRIVE_TYPE = {x:x for x in [DRIVE_UNKNOWN, DRIVE_NO_ROOT_DIR, DRIVE_REMOVABLE,
|
||||
DRIVE_FIXED, DRIVE_REMOTE, DRIVE_CDROM, DRIVE_RAMDISK]}
|
||||
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
|
||||
@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):
|
||||
"""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)
|
||||
|
||||
|
||||
|
||||
def enum_logical_drive():
|
||||
return [LogicalDrive(name) for name in get_logical_drive_names()]
|
||||
|
||||
def get_logical_drive_names():
|
||||
size = 0x100
|
||||
buffer = ctypes.c_buffer(size)
|
||||
rsize = winproxy.GetLogicalDriveStringsA(0x1000, buffer)
|
||||
return buffer[:rsize].rstrip("\x00").split("\x00")
|
||||
|
||||
def get_info(drivename):
|
||||
size = 0x1000
|
||||
volume_name = ctypes.c_buffer(size)
|
||||
fs_name = ctypes.c_buffer(size)
|
||||
flags = DWORD()
|
||||
winproxy.GetVolumeInformationA(drivename, volume_name, size, None, None, ctypes.byref(flags), fs_name, size)
|
||||
raise NotImplementedError("get_info")
|
||||
|
||||
def query_dos_device(name):
|
||||
size = 0x1000
|
||||
buffer = ctypes.c_buffer(size)
|
||||
rsize = winproxy.QueryDosDeviceA(name, buffer, size)
|
||||
return buffer[:rsize].rstrip("\x00").split("\x00")
|
||||
@@ -0,0 +1,51 @@
|
||||
import ctypes
|
||||
|
||||
import windows
|
||||
from windows.generated_def import *
|
||||
|
||||
|
||||
|
||||
callback_type = ctypes.WINFUNCTYPE(UINT, HWND, LPARAM)
|
||||
|
||||
class Window(object):
|
||||
def __init__(self, handle):
|
||||
self.handle = handle
|
||||
|
||||
def name(self):
|
||||
size = 0x1024
|
||||
buffer = ctypes.c_buffer(size)
|
||||
|
||||
res = windows.winproxy.GetWindowTextA(self.handle, buffer, size)
|
||||
return buffer[:res]
|
||||
|
||||
# I don't understand the interest:
|
||||
# Either return "" or C:\Python27\python.exe
|
||||
#def module(self):
|
||||
# size = 0x1024
|
||||
# buffer = ctypes.c_buffer(size)
|
||||
# res = windows.winproxy.GetWindowModuleFileNameA(self.handle, buffer, size)
|
||||
# return buffer[:res]
|
||||
|
||||
|
||||
def enumwindows():
|
||||
result = []
|
||||
def callback(handle, param):
|
||||
result.append(handle)
|
||||
return True
|
||||
|
||||
try:
|
||||
x = windows.winproxy.EnumWindows(callback_type(callback), 0)
|
||||
except WindowsError:
|
||||
if not result:
|
||||
raise
|
||||
return result
|
||||
|
||||
|
||||
v = enumwindows()
|
||||
|
||||
for i in v:
|
||||
w = Window(i)
|
||||
if w.name():
|
||||
print("{0} -> {1} ".format(i, w.name()))
|
||||
|
||||
raise "YOLO"
|
||||
@@ -0,0 +1,88 @@
|
||||
import windows
|
||||
import ctypes
|
||||
import struct
|
||||
import functools
|
||||
|
||||
from ctypes.wintypes import *
|
||||
|
||||
import windows.com
|
||||
from windows.generated_def.winstructs import *
|
||||
from windows.generated_def.interfaces import IWbemLocator, IWbemServices, IEnumWbemClassObject, IWbemClassObject
|
||||
|
||||
|
||||
class WmiRequester(object):
|
||||
r"""An object to perform wmi request to ``root\cimv2``"""
|
||||
INSTANCE = None
|
||||
|
||||
def __new__(cls):
|
||||
if cls.INSTANCE is not None:
|
||||
return cls.INSTANCE
|
||||
cls.INSTANCE = super(cls, cls).__new__(cls)
|
||||
return cls.INSTANCE
|
||||
|
||||
def __init__(self):
|
||||
locator = IWbemLocator()
|
||||
service = IWbemServices()
|
||||
CLSID_WbemAdministrativeLocator_IID = windows.com.IID.from_string('CB8555CC-9128-11D1-AD9B-00C04FD8FDFF')
|
||||
|
||||
windows.com.init()
|
||||
windows.com.create_instance(CLSID_WbemAdministrativeLocator_IID, locator)
|
||||
locator.ConnectServer("root\\cimv2", None, None , None, 0x80, None, None, ctypes.byref(service))
|
||||
self.service = service
|
||||
|
||||
def select(self, frm, attrs="*"):
|
||||
"""Select ``attrs`` from ``frm``
|
||||
|
||||
:rtype: list of dict
|
||||
"""
|
||||
enumerator = IEnumWbemClassObject()
|
||||
try:
|
||||
self.service.ExecQuery("WQL", "select * from {0}".format(frm), 0x20, 0, ctypes.byref(enumerator))
|
||||
except WindowsError as e:
|
||||
if (e.winerror & 0xffffffff) == WBEM_E_INVALID_CLASS:
|
||||
raise WindowsError(e.winerror, 'WBEM_E_INVALID_CLASS <Invalid WMI class "{0}">'.format(frm))
|
||||
elif (e.winerror & 0xffffffff) in WBEMSTATUS.values:
|
||||
raise WindowsError(e.winerror, WBEMSTATUS(e.winerror & 0xffffffff).value)
|
||||
raise
|
||||
|
||||
count = ctypes.c_ulong(0)
|
||||
processor = IWbemClassObject()
|
||||
res = []
|
||||
enumerator.Next(0xffffffff, 1, ctypes.byref(processor), ctypes.byref(count))
|
||||
while count.value:
|
||||
current_res = {}
|
||||
variant_res = windows.com.ImprovedVariant()
|
||||
if attrs == "*":
|
||||
attrs = [x for x in self.get_names(processor) if not x.startswith("__")]
|
||||
for name in attrs:
|
||||
processor.Get(name, 0, ctypes.byref(variant_res), None, None)
|
||||
# TODO: something clean and generic
|
||||
if variant_res.vt & VT_ARRAY:
|
||||
if variant_res.vt & VT_TYPEMASK == VT_BSTR:
|
||||
current_res[name] = variant_res.asarray.to_list(BSTR)
|
||||
if variant_res.vt & VT_TYPEMASK == VT_I4:
|
||||
current_res[name] = variant_res.asarray.to_list(LONG)
|
||||
elif variant_res.vt in [VT_EMPTY, VT_NULL]:
|
||||
current_res[name] = None
|
||||
elif variant_res.vt == VT_BSTR:
|
||||
current_res[name] = variant_res.asbstr
|
||||
elif variant_res.vt == VT_I4:
|
||||
current_res[name] = variant_res.aslong
|
||||
elif variant_res.vt == VT_BOOL:
|
||||
current_res[name] = variant_res.asbool
|
||||
elif variant_res.vt == VT_I2:
|
||||
current_res[name] = variant_res.asshort
|
||||
elif variant_res.vt == VT_UI1:
|
||||
current_res[name] = variant_res.asbyte
|
||||
else:
|
||||
print("[WARN] WMI Ignore variant of type {0}".format(hex(variant_res.vt)))
|
||||
res.append(current_res)
|
||||
enumerator.Next(0xffffffff, 1, ctypes.byref(processor), ctypes.byref(count))
|
||||
return res
|
||||
|
||||
def get_names(self, processor):
|
||||
res = POINTER(SAFEARRAY)()
|
||||
processor.GetNames(None, 0, None, byref(res))
|
||||
safe_array = ctypes.cast(res, POINTER(windows.com.ImprovedSAFEARRAY))[0]
|
||||
safe_array.elt_type = BSTR
|
||||
return safe_array.to_list()
|
||||
+431
-25
@@ -136,6 +136,7 @@ class ApiProxy(object):
|
||||
return self._cprototyped(*args)
|
||||
|
||||
setattr(python_proxy, "ctypes_function", perform_call)
|
||||
setattr(python_proxy, "force_resolution", generate_ctypes_function)
|
||||
return python_proxy
|
||||
|
||||
|
||||
@@ -153,7 +154,6 @@ class IphlpapiProxy(ApiProxy):
|
||||
APIDLL = "iphlpapi"
|
||||
default_error_check = staticmethod(iphlpapi_error_check)
|
||||
|
||||
|
||||
class NtdllProxy(ApiProxy):
|
||||
APIDLL = "ntdll"
|
||||
default_error_check = staticmethod(kernel32_zero_check)
|
||||
@@ -162,7 +162,21 @@ class WinTrustProxy(ApiProxy):
|
||||
APIDLL = "wintrust"
|
||||
default_error_check = staticmethod(no_error_check)
|
||||
|
||||
class Ole32Proxy(ApiProxy):
|
||||
APIDLL = "ole32"
|
||||
default_error_check = staticmethod(no_error_check)
|
||||
|
||||
class PsapiProxy(ApiProxy):
|
||||
APIDLL = "psapi"
|
||||
default_error_check = staticmethod(kernel32_error_check)
|
||||
|
||||
class User32Proxy(ApiProxy):
|
||||
APIDLL = "user32"
|
||||
default_error_check = staticmethod(kernel32_error_check)
|
||||
|
||||
class VersionProxy(ApiProxy):
|
||||
APIDLL = "version"
|
||||
default_error_check = staticmethod(kernel32_error_check)
|
||||
|
||||
class OptionalExport(object):
|
||||
"""used 'around' a Proxy decorator
|
||||
@@ -179,7 +193,9 @@ class OptionalExport(object):
|
||||
|
||||
def __call__(self, f):
|
||||
try:
|
||||
return self.subdecorator(f)
|
||||
x = self.subdecorator(f)
|
||||
x.force_resolution()
|
||||
return x
|
||||
except ExportNotFound as e:
|
||||
dbgprint("Export <{e.func_name}> not found in <{e.api_name}>".format(e=e), "EXPORTNOTFOUND")
|
||||
return None
|
||||
@@ -192,20 +208,26 @@ class TransparentApiProxy(object):
|
||||
self._ctypes_function = None
|
||||
|
||||
self.prototype = getattr(winfuncs, func_name + "Prototype")
|
||||
# TODO: fix double name..
|
||||
self.params = getattr(winfuncs, func_name + "Params")
|
||||
self.args = getattr(winfuncs, func_name + "Params")
|
||||
|
||||
def __call__(self, *args, **kwargs):
|
||||
if self._ctypes_function is None:
|
||||
try:
|
||||
c_prototyped = self.prototype((self.func_name, getattr(ctypes.windll, self.dll_name)), self.args)
|
||||
except AttributeError:
|
||||
raise ExportNotFound(func_name, APIDLL)
|
||||
c_prototyped.errcheck = functools.wraps(self.error_check)(functools.partial(self.error_check, self.func_name))
|
||||
self._ctypes_function = c_prototyped
|
||||
self.force_resolution()
|
||||
return self._ctypes_function(*args, **kwargs)
|
||||
|
||||
def force_resolution(self):
|
||||
try:
|
||||
c_prototyped = self.prototype((self.func_name, getattr(ctypes.windll, self.dll_name)), self.args)
|
||||
except AttributeError:
|
||||
raise ExportNotFound(self.func_name, self.dll_name)
|
||||
c_prototyped.errcheck = functools.wraps(self.error_check)(functools.partial(self.error_check, self.func_name))
|
||||
self._ctypes_function = c_prototyped
|
||||
|
||||
|
||||
TransparentKernel32Proxy = lambda func_name, error_check=kernel32_error_check: TransparentApiProxy("kernel32", func_name, error_check)
|
||||
TransparentUser32Proxy = lambda func_name, error_check=kernel32_error_check: TransparentApiProxy("user32", func_name, error_check)
|
||||
TransparentAdvapi32Proxy = lambda func_name, error_check=kernel32_error_check: TransparentApiProxy("advapi32", func_name, error_check)
|
||||
TransparentIphlpapiProxy = lambda func_name, error_check=iphlpapi_error_check: TransparentApiProxy("iphlpapi", func_name, error_check)
|
||||
|
||||
@@ -245,6 +267,15 @@ GetThreadId = TransparentKernel32Proxy("GetThreadId")
|
||||
VirtualQueryEx = TransparentKernel32Proxy("VirtualQueryEx")
|
||||
GetExitCodeThread = TransparentKernel32Proxy("GetExitCodeThread")
|
||||
GetExitCodeProcess = TransparentKernel32Proxy("GetExitCodeProcess")
|
||||
GetProcessId = TransparentKernel32Proxy("GetProcessId")
|
||||
lstrcmpA = TransparentKernel32Proxy("lstrcmpA")
|
||||
lstrcmpW = TransparentKernel32Proxy("lstrcmpW")
|
||||
GetVersionExA = TransparentKernel32Proxy("GetVersionExA")
|
||||
GetVersionExW = TransparentKernel32Proxy("GetVersionExW")
|
||||
GetComputerNameA = TransparentKernel32Proxy("GetComputerNameA")
|
||||
GetComputerNameW = TransparentKernel32Proxy("GetComputerNameW")
|
||||
|
||||
|
||||
|
||||
Wow64DisableWow64FsRedirection = OptionalExport(TransparentKernel32Proxy)("Wow64DisableWow64FsRedirection")
|
||||
Wow64RevertWow64FsRedirection = OptionalExport(TransparentKernel32Proxy)("Wow64RevertWow64FsRedirection")
|
||||
@@ -252,12 +283,19 @@ Wow64EnableWow64FsRedirection = OptionalExport(TransparentKernel32Proxy)("Wow64E
|
||||
Wow64GetThreadContext = OptionalExport(TransparentKernel32Proxy)("Wow64GetThreadContext")
|
||||
|
||||
|
||||
@Kernel32Proxy("CreateFileA")
|
||||
def CreateFile_error_check(func_name, result, func, args):
|
||||
"""raise Kernel32Error if result is NOT 0"""
|
||||
if result == INVALID_HANDLE_VALUE:
|
||||
raise Kernel32Error(func_name)
|
||||
return args
|
||||
|
||||
|
||||
@Kernel32Proxy("CreateFileA", error_check=CreateFile_error_check)
|
||||
def CreateFileA(lpFileName, dwDesiredAccess=GENERIC_READ, dwShareMode=0, lpSecurityAttributes=None, dwCreationDisposition=OPEN_EXISTING, dwFlagsAndAttributes=FILE_ATTRIBUTE_NORMAL, hTemplateFile=None):
|
||||
return CreateFileA.ctypes_function(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile)
|
||||
|
||||
|
||||
@Kernel32Proxy("CreateFileW")
|
||||
@Kernel32Proxy("CreateFileW", error_check=CreateFile_error_check)
|
||||
def CreateFileW(lpFileName, dwDesiredAccess=GENERIC_READ, dwShareMode=0, lpSecurityAttributes=None, dwCreationDisposition=OPEN_EXISTING, dwFlagsAndAttributes=FILE_ATTRIBUTE_NORMAL, hTemplateFile=None):
|
||||
return CreateFileA.ctypes_function(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile)
|
||||
|
||||
@@ -294,10 +332,18 @@ def CreateRemoteThread(hProcess=NeededParameter, lpThreadAttributes=None, dwStac
|
||||
|
||||
|
||||
@Kernel32Proxy("VirtualProtect")
|
||||
def VirtualProtect(lpAddress, dwSize, flNewProtect, lpflOldProtect=0):
|
||||
def VirtualProtect(lpAddress, dwSize, flNewProtect, lpflOldProtect=None):
|
||||
if lpflOldProtect is None:
|
||||
lpflOldProtect = ctypes.byref(DWORD())
|
||||
return VirtualProtect.ctypes_function(lpAddress, dwSize, flNewProtect, lpflOldProtect)
|
||||
|
||||
|
||||
@Kernel32Proxy("VirtualProtectEx")
|
||||
def VirtualProtectEx(hProcess, lpAddress, dwSize, flNewProtect, lpflOldProtect=None):
|
||||
if lpflOldProtect is None:
|
||||
lpflOldProtect = ctypes.byref(DWORD())
|
||||
return VirtualProtectEx.ctypes_function(hProcess, lpAddress, dwSize, flNewProtect, lpflOldProtect)
|
||||
|
||||
@Kernel32Proxy("CreateProcessA")
|
||||
def CreateProcessA(lpApplicationName, lpCommandLine=None, lpProcessAttributes=None, lpThreadAttributes=None, bInheritHandles=False,
|
||||
dwCreationFlags=0, lpEnvironment=None, lpCurrentDirectory=None, lpStartupInfo=None, lpProcessInformation=None):
|
||||
@@ -337,11 +383,12 @@ def GetThreadContext(hThread, lpContext=None):
|
||||
|
||||
@Kernel32Proxy("SetThreadContext")
|
||||
def SetThreadContext(hThread, lpContext):
|
||||
""" Allows to directly pass a CONTEXT and will call with byref(CONTEXT) by itself"""
|
||||
if type(lpContext) == CONTEXT:
|
||||
lpContext = ctypes.byref(lpContext)
|
||||
return SetThreadContext.ctypes_function(hThread, lpContext)
|
||||
|
||||
@Kernel32Proxy("Wow64SetThreadContext")
|
||||
def Wow64SetThreadContext(hThread, lpContext):
|
||||
return Wow64SetThreadContext.ctypes_function(hThread, lpContext)
|
||||
|
||||
|
||||
@Kernel32Proxy("OpenThread")
|
||||
def OpenThread(dwDesiredAccess=THREAD_ALL_ACCESS, bInheritHandle=0, dwThreadId=NeededParameter):
|
||||
@@ -366,6 +413,10 @@ def WriteProcessMemory(hProcess, lpBaseAddress, lpBuffer, nSize=None, lpNumberOf
|
||||
return WriteProcessMemory.ctypes_function(hProcess, lpBaseAddress, lpBuffer, nSize, lpNumberOfBytesWritten)
|
||||
|
||||
|
||||
@Kernel32Proxy("GetProcessTimes")
|
||||
def GetProcessTimes(hProcess, lpCreationTime, lpExitTime, lpKernelTime, lpUserTime):
|
||||
return GetProcessTimes.ctypes_function(hProcess, lpCreationTime, lpExitTime, lpKernelTime, lpUserTime)
|
||||
|
||||
@Kernel32Proxy('SetThreadAffinityMask')
|
||||
def SetThreadAffinityMask(hThread=None, dwThreadAffinityMask=NeededParameter):
|
||||
"""If hThread is not given, it will be the current thread"""
|
||||
@@ -379,7 +430,7 @@ def CreateToolhelp32Snapshot(dwFlags, th32ProcessID=0):
|
||||
return CreateToolhelp32Snapshot.ctypes_function(dwFlags, th32ProcessID)
|
||||
|
||||
|
||||
@Kernel32Proxy("Thread32First", no_error_check)
|
||||
@Kernel32Proxy("Thread32First")
|
||||
def Thread32First(hSnapshot, lpte):
|
||||
"""Set byref(lpte) if needed"""
|
||||
if type(lpte) == THREADENTRY32:
|
||||
@@ -395,21 +446,22 @@ def Thread32Next(hSnapshot, lpte):
|
||||
return Thread32Next.ctypes_function(hSnapshot, lpte)
|
||||
|
||||
|
||||
@Kernel32Proxy("Process32First", no_error_check)
|
||||
@Kernel32Proxy("Process32First")
|
||||
def Process32First(hSnapshot, lpte):
|
||||
"""Set byref(lpte) if needed"""
|
||||
if type(lpte) == THREADENTRY32:
|
||||
lpte = ctypes.byref(lpte)
|
||||
return Process32First.ctypes_function(hSnapshot, lpte)
|
||||
|
||||
|
||||
@Kernel32Proxy("Process32Next", no_error_check)
|
||||
def Process32Next(hSnapshot, lpte):
|
||||
"""Set byref(lpte) if needed"""
|
||||
if type(lpte) == THREADENTRY32:
|
||||
lpte = ctypes.byref(lpte)
|
||||
return Process32Next.ctypes_function(hSnapshot, lpte)
|
||||
|
||||
@Kernel32Proxy("OpenEventA")
|
||||
def OpenEventA(dwDesiredAccess, bInheritHandle, lpName):
|
||||
return OpenEventA.ctypes_function(dwDesiredAccess, bInheritHandle, lpName)
|
||||
|
||||
@Kernel32Proxy("OpenEventW")
|
||||
def OpenEventW(dwDesiredAccess, bInheritHandle, lpName):
|
||||
return OpenEventA.ctypes_function(dwDesiredAccess, bInheritHandle, lpName)
|
||||
|
||||
# File stuff
|
||||
@Kernel32Proxy("WriteFile")
|
||||
@@ -454,12 +506,144 @@ def DeviceIoControl(hDevice, dwIoControlCode, lpInBuffer, nInBufferSize=None, lp
|
||||
return DeviceIoControl.ctypes_function(hDevice, dwIoControlCode, lpInBuffer, nInBufferSize, lpOutBuffer, nOutBufferSize, lpBytesReturned, lpOverlapped)
|
||||
|
||||
|
||||
|
||||
@Kernel32Proxy("CreateFileMappingA")
|
||||
def CreateFileMappingA(hFile, lpFileMappingAttributes=None, flProtect=PAGE_READWRITE, dwMaximumSizeHigh=0, dwMaximumSizeLow=NeededParameter, lpName=NeededParameter):
|
||||
return CreateFileMappingA.ctypes_function(hFile, lpFileMappingAttributes, flProtect, dwMaximumSizeHigh, dwMaximumSizeLow, lpName)
|
||||
|
||||
|
||||
@Kernel32Proxy("CreateFileMappingW")
|
||||
def CreateFileMappingW(hFile, lpFileMappingAttributes=None, flProtect=PAGE_READWRITE, dwMaximumSizeHigh=0, dwMaximumSizeLow=0, lpName=NeededParameter):
|
||||
return CreateFileMappingW.ctypes_function(hFile, lpFileMappingAttributes, flProtect, dwMaximumSizeHigh, dwMaximumSizeLow, lpName)
|
||||
|
||||
|
||||
@Kernel32Proxy("MapViewOfFile")
|
||||
def MapViewOfFile(hFileMappingObject, dwDesiredAccess=FILE_MAP_ALL_ACCESS, dwFileOffsetHigh=0, dwFileOffsetLow=0, dwNumberOfBytesToMap=NeededParameter):
|
||||
return MapViewOfFile.ctypes_function(hFileMappingObject, dwDesiredAccess, dwFileOffsetHigh, dwFileOffsetLow, dwNumberOfBytesToMap)
|
||||
|
||||
|
||||
@Kernel32Proxy("DuplicateHandle")
|
||||
def DuplicateHandle(hSourceProcessHandle, hSourceHandle, hTargetProcessHandle, lpTargetHandle, dwDesiredAccess=0, bInheritHandle=False, dwOptions=0):
|
||||
return DuplicateHandle.ctypes_function(hSourceProcessHandle, hSourceHandle, hTargetProcessHandle, lpTargetHandle, dwDesiredAccess, bInheritHandle, dwOptions)
|
||||
|
||||
|
||||
# TODO: might be in another DLL depending of version
|
||||
# Should handle this..
|
||||
|
||||
def GetMappedFileNameWWrapper(hProcess, lpv, lpFilename, nSize=None):
|
||||
if nSize is None:
|
||||
nSize = ctypes.sizeof(lpFilename)
|
||||
return GetMappedFileNameWWrapper.ctypes_function(hProcess, lpv, lpFilename, nSize)
|
||||
GetMappedFileNameW = OptionalExport(Kernel32Proxy("GetMappedFileNameW"))(GetMappedFileNameWWrapper)
|
||||
|
||||
|
||||
def GetMappedFileNameAWrapper(hProcess, lpv, lpFilename, nSize=None):
|
||||
if nSize is None:
|
||||
nSize = ctypes.sizeof(lpFilename)
|
||||
return GetMappedFileNameAWrapper.ctypes_function(hProcess, lpv, lpFilename, nSize)
|
||||
GetMappedFileNameA = OptionalExport(Kernel32Proxy("GetMappedFileNameA"))(GetMappedFileNameAWrapper)
|
||||
|
||||
def QueryWorkingSetWrapper(hProcess, pv, cb):
|
||||
return QueryWorkingSet.ctypes_function(hProcess, pv, cb)
|
||||
QueryWorkingSet = OptionalExport(Kernel32Proxy("QueryWorkingSet"))(QueryWorkingSetWrapper)
|
||||
|
||||
def QueryWorkingSetExWrapper(hProcess, pv, cb):
|
||||
return QueryWorkingSetEx.ctypes_function(hProcess, pv, cb)
|
||||
QueryWorkingSetEx = OptionalExport(Kernel32Proxy("QueryWorkingSetEx"))(QueryWorkingSetExWrapper)
|
||||
|
||||
if GetMappedFileNameA is None:
|
||||
GetMappedFileNameW = PsapiProxy("GetMappedFileNameW")(GetMappedFileNameWWrapper)
|
||||
GetMappedFileNameA = PsapiProxy("GetMappedFileNameA")(GetMappedFileNameAWrapper)
|
||||
QueryWorkingSet = PsapiProxy("QueryWorkingSet")(QueryWorkingSetWrapper)
|
||||
QueryWorkingSetEx = PsapiProxy("QueryWorkingSetEx")(QueryWorkingSetExWrapper)
|
||||
|
||||
def GetModuleBaseNameAWrapper(hProcess, hModule, lpBaseName, nSize=None):
|
||||
if nSize is None:
|
||||
nSize = len(lpBaseName)
|
||||
return GetModuleBaseNameAWrapper.ctypes_function(hProcess, hModule, lpBaseName, nSize)
|
||||
GetModuleBaseNameA = OptionalExport(Kernel32Proxy("GetMappedFileNameA"))(GetModuleBaseNameAWrapper)
|
||||
|
||||
|
||||
def GetModuleBaseNameWWrapper(hProcess, hModule, lpBaseName, nSize=None):
|
||||
if nSize is None:
|
||||
nSize = len(lpBaseName)
|
||||
return GetModuleBaseNameWWrapper.ctypes_function(hProcess, hModule, lpBaseName, nSize)
|
||||
GetModuleBaseNameA = OptionalExport(Kernel32Proxy("GetModuleBaseNameW"))(GetModuleBaseNameWWrapper)
|
||||
|
||||
if GetModuleBaseNameA is None:
|
||||
GetModuleBaseNameA = PsapiProxy("GetModuleBaseNameA")(GetModuleBaseNameAWrapper)
|
||||
GetModuleBaseNameW = PsapiProxy("GetModuleBaseNameW")(GetModuleBaseNameWWrapper)
|
||||
|
||||
|
||||
def GetProcessImageFileNameAWrapper(hProcess, lpImageFileName, nSize=None):
|
||||
if nSize is None:
|
||||
nSize = len(lpImageFileName)
|
||||
return GetProcessImageFileNameAWrapper.ctypes_function(hProcess, lpImageFileName, nSize)
|
||||
GetProcessImageFileNameA = OptionalExport(Kernel32Proxy("GetProcessImageFileNameA"))(GetProcessImageFileNameAWrapper)
|
||||
|
||||
def GetProcessImageFileNameWWrapper(hProcess, lpImageFileName, nSize=None):
|
||||
if nSize is None:
|
||||
nSize = len(lpImageFileName)
|
||||
return GetProcessImageFileNameWWrapper.ctypes_function(hProcess, lpImageFileName, nSize)
|
||||
GetProcessImageFileNameW = OptionalExport(Kernel32Proxy("GetProcessImageFileNameW"))(GetProcessImageFileNameWWrapper)
|
||||
|
||||
if GetProcessImageFileNameA is None:
|
||||
GetProcessImageFileNameA = PsapiProxy("GetProcessImageFileNameA")(GetProcessImageFileNameAWrapper)
|
||||
GetProcessImageFileNameW = PsapiProxy("GetProcessImageFileNameW")(GetProcessImageFileNameWWrapper)
|
||||
|
||||
# Debug API
|
||||
|
||||
DebugBreak = TransparentKernel32Proxy("DebugBreak")
|
||||
ContinueDebugEvent = TransparentKernel32Proxy("ContinueDebugEvent")
|
||||
DebugActiveProcess = TransparentKernel32Proxy("DebugActiveProcess")
|
||||
DebugActiveProcessStop = TransparentKernel32Proxy("DebugActiveProcessStop")
|
||||
DebugSetProcessKillOnExit = TransparentKernel32Proxy("DebugSetProcessKillOnExit")
|
||||
DebugBreakProcess = TransparentKernel32Proxy("DebugBreakProcess")
|
||||
|
||||
@Kernel32Proxy("WaitForDebugEvent")
|
||||
def WaitForDebugEvent(lpDebugEvent, dwMilliseconds=INFINITE):
|
||||
return WaitForDebugEvent.ctypes_function(lpDebugEvent, dwMilliseconds)
|
||||
|
||||
|
||||
# Volumes stuff
|
||||
|
||||
GetLogicalDriveStringsA = TransparentKernel32Proxy("GetLogicalDriveStringsA")
|
||||
GetLogicalDriveStringsW = TransparentKernel32Proxy("GetLogicalDriveStringsW")
|
||||
GetDriveTypeA = TransparentKernel32Proxy("GetDriveTypeA")
|
||||
GetDriveTypeW = TransparentKernel32Proxy("GetDriveTypeW")
|
||||
QueryDosDeviceA = TransparentKernel32Proxy("QueryDosDeviceA")
|
||||
QueryDosDeviceW = TransparentKernel32Proxy("QueryDosDeviceW")
|
||||
GetVolumeNameForVolumeMountPointA = TransparentKernel32Proxy("GetVolumeNameForVolumeMountPointA")
|
||||
GetVolumeNameForVolumeMountPointW = TransparentKernel32Proxy("GetVolumeNameForVolumeMountPointW")
|
||||
|
||||
@Kernel32Proxy("GetVolumeInformationA")
|
||||
def GetVolumeInformationA(lpRootPathName, lpVolumeNameBuffer, nVolumeNameSize, lpVolumeSerialNumber, lpMaximumComponentLength, lpFileSystemFlags, lpFileSystemNameBuffer, nFileSystemNameSize):
|
||||
if nVolumeNameSize == 0 and lpVolumeNameBuffer is not None:
|
||||
nVolumeNameSize = len(lpVolumeNameBuffer)
|
||||
if nFileSystemNameSize == 0 and lpFileSystemNameBuffer is not None:
|
||||
nFileSystemNameSize = len(lpFileSystemNameBuffer)
|
||||
return GetVolumeInformationA.ctypes_function(lpRootPathName, lpVolumeNameBuffer, nVolumeNameSize, lpVolumeSerialNumber, lpMaximumComponentLength, lpFileSystemFlags, lpFileSystemNameBuffer, nFileSystemNameSize)
|
||||
|
||||
|
||||
@Kernel32Proxy("GetVolumeInformationW")
|
||||
def GetVolumeInformationW(lpRootPathName, lpVolumeNameBuffer=None, nVolumeNameSize=0, lpVolumeSerialNumber=None, lpMaximumComponentLength=None, lpFileSystemFlags=None, lpFileSystemNameBuffer=None, nFileSystemNameSize=0):
|
||||
if nVolumeNameSize == 0 and lpVolumeNameBuffer is not None:
|
||||
nVolumeNameSize = len(lpVolumeNameBuffer)
|
||||
if nFileSystemNameSize == 0 and lpFileSystemNameBuffer is not None:
|
||||
nFileSystemNameSize = len(lpFileSystemNameBuffer)
|
||||
return GetVolumeInformationW.ctypes_function(lpRootPathName, lpVolumeNameBuffer, nVolumeNameSize, lpVolumeSerialNumber, lpMaximumComponentLength, lpFileSystemFlags, lpFileSystemNameBuffer, nFileSystemNameSize)
|
||||
|
||||
|
||||
|
||||
# ### NTDLL #### #
|
||||
|
||||
@OptionalExport(NtdllProxy('NtWow64ReadVirtualMemory64', error_ntstatus))
|
||||
def NtWow64ReadVirtualMemory64(hProcess, lpBaseAddress, lpBuffer, nSize, lpNumberOfBytesRead=None):
|
||||
return NtWow64ReadVirtualMemory64.ctypes_function(hProcess, lpBaseAddress, lpBuffer, nSize, lpNumberOfBytesRead)
|
||||
|
||||
@OptionalExport(NtdllProxy('NtWow64WriteVirtualMemory64', error_ntstatus))
|
||||
def NtWow64WriteVirtualMemory64(hProcess, lpBaseAddress, lpBuffer, nSize, lpNumberOfBytesWritten=None):
|
||||
return NtWow64WriteVirtualMemory64.ctypes_function(hProcess, lpBaseAddress, lpBuffer, nSize, lpNumberOfBytesWritten)
|
||||
|
||||
def ntquerysysteminformation_error_check(func_name, result, func, args):
|
||||
if result == 0:
|
||||
@@ -473,6 +657,10 @@ def ntquerysysteminformation_error_check(func_name, result, func, args):
|
||||
def NtGetContextThread(hThread, lpContext):
|
||||
return NtGetContextThread.ctypes_function(hThread, lpContext)
|
||||
|
||||
@NtdllProxy("LdrLoadDll", error_ntstatus)
|
||||
def LdrLoadDll(PathToFile, Flags, ModuleFileName, ModuleHandle):
|
||||
return LdrLoadDll.ctypes_function(PathToFile, Flags, ModuleFileName, ModuleHandle)
|
||||
|
||||
|
||||
@NtdllProxy('NtQuerySystemInformation', ntquerysysteminformation_error_check)
|
||||
def NtQuerySystemInformation(SystemInformationClass, SystemInformation=None, SystemInformationLength=0, ReturnLength=NeededParameter):
|
||||
@@ -501,6 +689,12 @@ def NtQueryInformationThread(ThreadHandle, ThreadInformationClass, ThreadInforma
|
||||
return NtQueryInformationThread.ctypes_function(ThreadHandle, ThreadInformationClass, ThreadInformation, ThreadInformationLength, ReturnLength)
|
||||
|
||||
|
||||
@NtdllProxy('NtProtectVirtualMemory', error_ntstatus)
|
||||
def NtProtectVirtualMemory(ProcessHandle, BaseAddress, NumberOfBytesToProtect, NewAccessProtection, OldAccessProtection=None):
|
||||
if OldAccessProtection is None:
|
||||
OldAccessProtection = DWORD()
|
||||
return NtProtectVirtualMemory.ctypes_function(ProcessHandle, BaseAddress, NumberOfBytesToProtect, NewAccessProtection, OldAccessProtection)
|
||||
|
||||
@OptionalExport(NtdllProxy('NtQueryVirtualMemory', error_ntstatus))
|
||||
def NtQueryVirtualMemory(ProcessHandle, BaseAddress, MemoryInformationClass, MemoryInformation=NeededParameter, MemoryInformationLength=0, ReturnLength=None):
|
||||
if ReturnLength is None:
|
||||
@@ -512,6 +706,10 @@ def NtQueryVirtualMemory(ProcessHandle, BaseAddress, MemoryInformationClass, Mem
|
||||
return NtQueryVirtualMemory.ctypes_function(ProcessHandle, BaseAddress, MemoryInformationClass, MemoryInformation=NeededParameter, MemoryInformationLength=0, ReturnLength=None)
|
||||
|
||||
|
||||
@NtdllProxy('NtQueryObject', error_ntstatus)
|
||||
def NtQueryObject(Handle, ObjectInformationClass, ObjectInformation=None, ObjectInformationLength=0, ReturnLength=NeededParameter):
|
||||
return NtQueryObject.ctypes_function(Handle, ObjectInformationClass, ObjectInformation, ObjectInformationLength, ReturnLength)
|
||||
|
||||
@OptionalExport(NtdllProxy('NtCreateThreadEx', error_ntstatus))
|
||||
def NtCreateThreadEx(ThreadHandle=None, DesiredAccess=0x1fffff, ObjectAttributes=0, ProcessHandle=NeededParameter, lpStartAddress=NeededParameter, lpParameter=NeededParameter, CreateSuspended=0, dwStackSize=0, Unknown1=0, Unknown2=0, Unknown=0):
|
||||
if ThreadHandle is None:
|
||||
@@ -519,6 +717,63 @@ def NtCreateThreadEx(ThreadHandle=None, DesiredAccess=0x1fffff, ObjectAttributes
|
||||
return NtCreateThreadEx.ctypes_function(ThreadHandle, DesiredAccess, ObjectAttributes, ProcessHandle, lpStartAddress, lpParameter, CreateSuspended, dwStackSize, Unknown1, Unknown2, Unknown3)
|
||||
|
||||
|
||||
@NtdllProxy("NtSetContextThread", error_ntstatus)
|
||||
def NtSetContextThread(hThread, lpContext):
|
||||
return NtSetContextThread.ctypes_function(hThread, lpContext)
|
||||
|
||||
@NtdllProxy("NtOpenEvent", error_ntstatus)
|
||||
def NtOpenEvent(EventHandle, DesiredAccess, ObjectAttributes):
|
||||
return NtOpenEvent.ctypes_function(EventHandle, DesiredAccess, ObjectAttributes)
|
||||
|
||||
|
||||
@NtdllProxy("NtAlpcCreatePort", error_ntstatus)
|
||||
def NtAlpcCreatePort(PortHandle, ObjectAttributes, PortAttributes):
|
||||
return NtAlpcCreatePort.ctypes_function(PortHandle, ObjectAttributes, PortAttributes)
|
||||
|
||||
|
||||
@NtdllProxy("NtAlpcConnectPort", error_ntstatus)
|
||||
def NtAlpcConnectPort(PortHandle, PortName, ObjectAttributes, PortAttributes, Flags, RequiredServerSid, ConnectionMessage, BufferLength, OutMessageAttributes, InMessageAttributes, Timeout):
|
||||
return NtAlpcConnectPort.ctypes_function(PortHandle, PortName, ObjectAttributes, PortAttributes, Flags, RequiredServerSid, ConnectionMessage, BufferLength, OutMessageAttributes, InMessageAttributes, Timeout)
|
||||
|
||||
|
||||
@NtdllProxy("NtAlpcAcceptConnectPort", error_ntstatus)
|
||||
def NtAlpcAcceptConnectPort(PortHandle, ConnectionPortHandle, Flags, ObjectAttributes, PortAttributes, PortContext, ConnectionRequest, ConnectionMessageAttributes, AcceptConnection):
|
||||
return NtAlpcAcceptConnectPort.ctypes_function(PortHandle, ConnectionPortHandle, Flags, ObjectAttributes, PortAttributes, PortContext, ConnectionRequest, ConnectionMessageAttributes, AcceptConnection)
|
||||
|
||||
@NtdllProxy("NtAlpcSendWaitReceivePort", error_ntstatus)
|
||||
def NtAlpcSendWaitReceivePort(PortHandle, Flags, SendMessage, SendMessageAttributes, ReceiveMessage, BufferLength, ReceiveMessageAttributes, Timeout):
|
||||
return NtAlpcSendWaitReceivePort.ctypes_function(PortHandle, Flags, SendMessage, SendMessageAttributes, ReceiveMessage, BufferLength, ReceiveMessageAttributes, Timeout)
|
||||
|
||||
|
||||
@NtdllProxy("AlpcInitializeMessageAttribute", error_ntstatus)
|
||||
def AlpcInitializeMessageAttribute(AttributeFlags, Buffer, BufferSize, RequiredBufferSize):
|
||||
return AlpcInitializeMessageAttribute.ctypes_function(AttributeFlags, Buffer, BufferSize, RequiredBufferSize)
|
||||
|
||||
|
||||
@NtdllProxy("AlpcGetMessageAttribute", no_error_check)
|
||||
def AlpcGetMessageAttribute(Buffer, AttributeFlag):
|
||||
return AlpcGetMessageAttribute.ctypes_function(Buffer, AttributeFlag)
|
||||
|
||||
|
||||
@NtdllProxy("NtOpenDirectoryObject", error_ntstatus)
|
||||
def NtOpenDirectoryObject(DirectoryHandle, DesiredAccess, ObjectAttributes):
|
||||
return NtOpenDirectoryObject.ctypes_function(DirectoryHandle, DesiredAccess, ObjectAttributes)
|
||||
|
||||
|
||||
@NtdllProxy("NtQueryDirectoryObject", error_ntstatus)
|
||||
def NtQueryDirectoryObject(DirectoryHandle, Buffer, Length, ReturnSingleEntry, RestartScan, Context, ReturnLength):
|
||||
return NtQueryDirectoryObject.ctypes_function(DirectoryHandle, Buffer, Length, ReturnSingleEntry, RestartScan, Context, ReturnLength)
|
||||
|
||||
|
||||
@NtdllProxy("NtQuerySymbolicLinkObject", error_ntstatus)
|
||||
def NtQuerySymbolicLinkObject(LinkHandle, LinkTarget, ReturnedLength):
|
||||
return NtQuerySymbolicLinkObject.ctypes_function(LinkHandle, LinkTarget, ReturnedLength)
|
||||
|
||||
|
||||
@NtdllProxy("NtOpenSymbolicLinkObject", error_ntstatus)
|
||||
def NtOpenSymbolicLinkObject(LinkHandle, DesiredAccess, ObjectAttributes):
|
||||
return NtOpenSymbolicLinkObject.ctypes_function(LinkHandle, DesiredAccess, ObjectAttributes)
|
||||
|
||||
# ##### ADVAPI32 ####### #
|
||||
|
||||
@Advapi32Proxy('OpenProcessToken')
|
||||
@@ -546,7 +801,19 @@ def AdjustTokenPrivileges(TokenHandle, DisableAllPrivileges=False, NewState=Need
|
||||
return AdjustTokenPrivileges.ctypes_function(TokenHandle, DisableAllPrivileges, NewState, BufferLength, PreviousState, ReturnLength)
|
||||
|
||||
|
||||
# Registry stuff
|
||||
@Advapi32Proxy('LookupAccountSidA')
|
||||
def LookupAccountSidA(lpSystemName, lpSid, lpName, cchName, lpReferencedDomainName, cchReferencedDomainName, peUse):
|
||||
return LookupAccountSidA.ctypes_function(lpSystemName, lpSid, lpName, cchName, lpReferencedDomainName, cchReferencedDomainName, peUse)
|
||||
|
||||
|
||||
@Advapi32Proxy('LookupAccountSidW')
|
||||
def LookupAccountSidW(lpSystemName, lpSid, lpName, cchName, lpReferencedDomainName, cchReferencedDomainName, peUse):
|
||||
return LookupAccountSidW.ctypes_function(lpSystemName, lpSid, lpName, cchName, lpReferencedDomainName, cchReferencedDomainName, peUse)
|
||||
|
||||
# Token stuff
|
||||
|
||||
GetSidSubAuthorityCount = TransparentAdvapi32Proxy("GetSidSubAuthorityCount")
|
||||
GetSidSubAuthority = TransparentAdvapi32Proxy("GetSidSubAuthority")
|
||||
|
||||
@Advapi32Proxy('GetTokenInformation')
|
||||
def GetTokenInformation(TokenHandle=NeededParameter, TokenInformationClass=NeededParameter, TokenInformation=None, TokenInformationLength=0, ReturnLength=None):
|
||||
@@ -559,6 +826,7 @@ def GetTokenInformation(TokenHandle=NeededParameter, TokenInformationClass=Neede
|
||||
def RegOpenKeyExA(hKey, lpSubKey, ulOptions, samDesired, phkResult):
|
||||
return RegOpenKeyExA.ctypes_function(hKey, lpSubKey, ulOptions, samDesired, phkResult)
|
||||
|
||||
# Registry stuff
|
||||
|
||||
# TODO: default values? which ones ?
|
||||
|
||||
@@ -582,6 +850,28 @@ def RegCloseKey(hKey):
|
||||
return RegCloseKey.ctypes_function(hKey)
|
||||
|
||||
|
||||
# Services
|
||||
@Advapi32Proxy('OpenSCManagerA')
|
||||
def OpenSCManagerA(lpMachineName=None, lpDatabaseName=None, dwDesiredAccess=SC_MANAGER_ALL_ACCESS):
|
||||
return OpenSCManagerA.ctypes_function(lpMachineName, lpDatabaseName, dwDesiredAccess)
|
||||
|
||||
|
||||
@Advapi32Proxy('OpenSCManagerW')
|
||||
def OpenSCManagerW(lpMachineName=None, lpDatabaseName=None, dwDesiredAccess=SC_MANAGER_ALL_ACCESS):
|
||||
return OpenSCManagerW.ctypes_function(lpMachineName, lpDatabaseName, dwDesiredAccess)
|
||||
|
||||
|
||||
@Advapi32Proxy('EnumServicesStatusExA')
|
||||
def EnumServicesStatusExA(hSCManager, InfoLevel, dwServiceType, dwServiceState, lpServices, cbBufSize, pcbBytesNeeded, lpServicesReturned, lpResumeHandle, pszGroupName):
|
||||
return EnumServicesStatusExA.ctypes_function(hSCManager, InfoLevel, dwServiceType, dwServiceState, lpServices, cbBufSize, pcbBytesNeeded, lpServicesReturned, lpResumeHandle, pszGroupName)
|
||||
|
||||
|
||||
@Advapi32Proxy('EnumServicesStatusExW')
|
||||
def EnumServicesStatusExW(hSCManager, InfoLevel, dwServiceType, dwServiceState, lpServices, cbBufSize, pcbBytesNeeded, lpServicesReturned, lpResumeHandle, pszGroupName):
|
||||
return EnumServicesStatusExW.ctypes_function(hSCManager, InfoLevel, dwServiceType, dwServiceState, lpServices, cbBufSize, pcbBytesNeeded, lpServicesReturned, lpResumeHandle, pszGroupName)
|
||||
|
||||
|
||||
|
||||
# ##### Iphlpapi (network list and stuff) ###### #
|
||||
|
||||
def set_tcp_entry_error_check(func_name, result, func, args):
|
||||
@@ -598,11 +888,127 @@ SetTcpEntry = TransparentIphlpapiProxy('SetTcpEntry', error_check=set_tcp_entry_
|
||||
@OptionalExport(IphlpapiProxy('GetExtendedTcpTable'))
|
||||
def GetExtendedTcpTable(pTcpTable, pdwSize=None, bOrder=True, ulAf=NeededParameter, TableClass=TCP_TABLE_OWNER_PID_ALL, Reserved=0):
|
||||
if pdwSize is None:
|
||||
ctypes.sizeof(pTcpTable)
|
||||
pdwSize = ULONG(ctypes.sizeof(pTcpTable))
|
||||
return GetExtendedTcpTable.ctypes_function(pTcpTable, pdwSize, bOrder, ulAf, TableClass, Reserved)
|
||||
|
||||
|
||||
@IphlpapiProxy('GetInterfaceInfo')
|
||||
def GetInterfaceInfo(pIfTable, dwOutBufLen=None):
|
||||
if dwOutBufLen is None:
|
||||
dwOutBufLen = ULONG(ctypes.sizeof(pIfTable))
|
||||
return GetInterfaceInfo.ctypes_function(pIfTable, dwOutBufLen)
|
||||
|
||||
|
||||
@IphlpapiProxy('GetIfTable')
|
||||
def GetIfTable(pIfTable, pdwSize, bOrder=False):
|
||||
return GetIfTable.ctypes_function(pIfTable, pdwSize, bOrder)
|
||||
|
||||
@IphlpapiProxy('GetIpAddrTable')
|
||||
def GetIpAddrTable(pIpAddrTable, pdwSize, bOrder=False):
|
||||
return GetIpAddrTable.ctypes_function(pIpAddrTable, pdwSize, bOrder)
|
||||
|
||||
# ## WinTrustProxy PE signature##
|
||||
|
||||
@WinTrustProxy('WinVerifyTrust')
|
||||
def WinVerifyTrust(hwnd, pgActionID, pWVTData):
|
||||
return WinVerifyTrust.ctypes_function(hwnd, pgActionID, pWVTData)
|
||||
return WinVerifyTrust.ctypes_function(hwnd, pgActionID, pWVTData)
|
||||
|
||||
|
||||
# ##Wintrust: catalog stuff ###
|
||||
|
||||
@WinTrustProxy('CryptCATAdminCalcHashFromFileHandle', error_check=kernel32_error_check)
|
||||
def CryptCATAdminCalcHashFromFileHandle(hFile, pcbHash, pbHash, dwFlags):
|
||||
return CryptCATAdminCalcHashFromFileHandle.ctypes_function(hFile, pcbHash, pbHash, dwFlags)
|
||||
|
||||
|
||||
@WinTrustProxy('CryptCATAdminEnumCatalogFromHash')
|
||||
def CryptCATAdminEnumCatalogFromHash(hCatAdmin, pbHash, cbHash, dwFlags, phPrevCatInfo):
|
||||
return CryptCATAdminEnumCatalogFromHash.ctypes_function(hCatAdmin, pbHash, cbHash, dwFlags, phPrevCatInfo)
|
||||
|
||||
|
||||
@WinTrustProxy('CryptCATAdminAcquireContext', error_check=kernel32_error_check)
|
||||
def CryptCATAdminAcquireContext(phCatAdmin, pgSubsystem, dwFlags):
|
||||
return CryptCATAdminAcquireContext.ctypes_function(phCatAdmin, pgSubsystem, dwFlags)
|
||||
|
||||
|
||||
@WinTrustProxy('CryptCATCatalogInfoFromContext', error_check=kernel32_error_check)
|
||||
def CryptCATCatalogInfoFromContext(hCatInfo, psCatInfo, dwFlags):
|
||||
return CryptCATCatalogInfoFromContext.ctypes_function(hCatInfo, psCatInfo, dwFlags)
|
||||
|
||||
|
||||
@WinTrustProxy('CryptCATAdminReleaseCatalogContext')
|
||||
def CryptCATAdminReleaseCatalogContext(hCatAdmin, hCatInfo, dwFlags):
|
||||
return CryptCATAdminReleaseCatalogContext.ctypes_function(hCatAdmin, hCatInfo, dwFlags)
|
||||
|
||||
|
||||
@WinTrustProxy('CryptCATAdminReleaseContext')
|
||||
def CryptCATAdminReleaseContext(hCatAdmin, dwFlags):
|
||||
return CryptCATAdminReleaseContext.ctypes_function(hCatAdmin, dwFlags)
|
||||
|
||||
|
||||
# ## User32 stuff ## #
|
||||
|
||||
EnumWindows = TransparentUser32Proxy('EnumWindows')
|
||||
GetWindowTextA = TransparentUser32Proxy('GetWindowTextA', no_error_check)
|
||||
GetWindowTextW = TransparentUser32Proxy('GetWindowTextW', no_error_check)
|
||||
GetWindowModuleFileNameA = TransparentUser32Proxy('GetWindowModuleFileNameA', no_error_check)
|
||||
GetWindowModuleFileNameW = TransparentUser32Proxy('GetWindowModuleFileNameW', no_error_check)
|
||||
GetSystemMetrics = TransparentUser32Proxy('GetSystemMetrics', no_error_check)
|
||||
|
||||
# ## Version stuff ## #
|
||||
|
||||
@VersionProxy("GetFileVersionInfoA")
|
||||
def GetFileVersionInfoA(lptstrFilename, dwHandle=0, dwLen=None, lpData=NeededParameter):
|
||||
if dwLen is None and lpData is not None:
|
||||
dwLen = len(lpData)
|
||||
return GetFileVersionInfoA.ctypes_function(lptstrFilename, dwHandle, dwLen, lpData)
|
||||
|
||||
|
||||
@VersionProxy("GetFileVersionInfoW")
|
||||
def GetFileVersionInfoW(lptstrFilename, dwHandle=0, dwLen=None, lpData=NeededParameter):
|
||||
if dwLen is None and lpData is not None:
|
||||
dwLen = len(lpData)
|
||||
return GetFileVersionInfoA.ctypes_function(lptstrFilename, dwHandle, dwLen, lpData)
|
||||
|
||||
|
||||
@VersionProxy("GetFileVersionInfoSizeA")
|
||||
def GetFileVersionInfoSizeA(lptstrFilename, lpdwHandle=None):
|
||||
if lpdwHandle is None:
|
||||
lpdwHandle = ctypes.byref(DWORD())
|
||||
return GetFileVersionInfoSizeA.ctypes_function(lptstrFilename, lpdwHandle)
|
||||
|
||||
|
||||
@VersionProxy("GetFileVersionInfoSizeW")
|
||||
def GetFileVersionInfoSizeW(lptstrFilename, lpdwHandle=None):
|
||||
if lpdwHandle is None:
|
||||
lpdwHandle = ctypes.byref(DWORD())
|
||||
return GetFileVersionInfoSizeW.ctypes_function(lptstrFilename, lpdwHandle)
|
||||
|
||||
|
||||
@VersionProxy("VerQueryValueA")
|
||||
def VerQueryValueA(pBlock, lpSubBlock, lplpBuffer, puLen):
|
||||
return VerQueryValueA.ctypes_function(pBlock, lpSubBlock, lplpBuffer, puLen)
|
||||
|
||||
|
||||
@VersionProxy("VerQueryValueW")
|
||||
def VerQueryValueW(pBlock, lpSubBlock, lplpBuffer, puLen):
|
||||
return VerQueryValueW.ctypes_function(pBlock, lpSubBlock, lplpBuffer, puLen)
|
||||
|
||||
|
||||
# ## Ole32Proxy (COM STUFF) ## #
|
||||
|
||||
@Ole32Proxy('CoInitializeEx', no_error_check)
|
||||
def CoInitializeEx(pvReserved=None, dwCoInit=COINIT_MULTITHREADED):
|
||||
return CoInitializeEx.ctypes_function(pvReserved, dwCoInit)
|
||||
|
||||
|
||||
@Ole32Proxy('CoInitializeSecurity')
|
||||
def CoInitializeSecurity(pSecDesc, cAuthSvc, asAuthSvc, pReserved1, dwAuthnLevel, dwImpLevel, pAuthList, dwCapabilities, pReserved3):
|
||||
return CoInitializeSecurity.ctypes_function(pSecDesc, cAuthSvc, asAuthSvc, pReserved1, dwAuthnLevel, dwImpLevel, pAuthList, dwCapabilities, pReserved3)
|
||||
|
||||
|
||||
@Ole32Proxy('CoCreateInstance')
|
||||
def CoCreateInstance(rclsid, pUnkOuter=None, dwClsContext=CLSCTX_INPROC_SERVER, riid=NeededParameter, ppv=NeededParameter):
|
||||
return CoCreateInstance.ctypes_function(rclsid, pUnkOuter, dwClsContext, riid, ppv)
|
||||
|
||||
|
||||
|
||||
+134
-7
@@ -1,8 +1,10 @@
|
||||
import ctypes
|
||||
import struct
|
||||
import windows
|
||||
from collections import namedtuple
|
||||
from windows import winproxy
|
||||
from windows.generated_def.winstructs import *
|
||||
from windows.winproxy import WinVerifyTrust
|
||||
|
||||
|
||||
IID_PACK = "<I", "<H", "<H", "<B", "<B", "<B", "<B", "<B", "<B", "<B", "<B"
|
||||
def get_IID_from_raw(raw):
|
||||
@@ -17,6 +19,10 @@ WINTRUST_ACTION_GENERIC_VERIFY_V2_STR = get_IID_from_raw(WINTRUST_ACTION_GENERIC
|
||||
# Otherwise there is a problem with `Data4` of `type c_char_Array_8` containing 0x00 (0x8c, 0xc2, 0x0, 0xc0, 0x4f, 0xc2, 0x95, 0xee)
|
||||
WINTRUST_ACTION_GENERIC_VERIFY_V2 = GUID.from_address(ctypes.addressof(WINTRUST_ACTION_GENERIC_VERIFY_V2_STR))
|
||||
|
||||
DRIVER_ACTION_VERIFY_RAW = 0xf750e6c3, 0x38ee, 0x11d1, 0x85, 0xe5, 0x0, 0xc0, 0x4f, 0xc2, 0x95, 0xee
|
||||
DRIVER_ACTION_VERIFY_STR = get_IID_from_raw(DRIVER_ACTION_VERIFY_RAW)
|
||||
DRIVER_ACTION_VERIFY = GUID.from_address(ctypes.addressof(DRIVER_ACTION_VERIFY_STR))
|
||||
|
||||
WTD_UI_ALL = 1
|
||||
WTD_UI_NONE = 2
|
||||
WTD_UI_NOBAD = 3
|
||||
@@ -37,10 +43,45 @@ WTD_STATEACTION_CLOSE = 0x00000002
|
||||
WTD_STATEACTION_AUTO_CACHE = 0x00000003
|
||||
WTD_STATEACTION_AUTO_CACHE_FLUSH = 0x00000004
|
||||
|
||||
def check_signature(filename):
|
||||
"""Check if ``filename`` is a valid signed file
|
||||
wintrust_know_return_value = [
|
||||
TRUST_E_PROVIDER_UNKNOWN,
|
||||
TRUST_E_ACTION_UNKNOWN,
|
||||
TRUST_E_SUBJECT_FORM_UNKNOWN,
|
||||
DIGSIG_E_ENCODE,
|
||||
TRUST_E_SUBJECT_NOT_TRUSTED,
|
||||
DIGSIG_E_DECODE,
|
||||
DIGSIG_E_EXTENSIBILITY,
|
||||
PERSIST_E_SIZEDEFINITE,
|
||||
DIGSIG_E_CRYPTO,
|
||||
PERSIST_E_SIZEINDEFINITE,
|
||||
PERSIST_E_NOTSELFSIZING,
|
||||
TRUST_E_NOSIGNATURE,
|
||||
CERT_E_EXPIRED,
|
||||
CERT_E_VALIDITYPERIODNESTING,
|
||||
CERT_E_PURPOSE,
|
||||
CERT_E_ISSUERCHAINING,
|
||||
CERT_E_MALFORMED,
|
||||
CERT_E_UNTRUSTEDROOT,
|
||||
CERT_E_CHAINING,
|
||||
TRUST_E_FAIL,
|
||||
CERT_E_REVOKED,
|
||||
CERT_E_UNTRUSTEDTESTROOT,
|
||||
CERT_E_REVOCATION_FAILURE,
|
||||
CERT_E_CN_NO_MATCH,
|
||||
CERT_E_WRONG_USAGE,
|
||||
TRUST_E_EXPLICIT_DISTRUST,
|
||||
CERT_E_UNTRUSTEDCA,
|
||||
CERT_E_INVALID_POLICY,
|
||||
CERT_E_INVALID_NAME,
|
||||
CRYPT_E_FILE_ERROR,
|
||||
]
|
||||
wintrust_return_value_mapper = {x:x for x in wintrust_know_return_value}
|
||||
|
||||
:return: 0 if file have a valid signature
|
||||
|
||||
def check_signature(filename):
|
||||
"""Check if ``filename`` embeds a valid signature.
|
||||
|
||||
:return: :class:`int`: ``0`` if ``filename`` have a valid signature else the error
|
||||
"""
|
||||
file_data = WINTRUST_FILE_INFO()
|
||||
file_data.cbStruct = ctypes.sizeof(WINTRUST_FILE_INFO)
|
||||
@@ -61,9 +102,95 @@ def check_signature(filename):
|
||||
win_trust_data.hWVTStateData = None
|
||||
win_trust_data.pwszURLReference = None
|
||||
win_trust_data.dwUIContext = 0
|
||||
|
||||
#win_trust_data.dwProvFlags = 0x1000 + 0x10 + 0x800
|
||||
win_trust_data.tmp_union.pFile = ctypes.pointer(file_data)
|
||||
|
||||
x = WinVerifyTrust(None, ctypes.byref(WVTPolicyGUID), ctypes.byref(win_trust_data))
|
||||
x = winproxy.WinVerifyTrust(None, ctypes.byref(WVTPolicyGUID), ctypes.byref(win_trust_data))
|
||||
win_trust_data.dwStateAction = WTD_STATEACTION_CLOSE
|
||||
WinVerifyTrust(None, ctypes.byref(WVTPolicyGUID), ctypes.byref(win_trust_data))
|
||||
return x & 0xffffffff
|
||||
winproxy.WinVerifyTrust(None, ctypes.byref(WVTPolicyGUID), ctypes.byref(win_trust_data))
|
||||
return wintrust_return_value_mapper.get(x & 0xffffffff, x & 0xffffffff)
|
||||
|
||||
|
||||
def get_catalog_for_filename(filename):
|
||||
ctx = HCATADMIN()
|
||||
winproxy.CryptCATAdminAcquireContext(ctypes.byref(ctx), DRIVER_ACTION_VERIFY, 0)
|
||||
hash = get_file_hash(filename)
|
||||
if hash is None:
|
||||
return None
|
||||
t = winproxy.CryptCATAdminEnumCatalogFromHash(ctx, hash, len(hash), 0, None)
|
||||
if t is None:
|
||||
return None
|
||||
tname = get_catalog_name_from_handle(t)
|
||||
|
||||
while t is not None:
|
||||
t = winproxy.CryptCATAdminEnumCatalogFromHash(ctx, hash, len(hash), 0, ctypes.byref(HCATINFO(t)))
|
||||
winproxy.CryptCATAdminReleaseCatalogContext(ctx, t, 0)
|
||||
winproxy.CryptCATAdminReleaseContext(ctx, 0)
|
||||
return tname
|
||||
|
||||
|
||||
def get_file_hash(filename):
|
||||
f = open(filename, "rb")
|
||||
handle = windows.utils.get_handle_from_file(f)
|
||||
|
||||
size = DWORD(0)
|
||||
x = winproxy.CryptCATAdminCalcHashFromFileHandle(handle, ctypes.byref(size), None, 0)
|
||||
buffer = (BYTE * size.value)()
|
||||
try:
|
||||
x = winproxy.CryptCATAdminCalcHashFromFileHandle(handle, ctypes.byref(size), buffer, 0)
|
||||
except WindowsError as e:
|
||||
if e.winerror == 1006:
|
||||
# CryptCATAdminCalcHashFromFileHandle: [Error 1006]
|
||||
# The volume for a file has been externally altered so that the opened file is no longer valid.
|
||||
# (returned for empty file)
|
||||
return None
|
||||
return buffer
|
||||
|
||||
|
||||
def get_catalog_name_from_handle(handle):
|
||||
cat_info = CATALOG_INFO()
|
||||
cat_info.cbStruct = ctypes.sizeof(cat_info)
|
||||
winproxy.CryptCATCatalogInfoFromContext(handle, ctypes.byref(cat_info), 0)
|
||||
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)
|
||||
if catalog is None:
|
||||
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
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user