1#!~/.wine/drive_c/Python25/python.exe
2# -*- coding: utf-8 -*-
3
4# Copyright (c) 2009-2014, 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"""
32Miscellaneous utility classes and functions.
33
34@group Helpers:
35    PathOperations,
36    MemoryAddresses,
37    CustomAddressIterator,
38    DataAddressIterator,
39    ImageAddressIterator,
40    MappedAddressIterator,
41    ExecutableAddressIterator,
42    ReadableAddressIterator,
43    WriteableAddressIterator,
44    ExecutableAndWriteableAddressIterator,
45    DebugRegister,
46    Regenerator,
47    BannerHelpFormatter,
48    StaticClass,
49    classproperty
50"""
51
52__revision__ = "$Id$"
53
54__all__ = [
55
56    # Filename and pathname manipulation
57    'PathOperations',
58
59    # Memory address operations
60    'MemoryAddresses',
61    'CustomAddressIterator',
62    'DataAddressIterator',
63    'ImageAddressIterator',
64    'MappedAddressIterator',
65    'ExecutableAddressIterator',
66    'ReadableAddressIterator',
67    'WriteableAddressIterator',
68    'ExecutableAndWriteableAddressIterator',
69
70    # Debug registers manipulation
71    'DebugRegister',
72
73    # Miscellaneous
74    'Regenerator',
75    ]
76
77import sys
78import os
79import ctypes
80import optparse
81
82from winappdbg import win32
83from winappdbg import compat
84
85#==============================================================================
86
87class classproperty(property):
88    """
89    Class property method.
90
91    Only works for getting properties, if you set them
92    the symbol gets overwritten in the class namespace.
93
94    Inspired on: U{http://stackoverflow.com/a/7864317/426293}
95    """
96    def __init__(self, fget=None, fset=None, fdel=None, doc=""):
97        if fset is not None or fdel is not None:
98            raise NotImplementedError()
99        super(classproperty, self).__init__(fget=classmethod(fget), doc=doc)
100    def __get__(self, cls, owner):
101        return self.fget.__get__(None, owner)()
102
103class BannerHelpFormatter(optparse.IndentedHelpFormatter):
104    "Just a small tweak to optparse to be able to print a banner."
105    def __init__(self, banner, *argv, **argd):
106        self.banner = banner
107        optparse.IndentedHelpFormatter.__init__(self, *argv, **argd)
108    def format_usage(self, usage):
109        msg = optparse.IndentedHelpFormatter.format_usage(self, usage)
110        return '%s\n%s' % (self.banner, msg)
111
112# See Process.generate_memory_snapshot()
113class Regenerator(object):
114    """
115    Calls a generator and iterates it. When it's finished iterating, the
116    generator is called again. This allows you to iterate a generator more
117    than once (well, sort of).
118    """
119
120    def __init__(self, g_function, *v_args, **d_args):
121        """
122        @type  g_function: function
123        @param g_function: Function that when called returns a generator.
124
125        @type  v_args: tuple
126        @param v_args: Variable arguments to pass to the generator function.
127
128        @type  d_args: dict
129        @param d_args: Variable arguments to pass to the generator function.
130        """
131        self.__g_function = g_function
132        self.__v_args     = v_args
133        self.__d_args     = d_args
134        self.__g_object   = None
135
136    def __iter__(self):
137        'x.__iter__() <==> iter(x)'
138        return self
139
140    def next(self):
141        'x.next() -> the next value, or raise StopIteration'
142        if self.__g_object is None:
143            self.__g_object = self.__g_function( *self.__v_args, **self.__d_args )
144        try:
145            return self.__g_object.next()
146        except StopIteration:
147            self.__g_object = None
148            raise
149
150class StaticClass (object):
151    def __new__(cls, *argv, **argd):
152        "Don't try to instance this class, just use the static methods."
153        raise NotImplementedError(
154                "Cannot instance static class %s" % cls.__name__)
155
156#==============================================================================
157
158class PathOperations (StaticClass):
159    """
160    Static methods for filename and pathname manipulation.
161    """
162
163    @staticmethod
164    def path_is_relative(path):
165        """
166        @see: L{path_is_absolute}
167
168        @type  path: str
169        @param path: Absolute or relative path.
170
171        @rtype:  bool
172        @return: C{True} if the path is relative, C{False} if it's absolute.
173        """
174        return win32.PathIsRelative(path)
175
176    @staticmethod
177    def path_is_absolute(path):
178        """
179        @see: L{path_is_relative}
180
181        @type  path: str
182        @param path: Absolute or relative path.
183
184        @rtype:  bool
185        @return: C{True} if the path is absolute, C{False} if it's relative.
186        """
187        return not win32.PathIsRelative(path)
188
189    @staticmethod
190    def make_relative(path, current = None):
191        """
192        @type  path: str
193        @param path: Absolute path.
194
195        @type  current: str
196        @param current: (Optional) Path to the current directory.
197
198        @rtype:  str
199        @return: Relative path.
200
201        @raise WindowsError: It's impossible to make the path relative.
202            This happens when the path and the current path are not on the
203            same disk drive or network share.
204        """
205        return win32.PathRelativePathTo(pszFrom = current, pszTo = path)
206
207    @staticmethod
208    def make_absolute(path):
209        """
210        @type  path: str
211        @param path: Relative path.
212
213        @rtype:  str
214        @return: Absolute path.
215        """
216        return win32.GetFullPathName(path)[0]
217
218    @staticmethod
219    def split_extension(pathname):
220        """
221        @type  pathname: str
222        @param pathname: Absolute path.
223
224        @rtype:  tuple( str, str )
225        @return:
226            Tuple containing the file and extension components of the filename.
227        """
228        filepart = win32.PathRemoveExtension(pathname)
229        extpart  = win32.PathFindExtension(pathname)
230        return (filepart, extpart)
231
232    @staticmethod
233    def split_filename(pathname):
234        """
235        @type  pathname: str
236        @param pathname: Absolute path.
237
238        @rtype:  tuple( str, str )
239        @return: Tuple containing the path to the file and the base filename.
240        """
241        filepart = win32.PathFindFileName(pathname)
242        pathpart = win32.PathRemoveFileSpec(pathname)
243        return (pathpart, filepart)
244
245    @staticmethod
246    def split_path(path):
247        """
248        @see: L{join_path}
249
250        @type  path: str
251        @param path: Absolute or relative path.
252
253        @rtype:  list( str... )
254        @return: List of path components.
255        """
256        components = list()
257        while path:
258            next = win32.PathFindNextComponent(path)
259            if next:
260                prev = path[ : -len(next) ]
261                components.append(prev)
262            path = next
263        return components
264
265    @staticmethod
266    def join_path(*components):
267        """
268        @see: L{split_path}
269
270        @type  components: tuple( str... )
271        @param components: Path components.
272
273        @rtype:  str
274        @return: Absolute or relative path.
275        """
276        if components:
277            path = components[0]
278            for next in components[1:]:
279                path = win32.PathAppend(path, next)
280        else:
281            path = ""
282        return path
283
284    @staticmethod
285    def native_to_win32_pathname(name):
286        """
287        @type  name: str
288        @param name: Native (NT) absolute pathname.
289
290        @rtype:  str
291        @return: Win32 absolute pathname.
292        """
293        # XXX TODO
294        # There are probably some native paths that
295        # won't be converted by this naive approach.
296        if name.startswith(compat.b("\\")):
297            if name.startswith(compat.b("\\??\\")):
298                name = name[4:]
299            elif name.startswith(compat.b("\\SystemRoot\\")):
300                system_root_path = os.environ['SYSTEMROOT']
301                if system_root_path.endswith('\\'):
302                    system_root_path = system_root_path[:-1]
303                name = system_root_path + name[11:]
304            else:
305                for drive_number in compat.xrange(ord('A'), ord('Z') + 1):
306                    drive_letter = '%c:' % drive_number
307                    try:
308                        device_native_path = win32.QueryDosDevice(drive_letter)
309                    except WindowsError:
310                        e = sys.exc_info()[1]
311                        if e.winerror in (win32.ERROR_FILE_NOT_FOUND, \
312                                                 win32.ERROR_PATH_NOT_FOUND):
313                            continue
314                        raise
315                    if not device_native_path.endswith(compat.b('\\')):
316                        device_native_path += compat.b('\\')
317                    if name.startswith(device_native_path):
318                        name = drive_letter + compat.b('\\') + \
319                                              name[ len(device_native_path) : ]
320                        break
321        return name
322
323    @staticmethod
324    def pathname_to_filename(pathname):
325        """
326        Equivalent to: C{PathOperations.split_filename(pathname)[0]}
327
328        @note: This function is preserved for backwards compatibility with
329            WinAppDbg 1.4 and earlier. It may be removed in future versions.
330
331        @type  pathname: str
332        @param pathname: Absolute path to a file.
333
334        @rtype:  str
335        @return: Filename component of the path.
336        """
337        return win32.PathFindFileName(pathname)
338
339#==============================================================================
340
341class MemoryAddresses (StaticClass):
342    """
343    Class to manipulate memory addresses.
344
345    @type pageSize: int
346    @cvar pageSize: Page size in bytes. Defaults to 0x1000 but it's
347        automatically updated on runtime when importing the module.
348    """
349
350    @classproperty
351    def pageSize(cls):
352        """
353        Try to get the pageSize value on runtime.
354        """
355        try:
356            try:
357                pageSize = win32.GetSystemInfo().dwPageSize
358            except WindowsError:
359                pageSize = 0x1000
360        except NameError:
361            pageSize = 0x1000
362        cls.pageSize = pageSize     # now this function won't be called again
363        return pageSize
364
365    @classmethod
366    def align_address_to_page_start(cls, address):
367        """
368        Align the given address to the start of the page it occupies.
369
370        @type  address: int
371        @param address: Memory address.
372
373        @rtype:  int
374        @return: Aligned memory address.
375        """
376        return address - ( address % cls.pageSize )
377
378    @classmethod
379    def align_address_to_page_end(cls, address):
380        """
381        Align the given address to the end of the page it occupies.
382        That is, to point to the start of the next page.
383
384        @type  address: int
385        @param address: Memory address.
386
387        @rtype:  int
388        @return: Aligned memory address.
389        """
390        return address + cls.pageSize - ( address % cls.pageSize )
391
392    @classmethod
393    def align_address_range(cls, begin, end):
394        """
395        Align the given address range to the start and end of the page(s) it occupies.
396
397        @type  begin: int
398        @param begin: Memory address of the beginning of the buffer.
399            Use C{None} for the first legal address in the address space.
400
401        @type  end: int
402        @param end: Memory address of the end of the buffer.
403            Use C{None} for the last legal address in the address space.
404
405        @rtype:  tuple( int, int )
406        @return: Aligned memory addresses.
407        """
408        if begin is None:
409            begin = 0
410        if end is None:
411            end = win32.LPVOID(-1).value  # XXX HACK
412        if end < begin:
413            begin, end = end, begin
414        begin = cls.align_address_to_page_start(begin)
415        if end != cls.align_address_to_page_start(end):
416            end = cls.align_address_to_page_end(end)
417        return (begin, end)
418
419    @classmethod
420    def get_buffer_size_in_pages(cls, address, size):
421        """
422        Get the number of pages in use by the given buffer.
423
424        @type  address: int
425        @param address: Aligned memory address.
426
427        @type  size: int
428        @param size: Buffer size.
429
430        @rtype:  int
431        @return: Buffer size in number of pages.
432        """
433        if size < 0:
434            size    = -size
435            address = address - size
436        begin, end = cls.align_address_range(address, address + size)
437        # XXX FIXME
438        # I think this rounding fails at least for address 0xFFFFFFFF size 1
439        return int(float(end - begin) / float(cls.pageSize))
440
441    @staticmethod
442    def do_ranges_intersect(begin, end, old_begin, old_end):
443        """
444        Determine if the two given memory address ranges intersect.
445
446        @type  begin: int
447        @param begin: Start address of the first range.
448
449        @type  end: int
450        @param end: End address of the first range.
451
452        @type  old_begin: int
453        @param old_begin: Start address of the second range.
454
455        @type  old_end: int
456        @param old_end: End address of the second range.
457
458        @rtype:  bool
459        @return: C{True} if the two ranges intersect, C{False} otherwise.
460        """
461        return  (old_begin <= begin < old_end) or \
462                (old_begin < end <= old_end)   or \
463                (begin <= old_begin < end)     or \
464                (begin < old_end <= end)
465
466#==============================================================================
467
468def CustomAddressIterator(memory_map, condition):
469    """
470    Generator function that iterates through a memory map, filtering memory
471    region blocks by any given condition.
472
473    @type  memory_map: list( L{win32.MemoryBasicInformation} )
474    @param memory_map: List of memory region information objects.
475        Returned by L{Process.get_memory_map}.
476
477    @type  condition: function
478    @param condition: Callback function that returns C{True} if the memory
479        block should be returned, or C{False} if it should be filtered.
480
481    @rtype:  generator of L{win32.MemoryBasicInformation}
482    @return: Generator object to iterate memory blocks.
483    """
484    for mbi in memory_map:
485        if condition(mbi):
486            address  = mbi.BaseAddress
487            max_addr = address + mbi.RegionSize
488            while address < max_addr:
489                yield address
490                address = address + 1
491
492def DataAddressIterator(memory_map):
493    """
494    Generator function that iterates through a memory map, returning only those
495    memory blocks that contain data.
496
497    @type  memory_map: list( L{win32.MemoryBasicInformation} )
498    @param memory_map: List of memory region information objects.
499        Returned by L{Process.get_memory_map}.
500
501    @rtype:  generator of L{win32.MemoryBasicInformation}
502    @return: Generator object to iterate memory blocks.
503    """
504    return CustomAddressIterator(memory_map,
505                                      win32.MemoryBasicInformation.has_content)
506
507def ImageAddressIterator(memory_map):
508    """
509    Generator function that iterates through a memory map, returning only those
510    memory blocks that belong to executable images.
511
512    @type  memory_map: list( L{win32.MemoryBasicInformation} )
513    @param memory_map: List of memory region information objects.
514        Returned by L{Process.get_memory_map}.
515
516    @rtype:  generator of L{win32.MemoryBasicInformation}
517    @return: Generator object to iterate memory blocks.
518    """
519    return CustomAddressIterator(memory_map,
520                                         win32.MemoryBasicInformation.is_image)
521
522def MappedAddressIterator(memory_map):
523    """
524    Generator function that iterates through a memory map, returning only those
525    memory blocks that belong to memory mapped files.
526
527    @type  memory_map: list( L{win32.MemoryBasicInformation} )
528    @param memory_map: List of memory region information objects.
529        Returned by L{Process.get_memory_map}.
530
531    @rtype:  generator of L{win32.MemoryBasicInformation}
532    @return: Generator object to iterate memory blocks.
533    """
534    return CustomAddressIterator(memory_map,
535                                        win32.MemoryBasicInformation.is_mapped)
536
537def ReadableAddressIterator(memory_map):
538    """
539    Generator function that iterates through a memory map, returning only those
540    memory blocks that are readable.
541
542    @type  memory_map: list( L{win32.MemoryBasicInformation} )
543    @param memory_map: List of memory region information objects.
544        Returned by L{Process.get_memory_map}.
545
546    @rtype:  generator of L{win32.MemoryBasicInformation}
547    @return: Generator object to iterate memory blocks.
548    """
549    return CustomAddressIterator(memory_map,
550                                      win32.MemoryBasicInformation.is_readable)
551
552def WriteableAddressIterator(memory_map):
553    """
554    Generator function that iterates through a memory map, returning only those
555    memory blocks that are writeable.
556
557    @note: Writeable memory is always readable too.
558
559    @type  memory_map: list( L{win32.MemoryBasicInformation} )
560    @param memory_map: List of memory region information objects.
561        Returned by L{Process.get_memory_map}.
562
563    @rtype:  generator of L{win32.MemoryBasicInformation}
564    @return: Generator object to iterate memory blocks.
565    """
566    return CustomAddressIterator(memory_map,
567                                     win32.MemoryBasicInformation.is_writeable)
568
569def ExecutableAddressIterator(memory_map):
570    """
571    Generator function that iterates through a memory map, returning only those
572    memory blocks that are executable.
573
574    @note: Executable memory is always readable too.
575
576    @type  memory_map: list( L{win32.MemoryBasicInformation} )
577    @param memory_map: List of memory region information objects.
578        Returned by L{Process.get_memory_map}.
579
580    @rtype:  generator of L{win32.MemoryBasicInformation}
581    @return: Generator object to iterate memory blocks.
582    """
583    return CustomAddressIterator(memory_map,
584                                    win32.MemoryBasicInformation.is_executable)
585
586def ExecutableAndWriteableAddressIterator(memory_map):
587    """
588    Generator function that iterates through a memory map, returning only those
589    memory blocks that are executable and writeable.
590
591    @note: The presence of such pages make memory corruption vulnerabilities
592        much easier to exploit.
593
594    @type  memory_map: list( L{win32.MemoryBasicInformation} )
595    @param memory_map: List of memory region information objects.
596        Returned by L{Process.get_memory_map}.
597
598    @rtype:  generator of L{win32.MemoryBasicInformation}
599    @return: Generator object to iterate memory blocks.
600    """
601    return CustomAddressIterator(memory_map,
602                      win32.MemoryBasicInformation.is_executable_and_writeable)
603
604#==============================================================================
605try:
606    _registerMask = win32.SIZE_T(-1).value
607except TypeError:
608    if win32.SIZEOF(win32.SIZE_T) == 4:
609        _registerMask = 0xFFFFFFFF
610    elif win32.SIZEOF(win32.SIZE_T) == 8:
611        _registerMask = 0xFFFFFFFFFFFFFFFF
612    else:
613        raise
614
615class DebugRegister (StaticClass):
616    """
617    Class to manipulate debug registers.
618    Used by L{HardwareBreakpoint}.
619
620    @group Trigger flags used by HardwareBreakpoint:
621        BREAK_ON_EXECUTION, BREAK_ON_WRITE, BREAK_ON_ACCESS, BREAK_ON_IO_ACCESS
622    @group Size flags used by HardwareBreakpoint:
623        WATCH_BYTE, WATCH_WORD, WATCH_DWORD, WATCH_QWORD
624    @group Bitwise masks for Dr7:
625        enableMask, disableMask, triggerMask, watchMask, clearMask,
626        generalDetectMask
627    @group Bitwise masks for Dr6:
628        hitMask, hitMaskAll, debugAccessMask, singleStepMask, taskSwitchMask,
629        clearDr6Mask, clearHitMask
630    @group Debug control MSR definitions:
631        DebugCtlMSR, LastBranchRecord, BranchTrapFlag, PinControl,
632        LastBranchToIP, LastBranchFromIP,
633        LastExceptionToIP, LastExceptionFromIP
634
635    @type BREAK_ON_EXECUTION: int
636    @cvar BREAK_ON_EXECUTION: Break on execution.
637
638    @type BREAK_ON_WRITE: int
639    @cvar BREAK_ON_WRITE: Break on write.
640
641    @type BREAK_ON_ACCESS: int
642    @cvar BREAK_ON_ACCESS: Break on read or write.
643
644    @type BREAK_ON_IO_ACCESS: int
645    @cvar BREAK_ON_IO_ACCESS: Break on I/O port access.
646        Not supported by any hardware.
647
648    @type WATCH_BYTE: int
649    @cvar WATCH_BYTE: Watch a byte.
650
651    @type WATCH_WORD: int
652    @cvar WATCH_WORD: Watch a word.
653
654    @type WATCH_DWORD: int
655    @cvar WATCH_DWORD: Watch a double word.
656
657    @type WATCH_QWORD: int
658    @cvar WATCH_QWORD: Watch one quad word.
659
660    @type enableMask: 4-tuple of integers
661    @cvar enableMask:
662        Enable bit on C{Dr7} for each slot.
663        Works as a bitwise-OR mask.
664
665    @type disableMask: 4-tuple of integers
666    @cvar disableMask:
667        Mask of the enable bit on C{Dr7} for each slot.
668        Works as a bitwise-AND mask.
669
670    @type triggerMask: 4-tuple of 2-tuples of integers
671    @cvar triggerMask:
672        Trigger bits on C{Dr7} for each trigger flag value.
673        Each 2-tuple has the bitwise-OR mask and the bitwise-AND mask.
674
675    @type watchMask: 4-tuple of 2-tuples of integers
676    @cvar watchMask:
677        Watch bits on C{Dr7} for each watch flag value.
678        Each 2-tuple has the bitwise-OR mask and the bitwise-AND mask.
679
680    @type clearMask: 4-tuple of integers
681    @cvar clearMask:
682        Mask of all important bits on C{Dr7} for each slot.
683        Works as a bitwise-AND mask.
684
685    @type generalDetectMask: integer
686    @cvar generalDetectMask:
687        General detect mode bit. It enables the processor to notify the
688        debugger when the debugee is trying to access one of the debug
689        registers.
690
691    @type hitMask: 4-tuple of integers
692    @cvar hitMask:
693        Hit bit on C{Dr6} for each slot.
694        Works as a bitwise-AND mask.
695
696    @type hitMaskAll: integer
697    @cvar hitMaskAll:
698        Bitmask for all hit bits in C{Dr6}. Useful to know if at least one
699        hardware breakpoint was hit, or to clear the hit bits only.
700
701    @type clearHitMask: integer
702    @cvar clearHitMask:
703        Bitmask to clear all the hit bits in C{Dr6}.
704
705    @type debugAccessMask: integer
706    @cvar debugAccessMask:
707        The debugee tried to access a debug register. Needs bit
708        L{generalDetectMask} enabled in C{Dr7}.
709
710    @type singleStepMask: integer
711    @cvar singleStepMask:
712        A single step exception was raised. Needs the trap flag enabled.
713
714    @type taskSwitchMask: integer
715    @cvar taskSwitchMask:
716        A task switch has occurred. Needs the TSS T-bit set to 1.
717
718    @type clearDr6Mask: integer
719    @cvar clearDr6Mask:
720        Bitmask to clear all meaningful bits in C{Dr6}.
721    """
722
723    BREAK_ON_EXECUTION  = 0
724    BREAK_ON_WRITE      = 1
725    BREAK_ON_ACCESS     = 3
726    BREAK_ON_IO_ACCESS  = 2
727
728    WATCH_BYTE  = 0
729    WATCH_WORD  = 1
730    WATCH_DWORD = 3
731    WATCH_QWORD = 2
732
733    registerMask = _registerMask
734
735#------------------------------------------------------------------------------
736
737    ###########################################################################
738    # http://en.wikipedia.org/wiki/Debug_register
739    #
740    # DR7 - Debug control
741    #
742    # The low-order eight bits of DR7 (0,2,4,6 and 1,3,5,7) selectively enable
743    # the four address breakpoint conditions. There are two levels of enabling:
744    # the local (0,2,4,6) and global (1,3,5,7) levels. The local enable bits
745    # are automatically reset by the processor at every task switch to avoid
746    # unwanted breakpoint conditions in the new task. The global enable bits
747    # are not reset by a task switch; therefore, they can be used for
748    # conditions that are global to all tasks.
749    #
750    # Bits 16-17 (DR0), 20-21 (DR1), 24-25 (DR2), 28-29 (DR3), define when
751    # breakpoints trigger. Each breakpoint has a two-bit entry that specifies
752    # whether they break on execution (00b), data write (01b), data read or
753    # write (11b). 10b is defined to mean break on IO read or write but no
754    # hardware supports it. Bits 18-19 (DR0), 22-23 (DR1), 26-27 (DR2), 30-31
755    # (DR3), define how large area of memory is watched by breakpoints. Again
756    # each breakpoint has a two-bit entry that specifies whether they watch
757    # one (00b), two (01b), eight (10b) or four (11b) bytes.
758    ###########################################################################
759
760    # Dr7 |= enableMask[register]
761    enableMask = (
762        1 << 0,     # Dr0 (bit 0)
763        1 << 2,     # Dr1 (bit 2)
764        1 << 4,     # Dr2 (bit 4)
765        1 << 6,     # Dr3 (bit 6)
766    )
767
768    # Dr7 &= disableMask[register]
769    disableMask = tuple( [_registerMask ^ x for x in enableMask] ) # The registerMask from the class is not there in py3
770    try:
771        del x # It's not there in py3
772    except:
773        pass
774
775    # orMask, andMask = triggerMask[register][trigger]
776    # Dr7 = (Dr7 & andMask) | orMask    # to set
777    # Dr7 = Dr7 & andMask               # to remove
778    triggerMask = (
779        # Dr0 (bits 16-17)
780        (
781            ((0 << 16), (3 << 16) ^ registerMask),  # execute
782            ((1 << 16), (3 << 16) ^ registerMask),  # write
783            ((2 << 16), (3 << 16) ^ registerMask),  # io read
784            ((3 << 16), (3 << 16) ^ registerMask),  # access
785        ),
786        # Dr1 (bits 20-21)
787        (
788            ((0 << 20), (3 << 20) ^ registerMask),  # execute
789            ((1 << 20), (3 << 20) ^ registerMask),  # write
790            ((2 << 20), (3 << 20) ^ registerMask),  # io read
791            ((3 << 20), (3 << 20) ^ registerMask),  # access
792        ),
793        # Dr2 (bits 24-25)
794        (
795            ((0 << 24), (3 << 24) ^ registerMask),  # execute
796            ((1 << 24), (3 << 24) ^ registerMask),  # write
797            ((2 << 24), (3 << 24) ^ registerMask),  # io read
798            ((3 << 24), (3 << 24) ^ registerMask),  # access
799        ),
800        # Dr3 (bits 28-29)
801        (
802            ((0 << 28), (3 << 28) ^ registerMask),  # execute
803            ((1 << 28), (3 << 28) ^ registerMask),  # write
804            ((2 << 28), (3 << 28) ^ registerMask),  # io read
805            ((3 << 28), (3 << 28) ^ registerMask),  # access
806        ),
807    )
808
809    # orMask, andMask = watchMask[register][watch]
810    # Dr7 = (Dr7 & andMask) | orMask    # to set
811    # Dr7 = Dr7 & andMask               # to remove
812    watchMask = (
813        # Dr0 (bits 18-19)
814        (
815            ((0 << 18), (3 << 18) ^ registerMask),  # byte
816            ((1 << 18), (3 << 18) ^ registerMask),  # word
817            ((2 << 18), (3 << 18) ^ registerMask),  # qword
818            ((3 << 18), (3 << 18) ^ registerMask),  # dword
819        ),
820        # Dr1 (bits 22-23)
821        (
822            ((0 << 23), (3 << 23) ^ registerMask),  # byte
823            ((1 << 23), (3 << 23) ^ registerMask),  # word
824            ((2 << 23), (3 << 23) ^ registerMask),  # qword
825            ((3 << 23), (3 << 23) ^ registerMask),  # dword
826        ),
827        # Dr2 (bits 26-27)
828        (
829            ((0 << 26), (3 << 26) ^ registerMask),  # byte
830            ((1 << 26), (3 << 26) ^ registerMask),  # word
831            ((2 << 26), (3 << 26) ^ registerMask),  # qword
832            ((3 << 26), (3 << 26) ^ registerMask),  # dword
833        ),
834        # Dr3 (bits 30-31)
835        (
836            ((0 << 30), (3 << 31) ^ registerMask),  # byte
837            ((1 << 30), (3 << 31) ^ registerMask),  # word
838            ((2 << 30), (3 << 31) ^ registerMask),  # qword
839            ((3 << 30), (3 << 31) ^ registerMask),  # dword
840        ),
841    )
842
843    # Dr7 = Dr7 & clearMask[register]
844    clearMask = (
845        registerMask ^ ( (1 << 0) + (3 << 16) + (3 << 18) ),    # Dr0
846        registerMask ^ ( (1 << 2) + (3 << 20) + (3 << 22) ),    # Dr1
847        registerMask ^ ( (1 << 4) + (3 << 24) + (3 << 26) ),    # Dr2
848        registerMask ^ ( (1 << 6) + (3 << 28) + (3 << 30) ),    # Dr3
849    )
850
851    # Dr7 = Dr7 | generalDetectMask
852    generalDetectMask = (1 << 13)
853
854    ###########################################################################
855    # http://en.wikipedia.org/wiki/Debug_register
856    #
857    # DR6 - Debug status
858    #
859    # The debug status register permits the debugger to determine which debug
860    # conditions have occurred. When the processor detects an enabled debug
861    # exception, it sets the low-order bits of this register (0,1,2,3) before
862    # entering the debug exception handler.
863    #
864    # Note that the bits of DR6 are never cleared by the processor. To avoid
865    # any confusion in identifying the next debug exception, the debug handler
866    # should move zeros to DR6 immediately before returning.
867    ###########################################################################
868
869    # bool(Dr6 & hitMask[register])
870    hitMask = (
871        (1 << 0),   # Dr0
872        (1 << 1),   # Dr1
873        (1 << 2),   # Dr2
874        (1 << 3),   # Dr3
875    )
876
877    # bool(Dr6 & anyHitMask)
878    hitMaskAll = hitMask[0] | hitMask[1] | hitMask[2] | hitMask[3]
879
880    # Dr6 = Dr6 & clearHitMask
881    clearHitMask = registerMask ^ hitMaskAll
882
883    # bool(Dr6 & debugAccessMask)
884    debugAccessMask = (1 << 13)
885
886    # bool(Dr6 & singleStepMask)
887    singleStepMask  = (1 << 14)
888
889    # bool(Dr6 & taskSwitchMask)
890    taskSwitchMask  = (1 << 15)
891
892    # Dr6 = Dr6 & clearDr6Mask
893    clearDr6Mask = registerMask ^ (hitMaskAll | \
894                            debugAccessMask | singleStepMask | taskSwitchMask)
895
896#------------------------------------------------------------------------------
897
898###############################################################################
899#
900#    (from the AMD64 manuals)
901#
902#    The fields within the DebugCtlMSR register are:
903#
904#    Last-Branch Record (LBR) - Bit 0, read/write. Software sets this bit to 1
905#    to cause the processor to record the source and target addresses of the
906#    last control transfer taken before a debug exception occurs. The recorded
907#    control transfers include branch instructions, interrupts, and exceptions.
908#
909#    Branch Single Step (BTF) - Bit 1, read/write. Software uses this bit to
910#    change the behavior of the rFLAGS.TF bit. When this bit is cleared to 0,
911#    the rFLAGS.TF bit controls instruction single stepping, (normal behavior).
912#    When this bit is set to 1, the rFLAGS.TF bit controls single stepping on
913#    control transfers. The single-stepped control transfers include branch
914#    instructions, interrupts, and exceptions. Control-transfer single stepping
915#    requires both BTF=1 and rFLAGS.TF=1.
916#
917#    Performance-Monitoring/Breakpoint Pin-Control (PBi) - Bits 5-2, read/write.
918#    Software uses these bits to control the type of information reported by
919#    the four external performance-monitoring/breakpoint pins on the processor.
920#    When a PBi bit is cleared to 0, the corresponding external pin (BPi)
921#    reports performance-monitor information. When a PBi bit is set to 1, the
922#    corresponding external pin (BPi) reports breakpoint information.
923#
924#    All remaining bits in the DebugCtlMSR register are reserved.
925#
926#    Software can enable control-transfer single stepping by setting
927#    DebugCtlMSR.BTF to 1 and rFLAGS.TF to 1. The processor automatically
928#    disables control-transfer single stepping when a debug exception (#DB)
929#    occurs by clearing DebugCtlMSR.BTF to 0. rFLAGS.TF is also cleared when a
930#    #DB exception occurs. Before exiting the debug-exception handler, software
931#    must set both DebugCtlMSR.BTF and rFLAGS.TF to 1 to restart single
932#    stepping.
933#
934###############################################################################
935
936    DebugCtlMSR      = 0x1D9
937    LastBranchRecord = (1 << 0)
938    BranchTrapFlag   = (1 << 1)
939    PinControl       = (
940                        (1 << 2),   # PB1
941                        (1 << 3),   # PB2
942                        (1 << 4),   # PB3
943                        (1 << 5),   # PB4
944                       )
945
946###############################################################################
947#
948#    (from the AMD64 manuals)
949#
950#    Control-transfer recording MSRs: LastBranchToIP, LastBranchFromIP,
951#    LastExceptionToIP, and LastExceptionFromIP. These registers are loaded
952#    automatically by the processor when the DebugCtlMSR.LBR bit is set to 1.
953#    These MSRs are read-only.
954#
955#    The processor automatically disables control-transfer recording when a
956#    debug exception (#DB) occurs by clearing DebugCtlMSR.LBR to 0. The
957#    contents of the control-transfer recording MSRs are not altered by the
958#    processor when the #DB occurs. Before exiting the debug-exception handler,
959#    software can set DebugCtlMSR.LBR to 1 to re-enable the recording mechanism.
960#
961###############################################################################
962
963    LastBranchToIP      = 0x1DC
964    LastBranchFromIP    = 0x1DB
965    LastExceptionToIP   = 0x1DE
966    LastExceptionFromIP = 0x1DD
967
968#------------------------------------------------------------------------------
969
970    @classmethod
971    def clear_bp(cls, ctx, register):
972        """
973        Clears a hardware breakpoint.
974
975        @see: find_slot, set_bp
976
977        @type  ctx: dict( str S{->} int )
978        @param ctx: Thread context dictionary.
979
980        @type  register: int
981        @param register: Slot (debug register) for hardware breakpoint.
982        """
983        ctx['Dr7'] &= cls.clearMask[register]
984        ctx['Dr%d' % register] = 0
985
986    @classmethod
987    def set_bp(cls, ctx, register, address, trigger, watch):
988        """
989        Sets a hardware breakpoint.
990
991        @see: clear_bp, find_slot
992
993        @type  ctx: dict( str S{->} int )
994        @param ctx: Thread context dictionary.
995
996        @type  register: int
997        @param register: Slot (debug register).
998
999        @type  address: int
1000        @param address: Memory address.
1001
1002        @type  trigger: int
1003        @param trigger: Trigger flag. See L{HardwareBreakpoint.validTriggers}.
1004
1005        @type  watch: int
1006        @param watch: Watch flag. See L{HardwareBreakpoint.validWatchSizes}.
1007        """
1008        Dr7 = ctx['Dr7']
1009        Dr7 |= cls.enableMask[register]
1010        orMask, andMask = cls.triggerMask[register][trigger]
1011        Dr7 &= andMask
1012        Dr7 |= orMask
1013        orMask, andMask = cls.watchMask[register][watch]
1014        Dr7 &= andMask
1015        Dr7 |= orMask
1016        ctx['Dr7'] = Dr7
1017        ctx['Dr%d' % register] = address
1018
1019    @classmethod
1020    def find_slot(cls, ctx):
1021        """
1022        Finds an empty slot to set a hardware breakpoint.
1023
1024        @see: clear_bp, set_bp
1025
1026        @type  ctx: dict( str S{->} int )
1027        @param ctx: Thread context dictionary.
1028
1029        @rtype:  int
1030        @return: Slot (debug register) for hardware breakpoint.
1031        """
1032        Dr7  = ctx['Dr7']
1033        slot = 0
1034        for m in cls.enableMask:
1035            if (Dr7 & m) == 0:
1036                return slot
1037            slot += 1
1038        return None
1039