Пример #1
0
def injectmex64(pid, shellcode):
    from sys import platform

    if platform.startswith('win'):
        print("\nPtrace not working on windows machines ..\n")
        return False
    else:
        try:
            from ptrace.debugger.debugger import PtraceDebugger
            from ptrace.debugger.debugger import PtraceProcess
        except ImportError:
            print(
                "\nYou must install ptrace library before use this script.\n")
            return False
        else:
            try:
                dbg = PtraceDebugger()
                process = dbg.addProcess(int(pid), False)
                rip = process.getInstrPointer()
                bytes = process.writeBytes(
                    rip,
                    shellcode.replace("\\x", "").decode("hex"))
                process.setreg("rbx", 0)
                process.cont()
            except Exception as error:
                print(error)
                print("\nPlease do not forget report !\n")
            else:
                print("\nInject complate !\n")
Пример #2
0
def main():
    # Check the command line
    if len(argv) < 2:
        print("usage: %s program [arg1 arg2 ...]" % argv[0], file=stderr)
        print("   or: %s pid" % argv[0], file=stderr)
        exit(1)

    # Get the process identifier
    is_attached = False
    has_pid = False
    if len(argv) == 2:
        try:
            # User asked to attach a process
            pid = int(argv[1])
            has_pid = True
        except ValueError:
            pass

    if not has_pid:
        # User asked to create a new program and trace it
        arguments = argv[1:]
        pid = traceProgram(arguments)
        is_attached = True

    # Create the debugger and attach the process
    dbg = PtraceDebugger()
    process = dbg.addProcess(pid, is_attached)

    # Play with the process and then quit
    playWithProcess(process)
    dbg.quit()
Пример #3
0
    def _startServer(self):
        # create child via ptrace debugger
        # API: createChild(arguments[], no_stdout, env=None)
        logging.debug("START: " + str(
            serverutils.getInvokeTargetArgs(self.config, self.targetPort +
                                            1000)))
        self.pid = createChild(
            serverutils.getInvokeTargetArgs(self.config, self.targetPort),
            False,  # no_stdout
            None,
        )

        # Attach to the process with ptrace and let it run
        self.dbg = PtraceDebugger()
        self.proc = self.dbg.addProcess(self.pid, True)
        self.proc.cont()

        time.sleep(1)

        # i dont think this works here...
        # FIXME
        event = self.dbg.waitProcessEvent(blocking=False)
        if event is not None and type(event) == ProcessExit:
            logging.error("Started server, but it already exited: " +
                          str(event))
            return False

        return True
Пример #4
0
def fuzzProg(arguments, program):
  is_attached = False
  #create the debugger

  dbg = PtraceDebugger()
  #create list to fuzz the argument
  fuzzed = attack()
  
  index = 0
  fileProgName = program
  slashes = program.rfind('/') #if the user has put in the full program path
  if slashes!=-1:
    fileProgName = program[slashes+1:]
  filename = 'ErrorsIn' + fileProgName
  file = open(filename, 'w')

  #for fuzzing each argument in turn
  for arg in arguments:
    for fuzzedArg in fuzzed:
      toFuzz = [program, arg, fuzzedArg]
      pid = procFork(toFuzz)
      is_attached = True
      if len(toFuzz)==2:
        print "Fuzzing %s %s" % (toFuzz[0], toFuzz[1])
      elif len(toFuzz)>2:
        print "Fuzzing %s %s %s" % (toFuzz[0], toFuzz[1], toFuzz[2])
      error = fuzz(dbg, pid, is_attached, toFuzz)
      #if there's an error, print it to file
      if error != '':
        print error
        file.write(error)
  #make sure to close file after fuzzed
  file.close()
  #Quit the debugger after fuzzing everything  
  dbg.quit()
Пример #5
0
def injectmex64(pid, shellcode):
    from sys import platform

    if platform.startswith('win'):
        print ("\nPtrace not working on windows machines ..\n")
        return False
    else:
        try:
            from ptrace.debugger.debugger import PtraceDebugger
            from ptrace.debugger.debugger import PtraceProcess
        except ImportError: 
            print ("\nYou must install ptrace library before use this script.\n")
            return False
        else:
            try:
                dbg = PtraceDebugger()
                process = dbg.addProcess(int(pid), False)
                rip = process.getInstrPointer()
                bytes = process.writeBytes(rip, shellcode.replace("\\x", "").decode("hex"))
                process.setreg("rbx", 0)
                process.cont()
            except Exception as error:
                print (error)
                print ("\nPlease do not forget report !\n")
            else:
                print ("\nInject complate !\n")
Пример #6
0
def main():
    # Check the command line
    if len(argv) < 2:
        print("usage: %s program [arg1 arg2 ...]" % argv[0], file=stderr)
        print("   or: %s pid" % argv[0], file=stderr)
        exit(1)

    # Get the process identifier
    is_attached = False
    has_pid = False
    if len(argv) == 2:
        try:
            # User asked to attach a process
            pid = int(argv[1])
            has_pid = True
        except ValueError:
            pass

    if not has_pid:
        # User asked to create a new program and trace it
        arguments = argv[1:]
        pid = traceProgram(arguments)
        is_attached = True

    # Create the debugger and attach the process
    dbg = PtraceDebugger()
    process = dbg.addProcess(pid, is_attached)

    # Play with the process and then quit
    playWithProcess(process)
    dbg.quit()
Пример #7
0
 def __init__(self, pid):
     self.maps = []
     self.pid = pid
     self.current_ip = None
     self.tracer = PtraceDebugger()
     self.process = False
     self.attached = False
class TibiaProcess:
	ips = [
		"login01.tibia.com",
		"login02.tibia.com",
		"login03.tibia.com",
		"login04.tibia.com",
		"login05.tibia.com",
		"tibia01.cipsoft.com",
		"tibia02.cipsoft.com",
		"tibia03.cipsoft.com",
		"tibia04.cipsoft.com",
		"tibia05.cipsoft.com",
		"test.tibia.com",
		"test.cipsoft.com",
		"tibia2.cipsoft.com",
		"tibia1.cipsoft.com",
		"server.tibia.com",
		"server2.tibia.com"
	]

	rsas = (
		"124710459426827943004376449897985582167801707960697037164044904862948569380850421396904597686953877022394604239428185498284169068581802277612081027966724336319448537811441719076484340922854929273517308661370727105382899118999403808045846444647284499123164879035103627004668521005328367415259939915284902061793",
		"132127743205872284062295099082293384952776326496165507967876361843343953435544496682053323833394351797728954155097012103928360786959821132214473291575712138800495033169914814069637740318278150290733684032524174782740134357629699062987023311132821016569775488792221429527047321331896351555606801473202394175817"
	)

	ot_rsa = "109120132967399429278860960508995541528237502902798129123468757937266291492576446330739696001110603907230888610072655818825358503429057592827629436413108566029093628212635953836686562675849720620786279431090218017681061521755056710823876476444260558147179707119674283982419152118103759076030616683978566631413"

	def __init__(self, process):
		self.maps = []
		self.current_ip = None
		self.tracer = PtraceDebugger()
		self.process = self.tracer.addProcess(process.pid, False)
		self.maps.extend(self.process.readMappings()[0:4])

	def detach(self):
		self.process.detach()
		self.tracer.quit()

	def changeRsa(self):
		for rsa in self.rsas:
			for res in self.maps[0].search(bytes(rsa, 'utf-8')):
				print("RSA modified.", res)
				self.process.writeBytes(res, bytes(self.ot_rsa, 'utf-8'))

	def changeIp(self, newip):
		for ip in self.ips:
			for maps in self.maps:
				for res in maps.search(bytes(ip, 'utf-8')):
					print("Found: " + ip)
					self.process.writeBytes(res, bytes(newip, 'utf-8'))
					if len(ip) > len(newip):
						for offset in range(len(newip), len(ip)):
							self.process.writeBytes(res + offset, bytes('\x00', 'utf-8'))
					print("Writing: " + newip)

		self.ips.insert(0, newip)
