Ejemplo n.º 1
0
class GetKey:
    def __init__(self, printer, config, project, adb_path="adb"):
        self.printer = printer
        self.params = {
            "adbpath": {
                "description": "Path of the adb command",
                "value": adb_path,
                "required": True
            },
            "dumpfile": {
                "description":
                "Where to save the memory dumpfile with the filename",
                "value": "dumpfile",
                "required": True
            },
            "out_dir": {
                "description":
                "Where to generate the results and download files on the computer.",
                "value": "results",
                "required": True
            },
            "dekfile": {
                "description":
                "Where to generate the results and download files on the computer.",
                "value": "dek.bin",
                "required": True
            },
            "phonewithos": {
                "description": "The samsung hardware and the android version",
                "value": "GT-I9300 4.1.2",
                "required": True
            },
        }
        self.adb = ADB(self.params["adbpath"]["value"])
        self.out_dir = self.params["out_dir"]["value"]
        self.dumpfile = self.params["dumpfile"]["value"]
        self.dekfile = self.params["dekfile"]["value"]
        self.project = project

    def setparams(self, params):
        self.params = params
        self.adb = ADB(self.params["adbpath"]["value"])
        self.dumpfile = self.params["dumpfile"]["value"]
        self.dekfile = self.params["dekfile"]["value"]
        self.phone = self.params["phonewithos"]["value"]
        self.out_dir = self.params["out_dir"]["value"]

    def getparams(self):
        return self.params

    def get_vold_data_segment(self):
        self.printer.print_debug("Check for su!")
        su = checkforsu(self.adb)
        if (su == ""):
            self.printer.print_err(
                "The su comand was not found, hope adb have immediate root access!"
            )
            su = ""

        #No magic here, the phone should be fully booted for this module
        self.dest_dir = "/data/local/tmp"

        ps = self.adb.shell_command("su -c ps")
        for process in ps.splitlines():
            if (process.rfind("vold") != -1):
                process = re.sub("\s+", ' ', process)
                self.voldpid = process.split(' ')[1]

        self.printer.print_debug("Found vold process id: %s!" % self.voldpid)
        memsegments = self.adb.shell_command("su -c cat /proc/%s/maps" %
                                             self.voldpid).splitlines()
        for segment in memsegments:
            if (re.match(".*w-p.*vold.*", segment) != None):
                addresses = segment.split(" ")[0].split("-")
                self.datastart = addresses[0]
                self.dataend = addresses[1]
                self.numberofbytes = int(addresses[1], 16) - int(
                    addresses[0], 16)

        self.printer.print_debug("The data segment addresses are: %s - %s" %
                                 (self.datastart, self.dataend))

        self.printer.print_info("Copy the memory dumper to %s." %
                                (self.dest_dir))

        push = self.adb.push_local_file(
            "dump_android_memory/dump_android_memory", "%s" % self.dest_dir)
        if (push.find("bytes") == -1):
            self.print_info_adb(push, False)
            return -1

        self.printer.print_ok("Copy - Done")
        self.print_info_adb(push.rstrip("\n"))

        self.printer.print_info("Run the memory dumper.")

        dump = self.adb.shell_command(
            "su -c /data/local/tmp/dump_android_memory %s 0x%s %d %s/dumpfile"
            %
            (self.voldpid, self.datastart, self.numberofbytes, self.dest_dir))
        if (dump):
            self.printer.print_info_adb(dump, False)
            return -1
        self.printer.print_ok("Memory dumber - Done")

        self.printer.print_info("Download the dump file")

        pull = self.adb.get_remote_file(
            "/data/local/tmp/dumpfile",
            "%s/%s_%s" % (self.out_dir, self.project, self.dumpfile))
        if (pull.find("bytes") == -1):
            self.print_info_adb(pull, False)
            return -1

        self.printer.print_ok("Download - Done")
        self.print_info_adb(pull.rstrip("\n"))

        #Cleanup
        self.printer.print_info(
            "Cleaning up! Please check the %s folder. Unsuccessull cleanup weakens the security of the phone!!!!"
            % self.dest_dir)
        out = self.adb.shell_command(su + "rm %s/dumpfile" % self.dest_dir)
        out = self.adb.shell_command(su + "rm %s/dump_android_memory" %
                                     self.dest_dir)
        self.printer.print_ok("Clean up - Done")

    def getpin(self):
        buff = ""
        strings = self.strings("%s/%s_%s" %
                               (self.out_dir, self.project, self.dumpfile))
        self.printer.print_info(
            "Following strings found in the vold memory segment:")
        for entry in strings:
            #self.printer.print_info("  %s:%d" % (entry.string, entry.pos))
            self.printer.print_info("  %s" % (entry.string))
        self.printer.print_info(
            "Assuming the last one is the pin/password, let's find the DEK")
        last_entry = strings[len(strings) - 1]
        index = len(last_entry.string) + last_entry.pos
        try:
            f = open("%s/%s_%s" % (self.out_dir, self.project, self.dumpfile),
                     "rb")
            try:
                buff = f.read(4096)
            finally:
                f.close()
        except IOError as e:
            self.printer.print_err("I/O error({0}): {1} {2}".format(
                e.errno, e.strerror,
                "%s/%s_%s" % (self.out_dir, self.project, self.dumpfile)))
            return -1

        for i in range(index + 1, index + 200):
            if (buff[i] != '\0'):
                break

        #Because we search for the first non zero, the search can be broken.
        dek1 = buff[i:i + 32]
        self.printer.print_info("The first possible key is:")
        self.printer.print_ok(hexlify(dek1))
        dek2 = buff[i - 1:i - 1 + 32]
        self.printer.print_info("The second possible key is:")
        self.printer.print_ok(hexlify(dek2))

        self.printer.print_info("Creating two files:")
        self.printer.print_ok("%s/%s_%s.1" %
                              (self.out_dir, self.project, self.dekfile))
        self.printer.print_ok("%s/%s_%s.2" %
                              (self.out_dir, self.project, self.dekfile))

        self.printer.print_info(
            "If they are not working, analyze the dumpfile manually and you will find the key. It works for S2 and S3 until 4.1.2."
        )

        try:
            f = open("%s/%s_%s.1" % (self.out_dir, self.project, self.dekfile),
                     "wb")
            try:
                f.write(dek1)
            finally:
                f.close()
        except IOError as e:
            self.printer.print_err("I/O error({0}): {1} {2}/{3}_footer".format(
                e.errno, e.strerror, self.out_dir, self.project))
            return -1

        try:
            f = open("%s/%s_%s.2" % (self.out_dir, self.project, self.dekfile),
                     "wb")
            try:
                f.write(dek2)
            finally:
                f.close()
        except IOError as e:
            self.printer.print_err("I/O error({0}): {1} {2}/{3}_footer".format(
                e.errno, e.strerror, self.out_dir, self.project))
            return -1

        return 1

    def print_info_adb(self, message, ok=True):
        if (ok):
            self.printer.print_info("OK! Received the following from adb: %s" %
                                    message)
        else:
            self.printer.print_err(
                "ERROR! Received the following from adb: %s" % message)

    def strings(self, filename):
        pos = 0
        strings = []
        s_entry = namedtuple("s_entry", "string pos")
        printable = set(string.printable)
        found_str = ""
        fh = open(filename, "rb")
        data = fh.read(4096)
        fh.close()
        pos = 0
        for char in data:
            pos += 1
            if char in printable:
                found_str += char
            elif len(found_str) >= 4:
                strings.append(s_entry(found_str, pos))
                found_str = ""
            else:
                found_str = ""
        return strings
