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