Beispiel #1
0
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)
Beispiel #2
0
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)
Beispiel #3
0
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()
Beispiel #4
0
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 )
Beispiel #6
0
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)
Beispiel #7
0
 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
Beispiel #9
0
    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
Beispiel #10
0
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
Beispiel #11
0
	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)
Beispiel #12
0
 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 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))
Beispiel #16
0
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
Beispiel #17
0
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)
Beispiel #18
0
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()
Beispiel #19
0
    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))
Beispiel #20
0
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)
Beispiel #21
0
 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
Beispiel #22
0
    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())
Beispiel #23
0
 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)
Beispiel #24
0
    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() )
Beispiel #25
0
    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')
Beispiel #27
0
	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
Beispiel #28
0
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)
Beispiel #29
0
    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
Beispiel #30
0
    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()
Beispiel #31
0
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
Beispiel #32
0
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 )
Beispiel #33
0
    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()
Beispiel #34
0
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)
Beispiel #35
0
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)
Beispiel #36
0
    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()
        )
Beispiel #37
0
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)
Beispiel #38
0
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),
Beispiel #39
0
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)
Beispiel #43
0
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))
Beispiel #44
0
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)
Beispiel #45
0
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()
    )
Beispiel #47
0
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 )
Beispiel #49
0
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()
Beispiel #50
0
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())
Beispiel #51
0
    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
Beispiel #52
0
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 )    
Beispiel #53
0
        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()
Beispiel #54
0
# 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!"
Beispiel #55
0
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 )