Beispiel #1
0
 def _load_templates(self):
     """
     @return None
     """
     if self._templates is None:
         self._templates = {}
     for i in xrange(32):
         ofs = self.unpack_dword(0x180 + (i * 4))
         while ofs > 0:
             # unclear why these are found before the offset
             # this is a direct port from A.S.'s code
             token = self.unpack_byte(ofs - 10)
             pointer = self.unpack_dword(ofs - 4)
             if token != 0x0c or pointer != ofs:
                 warning("Unexpected token encountered")
                 ofs = 0
                 continue
             template = self.add_template(ofs)
             ofs = template.next_offset()
Beispiel #2
0
 def _load_templates(self):
     """
     @return None
     """
     if self._templates is None:
         self._templates = {}
     for i in xrange(32):
         ofs = self.unpack_dword(0x180 + (i * 4))
         while ofs > 0:
             # unclear why these are found before the offset
             # this is a direct port from A.S.'s code
             token = self.unpack_byte(ofs - 10)
             pointer = self.unpack_dword(ofs - 4)
             if token != 0x0C or pointer != ofs:
                 warning("Unexpected token encountered")
                 ofs = 0
                 continue
             template = self.add_template(ofs)
             ofs = template.next_offset()
Beispiel #3
0
    def fixup(self, num_fixups, fixup_value_offset):
        fixup_value = self.unpack_word(fixup_value_offset)

        for i in range(0, num_fixups - 1):
            fixup_offset = 512 * (i + 1) - 2
            check_value = self.unpack_word(fixup_offset)

            if check_value != fixup_value:
                warning("Bad fixup at %s" % \
                            (hex(self.offset() + fixup_offset)))
                continue

            new_value = self.unpack_word(fixup_value_offset + 2 + 2 * i)
            self.pack_word(fixup_offset, new_value)

            check_value = self.unpack_word(fixup_offset)
            debug("Fixup verified at %s and patched from %s to %s." % \
                  (hex(self.offset() + fixup_offset),
                   hex(fixup_value), hex(check_value)))