Ejemplo n.º 2
0
class SandS4GetEDK:


   def __init__(self, printer, config, project, adb_path="adb"):
      self.printer=printer
      self.config=config
      self.project=project
      self.params={"adbpath":{"description":"Path of the adb command",
			      "value":adb_path,
			      "required":True
			      },
		  "phonewithos":{"description":"The samsung hardware and the android version",
			      "value":"GT-I9505 4.3.2",
			      "required":True
			      },
		  "out_dir":{"description":"Where to generate the results and download files on the computer.",
			      "value":"results",
			      "required":True
			      },
		  }
      self.setparams(self.params)

   def setparams(self, params):
      self.params=params
      self.adb = ADB(self.params["adbpath"]["value"])
      self.phone = self.params["phonewithos"]["value"]
      self.out_dir = self.params["out_dir"]["value"]

   def getparams(self):
      return self.params

   def downloadforgdb(self,fullpath):
      
      """
      Downloads the fullpath for gdb. It puts the file in lib or in bin,
      Depends on the fullpath is a lib directory or not.
      """

      path, filename = os.path.split(fullpath)
      if(path.find("lib")!=-1):
         out=self.adb.get_remote_file(fullpath, "recovery/s4/system/lib/%s" % (filename))
      else:
         out=self.adb.get_remote_file(fullpath, "recovery/s4/system/bin/%s" % (filename))
      return out

   def write2john(self,edk):

      """
      Simple save the edk into the prject_sanddek.jtr file to jonh the ripper
      cracking
      """

      self.printer.print_info("This will be written to file %s/%s_sanddek.jtr, for jtr:" % (self.out_dir, self.project))
      self.printer.print_ok("%s_s4:%s" % (self.project, edk))
      try:
	 f= open("%s/%s_sanddek.jtr" % (self.out_dir, self.project), "a")
	 f.write("%s_s4:%s\n" % (self.project,  edk))
	 f.close()
      except IOError as e:
	 self.printer.print_err("I/O error({0}): {1}: {2}/{3}_sanddek.jtr".format(e.errno, e.strerror, self.out_dir, self.project))
	 return -1

   def write2footer(self,edk):

      """
      Save the EDK to a footer file. The we can use the mount modules, that
      uses the password
      """

      self.printer.print_info("Footer will be created: %s/%s_footer" % (self.out_dir, self.project))
      footer='\0'*0x84+unhexlify(edk)
      try:
	 f= open("%s/%s_footer" % (self.out_dir, self.project), "wb")
	 f.write(footer)
	 f.close()
      except IOError as e:
	 self.printer.print_err("I/O error({0}): {1}: {2}/{3}_footer".format(e.errno, e.strerror, self.out_dir, self.project))
	 return -1

   def cleanup(self, gdb=None, gdbserver=None):
      
      """
      Tries to gently stop gdb, kill gdbserver and delete it from /data/local/tmp or /tmp
      """
      
      if(gdb):
	 gdb.sendcontrol('c')
	 gdb.sendline("detach")
	 gdb.sendline("quit")
	 gdb.kill(0)
      if(gdbserver):
	 gdbserver.kill()
   
      self.adb.shell_command("rm /data/local/tmp/gdbserver")
      self.adb.shell_command("rm /tmp/gdbserver")
   

   def getedk(self):

      """
      Write the the help of the gdb and gdbserver, gets out the EDK on a S4.
      It puts a breakpoint on verify_EDK which is called when vdc cryptfs verifypw
      is called. The R0 register contains the EDK>
      """

      state=checkcryptostate(self.adb)
      if(state==""):
	 self.printer.print_err("The phone is not encrypted. ro.crypto.state is empty!")
	 return -1
      self.printer.print_debug("Check for su!")
      su=checkforsu(self.adb)
      if (su==""):
	 self.printer.print_err("The su comand was not found, hope adb have immediate root access!")
	 su=""
      
      self.printer.print_info("Downloading vold and libsec_km.so for gdb...")
      out=self.downloadforgdb("/system/bin/vold")
      if(out==None):
	 self.printer.print_err("Could not download vold! Exiting...")
	 return -1
      out=self.downloadforgdb("/system/lib/libsec_km.so")
      if(out==None):
	 self.printer.print_err("Could not download libsec_km.so! Exiting...")
	 return -1
      self.printer.print_ok("Download - Done")

      self.printer.print_debug("Check the destination directory!")
      dest_dir=""
      out=self.adb.shell_command(su+"ls /tmp")
      if (out.find("No such file or directory")!=-1):
	 self.printer.print_err("The /tmp directory was not found! We try the /data/local/tmp directory!")
	 out=self.adb.shell_command(su+"ls /data/local/tmp")
	 #if the directory empty, we will receive NoneType
	 if (out):
	    if (out.find("No such file or directory")!=-1):
	       self.printer.print_err("The /data/local/tmp directory was not found!")
	       self.printer.print_err("We did not found suitable destination directory! Please start the phone with the right recovery.")
	       return -1
	 dest_dir="/data/local/tmp"
      else:
	 dest_dir="/tmp"
      self.printer.print_debug("Use %s on the phone as a detination directory!" % dest_dir)
      
      self.printer.print_info("Uploading the gdb server...")
      push=self.adb.push_local_file("gdb/gdbserver","%s" % dest_dir)
      if(push.find("bytes")==-1):
	 self.printer.print_err("Could not upload the gdb server: %s" % push)
	 return -1
      self.printer.print_ok("Upload - Done")      

      self.print_info_adb(push.rstrip('\n'))
      self.printer.print_info("Staring gdbserver to listen on port 23946...")
      command="%s shell %s%s/gdbserver --multi :23946" % (self.adb.get_adb_path(),su,dest_dir)
      popen_args=shlex.split(command)
      self.printer.print_debug(command)
      gdbserver=subprocess.Popen(popen_args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
      out=gdbserver.stdout.read(10)
      if(out.find("Listen")==-1):
	 self.printer.print_err("Could not start the gdbserver:")
	 self.printer.print_err("%s" % out.replace("\r\n","\\r\\n"))
	 self.printer.print_err("Cleaning up! You should check the %s directory on the phone!" % (dest_dir))
	 self.cleanup()
	 return -1
      
      self.printer.print_debug("Forwarding tcp socket for gdbserver...")
      out=self.adb.forward_socket("tcp:23946","tcp:23946")
      #out=self.adb.forward_socket("tcp:4446","tcp:4446")
      if(out):
	 self.printer.print_err("Could not bind on 127.0.0.1:23946! Cleaning up! You should check the %s directory on the phone!" % (dest_dir))
	 self.cleanup(gdbserver=gdbserver)
	 return -1
      
      self.printer.print_ok("Server start - Done")
      self.printer.print_info("Starting gdb...") 
      #gdb=pexpect.spawn("gdb/gdb", logfile=sys.stdout)
      gdb=pexpect.spawn("gdb/gdb")
      gdb.sendline("target extended-remote :23946")
      ret=gdb.expect(["Remote.*",".*Operation.*", ".*Ignoring.*", pexpect.TIMEOUT])
      if(ret!=0):
	 self.printer.print_err("Could not connect to gdb server! Cleaning up! You should check the %s directory on the phone!" % (dest_dir))
	 self.cleanup(gdb=gdb, gdbserver=gdbserver)
	 return -1
      self.printer.print_ok("gdb connected - Done")
      
      gdb.sendline("file recovery/s4/system/bin/vold") 
      ret=gdb.expect(["Reading.*",".*No such.*", pexpect.TIMEOUT])
      if(ret!=0):
	 self.printer.print_err("We need the vold executable from the phone! Cleaning up! You should check the %s directory on the phone!" % (dest_dir))
	 self.cleanup(gdb=gdb, gdbserver=gdbserver)
	 return -1
      self.printer.print_debug("We sent the file command")
      
      gdb.sendline("set solib-search-path recovery/s4/system/lib/")

      ps=self.adb.shell_command("su -c ps")
      for process in ps.splitlines():
	 if(process.rfind("vold") != -1 ):
	    process=re.sub("\s+", ' ' , process)	
	    self.voldpid=process.split(' ')[1]
      self.printer.print_ok("Found vold process id: %s!" % self.voldpid)
     
      gdb.sendline("attach %s" % (self.voldpid))
      ret=gdb.expect(["0x.*",".*to process.*", pexpect.TIMEOUT])
      if(ret!=0):
	 self.printer.print_err("Could not attach to the vold process: %s! Cleaning up! You should check the %s directory on the phone!" % (self.voldpid, dest_dir))
	 self.cleanup(gdb=gdb, gdbserver=gdbserver)
	 return -1
      self.printer.print_ok("Attached vold process: %s!" % self.voldpid)
      
      gdb.sendline("info threads")
      gdb.expect("  4")
      thread4=gdb.readline().split(' ')[5].split('.')[1]
      #Read the rests
      for i in xrange(3):
	 gdb.readline()
      gdb.sendline("detach")
      gdb.sendline("attach %s" % (thread4))
      ret=gdb.expect(["0x.*",".*to process.*", pexpect.TIMEOUT])
      if(ret!=0):
	 self.printer.print_err("Could not attach to the vold thread: %s! Cleaning up! You should check the %s directory on the phone!" % (thread4, dest_dir))
	 self.cleanup(gdb=gdb, gdbserver=gdbserver)
	 return -1
      self.printer.print_ok("Attached vold thread: %s!" % thread4)
      
      gdb.sendline("break verify_EDK")
      ret=gdb.expect([".*Breakpoint.*",".*pending.*"])
      if(ret!=0):
	 self.printer.print_err("Could not set breakpoint on the verify_EDK function! Cleaning up! You should check the %s directory on the phone!")
	 gdb.sendline("n")
	 self.cleanup(gdb=gdb, gdbserver=gdbserver)
	 return -1
      self.printer.print_debug("Breakpoint was set on the verify_EDK function.")
      
      self.printer.print_debug("Staring vdc:")
      command="%s shell %s vdc cryptfs verifypw 1234" % (self.adb.get_adb_path(),su)
      popen_args=shlex.split(command)
      self.printer.print_debug(command)
      vdc=subprocess.Popen(popen_args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
      out=vdc.stdout.read(15)
      if(out.find("command cryptfs")==-1):
	 self.printer.print_err("Could not start vdc: %s" % (out))
	 self.printer.print_err(" Cleaning up! You should check the %s directory on the phone!" % (dest_dir))
	 self.cleanup(gdb=gdb, gdbserver=gdbserver)
	 return -1
      
      gdb.sendline("c")
      ret=gdb.expect(".*Breakpoint.*")
      self.printer.print_debug("Breakpoint hit! Let's investigate the first parameter (r0)!")
      gdb.sendline("x /80bx $r0+32")
      gdb.expect(":")
      hex_list=[]
      for i in range(0,10):
	 if(i==0):
	    line=gdb.before+gdb.readline()
	 else:
	    line=gdb.readline()
	 hex_line=''.join(line.split("\t")[1:]).replace("0x","").rstrip("\r\n").upper()
	 hex_list.append(hex_line)
       
      self.write2john(''.join(hex_list))
      self.write2footer(''.join(hex_list))
      
      self.cleanup(gdb=gdb, gdbserver=gdbserver)
   
      return 1
   
   def print_info_adb(self,message, ok=True):
      if(ok):
	 self.printer.printer.print_debug("OK! Received the following from adb: %s" %message)
      else:
	 self.printer.print_error("ERROR! Received the following from adb: %s" %message)
Ejemplo n.º 3
0
class SandSdcKeyctl:
    def __init__(self, printer, config, project, adb_path="adb"):
        self.printer = printer
        self.config = config
        self.project = project
        self.params = {
            "adbpath": {
                "description": "Path of the adb command",
                "value": adb_path,
                "required": True
            },
            "phonewithos": {
                "description": "The samsung hardware and the android version",
                "value": "GT-I9300 4.1.2",
                "required": True
            },
            "out_dir": {
                "description":
                "Where to generate the results and download files on the computer.",
                "value": "results",
                "required": True
            },
        }
        self.setparams(self.params)

    def setparams(self, params):
        self.params = params
        self.adb = ADB(self.params["adbpath"]["value"])
        self.phone = self.params["phonewithos"]["value"]
        self.out_dir = self.params["out_dir"]["value"]

    def getparams(self):
        return self.params

    def getsdckeybin(self):
        self.printer.print_debug("Check for su!")
        su = checkforsu(self.adb)
        if (su == ""):
            self.printer.print_err(
                "The su comand was not found, hope adb have immediate root access!"
            )
            su = ""
        #No magic here, the phone should be fully booted for this module
        dest_dir = "/data/local/tmp"
        self.printer.print_debug(
            "We will use %s on the phone as a destination directory." %
            dest_dir)
        self.printer.print_info("Uploading keyctl utility to %s..." % dest_dir)
        push = self.adb.push_local_file("keyctl/keyctl", "%s" % dest_dir)
        if (push.find("bytes") == -1):
            self.printer.print_err("Could not upload the keyctl: %s" % push)
            return -1
        self.printer.print_ok("Upload - Done")

        self.printer.print_info("Searching for the keyid...")
        self.printer.print_debug(
            "Running the following command: %s %s/keyctl show @u" %
            (su, dest_dir))
        out = self.adb.shell_command(su + "%s/keyctl show @u" % (dest_dir))
        self.printer.print_debug("The keys on the keyring:\n%s" % out)
        keyid = ""
        for line in out.splitlines():
            if (line.find("user:"******" ").split(" ")[0]

        if (keyid == ""):
            self.printer.print_err(
                "Something went wrong, could not parse 'keyctl show' output.")
            return -1
        self.printer.print_ok("The keyid is: %s." % (keyid))

        self.printer.print_info("Dumping the key...")
        self.printer.print_debug(
            "Running the following command: %s %s/keyctl pipe %s > %s/sdckey.bin"
            % (su, dest_dir, keyid, dest_dir))
        out = self.adb.shell_command(
            "\"%s %s/keyctl pipe %s > %s/sdckey.bin\"" %
            (su, dest_dir, keyid, dest_dir))
        if (out != None):
            self.printer.print_err("Something went wrong: %s" % (out))
            return -1

        self.printer.print_info("Downloading the dumped key file...")
        pull = self.adb.get_remote_file(
            "%s/sdckey.bin" % dest_dir,
            "%s/%s_sdckey.bin" % (self.out_dir, self.project))
        if (pull.find("bytes") == -1):
            self.printer.print_err("Could not download dumped key file: %s" %
                                   pull)
            self.printer.print_info(
                "Cleaning up! Please check the %s folder. Unsuccessull cleanup weakens the security of the phone!!!!"
                % dest_dir)
            out = self.adb.shell_command(su + "rm %s/sdckey.bin" % dest_dir)
            out = self.adb.shell_command(su + "rm %s/keyctl" % dest_dir)
            return -1
        self.printer.print_ok("Download - Done")
        #self.printer.print_info(pull.rstrip("\n"))

        #Cleanup
        self.printer.print_info(
            "Cleaning up! Please check the %s folder. Unsuccessull cleanup weakens the security of the phone!!!!"
            % dest_dir)
        out = self.adb.shell_command(su + "rm %s/sdckey.bin" % dest_dir)
        out = self.adb.shell_command(su + "rm %s/keyctl" % dest_dir)

        return 1

    def print_info_adb(self, message, ok=True):
        if (ok):
            self.printer.printer.print_info(
                "OK! Received the following from adb: %s" % message)
        else:
            self.printer.print_error(
                "ERROR! Received the following from adb: %s" % message)
Ejemplo n.º 4
0
class GetKey:

   def __init__(self, printer, config, project, adb_path="adb"):
      self.printer=printer
      self.params={"adbpath":{"description":"Path of the adb command",
			      "value":adb_path,
			      "required":True
			      },
		  "dumpfile":{"description":"Where to save the memory dumpfile with the filename",
			      "value":"dumpfile",
			      "required":True
			      },
		  "out_dir":{"description":"Where to generate the results and download files on the computer.",
			      "value":"results",
			      "required":True
			      },
		  "dekfile":{"description":"Where to generate the results and download files on the computer.",
			      "value":"dek.bin",
			      "required":True
			      },
		  "phonewithos":{"description":"The samsung hardware and the android version",
			      "value":"GT-I9300 4.1.2",
			      "required":True
			      },

		  }
      self.adb = ADB(self.params["adbpath"]["value"])
      self.out_dir=self.params["out_dir"]["value"]
      self.dumpfile = self.params["dumpfile"]["value"]
      self.dekfile = self.params["dekfile"]["value"]
      self.project=project

   def setparams(self, params):
      self.params=params
      self.adb = ADB(self.params["adbpath"]["value"])
      self.dumpfile = self.params["dumpfile"]["value"]
      self.dekfile = self.params["dekfile"]["value"]
      self.phone = self.params["phonewithos"]["value"]
      self.out_dir = self.params["out_dir"]["value"]
   
   def getparams(self):
      return self.params

   def get_vold_data_segment(self):
      self.printer.print_debug("Check for su!")
      su=checkforsu(self.adb)
      if (su==""):
	 self.printer.print_err("The su comand was not found, hope adb have immediate root access!")
	 su=""
      
      #No magic here, the phone should be fully booted for this module
      self.dest_dir="/data/local/tmp"

      ps=self.adb.shell_command("su -c ps")
      self.voldpid=None
      for process in ps.splitlines():
          if(process.rfind("vold") != -1 ):
              process=re.sub("\s+", ' ' , process)	
              self.voldpid=process.split(' ')[1]
              break
          
      if self.voldpid==None:
          self.adb.shell_command("su -c start vold")
          ps=self.adb.shell_command("su -c ps")
          for process in ps.splitlines():
              if(process.rfind("vold") != -1 ):
                  process=re.sub("\s+", ' ' , process)    
                  self.voldpid=process.split(' ')[1]
                  break
          if self.voldpid==None:
              print "Couldn't find vold process. Try to start manually using \"adb shell su -c 'start vold'\""
              return -1

      self.printer.print_debug("Found vold process id: %s!" % self.voldpid)
      memsegments=self.adb.shell_command("su -c cat /proc/%s/maps" % self.voldpid).splitlines()
      for segment in memsegments:
          if(re.match(".*w-p.*vold.*", segment)!=None):
                 addresses=segment.split(" ")[0].split("-")
                 self.datastart=addresses[0]
                 self.dataend=addresses[1]
                 self.numberofbytes=int(addresses[1],16)-int(addresses[0],16)
                 break

      self.printer.print_debug("The data segment addresses are: %s - %s" % (self.datastart, self.dataend))
      
      self.printer.print_info("Copy the memory dumper to %s." % (self.dest_dir))
 
      push=self.adb.push_local_file("dump_android_memory/dump_android_memory","%s/dump_android_memory" % self.dest_dir)
      if(push.find("bytes")==-1):
	 self.print_info_adb(push, False)
	 return -1

      self.printer.print_ok("Copy - Done")
      self.print_info_adb(push.rstrip("\n"))
      
      self.printer.print_info("Run the memory dumper.")
      
      dump=self.adb.shell_command("su -c /data/local/tmp/dump_android_memory %s 0x%s %d %s/dumpfile" % (self.voldpid, self.datastart, self.numberofbytes, self.dest_dir))
      if(dump):
	 self.printer.print_info_adb(dump,False)
	 return -1
      self.printer.print_ok("Memory dumper - Done")

      self.printer.print_info("Download the dump file")
      
      pull=self.adb.get_remote_file("/data/local/tmp/dumpfile","%s/%s_%s" % (self.out_dir, self.project, self.dumpfile))
      if(pull.find("bytes")==-1):
	 self.print_info_adb(pull,False)
	 return -1

      self.printer.print_ok("Download - Done")
      self.print_info_adb(pull.rstrip("\n"))
      
      #Cleanup
      self.printer.print_info("Cleaning up! Please check the %s folder. Unsuccessfull cleanup weakens the security of the phone!!!!" % self.dest_dir)
      out=self.adb.shell_command(su+"rm %s/dumpfile" % self.dest_dir)
      out=self.adb.shell_command(su+"rm %s/dump_android_memory" % self.dest_dir)
      self.printer.print_ok("Clean up - Done")

   def getpin(self):
      buff=""
      strings=self.strings("%s/%s_%s" % (self.out_dir, self.project, self.dumpfile));
      self.printer.print_info("Following strings found in the vold memory segment:")
      for entry in strings:
	 #self.printer.print_info("  %s:%d" % (entry.string, entry.pos))
	 self.printer.print_info("  %s" % (entry.string))
      self.printer.print_info("Assuming the last one is the pin/password, let's find the DEK")
      last_entry=strings[len(strings)-1]
      index=len(last_entry.string)+last_entry.pos
      try:
	 f=open("%s/%s_%s" % (self.out_dir, self.project, self.dumpfile),"rb")
	 try:
	    buff=f.read(4096)
	 finally:
	    f.close()
      except IOError as e:
	 self.printer.print_err("I/O error({0}): {1} {2}".format(e.errno, e.strerror, "%s/%s_%s" % (self.out_dir, self.project, self.dumpfile)))
	 return -1
      
      for i in range(index+1,index+200):
	 if(buff[i]!='\0'):
	    break
      
      #Because we search for the first non zero, the search can be broken. 
      dek1=buff[i:i+32]
      self.printer.print_info("The first possible key is:")
      self.printer.print_ok(hexlify(dek1))
      dek2=buff[i-1:i-1+32]
      self.printer.print_info("The second possible key is:")
      self.printer.print_ok(hexlify(dek2))
      
      self.printer.print_info("Creating two files:")
      self.printer.print_ok("%s/%s_%s.1" % (self.out_dir, self.project, self.dekfile))
      self.printer.print_ok("%s/%s_%s.2" % (self.out_dir, self.project, self.dekfile))

      self.printer.print_info("If they are not working, analyze the dumpfile manually and you will find the key. It works for S2 and S3 until 4.1.2.")
      
      try:
	 f=open("%s/%s_%s.1" % (self.out_dir, self.project, self.dekfile),"wb")
	 try:
	       f.write(dek1)
	 finally:
	    f.close()
      except IOError as e:
	 self.printer.print_err("I/O error({0}): {1} {2}/{3}_footer".format(e.errno, e.strerror, self.out_dir, self.project))
	 return -1

      try:
	 f=open("%s/%s_%s.2" % (self.out_dir, self.project, self.dekfile),"wb")
	 try:
	       f.write(dek2)
	 finally:
	    f.close()
      except IOError as e:
	 self.printer.print_err("I/O error({0}): {1} {2}/{3}_footer".format(e.errno, e.strerror, self.out_dir, self.project))
	 return -1

 
      return 1




   def print_info_adb(self,message, ok=True):
      if(ok):
	 self.printer.print_info("OK! Received the following from adb: %s" %message)
      else:
	 self.printer.print_err("ERROR! Received the following from adb: %s" %message)
   
   def strings(self,filename):
      pos=0
      strings=[]
      s_entry=namedtuple("s_entry","string pos")
      printable=set(string.printable)
      found_str=""
      fh=open(filename,"rb")
      data=fh.read(4096)
      fh.close()
      pos=0
      for char in data:
	 pos+=1
	 if char in printable:
	    found_str+=char
	 elif len(found_str) >= 4:
	    strings.append(s_entry(found_str, pos))
	    found_str=""
	 else:
	    found_str=""
      return strings
Ejemplo n.º 5
0
class SandSdcKeyctl:


   def __init__(self, printer, config, project, adb_path="adb"):
      self.printer=printer
      self.config=config
      self.project=project
      self.params={"adbpath":{"description":"Path of the adb command",
			      "value":adb_path,
			      "required":True
			      },
		  "phonewithos":{"description":"The samsung hardware and the android version",
			      "value":"GT-I9300 4.1.2",
			      "required":True
			      },
		  "out_dir":{"description":"Where to generate the results and download files on the computer.",
			      "value":"results",
			      "required":True
			      },
		  }
      self.setparams(self.params)

   def setparams(self, params):
      self.params=params
      self.adb = ADB(self.params["adbpath"]["value"])
      self.phone = self.params["phonewithos"]["value"]
      self.out_dir = self.params["out_dir"]["value"]

   def getparams(self):
      return self.params

   def getsdckeybin(self):
      self.printer.print_debug("Check for su!")
      su=checkforsu(self.adb)
      if (su==""):
	 self.printer.print_err("The su comand was not found, hope adb have immediate root access!")
	 su=""
      #No magic here, the phone should be fully booted for this module
      dest_dir="/data/local/tmp"
      self.printer.print_debug("We will use %s on the phone as a destination directory." % dest_dir)
      self.printer.print_info("Uploading keyctl utility to %s..." % dest_dir)
      push=self.adb.push_local_file("keyctl/keyctl","%s" % dest_dir)
      if(push.find("bytes")==-1):
	 self.printer.print_err("Could not upload the keyctl: %s" % push)
	 return -1
      self.printer.print_ok("Upload - Done")
      
      self.printer.print_info("Searching for the keyid...")
      self.printer.print_debug("Running the following command: %s %s/keyctl show @u" % (su, dest_dir))
      out=self.adb.shell_command(su+"%s/keyctl show @u" % (dest_dir))
      self.printer.print_debug("The keys on the keyring:\n%s" % out)
      keyid=""
      for line in out.splitlines():
	 if(line.find("user:"******" ").split(" ")[0]
      
      if(keyid==""):
	 self.printer.print_err("Something went wrong, could not parse 'keyctl show' output.")
	 return -1
      self.printer.print_ok("The keyid is: %s." % (keyid))
      
      self.printer.print_info("Dumping the key...")
      self.printer.print_debug("Running the following command: %s %s/keyctl pipe %s > %s/sdckey.bin" % (su, dest_dir, keyid, dest_dir))
      out=self.adb.shell_command("\"%s %s/keyctl pipe %s > %s/sdckey.bin\"" % (su, dest_dir, keyid, dest_dir))
      if(out!=None):
	 self.printer.print_err("Something went wrong: %s" % (out))
	 return -1

      self.printer.print_info("Downloading the dumped key file...")
      pull=self.adb.get_remote_file("%s/sdckey.bin" % dest_dir,"%s/%s_sdckey.bin" % (self.out_dir, self.project))
      if(pull.find("bytes")==-1):
	 self.printer.print_err("Could not download dumped key file: %s" % pull)
	 self.printer.print_info("Cleaning up! Please check the %s folder. Unsuccessull cleanup weakens the security of the phone!!!!" % dest_dir)
	 out=self.adb.shell_command(su+"rm %s/sdckey.bin" % dest_dir)
	 out=self.adb.shell_command(su+"rm %s/keyctl" % dest_dir)
	 return -1
      self.printer.print_ok("Download - Done")
      #self.printer.print_info(pull.rstrip("\n"))
      
      #Cleanup
      self.printer.print_info("Cleaning up! Please check the %s folder. Unsuccessull cleanup weakens the security of the phone!!!!" % dest_dir)
      out=self.adb.shell_command(su+"rm %s/sdckey.bin" % dest_dir)
      out=self.adb.shell_command(su+"rm %s/keyctl" % dest_dir)
 
      return 1
 
   def print_info_adb(self,message, ok=True):
      if(ok):
	 self.printer.printer.print_info("OK! Received the following from adb: %s" %message)
      else:
	 self.printer.print_error("ERROR! Received the following from adb: %s" %message)
Ejemplo n.º 6
0
class SandGetFooter:


   def __init__(self, printer, config, project, adb_path="adb"):
      self.printer=printer
      self.config=config
      self.project=project
      self.params={"adbpath":{"description":"Path of the adb command",
			      "value":adb_path,
			      "required":True
			      },
		  "footer":{"description":"Is the key is stored in footer?",
			      "value":"True",
			      "required":True
			      },
		  "phonewithos":{"description":"The samsung hardware and the android version",
			      "value":"GT-I9300 4.1.2",
			      "required":True
			      },
		  "out_dir":{"description":"Where to generate the results and download files on the computer.",
			      "value":"results",
			      "required":True
			      },
		  "footer_file":{"description":"The DEK is stored in this file on the phone.",
			      "value":"/efs/metadata",
			      "required":True
			      },
		  }
      self.setparams(self.params)

   def setparams(self, params):
      self.params=params
      self.adb = ADB(self.params["adbpath"]["value"])
      self.phone = self.params["phonewithos"]["value"]
      self.out_dir = self.params["out_dir"]["value"]
      self.footer_file = self.params["footer_file"]["value"]

   def getparams(self):
      return self.params

   
   def get_footer_from_phone(self):
      
      '''
      Uploads the seek_and_read to /tmp or /data/local/tmp and runs it. Then it downloads the result footer file.
      It dumps the last 16K of the data partition, configure in the config.cfg file. Please check the given
      directories on the phone to make sure the cleanup was ok.
      '''
      
      partition=self.config.get(self.phone, "data")
      self.printer.print_debug(partition)
      self.printer.print_debug("Check for su!")
      su=checkforsu(self.adb)
      if (su==""):
	 self.printer.print_err("The su comand was not found, hope the phone in a recovery with root access!")
	 su=""
      
      #dd was too slow on the phone (5min on s3), thus we implemented a seek and read program.
   
      dest_dir=check_tmp(self.printer,self.adb,su)
      self.printer.print_info("Uploading the footer reader to %s..." % (dest_dir))
      push=self.adb.push_local_file("seek_and_read/seek_and_read","%s" % dest_dir)
      if(push.find("bytes")==-1):
	 self.printer.print_err("Could not upload the file reader: %s" % push)
	 return -1
      self.printer.print_ok("Upload - Done")

      self.printer.print_debug("Running the following command:")
      command=su+"%s/seek_and_read %s %s/footer" % (dest_dir, partition, dest_dir)
      self.printer.print_debug(command)
      out=self.adb.shell_command(command)
      if(out.find("16384")==-1):
	 self.printer.print_err("File reader did not work: %s" % out)
	 self.printer.print_info("Cleaning up! Please check the %s folder. Unsuccessull cleanup weakens the security of the phone!!!!" % dest_dir)
	 out=self.adb.shell_command(su+"rm %s/footer" % dest_dir)
	 out=self.adb.shell_command(su+"rm %s/seek_and_read" % dest_dir)
	 return -1
      
      self.printer.print_info("Downloading the footer file...")
      pull=self.adb.get_remote_file("%s/footer" % dest_dir,"%s/%s_footer" % (self.out_dir, self.project))
      if(pull.find("bytes")==-1):
	 self.printer.print_err("Could not download footer file: %s" % pull)
	 self.printer.print_info("Cleaning up! Please check the %s folder. Unsuccessull cleanup weakens the security of the phone!!!!" % dest_dir)
	 out=self.adb.shell_command(su+"rm %s/footer" % dest_dir)
	 out=self.adb.shell_command(su+"rm %s/seek_and_read" % dest_dir)
	 return -1 	
      self.printer.print_ok("Download - Done") 
      self.printer.print_info(pull.rstrip("\n"))
      
      #Cleanup
      self.printer.print_info("Cleaning up! Please check the %s folder. Unsuccessull cleanup weakens the security of the phone!!!!" % dest_dir)
      out=self.adb.shell_command(su+"rm %s/footer" % dest_dir)
      out=self.adb.shell_command(su+"rm %s/seek_and_read" % dest_dir)

      self.printer.print_ok("Download - Done")
      return 1

   def get_footer_file(self):

      '''
      Downloads the footer_file (typical /efs/metadata) that contains the DEK on S2. It copies the file to /tmp
      or /data/local/tmp. Changes the access right to adb pull and downloads it.
      '''

      self.printer.print_debug("Check for su!")
      su=checkforsu(self.adb)
      if (su==""):
	 self.printer.print_err("The su comand was not found, hope the phone in a recovery with root access!")
	 su=""

      self.printer.print_info("Downloading the footer [ %s ] file" % self.params["footer_file"])
      pull = get_file(self.printer, self.adb, su, self.params["footer_file"], "%s/%s_footer"%(self.out_dir, self.project))
      if (pull!=-1):
	 self.printer.print_ok("Download - Done")
      return pull

   def getfooter(self):

      '''
      Decides whether the DEK is stored in file or at the end of data partition. The decision is based on the
      config.cg file.
      '''

      if(self.params["footer"]["value"]=="n"):
	 if(self.get_footer_file()==-1):
	    return -1
      else:
	 if(self.get_footer_from_phone()==-1):
	    return -1
      return 1

   
   def print_info_adb(self,message, ok=True):
      if(ok):
	 self.printer.printer.print_info("OK! Received the following from adb: %s" %message)
      else:
	 self.printer.print_error("ERROR! Received the following from adb: %s" %message)
Ejemplo n.º 7
0
class SandS4GetEDK:
    def __init__(self, printer, config, project, adb_path="adb"):
        self.printer = printer
        self.config = config
        self.project = project
        self.params = {
            "adbpath": {
                "description": "Path of the adb command",
                "value": adb_path,
                "required": True
            },
            "phonewithos": {
                "description": "The samsung hardware and the android version",
                "value": "GT-I9505 4.3.2",
                "required": True
            },
            "out_dir": {
                "description":
                "Where to generate the results and download files on the computer.",
                "value": "results",
                "required": True
            },
        }
        self.setparams(self.params)

    def setparams(self, params):
        self.params = params
        self.adb = ADB(self.params["adbpath"]["value"])
        self.phone = self.params["phonewithos"]["value"]
        self.out_dir = self.params["out_dir"]["value"]

    def getparams(self):
        return self.params

    def downloadforgdb(self, fullpath):
        """
      Downloads the fullpath for gdb. It puts the file in lib or in bin,
      Depends on the fullpath is a lib directory or not.
      """

        path, filename = os.path.split(fullpath)
        if (path.find("lib") != -1):
            out = self.adb.get_remote_file(
                fullpath, "recovery/s4/system/lib/%s" % (filename))
        else:
            out = self.adb.get_remote_file(
                fullpath, "recovery/s4/system/bin/%s" % (filename))
        return out

    def write2john(self, edk):
        """
      Simple save the edk into the prject_sanddek.jtr file to jonh the ripper
      cracking
      """

        self.printer.print_info(
            "This will be written to file %s/%s_sanddek.jtr, for jtr:" %
            (self.out_dir, self.project))
        self.printer.print_ok("%s_s4:%s" % (self.project, edk))
        try:
            f = open("%s/%s_sanddek.jtr" % (self.out_dir, self.project), "a")
            f.write("%s_s4:%s\n" % (self.project, edk))
            f.close()
        except IOError as e:
            self.printer.print_err(
                "I/O error({0}): {1}: {2}/{3}_sanddek.jtr".format(
                    e.errno, e.strerror, self.out_dir, self.project))
            return -1

    def write2footer(self, edk):
        """
      Save the EDK to a footer file. The we can use the mount modules, that
      uses the password
      """

        self.printer.print_info("Footer will be created: %s/%s_footer" %
                                (self.out_dir, self.project))
        footer = '\0' * 0x84 + unhexlify(edk)
        try:
            f = open("%s/%s_footer" % (self.out_dir, self.project), "wb")
            f.write(footer)
            f.close()
        except IOError as e:
            self.printer.print_err(
                "I/O error({0}): {1}: {2}/{3}_footer".format(
                    e.errno, e.strerror, self.out_dir, self.project))
            return -1

    def cleanup(self, gdb=None, gdbserver=None):
        """
      Tries to gently stop gdb, kill gdbserver and delete it from /data/local/tmp or /tmp
      """

        if (gdb):
            gdb.sendcontrol('c')
            gdb.sendline("detach")
            gdb.sendline("quit")
            gdb.kill(0)
        if (gdbserver):
            gdbserver.kill()

        self.adb.shell_command("rm /data/local/tmp/gdbserver")
        self.adb.shell_command("rm /tmp/gdbserver")

    def getedk(self):
        """
      Write the the help of the gdb and gdbserver, gets out the EDK on a S4.
      It puts a breakpoint on verify_EDK which is called when vdc cryptfs verifypw
      is called. The R0 register contains the EDK>
      """

        state = checkcryptostate(self.adb)
        if (state == ""):
            self.printer.print_err(
                "The phone is not encrypted. ro.crypto.state is empty!")
            return -1
        self.printer.print_debug("Check for su!")
        su = checkforsu(self.adb)
        if (su == ""):
            self.printer.print_err(
                "The su comand was not found, hope adb have immediate root access!"
            )
            su = ""

        self.printer.print_info("Downloading vold and libsec_km.so for gdb...")
        out = self.downloadforgdb("/system/bin/vold")
        if (out == None):
            self.printer.print_err("Could not download vold! Exiting...")
            return -1
        out = self.downloadforgdb("/system/lib/libsec_km.so")
        if (out == None):
            self.printer.print_err(
                "Could not download libsec_km.so! Exiting...")
            return -1
        self.printer.print_ok("Download - Done")

        self.printer.print_debug("Check the destination directory!")
        dest_dir = ""
        out = self.adb.shell_command(su + "ls /tmp")
        if (out.find("No such file or directory") != -1):
            self.printer.print_err(
                "The /tmp directory was not found! We try the /data/local/tmp directory!"
            )
            out = self.adb.shell_command(su + "ls /data/local/tmp")
            #if the directory empty, we will receive NoneType
            if (out):
                if (out.find("No such file or directory") != -1):
                    self.printer.print_err(
                        "The /data/local/tmp directory was not found!")
                    self.printer.print_err(
                        "We did not found suitable destination directory! Please start the phone with the right recovery."
                    )
                    return -1
            dest_dir = "/data/local/tmp"
        else:
            dest_dir = "/tmp"
        self.printer.print_debug(
            "Use %s on the phone as a detination directory!" % dest_dir)

        self.printer.print_info("Uploading the gdb server...")
        push = self.adb.push_local_file("gdb/gdbserver", "%s" % dest_dir)
        if (push.find("bytes") == -1):
            self.printer.print_err("Could not upload the gdb server: %s" %
                                   push)
            return -1
        self.printer.print_ok("Upload - Done")

        self.print_info_adb(push.rstrip('\n'))
        self.printer.print_info("Staring gdbserver to listen on port 23946...")
        command = "%s shell %s%s/gdbserver --multi :23946" % (
            self.adb.get_adb_path(), su, dest_dir)
        popen_args = shlex.split(command)
        self.printer.print_debug(command)
        gdbserver = subprocess.Popen(popen_args,
                                     stdin=subprocess.PIPE,
                                     stdout=subprocess.PIPE,
                                     stderr=subprocess.PIPE)
        out = gdbserver.stdout.read(10)
        if (out.find("Listen") == -1):
            self.printer.print_err("Could not start the gdbserver:")
            self.printer.print_err("%s" % out.replace("\r\n", "\\r\\n"))
            self.printer.print_err(
                "Cleaning up! You should check the %s directory on the phone!"
                % (dest_dir))
            self.cleanup()
            return -1

        self.printer.print_debug("Forwarding tcp socket for gdbserver...")
        out = self.adb.forward_socket("tcp:23946", "tcp:23946")
        #out=self.adb.forward_socket("tcp:4446","tcp:4446")
        if (out):
            self.printer.print_err(
                "Could not bind on 127.0.0.1:23946! Cleaning up! You should check the %s directory on the phone!"
                % (dest_dir))
            self.cleanup(gdbserver=gdbserver)
            return -1

        self.printer.print_ok("Server start - Done")
        self.printer.print_info("Starting gdb...")
        #gdb=pexpect.spawn("gdb/gdb", logfile=sys.stdout)
        gdb = pexpect.spawn("gdb/gdb")
        gdb.sendline("target extended-remote :23946")
        ret = gdb.expect(
            ["Remote.*", ".*Operation.*", ".*Ignoring.*", pexpect.TIMEOUT])
        if (ret != 0):
            self.printer.print_err(
                "Could not connect to gdb server! Cleaning up! You should check the %s directory on the phone!"
                % (dest_dir))
            self.cleanup(gdb=gdb, gdbserver=gdbserver)
            return -1
        self.printer.print_ok("gdb connected - Done")

        gdb.sendline("file recovery/s4/system/bin/vold")
        ret = gdb.expect(["Reading.*", ".*No such.*", pexpect.TIMEOUT])
        if (ret != 0):
            self.printer.print_err(
                "We need the vold executable from the phone! Cleaning up! You should check the %s directory on the phone!"
                % (dest_dir))
            self.cleanup(gdb=gdb, gdbserver=gdbserver)
            return -1
        self.printer.print_debug("We sent the file command")

        gdb.sendline("set solib-search-path recovery/s4/system/lib/")

        ps = self.adb.shell_command("su -c ps")
        for process in ps.splitlines():
            if (process.rfind("vold") != -1):
                process = re.sub("\s+", ' ', process)
                self.voldpid = process.split(' ')[1]
        self.printer.print_ok("Found vold process id: %s!" % self.voldpid)

        gdb.sendline("attach %s" % (self.voldpid))
        ret = gdb.expect(["0x.*", ".*to process.*", pexpect.TIMEOUT])
        if (ret != 0):
            self.printer.print_err(
                "Could not attach to the vold process: %s! Cleaning up! You should check the %s directory on the phone!"
                % (self.voldpid, dest_dir))
            self.cleanup(gdb=gdb, gdbserver=gdbserver)
            return -1
        self.printer.print_ok("Attached vold process: %s!" % self.voldpid)

        gdb.sendline("info threads")
        gdb.expect("  4")
        thread4 = gdb.readline().split(' ')[5].split('.')[1]
        #Read the rests
        for i in xrange(3):
            gdb.readline()
        gdb.sendline("detach")
        gdb.sendline("attach %s" % (thread4))
        ret = gdb.expect(["0x.*", ".*to process.*", pexpect.TIMEOUT])
        if (ret != 0):
            self.printer.print_err(
                "Could not attach to the vold thread: %s! Cleaning up! You should check the %s directory on the phone!"
                % (thread4, dest_dir))
            self.cleanup(gdb=gdb, gdbserver=gdbserver)
            return -1
        self.printer.print_ok("Attached vold thread: %s!" % thread4)

        gdb.sendline("break verify_EDK")
        ret = gdb.expect([".*Breakpoint.*", ".*pending.*"])
        if (ret != 0):
            self.printer.print_err(
                "Could not set breakpoint on the verify_EDK function! Cleaning up! You should check the %s directory on the phone!"
            )
            gdb.sendline("n")
            self.cleanup(gdb=gdb, gdbserver=gdbserver)
            return -1
        self.printer.print_debug(
            "Breakpoint was set on the verify_EDK function.")

        self.printer.print_debug("Staring vdc:")
        command = "%s shell %s vdc cryptfs verifypw 1234" % (
            self.adb.get_adb_path(), su)
        popen_args = shlex.split(command)
        self.printer.print_debug(command)
        vdc = subprocess.Popen(popen_args,
                               stdin=subprocess.PIPE,
                               stdout=subprocess.PIPE,
                               stderr=subprocess.PIPE)
        out = vdc.stdout.read(15)
        if (out.find("command cryptfs") == -1):
            self.printer.print_err("Could not start vdc: %s" % (out))
            self.printer.print_err(
                " Cleaning up! You should check the %s directory on the phone!"
                % (dest_dir))
            self.cleanup(gdb=gdb, gdbserver=gdbserver)
            return -1

        gdb.sendline("c")
        ret = gdb.expect(".*Breakpoint.*")
        self.printer.print_debug(
            "Breakpoint hit! Let's investigate the first parameter (r0)!")
        gdb.sendline("x /80bx $r0+32")
        gdb.expect(":")
        hex_list = []
        for i in range(0, 10):
            if (i == 0):
                line = gdb.before + gdb.readline()
            else:
                line = gdb.readline()
            hex_line = ''.join(line.split("\t")[1:]).replace(
                "0x", "").rstrip("\r\n").upper()
            hex_list.append(hex_line)

        self.write2john(''.join(hex_list))
        self.write2footer(''.join(hex_list))

        self.cleanup(gdb=gdb, gdbserver=gdbserver)

        return 1

    def print_info_adb(self, message, ok=True):
        if (ok):
            self.printer.printer.print_debug(
                "OK! Received the following from adb: %s" % message)
        else:
            self.printer.print_error(
                "ERROR! Received the following from adb: %s" % message)