Пример #9
0
    def start(self):
        pid = createChild(["/tmp/test"], False)
        debugger = PtraceDebugger()
        debugger.addProcess(pid, True)
        debugger.enableSysgood()
        process = debugger[pid]
        process.syscall()
        e = process.waitEvent()
        assert isinstance(e, ptrace_debugger.ProcessSignal)

        return debugger, process
Пример #10
0
def start(pid):
    # need to attach to the process with ptrace before you can read it's proc/$pid/maps
    # or be root I guess
    # https://unix.stackexchange.com/questions/6301/how-do-i-read-from-proc-pid-mem-under-linux
    # http://lkml.iu.edu/hypermail/linux/kernel/0505.0/0858.html
    dbg = PtraceDebugger()
    try:
        process = dbg.addProcess(pid, False)
    except:
        print("Could not attach to process {}".format(pid))
        return
    dump(process, pid)
    dbg.quit()
Пример #11
0
class Sniffer(object):
    def __init__(self, pid=None):
        self.sessions = {}
        self.connections = {}
        self.dbg = PtraceDebugger()
        self.processes = {}

    def __del__(self):
        for pid in dict(self.processes):
            self.deleteProcess(pid)
        self.dbg.quit()

    def tcp_handler(self, tcp):
        if tcp.nids_state == nids.NIDS_JUST_EST and tcp.addr[1][1] in PORTS:
            self.connections[tcp.addr] = Connection(self, tcp)
        elif tcp.nids_state == nids.NIDS_DATA:
            if tcp.addr not in self.connections:
                return

            connection = self.connections[tcp.addr]

            try:
                if tcp.client.count_new:
                    connection.handle_data(
                        connection.server,
                        tcp.client.data[:tcp.client.count_new])
                if tcp.server.count_new:
                    connection.handle_data(
                        connection.client,
                        tcp.server.data[:tcp.server.count_new])
            except Connection.InvalidDataException:
                del self.connections[tcp.addr]

        elif tcp.nids_state in (nids.NIDS_CLOSE, nids.NIDS_TIMEOUT,
                                nids.NIDS_RESET):
            if tcp.addr in self.connections:
                del self.connections[tcp.addr]

    def message_handler(self, message):
        pass

    def session_handler(self, session):
        pass

    def addProcess(self, pid):
        self.processes[pid] = self.dbg.addProcess(pid, False)
        self.processes[pid].cont()

    def deleteProcess(self, pid):
        self.dbg.deleteProcess(pid)
        del self.processes[pid]
Пример #12
0
def main():
    if len(argv) < 2:
        print(T.red("Error: No command given."))
        print("Usage: %s COMMAND [ARGUMENT]..." % argv[0])
        exit(1)

    # This is basically "shlex.join"
    command = " ".join([(("'%s'" % arg) if (" " in arg) else arg) for arg in argv[1:]])

    arguments = argv[1:]
    arguments[0] = locateProgram(arguments[0])

    try:
        pid = createChild(arguments, False)
    except Exception as error:
        print(T.red("Error executing %s: %s." % (T.bold(command) + T.red, error)))
        exit(1)

    debugger = PtraceDebugger()
    debugger.traceExec()
    try:
        debugger.traceFork()
    except DebuggerError:
        print(T.yellow("Warning: Running without traceFork support. " +
                       "Syscalls from subprocesses can not be intercepted."))

    process = debugger.addProcess(pid, True)
    prepareProcess(process)

    try:
        operations = get_operations(debugger)
    except Exception as error:
        print(T.red("Error tracing process: %s." % error))
        exit(1)
    except KeyboardInterrupt:
        print(T.yellow("%s terminated by keyboard interrupt." % (T.bold(command) + T.yellow)))
        exit(2)
    finally:
        # Cut down all processes no matter what happens
        # to prevent them from doing any damage
        debugger.quit()

    if operations:
        print("%s has prevented %s from performing %d file system operations:\n" %
              (T.bold("maybe"), T.bold(command), len(operations)))
        for operation in operations:
            print("  " + operation)
        try:
            choice = input("\nDo you want to rerun %s and permit these operations? [y/N] " % T.bold(command))
        except KeyboardInterrupt:
            choice = ""
        if choice.lower() == "y":
            call(argv[1:])
    else:
        print("%s has not detected any file system operations from %s." %
              (T.bold("maybe"), T.bold(command)))
Пример #13
0
def fuzzPOPmain(ip, port, username, password, toAttach, pid):
  if toAttach: #local service, being attached
    if int(pid)<0:
      print 'Invalid PID. Make sure is correct if you want to attach a local service'
      exit(1)
    else:
      #valid PID, so create debugger & attach it
      dbg=PtraceDebugger()
      process = dbg.addProcess(pid, is_attached)
      is_attached = True
      process.cont()      
  else: 
    process=''
  #last parameter of actualPOPfuzz here should be process, but turns out library cannot work like this. Perhaps due to way programs are implemented, or way operating systems. Either way it cannot actually work, meaning that a debugger will need to be manually attached to the running server.
  actualPOPfuzz(ip, port, username, password, '')
Пример #14
0
def findCipherContext():
  dbg=PtraceDebugger()
  process=dbg.addProcess(pid,is_attached=False)
  if process is None:
    log.error("Error initializing Process debugging for %d"% pid)
    sys.exit(-1)
  mappings=readProcessMappings(process)
  stack=process.findStack()
  for m in mappings:
    #if m.pathname != '[heap]':
    #  continue
    if not abouchet.hasValidPermissions(m):
      continue    
    print m,m.permissions
    abouchet.find_struct(process, m, ctypes_openssh.CipherContext, printme)