Beispiel #4
0
def main():
    parser = argparse.ArgumentParser(description='Parse NTFS '
                                     'filesystem structures.')
    parser.add_argument('-t', action="store", metavar="type",
                        nargs=1, dest="filetype",
                        choices=["image", "MFT", "INDX", "auto"],
                        default="auto",
                        help="The type of data provided.")
    parser.add_argument('-c', action="store", metavar="size",
                        nargs=1, type=int, dest="clustersize",
                        help="Use this cluster size in bytes "
                        "(default 4096 bytes)")
    parser.add_argument('-o', action="store", metavar="offset",
                        nargs=1, type=int, dest="offset",
                        help="Offset in bytes to volume in image "
                        "(default 32256 bytes)")
    parser.add_argument('-l', action="store_true", dest="indxlist",
                        help="List file entries in INDX records")
    parser.add_argument('-s', action="store_true", dest="slack",
                        help="List file entries in INDX slack space")
    parser.add_argument('-m', action="store_true", dest="mftlist",
                        help="List file entries for active MFT records")
    parser.add_argument('-d', action="store_true", dest="deleted",
                        help="List file entries for MFT records "
                        "marked as deleted")
    parser.add_argument('-i', action="store", metavar="path|inode",
                        nargs=1, dest="infomode",
                        help="Print information about a path's INDX records")
    parser.add_argument('-e', action="store", metavar="i30",
                        nargs=1, dest="extract",
                        help="Used with -i, extract INDX_ALLOCATION "
                        "attribute to a file")
    parser.add_argument('-f', action="store", metavar="regex",
                        nargs=1, dest="filter",
                        help="Only consider entries whose path "
                        "matches this regular expression")
    parser.add_argument('-p', action="store", metavar="prefix",
                        nargs=1, dest="prefix",
                        help="Prefix paths with `prefix` rather than \\.\\")
    parser.add_argument('--progress', action="store_true",
                        dest="progress",
                        help="Update a status indicator on STDERR "
                        "if STDOUT is redirected")
    parser.add_argument('-v', action="store_true", dest="verbose",
                        help="Print debugging information")
    parser.add_argument('filename', action="store",
                        help="Input INDX file path")

    results = parser.parse_args()

    global verbose
    verbose = results.verbose

    if results.filetype and results.filetype != "auto":
        results.filetype = results.filetype[0].lower()
        info("Asked to process a file with type: " + results.filetype)
    else:
        with open(results.filename, "rb") as f:
            b = f.read(1024)
            if b[0:4] == "FILE":
                results.filetype = "mft"
            elif b[0:4] == "INDX":
                results.filetype = "indx"
            else:
                results.filetype = "image"
        info("Auto-detected input file type: " + results.filetype)

    if results.clustersize:
        results.clustersize = results.clustersize[0]
        info("Using explicit file system cluster size %s (%s) bytes" %
             (str(results.clustersize), hex(results.clustersize)))
    else:
        results.clustersize = 4096
        info("Assuming file system cluster size %s (%s) bytes" %
             (str(results.clustersize), hex(results.clustersize)))

    if results.offset:
        results.offset = results.offset[0]
        info("Using explicit volume offset %s (%s) bytes" %
             (str(results.offset), hex(results.offset)))
    else:
        results.offset = 32256
        info("Assuming volume offset %s (%s) bytes" %
             (str(results.offset), hex(results.offset)))

    if results.prefix:
        results.prefix = results.prefix[0]
        info("Using path prefix " + results.prefix)

    if results.indxlist:
        info("Asked to list entries in INDX records")
        if results.filetype == "mft":
            info("  Note, only resident INDX records can be processed "
                 "with an MFT input file")
            info("  If you find an interesting record, "
                 "use -i to identify the relevant INDX record clusters")
        elif results.filetype == "indx":
            info("  Note, only records in this INDX record will be listed")
        elif results.filetype == "image":
            pass
        else:
            pass

    if results.slack:
        info("Asked to list slack entries in INDX records")
        info("  Note, this uses a scanning heuristic to identify records. "
             "These records may be corrupt or out-of-date.")

    if results.mftlist:
        info("Asked to list active file entries in the MFT")
        if results.filetype == "indx":
            error("Cannot list MFT entries of an INDX record")

    if results.deleted:
        info("Asked to list deleted file entries in the MFT")
        if results.filetype == "indx":
            error("Cannot list MFT entries of an INDX record")

    if results.infomode:
        results.infomode = results.infomode[0]
        info("Asked to list information about path " + results.infomode)
        if results.indxlist or \
           results.slack or \
           results.mftlist or \
           results.deleted:
            error("Information mode (-i) cannot be run "
                  "with file entry list modes (-l/-s/-m/-d)")

        if results.extract:
            results.extract = results.extract[0]
            info("Asked to extract INDX_ALLOCATION attribute "
                 "for the path " + results.infomode)

    if results.extract and not results.infomode:
        warning("Extract (-e) doesn't make sense "
                "without information mode (-i)")

    if results.extract and not results.filetype == "image":
        error("Cannot extract non-resident attributes "
              "from anything but an image")

    if not (results.indxlist or
            results.slack or
            results.mftlist or
            results.deleted or
            results.infomode):
        error("You must choose a mode (-i/-l/-s/-m/-d)")

    if results.filter:
        results.filter = results.filter[0]
        info("Asked to only list file entry information "
             "for paths matching the regular expression: " + results.filter)
        if results.infomode:
            warning("This filter has no meaning with information mode (-i)")

    if results.infomode:
        print_indx_info(results)
    elif results.indxlist or \
         results.slack or \
         results.mftlist or \
         results.deleted:
        print_bodyfile(results)
Beispiel #5
0
def try_write(s):
    try:
        sys.stdout.write(s)
    except (UnicodeEncodeError, UnicodeDecodeError):
        warning("Failed to write string "
                "due to encoding issue: " + str(list(s)))
