├── FuzzTemp ├── empty └── sample.xps ├── crashes └── empty ├── BaseOfficeDocs ├── MiscBaseFiles │ └── empty ├── OtherFileFormats │ └── empty ├── UnpackedMSOpenXMLFormatFiles │ └── empty └── OpenXMLFiles │ └── sample.xps ├── ExtDepLibs ├── utils │ ├── __init__.py │ ├── __init__.pyc │ ├── crash_binning.pyc │ ├── crash_binning.py │ └── LICENSE.txt ├── winappdbg │ ├── plugins │ │ ├── README │ │ ├── __init__.py │ │ ├── do_symfix.py │ │ ├── do_example.py │ │ ├── do_exploitable.py │ │ └── do_exchain.py │ ├── crash.pyc │ ├── debug.pyc │ ├── event.pyc │ ├── sql.pyc │ ├── util.pyc │ ├── disasm.pyc │ ├── module.pyc │ ├── process.pyc │ ├── search.pyc │ ├── system.pyc │ ├── textio.pyc │ ├── thread.pyc │ ├── window.pyc │ ├── __init__.pyc │ ├── breakpoint.pyc │ ├── registry.pyc │ ├── interactive.pyc │ ├── win32 │ │ ├── gdi32.pyc │ │ ├── ntdll.pyc │ │ ├── psapi.pyc │ │ ├── user32.pyc │ │ ├── __init__.pyc │ │ ├── advapi32.pyc │ │ ├── dbghelp.pyc │ │ ├── defines.pyc │ │ ├── kernel32.pyc │ │ ├── peb_teb.pyc │ │ ├── shell32.pyc │ │ ├── shlwapi.pyc │ │ ├── version.pyc │ │ ├── wtsapi32.pyc │ │ ├── context_amd64.pyc │ │ ├── context_i386.pyc │ │ ├── __init__.py │ │ ├── wtsapi32.py │ │ ├── psapi.py │ │ ├── shell32.py │ │ └── context_i386.py │ └── __init__.py ├── Au3Info.exe └── autoit │ ├── win.pyc │ ├── __init__.pyc │ ├── autoit.pyc │ ├── control.pyc │ ├── process.pyc │ ├── lib │ ├── AutoItX3.dll │ └── AutoItX3_x64.dll │ ├── __init__.py │ ├── process.py │ ├── autoit.py │ └── control.py ├── screens ├── logo.PNG ├── CrashSummary.png ├── popuphandler.PNG └── video_thumb.PNG ├── changelog ├── FileFormatHandlers ├── SampleHandler.py ├── binaryHandler.py └── test.py ├── LICENSE ├── OXDumper.py ├── crashSummary.py ├── OfficeFileProcessor.py ├── Mutator.py ├── PopUpKiller.py ├── config.py └── README.md /FuzzTemp/empty: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /crashes/empty: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /BaseOfficeDocs/MiscBaseFiles/empty: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /BaseOfficeDocs/OtherFileFormats/empty: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ExtDepLibs/utils/__init__.py: -------------------------------------------------------------------------------- 1 | import crash_binning -------------------------------------------------------------------------------- /BaseOfficeDocs/UnpackedMSOpenXMLFormatFiles/empty: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ExtDepLibs/winappdbg/plugins/README: -------------------------------------------------------------------------------- 1 | Here go the plugins for the interactive debugger. -------------------------------------------------------------------------------- /screens/logo.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/debasishm89/OpenXMolar/HEAD/screens/logo.PNG -------------------------------------------------------------------------------- /FuzzTemp/sample.xps: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/debasishm89/OpenXMolar/HEAD/FuzzTemp/sample.xps -------------------------------------------------------------------------------- /changelog: -------------------------------------------------------------------------------- 1 | Changelog 2 | ========= 3 | 4 | 5 | 6 | 5th May, 2017 : Version 1.0 Initial Release -------------------------------------------------------------------------------- /ExtDepLibs/Au3Info.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/debasishm89/OpenXMolar/HEAD/ExtDepLibs/Au3Info.exe -------------------------------------------------------------------------------- /ExtDepLibs/autoit/win.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/debasishm89/OpenXMolar/HEAD/ExtDepLibs/autoit/win.pyc -------------------------------------------------------------------------------- /screens/CrashSummary.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/debasishm89/OpenXMolar/HEAD/screens/CrashSummary.png -------------------------------------------------------------------------------- /screens/popuphandler.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/debasishm89/OpenXMolar/HEAD/screens/popuphandler.PNG -------------------------------------------------------------------------------- /screens/video_thumb.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/debasishm89/OpenXMolar/HEAD/screens/video_thumb.PNG -------------------------------------------------------------------------------- /ExtDepLibs/autoit/__init__.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/debasishm89/OpenXMolar/HEAD/ExtDepLibs/autoit/__init__.pyc -------------------------------------------------------------------------------- /ExtDepLibs/autoit/autoit.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/debasishm89/OpenXMolar/HEAD/ExtDepLibs/autoit/autoit.pyc -------------------------------------------------------------------------------- /ExtDepLibs/autoit/control.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/debasishm89/OpenXMolar/HEAD/ExtDepLibs/autoit/control.pyc -------------------------------------------------------------------------------- /ExtDepLibs/autoit/process.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/debasishm89/OpenXMolar/HEAD/ExtDepLibs/autoit/process.pyc -------------------------------------------------------------------------------- /ExtDepLibs/utils/__init__.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/debasishm89/OpenXMolar/HEAD/ExtDepLibs/utils/__init__.pyc -------------------------------------------------------------------------------- /ExtDepLibs/winappdbg/crash.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/debasishm89/OpenXMolar/HEAD/ExtDepLibs/winappdbg/crash.pyc -------------------------------------------------------------------------------- /ExtDepLibs/winappdbg/debug.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/debasishm89/OpenXMolar/HEAD/ExtDepLibs/winappdbg/debug.pyc -------------------------------------------------------------------------------- /ExtDepLibs/winappdbg/event.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/debasishm89/OpenXMolar/HEAD/ExtDepLibs/winappdbg/event.pyc -------------------------------------------------------------------------------- /ExtDepLibs/winappdbg/sql.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/debasishm89/OpenXMolar/HEAD/ExtDepLibs/winappdbg/sql.pyc -------------------------------------------------------------------------------- /ExtDepLibs/winappdbg/util.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/debasishm89/OpenXMolar/HEAD/ExtDepLibs/winappdbg/util.pyc -------------------------------------------------------------------------------- /ExtDepLibs/winappdbg/disasm.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/debasishm89/OpenXMolar/HEAD/ExtDepLibs/winappdbg/disasm.pyc -------------------------------------------------------------------------------- /ExtDepLibs/winappdbg/module.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/debasishm89/OpenXMolar/HEAD/ExtDepLibs/winappdbg/module.pyc -------------------------------------------------------------------------------- /ExtDepLibs/winappdbg/process.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/debasishm89/OpenXMolar/HEAD/ExtDepLibs/winappdbg/process.pyc -------------------------------------------------------------------------------- /ExtDepLibs/winappdbg/search.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/debasishm89/OpenXMolar/HEAD/ExtDepLibs/winappdbg/search.pyc -------------------------------------------------------------------------------- /ExtDepLibs/winappdbg/system.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/debasishm89/OpenXMolar/HEAD/ExtDepLibs/winappdbg/system.pyc -------------------------------------------------------------------------------- /ExtDepLibs/winappdbg/textio.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/debasishm89/OpenXMolar/HEAD/ExtDepLibs/winappdbg/textio.pyc -------------------------------------------------------------------------------- /ExtDepLibs/winappdbg/thread.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/debasishm89/OpenXMolar/HEAD/ExtDepLibs/winappdbg/thread.pyc -------------------------------------------------------------------------------- /ExtDepLibs/winappdbg/window.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/debasishm89/OpenXMolar/HEAD/ExtDepLibs/winappdbg/window.pyc -------------------------------------------------------------------------------- /ExtDepLibs/autoit/lib/AutoItX3.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/debasishm89/OpenXMolar/HEAD/ExtDepLibs/autoit/lib/AutoItX3.dll -------------------------------------------------------------------------------- /ExtDepLibs/utils/crash_binning.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/debasishm89/OpenXMolar/HEAD/ExtDepLibs/utils/crash_binning.pyc -------------------------------------------------------------------------------- /ExtDepLibs/winappdbg/__init__.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/debasishm89/OpenXMolar/HEAD/ExtDepLibs/winappdbg/__init__.pyc -------------------------------------------------------------------------------- /ExtDepLibs/winappdbg/breakpoint.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/debasishm89/OpenXMolar/HEAD/ExtDepLibs/winappdbg/breakpoint.pyc -------------------------------------------------------------------------------- /ExtDepLibs/winappdbg/registry.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/debasishm89/OpenXMolar/HEAD/ExtDepLibs/winappdbg/registry.pyc -------------------------------------------------------------------------------- /ExtDepLibs/winappdbg/interactive.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/debasishm89/OpenXMolar/HEAD/ExtDepLibs/winappdbg/interactive.pyc -------------------------------------------------------------------------------- /ExtDepLibs/winappdbg/win32/gdi32.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/debasishm89/OpenXMolar/HEAD/ExtDepLibs/winappdbg/win32/gdi32.pyc -------------------------------------------------------------------------------- /ExtDepLibs/winappdbg/win32/ntdll.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/debasishm89/OpenXMolar/HEAD/ExtDepLibs/winappdbg/win32/ntdll.pyc -------------------------------------------------------------------------------- /ExtDepLibs/winappdbg/win32/psapi.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/debasishm89/OpenXMolar/HEAD/ExtDepLibs/winappdbg/win32/psapi.pyc -------------------------------------------------------------------------------- /ExtDepLibs/winappdbg/win32/user32.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/debasishm89/OpenXMolar/HEAD/ExtDepLibs/winappdbg/win32/user32.pyc -------------------------------------------------------------------------------- /BaseOfficeDocs/OpenXMLFiles/sample.xps: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/debasishm89/OpenXMolar/HEAD/BaseOfficeDocs/OpenXMLFiles/sample.xps -------------------------------------------------------------------------------- /ExtDepLibs/autoit/lib/AutoItX3_x64.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/debasishm89/OpenXMolar/HEAD/ExtDepLibs/autoit/lib/AutoItX3_x64.dll -------------------------------------------------------------------------------- /ExtDepLibs/winappdbg/win32/__init__.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/debasishm89/OpenXMolar/HEAD/ExtDepLibs/winappdbg/win32/__init__.pyc -------------------------------------------------------------------------------- /ExtDepLibs/winappdbg/win32/advapi32.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/debasishm89/OpenXMolar/HEAD/ExtDepLibs/winappdbg/win32/advapi32.pyc -------------------------------------------------------------------------------- /ExtDepLibs/winappdbg/win32/dbghelp.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/debasishm89/OpenXMolar/HEAD/ExtDepLibs/winappdbg/win32/dbghelp.pyc -------------------------------------------------------------------------------- /ExtDepLibs/winappdbg/win32/defines.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/debasishm89/OpenXMolar/HEAD/ExtDepLibs/winappdbg/win32/defines.pyc -------------------------------------------------------------------------------- /ExtDepLibs/winappdbg/win32/kernel32.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/debasishm89/OpenXMolar/HEAD/ExtDepLibs/winappdbg/win32/kernel32.pyc -------------------------------------------------------------------------------- /ExtDepLibs/winappdbg/win32/peb_teb.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/debasishm89/OpenXMolar/HEAD/ExtDepLibs/winappdbg/win32/peb_teb.pyc -------------------------------------------------------------------------------- /ExtDepLibs/winappdbg/win32/shell32.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/debasishm89/OpenXMolar/HEAD/ExtDepLibs/winappdbg/win32/shell32.pyc -------------------------------------------------------------------------------- /ExtDepLibs/winappdbg/win32/shlwapi.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/debasishm89/OpenXMolar/HEAD/ExtDepLibs/winappdbg/win32/shlwapi.pyc -------------------------------------------------------------------------------- /ExtDepLibs/winappdbg/win32/version.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/debasishm89/OpenXMolar/HEAD/ExtDepLibs/winappdbg/win32/version.pyc -------------------------------------------------------------------------------- /ExtDepLibs/winappdbg/win32/wtsapi32.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/debasishm89/OpenXMolar/HEAD/ExtDepLibs/winappdbg/win32/wtsapi32.pyc -------------------------------------------------------------------------------- /ExtDepLibs/winappdbg/win32/context_amd64.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/debasishm89/OpenXMolar/HEAD/ExtDepLibs/winappdbg/win32/context_amd64.pyc -------------------------------------------------------------------------------- /ExtDepLibs/winappdbg/win32/context_i386.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/debasishm89/OpenXMolar/HEAD/ExtDepLibs/winappdbg/win32/context_i386.pyc -------------------------------------------------------------------------------- /FileFormatHandlers/SampleHandler.py: -------------------------------------------------------------------------------- 1 | # Import whatever you want. 2 | 3 | 4 | 5 | class Handler(): # The class name should be always Handler 6 | def __init__(self): 7 | pass # Not required. 8 | 9 | def Fuzzit(self,actual_data): 10 | # A function called Fuzzit must be present in Handler class and it should return fuzzed data/xml string/whatever. 11 | # Note: Date type of actual_data and data_after_mutation should always be same. 12 | ''' 13 | Fuzz the content of actual_data and return the fuzzed binary data Binary data. 14 | For effective fuzzing result, show your mutation creativity here :) 15 | ''' 16 | data_after_mutation = actual_data 17 | return data_after_mutation 18 | -------------------------------------------------------------------------------- /FileFormatHandlers/binaryHandler.py: -------------------------------------------------------------------------------- 1 | from random import randrange 2 | from math import ceil 3 | from random import randint 4 | from random import choice 5 | 6 | class Handler(): 7 | def __init__(self): 8 | pass 9 | def int2binary(self,n, cnt=24): 10 | return "".join([str((n >> y) & 1) for y in range(cnt-1, -1, -1)]) 11 | def Fuzzit(self,data): 12 | ''' 13 | Fuzz Binary data. 14 | ''' 15 | fuzzratio = float(0.09) 16 | b = list(data) 17 | data_to_be_fuzzed = randrange(ceil((float(len(data))) * fuzzratio))+1 #Number of bytes to fuzz 18 | case = randint(0,1) 19 | if case == 0: 20 | # Replace random offsets with random chars 21 | for j in range(data_to_be_fuzzed): #Iterate all bytes 22 | randbyte = randrange(256) #Random character 23 | ran = randrange(len(data)) #Random offset 24 | #ran = randint(10,len(data)) #Random offset Leave first 10 bytes 25 | b[ran] = '%c'%(randbyte) #Replace 26 | mutated =''.join(b) #Append 27 | if case == 1: 28 | # Bit flip randomly chosen bytes 29 | for j in range(data_to_be_fuzzed): #Iterate 30 | ran = randrange(len(data)) #Random offset 31 | #ran = randint(10,len(data)) #Random offset Leave first 10 bytes 32 | bits = self.int2binary(ord(b[ran]),8) #Int to Binary 33 | flipped = bits[::-1] #Bit-flip 34 | b[ran] = chr(int(flipped,2)) #Replace 35 | mutated =''.join(b) #Append 36 | return mutated 37 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2017 Debasish Mandal 2 | 3 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 4 | 5 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 6 | 7 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 8 | 9 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 10 | 11 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /ExtDepLibs/winappdbg/plugins/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # Copyright (c) 2009-2016, Mario Vilas 5 | # All rights reserved. 6 | # 7 | # Redistribution and use in source and binary forms, with or without 8 | # modification, are permitted provided that the following conditions are met: 9 | # 10 | # * Redistributions of source code must retain the above copyright notice, 11 | # this list of conditions and the following disclaimer. 12 | # * Redistributions in binary form must reproduce the above copyright 13 | # notice,this list of conditions and the following disclaimer in the 14 | # documentation and/or other materials provided with the distribution. 15 | # * Neither the name of the copyright holder nor the names of its 16 | # contributors may be used to endorse or promote products derived from 17 | # this software without specific prior written permission. 18 | # 19 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 | # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 23 | # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 | # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 | # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 | # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 | # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 | # POSSIBILITY OF SUCH DAMAGE. 30 | 31 | """ 32 | Plugins folder for the WinAppDbg interactive debugger. 33 | """ 34 | -------------------------------------------------------------------------------- /ExtDepLibs/winappdbg/plugins/do_symfix.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # Command line debugger using WinAppDbg 5 | # Fix the symbol store path 6 | # Copyright (c) 2009-2016, Mario Vilas 7 | # All rights reserved. 8 | # 9 | # Redistribution and use in source and binary forms, with or without 10 | # modification, are permitted provided that the following conditions are met: 11 | # 12 | # * Redistributions of source code must retain the above copyright notice, 13 | # this list of conditions and the following disclaimer. 14 | # * Redistributions in binary form must reproduce the above copyright 15 | # notice,this list of conditions and the following disclaimer in the 16 | # documentation and/or other materials provided with the distribution. 17 | # * Neither the name of the copyright holder nor the names of its 18 | # contributors may be used to endorse or promote products derived from 19 | # this software without specific prior written permission. 20 | # 21 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 | # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 25 | # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 | # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 | # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 | # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 | # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 | # POSSIBILITY OF SUCH DAMAGE. 32 | 33 | def do(self, arg): 34 | ".symfix - Set the default Microsoft Symbol Store settings if missing" 35 | self.debug.system.fix_symbol_store_path(remote = True, force = False) 36 | -------------------------------------------------------------------------------- /ExtDepLibs/winappdbg/plugins/do_example.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # Command line debugger using WinAppDbg 5 | # Example command 6 | # Copyright (c) 2009-2016, Mario Vilas 7 | # All rights reserved. 8 | # 9 | # Redistribution and use in source and binary forms, with or without 10 | # modification, are permitted provided that the following conditions are met: 11 | # 12 | # * Redistributions of source code must retain the above copyright notice, 13 | # this list of conditions and the following disclaimer. 14 | # * Redistributions in binary form must reproduce the above copyright 15 | # notice,this list of conditions and the following disclaimer in the 16 | # documentation and/or other materials provided with the distribution. 17 | # * Neither the name of the copyright holder nor the names of its 18 | # contributors may be used to endorse or promote products derived from 19 | # this software without specific prior written permission. 20 | # 21 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 | # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 25 | # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 | # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 | # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 | # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 | # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 | # POSSIBILITY OF SUCH DAMAGE. 32 | 33 | def do(self, arg): 34 | ".example - This is an example plugin for the command line debugger" 35 | print "This is an example command." 36 | print "%s.do(%r, %r):" % (__name__, self, arg) 37 | print " last event", self.lastEvent 38 | print " prefix", self.cmdprefix 39 | print " arguments", self.split_tokens(arg) 40 | -------------------------------------------------------------------------------- /ExtDepLibs/winappdbg/plugins/do_exploitable.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # Command line debugger using WinAppDbg 5 | # Determine the approximate exploitability rating 6 | # Copyright (c) 2009-2016, Mario Vilas 7 | # All rights reserved. 8 | # 9 | # Redistribution and use in source and binary forms, with or without 10 | # modification, are permitted provided that the following conditions are met: 11 | # 12 | # * Redistributions of source code must retain the above copyright notice, 13 | # this list of conditions and the following disclaimer. 14 | # * Redistributions in binary form must reproduce the above copyright 15 | # notice,this list of conditions and the following disclaimer in the 16 | # documentation and/or other materials provided with the distribution. 17 | # * Neither the name of the copyright holder nor the names of its 18 | # contributors may be used to endorse or promote products derived from 19 | # this software without specific prior written permission. 20 | # 21 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 | # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 25 | # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 | # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 | # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 | # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 | # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 | # POSSIBILITY OF SUCH DAMAGE. 32 | 33 | def do(self, arg): 34 | ".exploitable - Determine the approximate exploitability rating" 35 | 36 | from winappdbg import Crash 37 | 38 | event = self.debug.lastEvent 39 | crash = Crash(event) 40 | crash.fetch_extra_data(event) 41 | 42 | status, rule, description = crash.isExploitable() 43 | 44 | print "-" * 79 45 | print "Exploitability: %s" % status 46 | print "Matched rule: %s" % rule 47 | print "Description: %s" % description 48 | print "-" * 79 49 | -------------------------------------------------------------------------------- /ExtDepLibs/winappdbg/plugins/do_exchain.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # Command line debugger using WinAppDbg 5 | # Show exception handlers list 6 | # Copyright (c) 2009-2016, Mario Vilas 7 | # All rights reserved. 8 | # 9 | # Redistribution and use in source and binary forms, with or without 10 | # modification, are permitted provided that the following conditions are met: 11 | # 12 | # * Redistributions of source code must retain the above copyright notice, 13 | # this list of conditions and the following disclaimer. 14 | # * Redistributions in binary form must reproduce the above copyright 15 | # notice,this list of conditions and the following disclaimer in the 16 | # documentation and/or other materials provided with the distribution. 17 | # * Neither the name of the copyright holder nor the names of its 18 | # contributors may be used to endorse or promote products derived from 19 | # this software without specific prior written permission. 20 | # 21 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 | # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 25 | # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 | # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 | # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 | # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 | # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 | # POSSIBILITY OF SUCH DAMAGE. 32 | 33 | from winappdbg import HexDump, Table 34 | 35 | def do(self, arg): 36 | ".exchain - Show the SEH chain" 37 | thread = self.get_thread_from_prefix() 38 | print "Exception handlers for thread %d" % thread.get_tid() 39 | print 40 | table = Table() 41 | table.addRow("Block", "Function") 42 | bits = thread.get_bits() 43 | for (seh, seh_func) in thread.get_seh_chain(): 44 | if seh is not None: 45 | seh = HexDump.address(seh, bits) 46 | if seh_func is not None: 47 | seh_func = HexDump.address(seh_func, bits) 48 | table.addRow(seh, seh_func) 49 | print table.getOutput() 50 | -------------------------------------------------------------------------------- /OXDumper.py: -------------------------------------------------------------------------------- 1 | ''' 2 | 3 | Copyright 2017 Debasish Mandal 4 | 5 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | 9 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 10 | 11 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 12 | 13 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 14 | 15 | ''' 16 | 17 | from OfficeFileProcessor import OfficeFileProcessor 18 | import sys 19 | import os 20 | class OXDumper: 21 | def __init__(self): 22 | pass 23 | def getFiles(self): 24 | files = os.listdir('BaseOfficeDocs\\OpenXMLFiles') 25 | if len(files) == 0: 26 | print '[+] No OpenXML file found in base folder : BaseOfficeDocs\\OpenXMLFiles' 27 | exit() 28 | else: 29 | all_internal_files = [] 30 | for file in files: 31 | op = OfficeFileProcessor('BaseOfficeDocs\\UnpackedMSOpenXMLFormatFiles','',True,'BaseOfficeDocs\\OpenXMLFiles') 32 | ox_dict = op.generateDict(file.split('\\')[-1]) 33 | all_internal_files = all_internal_files + ox_dict.keys() 34 | #print ox_dict.keys() 35 | return all_internal_files 36 | ''' 37 | elif len(files) > 1: 38 | #print len(files) 39 | print '[+] There are multiple files in folder : BaseOfficeDocs\\OpenXMLFiles. Please provide only one OpenXML file as base when targetting specific file(s) inside openXML document.' 40 | exit() 41 | ''' 42 | #else 43 | # op = OfficeFileProcessor('BaseOfficeDocs\\UnpackedMSOpenXMLFormatFiles','',True,'BaseOfficeDocs\\OpenXMLFiles') 44 | # ox_dict = op.generateDict(files[0].split('\\')[-1]) 45 | # return ox_dict.keys() 46 | if __name__ == "__main__": 47 | if len(sys.argv) != 2: 48 | print '[+] Accepts only one command line argument(comma separated file extensions). Usage : OXDumper.py xml,rels,ext1,ext2' 49 | od = OXDumper() 50 | files = od.getFiles() 51 | print '################ Generated using OXDumper.py, You can simply copy paste follwing python file list to config file #####################' 52 | list_buff = 'FILES_TO_BE_FUZZED = [' 53 | for file in sorted(files): 54 | list_buff += 'r\'' + file +'\',\n' 55 | list_buff = list_buff[:-2]+']' 56 | print list_buff 57 | print '################ File list ends #####################' 58 | else: 59 | exts = (sys.argv[1]).split(',') 60 | if len(exts) == 0: 61 | print '[+] [Error]You must provide at least one extension. c:\fuzzer>OXDumper.py xml' 62 | exit() 63 | od = OXDumper() 64 | files = od.getFiles() 65 | if len(files) == 0: 66 | print '[+] No files found inside Base OpenXML document with provided exntension(s) :( ',exts 67 | exit() 68 | print '################ Generated using OXDumper.py, You can simply copy paste follwing python file list to config file #####################' 69 | list_buff = 'FILES_TO_BE_FUZZED = [' 70 | for file in sorted(files): 71 | if file.split('.')[-1] in exts: 72 | list_buff += 'r\'' + file +'\',\n' 73 | list_buff = list_buff[:-2]+']' 74 | print list_buff 75 | print '################ File list ends #####################' 76 | -------------------------------------------------------------------------------- /crashSummary.py: -------------------------------------------------------------------------------- 1 | ''' 2 | 3 | Copyright 2017 Debasish Mandal 4 | 5 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | 9 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 10 | 11 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 12 | 13 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 14 | 15 | ''' 16 | import os 17 | from collections import namedtuple 18 | import re 19 | from time import sleep 20 | def pprinttable(rows): 21 | # Source : http://stackoverflow.com/questions/5909873/how-can-i-pretty-print-ascii-tables-with-python 22 | if len(rows) > 1: 23 | headers = rows[0]._fields 24 | lens = [] 25 | for i in range(len(rows[0])): 26 | lens.append(len(max([x[i] for x in rows] + [headers[i]],key=lambda x:len(str(x))))) 27 | formats = [] 28 | hformats = [] 29 | for i in range(len(rows[0])): 30 | if isinstance(rows[0][i], int): 31 | formats.append("%%%dd" % lens[i]) 32 | else: 33 | formats.append("%%-%ds" % lens[i]) 34 | hformats.append("%%-%ds" % lens[i]) 35 | pattern = " | ".join(formats) 36 | hpattern = " | ".join(hformats) 37 | separator = "-+-".join(['-' * n for n in lens]) 38 | print hpattern % tuple(headers) 39 | print separator 40 | _u = lambda t: t.decode('UTF-8', 'replace') if isinstance(t, str) else t 41 | for line in rows: 42 | print pattern % tuple(_u(t) for t in line) 43 | elif len(rows) == 1: 44 | row = rows[0] 45 | hwidth = len(max(row._fields,key=lambda x: len(x))) 46 | for i in range(len(row)): 47 | print "%*s = %s" % (hwidth,row._fields[i],row[i]) 48 | 49 | class CrashSummary: 50 | def __init__(self): 51 | pass 52 | def getCrashDetails(self,path): 53 | files = os.listdir('crashes\\'+path) 54 | for file in files: 55 | if file.split('.')[-1] == 'txt': 56 | f = open('crashes\\'+path+'\\'+file) 57 | lines = f.readlines() 58 | func_line = lines[0] 59 | exp_line = lines[2] 60 | f.close() 61 | match1 = re.search(r'at .+',func_line) 62 | #match2 = re.search(r'at .+',exp_line) 63 | if match1: 64 | return match1.group(),exp_line 65 | return 'N/A' 66 | def Summarize(self): 67 | print '-----------------' 68 | print 'Crash Summary |' 69 | print '-----------------' 70 | Row = namedtuple('Row',['Application','FaultAddress','UniqueCrashCount','FunctionName','Exploitability']) 71 | data = Row(' ',' ',' ',' ',' ') 72 | rows = [data] 73 | apps = os.listdir('Crashes') 74 | if len(apps) == 0: 75 | print 'No Crash So far :( :(' 76 | else: 77 | for app in apps: 78 | addres = os.listdir('Crashes\\'+app) 79 | UniqueCrashCount = len(addres) 80 | for FaultAddress in addres: 81 | name,exploitability = self.getCrashDetails(app+'\\'+FaultAddress) 82 | data = Row(app,FaultAddress,UniqueCrashCount,name,exploitability) 83 | rows.append(data) 84 | pprinttable(rows) 85 | print '\n\nRefresh in 2 seconds.....' 86 | if __name__ == "__main__": 87 | print 88 | cs = CrashSummary() 89 | while True: 90 | cs.Summarize() 91 | sleep(2) 92 | os.system('cls') -------------------------------------------------------------------------------- /OfficeFileProcessor.py: -------------------------------------------------------------------------------- 1 | ''' 2 | 3 | Copyright 2017 Debasish Mandal 4 | 5 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | 9 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 10 | 11 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 12 | 13 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 14 | 15 | ''' 16 | 17 | import os 18 | import zipfile 19 | from datetime import datetime 20 | 21 | class OfficeFileProcessor: 22 | ''' 23 | Code responsible for OpenXML file handling. 24 | ''' 25 | def __init__(self,UNPACKED_OFFICE_PATH,TEMP_PATH,oxml,PACKED_OFFICE_PATH): 26 | self.UNPACKED_OFFICE_PATH = UNPACKED_OFFICE_PATH 27 | self.PACKED_OFFICE_PATH = PACKED_OFFICE_PATH 28 | self.TEMP_PATH = TEMP_PATH 29 | self.ALL_DOCS_IN_MEMORY = {} 30 | self.oxml = oxml 31 | if self.oxml: 32 | # its an open xml file, unpack all of them. 33 | files = os.listdir(self.PACKED_OFFICE_PATH) 34 | for file in files: 35 | self.ExtractOpenXML(self.PACKED_OFFICE_PATH+'\\'+file,self.UNPACKED_OFFICE_PATH+'\\'+file.replace(' ','_')) 36 | def Pack2OfficeDoc2(self,op_name,dict): 37 | ''' 38 | 39 | Compress in memory dict to OpenXML file in disk. 40 | 41 | ''' 42 | if self.oxml: 43 | # Its an open xml format file 44 | try: # Sometimes when office responds too slowly, fuzzer may crash,hence adding this, so fuzzing continues 45 | zipf = zipfile.ZipFile(self.TEMP_PATH+'\\'+op_name, 'w') 46 | for file in dict: 47 | #print file 48 | l = len(self.UNPACKED_OFFICE_PATH + '\\' + op_name) 49 | zipf.writestr(file[l+1:], dict[file], zipfile.ZIP_DEFLATED ) # encode to get rid of Unicode error. 50 | zipf.close() 51 | except: 52 | pass 53 | else: 54 | # Its a binary file 55 | #print 'packing binary files' 56 | #print self.TEMP_PATH + '\\' + op_name 57 | try: 58 | f = open(self.TEMP_PATH + '\\' + op_name,'wb') 59 | f.write(dict) # In this case its a Binary stream 60 | f.close() 61 | except: 62 | pass 63 | def ExtractOpenXML(self,path_to_zip_file,directory_to_extract_to): 64 | ''' 65 | Extract content of an OpenXML file. 66 | 67 | ''' 68 | try: 69 | zip_ref = zipfile.ZipFile(path_to_zip_file, 'r') 70 | zip_ref.extractall(directory_to_extract_to) 71 | zip_ref.close() 72 | except: 73 | print '[+]',datetime.now().strftime("%Y:%m:%d::%H:%M:%S"),'Problem while extracting ',path_to_zip_file 74 | def ReadContent(self,path): 75 | f = open(path,'rb') 76 | d = f.read() 77 | f.close() 78 | return d 79 | def generateDict(self,dir): 80 | ''' 81 | 82 | Generate a dict out of an OpenXML file, So that we can manage easily. 83 | 84 | ''' 85 | office_dict = {} 86 | path = self.UNPACKED_OFFICE_PATH + '\\' + dir 87 | for root, dirs, files in os.walk(path): 88 | for file in files: 89 | office_dict[os.path.join(root, file)] = self.ReadContent(os.path.join(root, file)) 90 | return office_dict 91 | def LoadFilesInMemory(self): 92 | ''' 93 | 94 | Load all Base files in memory. 95 | 96 | ''' 97 | if self.oxml: 98 | for curr in os.listdir(self.UNPACKED_OFFICE_PATH): 99 | #print '[+] Loading file in memory',curr 100 | office_dict = self.generateDict(curr) 101 | self.ALL_DOCS_IN_MEMORY[curr] = office_dict 102 | return self.ALL_DOCS_IN_MEMORY 103 | else: 104 | for curr in os.listdir(self.UNPACKED_OFFICE_PATH): 105 | office_bin_cont = self.ReadContent(self.UNPACKED_OFFICE_PATH+'\\'+curr) 106 | self.ALL_DOCS_IN_MEMORY[curr] = office_bin_cont 107 | return self.ALL_DOCS_IN_MEMORY 108 | -------------------------------------------------------------------------------- /ExtDepLibs/autoit/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | __author__ = 'Jace Xu' 4 | __version__ = "0.3" 5 | 6 | from .autoit import options, properties, commands 7 | from .autoit import AutoItError 8 | 9 | from .autoit import error 10 | from .autoit import auto_it_set_option 11 | from .autoit import clip_get 12 | from .autoit import clip_put 13 | from .autoit import is_admin 14 | from .autoit import drive_map_add 15 | from .autoit import drive_map_del 16 | from .autoit import drive_map_get 17 | from .autoit import mouse_click 18 | from .autoit import mouse_click_drag 19 | from .autoit import mouse_down 20 | from .autoit import mouse_get_cursor 21 | from .autoit import mouse_get_pos 22 | from .autoit import mouse_move 23 | from .autoit import mouse_up 24 | from .autoit import mouse_wheel 25 | from .autoit import opt 26 | from .autoit import pixel_checksum 27 | from .autoit import pixel_get_color 28 | from .autoit import pixel_search 29 | from .autoit import send 30 | from .autoit import tooltip 31 | 32 | from .process import run 33 | from .process import run_wait 34 | from .process import process_close 35 | from .process import process_exists 36 | from .process import process_set_priority 37 | from .process import process_wait 38 | from .process import process_wait_close 39 | from .process import run_as 40 | from .process import run_as_wait 41 | from .process import shutdown 42 | 43 | from .win import win_activate 44 | from .win import win_activate_by_handle 45 | from .win import win_active 46 | from .win import win_active_by_handle 47 | from .win import win_close 48 | from .win import win_close_by_handle 49 | from .win import win_exists 50 | from .win import win_exists_by_handle 51 | from .win import win_get_caret_pos 52 | from .win import win_get_class_list 53 | from .win import win_get_class_list_by_handle 54 | from .win import win_get_client_size 55 | from .win import win_get_client_size_by_handle 56 | from .win import win_get_handle 57 | from .win import win_get_handle_as_text 58 | from .win import win_get_pos 59 | from .win import win_get_pos_by_handle 60 | from .win import win_get_process 61 | from .win import win_get_process_by_handle 62 | from .win import win_get_state 63 | from .win import win_get_state_by_handle 64 | from .win import win_get_text 65 | from .win import win_get_text_by_handle 66 | from .win import win_get_title 67 | from .win import win_get_title_by_handle 68 | from .win import win_kill 69 | from .win import win_kill_by_handle 70 | from .win import win_menu_select_item 71 | from .win import win_menu_select_item_by_handle 72 | from .win import win_minimize_all 73 | from .win import win_minimize_all_undo 74 | from .win import win_move 75 | from .win import win_move_by_handle 76 | from .win import win_set_on_top 77 | from .win import win_set_on_top_by_handle 78 | from .win import win_set_state 79 | from .win import win_set_state_by_handle 80 | from .win import win_set_title 81 | from .win import win_set_title_by_handle 82 | from .win import win_set_trans 83 | from .win import win_set_trans_by_handle 84 | from .win import win_wait 85 | from .win import win_wait_by_handle 86 | from .win import win_wait_active 87 | from .win import win_wait_active_by_handle 88 | from .win import win_wait_close 89 | from .win import win_wait_close_by_handle 90 | from .win import win_wait_not_active 91 | from .win import win_wait_not_active_by_handle 92 | 93 | from .control import control_click 94 | from .control import control_click_by_handle 95 | from .control import control_command 96 | from .control import control_command_by_handle 97 | from .control import control_list_view 98 | from .control import control_list_view_by_handle 99 | from .control import control_disable 100 | from .control import control_disable_by_handle 101 | from .control import control_enable 102 | from .control import control_enable_by_handle 103 | from .control import control_focus 104 | from .control import control_focus_by_handle 105 | from .control import control_get_focus 106 | from .control import control_get_focus_by_handle 107 | from .control import control_get_handle 108 | from .control import control_get_handle_as_text 109 | from .control import control_get_pos 110 | from .control import control_get_pos_by_handle 111 | from .control import control_get_text 112 | from .control import control_get_text_by_handle 113 | from .control import control_hide 114 | from .control import control_hide_by_handle 115 | from .control import control_move 116 | from .control import control_move_by_handle 117 | from .control import control_send 118 | from .control import control_send_by_handle 119 | from .control import control_set_text 120 | from .control import control_set_text_by_handle 121 | from .control import control_show 122 | from .control import control_show_by_handle 123 | from .control import control_tree_view 124 | from .control import control_tree_view_by_handle 125 | from .control import statusbar_get_text 126 | from .control import statusbar_get_text_by_handle -------------------------------------------------------------------------------- /FileFormatHandlers/test.py: -------------------------------------------------------------------------------- 1 | from xmlHandler import Handler 2 | xml = '''''' 3 | xml1 = '''''' 4 | h = Handler() 5 | while 1: 6 | raw_input('>>') 7 | print h.Fuzzit(xml) -------------------------------------------------------------------------------- /ExtDepLibs/autoit/process.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | __author__ = 'Jace Xu' 4 | 5 | from autoit import AUTO_IT 6 | from autoit import api, error 7 | from autoit import Properties 8 | from autoit import AutoItError 9 | from ctypes.wintypes import * 10 | 11 | 12 | @api.check(1, "run program failed") 13 | def run(filename, work_dir="", show_flag=Properties.SW_SHOWNORMAL): 14 | """ 15 | 16 | :param filename: 17 | :param work_dir: 18 | :param show_flag: 19 | :return: 20 | """ 21 | ret = AUTO_IT.AU3_Run(LPCWSTR(filename), LPCWSTR(work_dir), 22 | INT(show_flag)) 23 | return ret 24 | 25 | 26 | @api.check(1, "run program failed") 27 | def run_wait(filename, work_dir="", show_flag=Properties.SW_SHOWNORMAL): 28 | """ 29 | 30 | :param filename: 31 | :param work_dir: 32 | :param show_flag: 33 | :return: 34 | """ 35 | ret = AUTO_IT.AU3_RunWait(LPCWSTR(filename), LPCWSTR(work_dir), 36 | INT(show_flag)) 37 | return ret 38 | 39 | 40 | def process_close(process): 41 | """ 42 | Terminates a named process. 43 | """ 44 | ret = AUTO_IT.AU3_ProcessClose(LPCWSTR(process)) 45 | return ret 46 | 47 | 48 | def process_exists(process): 49 | """ 50 | 51 | :param process: 52 | :return: 53 | """ 54 | ret = AUTO_IT.AU3_ProcessExists(LPCWSTR(process)) 55 | return ret 56 | 57 | 58 | def process_set_priority(process, priority): 59 | """ 60 | Changes the priority of a process 61 | :param process: The name or PID of the process to check. 62 | :param priority:A flag which determines what priority to set 63 | 0 - Idle/Low 64 | 1 - Below Normal (Not supported on Windows 95/98/ME) 65 | 2 - Normal 66 | 3 - Above Normal (Not supported on Windows 95/98/ME) 67 | 4 - High 68 | 5 - Realtime (Use with caution, may make the system unstable) 69 | :return: 70 | """ 71 | ret = AUTO_IT.AU3_ProcessSetPriority(LPCWSTR(process), INT(priority)) 72 | if ret == 0: 73 | if error() == 1: 74 | raise AutoItError("set priority failed") 75 | elif error() == 2: 76 | raise AutoItError("unsupported priority class be used") 77 | return ret 78 | 79 | 80 | @api.check(2, "the process wait timed out") 81 | def process_wait(process, timeout=0): 82 | """ 83 | Pauses script execution until a given process exists. 84 | :param process: 85 | :param timeout: 86 | :return: 87 | """ 88 | ret = AUTO_IT.AU3_ProcessWait(LPCWSTR(process), INT(timeout)) 89 | return ret 90 | 91 | 92 | @api.check(2, "the process wait close timed out") 93 | def process_wait_close(process, timeout=0): 94 | """ 95 | Pauses script execution until a given process does not exist. 96 | :param process: 97 | :param timeout: 98 | :return: 99 | """ 100 | ret = AUTO_IT.AU3_ProcessWaitClose(LPCWSTR(process), INT(timeout)) 101 | return ret 102 | 103 | 104 | @api.check(1, "run an external program failed") 105 | def run_as(user, domain, password, filename, logon_flag=1, work_dir="", 106 | show_flag=Properties.SW_SHOWNORMAL): 107 | """ 108 | Runs an external program. 109 | :param user: username The user name to use. 110 | :param domain: The domain name to use. 111 | :param password: The password to use. 112 | :param logon_flag: 0 = do not load the user profile, 1 = (default) load 113 | the user profile, 2 = use for net credentials only 114 | :param filename: The name of the executable (EXE, BAT, COM, or PIF) to run. 115 | :param work_dir: The working directory. 116 | :param show_flag: The "show" flag of the executed program: 117 | SW_HIDE = Hidden window 118 | SW_MINIMIZE = Minimized window 119 | SW_MAXIMIZE = Maximized window 120 | :return: 121 | """ 122 | ret = AUTO_IT.AU3_RunAs( 123 | LPCWSTR(user), LPCWSTR(domain), LPCWSTR(password), INT(logon_flag), 124 | LPCWSTR(filename), LPCWSTR(work_dir), INT(show_flag) 125 | ) 126 | return ret 127 | 128 | 129 | @api.check(1, "run an external program failed") 130 | def run_as_wait(user, domain, password, filename, logon_flag=1, work_dir="", 131 | show_flag=Properties.SW_SHOWNORMAL): 132 | """ 133 | Runs an external program. 134 | :param user: username The user name to use. 135 | :param domain: The domain name to use. 136 | :param password: The password to use. 137 | :param logon_flag: 0 = do not load the user profile, 1 = (default) load 138 | the user profile, 2 = use for net credentials only 139 | :param filename: The name of the executable (EXE, BAT, COM, or PIF) to run. 140 | :param work_dir: The working directory. 141 | :param show_flag: The "show" flag of the executed program: 142 | SW_HIDE = Hidden window 143 | SW_MINIMIZE = Minimized window 144 | SW_MAXIMIZE = Maximized window 145 | :return: 146 | """ 147 | ret = AUTO_IT.AU3_RunAsWait( 148 | LPCWSTR(user), LPCWSTR(domain), LPCWSTR(password), INT(logon_flag), 149 | LPCWSTR(filename), LPCWSTR(work_dir), INT(show_flag) 150 | ) 151 | return ret 152 | 153 | 154 | @api.check(2, "set shutdown failed") 155 | def shutdown(code): 156 | """ 157 | 158 | :param code: The shutdown code is a combination of the following values: 159 | 0 = Logoff 160 | 1 = Shutdown 161 | 2 = Reboot 162 | 4 = Force 163 | 8 = Power down 164 | :return: 165 | """ 166 | ret = AUTO_IT.AU3_Shutdown(INT(code)) 167 | return ret -------------------------------------------------------------------------------- /Mutator.py: -------------------------------------------------------------------------------- 1 | ''' 2 | 3 | Copyright 2017 Debasish Mandal 4 | 5 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | 9 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 10 | 11 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 12 | 13 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 14 | 15 | ''' 16 | 17 | import os 18 | from random import randint 19 | from random import choice 20 | from random import randrange 21 | from collections import OrderedDict 22 | import imp 23 | from datetime import datetime 24 | from math import ceil 25 | from copy import copy 26 | from xml.etree import ElementTree as ET 27 | 28 | 29 | 30 | class Mutator: 31 | ''' 32 | 33 | This class is responsible for data mutation (depending on xml / binary format it will choose appropriate file format mutation hanlder) . Its uses provided file handlers to mutate data. 34 | 35 | ''' 36 | def __init__(self,OpenXML,handlers,files_to_be_fuzzed,no_of_files_to_be_fuzzed,auto_id_file_type,all_handlers,all_inmem_docs): 37 | self.oxml = OpenXML 38 | self.HANDLERS = handlers 39 | self.handler_obj_dict = {} 40 | self.AUTO_ID_FILE_TYPE = auto_id_file_type 41 | self.ALL_HANDLERS = all_handlers 42 | self.ALL_INMEM_DOCS = all_inmem_docs 43 | self.LoadFormatHandlers() 44 | self.FILES_TO_BE_FUZZED = files_to_be_fuzzed 45 | self.NUMBER_OF_FILES_TO_MUTATE = no_of_files_to_be_fuzzed 46 | 47 | def LoadFormatHandlers(self): 48 | if self.AUTO_ID_FILE_TYPE and self.oxml: 49 | print '[+]',datetime.now().strftime("%Y:%m:%d::%H:%M:%S"),'Trying to indentify base OpenXML internal file types and choosing mutation handler accordingly : ' 50 | for i in self.ALL_INMEM_DOCS: 51 | files = self.ALL_INMEM_DOCS[i] 52 | for inner_f in files: 53 | ext = inner_f.split('.')[-1] 54 | try: 55 | x = ET.fromstring(files[inner_f]) 56 | result_type = 'xml' 57 | print '[+]',datetime.now().strftime("%Y:%m:%d::%H:%M:%S"),'For extension : ',ext,', selecting mutation handler =>',self.ALL_HANDLERS[result_type] 58 | foo = imp.load_source('Handler', 'FileFormatHandlers//'+self.ALL_HANDLERS[result_type]) 59 | a = foo.Handler() 60 | self.handler_obj_dict[ext] = a 61 | except: 62 | # Its not an xml file try to find other hanlder 63 | result_type = 'bin' 64 | print '[+]',datetime.now().strftime("%Y:%m:%d::%H:%M:%S"),'For extension : ',ext,', selecting mutation handler =>',self.ALL_HANDLERS[result_type] 65 | foo = imp.load_source('Handler', 'FileFormatHandlers//'+self.ALL_HANDLERS[result_type]) 66 | a = foo.Handler() 67 | self.handler_obj_dict[ext] = a 68 | else: 69 | for handler in self.HANDLERS: 70 | try: 71 | print '[+]',datetime.now().strftime("%Y:%m:%d::%H:%M:%S"),'Loading File Format Handler for extension : ',handler,'=>',self.HANDLERS[handler] 72 | foo = imp.load_source('Handler', 'FileFormatHandlers//'+self.HANDLERS[handler]) 73 | a = foo.Handler() 74 | self.handler_obj_dict[handler] = a 75 | except: 76 | print '[+]',datetime.now().strftime("%Y:%m:%d::%H:%M:%S"),'There is an error in this Fileformat handler or it was not written correctly.','FileFormatHandlers//'+self.HANDLERS[handler], 'Please check FileFormatHandlers\\SampleHandler.py' 77 | exit() 78 | print '[+]',datetime.now().strftime("%Y:%m:%d::%H:%M:%S"),'Loading File Format Handler Done !!' 79 | def Mutate(self,office_doc_dict,file_name): 80 | ''' 81 | 82 | This function accepts an office doc, converted into a python dictionary. 83 | It decides which files of the office document to be fuzzed, Based on the file (xml or binary file) 84 | 85 | ''' 86 | if self.oxml: 87 | # The content sent here is OpenXML format. Hence we are 88 | fuzzed_office_file_dict = {} 89 | fuzzed_office_file_dict = copy(office_doc_dict) 90 | #NUMBER_OF_FILES_TO_MUTATE = 5 91 | if len(self.FILES_TO_BE_FUZZED) == 0: 92 | # Fuzz some files randomly choosen from entire open xml file. 93 | for file_count in range(0,self.NUMBER_OF_FILES_TO_MUTATE): 94 | target_file = choice(office_doc_dict.keys()) # The file 95 | ext = target_file.split('.')[-1] # Get the extension of the file. 96 | if ext in self.handler_obj_dict: # Check if format handler for the current format is present 97 | HandlerClass = self.handler_obj_dict[ext] # Get the File handler object from handler dict. 98 | fuzzed_office_file_dict[target_file] = HandlerClass.Fuzzit(office_doc_dict[target_file]) 99 | else: 100 | fuzzed_office_file_dict[target_file] = office_doc_dict[target_file] # Do not do anything. 101 | else: 102 | # Fuzz some files randomly chosen from the config. 103 | #NUMBER_OF_FILES_TO_MUTATE = 2 104 | for file_count in range(0,self.NUMBER_OF_FILES_TO_MUTATE): 105 | target_file = choice(self.FILES_TO_BE_FUZZED) 106 | #print target_file 107 | ext = target_file.split('.')[-1] # Find the extension of the file 108 | if ext in self.handler_obj_dict: # Check if format handler for the current format is present 109 | HandlerClass = self.handler_obj_dict[ext] # Get the handler object 110 | try: 111 | fuzzed_office_file_dict[target_file] = HandlerClass.Fuzzit(office_doc_dict[target_file]) 112 | except: 113 | print '[+]',datetime.now().strftime("%Y:%m:%d::%H:%M:%S"),'[Error] File not found in provided base openXML file',target_file,'Please check config file parameter FILES_TO_BE_FUZZED. You can Re-Generate FILES_TO_BE_FUZZED list using OXDumper.py' 114 | exit() 115 | else: 116 | fuzzed_office_file_dict[target_file] = office_doc_dict[target_file] # Do not do anything. 117 | return fuzzed_office_file_dict 118 | else: 119 | # Return a binary stream 120 | ext = file_name.split('.')[-1] 121 | HandlerClass = self.handler_obj_dict[ext] 122 | return self.handler_obj_dict[ext].Fuzzit(office_doc_dict) 123 | -------------------------------------------------------------------------------- /PopUpKiller.py: -------------------------------------------------------------------------------- 1 | ''' 2 | 3 | Copyright 2017 Debasish Mandal 4 | 5 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | 9 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 10 | 11 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 12 | 13 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 14 | 15 | ''' 16 | 17 | 18 | import sys 19 | try: 20 | sys.path.append('ExtDepLibs') 21 | import autoit 22 | except: 23 | print('[Error] pyautoit is not installed. Which is required to run this fuzzer (Error POPUp Killer). Install pyautoit First https://pypi.python.org/pypi/PyAutoIt/0.3') 24 | exit() 25 | from datetime import datetime 26 | class PopUpKiller: 27 | def __init__(self): 28 | None 29 | def POPUpKillerThread(self): 30 | print '[+] '+ datetime.now().strftime("%Y:%m:%d::%H:%M:%S") +' POP Up killer Thread started..' 31 | while True: 32 | try: 33 | # MS Word 34 | if "Word found unreadable" in autoit.win_get_text('Microsoft Word'): 35 | autoit.control_click("[Class:#32770]", "Button1") 36 | if "You cannot close Microsoft Word because" in autoit.win_get_text('Microsoft Word'): 37 | autoit.control_click("[Class:#32770]", "Button1") 38 | if "caused a serious error the last time it was opened" in autoit.win_get_text('Microsoft Word'): 39 | autoit.control_click("[Class:#32770]", "Button1") 40 | if "Word failed to start correctly last time" in autoit.win_get_text('Microsoft Word'): 41 | autoit.control_click("[Class:#32770]", "Button2") 42 | if "This file was created in a pre-release version" in autoit.win_get_text('Microsoft Word'): 43 | autoit.control_click("[Class:#32770]", "Button1") 44 | if "The program used to create this object is" in autoit.win_get_text('Microsoft Word'): 45 | autoit.control_click("[Class:#32770]", "Button1") 46 | if "Word experienced an error trying to open the file" in autoit.win_get_text('Microsoft Word'): 47 | autoit.control_click("[Class:#32770]", "Button1") 48 | if "experienced an error trying to open the file" in autoit.win_get_text('Microsoft Word'): 49 | autoit.control_click("[Class:#32770]", "Button1") 50 | if "Word was unable to read this document" in autoit.win_get_text('Microsoft Word'): 51 | autoit.control_click("[Class:#32770]", "Button1") 52 | if "The last time you" in autoit.win_get_text('Microsoft Word'): 53 | autoit.control_click("[Class:#32770]", "Button1") 54 | if "Safe mode could help you" in autoit.win_get_text('Microsoft Word'): 55 | autoit.control_click("[Class:#32770]", "Button2") 56 | if "You may continue opening it or perform" in autoit.win_get_text('Microsoft Word'): 57 | autoit.control_click("[Class:#32770]", "Button2") # Button2 Recover Data or Button1 Open 58 | #Outlook 59 | if "Safe mode" in autoit.win_get_text('Microsoft Outlook'): 60 | autoit.control_click("[Class:#32770]", "Button2") # Button2 Recover Data or Button1 Open 61 | if "Your mailbox has been" in autoit.win_get_text('Microsoft Exchange'): 62 | autoit.control_click("[Class:#32770]", "Button2") # Button2 Recover Data or Button1 Open 63 | 64 | # MS Excel 65 | if "Word found unreadable" in autoit.win_get_text('Microsoft Excel'): 66 | autoit.control_click("[Class:#32770]", "Button1") 67 | if "You cannot close Microsoft Word because" in autoit.win_get_text('Microsoft Excel'): 68 | autoit.control_click("[Class:#32770]", "Button1") 69 | if "caused a serious error the last time it was opened" in autoit.win_get_text('Microsoft Excel'): 70 | autoit.control_click("[Class:#32770]", "Button1") 71 | if "Word failed to start correctly last time" in autoit.win_get_text('Microsoft Excel'): 72 | autoit.control_click("[Class:#32770]", "Button2") 73 | if "This file was created in a pre-release version" in autoit.win_get_text('Microsoft Excel'): 74 | autoit.control_click("[Class:#32770]", "Button1") 75 | if "The program used to create this object is" in autoit.win_get_text('Microsoft Excel'): 76 | autoit.control_click("[Class:#32770]", "Button1") 77 | if "because the file format or file extension is not valid" in autoit.win_get_text('Microsoft Excel'): 78 | autoit.control_click("[Class:#32770]", "Button1") 79 | if "The file you are trying to open" in autoit.win_get_text('Microsoft Excel'): 80 | autoit.control_click("[Class:#32770]", "Button1") 81 | if "The file may be corrupted" in autoit.win_get_text('Microsoft Excel'): 82 | autoit.control_click("[Class:#32770]", "Button2") 83 | if "The last time you" in autoit.win_get_text('Microsoft Excel'): 84 | autoit.control_click("[Class:#32770]", "Button1") 85 | if "We found" in autoit.win_get_text('Microsoft Excel'): 86 | autoit.control_click("[Class:#32770]", "Button1") 87 | 88 | #PPT 89 | if "The last time you" in autoit.win_get_text('Microsoft PowerPoint'): 90 | autoit.control_click("[Class:#32770]", "Button1") 91 | if "PowerPoint found a problem with content" in autoit.win_get_text('Microsoft PowerPoint'): 92 | autoit.control_click("[Class:#32770]", "Button1") 93 | if "read some content" in autoit.win_get_text('Microsoft PowerPoint'): 94 | autoit.control_click("[Class:#32770]", "Button1") 95 | if "Sorry" in autoit.win_get_text('Microsoft PowerPoint'): 96 | autoit.control_click("[Class:#32770]", "Button1") 97 | if "PowerPoint" in autoit.win_get_text('Microsoft PowerPoint'): 98 | autoit.control_click("[Class:#32770]", "Button1") 99 | if "is not supported" in autoit.win_get_text('SmartArt Graphics'): 100 | autoit.control_click("[Class:#32770]", "Button2") 101 | if "Safe mode" in autoit.win_get_text('Microsoft PowerPoint'): 102 | autoit.control_click("[Class:#32770]", "Button2") # Button2 Recover Data or Button1 Open 103 | 104 | # Outlook 105 | 106 | # XPS Viewer 107 | if "Close" in autoit.win_get_text('XPS Viewer'): 108 | autoit.control_click("[Class:#32770]", "Button1") 109 | if "XPS" in autoit.win_get_text('XPS Viewer'): 110 | autoit.control_click("[Class:#32770]", "Button1") 111 | autoit.win_close('[CLASS:bosa_sdm_msword]') 112 | except: 113 | pass 114 | -------------------------------------------------------------------------------- /config.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | ''' 4 | 5 | Copyright 2017 Debasish Mandal 6 | 7 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 12 | 13 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 16 | 17 | ''' 18 | 19 | 20 | # Configuration file for OpenXMolar. 21 | 22 | 23 | # Folder where base office OpenXML files will be kept.(Example *.docx , *.xlsx etc.) 24 | packed_open_xml_office_files = 'BaseOfficeDocs\\OpenXMLFiles' 25 | 26 | # Folder where base office binary format files are kept. For example *.doc 27 | binary_office_files = 'BaseOfficeDocs\\OtherFileFormats' 28 | 29 | # Temporary folder where base office OpenXML files will be unpacked before they are loaded in memory. 30 | open_xml_office_files = 'BaseOfficeDocs\\UnpackedMSOpenXMLFormatFiles' 31 | 32 | # Temporary folder where Test cases will be kept, before they are opened. 33 | fuzztempfolder = 'FuzzTemp' 34 | 35 | 36 | # File format to be fuzzed. 37 | # If OpenXMLFormat is False, Base files will be taken from folder 'binary_office_files' 38 | # If OpenXMLFormat is True, Base files will be taken from folder 'open_xml_office_files' 39 | OpenXMLFormat = True 40 | 41 | #################################################################################################################### 42 | # This dictionary is holding the mapping between office application and extension. 43 | # While fuzzing, an application (exe) will be chosen from this dictionary based on extension of file(s) provided in folder 'open_xml_office_files' or 'binary_office_files' 44 | # Add your own extension and exe. :). Note: Make sure extension does not repeat. 45 | APP_LIST = { 46 | 'xps':r'C:\Windows\system32\xpsrchvw.exe', 47 | 'oxps':r'C:\Windows\system32\xpsrchvw.exe' 48 | } 49 | 50 | # A Python list of command line arguments to be used while running target application. To be left blank when none required. Example : COMMAND_LINE_ARGUMENT = ['arg1','arg2','arg3','arg4'] 51 | COMMAND_LINE_ARGUMENT = [] 52 | #################################################################################################################### 53 | 54 | 55 | ######################################################################################## 56 | # An Open XML file package may contain various files like XML files, Binary files etc. 57 | # When AUTO_IDENTIFY_INTERNAL_FILE_FORAMT is set to 'True', OpenXMolar will try to indentify types of files present inside provided base openxml packages and based on that decide, which mutation script to to use during fuzzing. 58 | AUTO_IDENTIFY_INTERNAL_FILE_FORAMT = True 59 | 60 | 61 | # Mutation script list. Once AUTO_IDENTIFY_INTERNAL_FILE_FORAMT is set to True, available mutation scripts and associated extensions has to be defined under ALL_MUTATION_SCRIPTS in dict format. 62 | 63 | ALL_MUTATION_SCRIPTS = {'xml':'SampleHandler.py','bin':'binaryHandler.py'} 64 | ######################################################################################### 65 | 66 | 67 | 68 | # Note: This is only required when AUTO_IDENTIFY_INTERNAL_FILE_FORAMT is set to False. 69 | # Following dict. holds a mapping between different file extension and a file which can parse the format and mutate its content (handler). 70 | # For example when the fuzzer will find a *.xml file inside an OpenXML document it will use '\FileFormatHandlers\SampleHandler.py' file to mutate the xml file. 71 | # While writing your own custom file format handler , please refer sample : \FileFormatHandlers\SampleHandler.py and README.md doc. 72 | # File format handler(s) should always be kept inside '\FileFormatHandlers\' folder. 73 | 74 | FILE_FORMAT_HANDLERS = {'xml':'SampleHandler.py','rels':'SampleHandler.py'} 75 | 76 | 77 | 78 | # Delay Between test case iteration; 79 | FUZZ_LOOP_DELAY = 0.5 # In Seconds 80 | 81 | 82 | # Run the application for n seconds, and monitor it. 83 | # Tip: MSOffice usually considered as heavy application. If you are not running this fuzzer on a very fast system, increase APP_RUN_TIME accordingly. 84 | APP_RUN_TIME = 1.5 # In seconds 85 | 86 | 87 | # Debugger to use for process monitoring. 88 | # Right now MSOXFuzz supports two debuggers, 'winappdbg' and 'pydbg'. Installing pydbg could be painful sometimes, so use 'winappdbg' proudly :) It works pretty good. 89 | DEBUGGER = 'winappdbg' 90 | 91 | # Number of files to be mutated inside any base OpenXML document. For better results keep it less, For example 2,3 or max 5. 92 | NUMBER_OF_FILES_TO_MUTATE = 2 93 | 94 | 95 | # In case if you want to target/fuzz one or more specific file(s) inside an OpenXML document, you need to provide the file name(s) in this list 'FILES_TO_BE_FUZZED' depending on base files present at packed_open_xml_office_files 96 | # For example in following OpenXML structure, if you want to target 'MXDC_Empty_PT.xml' & 'FixedDocument.fdoc' file. 97 | # The list would look something like this : FILES_TO_BE_FUZZED = ['MXDC_Empty_PT.xml','FixedDocument.fdoc'] 98 | # In case if you want to fuzz all files, keep it empty FILE_TO_BE_FUZZED = [] 99 | 100 | # Note: This is only required when OpenXMLFormat = True , config. file. 101 | # You can use OXDumper.py to generate this list. 102 | # Warning : When FILES_TO_BE_FUZZED is not empty , you must provide only one OpenXML file as base file. When provided multiple base file this list should be empty. 103 | # Please remember to change this list when you change the Basefile in OpenXML base file folder. packed_open_xml_office_files to avoid nasty errors. 104 | 105 | ################ Generated using OXDumper.py, You can simply copy paste follwing python file list to config file ##################### 106 | FILES_TO_BE_FUZZED = [] 107 | ################ File list ends ##################### 108 | ''' 109 | Sample OpenXML directory structure 110 | 111 | │ FixedDocumentSequence.fdseq 112 | │ [Content_Types].xml 113 | ├───Documents 114 | │ └───1 115 | │ │ FixedDocument.fdoc 116 | │ ├───Metadata 117 | │ │ Page1_Thumbnail.JPG 118 | │ ├───Pages 119 | │ │ │ 1.fpage 120 | │ │ └───_rels 121 | │ │ 1.fpage.rels 122 | │ ├───Resources 123 | │ │ └───Images 124 | │ │ 1.JPG 125 | │ └───_rels 126 | │ FixedDocument.fdoc.rels 127 | ├───Metadata 128 | │ Job_PT.xml 129 | │ MXDC_Empty_PT.xml 130 | ├───Resources 131 | │ _D1.dict 132 | └───_rels 133 | .rels 134 | FixedDocumentSequence.fdseq.rels 135 | 136 | ''' 137 | -------------------------------------------------------------------------------- /ExtDepLibs/winappdbg/win32/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # Copyright (c) 2009-2016, Mario Vilas 5 | # All rights reserved. 6 | # 7 | # Redistribution and use in source and binary forms, with or without 8 | # modification, are permitted provided that the following conditions are met: 9 | # 10 | # * Redistributions of source code must retain the above copyright notice, 11 | # this list of conditions and the following disclaimer. 12 | # * Redistributions in binary form must reproduce the above copyright 13 | # notice,this list of conditions and the following disclaimer in the 14 | # documentation and/or other materials provided with the distribution. 15 | # * Neither the name of the copyright holder nor the names of its 16 | # contributors may be used to endorse or promote products derived from 17 | # this software without specific prior written permission. 18 | # 19 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 | # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 23 | # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 | # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 | # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 | # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 | # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 | # POSSIBILITY OF SUCH DAMAGE. 30 | 31 | """ 32 | Debugging API wrappers in ctypes. 33 | """ 34 | 35 | #----------------------------------------------------------------------------- 36 | # Monkey patch for Cygwin, which does not load some features correctly since 37 | # it believes to be running on Linux. 38 | 39 | # Detect whether we need to patch or not. 40 | try: 41 | from ctypes import WINFUNCTYPE 42 | except ImportError: 43 | import ctypes 44 | 45 | # Fix FormatError. 46 | ##from _ctypes import FormatError 47 | ##ctypes.FormatError = FormatError 48 | 49 | # Fix FUNCFLAG_STDCALL. 50 | ctypes.FUNCFLAG_STDCALL = FUNCFLAG_STDCALL = _FUNCFLAG_STDCALL = 0 51 | 52 | # Fix WINFUNCTYPE. 53 | ctypes._win_functype_cache = {} 54 | def WINFUNCTYPE(restype, *argtypes, **kw): 55 | flags = _FUNCFLAG_STDCALL 56 | if kw.pop("use_errno", False): 57 | flags |= ctypes._FUNCFLAG_USE_ERRNO 58 | if kw.pop("use_last_error", False): 59 | flags |= ctypes._FUNCFLAG_USE_LASTERROR 60 | if kw: 61 | raise ValueError("unexpected keyword argument(s) %s" % kw.keys()) 62 | try: 63 | return ctypes._win_functype_cache[(restype, argtypes, flags)] 64 | except KeyError: 65 | class WinFunctionType(ctypes._CFuncPtr): 66 | _argtypes_ = argtypes 67 | _restype_ = restype 68 | _flags_ = flags 69 | ctypes._win_functype_cache[(restype, argtypes, flags)] = WinFunctionType 70 | return WinFunctionType 71 | if WINFUNCTYPE.__doc__: 72 | WINFUNCTYPE.__doc__ = ctypes.CFUNCTYPE.__doc__.replace( 73 | "CFUNCTYPE", "WINFUNCTYPE") 74 | ctypes.WINFUNCTYPE = WINFUNCTYPE 75 | 76 | # Fix _reset_cache. 77 | _original_reset_cache = ctypes._reset_cache 78 | def _reset_cache(): 79 | ctypes._win_functype_cache.clear() 80 | _original_reset_cache() 81 | ctypes._reset_cache = _reset_cache 82 | 83 | # Fix the string conversion mode. 84 | if hasattr(ctypes, "set_conversion_mode"): 85 | ctypes.set_conversion_mode("mbcs", "ignore") 86 | 87 | # Fix WinDLL. 88 | class WinDLL(ctypes.CDLL): 89 | """This class represents a dll exporting functions using the 90 | Windows stdcall calling convention. 91 | """ 92 | _func_flags_ = _FUNCFLAG_STDCALL 93 | ctypes.WinDLL = WinDLL 94 | 95 | # Fix HRESULT. 96 | from _ctypes import _SimpleCData 97 | class HRESULT(_SimpleCData): 98 | _type_ = "l" 99 | ##_check_retval_ = _check_HRESULT 100 | ctypes.HRESULT = HRESULT 101 | 102 | # Fix OleDLL. 103 | class OleDLL(ctypes.CDLL): 104 | """This class represents a dll exporting functions using the 105 | Windows stdcall calling convention, and returning HRESULT. 106 | HRESULT error values are automatically raised as WindowsError 107 | exceptions. 108 | """ 109 | _func_flags_ = _FUNCFLAG_STDCALL 110 | _func_restype_ = HRESULT 111 | ctypes.OleDLL = OleDLL 112 | 113 | # Fix windll, oledll and GetLastError. 114 | ctypes.windll = ctypes.LibraryLoader(WinDLL) 115 | ctypes.oledll = ctypes.LibraryLoader(OleDLL) 116 | ctypes.GetLastError = ctypes.windll.kernel32.GetLastError 117 | 118 | # Fix get_last_error and set_last_error. 119 | ctypes.get_last_error = ctypes.windll.kernel32.GetLastError 120 | ctypes.set_last_error = ctypes.windll.kernel32.SetLastError 121 | 122 | # Fix FormatError. 123 | def FormatError(code): 124 | code = int(long(code)) 125 | try: 126 | if GuessStringType.t_default == GuessStringType.t_ansi: 127 | FormatMessage = windll.kernel32.FormatMessageA 128 | FormatMessage.argtypes = [DWORD, LPVOID, DWORD, DWORD, LPSTR, DWORD] 129 | FormatMessage.restype = DWORD 130 | lpBuffer = ctypes.create_string_buffer(1024) 131 | else: 132 | FormatMessage = windll.kernel32.FormatMessageW 133 | FormatMessage.argtypes = [DWORD, LPVOID, DWORD, DWORD, LPWSTR, DWORD] 134 | FormatMessage.restype = DWORD 135 | lpBuffer = ctypes.create_unicode_buffer(1024) 136 | ##FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000 137 | ##FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200 138 | success = FormatMessage(0x1200, None, code, 0, lpBuffer, 1024) 139 | if success: 140 | return lpBuffer.value 141 | except Exception: 142 | pass 143 | if GuessStringType.t_default == GuessStringType.t_ansi: 144 | return "Error code 0x%.8X" % code 145 | return u"Error code 0x%.8X" % code 146 | ctypes.FormatError = FormatError 147 | 148 | # Fix WinError. 149 | def WinError(code=None, descr=None): 150 | if code is None: 151 | code = ctypes.GetLastError() 152 | if descr is None: 153 | descr = ctypes.FormatError(code).strip() 154 | return WindowsError(code, descr) 155 | ctypes.WinError = WinError 156 | 157 | # Fix DllGetClassObject. 158 | def DllGetClassObject(rclsid, riid, ppv): 159 | try: 160 | ccom = __import__( 161 | "comtypes.server.inprocserver", globals(), locals(), ['*']) 162 | except ImportError: 163 | return -2147221231 # CLASS_E_CLASSNOTAVAILABLE 164 | else: 165 | return ccom.DllGetClassObject(rclsid, riid, ppv) 166 | ctypes.DllGetClassObject = DllGetClassObject 167 | 168 | # Fix DllCanUnloadNow. 169 | def DllCanUnloadNow(): 170 | try: 171 | ccom = __import__( 172 | "comtypes.server.inprocserver", globals(), locals(), ['*']) 173 | except ImportError: 174 | return 0 # S_OK 175 | return ccom.DllCanUnloadNow() 176 | ctypes.DllCanUnloadNow = DllCanUnloadNow 177 | 178 | #----------------------------------------------------------------------------- 179 | 180 | # Import all submodules into this namespace. 181 | # Required for compatibility with older versions of WinAppDbg. 182 | import defines 183 | import kernel32 184 | import user32 185 | import advapi32 186 | import wtsapi32 187 | import shell32 188 | import shlwapi 189 | import psapi 190 | import dbghelp 191 | import ntdll 192 | 193 | # Import all symbols from submodules into this namespace. 194 | # Required for compatibility with older versions of WinAppDbg. 195 | from defines import * 196 | from kernel32 import * 197 | from user32 import * 198 | from advapi32 import * 199 | from wtsapi32 import * 200 | from shell32 import * 201 | from shlwapi import * 202 | from psapi import * 203 | from dbghelp import * 204 | from ntdll import * 205 | 206 | # This calculates the list of exported symbols. 207 | _all = set() 208 | _all.update(defines._all) 209 | _all.update(kernel32._all) 210 | _all.update(user32._all) 211 | _all.update(advapi32._all) 212 | _all.update(wtsapi32._all) 213 | _all.update(shell32._all) 214 | _all.update(shlwapi._all) 215 | _all.update(psapi._all) 216 | _all.update(dbghelp._all) 217 | _all.update(ntdll._all) 218 | __all__ = [_x for _x in _all if not _x.startswith('_')] 219 | __all__.sort() 220 | -------------------------------------------------------------------------------- /ExtDepLibs/winappdbg/__init__.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # Copyright (c) 2009-2016, Mario Vilas 5 | # All rights reserved. 6 | # 7 | # Redistribution and use in source and binary forms, with or without 8 | # modification, are permitted provided that the following conditions are met: 9 | # 10 | # * Redistributions of source code must retain the above copyright notice, 11 | # this list of conditions and the following disclaimer. 12 | # * Redistributions in binary form must reproduce the above copyright 13 | # notice,this list of conditions and the following disclaimer in the 14 | # documentation and/or other materials provided with the distribution. 15 | # * Neither the name of the copyright holder nor the names of its 16 | # contributors may be used to endorse or promote products derived from 17 | # this software without specific prior written permission. 18 | # 19 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 | # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 23 | # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 | # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 | # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 | # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 | # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 | # POSSIBILITY OF SUCH DAMAGE. 30 | 31 | """ 32 | Windows application debugging engine for Python. 33 | 34 | by Mario Vilas (mvilas at gmail.com) 35 | 36 | Project: U{https://github.com/MarioVilas/winappdbg/} 37 | 38 | Web: U{http://winappdbg.readthedocs.io/en/latest/} 39 | 40 | Blog: U{http://breakingcode.wordpress.com} 41 | 42 | @group Debugging: 43 | Debug, EventHandler, EventSift, DebugLog 44 | 45 | @group Instrumentation: 46 | System, Process, Thread, Module, Window, Registry 47 | 48 | @group Disassemblers: 49 | Disassembler, 50 | BeaEngine, DistormEngine, PyDasmEngine 51 | 52 | @group Crash reporting: 53 | Crash, CrashDump, CrashDAO, CrashDictionary 54 | 55 | @group Memory search: 56 | Search, 57 | Pattern, 58 | BytePattern, 59 | TextPattern, 60 | RegExpPattern, 61 | HexPattern 62 | 63 | @group Debug events: 64 | Event, 65 | NoEvent, 66 | CreateProcessEvent, 67 | CreateThreadEvent, 68 | ExitProcessEvent, 69 | ExitThreadEvent, 70 | LoadDLLEvent, 71 | UnloadDLLEvent, 72 | OutputDebugStringEvent, 73 | RIPEvent, 74 | ExceptionEvent 75 | 76 | @group Win32 API wrappers: 77 | win32, Handle, ProcessHandle, ThreadHandle, FileHandle 78 | 79 | @group Helpers: 80 | HexInput, HexOutput, HexDump, Color, Table, Logger, 81 | PathOperations, 82 | MemoryAddresses, 83 | CustomAddressIterator, 84 | DataAddressIterator, 85 | ImageAddressIterator, 86 | MappedAddressIterator, 87 | ExecutableAddressIterator, 88 | ReadableAddressIterator, 89 | WriteableAddressIterator, 90 | ExecutableAndWriteableAddressIterator, 91 | DebugRegister, 92 | Regenerator 93 | 94 | @group Warnings: 95 | MixedBitsWarning, BreakpointWarning, BreakpointCallbackWarning, 96 | EventCallbackWarning, DebugSymbolsWarning, CrashWarning 97 | 98 | @group Deprecated classes: 99 | CrashContainer, CrashTable, CrashTableMSSQL, 100 | VolatileCrashContainer, DummyCrashContainer 101 | 102 | @type version_number: float 103 | @var version_number: This WinAppDbg major and minor version, 104 | as a floating point number. Use this for compatibility checking. 105 | 106 | @type version: str 107 | @var version: This WinAppDbg release version, 108 | as a printable string. Use this to show to the user. 109 | 110 | @undocumented: plugins 111 | """ 112 | 113 | # List of all public symbols 114 | __all__ = [ 115 | # Library version 116 | 'version', 117 | 'version_number', 118 | 119 | # from breakpoint import * 120 | ## 'Breakpoint', 121 | ## 'CodeBreakpoint', 122 | ## 'PageBreakpoint', 123 | ## 'HardwareBreakpoint', 124 | ## 'Hook', 125 | ## 'ApiHook', 126 | ## 'BufferWatch', 127 | 'BreakpointWarning', 128 | 'BreakpointCallbackWarning', 129 | 130 | # from crash import * 131 | 'Crash', 132 | 'CrashWarning', 133 | 'CrashDictionary', 134 | 'CrashContainer', 135 | 'CrashTable', 136 | 'CrashTableMSSQL', 137 | 'VolatileCrashContainer', 138 | 'DummyCrashContainer', 139 | 140 | # from debug import * 141 | 'Debug', 142 | 'MixedBitsWarning', 143 | 144 | # from disasm import * 145 | 'Disassembler', 146 | 'BeaEngine', 147 | 'DistormEngine', 148 | 'PyDasmEngine', 149 | 150 | # from event import * 151 | 'EventHandler', 152 | 'EventSift', 153 | ## 'EventFactory', 154 | ## 'EventDispatcher', 155 | 'EventCallbackWarning', 156 | 'Event', 157 | ## 'NoEvent', 158 | 'CreateProcessEvent', 159 | 'CreateThreadEvent', 160 | 'ExitProcessEvent', 161 | 'ExitThreadEvent', 162 | 'LoadDLLEvent', 163 | 'UnloadDLLEvent', 164 | 'OutputDebugStringEvent', 165 | 'RIPEvent', 166 | 'ExceptionEvent', 167 | 168 | # from interactive import * 169 | ## 'ConsoleDebugger', 170 | 171 | # from module import * 172 | 'Module', 173 | 'DebugSymbolsWarning', 174 | 175 | # from process import * 176 | 'Process', 177 | 178 | # from system import * 179 | 'System', 180 | 181 | # from search import * 182 | 'Search', 183 | 'Pattern', 184 | 'BytePattern', 185 | 'TextPattern', 186 | 'RegExpPattern', 187 | 'HexPattern', 188 | 189 | # from registry import * 190 | 'Registry', 191 | 192 | # from textio import * 193 | 'HexDump', 194 | 'HexInput', 195 | 'HexOutput', 196 | 'Color', 197 | 'Table', 198 | 'CrashDump', 199 | 'DebugLog', 200 | 'Logger', 201 | 202 | # from thread import * 203 | 'Thread', 204 | 205 | # from util import * 206 | 'PathOperations', 207 | 'MemoryAddresses', 208 | 'CustomAddressIterator', 209 | 'DataAddressIterator', 210 | 'ImageAddressIterator', 211 | 'MappedAddressIterator', 212 | 'ExecutableAddressIterator', 213 | 'ReadableAddressIterator', 214 | 'WriteableAddressIterator', 215 | 'ExecutableAndWriteableAddressIterator', 216 | 'DebugRegister', 217 | 218 | # from window import * 219 | 'Window', 220 | 221 | # import win32 222 | 'win32', 223 | 224 | # from win32 import Handle, ProcessHandle, ThreadHandle, FileHandle 225 | 'Handle', 226 | 'ProcessHandle', 227 | 'ThreadHandle', 228 | 'FileHandle', 229 | ] 230 | 231 | # Import all public symbols 232 | from breakpoint import * 233 | from crash import * 234 | from debug import * 235 | from disasm import * 236 | from event import * 237 | from interactive import * 238 | from module import * 239 | from process import * 240 | from registry import * 241 | from system import * 242 | from search import * 243 | from textio import * 244 | from thread import * 245 | from util import * 246 | from window import * 247 | 248 | import win32 249 | from win32 import Handle, ProcessHandle, ThreadHandle, FileHandle 250 | 251 | try: 252 | # We need to ignore all warnings from this module because SQLAlchemy 253 | # became really picky in its latest versions regarding what we send it. 254 | import warnings 255 | with warnings.catch_warnings(): 256 | warnings.simplefilter("ignore") 257 | from sql import * 258 | __all__.append('CrashDAO') 259 | except ImportError: 260 | import warnings 261 | warnings.warn("No SQL database support present (missing dependencies?)", 262 | ImportWarning) 263 | 264 | # Library version 265 | version_number = 1.6 266 | version = "Version %s" % version_number 267 | -------------------------------------------------------------------------------- /ExtDepLibs/utils/crash_binning.py: -------------------------------------------------------------------------------- 1 | # 2 | # Crash Binning 3 | # Copyright (C) 2006 Pedram Amini 4 | # 5 | # $Id: crash_binning.py 193 2007-04-05 13:30:01Z cameron $ 6 | # 7 | # This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public 8 | # License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later 9 | # version. 10 | # 11 | # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied 12 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License along with this program; if not, write to the Free 15 | # Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16 | # 17 | 18 | ''' 19 | @author: Pedram Amini 20 | @license: GNU General Public License 2.0 or later 21 | @contact: pedram.amini@gmail.com 22 | @organization: www.openrce.org 23 | ''' 24 | 25 | import sys 26 | import zlib 27 | import cPickle 28 | 29 | class __crash_bin_struct__: 30 | exception_module = None 31 | exception_address = 0 32 | write_violation = 0 33 | violation_address = 0 34 | violation_thread_id = 0 35 | context = None 36 | context_dump = None 37 | disasm = None 38 | disasm_around = [] 39 | stack_unwind = [] 40 | seh_unwind = [] 41 | extra = None 42 | 43 | 44 | class crash_binning: 45 | ''' 46 | @todo: Add MySQL import/export. 47 | ''' 48 | 49 | bins = {} 50 | last_crash = None 51 | pydbg = None 52 | 53 | #################################################################################################################### 54 | def __init__ (self): 55 | ''' 56 | ''' 57 | 58 | self.bins = {} 59 | self.last_crash = None 60 | self.pydbg = None 61 | 62 | 63 | #################################################################################################################### 64 | def record_crash (self, pydbg, extra=None): 65 | ''' 66 | Given a PyDbg instantiation that at the current time is assumed to have "crashed" (access violation for example) 67 | record various details such as the disassemly around the violating address, the ID of the offending thread, the 68 | call stack and the SEH unwind. Store the recorded data in an internal dictionary, binning them by the exception 69 | address. 70 | 71 | @type pydbg: pydbg 72 | @param pydbg: Instance of pydbg 73 | @type extra: Mixed 74 | @param extra: (Optional, Def=None) Whatever extra data you want to store with this bin 75 | ''' 76 | 77 | self.pydbg = pydbg 78 | crash = __crash_bin_struct__() 79 | 80 | # add module name to the exception address. 81 | exception_module = pydbg.addr_to_module(pydbg.dbg.u.Exception.ExceptionRecord.ExceptionAddress) 82 | 83 | if exception_module: 84 | exception_module = exception_module.szModule 85 | else: 86 | exception_module = "[INVALID]" 87 | 88 | crash.exception_module = exception_module 89 | crash.exception_address = pydbg.dbg.u.Exception.ExceptionRecord.ExceptionAddress 90 | crash.write_violation = pydbg.dbg.u.Exception.ExceptionRecord.ExceptionInformation[0] 91 | crash.violation_address = pydbg.dbg.u.Exception.ExceptionRecord.ExceptionInformation[1] 92 | crash.violation_thread_id = pydbg.dbg.dwThreadId 93 | crash.context = pydbg.context 94 | crash.context_dump = pydbg.dump_context(pydbg.context, print_dots=False) 95 | crash.disasm = pydbg.disasm(crash.exception_address) 96 | crash.disasm_around = pydbg.disasm_around(crash.exception_address, 10) 97 | crash.stack_unwind = pydbg.stack_unwind() 98 | crash.seh_unwind = pydbg.seh_unwind() 99 | crash.extra = extra 100 | 101 | # add module names to the stack unwind. 102 | for i in xrange(len(crash.stack_unwind)): 103 | addr = crash.stack_unwind[i] 104 | module = pydbg.addr_to_module(addr) 105 | 106 | if module: 107 | module = module.szModule 108 | else: 109 | module = "[INVALID]" 110 | 111 | crash.stack_unwind[i] = "%s:%08x" % (module, addr) 112 | 113 | 114 | # add module names to the SEH unwind. 115 | for i in xrange(len(crash.seh_unwind)): 116 | (addr, handler) = crash.seh_unwind[i] 117 | 118 | module = pydbg.addr_to_module(handler) 119 | 120 | if module: 121 | module = module.szModule 122 | else: 123 | module = "[INVALID]" 124 | 125 | crash.seh_unwind[i] = (addr, handler, "%s:%08x" % (module, handler)) 126 | 127 | if not self.bins.has_key(crash.exception_address): 128 | self.bins[crash.exception_address] = [] 129 | 130 | self.bins[crash.exception_address].append(crash) 131 | self.last_crash = crash 132 | 133 | 134 | #################################################################################################################### 135 | def crash_synopsis (self, crash=None): 136 | ''' 137 | For the supplied crash, generate and return a report containing the disassemly around the violating address, 138 | the ID of the offending thread, the call stack and the SEH unwind. If not crash is specified, then call through 139 | to last_crash_synopsis() which returns the same information for the last recorded crash. 140 | 141 | @see: crash_synopsis() 142 | 143 | @type crash: __crash_bin_struct__ 144 | @param crash: (Optional, def=None) Crash object to generate report on 145 | 146 | @rtype: String 147 | @return: Crash report 148 | ''' 149 | 150 | if not crash: 151 | return self.last_crash_synopsis() 152 | 153 | if crash.write_violation: 154 | direction = "write to" 155 | else: 156 | direction = "read from" 157 | 158 | synopsis = "%s:%08x %s from thread %d caused access violation\nwhen attempting to %s 0x%08x\n\n" % \ 159 | ( 160 | crash.exception_module, \ 161 | crash.exception_address, \ 162 | crash.disasm, \ 163 | crash.violation_thread_id, \ 164 | direction, \ 165 | crash.violation_address \ 166 | ) 167 | 168 | synopsis += crash.context_dump 169 | 170 | synopsis += "\ndisasm around:\n" 171 | for (ea, inst) in crash.disasm_around: 172 | synopsis += "\t0x%08x %s\n" % (ea, inst) 173 | 174 | if len(crash.stack_unwind): 175 | synopsis += "\nstack unwind:\n" 176 | for entry in crash.stack_unwind: 177 | synopsis += "\t%s\n" % entry 178 | 179 | if len(crash.seh_unwind): 180 | synopsis += "\nSEH unwind:\n" 181 | for (addr, handler, handler_str) in crash.seh_unwind: 182 | synopsis += "\t%08x -> %s\n" % (addr, handler_str) 183 | 184 | return synopsis + "\n" 185 | 186 | 187 | #################################################################################################################### 188 | def export_file (self, file_name): 189 | ''' 190 | Dump the entire object structure to disk. 191 | 192 | @see: import_file() 193 | 194 | @type file_name: String 195 | @param file_name: File name to export to 196 | 197 | @rtype: crash_binning 198 | @return: self 199 | ''' 200 | 201 | # null out what we don't serialize but save copies to restore after dumping to disk. 202 | last_crash = self.last_crash 203 | pydbg = self.pydbg 204 | 205 | self.last_crash = self.pydbg = None 206 | 207 | fh = open(file_name, "wb+") 208 | fh.write(zlib.compress(cPickle.dumps(self, protocol=2))) 209 | fh.close() 210 | 211 | self.last_crash = last_crash 212 | self.pydbg = pydbg 213 | 214 | return self 215 | 216 | 217 | #################################################################################################################### 218 | def import_file (self, file_name): 219 | ''' 220 | Load the entire object structure from disk. 221 | 222 | @see: export_file() 223 | 224 | @type file_name: String 225 | @param file_name: File name to import from 226 | 227 | @rtype: crash_binning 228 | @return: self 229 | ''' 230 | 231 | fh = open(file_name, "rb") 232 | tmp = cPickle.loads(zlib.decompress(fh.read())) 233 | fh.close() 234 | 235 | self.bins = tmp.bins 236 | 237 | return self 238 | 239 | 240 | #################################################################################################################### 241 | def last_crash_synopsis (self): 242 | ''' 243 | For the last recorded crash, generate and return a report containing the disassemly around the violating 244 | address, the ID of the offending thread, the call stack and the SEH unwind. 245 | 246 | @see: crash_synopsis() 247 | 248 | @rtype: String 249 | @return: Crash report 250 | ''' 251 | 252 | if self.last_crash.write_violation: 253 | direction = "write to" 254 | else: 255 | direction = "read from" 256 | 257 | synopsis = "%s:%08x %s from thread %d caused access violation\nwhen attempting to %s 0x%08x\n\n" % \ 258 | ( 259 | self.last_crash.exception_module, \ 260 | self.last_crash.exception_address, \ 261 | self.last_crash.disasm, \ 262 | self.last_crash.violation_thread_id, \ 263 | direction, \ 264 | self.last_crash.violation_address \ 265 | ) 266 | 267 | synopsis += self.last_crash.context_dump 268 | 269 | synopsis += "\ndisasm around:\n" 270 | for (ea, inst) in self.last_crash.disasm_around: 271 | synopsis += "\t0x%08x %s\n" % (ea, inst) 272 | 273 | if len(self.last_crash.stack_unwind): 274 | synopsis += "\nstack unwind:\n" 275 | for entry in self.last_crash.stack_unwind: 276 | synopsis += "\t%s\n" % entry 277 | 278 | if len(self.last_crash.seh_unwind): 279 | synopsis += "\nSEH unwind:\n" 280 | for (addr, handler, handler_str) in self.last_crash.seh_unwind: 281 | try: 282 | disasm = self.pydbg.disasm(handler) 283 | except: 284 | disasm = "[INVALID]" 285 | 286 | synopsis += "\t%08x -> %s %s\n" % (addr, handler_str, disasm) 287 | 288 | return synopsis + "\n" -------------------------------------------------------------------------------- /ExtDepLibs/winappdbg/win32/wtsapi32.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # Copyright (c) 2009-2016, Mario Vilas 5 | # All rights reserved. 6 | # 7 | # Redistribution and use in source and binary forms, with or without 8 | # modification, are permitted provided that the following conditions are met: 9 | # 10 | # * Redistributions of source code must retain the above copyright notice, 11 | # this list of conditions and the following disclaimer. 12 | # * Redistributions in binary form must reproduce the above copyright 13 | # notice,this list of conditions and the following disclaimer in the 14 | # documentation and/or other materials provided with the distribution. 15 | # * Neither the name of the copyright holder nor the names of its 16 | # contributors may be used to endorse or promote products derived from 17 | # this software without specific prior written permission. 18 | # 19 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 | # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 23 | # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 | # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 | # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 | # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 | # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 | # POSSIBILITY OF SUCH DAMAGE. 30 | 31 | """ 32 | Wrapper for wtsapi32.dll in ctypes. 33 | """ 34 | 35 | from defines import * 36 | from advapi32 import * 37 | 38 | #============================================================================== 39 | # This is used later on to calculate the list of exported symbols. 40 | _all = None 41 | _all = set(vars().keys()) 42 | #============================================================================== 43 | 44 | #--- Constants ---------------------------------------------------------------- 45 | 46 | WTS_CURRENT_SERVER_HANDLE = 0 47 | WTS_CURRENT_SESSION = 1 48 | 49 | #--- WTS_PROCESS_INFO structure ----------------------------------------------- 50 | 51 | # typedef struct _WTS_PROCESS_INFO { 52 | # DWORD SessionId; 53 | # DWORD ProcessId; 54 | # LPTSTR pProcessName; 55 | # PSID pUserSid; 56 | # } WTS_PROCESS_INFO, *PWTS_PROCESS_INFO; 57 | 58 | class WTS_PROCESS_INFOA(Structure): 59 | _fields_ = [ 60 | ("SessionId", DWORD), 61 | ("ProcessId", DWORD), 62 | ("pProcessName", LPSTR), 63 | ("pUserSid", PSID), 64 | ] 65 | PWTS_PROCESS_INFOA = POINTER(WTS_PROCESS_INFOA) 66 | 67 | class WTS_PROCESS_INFOW(Structure): 68 | _fields_ = [ 69 | ("SessionId", DWORD), 70 | ("ProcessId", DWORD), 71 | ("pProcessName", LPWSTR), 72 | ("pUserSid", PSID), 73 | ] 74 | PWTS_PROCESS_INFOW = POINTER(WTS_PROCESS_INFOW) 75 | 76 | #--- WTSQuerySessionInformation enums and structures -------------------------- 77 | 78 | # typedef enum _WTS_INFO_CLASS { 79 | # WTSInitialProgram = 0, 80 | # WTSApplicationName = 1, 81 | # WTSWorkingDirectory = 2, 82 | # WTSOEMId = 3, 83 | # WTSSessionId = 4, 84 | # WTSUserName = 5, 85 | # WTSWinStationName = 6, 86 | # WTSDomainName = 7, 87 | # WTSConnectState = 8, 88 | # WTSClientBuildNumber = 9, 89 | # WTSClientName = 10, 90 | # WTSClientDirectory = 11, 91 | # WTSClientProductId = 12, 92 | # WTSClientHardwareId = 13, 93 | # WTSClientAddress = 14, 94 | # WTSClientDisplay = 15, 95 | # WTSClientProtocolType = 16, 96 | # WTSIdleTime = 17, 97 | # WTSLogonTime = 18, 98 | # WTSIncomingBytes = 19, 99 | # WTSOutgoingBytes = 20, 100 | # WTSIncomingFrames = 21, 101 | # WTSOutgoingFrames = 22, 102 | # WTSClientInfo = 23, 103 | # WTSSessionInfo = 24, 104 | # WTSSessionInfoEx = 25, 105 | # WTSConfigInfo = 26, 106 | # WTSValidationInfo = 27, 107 | # WTSSessionAddressV4 = 28, 108 | # WTSIsRemoteSession = 29 109 | # } WTS_INFO_CLASS; 110 | 111 | WTSInitialProgram = 0 112 | WTSApplicationName = 1 113 | WTSWorkingDirectory = 2 114 | WTSOEMId = 3 115 | WTSSessionId = 4 116 | WTSUserName = 5 117 | WTSWinStationName = 6 118 | WTSDomainName = 7 119 | WTSConnectState = 8 120 | WTSClientBuildNumber = 9 121 | WTSClientName = 10 122 | WTSClientDirectory = 11 123 | WTSClientProductId = 12 124 | WTSClientHardwareId = 13 125 | WTSClientAddress = 14 126 | WTSClientDisplay = 15 127 | WTSClientProtocolType = 16 128 | WTSIdleTime = 17 129 | WTSLogonTime = 18 130 | WTSIncomingBytes = 19 131 | WTSOutgoingBytes = 20 132 | WTSIncomingFrames = 21 133 | WTSOutgoingFrames = 22 134 | WTSClientInfo = 23 135 | WTSSessionInfo = 24 136 | WTSSessionInfoEx = 25 137 | WTSConfigInfo = 26 138 | WTSValidationInfo = 27 139 | WTSSessionAddressV4 = 28 140 | WTSIsRemoteSession = 29 141 | 142 | WTS_INFO_CLASS = ctypes.c_int 143 | 144 | # typedef enum _WTS_CONNECTSTATE_CLASS { 145 | # WTSActive, 146 | # WTSConnected, 147 | # WTSConnectQuery, 148 | # WTSShadow, 149 | # WTSDisconnected, 150 | # WTSIdle, 151 | # WTSListen, 152 | # WTSReset, 153 | # WTSDown, 154 | # WTSInit 155 | # } WTS_CONNECTSTATE_CLASS; 156 | 157 | WTSActive = 0 158 | WTSConnected = 1 159 | WTSConnectQuery = 2 160 | WTSShadow = 3 161 | WTSDisconnected = 4 162 | WTSIdle = 5 163 | WTSListen = 6 164 | WTSReset = 7 165 | WTSDown = 8 166 | WTSInit = 9 167 | 168 | WTS_CONNECTSTATE_CLASS = ctypes.c_int 169 | 170 | # typedef struct _WTS_CLIENT_DISPLAY { 171 | # DWORD HorizontalResolution; 172 | # DWORD VerticalResolution; 173 | # DWORD ColorDepth; 174 | # } WTS_CLIENT_DISPLAY, *PWTS_CLIENT_DISPLAY; 175 | class WTS_CLIENT_DISPLAY(Structure): 176 | _fields_ = [ 177 | ("HorizontalResolution", DWORD), 178 | ("VerticalResolution", DWORD), 179 | ("ColorDepth", DWORD), 180 | ] 181 | PWTS_CLIENT_DISPLAY = POINTER(WTS_CLIENT_DISPLAY) 182 | 183 | # typedef struct _WTS_CLIENT_ADDRESS { 184 | # DWORD AddressFamily; 185 | # BYTE Address[20]; 186 | # } WTS_CLIENT_ADDRESS, *PWTS_CLIENT_ADDRESS; 187 | 188 | # XXX TODO 189 | 190 | # typedef struct _WTSCLIENT { 191 | # WCHAR ClientName[CLIENTNAME_LENGTH + 1]; 192 | # WCHAR Domain[DOMAIN_LENGTH + 1 ]; 193 | # WCHAR UserName[USERNAME_LENGTH + 1]; 194 | # WCHAR WorkDirectory[MAX_PATH + 1]; 195 | # WCHAR InitialProgram[MAX_PATH + 1]; 196 | # BYTE EncryptionLevel; 197 | # ULONG ClientAddressFamily; 198 | # USHORT ClientAddress[CLIENTADDRESS_LENGTH + 1]; 199 | # USHORT HRes; 200 | # USHORT VRes; 201 | # USHORT ColorDepth; 202 | # WCHAR ClientDirectory[MAX_PATH + 1]; 203 | # ULONG ClientBuildNumber; 204 | # ULONG ClientHardwareId; 205 | # USHORT ClientProductId; 206 | # USHORT OutBufCountHost; 207 | # USHORT OutBufCountClient; 208 | # USHORT OutBufLength; 209 | # WCHAR DeviceId[MAX_PATH + 1]; 210 | # } WTSCLIENT, *PWTSCLIENT; 211 | 212 | # XXX TODO 213 | 214 | # typedef struct _WTSINFO { 215 | # WTS_CONNECTSTATE_CLASS State; 216 | # DWORD SessionId; 217 | # DWORD IncomingBytes; 218 | # DWORD OutgoingBytes; 219 | # DWORD IncomingCompressedBytes; 220 | # DWORD OutgoingCompressedBytes; 221 | # WCHAR WinStationName; 222 | # WCHAR Domain; 223 | # WCHAR UserName; 224 | # LARGE_INTEGER ConnectTime; 225 | # LARGE_INTEGER DisconnectTime; 226 | # LARGE_INTEGER LastInputTime; 227 | # LARGE_INTEGER LogonTime; 228 | # LARGE_INTEGER CurrentTime; 229 | # } WTSINFO, *PWTSINFO; 230 | 231 | # XXX TODO 232 | 233 | # typedef struct _WTSINFOEX { 234 | # DWORD Level; 235 | # WTSINFOEX_LEVEL Data; 236 | # } WTSINFOEX, *PWTSINFOEX; 237 | 238 | # XXX TODO 239 | 240 | #--- wtsapi32.dll ------------------------------------------------------------- 241 | 242 | # void WTSFreeMemory( 243 | # __in PVOID pMemory 244 | # ); 245 | def WTSFreeMemory(pMemory): 246 | _WTSFreeMemory = windll.wtsapi32.WTSFreeMemory 247 | _WTSFreeMemory.argtypes = [PVOID] 248 | _WTSFreeMemory.restype = None 249 | _WTSFreeMemory(pMemory) 250 | 251 | # BOOL WTSEnumerateProcesses( 252 | # __in HANDLE hServer, 253 | # __in DWORD Reserved, 254 | # __in DWORD Version, 255 | # __out PWTS_PROCESS_INFO *ppProcessInfo, 256 | # __out DWORD *pCount 257 | # ); 258 | def WTSEnumerateProcessesA(hServer = WTS_CURRENT_SERVER_HANDLE): 259 | _WTSEnumerateProcessesA = windll.wtsapi32.WTSEnumerateProcessesA 260 | _WTSEnumerateProcessesA.argtypes = [HANDLE, DWORD, DWORD, POINTER(PWTS_PROCESS_INFOA), PDWORD] 261 | _WTSEnumerateProcessesA.restype = bool 262 | _WTSEnumerateProcessesA.errcheck = RaiseIfZero 263 | 264 | pProcessInfo = PWTS_PROCESS_INFOA() 265 | Count = DWORD(0) 266 | _WTSEnumerateProcessesA(hServer, 0, 1, byref(pProcessInfo), byref(Count)) 267 | return pProcessInfo, Count.value 268 | 269 | def WTSEnumerateProcessesW(hServer = WTS_CURRENT_SERVER_HANDLE): 270 | _WTSEnumerateProcessesW = windll.wtsapi32.WTSEnumerateProcessesW 271 | _WTSEnumerateProcessesW.argtypes = [HANDLE, DWORD, DWORD, POINTER(PWTS_PROCESS_INFOW), PDWORD] 272 | _WTSEnumerateProcessesW.restype = bool 273 | _WTSEnumerateProcessesW.errcheck = RaiseIfZero 274 | 275 | pProcessInfo = PWTS_PROCESS_INFOW() 276 | Count = DWORD(0) 277 | _WTSEnumerateProcessesW(hServer, 0, 1, byref(pProcessInfo), byref(Count)) 278 | return pProcessInfo, Count.value 279 | 280 | WTSEnumerateProcesses = DefaultStringType(WTSEnumerateProcessesA, WTSEnumerateProcessesW) 281 | 282 | # BOOL WTSTerminateProcess( 283 | # __in HANDLE hServer, 284 | # __in DWORD ProcessId, 285 | # __in DWORD ExitCode 286 | # ); 287 | def WTSTerminateProcess(hServer, ProcessId, ExitCode): 288 | _WTSTerminateProcess = windll.wtsapi32.WTSTerminateProcess 289 | _WTSTerminateProcess.argtypes = [HANDLE, DWORD, DWORD] 290 | _WTSTerminateProcess.restype = bool 291 | _WTSTerminateProcess.errcheck = RaiseIfZero 292 | _WTSTerminateProcess(hServer, ProcessId, ExitCode) 293 | 294 | # BOOL WTSQuerySessionInformation( 295 | # __in HANDLE hServer, 296 | # __in DWORD SessionId, 297 | # __in WTS_INFO_CLASS WTSInfoClass, 298 | # __out LPTSTR *ppBuffer, 299 | # __out DWORD *pBytesReturned 300 | # ); 301 | 302 | # XXX TODO 303 | 304 | #--- kernel32.dll ------------------------------------------------------------- 305 | 306 | # I've no idea why these functions are in kernel32.dll instead of wtsapi32.dll 307 | 308 | # BOOL ProcessIdToSessionId( 309 | # __in DWORD dwProcessId, 310 | # __out DWORD *pSessionId 311 | # ); 312 | def ProcessIdToSessionId(dwProcessId): 313 | _ProcessIdToSessionId = windll.kernel32.ProcessIdToSessionId 314 | _ProcessIdToSessionId.argtypes = [DWORD, PDWORD] 315 | _ProcessIdToSessionId.restype = bool 316 | _ProcessIdToSessionId.errcheck = RaiseIfZero 317 | 318 | dwSessionId = DWORD(0) 319 | _ProcessIdToSessionId(dwProcessId, byref(dwSessionId)) 320 | return dwSessionId.value 321 | 322 | # DWORD WTSGetActiveConsoleSessionId(void); 323 | def WTSGetActiveConsoleSessionId(): 324 | _WTSGetActiveConsoleSessionId = windll.kernel32.WTSGetActiveConsoleSessionId 325 | _WTSGetActiveConsoleSessionId.argtypes = [] 326 | _WTSGetActiveConsoleSessionId.restype = DWORD 327 | _WTSGetActiveConsoleSessionId.errcheck = RaiseIfZero 328 | return _WTSGetActiveConsoleSessionId() 329 | 330 | #============================================================================== 331 | # This calculates the list of exported symbols. 332 | _all = set(vars().keys()).difference(_all) 333 | __all__ = [_x for _x in _all if not _x.startswith('_')] 334 | __all__.sort() 335 | #============================================================================== 336 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | i) OpenXMolar v 1.0 2 | ======================= 3 | 4 | ![alt text](https://github.com/debasishm89/OpenXMolar/blob/master/screens/logo.PNG "OpenXMolar") 5 | 6 | OpenXMolar is a [Microsoft Open XML](https://en.wikipedia.org/wiki/Office_Open_XML) file format fuzzing framework, written in Python. 7 | 8 | 9 | ii) Motivation Behind OpenXMolar 10 | ========================================= 11 | MS OpenXML office files are widely used and the attack surface is huge, due to complexity of the softwares that supports OpenXML format. Office Open XML files are zipped, XML-based file format. I could not find any easy to use OpenXML auditing tools/framework available on the internet which provides software security auditors a easy to use platform using which auditors can write their own test cases and tweak internal structure of Open XML files and run fuzz test (Example : Microsoft Office). 12 | 13 | Hence OpenXMolar was developed, using which software security auditors can focus, only on writing test cases for tweaking OpenXML internal (XML and other ) files and the framework takes care of rest of the things like unpacking, packing of OpenXML files, Error handling, etc. 14 | 15 | iii) Dependencies 16 | ================== 17 | OpenXMolar is written and tested on Python v2.7. OpenXMolar uses following third party libraries 18 | 19 | 1. [winappdbg](https://github.com/MarioVilas/winappdbg) / [pydbg](https://github.com/OpenRCE/pydbg) 20 | 21 | Debugger is an immense part of any Fuzzer. Open X-Molar supports two python debugger, one is winappdbg and another is pydbg. Sometimes installing pydbg on windows environment can be painful, and pydbg code base is not well maintained hence winappdbg support added to Open X-Molar. Its recommended that user use winappdbg. 22 | 23 | 2. [pyautoit](https://pypi.python.org/pypi/PyAutoIt/0.3) 24 | 25 | Since we feed random yet valid data into target application during fuzzing, target application reacts in many different ways. During fuzzing the target application may throw different errors through different pop-up windows. To continue the fuzzing process, the fuzzer must handle these pop-up error windows properly. OpenXMolar uses PyAutoIT to suppress different application pop-up windows. PyAutoIt is Python binding for AutoItX3.dll 26 | 27 | 3. [crash_binning.py](https://github.com/OpenRCE/sulley) 28 | 29 | crash_binning is part of sulley framework. crash_binning.py is used only when you've selected pydbg as debugger. crash_binning.py is used to dump crash information. This is only required when you are using pydbg as debugger. 30 | 31 | 4. [xmltodict](https://github.com/martinblech/xmltodict) 32 | 33 | This is not core part of the Open X-Molar. The XML String Mutation module (FileFormatHandlers\xmlHandler.py) was written using xmltodict library. 34 | 35 | 36 | 37 | iv) Architecture: 38 | ================= 39 | 40 | On a high level, OpenXMolar can be divided into few components. 41 | 42 | 1. OpenXMolar.py 43 | 44 | This is the core component of this Tool and responsible for doing many important stuffs like the main fuzzing loop. 45 | 46 | 2. OfficeFileProcessor.py 47 | 48 | This component mostly handles processing of OpenXML document such as packing, unpacking of openxml files, mapping them in memory, converting OpenXML document to python data structures etc. 49 | 50 | 51 | 3. PopUpKiller.py - PopUp/Error Message Handlers : 52 | 53 | This component suppresses/kills unwanted pop-ups appeared during fuzzing. 54 | 55 | 4. FileFormatHandlers// 56 | 57 | An OpenXML file may contain various files like XML files, Binary files etc. FileFormatHandlers are basically a collection of mutation scripts, responsible for handling different files found inside an OpenXML document and mutate them. 58 | 59 | 60 | 5. OXDumper.py 61 | 62 | OXDumper.py decompresses OpenXML files provided in folder "OpenXMolar\\BaseOfficeDocs\\OpenXMLFiles" and output a python list of files present in the OpenXML file. OXDumper.py accepts comma separated file extensions. 63 | OXDumper.py is useful when you are targeting any specific set of files present in any OpenXML document. 64 | 65 | 6. crashSummary.py 66 | 67 | crashSummary.py summarizes crashes found during fuzzing process in tabular format. The output of crashSummary.py should look like this: 68 | 69 | ![alt text](https://github.com/debasishm89/OpenXMolar/blob/master/screens/CrashSummary.png "CrashSummary") 70 | 71 | 72 | 73 | v) Configuration File Walk through 74 | ================================= 75 | The default configuration file '[config.py](https://github.com/debasishm89/OpenXMolar/blob/master/config.py)' is very well commented and explains all of its parameters really well. Please review the default config.py file thoroughly before running the fuzzer to avoid unwanted errors. 76 | 77 | 78 | vi) Writing your Open XML internal File Mutation Scripts: 79 | ========================================================== 80 | 81 | As said earlier, an OpenXML file package may contain various files like XML files, Binary files etc. FileFormatHandlers are basically a collection of mutation scripts, responsible for handling different files found inside an OpenXML document and mutate them. Generating effective test cases is the most important step in any fuzz testing process. 82 | 83 | The motive behind OpenXMolar was to provide security auditors an easy & flexible platform on which fuzz tester can write their own test cases very easily for OpenXML files. When it comes to effective OpenXML format fuzzing, the main part is how we mutate different files (*.xml, *.bin etc) present inside OpenXML package (zip alike). To give users an idea of how file format handlers are written, two file format handlers are provided with this fuzzer, however they are very dumb in nature and not very effective. 84 | 85 | | FileHandler | Description | 86 | | ------ | ------ | 87 | | xmlHandler.py | Responsible for mutation of XML files. | 88 | | binaryHandler.py | Responsible for mutation of binary format files. | 89 | | SampleHandler.py | Blank file format handler template | 90 | 91 | 92 | Any file format handler module should be of following structure 93 | ```python 94 | # Import whatever you want. 95 | class Handler():# The class name should be always 'Handler' 96 | def __init__(self): 97 | pass 98 | def Fuzzit(self,actual_data_stream): 99 | # A function called Fuzzit must be present in Handler class 100 | # and it should return fuzzed data/xml string/whatever. 101 | # Note: Data type of actual_data_stream and data_after_mutation should always be same. 102 | 103 | return data_after_mutation 104 | 105 | ``` 106 | 107 | Once your file format handler module is ready you need to place the *.py file in FileFormatHandlers// folder and add the handler entry and associated file extension in config.py file like this : 108 | 109 | ```python 110 | FILE_FORMAT_HANDLERS = {'xml':'xmlHandler.py', 111 | 'bin':'BinaryHandler.py', 112 | 'rels':'xmlHandler.py', 113 | 'vml':'xmlHandler.py' 114 | } 115 | ``` 116 | 117 | vii)Adding More POPUP / Errors Windows Handler 118 | =============================================== 119 | 120 | The default PopUpKiller.py file provided with Open X-Molar, is having few most occurred pop up / error windows handler for MS Word, MS Excel & Power Point. Using AutoIT Window Info tool (https://www.autoitscript.com/site/autoit/downloads/) you can add more POPUP / Errors Windows Handlers into 'PopUpKiller.py'. One example is given below. 121 | 122 | ![alt text](https://github.com/debasishm89/OpenXMolar/blob/master/screens/popuphandler.PNG "OpenXMolar") 123 | 124 | So to be able to Handle the error pop up window shown in screen shot, following lines need to be added in : PopUpKiller.py 125 | 126 | ```python 127 | if "PowerPoint found a problem with content" in autoit.win_get_text('Microsoft PowerPoint'): 128 | autoit.control_click("[Class:#32770]", "Button1") 129 | 130 | ``` 131 | 132 | 133 | 134 | viii)The First Run 135 | =================== 136 | This fuzzer is well tested on 32 Bit and 64 Bit Windows Platforms (32 Bit Office Process). All the required libraries are distributed with this fuzzer in 'ExtDepLibs/' folder. Hence if you have installed python v2.7, you are good to go. 137 | 138 | To verify everything is at right place, better to run Open X-Molar with Microsoft Default XPS Viewer first time(C:\\Windows\\System32\\xpsrchvw.exe). Place any *.oxps file in '\BaseOfficeDocs\OpenXMLOfficeFiles' and run OpenXMolar.py. 139 | 140 | OpenXMolar.py accepts one command line argument which is the configuration file. 141 | 142 | ```sh 143 | C:\Users\John\Desktop\OpenXMolar>python OpenXMolar.py config.py 144 | 145 | [Warning] Pydbg was not found. Which is required to run this fuzzer. Install Pydbg First. Ignore if you have winappdbg installed. 146 | 147 | ____ __ ____ __ _ 148 | / __ \ \ \ / / \/ | | | 149 | | | | |_ __ ___ _ __ \ V /| \ / | ___ | | __ _ _ __ 150 | | | | | '_ \ / _ \ '_ \ > < | |\/| |/ _ \| |/ _` | '__| 151 | | |__| | |_) | __/ | | | / . \| | | | (_) | | (_| | | 152 | \____/| .__/ \___|_| |_| /_/ \_\_| |_|\___/|_|\__,_|_| 153 | | | 154 | |_| 155 | An MS OpenXML File Format Fuzzing Framework. 156 | Author : Debasish Mandal (twitter.com/debasishm89) 157 | 158 | [+] 2017:05:05::23:11:23 Using debugger : winappdbg 159 | [+] 2017:05:05::23:11:23 POP Up killer Thread started.. 160 | [+] 2017:05:05::23:11:24 Loading base files in memory from : BaseOfficeDocs\UnpackedMSOpenXMLFormatFiles 161 | [+] 2017:05:05::23:11:24 Loading File Format Handler for extension : xml => xmlHandler.py 162 | [+] 2017:05:05::23:11:24 Loading File Format Handler for extension : rels => xmlHandler.py 163 | [+] 2017:05:05::23:11:24 Loading File Format Handler Done !! 164 | [+] 2017:05:05::23:11:24 Starting Fuzzing 165 | [+] 2017:05:05::23:11:25 Temp cleaner started... 166 | [+] 2017:05:05::23:11:25 Cleaning Temp Directory... 167 | ... 168 | ... 169 | ``` 170 | 171 | 172 | ix) Open X-Molar in Action 173 | ========================== 174 | 175 | Here is a very short video on running fuzztest on MS Office Word: 176 | 177 | [![IMAGE ALT TEXT HERE](https://github.com/debasishm89/OpenXMolar/blob/master/screens/video_thumb.PNG)](https://www.youtube.com/watch?v=b7n1tuFDl5A) 178 | 179 | x) Fuzzing Non-OpenXML Applications : 180 | ==================================== 181 | 182 | Due to the flexible structure of the fuzzer, this Fuzzer can also be used to fuzz other windows application. You just need do following : 183 | 184 | 185 | * In config.py add the target application binary (exe) and extension in APP_LIST of config.py 186 | * In config.py change OpenXMLFormat to False 187 | * Write your own File format mutation handler and place it in FileFormatHandlers/ folder 188 | * Add the newly added FileFormatHandler in FILE_FORMAT_HANDLERS of config.py 189 | * Provide some base files in folder OtherFileFormats/ 190 | * Add custom error / popup windows handler in PopUpKiller.py using Au3Info tool if required 191 | 192 | And you're good to go. 193 | 194 | xi) Few More Points about OpenXMolar: 195 | ====================================== 196 | 1. Fuzzing Efficiency: 197 | To maximize fuzzing efficiency OpenXMolar doesn't read the provided base files again and from disk. While starting up, it loads all base files in memory and convert them into easy to manage python data structures and mutate them straight from memory. 198 | 199 | 2. Auto identification of internal files of OpenXML package : 200 | An Open XML file package may contain various files like XML files, Binary files etc. OpenXMolar has capability to identify internal file types and based that chooses mutation script and mutate them. Please refer to the default config.py file (Param : AUTO_IDENTIFY_INTERNAL_FILE_FORAMT) for details. 201 | 202 | 203 | xii) TODO 204 | ======= 205 | 1. Improve Fuzzing Speed 206 | 2. New Feature / Bugs -> https://github.com/debasishm89/OpenXMolar/issues 207 | 208 | xiii) License 209 | =========== 210 | 211 | This software is licenced under New BSD License although the following libraries are included with Open X-Molar and are licensed separately. 212 | 213 | | Module | Source | 214 | | ------ | ------ | 215 | | winappdbg | https://github.com/MarioVilas/winappdbg | 216 | | pydbg | https://github.com/OpenRCE/pydbg | 217 | | pyautoit | https://pypi.python.org/pypi/PyAutoIt/0.3 | 218 | | crash_binning | https://github.com/OpenRCE/sulley | 219 | | xmltodict | https://github.com/martinblech/xmltodict | 220 | | Au3Info.exe | https://www.autoitscript.com/autoit3/docs/intro/au3spy.htm | 221 | 222 | 223 | xiv )Author 224 | ============= 225 | 226 | Debasish Mandal ( https://twitter.com/debasishm89 ) 227 | 228 | xv ) CVE(s) 229 | ============ 230 | https://portal.msrc.microsoft.com/en-us/security-guidance/advisory/CVE-2017-8630 231 | 232 | https://portal.msrc.microsoft.com/en-us/security-guidance/advisory/CVE-2018-0792 233 | -------------------------------------------------------------------------------- /ExtDepLibs/winappdbg/win32/psapi.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # Copyright (c) 2009-2016, Mario Vilas 5 | # All rights reserved. 6 | # 7 | # Redistribution and use in source and binary forms, with or without 8 | # modification, are permitted provided that the following conditions are met: 9 | # 10 | # * Redistributions of source code must retain the above copyright notice, 11 | # this list of conditions and the following disclaimer. 12 | # * Redistributions in binary form must reproduce the above copyright 13 | # notice,this list of conditions and the following disclaimer in the 14 | # documentation and/or other materials provided with the distribution. 15 | # * Neither the name of the copyright holder nor the names of its 16 | # contributors may be used to endorse or promote products derived from 17 | # this software without specific prior written permission. 18 | # 19 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 | # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 23 | # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 | # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 | # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 | # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 | # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 | # POSSIBILITY OF SUCH DAMAGE. 30 | 31 | """ 32 | Wrapper for psapi.dll in ctypes. 33 | """ 34 | 35 | from defines import * 36 | 37 | #============================================================================== 38 | # This is used later on to calculate the list of exported symbols. 39 | _all = None 40 | _all = set(vars().keys()) 41 | #============================================================================== 42 | 43 | #--- PSAPI structures and constants ------------------------------------------- 44 | 45 | LIST_MODULES_DEFAULT = 0x00 46 | LIST_MODULES_32BIT = 0x01 47 | LIST_MODULES_64BIT = 0x02 48 | LIST_MODULES_ALL = 0x03 49 | 50 | # typedef struct _MODULEINFO { 51 | # LPVOID lpBaseOfDll; 52 | # DWORD SizeOfImage; 53 | # LPVOID EntryPoint; 54 | # } MODULEINFO, *LPMODULEINFO; 55 | class MODULEINFO(Structure): 56 | _fields_ = [ 57 | ("lpBaseOfDll", LPVOID), # remote pointer 58 | ("SizeOfImage", DWORD), 59 | ("EntryPoint", LPVOID), # remote pointer 60 | ] 61 | LPMODULEINFO = POINTER(MODULEINFO) 62 | 63 | #--- psapi.dll ---------------------------------------------------------------- 64 | 65 | # BOOL WINAPI EnumDeviceDrivers( 66 | # __out LPVOID *lpImageBase, 67 | # __in DWORD cb, 68 | # __out LPDWORD lpcbNeeded 69 | # ); 70 | def EnumDeviceDrivers(): 71 | _EnumDeviceDrivers = windll.psapi.EnumDeviceDrivers 72 | _EnumDeviceDrivers.argtypes = [LPVOID, DWORD, LPDWORD] 73 | _EnumDeviceDrivers.restype = bool 74 | _EnumDeviceDrivers.errcheck = RaiseIfZero 75 | 76 | size = 0x1000 77 | lpcbNeeded = DWORD(size) 78 | unit = sizeof(LPVOID) 79 | while 1: 80 | lpImageBase = (LPVOID * (size // unit))() 81 | _EnumDeviceDrivers(byref(lpImageBase), lpcbNeeded, byref(lpcbNeeded)) 82 | needed = lpcbNeeded.value 83 | if needed <= size: 84 | break 85 | size = needed 86 | return [ lpImageBase[index] for index in xrange(0, (needed // unit)) ] 87 | 88 | # BOOL WINAPI EnumProcesses( 89 | # __out DWORD *pProcessIds, 90 | # __in DWORD cb, 91 | # __out DWORD *pBytesReturned 92 | # ); 93 | def EnumProcesses(): 94 | _EnumProcesses = windll.psapi.EnumProcesses 95 | _EnumProcesses.argtypes = [LPVOID, DWORD, LPDWORD] 96 | _EnumProcesses.restype = bool 97 | _EnumProcesses.errcheck = RaiseIfZero 98 | 99 | size = 0x1000 100 | cbBytesReturned = DWORD() 101 | unit = sizeof(DWORD) 102 | while 1: 103 | ProcessIds = (DWORD * (size // unit))() 104 | cbBytesReturned.value = size 105 | _EnumProcesses(byref(ProcessIds), cbBytesReturned, byref(cbBytesReturned)) 106 | returned = cbBytesReturned.value 107 | if returned < size: 108 | break 109 | size = size + 0x1000 110 | ProcessIdList = list() 111 | for ProcessId in ProcessIds: 112 | if ProcessId is None: 113 | break 114 | ProcessIdList.append(ProcessId) 115 | return ProcessIdList 116 | 117 | # BOOL WINAPI EnumProcessModules( 118 | # __in HANDLE hProcess, 119 | # __out HMODULE *lphModule, 120 | # __in DWORD cb, 121 | # __out LPDWORD lpcbNeeded 122 | # ); 123 | def EnumProcessModules(hProcess): 124 | _EnumProcessModules = windll.psapi.EnumProcessModules 125 | _EnumProcessModules.argtypes = [HANDLE, LPVOID, DWORD, LPDWORD] 126 | _EnumProcessModules.restype = bool 127 | _EnumProcessModules.errcheck = RaiseIfZero 128 | 129 | size = 0x1000 130 | lpcbNeeded = DWORD(size) 131 | unit = sizeof(HMODULE) 132 | while 1: 133 | lphModule = (HMODULE * (size // unit))() 134 | _EnumProcessModules(hProcess, byref(lphModule), lpcbNeeded, byref(lpcbNeeded)) 135 | needed = lpcbNeeded.value 136 | if needed <= size: 137 | break 138 | size = needed 139 | return [ lphModule[index] for index in xrange(0, int(needed // unit)) ] 140 | 141 | # BOOL WINAPI EnumProcessModulesEx( 142 | # __in HANDLE hProcess, 143 | # __out HMODULE *lphModule, 144 | # __in DWORD cb, 145 | # __out LPDWORD lpcbNeeded, 146 | # __in DWORD dwFilterFlag 147 | # ); 148 | def EnumProcessModulesEx(hProcess, dwFilterFlag = LIST_MODULES_DEFAULT): 149 | _EnumProcessModulesEx = windll.psapi.EnumProcessModulesEx 150 | _EnumProcessModulesEx.argtypes = [HANDLE, LPVOID, DWORD, LPDWORD, DWORD] 151 | _EnumProcessModulesEx.restype = bool 152 | _EnumProcessModulesEx.errcheck = RaiseIfZero 153 | 154 | size = 0x1000 155 | lpcbNeeded = DWORD(size) 156 | unit = sizeof(HMODULE) 157 | while 1: 158 | lphModule = (HMODULE * (size // unit))() 159 | _EnumProcessModulesEx(hProcess, byref(lphModule), lpcbNeeded, byref(lpcbNeeded), dwFilterFlag) 160 | needed = lpcbNeeded.value 161 | if needed <= size: 162 | break 163 | size = needed 164 | return [ lphModule[index] for index in xrange(0, (needed // unit)) ] 165 | 166 | # DWORD WINAPI GetDeviceDriverBaseName( 167 | # __in LPVOID ImageBase, 168 | # __out LPTSTR lpBaseName, 169 | # __in DWORD nSize 170 | # ); 171 | def GetDeviceDriverBaseNameA(ImageBase): 172 | _GetDeviceDriverBaseNameA = windll.psapi.GetDeviceDriverBaseNameA 173 | _GetDeviceDriverBaseNameA.argtypes = [LPVOID, LPSTR, DWORD] 174 | _GetDeviceDriverBaseNameA.restype = DWORD 175 | 176 | nSize = MAX_PATH 177 | while 1: 178 | lpBaseName = ctypes.create_string_buffer("", nSize) 179 | nCopied = _GetDeviceDriverBaseNameA(ImageBase, lpBaseName, nSize) 180 | if nCopied == 0: 181 | raise ctypes.WinError() 182 | if nCopied < (nSize - 1): 183 | break 184 | nSize = nSize + MAX_PATH 185 | return lpBaseName.value 186 | 187 | def GetDeviceDriverBaseNameW(ImageBase): 188 | _GetDeviceDriverBaseNameW = windll.psapi.GetDeviceDriverBaseNameW 189 | _GetDeviceDriverBaseNameW.argtypes = [LPVOID, LPWSTR, DWORD] 190 | _GetDeviceDriverBaseNameW.restype = DWORD 191 | 192 | nSize = MAX_PATH 193 | while 1: 194 | lpBaseName = ctypes.create_unicode_buffer(u"", nSize) 195 | nCopied = _GetDeviceDriverBaseNameW(ImageBase, lpBaseName, nSize) 196 | if nCopied == 0: 197 | raise ctypes.WinError() 198 | if nCopied < (nSize - 1): 199 | break 200 | nSize = nSize + MAX_PATH 201 | return lpBaseName.value 202 | 203 | GetDeviceDriverBaseName = GuessStringType(GetDeviceDriverBaseNameA, GetDeviceDriverBaseNameW) 204 | 205 | # DWORD WINAPI GetDeviceDriverFileName( 206 | # __in LPVOID ImageBase, 207 | # __out LPTSTR lpFilename, 208 | # __in DWORD nSize 209 | # ); 210 | def GetDeviceDriverFileNameA(ImageBase): 211 | _GetDeviceDriverFileNameA = windll.psapi.GetDeviceDriverFileNameA 212 | _GetDeviceDriverFileNameA.argtypes = [LPVOID, LPSTR, DWORD] 213 | _GetDeviceDriverFileNameA.restype = DWORD 214 | 215 | nSize = MAX_PATH 216 | while 1: 217 | lpFilename = ctypes.create_string_buffer("", nSize) 218 | nCopied = ctypes.windll.psapi.GetDeviceDriverFileNameA(ImageBase, lpFilename, nSize) 219 | if nCopied == 0: 220 | raise ctypes.WinError() 221 | if nCopied < (nSize - 1): 222 | break 223 | nSize = nSize + MAX_PATH 224 | return lpFilename.value 225 | 226 | def GetDeviceDriverFileNameW(ImageBase): 227 | _GetDeviceDriverFileNameW = windll.psapi.GetDeviceDriverFileNameW 228 | _GetDeviceDriverFileNameW.argtypes = [LPVOID, LPWSTR, DWORD] 229 | _GetDeviceDriverFileNameW.restype = DWORD 230 | 231 | nSize = MAX_PATH 232 | while 1: 233 | lpFilename = ctypes.create_unicode_buffer(u"", nSize) 234 | nCopied = ctypes.windll.psapi.GetDeviceDriverFileNameW(ImageBase, lpFilename, nSize) 235 | if nCopied == 0: 236 | raise ctypes.WinError() 237 | if nCopied < (nSize - 1): 238 | break 239 | nSize = nSize + MAX_PATH 240 | return lpFilename.value 241 | 242 | GetDeviceDriverFileName = GuessStringType(GetDeviceDriverFileNameA, GetDeviceDriverFileNameW) 243 | 244 | # DWORD WINAPI GetMappedFileName( 245 | # __in HANDLE hProcess, 246 | # __in LPVOID lpv, 247 | # __out LPTSTR lpFilename, 248 | # __in DWORD nSize 249 | # ); 250 | def GetMappedFileNameA(hProcess, lpv): 251 | _GetMappedFileNameA = ctypes.windll.psapi.GetMappedFileNameA 252 | _GetMappedFileNameA.argtypes = [HANDLE, LPVOID, LPSTR, DWORD] 253 | _GetMappedFileNameA.restype = DWORD 254 | 255 | nSize = MAX_PATH 256 | while 1: 257 | lpFilename = ctypes.create_string_buffer("", nSize) 258 | nCopied = _GetMappedFileNameA(hProcess, lpv, lpFilename, nSize) 259 | if nCopied == 0: 260 | raise ctypes.WinError() 261 | if nCopied < (nSize - 1): 262 | break 263 | nSize = nSize + MAX_PATH 264 | return lpFilename.value 265 | 266 | def GetMappedFileNameW(hProcess, lpv): 267 | _GetMappedFileNameW = ctypes.windll.psapi.GetMappedFileNameW 268 | _GetMappedFileNameW.argtypes = [HANDLE, LPVOID, LPWSTR, DWORD] 269 | _GetMappedFileNameW.restype = DWORD 270 | 271 | nSize = MAX_PATH 272 | while 1: 273 | lpFilename = ctypes.create_unicode_buffer(u"", nSize) 274 | nCopied = _GetMappedFileNameW(hProcess, lpv, lpFilename, nSize) 275 | if nCopied == 0: 276 | raise ctypes.WinError() 277 | if nCopied < (nSize - 1): 278 | break 279 | nSize = nSize + MAX_PATH 280 | return lpFilename.value 281 | 282 | GetMappedFileName = GuessStringType(GetMappedFileNameA, GetMappedFileNameW) 283 | 284 | # DWORD WINAPI GetModuleFileNameEx( 285 | # __in HANDLE hProcess, 286 | # __in_opt HMODULE hModule, 287 | # __out LPTSTR lpFilename, 288 | # __in DWORD nSize 289 | # ); 290 | def GetModuleFileNameExA(hProcess, hModule = None): 291 | _GetModuleFileNameExA = ctypes.windll.psapi.GetModuleFileNameExA 292 | _GetModuleFileNameExA.argtypes = [HANDLE, HMODULE, LPSTR, DWORD] 293 | _GetModuleFileNameExA.restype = DWORD 294 | 295 | nSize = MAX_PATH 296 | while 1: 297 | lpFilename = ctypes.create_string_buffer("", nSize) 298 | nCopied = _GetModuleFileNameExA(hProcess, hModule, lpFilename, nSize) 299 | if nCopied == 0: 300 | raise ctypes.WinError() 301 | if nCopied < (nSize - 1): 302 | break 303 | nSize = nSize + MAX_PATH 304 | return lpFilename.value 305 | 306 | def GetModuleFileNameExW(hProcess, hModule = None): 307 | _GetModuleFileNameExW = ctypes.windll.psapi.GetModuleFileNameExW 308 | _GetModuleFileNameExW.argtypes = [HANDLE, HMODULE, LPWSTR, DWORD] 309 | _GetModuleFileNameExW.restype = DWORD 310 | 311 | nSize = MAX_PATH 312 | while 1: 313 | lpFilename = ctypes.create_unicode_buffer(u"", nSize) 314 | nCopied = _GetModuleFileNameExW(hProcess, hModule, lpFilename, nSize) 315 | if nCopied == 0: 316 | raise ctypes.WinError() 317 | if nCopied < (nSize - 1): 318 | break 319 | nSize = nSize + MAX_PATH 320 | return lpFilename.value 321 | 322 | GetModuleFileNameEx = GuessStringType(GetModuleFileNameExA, GetModuleFileNameExW) 323 | 324 | # BOOL WINAPI GetModuleInformation( 325 | # __in HANDLE hProcess, 326 | # __in HMODULE hModule, 327 | # __out LPMODULEINFO lpmodinfo, 328 | # __in DWORD cb 329 | # ); 330 | def GetModuleInformation(hProcess, hModule, lpmodinfo = None): 331 | _GetModuleInformation = windll.psapi.GetModuleInformation 332 | _GetModuleInformation.argtypes = [HANDLE, HMODULE, LPMODULEINFO, DWORD] 333 | _GetModuleInformation.restype = bool 334 | _GetModuleInformation.errcheck = RaiseIfZero 335 | 336 | if lpmodinfo is None: 337 | lpmodinfo = MODULEINFO() 338 | _GetModuleInformation(hProcess, hModule, byref(lpmodinfo), sizeof(lpmodinfo)) 339 | return lpmodinfo 340 | 341 | # DWORD WINAPI GetProcessImageFileName( 342 | # __in HANDLE hProcess, 343 | # __out LPTSTR lpImageFileName, 344 | # __in DWORD nSize 345 | # ); 346 | def GetProcessImageFileNameA(hProcess): 347 | _GetProcessImageFileNameA = windll.psapi.GetProcessImageFileNameA 348 | _GetProcessImageFileNameA.argtypes = [HANDLE, LPSTR, DWORD] 349 | _GetProcessImageFileNameA.restype = DWORD 350 | 351 | nSize = MAX_PATH 352 | while 1: 353 | lpFilename = ctypes.create_string_buffer("", nSize) 354 | nCopied = _GetProcessImageFileNameA(hProcess, lpFilename, nSize) 355 | if nCopied == 0: 356 | raise ctypes.WinError() 357 | if nCopied < (nSize - 1): 358 | break 359 | nSize = nSize + MAX_PATH 360 | return lpFilename.value 361 | 362 | def GetProcessImageFileNameW(hProcess): 363 | _GetProcessImageFileNameW = windll.psapi.GetProcessImageFileNameW 364 | _GetProcessImageFileNameW.argtypes = [HANDLE, LPWSTR, DWORD] 365 | _GetProcessImageFileNameW.restype = DWORD 366 | 367 | nSize = MAX_PATH 368 | while 1: 369 | lpFilename = ctypes.create_unicode_buffer(u"", nSize) 370 | nCopied = _GetProcessImageFileNameW(hProcess, lpFilename, nSize) 371 | if nCopied == 0: 372 | raise ctypes.WinError() 373 | if nCopied < (nSize - 1): 374 | break 375 | nSize = nSize + MAX_PATH 376 | return lpFilename.value 377 | 378 | GetProcessImageFileName = GuessStringType(GetProcessImageFileNameA, GetProcessImageFileNameW) 379 | 380 | #============================================================================== 381 | # This calculates the list of exported symbols. 382 | _all = set(vars().keys()).difference(_all) 383 | __all__ = [_x for _x in _all if not _x.startswith('_')] 384 | __all__.sort() 385 | #============================================================================== 386 | -------------------------------------------------------------------------------- /ExtDepLibs/winappdbg/win32/shell32.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # Copyright (c) 2009-2016, Mario Vilas 5 | # All rights reserved. 6 | # 7 | # Redistribution and use in source and binary forms, with or without 8 | # modification, are permitted provided that the following conditions are met: 9 | # 10 | # * Redistributions of source code must retain the above copyright notice, 11 | # this list of conditions and the following disclaimer. 12 | # * Redistributions in binary form must reproduce the above copyright 13 | # notice,this list of conditions and the following disclaimer in the 14 | # documentation and/or other materials provided with the distribution. 15 | # * Neither the name of the copyright holder nor the names of its 16 | # contributors may be used to endorse or promote products derived from 17 | # this software without specific prior written permission. 18 | # 19 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 | # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 23 | # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 | # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 | # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 | # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 | # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 | # POSSIBILITY OF SUCH DAMAGE. 30 | 31 | """ 32 | Wrapper for shell32.dll in ctypes. 33 | """ 34 | 35 | # TODO 36 | # * Add a class wrapper to SHELLEXECUTEINFO 37 | # * More logic into ShellExecuteEx 38 | 39 | from defines import * 40 | from kernel32 import LocalFree 41 | 42 | #============================================================================== 43 | # This is used later on to calculate the list of exported symbols. 44 | _all = None 45 | _all = set(vars().keys()) 46 | #============================================================================== 47 | 48 | #--- Constants ---------------------------------------------------------------- 49 | 50 | SEE_MASK_DEFAULT = 0x00000000 51 | SEE_MASK_CLASSNAME = 0x00000001 52 | SEE_MASK_CLASSKEY = 0x00000003 53 | SEE_MASK_IDLIST = 0x00000004 54 | SEE_MASK_INVOKEIDLIST = 0x0000000C 55 | SEE_MASK_ICON = 0x00000010 56 | SEE_MASK_HOTKEY = 0x00000020 57 | SEE_MASK_NOCLOSEPROCESS = 0x00000040 58 | SEE_MASK_CONNECTNETDRV = 0x00000080 59 | SEE_MASK_NOASYNC = 0x00000100 60 | SEE_MASK_DOENVSUBST = 0x00000200 61 | SEE_MASK_FLAG_NO_UI = 0x00000400 62 | SEE_MASK_UNICODE = 0x00004000 63 | SEE_MASK_NO_CONSOLE = 0x00008000 64 | SEE_MASK_ASYNCOK = 0x00100000 65 | SEE_MASK_HMONITOR = 0x00200000 66 | SEE_MASK_NOZONECHECKS = 0x00800000 67 | SEE_MASK_WAITFORINPUTIDLE = 0x02000000 68 | SEE_MASK_FLAG_LOG_USAGE = 0x04000000 69 | 70 | SE_ERR_FNF = 2 71 | SE_ERR_PNF = 3 72 | SE_ERR_ACCESSDENIED = 5 73 | SE_ERR_OOM = 8 74 | SE_ERR_DLLNOTFOUND = 32 75 | SE_ERR_SHARE = 26 76 | SE_ERR_ASSOCINCOMPLETE = 27 77 | SE_ERR_DDETIMEOUT = 28 78 | SE_ERR_DDEFAIL = 29 79 | SE_ERR_DDEBUSY = 30 80 | SE_ERR_NOASSOC = 31 81 | 82 | SHGFP_TYPE_CURRENT = 0 83 | SHGFP_TYPE_DEFAULT = 1 84 | 85 | CSIDL_DESKTOP = 0x0000 86 | CSIDL_INTERNET = 0x0001 87 | CSIDL_PROGRAMS = 0x0002 88 | CSIDL_CONTROLS = 0x0003 89 | CSIDL_PRINTERS = 0x0004 90 | CSIDL_PERSONAL = 0x0005 91 | CSIDL_FAVORITES = 0x0006 92 | CSIDL_STARTUP = 0x0007 93 | CSIDL_RECENT = 0x0008 94 | CSIDL_SENDTO = 0x0009 95 | CSIDL_BITBUCKET = 0x000a 96 | CSIDL_STARTMENU = 0x000b 97 | CSIDL_MYDOCUMENTS = CSIDL_PERSONAL 98 | CSIDL_MYMUSIC = 0x000d 99 | CSIDL_MYVIDEO = 0x000e 100 | CSIDL_DESKTOPDIRECTORY = 0x0010 101 | CSIDL_DRIVES = 0x0011 102 | CSIDL_NETWORK = 0x0012 103 | CSIDL_NETHOOD = 0x0013 104 | CSIDL_FONTS = 0x0014 105 | CSIDL_TEMPLATES = 0x0015 106 | CSIDL_COMMON_STARTMENU = 0x0016 107 | CSIDL_COMMON_PROGRAMS = 0x0017 108 | CSIDL_COMMON_STARTUP = 0x0018 109 | CSIDL_COMMON_DESKTOPDIRECTORY = 0x0019 110 | CSIDL_APPDATA = 0x001a 111 | CSIDL_PRINTHOOD = 0x001b 112 | CSIDL_LOCAL_APPDATA = 0x001c 113 | CSIDL_ALTSTARTUP = 0x001d 114 | CSIDL_COMMON_ALTSTARTUP = 0x001e 115 | CSIDL_COMMON_FAVORITES = 0x001f 116 | CSIDL_INTERNET_CACHE = 0x0020 117 | CSIDL_COOKIES = 0x0021 118 | CSIDL_HISTORY = 0x0022 119 | CSIDL_COMMON_APPDATA = 0x0023 120 | CSIDL_WINDOWS = 0x0024 121 | CSIDL_SYSTEM = 0x0025 122 | CSIDL_PROGRAM_FILES = 0x0026 123 | CSIDL_MYPICTURES = 0x0027 124 | CSIDL_PROFILE = 0x0028 125 | CSIDL_SYSTEMX86 = 0x0029 126 | CSIDL_PROGRAM_FILESX86 = 0x002a 127 | CSIDL_PROGRAM_FILES_COMMON = 0x002b 128 | CSIDL_PROGRAM_FILES_COMMONX86 = 0x002c 129 | CSIDL_COMMON_TEMPLATES = 0x002d 130 | CSIDL_COMMON_DOCUMENTS = 0x002e 131 | CSIDL_COMMON_ADMINTOOLS = 0x002f 132 | CSIDL_ADMINTOOLS = 0x0030 133 | CSIDL_CONNECTIONS = 0x0031 134 | CSIDL_COMMON_MUSIC = 0x0035 135 | CSIDL_COMMON_PICTURES = 0x0036 136 | CSIDL_COMMON_VIDEO = 0x0037 137 | CSIDL_RESOURCES = 0x0038 138 | CSIDL_RESOURCES_LOCALIZED = 0x0039 139 | CSIDL_COMMON_OEM_LINKS = 0x003a 140 | CSIDL_CDBURN_AREA = 0x003b 141 | CSIDL_COMPUTERSNEARME = 0x003d 142 | CSIDL_PROFILES = 0x003e 143 | 144 | CSIDL_FOLDER_MASK = 0x00ff 145 | 146 | CSIDL_FLAG_PER_USER_INIT = 0x0800 147 | CSIDL_FLAG_NO_ALIAS = 0x1000 148 | CSIDL_FLAG_DONT_VERIFY = 0x4000 149 | CSIDL_FLAG_CREATE = 0x8000 150 | 151 | CSIDL_FLAG_MASK = 0xff00 152 | 153 | #--- Structures --------------------------------------------------------------- 154 | 155 | # typedef struct _SHELLEXECUTEINFO { 156 | # DWORD cbSize; 157 | # ULONG fMask; 158 | # HWND hwnd; 159 | # LPCTSTR lpVerb; 160 | # LPCTSTR lpFile; 161 | # LPCTSTR lpParameters; 162 | # LPCTSTR lpDirectory; 163 | # int nShow; 164 | # HINSTANCE hInstApp; 165 | # LPVOID lpIDList; 166 | # LPCTSTR lpClass; 167 | # HKEY hkeyClass; 168 | # DWORD dwHotKey; 169 | # union { 170 | # HANDLE hIcon; 171 | # HANDLE hMonitor; 172 | # } DUMMYUNIONNAME; 173 | # HANDLE hProcess; 174 | # } SHELLEXECUTEINFO, *LPSHELLEXECUTEINFO; 175 | 176 | class SHELLEXECUTEINFO(Structure): 177 | _fields_ = [ 178 | ("cbSize", DWORD), 179 | ("fMask", ULONG), 180 | ("hwnd", HWND), 181 | ("lpVerb", LPSTR), 182 | ("lpFile", LPSTR), 183 | ("lpParameters", LPSTR), 184 | ("lpDirectory", LPSTR), 185 | ("nShow", ctypes.c_int), 186 | ("hInstApp", HINSTANCE), 187 | ("lpIDList", LPVOID), 188 | ("lpClass", LPSTR), 189 | ("hkeyClass", HKEY), 190 | ("dwHotKey", DWORD), 191 | ("hIcon", HANDLE), 192 | ("hProcess", HANDLE), 193 | ] 194 | 195 | def __get_hMonitor(self): 196 | return self.hIcon 197 | def __set_hMonitor(self, hMonitor): 198 | self.hIcon = hMonitor 199 | hMonitor = property(__get_hMonitor, __set_hMonitor) 200 | 201 | LPSHELLEXECUTEINFO = POINTER(SHELLEXECUTEINFO) 202 | 203 | #--- shell32.dll -------------------------------------------------------------- 204 | 205 | # LPWSTR *CommandLineToArgvW( 206 | # LPCWSTR lpCmdLine, 207 | # int *pNumArgs 208 | # ); 209 | def CommandLineToArgvW(lpCmdLine): 210 | _CommandLineToArgvW = windll.shell32.CommandLineToArgvW 211 | _CommandLineToArgvW.argtypes = [LPVOID, POINTER(ctypes.c_int)] 212 | _CommandLineToArgvW.restype = LPVOID 213 | 214 | if not lpCmdLine: 215 | lpCmdLine = None 216 | argc = ctypes.c_int(0) 217 | vptr = ctypes.windll.shell32.CommandLineToArgvW(lpCmdLine, byref(argc)) 218 | if vptr == NULL: 219 | raise ctypes.WinError() 220 | argv = vptr 221 | try: 222 | argc = argc.value 223 | if argc <= 0: 224 | raise ctypes.WinError() 225 | argv = ctypes.cast(argv, ctypes.POINTER(LPWSTR * argc) ) 226 | argv = [ argv.contents[i] for i in xrange(0, argc) ] 227 | finally: 228 | if vptr is not None: 229 | LocalFree(vptr) 230 | return argv 231 | 232 | def CommandLineToArgvA(lpCmdLine): 233 | t_ansi = GuessStringType.t_ansi 234 | t_unicode = GuessStringType.t_unicode 235 | if isinstance(lpCmdLine, t_ansi): 236 | cmdline = t_unicode(lpCmdLine) 237 | else: 238 | cmdline = lpCmdLine 239 | return [t_ansi(x) for x in CommandLineToArgvW(cmdline)] 240 | 241 | CommandLineToArgv = GuessStringType(CommandLineToArgvA, CommandLineToArgvW) 242 | 243 | # HINSTANCE ShellExecute( 244 | # HWND hwnd, 245 | # LPCTSTR lpOperation, 246 | # LPCTSTR lpFile, 247 | # LPCTSTR lpParameters, 248 | # LPCTSTR lpDirectory, 249 | # INT nShowCmd 250 | # ); 251 | def ShellExecuteA(hwnd = None, lpOperation = None, lpFile = None, lpParameters = None, lpDirectory = None, nShowCmd = None): 252 | _ShellExecuteA = windll.shell32.ShellExecuteA 253 | _ShellExecuteA.argtypes = [HWND, LPSTR, LPSTR, LPSTR, LPSTR, INT] 254 | _ShellExecuteA.restype = HINSTANCE 255 | 256 | if not nShowCmd: 257 | nShowCmd = 0 258 | success = _ShellExecuteA(hwnd, lpOperation, lpFile, lpParameters, lpDirectory, nShowCmd) 259 | success = ctypes.cast(success, c_int) 260 | success = success.value 261 | if not success > 32: # weird! isn't it? 262 | raise ctypes.WinError(success) 263 | 264 | def ShellExecuteW(hwnd = None, lpOperation = None, lpFile = None, lpParameters = None, lpDirectory = None, nShowCmd = None): 265 | _ShellExecuteW = windll.shell32.ShellExecuteW 266 | _ShellExecuteW.argtypes = [HWND, LPWSTR, LPWSTR, LPWSTR, LPWSTR, INT] 267 | _ShellExecuteW.restype = HINSTANCE 268 | 269 | if not nShowCmd: 270 | nShowCmd = 0 271 | success = _ShellExecuteW(hwnd, lpOperation, lpFile, lpParameters, lpDirectory, nShowCmd) 272 | success = ctypes.cast(success, c_int) 273 | success = success.value 274 | if not success > 32: # weird! isn't it? 275 | raise ctypes.WinError(success) 276 | 277 | ShellExecute = GuessStringType(ShellExecuteA, ShellExecuteW) 278 | 279 | # BOOL ShellExecuteEx( 280 | # __inout LPSHELLEXECUTEINFO lpExecInfo 281 | # ); 282 | def ShellExecuteEx(lpExecInfo): 283 | if isinstance(lpExecInfo, SHELLEXECUTEINFOA): 284 | ShellExecuteExA(lpExecInfo) 285 | elif isinstance(lpExecInfo, SHELLEXECUTEINFOW): 286 | ShellExecuteExW(lpExecInfo) 287 | else: 288 | raise TypeError("Expected SHELLEXECUTEINFOA or SHELLEXECUTEINFOW, got %s instead" % type(lpExecInfo)) 289 | 290 | def ShellExecuteExA(lpExecInfo): 291 | _ShellExecuteExA = windll.shell32.ShellExecuteExA 292 | _ShellExecuteExA.argtypes = [LPSHELLEXECUTEINFOA] 293 | _ShellExecuteExA.restype = BOOL 294 | _ShellExecuteExA.errcheck = RaiseIfZero 295 | _ShellExecuteExA(byref(lpExecInfo)) 296 | 297 | def ShellExecuteExW(lpExecInfo): 298 | _ShellExecuteExW = windll.shell32.ShellExecuteExW 299 | _ShellExecuteExW.argtypes = [LPSHELLEXECUTEINFOW] 300 | _ShellExecuteExW.restype = BOOL 301 | _ShellExecuteExW.errcheck = RaiseIfZero 302 | _ShellExecuteExW(byref(lpExecInfo)) 303 | 304 | # HINSTANCE FindExecutable( 305 | # __in LPCTSTR lpFile, 306 | # __in_opt LPCTSTR lpDirectory, 307 | # __out LPTSTR lpResult 308 | # ); 309 | def FindExecutableA(lpFile, lpDirectory = None): 310 | _FindExecutableA = windll.shell32.FindExecutableA 311 | _FindExecutableA.argtypes = [LPSTR, LPSTR, LPSTR] 312 | _FindExecutableA.restype = HINSTANCE 313 | 314 | lpResult = ctypes.create_string_buffer(MAX_PATH) 315 | success = _FindExecutableA(lpFile, lpDirectory, lpResult) 316 | success = ctypes.cast(success, ctypes.c_void_p) 317 | success = success.value 318 | if not success > 32: # weird! isn't it? 319 | raise ctypes.WinError(success) 320 | return lpResult.value 321 | 322 | def FindExecutableW(lpFile, lpDirectory = None): 323 | _FindExecutableW = windll.shell32.FindExecutableW 324 | _FindExecutableW.argtypes = [LPWSTR, LPWSTR, LPWSTR] 325 | _FindExecutableW.restype = HINSTANCE 326 | 327 | lpResult = ctypes.create_unicode_buffer(MAX_PATH) 328 | success = _FindExecutableW(lpFile, lpDirectory, lpResult) 329 | success = ctypes.cast(success, ctypes.c_void_p) 330 | success = success.value 331 | if not success > 32: # weird! isn't it? 332 | raise ctypes.WinError(success) 333 | return lpResult.value 334 | 335 | FindExecutable = GuessStringType(FindExecutableA, FindExecutableW) 336 | 337 | # HRESULT SHGetFolderPath( 338 | # __in HWND hwndOwner, 339 | # __in int nFolder, 340 | # __in HANDLE hToken, 341 | # __in DWORD dwFlags, 342 | # __out LPTSTR pszPath 343 | # ); 344 | def SHGetFolderPathA(nFolder, hToken = None, dwFlags = SHGFP_TYPE_CURRENT): 345 | _SHGetFolderPathA = windll.shell32.SHGetFolderPathA # shfolder.dll in older win versions 346 | _SHGetFolderPathA.argtypes = [HWND, ctypes.c_int, HANDLE, DWORD, LPSTR] 347 | _SHGetFolderPathA.restype = HRESULT 348 | _SHGetFolderPathA.errcheck = RaiseIfNotZero # S_OK == 0 349 | 350 | pszPath = ctypes.create_string_buffer(MAX_PATH + 1) 351 | _SHGetFolderPathA(None, nFolder, hToken, dwFlags, pszPath) 352 | return pszPath.value 353 | 354 | def SHGetFolderPathW(nFolder, hToken = None, dwFlags = SHGFP_TYPE_CURRENT): 355 | _SHGetFolderPathW = windll.shell32.SHGetFolderPathW # shfolder.dll in older win versions 356 | _SHGetFolderPathW.argtypes = [HWND, ctypes.c_int, HANDLE, DWORD, LPWSTR] 357 | _SHGetFolderPathW.restype = HRESULT 358 | _SHGetFolderPathW.errcheck = RaiseIfNotZero # S_OK == 0 359 | 360 | pszPath = ctypes.create_unicode_buffer(MAX_PATH + 1) 361 | _SHGetFolderPathW(None, nFolder, hToken, dwFlags, pszPath) 362 | return pszPath.value 363 | 364 | SHGetFolderPath = DefaultStringType(SHGetFolderPathA, SHGetFolderPathW) 365 | 366 | # BOOL IsUserAnAdmin(void); 367 | def IsUserAnAdmin(): 368 | # Supposedly, IsUserAnAdmin() is deprecated in Vista. 369 | # But I tried it on Windows 7 and it works just fine. 370 | _IsUserAnAdmin = windll.shell32.IsUserAnAdmin 371 | _IsUserAnAdmin.argtypes = [] 372 | _IsUserAnAdmin.restype = bool 373 | return _IsUserAnAdmin() 374 | 375 | #============================================================================== 376 | # This calculates the list of exported symbols. 377 | _all = set(vars().keys()).difference(_all) 378 | __all__ = [_x for _x in _all if not _x.startswith('_')] 379 | __all__.sort() 380 | #============================================================================== 381 | -------------------------------------------------------------------------------- /ExtDepLibs/utils/LICENSE.txt: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc. 5 | 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Library General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | -------------------------------------------------------------------------------- /ExtDepLibs/autoit/autoit.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | __author__ = 'Jace Xu' 4 | 5 | import ctypes 6 | import os 7 | import platform 8 | from ctypes.wintypes import * 9 | from functools import wraps 10 | 11 | dll = "AutoItX3.dll" 12 | bit, _ = platform.architecture() 13 | 14 | if "(x86)" in os.environ['PROGRAMFILES'] and bit == "64bit": 15 | # if 64bit version of python within 64bit version of Windows, 16 | # load AutoItX3_x64.dll 17 | dll = "AutoItX3_x64.dll" 18 | 19 | dll_path = os.path.join(os.path.dirname(__file__), "lib", dll) 20 | 21 | if not os.path.exists(dll_path): 22 | raise IOError("Cannot load AutoItX from path: %s" % dll_path) 23 | 24 | AUTO_IT = ctypes.windll.LoadLibrary(dll_path) 25 | 26 | 27 | class AutoItError(Exception): 28 | pass 29 | 30 | 31 | def error(): 32 | return AUTO_IT.AU3_error() 33 | 34 | 35 | class AutoItAPI(object): 36 | 37 | def __init__(self): 38 | self.msg = {} 39 | 40 | @staticmethod 41 | def _has_error(): 42 | return True if error() == 1 else False 43 | 44 | @staticmethod 45 | def _has_unexpected_ret(ret, unexpected): 46 | if ret in unexpected: 47 | return True 48 | return False 49 | 50 | @staticmethod 51 | def _parser(x, y): 52 | if x["num"] >= y: 53 | x["flags"].append(y) 54 | x["num"] -= y 55 | return x 56 | 57 | def check(self, mark=0, err_msg="", **kwds): 58 | """ 59 | :param mark: 60 | 0 - do not need check return value or error() 61 | 1 - check error() 62 | 2 - check return value 63 | """ 64 | unexpected_ret = kwds.get("unexpected_ret", (0,)) 65 | 66 | def _check(fn): 67 | @wraps(fn) 68 | def wrapper(*args, **kwargs): 69 | ret = fn(*args, **kwargs) 70 | 71 | flags = reduce( 72 | self._parser, [dict(num=mark, flags=[]), 2, 1])["flags"] 73 | 74 | if 1 in flags: 75 | if self._has_error(): 76 | raise AutoItError(err_msg) 77 | 78 | if 2 in flags: 79 | if self._has_unexpected_ret(ret, unexpected_ret): 80 | raise AutoItError(err_msg) 81 | 82 | return ret 83 | return wrapper 84 | return _check 85 | 86 | 87 | api = AutoItAPI() 88 | 89 | 90 | @api.check() 91 | def auto_it_set_option(option, param): 92 | """ 93 | Changes the operation of various AutoIt functions/parameters 94 | :param option: The option to change 95 | :param param: The parameter (varies by option). 96 | :return: 97 | """ 98 | pre_value = AUTO_IT.AU3_AutoItSetOption(LPCWSTR(option), INT(param)) 99 | return pre_value 100 | 101 | 102 | class Properties(object): 103 | """ 104 | Below is an list of all the properties available in AutoItX. 105 | """ 106 | SW_HIDE = 0 107 | SW_MAXIMIZE = 3 108 | SW_MINIMIZE = 6 109 | SW_RESTORE = 9 110 | SW_SHOW = 5 111 | SW_SHOWDEFAULT = 10 112 | SW_SHOWMAXIMIZED = 3 113 | SW_SHOWMINIMIZED = 2 114 | SW_SHOWMINNOACTIVE = 7 115 | SW_SHOWNA = 8 116 | SW_SHOWNOACTIVATE = 4 117 | SW_SHOWNORMAL = 1 118 | 119 | 120 | class _Options(object): 121 | 122 | def __init__(self): 123 | self._caret_coord_mode = 1 124 | self._mouse_click_delay = 10 125 | self._mouse_click_down_delay = 10 126 | self._mouse_click_drag_delay = 250 127 | self._mouse_coord_mode = 1 128 | self._pixel_coord_mode = 1 129 | self._send_attach_mode = 0 130 | self._send_capslock_mode = 1 131 | self._send_key_delay = 5 132 | self._send_key_down_delay = 10 133 | self._win_detect_hidden_text = 0 134 | self._win_search_children = 0 135 | self._win_text_match_mode = 1 136 | self._win_title_match_mode = 1 137 | self._win_wait_delay = 250 138 | 139 | @property 140 | def caret_coord_mode(self): 141 | return self._caret_coord_mode 142 | 143 | @caret_coord_mode.setter 144 | def caret_coord_mode(self, value): 145 | auto_it_set_option("CaretCoordMode", value) 146 | self._caret_coord_mode = value 147 | 148 | @property 149 | def mouse_click_delay(self): 150 | return self._mouse_click_delay 151 | 152 | @mouse_click_delay.setter 153 | def mouse_click_delay(self, value): 154 | auto_it_set_option("MouseClickDelay", value) 155 | self._mouse_click_delay = value 156 | 157 | @property 158 | def mouse_click_down_delay(self): 159 | return self._mouse_click_down_delay 160 | 161 | @mouse_click_down_delay.setter 162 | def mouse_click_down_delay(self, value): 163 | auto_it_set_option("MouseClickDownDelay", value) 164 | self._mouse_click_down_delay = value 165 | 166 | @property 167 | def mouse_click_drag_delay(self): 168 | return self._mouse_click_drag_delay 169 | 170 | @mouse_click_drag_delay.setter 171 | def mouse_click_drag_delay(self, value): 172 | auto_it_set_option("MouseClickDragDelay", value) 173 | self._mouse_click_drag_delay = value 174 | 175 | @property 176 | def mouse_coord_mode(self): 177 | return self._mouse_coord_mode 178 | 179 | @mouse_coord_mode.setter 180 | def mouse_coord_mode(self, value): 181 | auto_it_set_option("MouseCoordMode", value) 182 | self._mouse_coord_mode = value 183 | 184 | @property 185 | def pixel_coord_mode(self): 186 | return self._pixel_coord_mode 187 | 188 | @pixel_coord_mode.setter 189 | def pixel_coord_mode(self, value): 190 | auto_it_set_option("PixelCoordMode", value) 191 | self._pixel_coord_mode = value 192 | 193 | @property 194 | def send_attach_mode(self): 195 | return self._send_attach_mode 196 | 197 | @send_attach_mode.setter 198 | def send_attach_mode(self, value): 199 | auto_it_set_option("SendAttachMode", INT(value)) 200 | self._send_attach_mode = value 201 | 202 | @property 203 | def send_capslock_mode(self): 204 | return self._send_capslock_mode 205 | 206 | @send_capslock_mode.setter 207 | def send_capslock_mode(self, value): 208 | auto_it_set_option("SendCapslockMode", value) 209 | self._send_capslock_mode = value 210 | 211 | @property 212 | def send_key_delay(self): 213 | return self._send_key_delay 214 | 215 | @send_key_delay.setter 216 | def send_key_delay(self, value): 217 | auto_it_set_option("SendKeyDelay", value) 218 | self._send_key_delay = value 219 | 220 | @property 221 | def send_key_down_delay(self): 222 | return self._send_key_down_delay 223 | 224 | @send_key_down_delay.setter 225 | def send_key_down_delay(self, value): 226 | auto_it_set_option("SendKeyDownDelay", value) 227 | self._send_key_down_delay = value 228 | 229 | @property 230 | def win_detect_hidden_text(self): 231 | return self._win_detect_hidden_text 232 | 233 | @win_detect_hidden_text.setter 234 | def win_detect_hidden_text(self, value): 235 | auto_it_set_option("WinDetectHiddenText", value) 236 | self._win_detect_hidden_text = value 237 | 238 | @property 239 | def win_search_children(self): 240 | return self._win_search_children 241 | 242 | @win_search_children.setter 243 | def win_search_children(self, value): 244 | auto_it_set_option("WinSearchChildren", value) 245 | self._win_search_children = value 246 | 247 | @property 248 | def win_text_match_mode(self): 249 | return self._win_text_match_mode 250 | 251 | @win_text_match_mode.setter 252 | def win_text_match_mode(self, value): 253 | auto_it_set_option("WinTextMatchMode", value) 254 | self._win_text_match_mode = value 255 | 256 | @property 257 | def win_title_match_mode(self): 258 | return self._win_title_match_mode 259 | 260 | @win_title_match_mode.setter 261 | def win_title_match_mode(self, value): 262 | auto_it_set_option("WinTitleMatchMode", value) 263 | self._win_title_match_mode = value 264 | 265 | @property 266 | def win_wait_delay(self): 267 | return self._win_wait_delay 268 | 269 | @win_wait_delay.setter 270 | def win_wait_delay(self, value): 271 | auto_it_set_option("WinWaitDelay", value) 272 | self._win_wait_delay = value 273 | 274 | 275 | class Commands(object): 276 | 277 | is_visible = "IsVisible" 278 | is_enabled = "IsEnabled" 279 | show_drop_down = "ShowDropDown" 280 | hide_drop_down = "HideDropDown" 281 | add_string = "AddString" 282 | del_string = "DelString" 283 | find_string = "FindString" 284 | set_current_selection = "SetCurrentSelection" 285 | is_checked = "IsChecked" 286 | check = "Check" 287 | un_check = "UnCheck" 288 | get_current_line = "GetCurrentLine" 289 | get_current_col = "GetCurrentCol" 290 | get_current_selection = "GetCurrentSelection" 291 | get_line_count = "GetLineCount" 292 | get_line = "GetLine" 293 | get_selected = "GetSelected" 294 | edit_paste = "EditPaste" 295 | current_tab = "CurrentTab" 296 | tab_right = "TabRight" 297 | tab_left = "TabLeft" 298 | de_select = "DeSelect" 299 | find_item = "FindItem" 300 | get_item_count = "GetItemCount" 301 | get_selected_count = "GetSelectedCount" 302 | get_sub_item_count = "GetSubItemCount" 303 | get_text = "GetText" 304 | is_selected = "IsSelected" 305 | select = "Select" 306 | select_all = "SelectAll" 307 | select_clear = "SelectClear" 308 | select_invert = "SelectInvert" 309 | view_change = "View" 310 | collapse = "Collapse" 311 | exists = "Exists" 312 | expand = "Expand" 313 | uncheck = "Uncheck" 314 | 315 | options = _Options() 316 | properties = Properties 317 | commands = Commands 318 | INTDEFAULT = -2147483647 319 | 320 | 321 | @api.check(1, err_msg="clipboard is empty or contains a non-text entry") 322 | def clip_get(buf_size=256): 323 | """ 324 | 325 | :param buf_size: 326 | :return: 327 | """ 328 | 329 | clip = ctypes.create_unicode_buffer(buf_size) 330 | AUTO_IT.AU3_ClipGet(clip, INT(buf_size)) 331 | return clip.value.rstrip() 332 | 333 | 334 | @api.check(2, err_msg="Write text to clipboard failed") 335 | def clip_put(value): 336 | """ 337 | 338 | :param value: 339 | :return: 340 | """ 341 | ret = AUTO_IT.AU3_ClipPut(LPCWSTR(value)) 342 | return ret 343 | 344 | 345 | def is_admin(): 346 | """ 347 | 348 | :return: 349 | """ 350 | ret = AUTO_IT.AU3_IsAdmin() 351 | return ret 352 | 353 | 354 | def drive_map_add(device, share, flag=0, user="", pwd="", buf_size=256): 355 | """ 356 | 357 | :param device: 358 | :param share: 359 | :param flag: 0 = default 360 | 1 = Persistant mapping 361 | 8 = Show authentication dialog if required 362 | :param user: 363 | :param pwd: 364 | :param buf_size: 365 | :return: 366 | """ 367 | result = ctypes.create_unicode_buffer(buf_size) 368 | 369 | err_code = { 370 | 1: "Undefined / Other error", 371 | 2: "Access to the remote share was denied", 372 | 3: "The device is already assigned", 373 | 4: "Invalid device name", 374 | 5: "Invalid remote share", 375 | 6: "Invalid password" 376 | } 377 | AUTO_IT.AU3_DriveMapAdd( 378 | LPCWSTR(device), LPCWSTR(share), INT(flag), LPCWSTR(user), 379 | LPCWSTR(pwd), result, INT(buf_size)) 380 | 381 | if error(): 382 | raise AutoItError(err_code.get(error(), None)) 383 | return result.value.rstrip() 384 | 385 | 386 | @api.check(2, err_msg="the disconnection was unsuccessful") 387 | def drive_map_del(device): 388 | """ 389 | 390 | :param device: 391 | :return: 392 | """ 393 | ret = AUTO_IT.AU3_DriveMapDel(LPCWSTR(device)) 394 | return ret 395 | 396 | 397 | @api.check(1, err_msg="get the details of a mapped drive failed") 398 | def drive_map_get(device, buf_size=256): 399 | """ 400 | 401 | :param device: 402 | :param buf_size: 403 | :return: 404 | """ 405 | mapping = ctypes.create_unicode_buffer(buf_size) 406 | AUTO_IT.AU3_DriveMapGet(LPCWSTR(device), mapping, INT(buf_size)) 407 | return mapping.value.rstrip() 408 | 409 | 410 | def mouse_click(button="left", x=INTDEFAULT, y=INTDEFAULT, clicks=1, speed=-1): 411 | """ 412 | 413 | :param button: 414 | :param x: 415 | :param y: 416 | :param clicks: 417 | :param speed: 418 | :return: 419 | """ 420 | ret = AUTO_IT.AU3_MouseClick( 421 | LPCWSTR(button), INT(x), INT(y), INT(clicks), INT(speed) 422 | ) 423 | return ret 424 | 425 | 426 | def mouse_click_drag(x1, y1, x2, y2, button="left", speed=-1): 427 | """ 428 | 429 | :param x1: 430 | :param y1: 431 | :param x2: 432 | :param y2: 433 | :param button: 434 | :param speed: 435 | :return: 436 | """ 437 | 438 | ret = AUTO_IT.AU3_MouseClickDrag( 439 | LPCWSTR(button), INT(x1), INT(y1), INT(x2), INT(y2), INT(speed) 440 | ) 441 | return ret 442 | 443 | 444 | def mouse_down(button="left"): 445 | """ 446 | 447 | :param button: 448 | :return: 449 | """ 450 | AUTO_IT.AU3_MouseDown(LPCWSTR(button)) 451 | 452 | 453 | def mouse_get_cursor(): 454 | """ 455 | 456 | :return: 457 | """ 458 | ret = AUTO_IT.AU3_MouseGetCursor() 459 | return ret 460 | 461 | 462 | def mouse_get_pos(): 463 | """ 464 | 465 | :return: 466 | """ 467 | p = POINT() 468 | AUTO_IT.AU3_MouseGetPos(ctypes.byref(p)) 469 | return p.x, p.y 470 | 471 | 472 | def mouse_move(x, y, speed=-1): 473 | """ 474 | 475 | :param x: 476 | :param y: 477 | :param speed: 478 | :return: 479 | """ 480 | ret = AUTO_IT.AU3_MouseMove(INT(x), INT(y), INT(speed)) 481 | return ret 482 | 483 | 484 | def mouse_up(button="left"): 485 | """ 486 | 487 | :param button: 488 | :return: 489 | """ 490 | AUTO_IT.AU3_MouseUp(LPCWSTR(button)) 491 | 492 | 493 | @api.check(1, err_msg="the direction is not recognized") 494 | def mouse_wheel(direction, clicks=-1): 495 | """ 496 | 497 | :param direction: "up" or "down" 498 | :param clicks: 499 | :return: 500 | """ 501 | AUTO_IT.AU3_MouseWheel(LPCWSTR(direction), INT(clicks)) 502 | 503 | 504 | def opt(option, value): 505 | """ 506 | 507 | :param option: 508 | :param value: 509 | :return: 510 | """ 511 | return auto_it_set_option(option, value) 512 | 513 | 514 | def pixel_checksum(left, top, right, bottom, step=1): 515 | """ 516 | 517 | :param left: 518 | :param top: 519 | :param right: 520 | :param bottom: 521 | :param step: 522 | :return: 523 | """ 524 | rect = RECT(left, top, right, bottom) 525 | ret = AUTO_IT.AU3_PixelChecksum(ctypes.byref(rect), INT(step)) 526 | return ret 527 | 528 | 529 | @api.check(2, unexpected_ret=(-1,), err_msg="invalid coordinates") 530 | def pixel_get_color(x, y): 531 | """ 532 | 533 | :param x: 534 | :param y: 535 | :return: 536 | """ 537 | ret = AUTO_IT.AU3_PixelGetColor(INT(x), INT(y)) 538 | return ret 539 | 540 | 541 | @api.check(1, err_msg="color is not found") 542 | def pixel_search(left, top, right, bottom, col, var=1, step=1): 543 | """ 544 | 545 | :param left: 546 | :param top: 547 | :param right: 548 | :param bottom: 549 | :param col: 550 | :param var: 551 | :param step: 552 | :return: 553 | """ 554 | p = POINT() 555 | rect = RECT(left, top, right, bottom) 556 | 557 | AUTO_IT.AU3_PixelSearch( 558 | ctypes.byref(rect), INT(col), INT(var), INT(step), ctypes.byref(p) 559 | ) 560 | return p.x, p.y 561 | 562 | 563 | def send(send_text, mode=0): 564 | """ 565 | Sends simulated keystrokes to the active window. 566 | :param send_text: 567 | :param mode: Changes how "keys" is processed: 568 | flag = 0 (default), Text contains special characters like + and ! to 569 | indicate SHIFT and ALT key presses. 570 | flag = 1, keys are sent raw. 571 | :return: 572 | """ 573 | AUTO_IT.AU3_Send(LPCWSTR(send_text), INT(mode)) 574 | 575 | 576 | def tooltip(tip, x=INTDEFAULT, y=INTDEFAULT): 577 | """ 578 | 579 | :param tip: 580 | :param x: 581 | :param y: 582 | :return: 583 | """ 584 | AUTO_IT.AU3_ToolTip(LPCWSTR(tip), INT(x), INT(y)) 585 | -------------------------------------------------------------------------------- /ExtDepLibs/autoit/control.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | __author__ = 'Jace Xu' 4 | 5 | from autoit import INTDEFAULT, AUTO_IT 6 | from autoit import api 7 | from ctypes.wintypes import * 8 | import ctypes 9 | 10 | 11 | @api.check(2, "send click message failed") 12 | def control_click(title, control, **kwargs): 13 | """ 14 | 15 | :param title: 16 | :param text: 17 | :param control: 18 | :param button: 19 | :param clicks: 20 | :param x: 21 | :param y: 22 | :return: 23 | """ 24 | text = kwargs.get("text", "") 25 | button = kwargs.get("button", "left") 26 | clicks = kwargs.get("clicks", 1) 27 | x = kwargs.get("x", INTDEFAULT) 28 | y = kwargs.get("y", INTDEFAULT) 29 | 30 | ret = AUTO_IT.AU3_ControlClick(LPCWSTR(title), LPCWSTR(text), 31 | LPCWSTR(control), LPCWSTR(button), 32 | INT(clicks), INT(x), INT(y)) 33 | return ret 34 | 35 | 36 | @api.check(2, "send click message failed") 37 | def control_click_by_handle(hwnd, h_ctrl, **kwargs): 38 | """ 39 | 40 | :param handle: 41 | :param kwargs: 42 | :return: 43 | """ 44 | button = kwargs.get("button", "left") 45 | clicks = kwargs.get("clicks", 1) 46 | x = kwargs.get("x", INTDEFAULT) 47 | y = kwargs.get("y", INTDEFAULT) 48 | 49 | ret = AUTO_IT.AU3_ControlClickByHandle(HWND(hwnd), HWND(h_ctrl), 50 | LPCWSTR(button), INT(clicks), 51 | INT(x), INT(y)) 52 | return ret 53 | 54 | 55 | @api.check(1, "no window match the criteria") 56 | def control_command(title, control, command, buf_size=256, **kwargs): 57 | """ 58 | 59 | :param title: 60 | :param control: 61 | :param command: 62 | :param extra: 63 | :param buf_size: 64 | :return: 65 | """ 66 | text = kwargs.get("text", "") 67 | extra = kwargs.get("extra", "") 68 | result = ctypes.create_unicode_buffer(buf_size) 69 | AUTO_IT.AU3_ControlCommand(LPCWSTR(title), LPCWSTR(text), LPCWSTR(control), 70 | LPCWSTR(command), LPCWSTR(extra), 71 | result, INT(buf_size)) 72 | 73 | return result.value.rstrip() 74 | 75 | 76 | @api.check(1, "no window match the criteria") 77 | def control_command_by_handle(hwnd, h_ctrl, command, buf_size=256, **kwargs): 78 | """ 79 | 80 | :param hwnd: 81 | :param h_ctrl: 82 | :param command: 83 | :param kwargs: 84 | :return: 85 | """ 86 | extra = kwargs.get("extra", "") 87 | result = ctypes.create_unicode_buffer(buf_size) 88 | 89 | AUTO_IT.AU3_ControlCommandByHandle( 90 | HWND(hwnd), HWND(h_ctrl), LPCWSTR(command), LPCWSTR(extra), result, 91 | INT(buf_size)) 92 | return result.value.rstrip() 93 | 94 | 95 | @api.check(1, "Window/Control could not be found") 96 | def control_list_view(title, control, command, **kwargs): 97 | """ 98 | 99 | :param title: 100 | :param control: 101 | :param command: 102 | :param args: 103 | :param kwargs: 104 | :return: 105 | """ 106 | text = kwargs.get("text", "") 107 | buf_size = kwargs.get("buf_size", 256) 108 | result = ctypes.create_unicode_buffer(buf_size) 109 | extra1 = kwargs.get("extras1", "") 110 | extra2 = kwargs.get("extras2", "") 111 | 112 | AUTO_IT.AU3_ControlListView( 113 | LPCWSTR(title), LPCWSTR(text), LPCWSTR(control), LPCWSTR(command), 114 | LPCWSTR(extra1), LPCWSTR(extra2), result, INT(buf_size) 115 | ) 116 | return result.value.rstrip() 117 | 118 | 119 | @api.check(1, "Window/Control could not be found") 120 | def control_list_view_by_handle(hwnd, h_ctrl, command, **kwargs): 121 | """ 122 | 123 | :param hwnd: 124 | :param h_ctrl: 125 | :param command: 126 | :param kwargs: 127 | :return: 128 | """ 129 | extra1 = kwargs.get("extra1", "") 130 | extra2 = kwargs.get("extra2", "") 131 | buf_size = kwargs.get("buf_size", 256) 132 | result = ctypes.create_unicode_buffer(buf_size) 133 | 134 | AUTO_IT.AU3_ControlListViewByHandle( 135 | HWND(hwnd), HWND(h_ctrl), LPCWSTR(command), 136 | LPCWSTR(extra1), LPCWSTR(extra2), result, INT(buf_size) 137 | ) 138 | return result.value.rstrip() 139 | 140 | 141 | @api.check(2, "Window/Control could not be found") 142 | def control_disable(title, control, **kwargs): 143 | """ 144 | 145 | :param title: 146 | :param control: 147 | :param kwargs: 148 | :return: 149 | """ 150 | text = kwargs.get("text", "") 151 | 152 | ret = AUTO_IT.AU3_ControlDisable(LPCWSTR(title), LPCWSTR(text), 153 | LPCWSTR(control)) 154 | return ret 155 | 156 | 157 | @api.check(2, "Window/Control could not be found") 158 | def control_disable_by_handle(hwnd, h_ctrl): 159 | """ 160 | 161 | :param hwnd: 162 | :param h_ctrl: 163 | :return: 164 | """ 165 | ret = AUTO_IT.AU3_ControlDisableByHandle(HWND(hwnd), HWND(h_ctrl)) 166 | return ret 167 | 168 | 169 | @api.check(2, "Window/Control could not be found") 170 | def control_enable(title, control, **kwargs): 171 | """ 172 | 173 | :param title: 174 | :param control: 175 | :param kwargs: 176 | :return: 177 | """ 178 | text = kwargs.get("text", "") 179 | 180 | ret = AUTO_IT.AU3_ControlEnable(LPCWSTR(title), LPCWSTR(text), 181 | LPCWSTR(control)) 182 | return ret 183 | 184 | 185 | @api.check(2, "Window/Control could not be found") 186 | def control_enable_by_handle(hwnd, h_ctrl): 187 | """ 188 | 189 | :param hwnd: 190 | :param h_ctrl: 191 | :return: 192 | """ 193 | ret = AUTO_IT.AU3_ControlEnableByHandle(HWND(hwnd), HWND(h_ctrl)) 194 | return ret 195 | 196 | 197 | @api.check(2, "Window/Control could not be found") 198 | def control_focus(title, control, **kwargs): 199 | """ 200 | 201 | :param title: 202 | :param control: 203 | :param kwargs: 204 | :return: 205 | """ 206 | text = kwargs.get("text", "") 207 | 208 | ret = AUTO_IT.AU3_ControlFocus( 209 | LPCWSTR(title), LPCWSTR(text), LPCWSTR(control)) 210 | return ret 211 | 212 | 213 | @api.check(2, "Window/Control could not be found") 214 | def control_focus_by_handle(hwnd, h_ctrl): 215 | """ 216 | 217 | :param hwnd: 218 | :param h_ctrl: 219 | :return: 220 | """ 221 | ret = AUTO_IT.AU3_ControlFocusByHandle(HWND(hwnd), HWND(h_ctrl)) 222 | return ret 223 | 224 | 225 | @api.check(1, "Window/Control could not be found") 226 | def control_get_focus(title, **kwargs): 227 | """ 228 | 229 | :param title: 230 | :param kwargs: 231 | :return: 232 | """ 233 | buf_size = kwargs.get("buf_size", 256) 234 | text = kwargs.get("text", "") 235 | ctrl_with_focus = ctypes.create_unicode_buffer(buf_size) 236 | 237 | AUTO_IT.AU3_ControlGetFocus( 238 | LPCWSTR(title), LPCWSTR(text), ctrl_with_focus, INT(buf_size)) 239 | return ctrl_with_focus.value.rstrip() 240 | 241 | 242 | @api.check(1, "Window/Control could not be found") 243 | def control_get_focus_by_handle(hwnd, buf_size=256): 244 | """ 245 | 246 | :param hwnd: 247 | :param buf_size: 248 | :return: 249 | """ 250 | ctrl_with_focus = ctypes.create_unicode_buffer(buf_size) 251 | 252 | AUTO_IT.AU3_ControlGetFocusByHandle(HWND(hwnd), ctrl_with_focus, 253 | INT(buf_size)) 254 | return ctrl_with_focus.value.rstrip() 255 | 256 | 257 | @api.check(1, "Window/Control could not be found") 258 | def control_get_handle(hwnd, control): 259 | """ 260 | 261 | :param hwnd: 262 | :param control: 263 | :return: 264 | """ 265 | ret = AUTO_IT.AU3_ControlGetHandle(HWND(hwnd), LPCWSTR(control)) 266 | return ret 267 | 268 | 269 | @api.check(1, "Window/Control could not be found") 270 | def control_get_handle_as_text(title, control, **kwargs): 271 | """ 272 | 273 | :param title: 274 | :param control: 275 | :param kwargs: 276 | :return: 277 | """ 278 | text = kwargs.get("text", "") 279 | buf_size = kwargs.get("buf_size", 32) 280 | ret_text = ctypes.create_unicode_buffer(buf_size) 281 | 282 | AUTO_IT.AU3_ControlGetHandleAsText( 283 | LPCWSTR(title), LPCWSTR(text), LPCWSTR(control), 284 | ret_text, INT(buf_size) 285 | ) 286 | return ret_text.value.rstrip() 287 | 288 | 289 | @api.check(1, "Window/Control could not be found") 290 | def control_get_pos(title, control, text=""): 291 | """ 292 | 293 | :param title: 294 | :param control: 295 | :param text: 296 | :return: 297 | """ 298 | rect = RECT() 299 | 300 | AUTO_IT.AU3_ControlGetPos( 301 | LPCWSTR(title), LPCWSTR(text), LPCWSTR(control), 302 | ctypes.byref(rect) 303 | ) 304 | return rect.left, rect.top, rect.right, rect.bottom 305 | 306 | 307 | @api.check(1, "Window/Control could not be found") 308 | def control_get_pos_by_handle(hwnd, h_ctrl): 309 | """ 310 | 311 | :param hwnd: 312 | :param h_ctrl: 313 | :return: 314 | """ 315 | rect = RECT() 316 | 317 | AUTO_IT.AU3_ControlGetPosByHandle(HWND(hwnd), HWND(h_ctrl), 318 | ctypes.byref(rect)) 319 | return rect.left, rect.top, rect.right, rect.bottom 320 | 321 | 322 | @api.check(1, "Window/Control could not be found") 323 | def control_get_text(title, control, **kwargs): 324 | """ 325 | 326 | :param title: 327 | :param control: 328 | :param kwargs: 329 | :return: 330 | """ 331 | text = kwargs.get("text", "") 332 | buf_size = kwargs.get("buf_size", 256) 333 | ctrl_text = ctypes.create_unicode_buffer(buf_size) 334 | 335 | AUTO_IT.AU3_ControlGetText( 336 | LPCWSTR(title), LPCWSTR(text), LPCWSTR(control), 337 | ctrl_text, INT(buf_size) 338 | ) 339 | 340 | return ctrl_text.value.rstrip() 341 | 342 | 343 | @api.check(1, "Window/Control could not be found") 344 | def control_get_text_by_handle(hwnd, h_ctrl, **kwargs): 345 | """ 346 | 347 | :param hwnd: 348 | :param h_ctrl: 349 | :return: 350 | """ 351 | buf_size = kwargs.get("buf_size", 256) 352 | ctrl_text = ctypes.create_unicode_buffer(buf_size) 353 | 354 | AUTO_IT.AU3_ControlGetTextByHandle( 355 | HWND(hwnd), HWND(h_ctrl), ctrl_text, INT(buf_size) 356 | ) 357 | 358 | return ctrl_text.value.rstrip() 359 | 360 | 361 | @api.check(2, "Window/Control could not be found") 362 | def control_hide(title, control, **kwargs): 363 | """ 364 | 365 | :param title: 366 | :param control: 367 | :param kwargs: 368 | :return: 369 | """ 370 | text = kwargs.get("text", "") 371 | 372 | ret = AUTO_IT.AU3_ControlHide( 373 | LPCWSTR(title), LPCWSTR(text), LPCWSTR(control)) 374 | return ret 375 | 376 | 377 | @api.check(2, "Window/Control could not be found") 378 | def control_hide_by_handle(hwnd, h_ctrl): 379 | """ 380 | 381 | :param hwnd: 382 | :param h_ctrl: 383 | :return: 384 | """ 385 | ret = AUTO_IT.AU3_ControlHideByHandle(HWND(hwnd), HWND(h_ctrl)) 386 | return ret 387 | 388 | 389 | @api.check(2, "Window/Control could not be found") 390 | def control_move(title, control, x, y, width=-1, height=-1, **kwargs): 391 | """ 392 | 393 | :param title: 394 | :param control: 395 | :param x: 396 | :param y: 397 | :param kwargs: 398 | :return: 399 | """ 400 | text = kwargs.get("text", "") 401 | 402 | ret = AUTO_IT.AU3_ControlMove( 403 | LPCWSTR(title), LPCWSTR(text), LPCWSTR(control), 404 | INT(x), INT(y), INT(width), INT(height) 405 | ) 406 | return ret 407 | 408 | 409 | @api.check(2, "Window/Control could not be found") 410 | def control_move_by_handle(hwnd, h_ctrl, x, y, width=-1, height=-1): 411 | """ 412 | 413 | :param hwnd: 414 | :param h_ctrl: 415 | :param x: 416 | :param y: 417 | :param width: 418 | :param height: 419 | :return: 420 | """ 421 | ret = AUTO_IT.AU3_ControlMoveByHandle( 422 | HWND(hwnd), HWND(h_ctrl), INT(x), INT(y), INT(width), INT(height) 423 | ) 424 | return ret 425 | 426 | 427 | @api.check(2, "Window/Control could not be found") 428 | def control_send(title, control, send_text, mode=0, **kwargs): 429 | """ 430 | 431 | :param title: 432 | :param control: 433 | :param send_text: 434 | :param mode: 435 | flag = 0 (default), Text contains special characters like + to indicate 436 | SHIFT and {LEFT} to indicate left arrow. 437 | flag = 1, keys are sent raw. 438 | :param kwargs: 439 | :return: 440 | """ 441 | text = kwargs.get("text", "") 442 | 443 | ret = AUTO_IT.AU3_ControlSend( 444 | LPCWSTR(title), LPCWSTR(text), LPCWSTR(control), 445 | LPCWSTR(send_text), INT(mode) 446 | ) 447 | return ret 448 | 449 | 450 | @api.check(2, "Window/Control could not be found") 451 | def control_send_by_handle(hwnd, h_ctrl, send_text, mode=0): 452 | """ 453 | 454 | :param hwnd: 455 | :param h_ctrl: 456 | :param send_text: 457 | :param mode: 458 | :return: 459 | """ 460 | 461 | ret = AUTO_IT.AU3_ControlSendByHandle( 462 | HWND(hwnd), HWND(h_ctrl), LPCWSTR(send_text), INT(mode) 463 | ) 464 | return ret 465 | 466 | 467 | @api.check(2, "Window/Control could not be found") 468 | def control_set_text(title, control, control_text, **kwargs): 469 | """ 470 | 471 | :param title: 472 | :param control: 473 | :param control_text: 474 | :param kwargs: 475 | :return: 476 | """ 477 | text = kwargs.get("text", "") 478 | 479 | ret = AUTO_IT.AU3_ControlSetText( 480 | LPCWSTR(title), LPCWSTR(text), LPCWSTR(control), LPCWSTR(control_text) 481 | ) 482 | return ret 483 | 484 | 485 | @api.check(2, "Window/Control could not be found") 486 | def control_set_text_by_handle(hwnd, h_ctrl, control_text): 487 | """ 488 | 489 | :param hwnd: 490 | :param h_ctrl: 491 | :param control_text: 492 | :return: 493 | """ 494 | ret = AUTO_IT.AU3_ControlSetTextByHandle( 495 | HWND(hwnd), HWND(h_ctrl), LPCWSTR(control_text) 496 | ) 497 | return ret 498 | 499 | 500 | @api.check(2, "Window/Control could not be found") 501 | def control_show(title, control, **kwargs): 502 | """ 503 | 504 | :param title: 505 | :param control: 506 | :param kwargs: 507 | :return: 508 | """ 509 | text = kwargs.get("text", "") 510 | 511 | ret = AUTO_IT.AU3_ControlShow( 512 | LPCWSTR(title), LPCWSTR(text), LPCWSTR(control)) 513 | return ret 514 | 515 | 516 | @api.check(2, "Window/Control could not be found") 517 | def control_show_by_handle(hwnd, h_ctrl): 518 | """ 519 | 520 | :param hwnd: 521 | :param h_ctrl: 522 | :return: 523 | """ 524 | ret = AUTO_IT.AU3_ControlShowByHandle(HWND(hwnd), HWND(h_ctrl)) 525 | return ret 526 | 527 | 528 | @api.check(1, "Window/Control could not be found") 529 | def control_tree_view(title, control, command, **kwargs): 530 | """ 531 | 532 | :param title: 533 | :param control: 534 | :param command: 535 | :param args: 536 | :param kwargs: 537 | :return: 538 | """ 539 | text = kwargs.get("text", "") 540 | buf_size = kwargs.get("buf_size", 256) 541 | result = ctypes.create_unicode_buffer(buf_size) 542 | extra1 = kwargs.get("extras1", "") 543 | extra2 = kwargs.get("extras2", "") 544 | 545 | AUTO_IT.AU3_ControlTreeView( 546 | LPCWSTR(title), LPCWSTR(text), LPCWSTR(control), LPCWSTR(command), 547 | LPCWSTR(extra1), LPCWSTR(extra2), result, INT(buf_size) 548 | ) 549 | 550 | return result.value.rstrip() 551 | 552 | 553 | @api.check(1, "Window/Control could not be found") 554 | def control_tree_view_by_handle(hwnd, h_ctrl, command, **kwargs): 555 | """ 556 | 557 | :param hwnd: 558 | :param h_ctrl: 559 | :param command: 560 | :param kwargs: 561 | :return: 562 | """ 563 | extra1 = kwargs.get("extra1", "") 564 | extra2 = kwargs.get("extra2", "") 565 | buf_size = kwargs.get("buf_size", 256) 566 | result = ctypes.create_unicode_buffer(buf_size) 567 | 568 | AUTO_IT.AU3_ControlTreeViewByHandle( 569 | HWND(hwnd), HWND(h_ctrl), LPCWSTR(command), 570 | LPCWSTR(extra1), LPCWSTR(extra2), result, INT(buf_size) 571 | ) 572 | return result.value.rstrip() 573 | 574 | 575 | @api.check(1, "Window/Control could not be found") 576 | def statusbar_get_text(title, text="", part=1, buf_size=256): 577 | """ 578 | 579 | :param title: 580 | :param text: 581 | :param part: The "part" number of the status bar to read - the default 582 | is 1. 1 is the first possible part and usually the one that contains 583 | the useful messages like "Ready" "Loading...", etc. 584 | :param buf_size: 585 | :return: 586 | """ 587 | sb_text = ctypes.create_unicode_buffer(buf_size) 588 | 589 | AUTO_IT.AU3_StatusbarGetText( 590 | LPCWSTR(title), LPCWSTR(text), INT(part), sb_text, INT(buf_size) 591 | ) 592 | 593 | return sb_text.value.rstrip() 594 | 595 | 596 | @api.check(1, "Window/Control could not be found") 597 | def statusbar_get_text_by_handle(hwnd, part=1, buf_size=256): 598 | """ 599 | 600 | :param hwnd: 601 | :param part: 602 | :param buf_size: 603 | :return: 604 | """ 605 | statusbar_text = ctypes.create_unicode_buffer(buf_size) 606 | 607 | AUTO_IT.AU3_StatusbarGetTextByHandle( 608 | HWND(hwnd), INT(part), statusbar_text, INT(buf_size) 609 | ) 610 | 611 | return statusbar_text.value.rstrip() -------------------------------------------------------------------------------- /ExtDepLibs/winappdbg/win32/context_i386.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # Copyright (c) 2009-2016, Mario Vilas 5 | # All rights reserved. 6 | # 7 | # Redistribution and use in source and binary forms, with or without 8 | # modification, are permitted provided that the following conditions are met: 9 | # 10 | # * Redistributions of source code must retain the above copyright notice, 11 | # this list of conditions and the following disclaimer. 12 | # * Redistributions in binary form must reproduce the above copyright 13 | # notice,this list of conditions and the following disclaimer in the 14 | # documentation and/or other materials provided with the distribution. 15 | # * Neither the name of the copyright holder nor the names of its 16 | # contributors may be used to endorse or promote products derived from 17 | # this software without specific prior written permission. 18 | # 19 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 | # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 23 | # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 | # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 | # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 | # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 | # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 | # POSSIBILITY OF SUCH DAMAGE. 30 | 31 | """ 32 | CONTEXT structure for i386. 33 | """ 34 | 35 | from defines import * 36 | from version import ARCH_I386 37 | 38 | #============================================================================== 39 | # This is used later on to calculate the list of exported symbols. 40 | _all = None 41 | _all = set(vars().keys()) 42 | #============================================================================== 43 | 44 | #--- CONTEXT structures and constants ----------------------------------------- 45 | 46 | # The following values specify the type of access in the first parameter 47 | # of the exception record when the exception code specifies an access 48 | # violation. 49 | EXCEPTION_READ_FAULT = 0 # exception caused by a read 50 | EXCEPTION_WRITE_FAULT = 1 # exception caused by a write 51 | EXCEPTION_EXECUTE_FAULT = 8 # exception caused by an instruction fetch 52 | 53 | CONTEXT_i386 = 0x00010000 # this assumes that i386 and 54 | CONTEXT_i486 = 0x00010000 # i486 have identical context records 55 | 56 | CONTEXT_CONTROL = (CONTEXT_i386 | 0x00000001L) # SS:SP, CS:IP, FLAGS, BP 57 | CONTEXT_INTEGER = (CONTEXT_i386 | 0x00000002L) # AX, BX, CX, DX, SI, DI 58 | CONTEXT_SEGMENTS = (CONTEXT_i386 | 0x00000004L) # DS, ES, FS, GS 59 | CONTEXT_FLOATING_POINT = (CONTEXT_i386 | 0x00000008L) # 387 state 60 | CONTEXT_DEBUG_REGISTERS = (CONTEXT_i386 | 0x00000010L) # DB 0-3,6,7 61 | CONTEXT_EXTENDED_REGISTERS = (CONTEXT_i386 | 0x00000020L) # cpu specific extensions 62 | 63 | CONTEXT_FULL = (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS) 64 | 65 | CONTEXT_ALL = (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS | \ 66 | CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS | \ 67 | CONTEXT_EXTENDED_REGISTERS) 68 | 69 | SIZE_OF_80387_REGISTERS = 80 70 | MAXIMUM_SUPPORTED_EXTENSION = 512 71 | 72 | # typedef struct _FLOATING_SAVE_AREA { 73 | # DWORD ControlWord; 74 | # DWORD StatusWord; 75 | # DWORD TagWord; 76 | # DWORD ErrorOffset; 77 | # DWORD ErrorSelector; 78 | # DWORD DataOffset; 79 | # DWORD DataSelector; 80 | # BYTE RegisterArea[SIZE_OF_80387_REGISTERS]; 81 | # DWORD Cr0NpxState; 82 | # } FLOATING_SAVE_AREA; 83 | class FLOATING_SAVE_AREA(Structure): 84 | _pack_ = 1 85 | _fields_ = [ 86 | ('ControlWord', DWORD), 87 | ('StatusWord', DWORD), 88 | ('TagWord', DWORD), 89 | ('ErrorOffset', DWORD), 90 | ('ErrorSelector', DWORD), 91 | ('DataOffset', DWORD), 92 | ('DataSelector', DWORD), 93 | ('RegisterArea', BYTE * SIZE_OF_80387_REGISTERS), 94 | ('Cr0NpxState', DWORD), 95 | ] 96 | 97 | _integer_members = ('ControlWord', 'StatusWord', 'TagWord', 'ErrorOffset', 'ErrorSelector', 'DataOffset', 'DataSelector', 'Cr0NpxState') 98 | 99 | @classmethod 100 | def from_dict(cls, fsa): 101 | 'Instance a new structure from a Python dictionary.' 102 | fsa = dict(fsa) 103 | s = cls() 104 | for key in cls._integer_members: 105 | setattr(s, key, fsa.get(key)) 106 | ra = fsa.get('RegisterArea', None) 107 | if ra is not None: 108 | for index in xrange(0, SIZE_OF_80387_REGISTERS): 109 | s.RegisterArea[index] = ra[index] 110 | return s 111 | 112 | def to_dict(self): 113 | 'Convert a structure into a Python dictionary.' 114 | fsa = dict() 115 | for key in self._integer_members: 116 | fsa[key] = getattr(self, key) 117 | ra = [ self.RegisterArea[index] for index in xrange(0, SIZE_OF_80387_REGISTERS) ] 118 | ra = tuple(ra) 119 | fsa['RegisterArea'] = ra 120 | return fsa 121 | 122 | PFLOATING_SAVE_AREA = POINTER(FLOATING_SAVE_AREA) 123 | LPFLOATING_SAVE_AREA = PFLOATING_SAVE_AREA 124 | 125 | # typedef struct _CONTEXT { 126 | # DWORD ContextFlags; 127 | # DWORD Dr0; 128 | # DWORD Dr1; 129 | # DWORD Dr2; 130 | # DWORD Dr3; 131 | # DWORD Dr6; 132 | # DWORD Dr7; 133 | # FLOATING_SAVE_AREA FloatSave; 134 | # DWORD SegGs; 135 | # DWORD SegFs; 136 | # DWORD SegEs; 137 | # DWORD SegDs; 138 | # DWORD Edi; 139 | # DWORD Esi; 140 | # DWORD Ebx; 141 | # DWORD Edx; 142 | # DWORD Ecx; 143 | # DWORD Eax; 144 | # DWORD Ebp; 145 | # DWORD Eip; 146 | # DWORD SegCs; 147 | # DWORD EFlags; 148 | # DWORD Esp; 149 | # DWORD SegSs; 150 | # BYTE ExtendedRegisters[MAXIMUM_SUPPORTED_EXTENSION]; 151 | # } CONTEXT; 152 | class CONTEXT(Structure): 153 | arch = ARCH_I386 154 | 155 | _pack_ = 1 156 | 157 | # Context Frame 158 | # 159 | # This frame has a several purposes: 1) it is used as an argument to 160 | # NtContinue, 2) is is used to constuct a call frame for APC delivery, 161 | # and 3) it is used in the user level thread creation routines. 162 | # 163 | # The layout of the record conforms to a standard call frame. 164 | 165 | _fields_ = [ 166 | 167 | # The flags values within this flag control the contents of 168 | # a CONTEXT record. 169 | # 170 | # If the context record is used as an input parameter, then 171 | # for each portion of the context record controlled by a flag 172 | # whose value is set, it is assumed that that portion of the 173 | # context record contains valid context. If the context record 174 | # is being used to modify a threads context, then only that 175 | # portion of the threads context will be modified. 176 | # 177 | # If the context record is used as an IN OUT parameter to capture 178 | # the context of a thread, then only those portions of the thread's 179 | # context corresponding to set flags will be returned. 180 | # 181 | # The context record is never used as an OUT only parameter. 182 | 183 | ('ContextFlags', DWORD), 184 | 185 | # This section is specified/returned if CONTEXT_DEBUG_REGISTERS is 186 | # set in ContextFlags. Note that CONTEXT_DEBUG_REGISTERS is NOT 187 | # included in CONTEXT_FULL. 188 | 189 | ('Dr0', DWORD), 190 | ('Dr1', DWORD), 191 | ('Dr2', DWORD), 192 | ('Dr3', DWORD), 193 | ('Dr6', DWORD), 194 | ('Dr7', DWORD), 195 | 196 | # This section is specified/returned if the 197 | # ContextFlags word contains the flag CONTEXT_FLOATING_POINT. 198 | 199 | ('FloatSave', FLOATING_SAVE_AREA), 200 | 201 | # This section is specified/returned if the 202 | # ContextFlags word contains the flag CONTEXT_SEGMENTS. 203 | 204 | ('SegGs', DWORD), 205 | ('SegFs', DWORD), 206 | ('SegEs', DWORD), 207 | ('SegDs', DWORD), 208 | 209 | # This section is specified/returned if the 210 | # ContextFlags word contains the flag CONTEXT_INTEGER. 211 | 212 | ('Edi', DWORD), 213 | ('Esi', DWORD), 214 | ('Ebx', DWORD), 215 | ('Edx', DWORD), 216 | ('Ecx', DWORD), 217 | ('Eax', DWORD), 218 | 219 | # This section is specified/returned if the 220 | # ContextFlags word contains the flag CONTEXT_CONTROL. 221 | 222 | ('Ebp', DWORD), 223 | ('Eip', DWORD), 224 | ('SegCs', DWORD), # MUST BE SANITIZED 225 | ('EFlags', DWORD), # MUST BE SANITIZED 226 | ('Esp', DWORD), 227 | ('SegSs', DWORD), 228 | 229 | # This section is specified/returned if the ContextFlags word 230 | # contains the flag CONTEXT_EXTENDED_REGISTERS. 231 | # The format and contexts are processor specific. 232 | 233 | ('ExtendedRegisters', BYTE * MAXIMUM_SUPPORTED_EXTENSION), 234 | ] 235 | 236 | _ctx_debug = ('Dr0', 'Dr1', 'Dr2', 'Dr3', 'Dr6', 'Dr7') 237 | _ctx_segs = ('SegGs', 'SegFs', 'SegEs', 'SegDs', ) 238 | _ctx_int = ('Edi', 'Esi', 'Ebx', 'Edx', 'Ecx', 'Eax') 239 | _ctx_ctrl = ('Ebp', 'Eip', 'SegCs', 'EFlags', 'Esp', 'SegSs') 240 | 241 | @classmethod 242 | def from_dict(cls, ctx): 243 | 'Instance a new structure from a Python dictionary.' 244 | ctx = Context(ctx) 245 | s = cls() 246 | ContextFlags = ctx['ContextFlags'] 247 | setattr(s, 'ContextFlags', ContextFlags) 248 | if (ContextFlags & CONTEXT_DEBUG_REGISTERS) == CONTEXT_DEBUG_REGISTERS: 249 | for key in s._ctx_debug: 250 | setattr(s, key, ctx[key]) 251 | if (ContextFlags & CONTEXT_FLOATING_POINT) == CONTEXT_FLOATING_POINT: 252 | fsa = ctx['FloatSave'] 253 | s.FloatSave = FLOATING_SAVE_AREA.from_dict(fsa) 254 | if (ContextFlags & CONTEXT_SEGMENTS) == CONTEXT_SEGMENTS: 255 | for key in s._ctx_segs: 256 | setattr(s, key, ctx[key]) 257 | if (ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER: 258 | for key in s._ctx_int: 259 | setattr(s, key, ctx[key]) 260 | if (ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL: 261 | for key in s._ctx_ctrl: 262 | setattr(s, key, ctx[key]) 263 | if (ContextFlags & CONTEXT_EXTENDED_REGISTERS) == CONTEXT_EXTENDED_REGISTERS: 264 | er = ctx['ExtendedRegisters'] 265 | for index in xrange(0, MAXIMUM_SUPPORTED_EXTENSION): 266 | s.ExtendedRegisters[index] = er[index] 267 | return s 268 | 269 | def to_dict(self): 270 | 'Convert a structure into a Python native type.' 271 | ctx = Context() 272 | ContextFlags = self.ContextFlags 273 | ctx['ContextFlags'] = ContextFlags 274 | if (ContextFlags & CONTEXT_DEBUG_REGISTERS) == CONTEXT_DEBUG_REGISTERS: 275 | for key in self._ctx_debug: 276 | ctx[key] = getattr(self, key) 277 | if (ContextFlags & CONTEXT_FLOATING_POINT) == CONTEXT_FLOATING_POINT: 278 | ctx['FloatSave'] = self.FloatSave.to_dict() 279 | if (ContextFlags & CONTEXT_SEGMENTS) == CONTEXT_SEGMENTS: 280 | for key in self._ctx_segs: 281 | ctx[key] = getattr(self, key) 282 | if (ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER: 283 | for key in self._ctx_int: 284 | ctx[key] = getattr(self, key) 285 | if (ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL: 286 | for key in self._ctx_ctrl: 287 | ctx[key] = getattr(self, key) 288 | if (ContextFlags & CONTEXT_EXTENDED_REGISTERS) == CONTEXT_EXTENDED_REGISTERS: 289 | er = [ self.ExtendedRegisters[index] for index in xrange(0, MAXIMUM_SUPPORTED_EXTENSION) ] 290 | er = tuple(er) 291 | ctx['ExtendedRegisters'] = er 292 | return ctx 293 | 294 | PCONTEXT = POINTER(CONTEXT) 295 | LPCONTEXT = PCONTEXT 296 | 297 | class Context(dict): 298 | """ 299 | Register context dictionary for the i386 architecture. 300 | """ 301 | 302 | arch = CONTEXT.arch 303 | 304 | def __get_pc(self): 305 | return self['Eip'] 306 | def __set_pc(self, value): 307 | self['Eip'] = value 308 | pc = property(__get_pc, __set_pc) 309 | 310 | def __get_sp(self): 311 | return self['Esp'] 312 | def __set_sp(self, value): 313 | self['Esp'] = value 314 | sp = property(__get_sp, __set_sp) 315 | 316 | def __get_fp(self): 317 | return self['Ebp'] 318 | def __set_fp(self, value): 319 | self['Ebp'] = value 320 | fp = property(__get_fp, __set_fp) 321 | 322 | #--- LDT_ENTRY structure ------------------------------------------------------ 323 | 324 | # typedef struct _LDT_ENTRY { 325 | # WORD LimitLow; 326 | # WORD BaseLow; 327 | # union { 328 | # struct { 329 | # BYTE BaseMid; 330 | # BYTE Flags1; 331 | # BYTE Flags2; 332 | # BYTE BaseHi; 333 | # } Bytes; 334 | # struct { 335 | # DWORD BaseMid :8; 336 | # DWORD Type :5; 337 | # DWORD Dpl :2; 338 | # DWORD Pres :1; 339 | # DWORD LimitHi :4; 340 | # DWORD Sys :1; 341 | # DWORD Reserved_0 :1; 342 | # DWORD Default_Big :1; 343 | # DWORD Granularity :1; 344 | # DWORD BaseHi :8; 345 | # } Bits; 346 | # } HighWord; 347 | # } LDT_ENTRY, 348 | # *PLDT_ENTRY; 349 | 350 | class _LDT_ENTRY_BYTES_(Structure): 351 | _pack_ = 1 352 | _fields_ = [ 353 | ('BaseMid', BYTE), 354 | ('Flags1', BYTE), 355 | ('Flags2', BYTE), 356 | ('BaseHi', BYTE), 357 | ] 358 | 359 | class _LDT_ENTRY_BITS_(Structure): 360 | _pack_ = 1 361 | _fields_ = [ 362 | ('BaseMid', DWORD, 8), 363 | ('Type', DWORD, 5), 364 | ('Dpl', DWORD, 2), 365 | ('Pres', DWORD, 1), 366 | ('LimitHi', DWORD, 4), 367 | ('Sys', DWORD, 1), 368 | ('Reserved_0', DWORD, 1), 369 | ('Default_Big', DWORD, 1), 370 | ('Granularity', DWORD, 1), 371 | ('BaseHi', DWORD, 8), 372 | ] 373 | 374 | class _LDT_ENTRY_HIGHWORD_(Union): 375 | _pack_ = 1 376 | _fields_ = [ 377 | ('Bytes', _LDT_ENTRY_BYTES_), 378 | ('Bits', _LDT_ENTRY_BITS_), 379 | ] 380 | 381 | class LDT_ENTRY(Structure): 382 | _pack_ = 1 383 | _fields_ = [ 384 | ('LimitLow', WORD), 385 | ('BaseLow', WORD), 386 | ('HighWord', _LDT_ENTRY_HIGHWORD_), 387 | ] 388 | 389 | PLDT_ENTRY = POINTER(LDT_ENTRY) 390 | LPLDT_ENTRY = PLDT_ENTRY 391 | 392 | ############################################################################### 393 | 394 | # BOOL WINAPI GetThreadSelectorEntry( 395 | # __in HANDLE hThread, 396 | # __in DWORD dwSelector, 397 | # __out LPLDT_ENTRY lpSelectorEntry 398 | # ); 399 | def GetThreadSelectorEntry(hThread, dwSelector): 400 | _GetThreadSelectorEntry = windll.kernel32.GetThreadSelectorEntry 401 | _GetThreadSelectorEntry.argtypes = [HANDLE, DWORD, LPLDT_ENTRY] 402 | _GetThreadSelectorEntry.restype = bool 403 | _GetThreadSelectorEntry.errcheck = RaiseIfZero 404 | 405 | ldt = LDT_ENTRY() 406 | _GetThreadSelectorEntry(hThread, dwSelector, byref(ldt)) 407 | return ldt 408 | 409 | # BOOL WINAPI GetThreadContext( 410 | # __in HANDLE hThread, 411 | # __inout LPCONTEXT lpContext 412 | # ); 413 | def GetThreadContext(hThread, ContextFlags = None, raw = False): 414 | _GetThreadContext = windll.kernel32.GetThreadContext 415 | _GetThreadContext.argtypes = [HANDLE, LPCONTEXT] 416 | _GetThreadContext.restype = bool 417 | _GetThreadContext.errcheck = RaiseIfZero 418 | 419 | if ContextFlags is None: 420 | ContextFlags = CONTEXT_ALL | CONTEXT_i386 421 | Context = CONTEXT() 422 | Context.ContextFlags = ContextFlags 423 | _GetThreadContext(hThread, byref(Context)) 424 | if raw: 425 | return Context 426 | return Context.to_dict() 427 | 428 | # BOOL WINAPI SetThreadContext( 429 | # __in HANDLE hThread, 430 | # __in const CONTEXT* lpContext 431 | # ); 432 | def SetThreadContext(hThread, lpContext): 433 | _SetThreadContext = windll.kernel32.SetThreadContext 434 | _SetThreadContext.argtypes = [HANDLE, LPCONTEXT] 435 | _SetThreadContext.restype = bool 436 | _SetThreadContext.errcheck = RaiseIfZero 437 | 438 | if isinstance(lpContext, dict): 439 | lpContext = CONTEXT.from_dict(lpContext) 440 | _SetThreadContext(hThread, byref(lpContext)) 441 | 442 | #============================================================================== 443 | # This calculates the list of exported symbols. 444 | _all = set(vars().keys()).difference(_all) 445 | __all__ = [_x for _x in _all if not _x.startswith('_')] 446 | __all__.sort() 447 | #============================================================================== 448 | --------------------------------------------------------------------------------