Пример #15
0
def main(argv=sys.argv):
    if len(argv) < 2:
        print(T.red("Error: No command given."))
        print("Usage: %s COMMAND [ARGUMENT]..." % argv[0])
        return 1

    # This is basically "shlex.join"
    command = " ".join([(("'%s'" % arg) if (" " in arg) else arg) for arg in argv[1:]])

    arguments = argv[1:]
    arguments[0] = locateProgram(arguments[0])

    try:
        pid = createChild(arguments, False)
    except Exception as error:
        print(T.red("Error executing %s: %s." % (T.bold(command) + T.red, error)))
        return 1

    debugger = PtraceDebugger()
    debugger.traceExec()
    try:
        debugger.traceFork()
    except DebuggerError:
        print(T.yellow("Warning: Running without traceFork support. " +
                       "Syscalls from subprocesses can not be intercepted."))

    process = debugger.addProcess(pid, True)
    prepareProcess(process)

    try:
        operations = get_operations(debugger)
    except Exception as error:
        print(T.red("Error tracing process: %s." % error))
        return 1
    except KeyboardInterrupt:
        print(T.yellow("%s terminated by keyboard interrupt." % (T.bold(command) + T.yellow)))
        return 2
    finally:
        # Cut down all processes no matter what happens
        # to prevent them from doing any damage
        debugger.quit()

    if operations:
        print("%s has prevented %s from performing %d file system operations:\n" %
              (T.bold("maybe"), T.bold(command), len(operations)))
        for operation in operations:
            print("  " + operation)
        try:
            choice = input("\nDo you want to rerun %s and permit these operations? [y/N] " % T.bold(command))
        except KeyboardInterrupt:
            choice = ""
            # Ctrl+C does not print a newline automatically
            print("")
        if choice.lower() == "y":
            subprocess.call(argv[1:])
    else:
        print("%s has not detected any file system operations from %s." %
              (T.bold("maybe"), T.bold(command)))
Пример #16
0
	def fuzz(self, arguments, address):
		self.arguments = arguments
   		self.address = address
		self.mem = None
		self.pid = traceProgram(self.arguments)
		self.is_attached = True
	
		self.dbg = PtraceDebugger()
		self.process = self.dbg.addProcess(self.pid, self.is_attached)
	
		self.process.createBreakpoint(self.address, None)
		self.process.setoptions(ptrace_bindings.PTRACE_O_TRACEFORK)
		
		self.mem = allocateMemory(self.process)
		
		playWithProcess(self.process)
		
		ip = self.process.getInstrPointer() - 1
		breakpoint = self.process.findBreakpoint(ip)
		if breakpoint:
		    print ("Stopped at %s" % breakpoint)
		    breakpoint.desinstall(set_ip=True)
		
		for length in range(0, 20):
			self.test_process = createCheckpoint(self.process)
			self.try_arg("a" * length)
			#self.test_process.terminate(True)
		
		self.dbg.quit()
Пример #17
0
class Sniffer(object):
	def __init__(self, pid=None):
		self.sessions = {}
		self.connections = {}
		self.dbg = PtraceDebugger()
		self.processes = {}
	
	def __del__(self):
		for pid in dict(self.processes):
			self.deleteProcess(pid)
		self.dbg.quit()
	
	def tcp_handler(self, tcp):	
		if tcp.nids_state == nids.NIDS_JUST_EST and tcp.addr[1][1] in PORTS:
			self.connections[tcp.addr] = Connection(self, tcp)
		elif tcp.nids_state == nids.NIDS_DATA:
			if tcp.addr not in self.connections:
				return
			
			connection = self.connections[tcp.addr]
			
			try:
				if tcp.client.count_new:
					connection.handle_data(connection.server, tcp.client.data[:tcp.client.count_new])
				if tcp.server.count_new:
					connection.handle_data(connection.client, tcp.server.data[:tcp.server.count_new])
			except Connection.InvalidDataException:
				del self.connections[tcp.addr]
		
		elif tcp.nids_state in (nids.NIDS_CLOSE, nids.NIDS_TIMEOUT, nids.NIDS_RESET):
			if tcp.addr in self.connections:
				del self.connections[tcp.addr]
	
	def message_handler(self, message):
		pass
	
	def session_handler(self, session):
		pass
	
	def addProcess(self, pid):
		self.processes[pid] = self.dbg.addProcess(pid, False)
		self.processes[pid].cont()
	
	def deleteProcess(self, pid):
		self.dbg.deleteProcess(pid)
		del self.processes[pid]
Пример #18
0
class CPtraceDumper:
    """ Ptrace Dumper """

    # Output base file
    outFile = None
    # Pid of the process to dump
    pid = None

    # PtraceDebugger instance
    dbg = None
    # Process name
    processName = None

    def __init__(self, pid, outFile):
        """ Set the pid and the base output filename """
        self.pid = pid
        self.outFile = outFile

    def dump(self):
        """ Dump the memory """
        self.dbg = PtraceDebugger()
        #print "Created object"
        try:
            self.dbg.addProcess(self.pid, False)
            #print "Attached to process"
        except:
            #print "Error adding process", sys.exc_info()[1]
            pass
        try:
            #print "Resolving process's name"
            self.processName = getProcessName(self.pid)
            #print "Resolving segmnents"
            segments = getMemorySegments(self.pid, True)
            #print "SEGMENTS:", segments
            #print "Now dumping memory"
            dumpProcessMemory(self.pid, self.outFile, segments, True)
        except:
            pass
            #print "Exception in self.dump"
            #print sys.exc_info()[1]
            #raise

    def quit(self):
        """ Exit from ptrace debugger """
        #print "Quiting from ptrace debugger"
        self.dbg.quit()
Пример #19
0
class Fuzz(object):

	def try_arg(self, str_argument):
	
		print "Trying argument %s" % str_argument
	
		process = self.test_process
		new_str_addr = self.mem + 0x100
		arg_addr = process.getreg("esp") + 4
		arg = process.readWord(arg_addr)
		process.writeBytes(new_str_addr, str_argument)
		process.writeWord(arg_addr, new_str_addr)
		arg = process.readWord(arg_addr)
		playWithProcess(process)
	
	
	def fuzz(self, arguments, address):
		self.arguments = arguments
   		self.address = address
		self.mem = None
		self.pid = traceProgram(self.arguments)
		self.is_attached = True
	
		self.dbg = PtraceDebugger()
		self.process = self.dbg.addProcess(self.pid, self.is_attached)
	
		self.process.createBreakpoint(self.address, None)
		self.process.setoptions(ptrace_bindings.PTRACE_O_TRACEFORK)
		
		self.mem = allocateMemory(self.process)
		
		playWithProcess(self.process)
		
		ip = self.process.getInstrPointer() - 1
		breakpoint = self.process.findBreakpoint(ip)
		if breakpoint:
		    print ("Stopped at %s" % breakpoint)
		    breakpoint.desinstall(set_ip=True)
		
		for length in range(0, 20):
			self.test_process = createCheckpoint(self.process)
			self.try_arg("a" * length)
			#self.test_process.terminate(True)
		
		self.dbg.quit()
