Package winappdbg :: Module util
[hide private]
[frames] | no frames]

Source Code for Module winappdbg.util

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