| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # | 2 # |
| 3 # Copyright 2012 the V8 project authors. All rights reserved. | 3 # Copyright 2012 the V8 project authors. All rights reserved. |
| 4 # Redistribution and use in source and binary forms, with or without | 4 # Redistribution and use in source and binary forms, with or without |
| 5 # modification, are permitted provided that the following conditions are | 5 # modification, are permitted provided that the following conditions are |
| 6 # met: | 6 # met: |
| 7 # | 7 # |
| 8 # * Redistributions of source code must retain the above copyright | 8 # * Redistributions of source code must retain the above copyright |
| 9 # notice, this list of conditions and the following disclaimer. | 9 # notice, this list of conditions and the following disclaimer. |
| 10 # * Redistributions in binary form must reproduce the above | 10 # * Redistributions in binary form must reproduce the above |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 128 | 128 |
| 129 if is_executable is not False: | 129 if is_executable is not False: |
| 130 lines = reader.GetDisasmLines(start, size) | 130 lines = reader.GetDisasmLines(start, size) |
| 131 for line in lines: | 131 for line in lines: |
| 132 print FormatDisasmLine(start, heap, line) | 132 print FormatDisasmLine(start, heap, line) |
| 133 print | 133 print |
| 134 | 134 |
| 135 if is_ascii is not False: | 135 if is_ascii is not False: |
| 136 # Output in the same format as the Unix hd command | 136 # Output in the same format as the Unix hd command |
| 137 addr = start | 137 addr = start |
| 138 for slot in xrange(location, location + size, 16): | 138 for i in xrange(0, size, 16): |
| 139 slot = i + location |
| 139 hex_line = "" | 140 hex_line = "" |
| 140 asc_line = "" | 141 asc_line = "" |
| 141 for i in xrange(0, 16): | 142 for i in xrange(16): |
| 142 if slot + i < location + size: | 143 if slot + i < location + size: |
| 143 byte = ctypes.c_uint8.from_buffer(reader.minidump, slot + i).value | 144 byte = ctypes.c_uint8.from_buffer(reader.minidump, slot + i).value |
| 144 if byte >= 0x20 and byte < 0x7f: | 145 if byte >= 0x20 and byte < 0x7f: |
| 145 asc_line += chr(byte) | 146 asc_line += chr(byte) |
| 146 else: | 147 else: |
| 147 asc_line += "." | 148 asc_line += "." |
| 148 hex_line += " %02x" % (byte) | 149 hex_line += " %02x" % (byte) |
| 149 else: | 150 else: |
| 150 hex_line += " " | 151 hex_line += " " |
| 151 if i == 7: | 152 if i == 7: |
| 152 hex_line += " " | 153 hex_line += " " |
| 153 print "%s %s |%s|" % (reader.FormatIntPtr(addr), | 154 print "%s %s |%s|" % (reader.FormatIntPtr(addr), |
| 154 hex_line, | 155 hex_line, |
| 155 asc_line) | 156 asc_line) |
| 156 addr += 16 | 157 addr += 16 |
| 157 | 158 |
| 158 if is_executable is not True and is_ascii is not True: | 159 if is_executable is not True and is_ascii is not True: |
| 159 print "%s - %s" % (reader.FormatIntPtr(start), | 160 print "%s - %s" % (reader.FormatIntPtr(start), |
| 160 reader.FormatIntPtr(start + size)) | 161 reader.FormatIntPtr(start + size)) |
| 161 for slot in xrange(start, | 162 print start + size + 1; |
| 162 start + size, | 163 for i in xrange(0, size, reader.PointerSize()): |
| 163 reader.PointerSize()): | 164 slot = start + i |
| 164 maybe_address = reader.ReadUIntPtr(slot) | 165 maybe_address = reader.ReadUIntPtr(slot) |
| 165 heap_object = heap.FindObject(maybe_address) | 166 heap_object = heap.FindObject(maybe_address) |
| 166 print "%s: %s" % (reader.FormatIntPtr(slot), | 167 print "%s: %s" % (reader.FormatIntPtr(slot), |
| 167 reader.FormatIntPtr(maybe_address)) | 168 reader.FormatIntPtr(maybe_address)) |
| 168 if heap_object: | 169 if heap_object: |
| 169 heap_object.Print(Printer()) | 170 heap_object.Print(Printer()) |
| 170 print | 171 print |
| 171 | 172 |
| 172 reader.ForEachMemoryRegion(dump_region) | 173 reader.ForEachMemoryRegion(dump_region) |
| 173 | 174 |
| (...skipping 479 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 653 if self.arch == MD_CPU_ARCHITECTURE_AMD64: | 654 if self.arch == MD_CPU_ARCHITECTURE_AMD64: |
| 654 return ctypes.c_uint64.from_buffer(self.minidump, location).value | 655 return ctypes.c_uint64.from_buffer(self.minidump, location).value |
| 655 elif self.arch == MD_CPU_ARCHITECTURE_ARM: | 656 elif self.arch == MD_CPU_ARCHITECTURE_ARM: |
| 656 return ctypes.c_uint32.from_buffer(self.minidump, location).value | 657 return ctypes.c_uint32.from_buffer(self.minidump, location).value |
| 657 elif self.arch == MD_CPU_ARCHITECTURE_X86: | 658 elif self.arch == MD_CPU_ARCHITECTURE_X86: |
| 658 return ctypes.c_uint32.from_buffer(self.minidump, location).value | 659 return ctypes.c_uint32.from_buffer(self.minidump, location).value |
| 659 | 660 |
| 660 def IsProbableASCIIRegion(self, location, length): | 661 def IsProbableASCIIRegion(self, location, length): |
| 661 ascii_bytes = 0 | 662 ascii_bytes = 0 |
| 662 non_ascii_bytes = 0 | 663 non_ascii_bytes = 0 |
| 663 for loc in xrange(location, location + length): | 664 for i in xrange(length): |
| 665 loc = location + i |
| 664 byte = ctypes.c_uint8.from_buffer(self.minidump, loc).value | 666 byte = ctypes.c_uint8.from_buffer(self.minidump, loc).value |
| 665 if byte >= 0x7f: | 667 if byte >= 0x7f: |
| 666 non_ascii_bytes += 1 | 668 non_ascii_bytes += 1 |
| 667 if byte < 0x20 and byte != 0: | 669 if byte < 0x20 and byte != 0: |
| 668 non_ascii_bytes += 1 | 670 non_ascii_bytes += 1 |
| 669 if byte < 0x7f and byte >= 0x20: | 671 if byte < 0x7f and byte >= 0x20: |
| 670 ascii_bytes += 1 | 672 ascii_bytes += 1 |
| 671 if byte == 0xa: # newline | 673 if byte == 0xa: # newline |
| 672 ascii_bytes += 1 | 674 ascii_bytes += 1 |
| 673 if ascii_bytes * 10 <= length: | 675 if ascii_bytes * 10 <= length: |
| 674 return False | 676 return False |
| 675 if length > 0 and ascii_bytes > non_ascii_bytes * 7: | 677 if length > 0 and ascii_bytes > non_ascii_bytes * 7: |
| 676 return True | 678 return True |
| 677 if ascii_bytes > non_ascii_bytes * 3: | 679 if ascii_bytes > non_ascii_bytes * 3: |
| 678 return None # Maybe | 680 return None # Maybe |
| 679 return False | 681 return False |
| 680 | 682 |
| 681 def IsProbableExecutableRegion(self, location, length): | 683 def IsProbableExecutableRegion(self, location, length): |
| 682 opcode_bytes = 0 | 684 opcode_bytes = 0 |
| 683 sixty_four = self.arch == MD_CPU_ARCHITECTURE_AMD64 | 685 sixty_four = self.arch == MD_CPU_ARCHITECTURE_AMD64 |
| 684 for loc in xrange(location, location + length): | 686 for i in xrange(length): |
| 687 loc = location + i |
| 685 byte = ctypes.c_uint8.from_buffer(self.minidump, loc).value | 688 byte = ctypes.c_uint8.from_buffer(self.minidump, loc).value |
| 686 if (byte == 0x8b or # mov | 689 if (byte == 0x8b or # mov |
| 687 byte == 0x89 or # mov reg-reg | 690 byte == 0x89 or # mov reg-reg |
| 688 (byte & 0xf0) == 0x50 or # push/pop | 691 (byte & 0xf0) == 0x50 or # push/pop |
| 689 (sixty_four and (byte & 0xf0) == 0x40) or # rex prefix | 692 (sixty_four and (byte & 0xf0) == 0x40) or # rex prefix |
| 690 byte == 0xc3 or # return | 693 byte == 0xc3 or # return |
| 691 byte == 0x74 or # jeq | 694 byte == 0x74 or # jeq |
| 692 byte == 0x84 or # jeq far | 695 byte == 0x84 or # jeq far |
| 693 byte == 0x75 or # jne | 696 byte == 0x75 or # jne |
| 694 byte == 0x85 or # jne far | 697 byte == 0x85 or # jne far |
| (...skipping 27 matching lines...) Expand all Loading... |
| 722 cb(self, r.start, r.size, location) | 725 cb(self, r.start, r.size, location) |
| 723 offset += r.size | 726 offset += r.size |
| 724 | 727 |
| 725 if self.memory_list is not None: | 728 if self.memory_list is not None: |
| 726 for r in self.memory_list.ranges: | 729 for r in self.memory_list.ranges: |
| 727 cb(self, r.start, r.memory.data_size, r.memory.rva) | 730 cb(self, r.start, r.memory.data_size, r.memory.rva) |
| 728 | 731 |
| 729 def FindWord(self, word, alignment=0): | 732 def FindWord(self, word, alignment=0): |
| 730 def search_inside_region(reader, start, size, location): | 733 def search_inside_region(reader, start, size, location): |
| 731 location = (location + alignment) & ~alignment | 734 location = (location + alignment) & ~alignment |
| 732 for loc in xrange(location, location + size - self.PointerSize()): | 735 for i in xrange(size - self.PointerSize()): |
| 736 loc = location + i |
| 733 if reader._ReadWord(loc) == word: | 737 if reader._ReadWord(loc) == word: |
| 734 slot = start + (loc - location) | 738 slot = start + (loc - location) |
| 735 print "%s: %s" % (reader.FormatIntPtr(slot), | 739 print "%s: %s" % (reader.FormatIntPtr(slot), |
| 736 reader.FormatIntPtr(word)) | 740 reader.FormatIntPtr(word)) |
| 737 self.ForEachMemoryRegion(search_inside_region) | 741 self.ForEachMemoryRegion(search_inside_region) |
| 738 | 742 |
| 739 def FindWordList(self, word): | 743 def FindWordList(self, word): |
| 740 aligned_res = [] | 744 aligned_res = [] |
| 741 unaligned_res = [] | 745 unaligned_res = [] |
| 742 def search_inside_region(reader, start, size, location): | 746 def search_inside_region(reader, start, size, location): |
| 743 for loc in xrange(location, location + size - self.PointerSize()): | 747 for i in xrange(size - self.PointerSize()): |
| 748 loc = location + i |
| 744 if reader._ReadWord(loc) == word: | 749 if reader._ReadWord(loc) == word: |
| 745 slot = start + (loc - location) | 750 slot = start + (loc - location) |
| 746 if slot % self.PointerSize() == 0: | 751 if slot % self.PointerSize() == 0: |
| 747 aligned_res.append(slot) | 752 aligned_res.append(slot) |
| 748 else: | 753 else: |
| 749 unaligned_res.append(slot) | 754 unaligned_res.append(slot) |
| 750 self.ForEachMemoryRegion(search_inside_region) | 755 self.ForEachMemoryRegion(search_inside_region) |
| 751 return (aligned_res, unaligned_res) | 756 return (aligned_res, unaligned_res) |
| 752 | 757 |
| 753 def FindLocation(self, address): | 758 def FindLocation(self, address): |
| (...skipping 1577 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2331 " more..." | 2336 " more..." |
| 2332 " </a>)" % | 2337 " </a>)" % |
| 2333 (self.encfilename, highlight_address)) | 2338 (self.encfilename, highlight_address)) |
| 2334 | 2339 |
| 2335 f.write("<h3>%s 0x%x - 0x%x, " | 2340 f.write("<h3>%s 0x%x - 0x%x, " |
| 2336 "highlighting <a href=\"#highlight\">0x%x</a> %s</h3>\n" % | 2341 "highlighting <a href=\"#highlight\">0x%x</a> %s</h3>\n" % |
| 2337 (desc, start_address, end_address, highlight_address, expand)) | 2342 (desc, start_address, end_address, highlight_address, expand)) |
| 2338 f.write('<div class="code">') | 2343 f.write('<div class="code">') |
| 2339 f.write("<table class=\"codedump\">\n") | 2344 f.write("<table class=\"codedump\">\n") |
| 2340 | 2345 |
| 2341 for slot in xrange(start_address, end_address, size): | 2346 for j in xrange(0, end_address - start_address, size): |
| 2347 slot = start_address + j |
| 2342 heap_object = "" | 2348 heap_object = "" |
| 2343 maybe_address = None | 2349 maybe_address = None |
| 2344 end_region = region[0] + region[1] | 2350 end_region = region[0] + region[1] |
| 2345 if slot < region[0] or slot + size > end_region: | 2351 if slot < region[0] or slot + size > end_region: |
| 2346 straddress = "0x" | 2352 straddress = "0x" |
| 2347 for i in xrange(end_region, slot + size): | 2353 for i in xrange(end_region, slot + size): |
| 2348 straddress += "??" | 2354 straddress += "??" |
| 2349 for i in reversed( | 2355 for i in reversed( |
| 2350 xrange(max(slot, region[0]), min(slot + size, end_region))): | 2356 xrange(max(slot, region[0]), min(slot + size, end_region))): |
| 2351 straddress += "%02x" % self.reader.ReadU8(i) | 2357 straddress += "%02x" % self.reader.ReadU8(i) |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2406 | 2412 |
| 2407 f.write("<h3>ASCII dump 0x%x - 0x%x, highlighting 0x%x %s</h3>" % | 2413 f.write("<h3>ASCII dump 0x%x - 0x%x, highlighting 0x%x %s</h3>" % |
| 2408 (start_address, end_address, highlight_address, expand)) | 2414 (start_address, end_address, highlight_address, expand)) |
| 2409 | 2415 |
| 2410 line_width = 64 | 2416 line_width = 64 |
| 2411 | 2417 |
| 2412 f.write('<div class="code">') | 2418 f.write('<div class="code">') |
| 2413 | 2419 |
| 2414 start = self.align_down(start_address, line_width) | 2420 start = self.align_down(start_address, line_width) |
| 2415 | 2421 |
| 2416 for address in xrange(start, end_address): | 2422 for i in xrange(end_address - start): |
| 2423 address = start + i |
| 2417 if address % 64 == 0: | 2424 if address % 64 == 0: |
| 2418 if address != start: | 2425 if address != start: |
| 2419 f.write("<br>") | 2426 f.write("<br>") |
| 2420 f.write("0x%08x: " % address) | 2427 f.write("0x%08x: " % address) |
| 2421 if address < start_address: | 2428 if address < start_address: |
| 2422 f.write(" ") | 2429 f.write(" ") |
| 2423 else: | 2430 else: |
| 2424 if address == highlight_address: | 2431 if address == highlight_address: |
| 2425 f.write("<span class=\"highlight\">") | 2432 f.write("<span class=\"highlight\">") |
| 2426 code = self.reader.ReadU8(address) | 2433 code = self.reader.ReadU8(address) |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2475 if exact and not found and end_address == region[0] + region[1]: | 2482 if exact and not found and end_address == region[0] + region[1]: |
| 2476 exactness = "&exact=off" | 2483 exactness = "&exact=off" |
| 2477 expand = ("(<a href=\"disasm.html?%s%s" | 2484 expand = ("(<a href=\"disasm.html?%s%s" |
| 2478 "&val=0x%x#highlight\">more...</a>)" % | 2485 "&val=0x%x#highlight\">more...</a>)" % |
| 2479 (self.encfilename, exactness, highlight_address)) | 2486 (self.encfilename, exactness, highlight_address)) |
| 2480 | 2487 |
| 2481 f.write("<h3>Disassembling 0x%x - 0x%x, highlighting 0x%x %s</h3>" % | 2488 f.write("<h3>Disassembling 0x%x - 0x%x, highlighting 0x%x %s</h3>" % |
| 2482 (start_address, end_address, highlight_address, expand)) | 2489 (start_address, end_address, highlight_address, expand)) |
| 2483 f.write('<div class="code">') | 2490 f.write('<div class="code">') |
| 2484 f.write("<table class=\"codedump\">\n"); | 2491 f.write("<table class=\"codedump\">\n"); |
| 2485 for i in xrange(0, len(lines)): | 2492 for i in xrange(len(lines)): |
| 2486 line = lines[i] | 2493 line = lines[i] |
| 2487 next_address = count | 2494 next_address = count |
| 2488 if i + 1 < len(lines): | 2495 if i + 1 < len(lines): |
| 2489 next_line = lines[i + 1] | 2496 next_line = lines[i + 1] |
| 2490 next_address = next_line[0] | 2497 next_address = next_line[0] |
| 2491 self.format_disasm_line( | 2498 self.format_disasm_line( |
| 2492 f, start_address, line, next_address, highlight_address) | 2499 f, start_address, line, next_address, highlight_address) |
| 2493 f.write("</table>\n") | 2500 f.write("</table>\n") |
| 2494 f.write("</div>") | 2501 f.write("</div>") |
| 2495 return | 2502 return |
| (...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2831 Interpret memory in the given region [address, address + num * word_size) | 2838 Interpret memory in the given region [address, address + num * word_size) |
| 2832 (if available) as a sequence of words. Automatic alignment is not performed
. | 2839 (if available) as a sequence of words. Automatic alignment is not performed
. |
| 2833 If the num is not specified, a default value of 16 words is used. | 2840 If the num is not specified, a default value of 16 words is used. |
| 2834 Synopsis: dd 0x<address> 0x<num> | 2841 Synopsis: dd 0x<address> 0x<num> |
| 2835 """ | 2842 """ |
| 2836 args = args.split(' ') | 2843 args = args.split(' ') |
| 2837 start = int(args[0], 16) | 2844 start = int(args[0], 16) |
| 2838 num = int(args[1], 16) if len(args) > 1 else 0x10 | 2845 num = int(args[1], 16) if len(args) > 1 else 0x10 |
| 2839 if (start & self.heap.ObjectAlignmentMask()) != 0: | 2846 if (start & self.heap.ObjectAlignmentMask()) != 0: |
| 2840 print "Warning: Dumping un-aligned memory, is this what you had in mind?" | 2847 print "Warning: Dumping un-aligned memory, is this what you had in mind?" |
| 2841 for slot in xrange(start, | 2848 for i in xrange(0, |
| 2842 start + self.reader.PointerSize() * num, | 2849 self.reader.PointerSize() * num, |
| 2843 self.reader.PointerSize()): | 2850 self.reader.PointerSize()): |
| 2851 slot = start + i |
| 2844 if not self.reader.IsValidAddress(slot): | 2852 if not self.reader.IsValidAddress(slot): |
| 2845 print "Address is not contained within the minidump!" | 2853 print "Address is not contained within the minidump!" |
| 2846 return | 2854 return |
| 2847 maybe_address = self.reader.ReadUIntPtr(slot) | 2855 maybe_address = self.reader.ReadUIntPtr(slot) |
| 2848 heap_object = self.padawan.SenseObject(maybe_address) | 2856 heap_object = self.padawan.SenseObject(maybe_address) |
| 2849 print "%s: %s %s" % (self.reader.FormatIntPtr(slot), | 2857 print "%s: %s %s" % (self.reader.FormatIntPtr(slot), |
| 2850 self.reader.FormatIntPtr(maybe_address), | 2858 self.reader.FormatIntPtr(maybe_address), |
| 2851 heap_object or '') | 2859 heap_object or '') |
| 2852 | 2860 |
| 2853 def do_do(self, address): | 2861 def do_do(self, address): |
| (...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3164 try: | 3172 try: |
| 3165 server = InspectionWebServer(PORT_NUMBER, options, args[0]) | 3173 server = InspectionWebServer(PORT_NUMBER, options, args[0]) |
| 3166 print 'Started httpserver on port ' , PORT_NUMBER | 3174 print 'Started httpserver on port ' , PORT_NUMBER |
| 3167 webbrowser.open('http://localhost:%i/summary.html' % PORT_NUMBER) | 3175 webbrowser.open('http://localhost:%i/summary.html' % PORT_NUMBER) |
| 3168 server.serve_forever() | 3176 server.serve_forever() |
| 3169 except KeyboardInterrupt: | 3177 except KeyboardInterrupt: |
| 3170 print '^C received, shutting down the web server' | 3178 print '^C received, shutting down the web server' |
| 3171 server.socket.close() | 3179 server.socket.close() |
| 3172 else: | 3180 else: |
| 3173 AnalyzeMinidump(options, args[0]) | 3181 AnalyzeMinidump(options, args[0]) |
| OLD | NEW |