Пример #20
0
def fuzzFTPmain(ip, port, username, password, toAttach, pid):
  is_attached = False
  if toAttach:
    if int(pid)>=0:
      #valid PID, so create debugger & attach it
      dbg=PtraceDebugger()
      process = dbg.addProcess(pid, is_attached)
      print 'Attaching debugger...'
      is_attached = True
      process.cont()
    else:
      print 'If connecting a server, need a valid PID, otherwise set 4th arguments to False'
      exit(1)
  else: #not attaching
    process = ''
  #call to actualFTPfuzz should have process as last argument, but turns out the library will not work like that, making it impossible to implement as I would've liked. This means a debugger will have to be physically attached. 
  actualFTPfuzz(True, username, password, port, ip, '')
  actualFTPfuzz(False, username, password, port, ip, '')
Пример #21
0
def main():
    sys.argv = sys.argv[1:]
    filter_scopes = SYSCALL_FILTERS.keys()
    syscall_filters = {}

    for filter_scope in SYSCALL_FILTERS:
        if filter_scope in filter_scopes:
            for syscall in SYSCALL_FILTERS[filter_scope]:
                syscall_filters[syscall] = SYSCALL_FILTERS[filter_scope][
                    syscall]

    # Suppress logging output from python-ptrace
    getLogger().addHandler(NullHandler())

    # Prevent python-ptrace from decoding arguments to keep raw numerical values
    DIRFD_ARGUMENTS.clear()
    SYSCALL_ARG_DICT.clear()
    ARGUMENT_CALLBACK.clear()

    try:
        sys.argv[0] = locateProgram(sys.argv[0])
        pid = createChild(sys.argv, False)
    except Exception as error:
        print(f"Error executing {sys.argv}: {error}.")
        return 1

    debugger = PtraceDebugger()
    debugger.traceFork()
    debugger.traceExec()

    process = debugger.addProcess(pid, True)
    process.syscall()

    try:
        operations = get_operations(debugger, syscall_filters, True)
    except Exception as error:
        print(f"Error tracing process: {error}.")
        return 1
    finally:
        # Cut down all processes no matter what happens
        # to prevent them from doing any damage
        debugger.quit()

    if operations:
        for operation in operations:
            print("  " + operation)
    else:
        print(f"Not detected any file system operations from: {sys.argv}")
Пример #22
0
 def dump(self):
     """ Dump the memory """
     self.dbg = PtraceDebugger()
     #print "Created object"
     try:
         self.dbg.addProcess(self.pid, False)
         #print "Attached to process"
     except:
         #print "Error adding process", sys.exc_info()[1]
         pass
     try:
         #print "Resolving process's name"
         self.processName = getProcessName(self.pid)
         #print "Resolving segmnents"
         segments = getMemorySegments(self.pid, True)
         #print "SEGMENTS:", segments
         #print "Now dumping memory"
         dumpProcessMemory(self.pid, self.outFile, segments, True)
     except:
         pass
Пример #23
0
def readRsa(addr):
  dbg=PtraceDebugger()
  process=dbg.addProcess(PID, is_attached=False)
  if process is None:
    log.error("Error initializing Process debugging for %d"% PID)
    sys.exit(-1)
  # read where it is
  ######################### RAAAAAAAAAAAAH
  rsa=ctypes_openssl.RSA.from_buffer_copy(process.readStruct(addr,ctypes_openssl.RSA))
  mappings=readProcessMappings(process)
  print "isValid : ", rsa.isValid(mappings)
  #rsa.printValid(maps)
  print rsa
  #print rsa.n
  #print rsa.n.contents
  #print ctypes.byref(rsa.n.contents)
  #print rsa
  print '------------ === Loading members'
  ret=rsa.loadMembers(process,mappings)
  print '------------ === Loading members finished'
  print ret,rsa
  return rsa
Пример #24
0
def readDsa(addr):
  dbg=PtraceDebugger()
  process=dbg.addProcess(PID, is_attached=False)
  if process is None:
    log.error("Error initializing Process debugging for %d"% pid)
    sys.exit(-1)
  # read where it is
  dsa=ctypes_openssl.DSA.from_buffer_copy(process.readStruct(addr,ctypes_openssl.DSA))
  mappings=readProcessMappings(process)
  print "isValid : ", dsa.isValid(mappings)
  #dsa.printValid(maps)
  #print 'DSA1 -> ', dsa
  #print '------------'
  #print 'DSA1.q -> ', dsa.q
  print '------------ === Loading members'
  dsa.loadMembers(process,mappings)
  #print '------------  ===== ==== '
  #print 'DSA2.q -> ', dsa.q
  #print 'DSA2.q.contents -> ', dsa.q.contents
  #print ctypes.byref(rsa.n.contents)
  #print dsa
  return dsa
Пример #25
0
def main():
  parser = argparse.ArgumentParser(
      description='Utility to reset user\'s health to full.')
  parser.add_argument('pid', nargs='?', type=int,
      help='Specify the PID of the game')

  args = parser.parse_args()

  pid = args.pid
  if not pid:
    pid = find_hack_pid()

  if pid == -1:
    logging.error('Unable to find hack process to attach to.')
    return

  dbg = PtraceDebugger()
  proc = dbg.addProcess(pid, False)

  # Read the value for full health, need just the lower 4 bytes
  full_hp = proc.readWord(0x6425a0) & 0xffffffff

  # Value is (curr hp, ???)
  value = proc.readWord(0x642598)

  curr_hp = value >> 32

  logging.info('Changing health from %d -> %d', curr_hp, full_hp)

  # Calculate the new value to write back
  value = (full_hp << 32) + (value & 0xffffffff)

  # Write the new value
  proc.writeWord(0x642598, value)

  dbg.quit()
