Compare commits

...

81 Commits

Author SHA1 Message Date
Clement Rouault dfdeb82682 Let's call it a version 0.2 2016-04-27 18:27:11 +02:00
Clement Rouault feeb2e406e Update readme with more features + some simple demos 2016-04-27 18:25:21 +02:00
Clement Rouault 3243f6e8fc more doc 2016-04-27 16:36:17 +02:00
hakril c2c3fe2dc2 more doc 2016-04-27 00:33:02 +02:00
Clement Rouault a988ad03e3 Add struct + thread.teb_base 2016-04-25 17:48:49 +02:00
Clement Rouault 57634f076c Add process.time_info 2016-04-21 10:58:35 +02:00
Clement Rouault 085c36c706 fix/simplify get_string in pe_parse / adapt syswow.py 2016-04-21 10:47:00 +02:00
Clement Rouault 09e9b7efbb Fix get_mapped_filename 32 -> 64 (use NtQueryVirtualMemory) 2016-04-19 11:49:33 +02:00
Clement Rouault 5b66242680 writing some doc 2016-04-18 23:09:26 +02:00
Clement Rouault 4ab9e97667 fix setup.py to include windows.test 2016-04-18 21:20:02 +02:00
Clement Rouault cb3c0f20c0 pe_parse: fix read string PE32 in process 64b 2016-04-18 11:54:51 +02:00
Clement Rouault b621e6a09f fix queryworkingset / add test / add virtual protect context manager 2016-04-18 11:24:41 +02:00
Clement Rouault 3454801ad0 small fix in Debugger.add_bp 2016-04-11 19:15:39 +02:00
Clement Rouault e781e3493f Playing with workingset 2016-04-11 19:15:23 +02:00
Clement Rouault 85cb4eef1b add some additional info to full_signature_information 2016-04-11 10:16:06 +02:00
Clement Rouault 18bba9b24e Fix pe_parse to handle 32bits PE in 64bits process (PE32 .NET) 2016-04-08 16:11:55 +02:00
Clement Rouault ef9b2486ec fix + add some info in Section 2016-04-08 13:46:06 +02:00
Clement Rouault b698b27a6f Add process.query_working_set 2016-04-08 13:45:27 +02:00
Clement Rouault 0e9ec9ed82 add / fix in registry and registry sample 2016-04-01 17:34:56 +02:00
Clement Rouault 6c1b4cf5e6 More doc / sample 2016-03-30 18:27:40 +02:00
Clement Rouault 96c8d68297 kernobj.py -> WinObj explorer 2016-03-30 15:28:04 +02:00
hakril 53e131831d Writing / updating some doc 2016-03-29 23:41:54 +02:00
Clement Rouault 4c1192bf75 Fix crash du to bad declaration / size of CONTEXT64 2016-03-29 18:53:04 +02:00
Clement Rouault da52b1a014 More Nt def/structs/funcs 2016-03-29 17:19:17 +02:00
Clement Rouault cf8386400f Fix WinUnicodeString to use Length 2016-03-29 14:01:40 +02:00
Clement Rouault ff5ce9ae86 Add EnumType for generated enum 2016-03-25 16:59:40 +01:00
Clement Rouault 480cbcf1dc Improving com / wmi API / code 2016-03-25 15:14:53 +01:00
Clement Rouault cbd4f0b6b7 More struct/defs/funcs 2016-03-25 15:13:49 +01:00
Clement Rouault 9856a1614b Add firewall interface to system.network 2016-03-25 13:44:04 +01:00
Clement Rouault eadc0c6963 More COM interfaces/ API 2016-03-24 18:14:45 +01:00
Clement Rouault 374e842d3d Add com interfaces generated file 2016-03-24 16:05:09 +01:00
Clement Rouault 1a85d99b0e windows.com with a cleaner interface + use in wmi.pu 2016-03-24 16:03:13 +01:00
Clement Rouault d794ac8ceb Cleaning/working on windows.com API 2016-03-24 15:23:15 +01:00
Clement Rouault 641790f917 Still working on COM ctypes generation 2016-03-24 14:14:39 +01:00
Clement Rouault 1b33bbb025 Beginning to generate ctypes for COM interfaces 2016-03-23 22:11:35 +01:00
Clement Rouault 34ae5084cd Working/Trying com ctypes generator 2016-03-23 19:04:15 +01:00
Clement Rouault 3cb8cc6f9e Refactor: new winobject directory 2016-03-23 13:42:54 +01:00
Clement Rouault c24816f51f Improve create_process + test some other utils 2016-03-22 13:40:03 +01:00
Clement Rouault d096da3709 Exploring on system attribute and Token 2016-03-22 13:39:37 +01:00
Clement Rouault 9cae319c11 New registry API 2016-03-22 13:39:11 +01:00
Clement Rouault f06afc9b79 winproxy imported directly, use same format for call 2016-03-22 13:38:45 +01:00
Clement Rouault db4c51dc67 Syswow64ApiProxy now handle None from OptionalExport 2016-03-22 13:37:22 +01:00
Clement Rouault 1422db08ae More winproxy functions 2016-03-22 13:30:44 +01:00
Clement Rouault 16ef768f3f Unifor the import / use of winproxy 2016-03-21 13:27:23 +01:00
Clement Rouault fb0171b8b9 WinpProcess in not a PROCESSENTRY32 anymore 2016-03-21 13:18:01 +01:00
Clement Rouault 8628ff5595 new funcs + struct + fix winobject 2016-03-18 18:04:50 +01:00
Clement Rouault 5f1c841b75 Add ctypes struct pprinter 2016-03-18 18:03:45 +01:00
Clement Rouault 6a305458d5 Add signature verification by catalog 2016-03-18 18:01:57 +01:00
Clement Rouault faa0acd030 Add services and volumes files 2016-03-18 11:24:02 +01:00
Clement Rouault 78f9733295 Add del_bp + import LocalDebugger 2016-03-18 11:16:53 +01:00
Clement Rouault a4090ea215 Add some defs + wintrust catalog functions 2016-03-16 16:33:38 +01:00
Clement Rouault 9db75b0226 Add some doc/sample on LocalDebugger 2016-02-12 15:06:41 +01:00
Clement Rouault 5ffa21cd8a LocalDebugger sample + fix 2016-02-12 14:44:00 +01:00
hakril 9a1088daab Small fixes in DOC + update winproxy function list 2016-02-10 23:01:32 +01:00
Clement Rouault f9ce637ffa Small doc stuff + fix setup.py 2016-02-10 17:51:54 +01:00
Clement Rouault c5e021f10d Writing samples and doc ! 2016-02-10 17:30:54 +01:00
Clement Rouault c40cb0c8b0 Add get_mapped_filename to WinProcess 2016-02-10 16:29:46 +01:00
Clement Rouault b789a12040 Improve debugger + pe_parse 'guess' the PE type (32/64) 2016-02-10 16:27:53 +01:00
Clement Rouault 401db9c347 Working on debugger (str address + rewrite + test) 2016-02-10 11:53:13 +01:00
Clement Rouault 6cf4a9cae4 Add test / fix Winprocess.load_library / free some of the memory 2016-02-03 17:47:07 +01:00
Clement Rouault 9fbba331ca Add NTSTATUS to windef/add virtual_free/improve nativeutils GetProcAddr + test 2016-02-02 18:45:24 +01:00
Clement Rouault 3f06e95617 First - shameful version of syswow64 debugging 2016-02-01 18:45:51 +01:00
Clement Rouault 0da86e20aa SetThreadContext 32<->64 + test 2016-02-01 17:31:56 +01:00
Clement Rouault d720170781 Big commit GetProcAddrss 32 and 64 (fixed) 2016-01-29 18:05:21 +01:00
Clement Rouault 5b5db57e17 Rewrite injected stub for remote python -> now have nice threads handling 2016-01-29 13:51:35 +01:00
Clement Rouault 7be3561ccf Better remote veh sample :) 2016-01-28 17:02:18 +01:00
Clement Rouault ee62d6a972 Add sample on veh handle setup in remote process 2016-01-28 17:00:33 +01:00
Clement Rouault f307f8202a Add Process.write_[dq]word + rewrite injection.py to use PEB parsing if needed 2016-01-28 17:00:32 +01:00
Clement Rouault 38a2298dee Add nativeutils.py with GetProcAddress64 + add instr to x86/x64 assembler + add merge of labels in multipleinstr (dummy function support) 2016-01-28 17:00:31 +01:00
hakril ec4862439f Add LdrLoadDLL + Fix winproxy.VirtualProtect Commit2 2016-01-27 12:41:41 +01:00
hakril 6d8796f3ed Add LdrLoadDLL + Fix winproxy.VirtualProtect + add a first draft on veh sample 2016-01-26 22:06:02 +01:00
Clement Rouault 588a1e0461 Update TODO 2016-01-26 18:12:59 +01:00
Clement Rouault 010453e96d Fix test + Fix a Use-After-CloseHandle in debugger + add dbgprint on HANDLE 2016-01-26 14:50:21 +01:00
Clement Rouault 7c35615319 Working / testing the debugger 2016-01-25 19:11:51 +01:00
hakril cf89d25486 Slowly working on debug.py 2016-01-25 09:45:09 +01:00
Clement Rouault 99788d0368 Writting a debugger is fun :D 2016-01-22 18:19:00 +01:00
hakril f6f206b842 Still playing will debug API + add Winprocess.read_[dq]word 2016-01-21 00:43:41 +01:00
Clement Rouault 6b75fe3185 Playing with Token and Debugger API 2016-01-20 19:07:18 +01:00
hakril f43f7c4838 Fix WinProcess.is_exit + test case 2016-01-19 23:50:10 +01:00
hakril fad8121cbf Updated TODO and test for CreateFile error_check fix 2016-01-13 23:43:04 +01:00
hakril c35e517b35 Fix CreateFile error_check: now raise on INVALID_HANDLE_VALUE 2016-01-13 23:35:49 +01:00
101 changed files with 26140 additions and 4118 deletions
+81 -5
View File
@@ -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
+49 -7
View File
@@ -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
+47
View File
@@ -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;
+35
View File
@@ -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;
+153
View File
@@ -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;
+191
View File
@@ -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;
+68
View File
@@ -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;
+18
View File
@@ -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;
+30
View File
@@ -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;
+185
View File
@@ -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;
+168
View File
@@ -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
View File
@@ -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']
+18 -18
View File
@@ -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)
+287 -5
View File
@@ -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
+1 -1
View File
@@ -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,
+23 -16
View File
@@ -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)
+449
View File
@@ -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
+653 -1
View File
@@ -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
);
+18 -15
View File
@@ -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"
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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.
+67
View File
@@ -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:
+99
View File
@@ -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 -1
View File
@@ -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
+4
View File
@@ -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/
+53
View File
@@ -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
View File
@@ -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
+8 -1
View File
@@ -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
View File
@@ -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
""""""""
+274
View File
@@ -99,6 +99,49 @@ Output::
Sections: [<PESection ".text">, <PESection ".rdata">, <PESection ".data">, <PESection ".rsrc">, <PESection ".reloc">]
.. _sample_system:
``windows.system``
""""""""""""""""""
.. literalinclude:: ..\..\samples\system.py
Output::
(cmd λ) python system.py
Basic system infos:
version = (6, 3)
bitness = 64
computer_name = HAKRIL-PC
product_type = VER_NT_WORKSTATION(0x1L)
version_name = Windows 8.1
There is 95 processes
There is 1021 threads
Dumping first logical drive:
<LogicalDrive "C:\" (DRIVE_FIXED)>
name = C:\
type = DRIVE_FIXED(0x3L)
path = \Device\HarddiskVolume2
Dumping first service:
<ServiceA "ACPI">
name = ACPI
description = Microsoft ACPI Driver
status = ServiceStatus(type=SERVICE_KERNEL_DRIVER(0x1L), state=SERVICE_RUNNING(0x4L), control_accepted=1L, flags=0L)
process = None
Finding a service in a user process:
<ServiceA "Appinfo">
name = Appinfo
description = Application Information
status = ServiceStatus(type=SERVICE_WIN32_SHARE_PROCESS(0x20L), state=SERVICE_RUNNING(0x4L), control_accepted=129L, flags=0L)
process = <WinProcess "svchost.exe" pid 944 at 0x29d5290>
.. _sample_iat_hook:
IAT hooking
@@ -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
+15
View File
@@ -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:
+4 -1
View File
@@ -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
+16
View File
@@ -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
View File
@@ -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
View File
@@ -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
+40
View File
@@ -0,0 +1,40 @@
``windows.wintrust`` -- Checking signature
******************************************
.. module:: windows.wintrust
.. note::
See sample :ref:`sample_wintrust`
The :mod:`wintrust` module offers wrapper around ``wintrust.dll``.
It allows to check the signature of a file.
The signature of a file can be at two differents place:
* In the file itself (:func:`check_signature`)
* In a catalog file (:func:`full_signature_information`)
.. note::
`Explanation about catalog files <https://msdn.microsoft.com/en-us/library/windows/hardware/ff537872(v=vs.85).aspx>`_
API
"""
.. autofunction:: is_signed
.. autofunction:: full_signature_information
.. autofunction:: check_signature
SignatureData
'''''''''''''
.. autoclass:: SignatureData
:exclude-members: count, index
+1 -18
View File
@@ -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>
+10
View File
@@ -0,0 +1,10 @@
WMI -- Make request to WMI
==========================
.. module:: windows.winobject.wmi
.. note::
See sample :ref:`wmi_request`
.. autoclass:: WmiRequester
+46
View File
@@ -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()
+56
View File
@@ -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()
+44
View File
@@ -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()
+54
View File
@@ -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
View File
@@ -1,7 +1,6 @@
import sys
import os.path
import socket
sys.path.append(os.path.abspath(__file__ + "\..\.."))
import windows
+5 -5
View File
@@ -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))
+69
View File
@@ -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()
+42
View File
@@ -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)))
+43
View File
@@ -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")
+29
View File
@@ -0,0 +1,29 @@
import sys
import os.path
sys.path.append(os.path.abspath(__file__ + "\..\.."))
import windows.wintrust
TARGET_FILE = r"C:\windows\system32\ntdll.dll"
print("Checking signature of <{0}>".format(TARGET_FILE))
print(" is_signed: <{0}>".format(windows.wintrust.is_signed(TARGET_FILE)))
print(" check_signature: <{0}>".format(windows.wintrust.check_signature(TARGET_FILE)))
sign_info = windows.wintrust.full_signature_information(TARGET_FILE)
print(" full_signature_information:")
print(" * signed <{0}>".format(sign_info.signed))
print(" * catalog <{0}>".format(sign_info.catalog))
print(" * catalogsigned <{0}>".format(sign_info.catalogsigned))
print(" * additionalinfo <{0}>".format(sign_info.additionalinfo))
print("Checking signature of some loaded DLL")
for module in windows.current_process.peb.modules[:5]:
path = module.fullname
is_signed = windows.wintrust.is_signed(path)
if is_signed:
print("<{0}> : {1}".format(path, is_signed))
else:
sign_info = windows.wintrust.full_signature_information(path)
print("<{0}> : {1} ({2})".format(path, is_signed, sign_info[3]))
+31
View File
@@ -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))
+6 -2
View File
@@ -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'],
)
-8
View File
@@ -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
View File
@@ -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
View File
@@ -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
+757
View File
@@ -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()
+15
View File
@@ -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 *
+567
View File
@@ -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"),
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
+221 -92
View File
@@ -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):
+282
View File
@@ -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
+60 -5
View File
@@ -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):
+45 -3
View File
@@ -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):
+36 -1
View File
@@ -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]'))
+21
View File
@@ -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()
-208
View File
@@ -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
View File
@@ -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
-82
View File
@@ -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
View File
@@ -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)
+2 -2
View File
@@ -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
View File
@@ -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)
+34
View File
@@ -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)
+27 -4
View File
@@ -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 ::
-257
View File
@@ -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
-864
View File
@@ -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
View File
+353
View File
@@ -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
+106
View File
@@ -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)
+447
View File
@@ -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)
+116
View File
@@ -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))
+241
View File
@@ -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
+71
View File
@@ -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")
+51
View File
@@ -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"
+88
View File
@@ -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
View File
@@ -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
View File
@@ -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