Beispiel #6
0
def main():
    parser = argparse.ArgumentParser(description='Parse NTFS '
                                     'filesystem structures.')
    parser.add_argument('-t',
                        action="store",
                        metavar="type",
                        nargs=1,
                        dest="filetype",
                        choices=["image", "MFT", "INDX", "auto"],
                        default="auto",
                        help="The type of data provided.")
    parser.add_argument('-c',
                        action="store",
                        metavar="size",
                        nargs=1,
                        type=int,
                        dest="clustersize",
                        help="Use this cluster size in bytes "
                        "(default 4096 bytes)")
    parser.add_argument('-o',
                        action="store",
                        metavar="offset",
                        nargs=1,
                        type=int,
                        dest="offset",
                        help="Offset in bytes to volume in image "
                        "(default 32256 bytes)")
    parser.add_argument('-l',
                        action="store_true",
                        dest="indxlist",
                        help="List file entries in INDX records")
    parser.add_argument('-s',
                        action="store_true",
                        dest="slack",
                        help="List file entries in INDX slack space")
    parser.add_argument('-m',
                        action="store_true",
                        dest="mftlist",
                        help="List file entries for active MFT records")
    parser.add_argument('-d',
                        action="store_true",
                        dest="deleted",
                        help="List file entries for MFT records "
                        "marked as deleted")
    parser.add_argument('-i',
                        action="store",
                        metavar="path|inode",
                        nargs=1,
                        dest="infomode",
                        help="Print information about a path's INDX records")
    parser.add_argument('-e',
                        action="store",
                        metavar="i30",
                        nargs=1,
                        dest="extract",
                        help="Used with -i, extract INDX_ALLOCATION "
                        "attribute to a file")
    parser.add_argument('-f',
                        action="store",
                        metavar="regex",
                        nargs=1,
                        dest="filter",
                        help="Only consider entries whose path "
                        "matches this regular expression")
    parser.add_argument('-p',
                        action="store",
                        metavar="prefix",
                        nargs=1,
                        dest="prefix",
                        help="Prefix paths with `prefix` rather than \\.\\")
    parser.add_argument('--progress',
                        action="store_true",
                        dest="progress",
                        help="Update a status indicator on STDERR "
                        "if STDOUT is redirected")
    parser.add_argument('-v',
                        action="store_true",
                        dest="verbose",
                        help="Print debugging information")
    parser.add_argument('filename',
                        action="store",
                        help="Input INDX file path")

    results = parser.parse_args()

    global verbose
    verbose = results.verbose

    if results.filetype and results.filetype != "auto":
        results.filetype = results.filetype[0].lower()
        info("Asked to process a file with type: " + results.filetype)
    else:
        with open(results.filename, "rb") as f:
            b = f.read(1024)
            if b[0:4] == "FILE":
                results.filetype = "mft"
            elif b[0:4] == "INDX":
                results.filetype = "indx"
            else:
                results.filetype = "image"
        info("Auto-detected input file type: " + results.filetype)

    if results.clustersize:
        results.clustersize = results.clustersize[0]
        info("Using explicit file system cluster size %s (%s) bytes" %
             (str(results.clustersize), hex(results.clustersize)))
    else:
        results.clustersize = 4096
        info("Assuming file system cluster size %s (%s) bytes" %
             (str(results.clustersize), hex(results.clustersize)))

    if results.offset:
        results.offset = results.offset[0]
        info("Using explicit volume offset %s (%s) bytes" %
             (str(results.offset), hex(results.offset)))
    else:
        results.offset = 32256
        info("Assuming volume offset %s (%s) bytes" %
             (str(results.offset), hex(results.offset)))

    if results.prefix:
        results.prefix = results.prefix[0]
        info("Using path prefix " + results.prefix)

    if results.indxlist:
        info("Asked to list entries in INDX records")
        if results.filetype == "mft":
            info("  Note, only resident INDX records can be processed "
                 "with an MFT input file")
            info("  If you find an interesting record, "
                 "use -i to identify the relevant INDX record clusters")
        elif results.filetype == "indx":
            info("  Note, only records in this INDX record will be listed")
        elif results.filetype == "image":
            pass
        else:
            pass

    if results.slack:
        info("Asked to list slack entries in INDX records")
        info("  Note, this uses a scanning heuristic to identify records. "
             "These records may be corrupt or out-of-date.")

    if results.mftlist:
        info("Asked to list active file entries in the MFT")
        if results.filetype == "indx":
            error("Cannot list MFT entries of an INDX record")

    if results.deleted:
        info("Asked to list deleted file entries in the MFT")
        if results.filetype == "indx":
            error("Cannot list MFT entries of an INDX record")

    if results.infomode:
        results.infomode = results.infomode[0]
        info("Asked to list information about path " + results.infomode)
        if results.indxlist or \
           results.slack or \
           results.mftlist or \
           results.deleted:
            error("Information mode (-i) cannot be run "
                  "with file entry list modes (-l/-s/-m/-d)")

        if results.extract:
            results.extract = results.extract[0]
            info("Asked to extract INDX_ALLOCATION attribute "
                 "for the path " + results.infomode)

    if results.extract and not results.infomode:
        warning("Extract (-e) doesn't make sense "
                "without information mode (-i)")

    if results.extract and not results.filetype == "image":
        error("Cannot extract non-resident attributes "
              "from anything but an image")

    if not (results.indxlist or results.slack or results.mftlist
            or results.deleted or results.infomode):
        error("You must choose a mode (-i/-l/-s/-m/-d)")

    if results.filter:
        results.filter = results.filter[0]
        info("Asked to only list file entry information "
             "for paths matching the regular expression: " + results.filter)
        if results.infomode:
            warning("This filter has no meaning with information mode (-i)")

    if results.infomode:
        print_indx_info(results)
    elif results.indxlist or \
         results.slack or \
         results.mftlist or \
         results.deleted:
        print_bodyfile(results)
Beispiel #7
0
def try_write(s):
    try:
        sys.stdout.write(s)
    except (UnicodeEncodeError, UnicodeDecodeError):
        warning("Failed to write string "
                "due to encoding issue: " + str(list(s)))