Пример #26
0
def main(argv=sys.argv[1:]):
    if PY2:
        argv = [unicode(arg, sys.getfilesystemencoding()) for arg in argv]  # noqa

    # Insert positional argument separator, if not already present
    if "--" not in argv:
        for i, argument in enumerate(argv):
            if not argument.startswith("-"):
                argv.insert(i, "--")
                break

    arg_parser = ArgumentParser(
        prog="maybe",
        usage="%(prog)s [options] command [argument ...]",
        description="Run a command without the ability to make changes to your system " +
                    "and list the changes it would have made.",
        epilog="For more information, to report issues or to contribute, " +
               "visit https://github.com/p-e-w/maybe.",
    )
    arg_parser.add_argument("command", nargs="+", help="the command to run under maybe's control")
    arg_group = arg_parser.add_mutually_exclusive_group()
    arg_group.add_argument("-a", "--allow", nargs="+", metavar="OPERATION",
                           help="allow the command to perform the specified operation(s). " +
                                "all other operations will be denied. " +
                                "possible values for %(metavar)s are: " +
                                ", ".join(sorted(SYSCALL_FILTERS.keys())) +
                                "; as well as any filter scopes defined by loaded plugins")
    arg_group.add_argument("-d", "--deny", nargs="+", metavar="OPERATION",
                           help="deny the command the specified operation(s). " +
                                "all other operations will be allowed. " +
                                "see --allow for a list of possible values for %(metavar)s. " +
                                "--allow and --deny cannot be combined")
    arg_parser.add_argument("-p", "--plugin", nargs="+", metavar="FILE",
                            help="load the specified plugin script(s). " +
                                 "see the README for details and plugin API documentation")
    arg_parser.add_argument("-l", "--list-only", action="store_true",
                            help="list operations without header, indentation and rerun prompt")
    arg_parser.add_argument("--style-output", choices=["yes", "no", "auto"], default="auto",
                            help="colorize output using ANSI escape sequences (yes/no) " +
                                 "or automatically decide based on whether stdout is a terminal (auto, default)")
    arg_parser.add_argument("-v", "--verbose", action="count",
                            help="if specified once, print every filtered syscall. " +
                                 "if specified twice, print every syscall, highlighting filtered syscalls")
    arg_parser.add_argument("--version", action="version", version="%(prog)s 0.4.0")
    args = arg_parser.parse_args(argv)

    initialize_terminal(args.style_output)

    if args.plugin is not None:
        for plugin_path in args.plugin:
            try:
                module_name = splitext(basename(plugin_path))[0]
                # Note: imp.load_source is *long* deprecated and not even documented
                # in Python 3 anymore, but it still seems to work and the "alternatives"
                # (see http://stackoverflow.com/a/67692) are simply too insane to use
                load_source(module_name, plugin_path)
            except Exception as error:
                print(T.red("Error loading %s: %s." % (T.bold(plugin_path) + T.red, error)))
                return 1

    if args.allow is not None:
        for filter_scope in args.allow:
            if filter_scope not in SYSCALL_FILTERS:
                print(T.red("Unknown operation in --allow: %s." % (T.bold(filter_scope) + T.red)))
                return 1
        filter_scopes = set(SYSCALL_FILTERS.keys()) - set(args.allow)
    elif args.deny is not None:
        for filter_scope in args.deny:
            if filter_scope not in SYSCALL_FILTERS:
                print(T.red("Unknown operation in --deny: %s." % (T.bold(filter_scope) + T.red)))
                return 1
        filter_scopes = args.deny
    else:
        filter_scopes = SYSCALL_FILTERS.keys()

    syscall_filters = {}

    for filter_scope in SYSCALL_FILTERS:
        if filter_scope in filter_scopes:
            for syscall in SYSCALL_FILTERS[filter_scope]:
                syscall_filters[syscall] = SYSCALL_FILTERS[filter_scope][syscall]

    # Suppress logging output from python-ptrace
    getLogger().addHandler(NullHandler())

    # Prevent python-ptrace from decoding arguments to keep raw numerical values
    DIRFD_ARGUMENTS.clear()
    SYSCALL_ARG_DICT.clear()
    ARGUMENT_CALLBACK.clear()

    # This is basically "shlex.join"
    command = " ".join([(("'%s'" % arg) if (" " in arg) else arg) for arg in args.command])

    try:
        args.command[0] = locateProgram(args.command[0])
        pid = createChild(args.command, False)
    except Exception as error:
        print(T.red("Error executing %s: %s." % (T.bold(command) + T.red, error)))
        return 1

    debugger = PtraceDebugger()
    debugger.traceFork()
    debugger.traceExec()

    process = debugger.addProcess(pid, True)
    process.syscall()

    try:
        operations = get_operations(debugger, syscall_filters, args.verbose)
    except Exception as error:
        print(T.red("Error tracing process: %s." % error))
        return 1
    except KeyboardInterrupt:
        print(T.yellow("%s terminated by keyboard interrupt." % (T.bold(command) + T.yellow)))
        return 2
    finally:
        # Cut down all processes no matter what happens
        # to prevent them from doing any damage
        debugger.quit()

    if operations:
        if not args.list_only:
            print("%s has prevented %s from performing %d file system operations:\n" %
                  (T.bold("maybe"), T.bold(command), len(operations)))
        for operation in operations:
            print(("" if args.list_only else "  ") + operation)
        if not args.list_only:
            print("\nDo you want to rerun %s and permit these operations? [y/N] " % T.bold(command), end="")
            try:
                choice = input()
            except KeyboardInterrupt:
                choice = ""
                # Ctrl+C does not print a newline automatically
                print("")
            if choice.lower() == "y":
                subprocess.call(args.command)
    else:
        print("%s has not detected any file system operations from %s." %
              (T.bold("maybe"), T.bold(command)))
Пример #27
0
def attach(pid):
    print "%s{+} Attaching to %s %s" % (cyan, pid, clear)
    dbg = PtraceDebugger()
    process = dbg.addProcess(int(pid), False)
    return process
Пример #28
0
 def __init__(self, pid) :
     self.tracer = PtraceProcess(PtraceDebugger(), pid, True)
Пример #29
0
def doFuzz(config,
           setupEnvironment=_setupEnvironment,
           chooseInput=_chooseInput,
           generateSeed=_generateSeed,
           runFuzzer=_runFuzzer,
           runTarget=_runTarget,
           checkForCrash=_checkForCrash,
           handleOutcome=_handleOutcome):
    seed = 0
    count = 0
    haveOutcome = False
    outcome = None
    done = False

    # Step 1: Setup environment
    setupEnvironment(config)

    print "Running fuzzer:", config["fuzzer"]

    sys.stdout.write("%8d: " % (0))
    sys.stdout.flush()

    while not done:
        # Step 2: Choose an input
        inFile = chooseInput(config)

        # We're done if no input is returned
        if inFile is None:
            print "\nNo more inputs, exiting."
            break

        # Step 3: Generate a seed
        seed = generateSeed(config)

        # Generate a name for the output file
        outExt = os.path.splitext(inFile)[1]
        outFile = os.path.join(os.getcwd(), str(seed) + outExt)

        # Step 4: Run fuzzer
        runFuzzer(config, inFile, seed, outFile, count)

        # Step 5: Run the target
        pid = runTarget(config, outFile)

        #######################################################################
        # This is where the magic happens. We monitor the process to determine
        # if it has crashed
        # Attach to the process with ptrace
        dbg = PtraceDebugger()
        proc = dbg.addProcess(pid, True)
        proc.cont()

        # Calculate the maximum time the target will be allowed to run
        endTime = time.time() + config["target_timeout"]

        outcome = None
        while True:
            try:
                # Check if there is an event pending for the target applicaiton
                # This will return immediately with either an event or None if
                # there is no event. We do this so we can kill the target after
                # it reaches the timeout
                event = dbg.waitProcessEvent(blocking=False)

                # Check if the process exited
                if type(event) == ProcessExit:
                    # Step 6: Check for crash
                    outcome = checkForCrash(config, event)

                    # The target application exited so we're done here
                    break

                elif type(event) == ProcessSignal:
                    # SIGCHLD simply notifies the parent that one of it's
                    # children processes has exited or changed (exec another
                    # process). It's not a bug so we tell the process to
                    # continue and we loop again to get the next event
                    if event.signum == SIGCHLD:
                        event.process.cont()
                        continue

                    outcome = checkForCrash(config, event)
                    break

            except KeyboardInterrupt:
                done = True
                break

            # Check if the process has reached the timeout
            if time.time() >= endTime:
                break
            else:
                # Give the CPU some timeslices to run other things
                time.sleep(0.1)

        # Step 7: Handle any crashes
        if outcome is not None:
            handleOutcome(config, outcome, inFile, seed, outFile, count)

            haveOutcome = True

        # Done with the process
        proc.terminate()

        # Delete the output
        try:
            os.remove(outFile)
        except:
            print "Failed to remove file %s!" % outFile

        # Update the counter and display the visual feedback
        count += 1
        if count % 2 == 0:
            if haveOutcome:
                sys.stdout.write("!")
                haveOutcome = False
            else:
                sys.stdout.write(".")

            sys.stdout.flush()

        if count % 100 == 0:
            sys.stdout.write("\n%8d: " % count)
            sys.stdout.flush()
