def main(argv): print "Hex dumper using WinAppDbg" print "by Mario Vilas (mvilas at gmail.com)" print if len(argv) != 2: import os script = os.path.basename(argv[0]) print " %s <filename>" % script return with open(argv[1], "rb") as fd: fd.seek(0, 2) size = fd.tell() fd.seek(0, 0) if bit_length(size) > 32: width = 8 else: width = 16 address = 0 while 1: data = fd.read(16) if not data: break print HexDump.hexblock(data, address=address, width=width), address = address + len(data)
def main(): print "Process memory reader" print "by Mario Vilas (mvilas at gmail.com)" print if len(sys.argv) not in (4, 5): script = os.path.basename(sys.argv[0]) print " %s <pid> <address> <size> [binary output file]" % script print " %s <process.exe> <address> <size> [binary output file]" % script return System.request_debug_privileges() try: pid = HexInput.integer(sys.argv[1]) except: s = System() s.scan_processes() pl = s.find_processes_by_filename(sys.argv[1]) if not pl: print "Process not found: %s" % sys.argv[1] return if len(pl) > 1: print "Multiple processes found for %s" % sys.argv[1] for p,n in pl: print "\t%s: %s" % (HexDump.integer(p),n) return pid = pl[0][0].get_pid() try: address = HexInput.integer(sys.argv[2]) except Exception: print "Invalid value for address: %s" % sys.argv[2] return try: size = HexInput.integer(sys.argv[3]) except Exception: print "Invalid value for size: %s" % sys.argv[3] return p = Process(pid) data = p.read(address, size) ## data = p.peek(address, size) print "Read %d bytes from PID %d" % (len(data), pid) if len(sys.argv) == 5: filename = sys.argv[4] open(filename, 'wb').write(data) print "Written %d bytes to %s" % (len(data), filename) else: if win32.sizeof(win32.LPVOID) == win32.sizeof(win32.DWORD): width = 16 else: width = 8 print print HexDump.hexblock(data, address, width = width)
def my_event_handler( event ): # Get the event name. name = event.get_event_name() # Get the event code. code = event.get_event_code() # Get the process ID where the event occured. pid = event.get_pid() # Get the thread ID where the event occured. tid = event.get_tid() # Get the value of EIP at the thread. pc = event.get_thread().get_pc() # Show something to the user. bits = event.get_process().get_bits() format_string = "%s (%s) at address %s, process %d, thread %d" message = format_string % ( name, HexDump.integer(code, bits), HexDump.address(pc, bits), pid, tid ) print message # If the event is a crash... if code == win32.EXCEPTION_DEBUG_EVENT and event.is_last_chance(): print "Crash detected, storing crash dump in database..." # Generate a minimal crash dump. crash = Crash( event ) # You can turn it into a full crash dump (recommended). # crash.fetch_extra_data( event, takeMemorySnapshot = 0 ) # no memory dump # crash.fetch_extra_data( event, takeMemorySnapshot = 1 ) # small memory dump crash.fetch_extra_data( event, takeMemorySnapshot = 2 ) # full memory dump # Connect to the database. You can use any URL supported by SQLAlchemy. # For more details see the reference documentation. dao = CrashDAO( "sqlite:///crashes.sqlite" ) #dao = CrashDAO( "mysql+MySQLdb://root:toor@localhost/crashes" ) # Store the crash dump in the database. dao.add( crash ) # If you do this instead, heuristics are used to detect duplicated # crashes so they aren't added to the database. # dao.add( crash, allow_duplicates = False ) # You can also launch the interactive debugger from here. Try it! :) # event.debug.interactive() # Kill the process. event.get_process().kill()
def my_event_handler( event ): # Get the process ID where the event occured. pid = event.get_pid() # Get the thread ID where the event occured. tid = event.get_tid() # Find out if it's a 32 or 64 bit process. bits = event.get_process().get_bits() # Get the value of EIP at the thread. address = event.get_thread().get_pc() # Get the event name. name = event.get_event_name() # Get the event code. code = event.get_event_code() # If the event is an exception... if code == win32.EXCEPTION_DEBUG_EVENT: # Get the exception user-friendly description. name = event.get_exception_description() # Get the exception code. code = event.get_exception_code() # Get the address where the exception occurred. try: address = event.get_fault_address() except NotImplementedError: address = event.get_exception_address() # If the event is a process creation or destruction, # or a DLL being loaded or unloaded... elif code in ( win32.CREATE_PROCESS_DEBUG_EVENT, win32.EXIT_PROCESS_DEBUG_EVENT, win32.LOAD_DLL_DEBUG_EVENT, win32.UNLOAD_DLL_DEBUG_EVENT ): # Get the filename. filename = event.get_filename() if filename: name = "%s [%s]" % ( name, filename ) # Show a descriptive message to the user. print "-" * 79 format_string = "%s (0x%s) at address 0x%s, process %d, thread %d" message = format_string % ( name, HexDump.integer(code, bits), HexDump.address(address, bits), pid, tid ) print message
def memory_search( pid, bytes ): # Instance a Process object. process = Process( pid ) # Search for the string in the process memory. for address in process.search_bytes( bytes ): # Print the memory address where it was found. print HexDump.address( address )
def memory_search(pid, bytes): # Instance a Process object. process = Process(pid) # Search for the string in the process memory. for address in process.search_bytes(bytes): # Print the memory address where it was found. print HexDump.address(address)
def post_CreateThread(self, event, retval): bits = event.get_process().get_bits() params = event.hook.get_params(event.get_tid()) dwStackSize = params[1] StackSize = int(HexDump.integer(dwStackSize, bits), 16) lpStartAddress = params[2] StartAddress = "0x" + HexDump.address(lpStartAddress, bits) lpThreadId = retval buf = "StackSize: {}, StartAddress: {}, ThreadId: {}".format(StackSize, StartAddress, lpThreadId) hd.dispatch(event, "CreateThread", buf, "thread", StartAddress)
def my_event_handler(event): # Get the event name. name = event.get_event_name() # Get the event code. code = event.get_event_code() # Get the process ID where the event occured. pid = event.get_pid() # Get the thread ID where the event occured. tid = event.get_tid() # Get the value of EIP at the thread. pc = event.get_thread().get_pc() # Show something to the user. bits = event.get_process().get_bits() format_string = "%s (%s) at address %s, process %d, thread %d" message = format_string % (name, HexDump.integer(code, bits), HexDump.address(pc, bits), pid, tid) print message # If the event is a crash... if code == win32.EXCEPTION_DEBUG_EVENT and event.is_last_chance(): print "Crash detected, storing crash dump in database..." # Generate a minimal crash dump. crash = Crash(event) print crash # You can turn it into a full crash dump (recommended). # crash.fetch_extra_data( event, takeMemorySnapshot = 0 ) # no memory dump # crash.fetch_extra_data( event, takeMemorySnapshot = 1 ) # small memory dump # crash.fetch_extra_data( event, takeMemorySnapshot=2 ) # full memory dump # Connect to the database. You can use any URL supported by SQLAlchemy. # For more details see the reference documentation. # dao = CrashDAO( "sqlite:///crashes.sqlite" ) # dao = CrashDAO( "mysql+MySQLdb://root:toor@localhost/crashes" ) # Store the crash dump in the database. # dao.add( crash ) # If you do this instead, heuristics are used to detect duplicated # crashes so they arent added to the database. # dao.add( crash, allow_duplicates = False ) # You can also launch the interactive debugger from here. Try it! :) # event.debug.interactive() # Kill the process. event.get_process().kill() return
def handler(self, event): if ( event.get_event_code() == win32.EXCEPTION_DEBUG_EVENT and event.get_exception_code() != win32.STATUS_BREAKPOINT and (event.is_last_chance() or event.get_exception_code() in self.alwaysCatchExceptions) ): crash = Crash(event) report = CrashReport() crash = Crash(event) (exploitable, type, info) = crash.isExploitable() try: report.code = event.get_thread().disassemble(crash.pc, 0x10)[0][2] except: report.code = "Could not disassemble" if crash.faultAddress is None or MemoryAddresses.align_address_to_page_start(crash.faultAddress) == 0: report.nearNull = True else: report.nearNull = False report.type = type lib = event.get_thread().get_process().get_module_at_address(crash.pc) if lib != None: report.location = lib.get_label_at_address(crash.pc) else: report.location = HexDump.address(crash.pc, event.get_thread().get_process().get_bits())[-4:] if crash.faultAddress == None: crash.faultAddress = 0 report.faultAddr = HexDump.address(crash.faultAddress, event.get_thread().get_process().get_bits()) report.stack = "" stList = self.getStackTraceRelList(event.get_thread()) if len(stList) > 0: for ra in stList: lib = event.get_thread().get_process().get_module_at_address(ra) if lib != None: report.stack += ( lib.get_label_at_address(ra) + " " + HexDump.address(ra, event.get_thread().get_process().get_bits()) + "\n" ) else: report.stack += HexDump.address(ra, event.get_thread().get_process().get_bits()) + "\n" if report.stack == "": report.stack = "NO_STACK" report.info = crash.fullReport() return report return None
def my_event_handler(event): # Get the process ID where the event occured. pid = event.get_pid() # Get the thread ID where the event occured. tid = event.get_tid() # Find out if it's a 32 or 64 bit process. bits = event.get_process().get_bits() # Get the value of EIP at the thread. address = event.get_thread().get_pc() # Get the event name. name = event.get_event_name() # Get the event code. code = event.get_event_code() # If the event is an exception... if code == win32.EXCEPTION_DEBUG_EVENT: # Get the exception user-friendly description. name = event.get_exception_description() # Get the exception code. code = event.get_exception_code() # Get the address where the exception occurred. try: address = event.get_fault_address() except NotImplementedError: address = event.get_exception_address() # If the event is a process creation or destruction, # or a DLL being loaded or unloaded... elif code in (win32.CREATE_PROCESS_DEBUG_EVENT, win32.EXIT_PROCESS_DEBUG_EVENT, win32.LOAD_DLL_DEBUG_EVENT, win32.UNLOAD_DLL_DEBUG_EVENT): # Get the filename. filename = event.get_filename() if filename: name = "%s [%s]" % (name, filename) # Show a descriptive message to the user. print "-" * 79 format_string = "%s (0x%s) at address 0x%s, process %d, thread %d" message = format_string % (name, HexDump.integer( code, bits), HexDump.address(address, bits), pid, tid) print message
def pre_scanf(self, event, return_address, format_string, *args): # As this callback would be called for all calls to scanf, we # check the return address to confirm that this is the call we # care about if (return_address == 0x00401365): print 'Format string at address %s is "%s"' % (\ HexDump.address(format_string), \ event.get_process().peek_string(format_string)) # args contain pointers to one or more buffers to store # the values inputted by user if (len(args) > 0): print 'Buffer for user input at address: %s' % HexDump.address(args[0]) event.get_process().write_uint(args[0], 338724)
def post_CreateRemoteThread(self, event, retval): bits = event.get_process().get_bits() params = event.hook.get_params(event.get_tid()) dwStackSize = params[2] StackSize = int(HexDump.integer(dwStackSize, bits)) lpStartAddress = params[3] StartAddress = "0x" + HexDump.address(lpStartAddress, bits) lpThreadId = params[6] #ThreadId = event.get_process().read_uint(lpThreadId) #ThreadId = "0x" + HexDump.integer(ThreadId, bits) # TODO buf = "StackSize: {}, StartAddress: {}".format(StackSize, StartAddress) hd.dispatch(event, "CreateRemoteThread", buf, "thread", StartAddress)
def do(self, arg): ".exchain - Show the SEH chain" thread = self.get_thread_from_prefix() print("Exception handlers for thread %d" % thread.get_tid()) table = Table() table.addRow("Block", "Function") bits = thread.get_bits() for (seh, seh_func) in thread.get_seh_chain(): if seh is not None: seh = HexDump.address(seh, bits) if seh_func is not None: seh_func = HexDump.address(seh_func, bits) table.addRow(seh, seh_func) print(table.getOutput())
def check_args_callback(event): ''' This will be called when our breakpoint is hit. Checks if our string is a parameter. @param event: Event information, dear Watson. @todo: dereference the values in registers as well {eax, ebx, ecx, esi, edi} ''' nrOfArguments = 5 # TODO: Take this parameter from IDA MAX_USERSPACE_ADDRESS = 0x7FFFFFFF MIN_USERSPACE_ADDRESS = 0x1000 MAX_ARGUMENT_LEN = 100 # somehow arbitrary process = event.get_process() thread = event.get_thread() Eip = thread.get_pc() Esp = thread.get_context()['Esp'] stackAddress = Esp + 4 for idx in xrange(nrOfArguments): stackAddress += idx * 4 # Dereference at address and look for searchPattern # NOTE: read() returns a string, not a number (unpack does the trick) suspectedPointer = struct.unpack('<L', process.read(stackAddress, 4))[0] if suspectedPointer > MIN_USERSPACE_ADDRESS and suspectedPointer < MAX_USERSPACE_ADDRESS: try: possibleString = process.read(suspectedPointer, MAX_ARGUMENT_LEN) # This is already a string, cool if searchPattern in possibleString: if Eip not in logged_functions: logged_functions.append(Eip) print "[*] Found! %s is the parameter nr. %d of %08x" % (searchPattern, idx + 1, Eip) fd.write("[*] Found! %s is the %d parameter of %08x\n" % (searchPattern, idx + 1, Eip)) fd.write("%s\n" % HexDump.hexblock(possibleString, suspectedPointer)) except KeyboardInterrupt: fd.close() sys.exit(1) except: # Access violation. Log only by debugging (huge overhead due to I/O) pass # Let's search for the string in UNICODE possibleStringU = process.peek_string(suspectedPointer, fUnicode = True) if searchPattern in possibleStringU: if searchPattern in possibleString: if Eip not in logged_functions: logged_functions.append(Eip) print "[*] Found! %s is the parameter nr. %d of %08x" % (searchPattern, idx + 1, Eip) fd.write("[*] Found! %s is the %d parameter of %08x\n" % (searchPattern, idx + 1, Eip)) fd.write("%s\n" % HexDump.hexblock(possibleString, suspectedPointer))
def show_window(window): # Get the window coordinates. rect = window.get_screen_rect() position = (rect.left, rect.top, rect.right, rect.bottom) size = (rect.right - rect.left, rect.bottom - rect.top) # Print the window information. print "Handle: %s" % HexDump.integer(window.get_handle()) print "Caption: %s" % window.text print "Class: %s" % window.classname print "Style: %s" % HexDump.integer(window.style) print "ExStyle: %s" % HexDump.integer(window.exstyle) print "Position: (%i, %i) - (%i, %i)" % position print "Size: (%i, %i)" % size
def show_window( window ): # Get the window coordinates. rect = window.get_screen_rect() position = (rect.left, rect.top, rect.right, rect.bottom) size = (rect.right - rect.left, rect.bottom - rect.top) # Print the window information. print ("Handle: %s" % HexDump.integer( window.get_handle() )) print ("Caption: %s" % window.text) print ("Class: %s" % window.classname) print ("Style: %s" % HexDump.integer( window.style )) print ("ExStyle: %s" % HexDump.integer( window.exstyle )) print ("Position: (%i, %i) - (%i, %i)" % position) print ("Size: (%i, %i)" % size)
def print_state( process_name ): # Request debug privileges. System.request_debug_privileges() # Find the first process that matches the requested name. system = System() process, filename = system.find_processes_by_filename( process_name )[ 0 ] # Suspend the process execution. process.suspend() try: # For each thread in the process... for thread in process.iter_threads(): # Get the thread state. tid = thread.get_tid() eip = thread.get_pc() code = thread.disassemble_around( eip ) context = thread.get_context() # Display the thread state. print print "-" * 79 print "Thread: %s" % HexDump.integer( tid ) print print CrashDump.dump_registers( context ) print CrashDump.dump_code( code, eip ), print "-" * 79 # Resume the process execution. finally: process.resume()
def scanBtnClk(self): if hack == None: return text = str(self.searchtext.toPlainText()) if text.strip() == '': return self.searchlistwidget.clear() if valuetype == 'byte': num = memprc.d2h(int(text), 1) if valuetype == '2byte': num = memprc.d2h(int(text), 2) if valuetype == '4bytes': num = memprc.d2h(int(text), 4) if valuetype == '8bytes': num = memprc.d2h(int(text), 8) if valuetype == 'String': pass #num = memprc.d2h(int(text), 4) result = hack.hwnd.search_hexa(num, hack.base_address, hack.last_address) cnt = 0 for address, data in result: item = QtGui.QListWidgetItem(self.searchlistwidget) item.setText(HexDump.hexblock(data, address=address)) #print HexDump.hexblock(data, address=address) cnt += 1 self.searchcntlabel.setText(str(cnt))
def main(argv): print("Hex dumper using WinAppDbg") print("by Mario Vilas (mvilas at gmail.com)") print() if len(argv) != 2: import os script = os.path.basename(argv[0]) print(" %s <filename>" % script) return with open(argv[1], 'rb') as fd: fd.seek(0, 2) size = fd.tell() fd.seek(0, 0) if bit_length(size) > 32: width = 8 else: width = 16 address = 0 while 1: data = fd.read(16) if not data: break print(HexDump.hexblock(data, address=address, width=width), end=' ') address = address + len(data)
def message(self, pid, address, data=None): if self.start < 0: raise StopIteration count = self.count + 1 # NOQA address = address + self.start where = HexDump.address(address) # NOQA size = self.end - self.start # NOQA msg = self.showfmt % vars() if data is not None: msg += "\n" p = self.start & (~0xF) q = (self.end & (~0xF)) + 0x10 msg += HexDump.hexblock(data[p:q], address & (~0xF)) if msg.endswith('\n'): msg = msg[:-len('\n')] return msg
def single_step(self, event): # Show the user where we're running. thread = event.get_thread() pc = thread.get_pc() code = thread.disassemble(pc, 0x10)[0] bits = event.get_process().get_bits() print "%s: %s" % (HexDump.address(code[0], bits), code[2].lower())
def post_GetProcAddress(self, event, retval): params = event.hook.get_params(event.get_tid()) #hModule = self.peek(event, params[0]) lpProcName = params[1] procAddr = "0x" + HexDump.address(retval, bits) #TODO: attribiute CREATE_SUSPENDED buf = "lpProcName: {}, ret_addr: {}".format(lpProcName, procAddr) hd.dispatch(event, "GetProcAddress", buf, "module", lpProcName)
def single_step( self, event ): # Show the user where we're running. thread = event.get_thread() pc = thread.get_pc() code = thread.disassemble( pc, 0x10 ) [0] bits = event.get_process().get_bits() print "%s: %s" % ( HexDump.address(code[0], bits), code[2].lower() )
def accessed(self, event): # Show the user where we're running. thread = event.get_thread() pc = thread.get_pc() code = thread.disassemble(pc, 0x10)[0] print "%s: %s" % (HexDump.address(code[0], thread.get_bits()), code[2].lower())
def log_eip_callback(event): ''' This will be called when our breakpoint is hit. It writes the current EIP. @param event: Event information, dough! ''' address = event.get_thread().get_pc() fd.write(HexDump.address(address) + '\n')
def handler(self, event): if event.get_event_code() == win32.EXCEPTION_DEBUG_EVENT and event.get_exception_code() != win32.STATUS_BREAKPOINT and (event.is_last_chance() or event.get_exception_code() in self.alwaysCatchExceptions): crash = Crash(event) report = CrashReport() crash = Crash(event) (exploitable, type, info) = crash.isExploitable() try: report.code = event.get_thread().disassemble( crash.pc, 0x10 ) [0][2] except: report.code = "Could not disassemble" if crash.faultAddress is None or MemoryAddresses.align_address_to_page_start(crash.faultAddress) == 0: report.nearNull = True else: report.nearNull = False report.type = type lib = event.get_thread().get_process().get_module_at_address(crash.pc) if lib != None: report.location = lib.get_label_at_address(crash.pc) else: report.location = HexDump.address(crash.pc, event.get_thread().get_process().get_bits())[-4:] if crash.faultAddress == None: crash.faultAddress = 0 report.faultAddr = HexDump.address(crash.faultAddress, event.get_thread().get_process().get_bits()) report.stack = "" stList = self.getStackTraceRelList(event.get_thread()) if len(stList)>0: for ra in stList: lib = event.get_thread().get_process().get_module_at_address(ra) if lib != None: report.stack += lib.get_label_at_address(ra) + " " + HexDump.address(ra, event.get_thread().get_process().get_bits()) + "\n" else: report.stack += HexDump.address(ra, event.get_thread().get_process().get_bits()) + "\n" if report.stack == "": report.stack = "NO_STACK" report.info= crash.fullReport() return report return None
def breakpoint_010153FF(event): """ .rsrc:010153F0 mov ecx, [ebp+var_C] .rsrc:010153F3 mov edx, [ecx+28h] .rsrc:010153F6 push edx .rsrc:010153F7 call sub_1015270 .rsrc:010153FC cmp eax, [ebp+arg_0] .rsrc:010153FF jnz short loc_101540B <------ we are here """ global memory_snapshot, context_snapshot, first_time, filename, all_filenames, index thread = event.get_thread() context = thread.get_context() # logging.debug("-" * 79) logging.debug("filename: " + filename.decode("hex")) logging.debug("eax: " + HexDump.address(context["Eax"])) if context["Eax"] == 0x8FECD63F: logging.debug("-" * 79) logging.debug("filename: " + filename.decode("hex")) logging.debug("eax: " + HexDump.address(context["Eax"])) index += 1 if (index == len(all_filenames)): logging.debug("-" * 79) logging.debug("Reached the end of the address space") event.debug.stop() return # restore everything - need to wait and see if this is set_memory(event, memory_snapshot) thread.set_context(context_snapshot) # we need to write the memory_blob with the original because restore memory does not cover that # most likely due to skipping the memory mapped files # no idea why the restore context thing does not work # but this will send us back to top and hopefully that breakpoint will be triggered again thread.set_pc(0x010153F6)
def takeSnapshot(self): """ Called from the take snapshot event. This was fired by a breakpoint on an address that the user specified as the point where everything should be restored on the next fuzz iteration. NOTE: Que pasa con los contextos de los otros threads??? Se podram resumir en el mismo estado? Creo que si y deberiamos hacerlo. """ #logger.log_text("Taking snapshot of the process") # Take a snapshot of the contex of the current thread self.context = self.thread.get_context() pageSize = System.pageSize # Save also special pages like the PEB self.special_pages = dict() page = MemoryAddresses.align_address_to_page_start( self.process.get_peb_address()) self.special_pages[page] = self.process.read(page, pageSize) # Also do this for other threads for thread in self.process.iter_threads(): page = MemoryAddresses.align_address_to_page_start( thread.get_teb_address()) self.special_pages[page] = self.process.read(page, pageSize) self.memory = dict() self.tainted = set() # For each memory map in memory for mbi in self.process.get_memory_map(): # We only care about those who are writable if mbi.is_writeable(): page = mbi.BaseAddress max_page = page + mbi.RegionSize # For each page while page < max_page: # if it is not a special page if not self.special_pages.has_key(page): # Save the old protection permissions protect = mbi.Protect new_protect = self.protect_conversions[protect] try: self.process.mprotect(page, pageSize, new_protect) self.memory[page] = (None, protect, new_protect) except WindowsError: # if we have a weird error, mark it as a special page self.special_pages[page] = self.process.read( page, pageSize) logger.log_text("unexpected special page %s" % HexDump.address(page)) # next page page = page + pageSize
def single_step(self, event): thread = event.get_thread() pc = thread.get_pc() code = thread.disassemble(pc, 0x10)[0] trace_file = open(os.path.join(TRACE_PATH, "%s.csv" % event.get_pid()), "a") trace_file.write("\"0x%s\",\"%s\"\n" % (HexDump.address(code[0]), code[2])) trace_file.close()
def print_module_load(self, event): mod = event.get_module() base = mod.get_base() name = mod.get_filename() if not name: name = '' msg = "Loaded module (%s) %s" msg = msg % (HexDump.address(base), name) print msg
def strings( pid ): # Instance a Process object. process = Process( pid ) # For each ASCII string found in the process memory... for address, size, data in process.strings(): # Print the string and the memory address where it was found. print "%s: %s" % ( HexDump.address(address), data )
def strings(pid): # Instance a Process object. process = Process(pid) # For each ASCII string found in the process memory... for address, size, data in process.strings(): # Print the string and the memory address where it was found. print "%s: %s" % (HexDump.address(address), data)
def print_handle_caption(): system = System() for window in system.get_windows(): handle = HexDump.integer(window.get_handle()) caption = window.get_text() if not caption in None: print "%s\t%s" % (handle, caption)
def accessed( self, event ): # Show the user where we're running. thread = event.get_thread() pc = thread.get_pc() code = thread.disassemble( pc, 0x10 ) [0] print "%s: %s" % ( HexDump.address(code[0], thread.get_bits()), code[2].lower() )
def print_event(event): code = HexDump.integer(event.get_event_code()) name = event.get_event_name() desc = event.get_event_description() if code in desc: print print "%s: %s" % (name, desc) else: print print "%s (%s): %s" % (name, code, desc)
def print_thread(title, thread): tid = thread.get_tid() eip = thread.get_pc() context = thread.get_context() handle = thread.get_handle() code = thread.disassemble_around(eip) print("%s %s - %s " % (title, HexDump.integer(tid), handle)) print CrashDump.dump_registers(context) print CrashDump.dump_code(code, eip),
def print_modules(pid): # Instance a Process object. process = Process(pid) print "Process %d" % process.get_pid() # ...and the modules in the process. print "Modules:" bits = process.get_bits() for module in process.iter_modules(): print "\t%s\t%s" % (HexDump.address(module.get_base(), bits), module.get_filename())
def entering( event ): # Get the thread object. thread = event.get_thread() # Get the thread ID. tid = thread.get_tid() # Get the return address location (the top of the stack). stack_top = thread.get_sp() # Get the return address and the parameters from the stack. bits = event.get_process().get_bits() if bits == 32: return_address, hModule, lpProcName = thread.read_stack_dwords( 3 ) else: return_address = thread.read_stack_qwords( 1 ) registers = thread.get_context() hModule = registers['Rcx'] lpProcName = registers['Rdx'] # Get the string from the process memory. procedure_name = event.get_process().peek_string( lpProcName ) # Show a message to the user. message = "%s: GetProcAddress(%s, %r);" print message % ( HexDump.address(return_address, bits), HexDump.address(hModule, bits), procedure_name ) # Watch the DWORD at the top of the stack. try: event.debug.stalk_variable( tid, stack_top, 4, returning ) #event.debug.watch_variable( tid, stack_top, 4, returning ) # If no more slots are available, set a code breakpoint at the return address. except RuntimeError: event.debug.stalk_at( event.get_pid(), return_address, returning_2 )
def access_violation(self, evt): thread = evt.get_thread() tid = thread.get_tid() code = thread.disassemble_around_pc() context = thread.get_context() print print "-" * 79 print "Thread: %s" % HexDump.integer(tid) print print CrashDump.dump_registers(context) print CrashDump.dump_code(code) print "-" * 79
def wildcard_search( pid, pattern ): # # Hex patterns must be in this form: # "68 65 6c 6c 6f 20 77 6f 72 6c 64" # "hello world" # # Spaces are optional. Capitalization of hex digits doesn't matter. # This is exactly equivalent to the previous example: # "68656C6C6F20776F726C64" # "hello world" # # Wildcards are allowed, in the form of a "?" sign in any hex digit: # "5? 5? c3" # pop register / pop register / ret # "b8 ?? ?? ?? ??" # mov eax, immediate value # # Instance a Process object. process = Process( pid ) # Search for the hexadecimal pattern in the process memory. for address, data in process.search_hexa( pattern ): # Print a hex dump for each memory location found. print HexDump.hexblock(data, address = address)
def main(): print("Process memory writer") print("by Mario Vilas (mvilas at gmail.com)") print() if len(sys.argv) < 4: script = os.path.basename(sys.argv[0]) print(" %s <pid> <address> {binary input file / hex data}" % script) print(" %s <process.exe> <address> {binary input file / hex data}" % script) return System.request_debug_privileges() try: pid = HexInput.integer(sys.argv[1]) except Exception: s = System() s.scan_processes() pl = s.find_processes_by_filename(sys.argv[1]) if not pl: print("Process not found: %s" % sys.argv[1]) return if len(pl) > 1: print("Multiple processes found for %s" % sys.argv[1]) for p, n in pl: print("\t%s: %s" % (HexDump.integer(p), n)) return pid = pl[0][0].get_pid() try: address = HexInput.integer(sys.argv[2]) except Exception: print("Invalid value for address: %s" % sys.argv[2]) return filename = ' '.join(sys.argv[3:]) if os.path.exists(filename): data = open(filename, 'rb').read() print("Read %d bytes from %s" % (len(data), filename)) else: try: data = HexInput.hexadecimal(filename) except Exception: print("Invalid filename or hex block: %s" % filename) return p = Process(pid) p.write(address, data) print("Written %d bytes to PID %d" % (len(data), pid))
def wildcard_search(pid, pattern): # # Hex patterns must be in this form: # "68 65 6c 6c 6f 20 77 6f 72 6c 64" # "hello world" # # Spaces are optional. Capitalization of hex digits doesn't matter. # This is exactly equivalent to the previous example: # "68656C6C6F20776F726C64" # "hello world" # # Wildcards are allowed, in the form of a "?" sign in any hex digit: # "5? 5? c3" # pop register / pop register / ret # "b8 ?? ?? ?? ??" # mov eax, immediate value # # Instance a Process object. process = Process(pid) # Search for the hexadecimal pattern in the process memory. for address, data in process.search_hexa(pattern): # Print a hex dump for each memory location found. print HexDump.hexblock(data, address=address)
def main(): print "Process memory writer" print "by Mario Vilas (mvilas at gmail.com)" print if len(sys.argv) < 4: script = os.path.basename(sys.argv[0]) print " %s <pid> <address> {binary input file / hex data}" % script print " %s <process.exe> <address> {binary input file / hex data}" % script return System.request_debug_privileges() try: pid = HexInput.integer(sys.argv[1]) except Exception: s = System() s.scan_processes() pl = s.find_processes_by_filename(sys.argv[1]) if not pl: print "Process not found: %s" % sys.argv[1] return if len(pl) > 1: print "Multiple processes found for %s" % sys.argv[1] for p,n in pl: print "\t%s: %s" % (HexDump.integer(p),n) return pid = pl[0][0].get_pid() try: address = HexInput.integer(sys.argv[2]) except Exception: print "Invalid value for address: %s" % sys.argv[2] return filename = ' '.join(sys.argv[3:]) if os.path.exists(filename): data = open(filename, 'rb').read() print "Read %d bytes from %s" % (len(data), filename) else: try: data = HexInput.hexadecimal(filename) except Exception: print "Invalid filename or hex block: %s" % filename return p = Process(pid) p.write(address, data) print "Written %d bytes to PID %d" % (len(data), pid)
def print_threads_and_modules( pid ): # Instance a Process object. process = Process( pid ) print "Process %d" % process.get_pid() # Now we can enumerate the threads in the process... print "Threads:" for thread in process.iter_threads(): print "\t%d" % thread.get_tid() # ...and the modules in the process. print "Modules:" bits = process.get_bits() for module in process.iter_modules(): print "\t%s\t%s" % ( HexDump.address( module.get_base(), bits ), module.get_filename() )
def action_callback( event ): process = event.get_process() thread = event.get_thread() # Get the address of the top of the stack. stack = thread.get_sp() # Get the return address of the call. address = process.read_pointer( stack ) # Get the process and thread IDs. pid = event.get_pid() tid = event.get_tid() # Show a message to the user. message = "kernel32!CreateFileW called from %s by thread %d at process %d" print message % ( HexDump.address(address, process.get_bits()), tid, pid )
def show_window_tree( window, indent = 0 ): # Show this window's handle and caption. # Use some ASCII art to show the layout. :) handle = HexDump.integer( window.get_handle() ) caption = window.get_text() line = "" if indent > 0: print "| " * indent line = "| " * (indent - 1) + "|---" else: print "|" if caption is not None: line += handle + ": " + caption else: line += handle print line # Recursively show the child windows. for child in window.get_children(): show_window_tree( child, indent + 1 )
def print_alnum_jump_addresses(pid): # Request debug privileges so we can inspect the memory of services too. System.request_debug_privileges() # Suspend the process so there are no malloc's and free's while iterating. process = Process(pid) process.suspend() try: # For each executable alphanumeric address... for address, packed, module in iterate_alnum_jump_addresses(process): # Format the address for printing. numeric = HexDump.address(address, process.get_bits()) ascii = repr(packed) # Format the module name for printing. if module: modname = module.get_name() else: modname = "" # Try to disassemble the code at this location. try: code = process.disassemble(address, 16)[0][2] except NotImplementedError: code = "" # Print it. print numeric, ascii, modname, code # Resume the process when we're done. # This is inside a "finally" block, so if the program is interrupted # for any reason we don't leave the process suspended. finally: process.resume()
def print_threads_and_modules( pid, debug ): # Instance a Process object. process = Process( pid ) print "Process %d" % process.get_pid() # Now we can enumerate the threads in the process... print "Threads:" for thread in process.iter_threads(): print "\t%d" % thread.get_tid() # ...and the modules in the process. print "Modules:" bits = process.get_bits() for module in process.iter_modules(): print "\thas module: %s\t%s" % ( HexDump.address( module.get_base(), bits ), module.get_filename() ) print "Breakpoints:" for i in debug.get_all_breakpoints(): bp = i[2] print "breakpoint: %s %x" % (bp.get_state_name(), bp.get_address())
def openProc(pid): ''' return proc maps ''' process = Process(pid) fileName = process.get_filename() memoryMap = process.get_memory_map() mappedFilenames = process.get_mapped_filenames() # 08048000-080b0000 r-xp 0804d000 fe:01 3334030 /usr/myfile lines = [] for mbi in memoryMap: if not mbi.is_readable(): continue addr = '' perm = '--- ' offset = '' device = '' inode = '' filename = '' # Address and size of memory block. BaseAddress = HexDump.address(mbi.BaseAddress) RegionSize = HexDump.address(mbi.RegionSize) # State (free or allocated). mbiState = mbi.State if mbiState == win32.MEM_RESERVE: State = "Reserved" elif mbiState == win32.MEM_COMMIT: State = "Commited" elif mbiState == win32.MEM_FREE: State = "Free" else: State = "Unknown" # Page protection bits (R/W/X/G). if mbiState != win32.MEM_COMMIT: Protect = "--- " else: mbiProtect = mbi.Protect if mbiProtect & win32.PAGE_NOACCESS: Protect = "--- " elif mbiProtect & win32.PAGE_READONLY: Protect = "R-- " elif mbiProtect & win32.PAGE_READWRITE: Protect = "RW- " elif mbiProtect & win32.PAGE_WRITECOPY: Protect = "RC- " elif mbiProtect & win32.PAGE_EXECUTE: Protect = "--X " elif mbiProtect & win32.PAGE_EXECUTE_READ: Protect = "R-X " elif mbiProtect & win32.PAGE_EXECUTE_READWRITE: Protect = "RWX " elif mbiProtect & win32.PAGE_EXECUTE_WRITECOPY: Protect = "RCX " else: Protect = "??? " ''' if mbiProtect & win32.PAGE_GUARD: Protect += "G" #else: # Protect += "-" if mbiProtect & win32.PAGE_NOCACHE: Protect += "N" #else: # Protect += "-" if mbiProtect & win32.PAGE_WRITECOMBINE: Protect += "W" #else: # Protect += "-" ''' perm = Protect # Type (file mapping, executable image, or private memory). mbiType = mbi.Type if mbiType == win32.MEM_IMAGE: Type = "Image" elif mbiType == win32.MEM_MAPPED: Type = "Mapped" elif mbiType == win32.MEM_PRIVATE: Type = "Private" elif mbiType == 0: Type = "" else: Type = "Unknown" log.debug(BaseAddress) addr = '%08x-%08x' % (int(BaseAddress, 16), int(BaseAddress, 16) + int(RegionSize, 16)) perm = perm.lower() offset = '00000000' device = 'fe:01' inode = 24422442 filename = mappedFilenames.get(mbi.BaseAddress, ' ') # 08048000-080b0000 r-xp 0804d000 fe:01 3334030 /usr/myfile lines.append( '%s %s %s %s %s %s\n' % (addr, perm, offset, device, inode, filename)) log.debug( '%s %s %s %s %s %s\n' % (addr, perm, offset, device, inode, filename)) ##generate_memory_snapshot(self, minAddr=None, maxAddr=None) return lines # process.suspend() # try: # snapshot = process.generate_memory_snapshot() # for mbi in snapshot: # print HexDump.hexblock(mbi.content, mbi.BaseAddress) # finally: # process.resume() # process.read_structure() process = Process(pid) fileName = process.get_filename() memoryMap = process.get_memory_map() mappedFilenames = process.get_mapped_filenames() if fileName: log.debug("MemoryHandler map for %d (%s):" % (pid, fileName)) else: log.debug("MemoryHandler map for %d:" % pid) log.debug('%d filenames' % len(mappedFilenames)) log.debug('') log.debug('%d memorymap' % len(memoryMap)) readable = 0 writeable = 0 executable = 0 private = 0 mapped = 0 image = 0 total = 0 for mbi in memoryMap: size = mbi.RegionSize if not mbi.is_free(): total += size if mbi.is_readable(): readable += size if mbi.is_writeable(): writeable += size if mbi.is_executable(): executable += size if mbi.is_private(): private += size if mbi.is_mapped(): mapped += size if mbi.is_image(): image += size width = len(str(total)) log.debug(" %%%ds bytes of readable memory" % width) % int(readable) log.debug(" %%%ds bytes of writeable memory" % width) % int(writeable) log.debug(" %%%ds bytes of executable memory" % width) % int(executable) log.debug(" %%%ds bytes of private memory" % width) % int(private) log.debug(" %%%ds bytes of mapped memory" % width) % int(mapped) log.debug(" %%%ds bytes of image memory" % width) % int(image) log.debug(" %%%ds bytes of total memory" % width) % int(total) log.debug('') return
def memory_search( process, bytes, ): # Search for the string in the process memory. for address in process.search_bytes( bytes ): # Print the memory address where it was found. print HexDump.address( address )
s = System() s.scan_processes() pl = s.find_processes_by_filename(sys.argv[1]) if not pl: print "Process not found: %s" % sys.argv[1] return if len(pl) > 1: print "Multiple processes found for %s" % sys.argv[1] for p, n in pl: print "\t%s: %s" % (p.get_pid(), n) return pid = pl[0][0].get_pid() s.clear() del s p = Process(pid) for address, size, data in p.strings(): if data.endswith("\0"): data = data[:-1] print "%s: %r" % (HexDump.address(address), data) if __name__ == "__main__": try: import psyco psyco.bind(main) except ImportError: pass main()
# POSSIBILITY OF SUCH DAMAGE. from winappdbg import System, HexDump import sys try: # Get the coordinates from the command line. x = int( sys.argv[1] ) y = int( sys.argv[2] ) # Get the window at the requested position. window = System.get_window_at( x, y ) # Get the window coordinates. rect = window.get_screen_rect() position = (rect.left, rect.top, rect.right, rect.bottom) size = (rect.right - rect.left, rect.bottom - rect.top) # Print the window information. print "Handle: %s" % HexDump.integer( window.get_handle() ) print "Caption: %s" % window.text print "Class: %s" % window.classname print "Style: %s" % HexDump.integer( window.style ) print "ExStyle: %s" % HexDump.integer( window.exstyle ) print "Position: (%i, %i) - (%i, %i)" % position print "Size: (%i, %i)" % size except WindowsError: print "No window at those coordinates!"
def print_memory_map( pid ): # Instance a Process object. process = Process( pid ) # Find out if it's a 32 or 64 bit process. bits = process.get_bits() # Get the process memory map. memoryMap = process.get_memory_map() # Now you could do this... # # from winappdbg import CrashDump # print CrashDump.dump_memory_map( memoryMap ), # # ...but let's do it the hard way: # For each memory block in the map... print "Address \tSize \tState \tAccess \tType" for mbi in memoryMap: # Address and size of memory block. BaseAddress = HexDump.address(mbi.BaseAddress, bits) RegionSize = HexDump.address(mbi.RegionSize, bits) # State (free or allocated). if mbi.State == win32.MEM_RESERVE: State = "Reserved " elif mbi.State == win32.MEM_COMMIT: State = "Commited " elif mbi.State == win32.MEM_FREE: State = "Free " else: State = "Unknown " # Page protection bits (R/W/X/G). if mbi.State != win32.MEM_COMMIT: Protect = " " else: ## Protect = "0x%.08x" % mbi.Protect if mbi.Protect & win32.PAGE_NOACCESS: Protect = "--- " elif mbi.Protect & win32.PAGE_READONLY: Protect = "R-- " elif mbi.Protect & win32.PAGE_READWRITE: Protect = "RW- " elif mbi.Protect & win32.PAGE_WRITECOPY: Protect = "RC- " elif mbi.Protect & win32.PAGE_EXECUTE: Protect = "--X " elif mbi.Protect & win32.PAGE_EXECUTE_READ: Protect = "R-X " elif mbi.Protect & win32.PAGE_EXECUTE_READWRITE: Protect = "RWX " elif mbi.Protect & win32.PAGE_EXECUTE_WRITECOPY: Protect = "RCX " else: Protect = "??? " if mbi.Protect & win32.PAGE_GUARD: Protect += "G" else: Protect += "-" if mbi.Protect & win32.PAGE_NOCACHE: Protect += "N" else: Protect += "-" if mbi.Protect & win32.PAGE_WRITECOMBINE: Protect += "W" else: Protect += "-" Protect += " " # Type (file mapping, executable image, or private memory). if mbi.Type == win32.MEM_IMAGE: Type = "Image " elif mbi.Type == win32.MEM_MAPPED: Type = "Mapped " elif mbi.Type == win32.MEM_PRIVATE: Type = "Private " elif mbi.Type == 0: Type = "Free " else: Type = "Unknown " # Print the memory block information. fmt = "%s\t%s\t%s\t%s\t%s" print fmt % ( BaseAddress, RegionSize, State, Protect, Type )
# * Redistributions in binary form must reproduce the above copyright # notice,this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. from winappdbg import System, HexDump # Create a system snaphot. system = System() # Now we can enumerate the top-level windows. for window in system.get_windows(): handle = HexDump.integer( window.get_handle() ) caption = window.get_text() if caption is not None: print "%s:\t%s" % ( handle, caption )