Пример #30
0
def main(argv=sys.argv[1:]):
    filter_scopes = sorted(SYSCALL_FILTERS.keys())

    # Insert positional argument separator, if not already present
    if "--" not in argv:
        for i, argument in enumerate(argv):
            if not argument.startswith("-"):
                argv.insert(i, "--")
                break

    arg_parser = ArgumentParser(
        prog="maybe",
        usage="%(prog)s [options] command [argument ...]",
        description=
        "Run a command without the ability to make changes to your system " +
        "and list the changes it would have made.",
        epilog="For more information, to report issues or to contribute, " +
        "visit https://github.com/p-e-w/maybe.",
    )
    arg_parser.add_argument("command",
                            nargs="+",
                            help="the command to run under maybe's control")
    arg_group = arg_parser.add_mutually_exclusive_group()
    arg_group.add_argument(
        "-a",
        "--allow",
        nargs="+",
        choices=filter_scopes,
        metavar="OPERATION",
        help="allow the command to perform the specified operation(s). " +
        "all other operations will be denied. " +
        "possible values for %(metavar)s are: %(choices)s")
    arg_group.add_argument(
        "-d",
        "--deny",
        nargs="+",
        choices=filter_scopes,
        metavar="OPERATION",
        help="deny the command the specified operation(s). " +
        "all other operations will be allowed. " +
        "see --allow for a list of possible values for %(metavar)s. " +
        "--allow and --deny cannot be combined")
    arg_parser.add_argument(
        "-l",
        "--list-only",
        action="store_true",
        help="list operations without header, indentation and rerun prompt")
    arg_parser.add_argument(
        "--style-output",
        choices=["yes", "no", "auto"],
        default="auto",
        help="colorize output using ANSI escape sequences (yes/no) " +
        "or automatically decide based on whether stdout is a terminal (auto, default)"
    )
    arg_parser.add_argument(
        "-v",
        "--verbose",
        action="count",
        help="if specified once, print every filtered syscall. " +
        "if specified twice, print every syscall, highlighting filtered syscalls"
    )
    arg_parser.add_argument("--version",
                            action="version",
                            version="%(prog)s 0.4.0")
    args = arg_parser.parse_args(argv)

    initialize_terminal(args.style_output)

    if args.allow is not None:
        filter_scopes = set(filter_scopes) - set(args.allow)
    elif args.deny is not None:
        filter_scopes = args.deny

    syscall_filters = {}

    for filter_scope in filter_scopes:
        for syscall in SYSCALL_FILTERS[filter_scope]:
            syscall_filters[syscall] = SYSCALL_FILTERS[filter_scope][syscall]

    # Prevent python-ptrace from decoding arguments to keep raw numerical values
    DIRFD_ARGUMENTS.clear()
    SYSCALL_ARG_DICT.clear()
    ARGUMENT_CALLBACK.clear()

    # This is basically "shlex.join"
    command = " ".join([(("'%s'" % arg) if (" " in arg) else arg)
                        for arg in args.command])

    try:
        args.command[0] = locateProgram(args.command[0])
        pid = createChild(args.command, False)
    except Exception as error:
        print(
            T.red("Error executing %s: %s." %
                  (T.bold(command) + T.red, error)))
        return 1

    debugger = PtraceDebugger()
    debugger.traceFork()
    debugger.traceExec()

    process = debugger.addProcess(pid, True)
    process.syscall()

    try:
        operations = get_operations(debugger, syscall_filters, args.verbose)
    except Exception as error:
        print(T.red("Error tracing process: %s." % error))
        return 1
    except KeyboardInterrupt:
        print(
            T.yellow("%s terminated by keyboard interrupt." %
                     (T.bold(command) + T.yellow)))
        return 2
    finally:
        # Cut down all processes no matter what happens
        # to prevent them from doing any damage
        debugger.quit()

    if operations:
        if not args.list_only:
            print(
                "%s has prevented %s from performing %d file system operations:\n"
                % (T.bold("maybe"), T.bold(command), len(operations)))
        for operation in operations:
            print(("" if args.list_only else "  ") + operation)
        if not args.list_only:
            try:
                choice = input(
                    "\nDo you want to rerun %s and permit these operations? [y/N] "
                    % T.bold(command))
            except KeyboardInterrupt:
                choice = ""
                # Ctrl+C does not print a newline automatically
                print("")
            if choice.lower() == "y":
                subprocess.call(args.command)
    else:
        print("%s has not detected any file system operations from %s." %
              (T.bold("maybe"), T.bold(command)))
Пример #31
0
	def __init__(self, pid=None):
		self.sessions = {}
		self.connections = {}
		self.dbg = PtraceDebugger()
		self.processes = {}
Пример #32
0
	def __init__(self, process):
		self.maps = []
		self.current_ip = None
		self.tracer = PtraceDebugger()
		self.process = self.tracer.addProcess(process.pid, False)
		self.maps.extend(self.process.readMappings()[0:4])
Пример #33
0
pool = Pool(processes=1)
result = pool.apply_async(async_call)

while not isStarted:
    for pid in psutil.pids():
        if psutil.Process(pid).name() == 'hon-x86_64':
            hon_pid = pid
            isStarted = True
            print('isStarted == True\npid={}'.format(hon_pid))
            break
    time.sleep(10.0)
    print('sleeping...')

print('starting debugger')
dbg = PtraceDebugger()
process = dbg.addProcess(hon_pid, False)
memory_mapping = readProcessMappings(process)

print('found memory mappings')
_next = False
for addr in memory_mapping:
    if _next == True:
        for a in range(addr.start, addr.end, 4):
            value = bytesToFloat(process.readBytes(a, 4))
            if value == 1850.:
                print("value is {} at addr {}".format(value, hex(a)))
                process.writeBytes(a, floatToBytes(2400.))
        break

    if 'rw' in addr.permissions and addr.pathname and 'libgame_shared' in addr.pathname:
Пример #34
0
def main():
    if len(argv) < 2: usage()
 
    # create process
    env = None
    arguments = argv[1:]
    arguments[0] = locateProgram(arguments[0])
    pid = createChild(arguments, False, env)
 
    # create debugger
    debugger = PtraceDebugger()
    debugger.enableSysgood()
    debugger.traceExec()
    debugger.traceFork()
 
    # attach process
    debugger.addProcess(pid, True)
    process = debugger[pid]
    process.syscall()
 
    # start event loop
    loop(debugger)
 
    debugger.quit()
def attach(pid):
    print "%s{+} Attaching to %s %s" %(cyan, pid, clear)
    dbg = PtraceDebugger()
    process = dbg.addProcess(int(pid), False)
    return process
Пример #36
0
class DebugServerManager(ServerManager):
    def __init__(self, config, queue_sync, queue_out, targetPort):
        ServerManager.__init__(self, config, queue_sync, queue_out, targetPort)
        self.dbg = None
        self.crashEvent = None
        self.proc = None
        self.p = None

    def _startServer(self):
        # create child via ptrace debugger
        # API: createChild(arguments[], no_stdout, env=None)
        logging.debug("START: " + str(
            serverutils.getInvokeTargetArgs(self.config, self.targetPort +
                                            1000)))
        self.pid = createChild(
            serverutils.getInvokeTargetArgs(self.config, self.targetPort),
            False,  # no_stdout
            None,
        )

        # Attach to the process with ptrace and let it run
        self.dbg = PtraceDebugger()
        self.proc = self.dbg.addProcess(self.pid, True)
        self.proc.cont()

        time.sleep(1)

        # i dont think this works here...
        # FIXME
        event = self.dbg.waitProcessEvent(blocking=False)
        if event is not None and type(event) == ProcessExit:
            logging.error("Started server, but it already exited: " +
                          str(event))
            return False

        return True

    def _stopServer(self):
        try:
            self.dbg.quit()
            os.kill(self.pid, signal.SIGTERM)
        except:
            # is already dead...
            pass

    def _waitForCrash(self):
        #subprocess.call("echo AAA1; ls -l /proc/" + str(self.pid), shell=True)
        while True:
            logging.info("DebugServer: Waiting for process event")
            event = self.dbg.waitProcessEvent()
            logging.info("DebugServer: Got event: " + str(event))
            # If this is a process exit we need to check if it was abnormal
            if type(event) == ProcessExit:
                if event.signum is None or event.exitcode == 0:
                    # Clear the event since this was a normal exit
                    event = None

            # If this is a signal we need to check if we're ignoring it
            elif type(event) == ProcessSignal:
                if event.signum == signal.SIGCHLD:
                    # Ignore these signals and continue waiting
                    continue
                elif event.signum == signal.SIGTERM:
                    # server cannot be started, return
                    event = None
                    self.queue_sync.put(("err", event.signum))

            break

        if event is not None and event.signum != 15:
            logging.info("DebugServer: Event Result: Crash")
            #subprocess.call("echo AAA2; ls -l /proc/" + str(self.pid), shell=True)
            self.crashEvent = event
            return True
        else:
            logging.info("DebugServer: Event Result: No crash")
            self.crashEvent = None
            return False

    def _getCrashDetails(self):
        event = self.crashEvent
        # Get the address where the crash occurred
        faultAddress = 0
        try:
            faultAddress = event.process.getInstrPointer()
        except Exception as e:
            # process already dead, hmm
            print(("GetCrashDetails exception: " + str(e)))

        # Find the module that contains this address
        # Now we need to turn the address into an offset. This way when the process
        # is loaded again if the module is loaded at another address, due to ASLR,
        # the offset will be the same and we can correctly detect those as the same
        # crash
        module = None
        faultOffset = 0

        try:
            for mapping in event.process.readMappings():
                if faultAddress >= mapping.start and faultAddress < mapping.end:
                    module = mapping.pathname
                    faultOffset = faultAddress - mapping.start
                    break
        except Exception as error:
            print("getCrashDetails Exception: " + str(error))
            # it always has a an exception...
            pass

        # Apparently the address didn't fall within a mapping
        if module is None:
            module = "Unknown"
            faultOffset = faultAddress

        # Get the signal
        sig = event.signum

        # Get the details of the crash
        details = None

        details = ""
        stackAddr = 0
        stackPtr = 0
        backtraceFrames = None
        pRegisters = None
        try:
            if event._analyze() is not None:
                details = event._analyze().text

            # more data
            stackAddr = self.proc.findStack()
            stackPtr = self.proc.getStackPointer()

            # convert backtrace
            backtrace = self.proc.getBacktrace()
            backtraceFrames = []
            for frame in backtrace.frames:
                backtraceFrames.append(str(frame))

            # convert registers from ctype to python
            registers = self.proc.getregs()
            pRegisters = {}
            for field_name, field_type in registers._fields_:
                regName = str(field_name)
                regValue = str(getattr(registers, field_name))
                pRegisters[regName] = regValue

        except Exception as e:
            # process already dead, hmm
            print(("GetCrashDetails exception: " + str(e)))

        vCrashData = verifycrashdata.VerifyCrashData(
            faultAddress=faultAddress,
            faultOffset=faultOffset,
            module=module,
            sig=sig,
            details=details,
            stackPointer=stackPtr,
            stackAddr=str(stackAddr),
            backtrace=backtraceFrames,
            registers=pRegisters,
        )

        asanOutput = serverutils.getAsanOutput(self.config, self.pid)
        vCrashData.setTemp(asanOutput)

        return vCrashData
Пример #37
0
 def __init__(self, pid=None):
     self.sessions = {}
     self.connections = {}
     self.dbg = PtraceDebugger()
     self.processes = {}
Пример #38
0
def main(argv=sys.argv[1:]):
    filter_scopes = sorted(SYSCALL_FILTERS.keys())

    # Insert positional argument separator, if not already present
    if "--" not in argv:
        for i, argument in enumerate(argv):
            if not argument.startswith("-"):
                argv.insert(i, "--")
                break

    arg_parser = ArgumentParser(
        prog="maybe",
        usage="%(prog)s [options] command [argument ...]",
        description="Run a command without the ability to make changes to your system " +
                    "and list the changes it would have made.",
        epilog="For more information, to report issues or to contribute, " +
               "visit https://github.com/p-e-w/maybe.",
    )
    arg_parser.add_argument("command", nargs="+", help="the command to run under maybe's control")
    arg_group = arg_parser.add_mutually_exclusive_group()
    arg_group.add_argument("-a", "--allow", nargs="+", choices=filter_scopes, metavar="OPERATION",
                           help="allow the command to perform the specified operation(s). " +
                                "all other operations will be denied. " +
                                "possible values for %(metavar)s are: %(choices)s")
    arg_group.add_argument("-d", "--deny", nargs="+", choices=filter_scopes, metavar="OPERATION",
                           help="deny the command the specified operation(s). " +
                                "all other operations will be allowed. " +
                                "see --allow for a list of possible values for %(metavar)s. " +
                                "--allow and --deny cannot be combined")
    arg_parser.add_argument("-l", "--list-only", action="store_true",
                            help="list operations without header, indentation and rerun prompt")
    arg_parser.add_argument("--style-output", choices=["yes", "no", "auto"], default="auto",
                            help="colorize output using ANSI escape sequences (yes/no) " +
                                 "or automatically decide based on whether stdout is a terminal (auto, default)")
    arg_parser.add_argument("-v", "--verbose", action="count",
                            help="if specified once, print every filtered syscall. " +
                                 "if specified twice, print every syscall, highlighting filtered syscalls")
    arg_parser.add_argument("--version", action="version", version="%(prog)s 0.4.0")
    args = arg_parser.parse_args(argv)

    initialize_terminal(args.style_output)

    if args.allow is not None:
        filter_scopes = set(filter_scopes) - set(args.allow)
    elif args.deny is not None:
        filter_scopes = args.deny

    syscall_filters = {}

    for filter_scope in filter_scopes:
        for syscall_filter in SYSCALL_FILTERS[filter_scope]:
            syscall_filters[syscall_filter.syscall] = syscall_filter

    # Prevent python-ptrace from decoding arguments to keep raw numerical values
    DIRFD_ARGUMENTS.clear()
    SYSCALL_ARG_DICT.clear()
    ARGUMENT_CALLBACK.clear()

    # This is basically "shlex.join"
    command = " ".join([(("'%s'" % arg) if (" " in arg) else arg) for arg in args.command])

    try:
        args.command[0] = locateProgram(args.command[0])
        pid = createChild(args.command, False)
    except Exception as error:
        print(T.red("Error executing %s: %s." % (T.bold(command) + T.red, error)))
        return 1

    debugger = PtraceDebugger()
    debugger.traceExec()
    try:
        debugger.traceFork()
    except DebuggerError:
        print(T.yellow("Warning: Running without traceFork support. " +
                       "Syscalls from subprocesses can not be intercepted."))

    process = debugger.addProcess(pid, True)
    process.syscall()

    try:
        operations = get_operations(debugger, syscall_filters, args.verbose)
    except Exception as error:
        print(T.red("Error tracing process: %s." % error))
        return 1
    except KeyboardInterrupt:
        print(T.yellow("%s terminated by keyboard interrupt." % (T.bold(command) + T.yellow)))
        return 2
    finally:
        # Cut down all processes no matter what happens
        # to prevent them from doing any damage
        debugger.quit()

    if operations:
        if not args.list_only:
            print("%s has prevented %s from performing %d file system operations:\n" %
                  (T.bold("maybe"), T.bold(command), len(operations)))
        for operation in operations:
            print(("" if args.list_only else "  ") + operation)
        if not args.list_only:
            try:
                choice = input("\nDo you want to rerun %s and permit these operations? [y/N] " % T.bold(command))
            except KeyboardInterrupt:
                choice = ""
                # Ctrl+C does not print a newline automatically
                print("")
            if choice.lower() == "y":
                subprocess.call(args.command)
    else:
        print("%s has not detected any file system operations from %s." %
              (T.bold("maybe"), T.bold(command)))
Пример #39
0
def main(argv=sys.argv[1:]):
    # Insert positional argument separator, if not already present
    if "--" not in argv:
        for i, argument in enumerate(argv):
            if not argument.startswith("-"):
                argv.insert(i, "--")
                break

    arg_parser = ArgumentParser(
        prog="maybe",
        usage="%(prog)s [options] command [argument ...]",
        description="Run a command without the ability to make changes to your system " +
                    "and list the changes it would have made.",
        epilog="For more information, to report issues or to contribute, " +
               "visit https://github.com/p-e-w/maybe.",
    )
    arg_parser.add_argument("command", nargs="+", help="the command to run under maybe's control")
    arg_parser.add_argument("-l", "--list-only", action="store_true",
                            help="list operations without header, indentation and rerun prompt")
    arg_parser.add_argument("--style-output", choices=["yes", "no", "auto"], default="auto",
                            help="colorize output using ANSI escape sequences (yes/no) " +
                                 "or automatically decide based on whether stdout is a terminal (auto, default)")
    arg_parser.add_argument("-v", "--verbose", action="count",
                            help="if specified once, print every filtered syscall. " +
                                 "if specified twice, print every syscall, highlighting filtered syscalls")
    arg_parser.add_argument("--version", action="version", version="%(prog)s 0.4.0")
    args = arg_parser.parse_args(argv)

    initialize_terminal(args.style_output)

    # This is basically "shlex.join"
    command = " ".join([(("'%s'" % arg) if (" " in arg) else arg) for arg in args.command])

    try:
        args.command[0] = locateProgram(args.command[0])
        pid = createChild(args.command, False)
    except Exception as error:
        print(T.red("Error executing %s: %s." % (T.bold(command) + T.red, error)))
        return 1

    debugger = PtraceDebugger()
    debugger.traceExec()
    try:
        debugger.traceFork()
    except DebuggerError:
        print(T.yellow("Warning: Running without traceFork support. " +
                       "Syscalls from subprocesses can not be intercepted."))

    process = debugger.addProcess(pid, True)
    process.syscall()

    try:
        operations = get_operations(debugger, args)
    except Exception as error:
        print(T.red("Error tracing process: %s." % error))
        return 1
    except KeyboardInterrupt:
        print(T.yellow("%s terminated by keyboard interrupt." % (T.bold(command) + T.yellow)))
        return 2
    finally:
        # Cut down all processes no matter what happens
        # to prevent them from doing any damage
        debugger.quit()

    if operations:
        if not args.list_only:
            print("%s has prevented %s from performing %d file system operations:\n" %
                  (T.bold("maybe"), T.bold(command), len(operations)))
        for operation in operations:
            print(("" if args.list_only else "  ") + operation)
        if not args.list_only:
            try:
                choice = input("\nDo you want to rerun %s and permit these operations? [y/N] " % T.bold(command))
            except KeyboardInterrupt:
                choice = ""
                # Ctrl+C does not print a newline automatically
                print("")
            if choice.lower() == "y":
                subprocess.call(args.command)
    else:
        print("%s has not detected any file system operations from %s." %
              (T.bold("maybe"), T.bold(command)))