コード例 #1
0
ファイル: file.c プロジェクト: uw-dims/tsk4j
/*
 * Class:     edu_uw_apl_commons_tsk4j_filesys_File
 * Method:    walk
 * Signature: (JILedu/uw/apl/commons/tsk4j/filesys/File/Walk;)I
 */
JNIEXPORT jint JNICALL Java_edu_uw_apl_commons_tsk4j_filesys_File_walk
(JNIEnv *env, jobject thiz, jlong nativePtr, jint flags, jobject walk ) {

  // We need three handles in the callback, so package them here.  Gruesome!
  void* vs[3] = { env, thiz, walk };

  TSK_FS_FILE* fsFile = (TSK_FS_FILE*)nativePtr;
  
  return (jint)tsk_fs_file_walk( fsFile, flags, fileWalkCallback, (void*)vs );
}
コード例 #2
0
static TSK_WALK_RET_ENUM
count_slack_inode_act(TSK_FS_FILE * fs_file, void *ptr)
{
    BLKCALC_DATA *data = (BLKCALC_DATA *) ptr;

    if (tsk_verbose)
        tsk_fprintf(stderr,
            "count_slack_inode_act: Processing meta data: %" PRIuINUM
            "\n", fs_file->meta->addr);

    /* We will now do a file walk on the content */
    if (TSK_FS_TYPE_ISNTFS(fs_file->fs_info->ftype) == 0) {
        data->flen = fs_file->meta->size;
        if (tsk_fs_file_walk(fs_file,
                TSK_FS_FILE_WALK_FLAG_SLACK, count_slack_file_act, ptr)) {

            /* ignore any errors */
            if (tsk_verbose)
                tsk_fprintf(stderr, "Error walking file %" PRIuINUM,
                    fs_file->meta->addr);
            tsk_error_reset();
        }
    }

    /* For NTFS we go through each non-resident attribute */
    else {
        int i, cnt;

        cnt = tsk_fs_file_attr_getsize(fs_file);
        for (i = 0; i < cnt; i++) {
            const TSK_FS_ATTR *fs_attr =
                tsk_fs_file_attr_get_idx(fs_file, i);
            if (!fs_attr)
                continue;

            if (fs_attr->flags & TSK_FS_ATTR_NONRES) {
                data->flen = fs_attr->size;
                if (tsk_fs_file_walk_type(fs_file, fs_attr->type,
                        fs_attr->id, TSK_FS_FILE_WALK_FLAG_SLACK,
                        count_slack_file_act, ptr)) {
                    /* ignore any errors */
                    if (tsk_verbose)
                        tsk_fprintf(stderr,
                            "Error walking file %" PRIuINUM,
                            fs_file->meta->addr);
                    tsk_error_reset();
                }
            }
        }
    }
    return TSK_WALK_CONT;
}
コード例 #3
0
ファイル: fs_file.c プロジェクト: sleuthkit/sleuthkit
/**
 * Returns a string containing the md5 hash of the given file
 *
 * @param a_fs_file The file to calculate the hash of
 * @param a_hash_results The results will be stored here (must be allocated beforehand)
 * @param a_flags Indicates which hash algorithm(s) to use
 * @returns 0 on success or 1 on error
 */
extern uint8_t
tsk_fs_file_hash_calc(TSK_FS_FILE * a_fs_file,
    TSK_FS_HASH_RESULTS * a_hash_results, TSK_BASE_HASH_ENUM a_flags)
{
    TSK_FS_HASH_DATA hash_data;

    if ((a_fs_file == NULL) || (a_fs_file->fs_info == NULL)
        || (a_fs_file->meta == NULL)) {
        tsk_error_set_errno(TSK_ERR_FS_ARG);
        tsk_error_set_errstr("tsk_fs_file_hash_calc: fs_info is NULL");
        return 1;
    }

    if (a_hash_results == NULL) {
        tsk_error_set_errno(TSK_ERR_FS_ARG);
        tsk_error_set_errstr
            ("tsk_fs_file_hash_calc: hash_results is NULL");
        return 1;
    }

    if (a_flags & TSK_BASE_HASH_MD5) {
        TSK_MD5_Init(&(hash_data.md5_context));
    }
    if (a_flags & TSK_BASE_HASH_SHA1) {
        TSK_SHA_Init(&(hash_data.sha1_context));
    }

    hash_data.flags = a_flags;
    if (tsk_fs_file_walk(a_fs_file, TSK_FS_FILE_WALK_FLAG_NONE,
            tsk_fs_file_hash_calc_callback, (void *) &hash_data)) {
        tsk_error_set_errno(TSK_ERR_FS_ARG);
        tsk_error_set_errstr("tsk_fs_file_hash_calc: error in file walk");
        return 1;
    }

    a_hash_results->flags = a_flags;
    if (a_flags & TSK_BASE_HASH_MD5) {
        TSK_MD5_Final(a_hash_results->md5_digest,
            &(hash_data.md5_context));
    }
    if (a_flags & TSK_BASE_HASH_SHA1) {
        TSK_SHA_Final(a_hash_results->sha1_digest,
            &(hash_data.sha1_context));
    }

    return 0;
}
コード例 #4
0
/* Place journal data in *fs
 *
 * Return 0 on success and 1 on error 
 * */
uint8_t
ext2fs_jopen(TSK_FS_INFO * fs, TSK_INUM_T inum)
{
    EXT2FS_INFO *ext2fs = (EXT2FS_INFO *) fs;
    EXT2FS_JINFO *jinfo;

    // clean up any error messages that are lying around
    tsk_error_reset();

    if (!fs) {
        tsk_error_reset();
        tsk_errno = TSK_ERR_FS_ARG;
        snprintf(tsk_errstr, TSK_ERRSTR_L, "ext2fs_jopen: fs is null");
        return 1;
    }

    ext2fs->jinfo = jinfo =
        (EXT2FS_JINFO *) tsk_malloc(sizeof(EXT2FS_JINFO));
    if (jinfo == NULL) {
        return 1;
    }
    jinfo->j_inum = inum;

    jinfo->fs_file = tsk_fs_file_open_meta(fs, NULL, inum);
    if (!jinfo->fs_file) {
        free(jinfo);
        return 1;
//      error("error finding journal inode %" PRIu32, inum);
    }

    if (tsk_fs_file_walk(jinfo->fs_file, 0, load_sb_action, NULL)) {
        tsk_error_reset();
        tsk_errno = TSK_ERR_FS_FWALK;
        snprintf(tsk_errstr, TSK_ERRSTR_L, "Error loading ext3 journal");
        tsk_fs_file_close(jinfo->fs_file);
        free(jinfo);
        return 1;
    }

    if (tsk_verbose)
        tsk_fprintf(stderr,
            "journal opened at inode %" PRIuINUM " bsize: %" PRIu32
            " First JBlk: %" PRIuDADDR " Last JBlk: %" PRIuDADDR "\n",
            inum, jinfo->bsize, jinfo->first_block, jinfo->last_block);

    return 0;
}
コード例 #5
0
ファイル: icat_lib.c プロジェクト: TheLoneRanger14/vmxray
/* Return 1 on error and 0 on success */
uint8_t
tsk_fs_icat(TSK_FS_INFO * fs, TSK_INUM_T inum,
    TSK_FS_ATTR_TYPE_ENUM type, uint8_t type_used,
    uint16_t id, uint8_t id_used, TSK_FS_FILE_WALK_FLAG_ENUM flags)
{
    TSK_FS_FILE *fs_file;

#ifdef TSK_WIN32
    if (-1 == _setmode(_fileno(stdout), _O_BINARY)) {
        tsk_error_reset();
        tsk_errno = TSK_ERR_FS_WRITE;
        snprintf(tsk_errstr, TSK_ERRSTR_L,
            "icat_lib: error setting stdout to binary: %s",
            strerror(errno));
        return 1;
    }
#endif

    fs_file = tsk_fs_file_open_meta(fs, NULL, inum);
    if (!fs_file) {
        return 1;
    }

    if (type_used) {
        if (id_used == 0) {
            flags |= TSK_FS_FILE_WALK_FLAG_NOID;
        }
        if (tsk_fs_file_walk_type(fs_file, type, id, flags, icat_action,
                NULL)) {
            tsk_fs_file_close(fs_file);
            return 1;
        }
    }
    else {
        if (tsk_fs_file_walk(fs_file, flags, icat_action, NULL)) {
            tsk_fs_file_close(fs_file);
            return 1;
        }
    }


    tsk_fs_file_close(fs_file);

    return 0;
}
コード例 #6
0
ファイル: read_apis.cpp プロジェクト: TheLoneRanger14/vmxray
int
testfile(TSK_FS_INFO * a_fs, TSK_INUM_T a_inum)
{
    TSK_FS_FILE *file1 = NULL;

    if ((s_buf = (char *) malloc(a_fs->block_size)) == NULL) {
        fprintf(stderr, "Error allocating  memory\n");
        return 1;
    }

    file1 = tsk_fs_file_open_meta(a_fs, NULL, a_inum);
    if (file1 == NULL) {
        fprintf(stderr, "Error opening inode %" PRIuINUM "\n", a_inum);
        return 1;
    }

    s_file2 = tsk_fs_file_open_meta(a_fs, NULL, a_inum);
    if (s_file2 == NULL) {
        fprintf(stderr, "Error opening inode %" PRIuINUM "\n", a_inum);
        return 1;
    }

    s_off = 0;
    if (tsk_fs_file_walk(file1, (TSK_FS_FILE_WALK_FLAG_ENUM) 0,
            fw_action1, NULL)) {
        fprintf(stderr, "Error walking file inode: %" PRIuINUM "\n",
            a_inum);
        tsk_error_print(stderr);
        tsk_error_reset();
        return 1;
    }

    free(s_buf);
    tsk_fs_file_close(file1);
    tsk_fs_file_close(s_file2);
    return 0;
}
コード例 #7
0
ファイル: ffs_dent.c プロジェクト: nrv3/sleuthkit
/** \internal
 * Process a directory and load up FS_DIR with the entries. If a pointer to
 * an already allocated FS_DIR struture is given, it will be cleared.  If no existing
 * FS_DIR structure is passed (i.e. NULL), then a new one will be created. If the return
 * value is error or corruption, then the FS_DIR structure could
 * have entries (depending on when the error occured).
 *
 * @param a_fs File system to analyze
 * @param a_fs_dir Pointer to FS_DIR pointer. Can contain an already allocated
 * structure or a new structure.
 * @param a_addr Address of directory to process.
 * @returns error, corruption, ok etc.
 */
TSK_RETVAL_ENUM
ffs_dir_open_meta(TSK_FS_INFO * a_fs, TSK_FS_DIR ** a_fs_dir,
                  TSK_INUM_T a_addr)
{
    TSK_OFF_T size;
    FFS_INFO *ffs = (FFS_INFO *) a_fs;
    char *dirbuf;
    int nchnk, cidx;
    TSK_FS_LOAD_FILE load_file;
    TSK_FS_DIR *fs_dir;

    /* If we get corruption in one of the blocks, then continue processing.
     * retval_final will change when corruption is detected.  Errors are
     * returned immediately. */
    TSK_RETVAL_ENUM retval_tmp;
    TSK_RETVAL_ENUM retval_final = TSK_OK;


    if (a_addr < a_fs->first_inum || a_addr > a_fs->last_inum) {
        tsk_error_reset();
        tsk_error_set_errno(TSK_ERR_FS_WALK_RNG);
        tsk_error_set_errstr("ffs_dir_open_meta: Invalid inode value: %"
                             PRIuINUM, a_addr);
        return TSK_ERR;
    }
    else if (a_fs_dir == NULL) {
        tsk_error_reset();
        tsk_error_set_errno(TSK_ERR_FS_ARG);
        tsk_error_set_errstr
        ("ffs_dir_open_meta: NULL fs_attr argument given");
        return TSK_ERR;
    }

    if (tsk_verbose)
        tsk_fprintf(stderr,
                    "ffs_dir_open_meta: Processing directory %" PRIuINUM "\n",
                    a_addr);

    fs_dir = *a_fs_dir;
    if (fs_dir) {
        tsk_fs_dir_reset(fs_dir);
    }
    else {
        if ((*a_fs_dir = fs_dir =
                             tsk_fs_dir_alloc(a_fs, a_addr, 128)) == NULL) {
            return TSK_ERR;
        }
    }

    //  handle the orphan directory if its contents were requested
    if (a_addr == TSK_FS_ORPHANDIR_INUM(a_fs)) {
        return tsk_fs_dir_find_orphans(a_fs, fs_dir);
    }

    if ((fs_dir->fs_file =
                tsk_fs_file_open_meta(a_fs, NULL, a_addr)) == NULL) {
        tsk_error_reset();
        tsk_error_errstr2_concat("- ffs_dir_open_meta");
        return TSK_COR;
    }

    /* make a copy of the directory contents that we can process */
    /* round up cause we want the slack space too */
    size = roundup(fs_dir->fs_file->meta->size, FFS_DIRBLKSIZ);
    if ((dirbuf = tsk_malloc((size_t) size)) == NULL) {
        return TSK_ERR;
    }

    load_file.total = load_file.left = (size_t) size;
    load_file.base = load_file.cur = dirbuf;

    if (tsk_fs_file_walk(fs_dir->fs_file,
                         TSK_FS_FILE_WALK_FLAG_SLACK,
                         tsk_fs_load_file_action, (void *) &load_file)) {
        tsk_error_reset();
        tsk_error_errstr2_concat("- ffs_dir_open_meta");
        free(dirbuf);
        return TSK_COR;
    }

    /* Not all of the directory was copied, so we return */
    if (load_file.left > 0) {
        tsk_error_reset();
        tsk_error_set_errno(TSK_ERR_FS_FWALK);
        tsk_error_set_errstr("ffs_dir_open_meta: Error reading directory %"
                             PRIuINUM, a_addr);
        free(dirbuf);
        return TSK_COR;
    }

    /* Directory entries are written in chunks of DIRBLKSIZ
     ** determine how many chunks of this size we have to read to
     ** get a full block
     **
     ** Entries do not cross over the DIRBLKSIZ boundary
     */
    nchnk = (int) (size) / (FFS_DIRBLKSIZ) + 1;

    for (cidx = 0; cidx < nchnk && (int64_t) size > 0; cidx++) {
        int len = (FFS_DIRBLKSIZ < size) ? FFS_DIRBLKSIZ : (int) size;

        retval_tmp =
            ffs_dent_parse_block(ffs, fs_dir,
                                 (fs_dir->fs_file->
                                  meta->flags & TSK_FS_META_FLAG_UNALLOC) ? 1 : 0,
                                 dirbuf + cidx * FFS_DIRBLKSIZ, len);

        if (retval_tmp == TSK_ERR) {
            retval_final = TSK_ERR;
            break;
        }
        else if (retval_tmp == TSK_COR) {
            retval_final = TSK_COR;
        }
        size -= len;
    }
    free(dirbuf);

    // if we are listing the root directory, add the Orphan directory entry
    if (a_addr == a_fs->root_inum) {
        TSK_FS_NAME *fs_name = tsk_fs_name_alloc(256, 0);
        if (fs_name == NULL)
            return TSK_ERR;

        if (tsk_fs_dir_make_orphan_dir_name(a_fs, fs_name)) {
            tsk_fs_name_free(fs_name);
            return TSK_ERR;
        }

        if (tsk_fs_dir_add(fs_dir, fs_name)) {
            tsk_fs_name_free(fs_name);
            return TSK_ERR;
        }
        tsk_fs_name_free(fs_name);
    }

    return retval_final;
}
コード例 #8
0
ファイル: fiwalk_tsk.cpp プロジェクト: sleuthkit/sleuthkit
static uint8_t
process_tsk_file(TSK_FS_FILE * fs_file, const char *path)
{
    /* Use a flag to determine if a file is generically fit for plugins. */
    bool can_run_plugin;

    /* Make sure that the SleuthKit structures are properly set */
    if (fs_file->name == NULL)
        return 1;
    if (fs_file->meta == NULL && opt_debug)
        printf("File: %s %s  has no meta\n", path, fs_file->name->name);

    /* SleuthKit meta types are defined in tsk_fs.h.*/

    if (opt_debug) printf("Processing %s%s type=%s (0x%x) \n",
                              path, fs_file->name->name,
                              tsk_fs_name_type_str[fs_file->name->type],fs_file->name->type);

    /* Recover the filename from the fs_dent, if it is provided */
    content ci(fs_file->fs_info->img_info);	// where the content will go
    ci.evidence_dirname = path;
    ci.set_filename(fs_file->name->name);

    /* If we are filtering and we have a filename, see if we want this file. */
    if (ci.name_filtered()) return 0;

    /* Looks like we are processing */
    if(a) a->new_row();			// tell ARFF we are starting a new row
    if(x) x->push("fileobject"); 	// tell XML we are starting a new XML object
    if(opt_parent_tracking)
    {
        if(fs_file->name->par_addr) {
            if(x)
            {
                x->push("parent_object");
                file_info("inode", fs_file->name->par_addr);
                if(x) x->pop();
            }
            if((t||a) && !opt_body_file)
            {
                file_info("parent_inode", fs_file->name->par_addr);
            }
        }
    }

    if(fs_file->meta != NULL)
    {
        /* Get the content if needed */
        if(ci.need_file_walk() && (opt_maxgig==0 || fs_file->meta->size/1000000000 < opt_maxgig)) {
            int myflags = TSK_FS_FILE_WALK_FLAG_NOID;
            if (opt_no_data) myflags |= TSK_FS_FILE_WALK_FLAG_AONLY;
            if (tsk_fs_file_walk (fs_file, (TSK_FS_FILE_WALK_FLAG_ENUM) myflags, file_act, (void *) &ci)) {

                // ignore errors from deleted files that were being recovered
                //if (tsk_errno != TSK_ERR_FS_RECOVER) {
                if (tsk_error_get_errno() != TSK_ERR_FS_RECOVER) {
                    if(opt_debug) {
                        fprintf(stderr,"Processing: %s/%s (%" PRIuINUM ")\n", path,
                                fs_file->name->name, fs_file->meta->addr);
                        tsk_error_print(stderr);
                    }
                }
                tsk_error_reset();
            }
        }
    }

    if(file_count_max && file_count>file_count_max) return TSK_WALK_STOP;
    file_count++;

    /* Send through to the plugin if we were doing that.
     * Currently results only go to ARFF file, not to the XML file.
     */

    /* Finally output the informaton */
    if(opt_body_file && (fs_file->meta != NULL)) {
        char ls[64];
        tsk_fs_meta_make_ls(fs_file->meta,ls,sizeof(ls));
        fprintf(t,"%s|%s|%" PRId64 "|%s|%d|%d|%" PRId64 "|%d|%d|%d|%d\n",
                ci.h_md5.final().hexdigest().c_str(),ci.filename().c_str(),fs_file->meta->addr,
                ls,fs_file->meta->uid,fs_file->meta->gid,
                fs_file->meta->size,
                (uint32_t)(fs_file->meta->atime),
                (uint32_t)fs_file->meta->mtime,
                (uint32_t)fs_file->meta->ctime,
                (uint32_t)fs_file->meta->crtime);
        return TSK_WALK_CONT;
    }
コード例 #9
0
/**
 * Populates the buffer with the contents of the specified filename.
 *
 * \param id_number The id number of the file (in our case the inode)
 * \param filename The real filename for this file.
 * \param buf The buffer to write data into
 * \param size The size of the buffer
 * \param offset The offset into the file the data should be taken from.
 * \returns The amount of bytes read, or -1 on error.
 */
int do_read(unsigned int id_number, const char *filename, char *buf, size_t size, off_t offset)
{
//FILE* outfile = fopen("/tmp/sleuth.txt", "a");
//fprintf(outfile, "do_read(%u, %s, %p, %zu, %zu);\n", id_number, filename, buf, size, offset);
//fflush(outfile);
//fprintf(outfile, "inode_buffer=%p, inode_buffered=%lld, inode_buf_pos=%llu, end=%llu\n", inode_buffer, inode_buffered, inode_buffer_pos, inode_buffer_pos + inode_buffer_size);
//fflush(outfile);
  // If the data is already cached in our buffer then read from that instead
  if ((inode_buffer != NULL) && (id_number == inode_buffered) && (offset >= inode_buffer_pos) && (offset < inode_buffer_pos + inode_buffer_size))
  {
    if ((offset + size) <= (inode_buffer_pos + inode_buffer_size))
    {
      offset = offset % BUFFER_AMOUNT;
      memcpy(buf, inode_buffer + offset, size);
//fprintf(outfile, "Fully cached!\n");
//fclose(outfile);
      return size;
    }
    // If we're here then we've cached part of the data needed, but not all of it
    // (ie, the data requested spans a block boundary)
    offset = offset % BUFFER_AMOUNT;
    memcpy(buf, inode_buffer + offset, inode_buffer_size - offset);
    int ret_size = inode_buffer_size - offset;

    ret_size += do_read(id_number, filename, buf + ret_size, size - ret_size, inode_buffer_pos + inode_buffer_size);
//fprintf(outfile, "Partially cached: Size = %d\n", ret_size);
//fclose(outfile);
    return ret_size;
  }

  TSK_FS_FILE *fs_file = tsk_fs_file_open_meta(fs_info, NULL, id_number);

  if (fs_file == NULL)
  {
//fprintf(outfile, "FS file not found?\n");
//fclose(outfile);
    return -1;
  }
  // If the file is larger than FILE_SIZE_THRESHOLD, and the offset is larger 
  // than FILE_OFFSET_THRESHOLD, buffer up BUFFER_AMOUNT and return from that

  if (fs_file->meta != NULL)
  {
//fprintf(outfile, "File size is %" PRIdDADDR" bytes\n", fs_file->meta->size);
//fflush(outfile);
    if (offset >= fs_file->meta->size)
    {
//fprintf(outfile, "Reading beyond end of file\n");
//fclose(outfile);
      return 0;
    }
    if ((fs_file->meta->size >= FILE_SIZE_THRESHOLD) && (offset >= FILE_OFFSET_THRESHOLD))
    {
      if (inode_buffer == NULL)
      {
        inode_buffer = (unsigned char *) g_malloc(BUFFER_AMOUNT);
      }
      inode_buffered = id_number;
      inode_buffer_pos = (offset / BUFFER_AMOUNT) * BUFFER_AMOUNT;

      struct read_struct r;

      r.buf = inode_buffer;
      r.offset = inode_buffer_pos;
      r.size = BUFFER_AMOUNT;
      r.read = 0;

//fprintf(outfile, "Caching data...offset = %zu, size =%zu\n", r.offset, r.size);
//fflush(outfile);
      tsk_fs_file_walk(fs_file, TSK_FS_FILE_WALK_FLAG_NONE, read_file_content_callback, &r);

      inode_buffer_size = r.read;
//fprintf(outfile, "Recursing to read data\n");
//fclose(outfile);
      return do_read(id_number, filename, buf, size, offset);
    }
  }

  struct read_struct r;

  r.buf = (unsigned char *) buf;
  r.offset = offset;
  r.size = size;
  r.read = 0;

  tsk_fs_file_walk(fs_file, TSK_FS_FILE_WALK_FLAG_NONE, read_file_content_callback, &r);
  tsk_fs_file_close(fs_file);

//fprintf(outfile, "Simple read %zu\n", r.read);
//fclose(outfile);
  return r.read;
}
コード例 #10
0
/**
 * Populates the result reference with the supplied file and its details.
 *
 * \param r The result reference to populate.
 * \param fs_file The file to populate into the result structure
 * \param a_path The path containing the file.
 */
static void populate_sleuth_result(result_t r, TSK_FS_FILE * fs_file, const char *a_path)
{
  if ((fs_file->meta == NULL) || (fs_file->meta->size == 0))
  {
    return;
  }

  if (fs_file->name->flags == TSK_FS_NAME_FLAG_UNALLOC)
  {
    debug_log("Not allocated: %" PRIdINUM " -> %s", fs_file->name->meta_addr, fs_file->name->name);
    return;
  }
  // Removing '.' and '..' entries
  if (fs_file->name->name[0] == '.')
  {
    if (fs_file->name->name[1] == '\0')
    {
      return;
    } else if (fs_file->name->name[1] == '.')
    {
      if (fs_file->name->name[2] == '\0')
      {
        return;
      }
    }
  }

  if (inode_lookup == NULL)
  {
    inode_lookup = g_tree_new_full((GCompareDataFunc) unsigned_long_long_compare, NULL, g_free, NULL);
  }

  if (g_tree_lookup(inode_lookup, &(fs_file->name->meta_addr)) != NULL)
  {
    // This can happen if we have a directory and a child of that directory called '..'
    // Or we have a hard link on the filesystem
    debug_log("Duplicate inode detected: %" PRIdINUM " -> %s", fs_file->name->meta_addr, fs_file->name->name);
    return;
  }
  unsigned long long *l = (unsigned long long *) g_malloc(sizeof(unsigned long long));

  *l = fs_file->name->meta_addr;
  g_tree_insert(inode_lookup, l, NULL);

  // No point walking the filesystem if it's not needed
  if (r != NULL)
  {
    contract_t c = contract_init(NULL, 0);

    char *inode_string = g_strdup_printf("%s/%" PRIdINUM, mountpoint, fs_file->name->meta_addr);

    contract_set_path(c, inode_string);
    g_free(inode_string);

    // We can't guarantee the file is contiguous
    contract_set_contiguous(c, 0);

    // Only do this if the original_contract is on contiguous space
    if ((is_contiguous == 1) && (absolute_offset >= 0))
    {
      // Getting the block list
      tsk_fs_file_walk(fs_file, TSK_FS_FILE_WALK_FLAG_SLACK, (TSK_FS_FILE_WALK_CB) walk_file, c);
    }

    if (fs_file->meta->type == TSK_FS_META_TYPE_REG)
    {
      // Only add it if it's actually a file
      result_add_new_contract(r, c);
    }
    contract_close(c);
  }

  // Add it to the virtual filesystem
  char* full_file_path = g_strdup_printf("%s%s", a_path, fs_file->name->name);
  add_file(fs_file->name->meta_addr, full_file_path, fs_file->meta->size);
  g_free(full_file_path);
}
コード例 #11
0
TSK_RETVAL_ENUM
fatfs_dir_open_meta(TSK_FS_INFO * a_fs, TSK_FS_DIR ** a_fs_dir,
    TSK_INUM_T a_addr)
{
    TSK_OFF_T size, len;
    FATFS_INFO *fatfs = (FATFS_INFO *) a_fs;
    char *dirbuf;
    TSK_DADDR_T *addrbuf;
    FATFS_LOAD_DIR load;
    int retval;

    TSK_FS_DIR *fs_dir;

    if ((a_addr < a_fs->first_inum) || (a_addr > a_fs->last_inum)) {
        tsk_error_reset();
        tsk_error_set_errno(TSK_ERR_FS_WALK_RNG);
        tsk_error_set_errstr("fatfs_dir_open_meta: invalid a_addr value: %"
            PRIuINUM "\n", a_addr);
        return TSK_ERR;
    }
    else if (a_fs_dir == NULL) {
        tsk_error_reset();
        tsk_error_set_errno(TSK_ERR_FS_ARG);
        tsk_error_set_errstr
            ("fatfs_dir_open_meta: NULL fs_attr argument given");
        return TSK_ERR;
    }

    fs_dir = *a_fs_dir;
    if (fs_dir) {
        tsk_fs_dir_reset(fs_dir);
    }
    else {
        if ((*a_fs_dir = fs_dir =
                tsk_fs_dir_alloc(a_fs, a_addr, 128)) == NULL) {
            return TSK_ERR;
        }
    }

    //  handle the orphan directory if its contents were requested
    if (a_addr == TSK_FS_ORPHANDIR_INUM(a_fs)) {
        return tsk_fs_dir_find_orphans(a_fs, fs_dir);
    }

    fs_dir->fs_file = tsk_fs_file_open_meta(a_fs, NULL, a_addr);
    if (fs_dir->fs_file == NULL) {
        tsk_error_reset();
        tsk_error_set_errno(TSK_ERR_FS_INODE_NUM);
        tsk_error_set_errstr("fatfs_dir_open_meta: %" PRIuINUM
            " is not a valid inode", a_addr);
        return TSK_COR;
    }

    size = fs_dir->fs_file->meta->size;
    len = roundup(size, fatfs->ssize);

    if (tsk_verbose)
        tsk_fprintf(stderr,
            "fatfs_dir_open_meta: Processing directory %" PRIuINUM "\n",
            a_addr);

    if (size == 0) {
        if (tsk_verbose)
            tsk_fprintf(stderr,
                "fatfs_dir_open_meta: directory has 0 size\n");
        return TSK_OK;
    }

    /* Make a copy of the directory contents using file_walk */
    if ((dirbuf = tsk_malloc((size_t) len)) == NULL) {
        return TSK_ERR;
    }
    load.curdirptr = dirbuf;
    load.dirleft = (size_t) size;

    /* We are going to save the address of each sector in the directory
     * in a stack - they are needed to determine the inode address.
     */
    load.addrsize = (size_t) (len / fatfs->ssize);
    addrbuf =
        (TSK_DADDR_T *) tsk_malloc(load.addrsize * sizeof(TSK_DADDR_T));
    if (addrbuf == NULL) {
        free(dirbuf);
        return TSK_ERR;
    }

    /* Set the variables that are used during the copy */
    load.addridx = 0;
    load.addrbuf = addrbuf;

    /* save the directory contents into dirbuf */
    if (tsk_fs_file_walk(fs_dir->fs_file,
            TSK_FS_FILE_WALK_FLAG_SLACK,
            fatfs_dent_action, (void *) &load)) {
        tsk_error_errstr2_concat("- fatfs_dir_open_meta");
        free(dirbuf);
        free(addrbuf);
        return TSK_COR;
    }

    /* We did not copy the entire directory, which occurs if an error occured */
    if (load.dirleft > 0) {
        tsk_error_reset();
        tsk_error_set_errno(TSK_ERR_FS_FWALK);
        tsk_error_set_errstr
            ("fatfs_dir_open_meta: Error reading directory %" PRIuINUM,
            a_addr);

        /* Free the local buffers */
        free(dirbuf);
        free(addrbuf);
        return TSK_COR;
    }

    if (tsk_verbose)
        fprintf(stderr,
            "fatfs_dir_open_meta: Parsing directory %" PRIuINUM "\n",
            a_addr);

    retval = fatfs_dent_parse_buf(fatfs, fs_dir, dirbuf, len, addrbuf);

    free(dirbuf);
    free(addrbuf);

    // if we are listing the root directory, add the Orphan directory and special FAT file entries
    if (a_addr == a_fs->root_inum) {
        TSK_FS_NAME *fs_name = tsk_fs_name_alloc(256, 0);
        if (fs_name == NULL)
            return TSK_ERR;

        // MBR Entry
        strncpy(fs_name->name, FATFS_MBRNAME, fs_name->name_size);
        fs_name->meta_addr = FATFS_MBRINO(a_fs);
        fs_name->type = TSK_FS_NAME_TYPE_VIRT;
        fs_name->flags = TSK_FS_NAME_FLAG_ALLOC;
        if (tsk_fs_dir_add(fs_dir, fs_name)) {
            tsk_fs_name_free(fs_name);
            return TSK_ERR;
        }

        // FAT1 Entry
        strncpy(fs_name->name, FATFS_FAT1NAME, fs_name->name_size);
        fs_name->meta_addr = FATFS_FAT1INO(a_fs);
        fs_name->type = TSK_FS_NAME_TYPE_VIRT;
        fs_name->flags = TSK_FS_NAME_FLAG_ALLOC;
        if (tsk_fs_dir_add(fs_dir, fs_name)) {
            tsk_fs_name_free(fs_name);
            return TSK_ERR;
        }

        // FAT2 Entry
        strncpy(fs_name->name, FATFS_FAT2NAME, fs_name->name_size);
        fs_name->meta_addr = FATFS_FAT2INO(a_fs);
        fs_name->type = TSK_FS_NAME_TYPE_VIRT;
        fs_name->flags = TSK_FS_NAME_FLAG_ALLOC;
        if (tsk_fs_dir_add(fs_dir, fs_name)) {
            tsk_fs_name_free(fs_name);
            return TSK_ERR;
        }

        // orphan directory
        if (tsk_fs_dir_make_orphan_dir_name(a_fs, fs_name)) {
            tsk_fs_name_free(fs_name);
            return TSK_ERR;
        }
        if (tsk_fs_dir_add(fs_dir, fs_name)) {
            tsk_fs_name_free(fs_name);
            return TSK_ERR;
        }
        tsk_fs_name_free(fs_name);
    }

    return retval;
}
コード例 #12
0
ファイル: ext2fs_dent.c プロジェクト: 0xkasun/OpenDF
TSK_RETVAL_ENUM
ext2fs_dir_open_meta(TSK_FS_INFO * a_fs, TSK_FS_DIR ** a_fs_dir,
    TSK_INUM_T a_addr)
{
    EXT2FS_INFO *ext2fs = (EXT2FS_INFO *) a_fs;
    char *dirbuf, *dirptr;
    TSK_OFF_T size;
    TSK_FS_LOAD_FILE load_file;
    TSK_FS_DIR *fs_dir;
    TSK_LIST *list_seen = NULL;

    /* If we get corruption in one of the blocks, then continue processing.
     * retval_final will change when corruption is detected.  Errors are
     * returned immediately. */
    TSK_RETVAL_ENUM retval_tmp;
    TSK_RETVAL_ENUM retval_final = TSK_OK;

    if (a_addr < a_fs->first_inum || a_addr > a_fs->last_inum) {
        tsk_error_reset();
        tsk_error_set_errno(TSK_ERR_FS_WALK_RNG);
        tsk_error_set_errstr("ext2fs_dir_open_meta: inode value: %"
            PRIuINUM "\n", a_addr);
        return TSK_ERR;
    }
    else if (a_fs_dir == NULL) {
        tsk_error_reset();
        tsk_error_set_errno(TSK_ERR_FS_ARG);
        tsk_error_set_errstr
            ("ext2fs_dir_open_meta: NULL fs_attr argument given");
        return TSK_ERR;
    }

    if (tsk_verbose) {
        tsk_fprintf(stderr,
            "ext2fs_dir_open_meta: Processing directory %" PRIuINUM
            "\n", a_addr);
#ifdef Ext4_DBG
        tsk_fprintf(stderr,
            "ext2fs_dir_open_meta: $OrphanFiles Inum %" PRIuINUM
            " == %" PRIuINUM ": %d\n", TSK_FS_ORPHANDIR_INUM(a_fs), a_addr,
            a_addr == TSK_FS_ORPHANDIR_INUM(a_fs));
#endif
    }

    fs_dir = *a_fs_dir;
    if (fs_dir) {
        tsk_fs_dir_reset(fs_dir);
        fs_dir->addr = a_addr;
    }
    else {
        if ((*a_fs_dir = fs_dir =
                tsk_fs_dir_alloc(a_fs, a_addr, 128)) == NULL) {
            return TSK_ERR;
        }
    }

    //  handle the orphan directory if its contents were requested
    if (a_addr == TSK_FS_ORPHANDIR_INUM(a_fs)) {
#ifdef Ext4_DBG
        tsk_fprintf(stderr, "DEBUG: Getting ready to process ORPHANS\n");
#endif
        return tsk_fs_dir_find_orphans(a_fs, fs_dir);
    }
    else {
#ifdef Ext4_DBG
        tsk_fprintf(stderr,
            "DEBUG: not orphan %" PRIuINUM "!=%" PRIuINUM "\n", a_addr,
            TSK_FS_ORPHANDIR_INUM(a_fs));
#endif
    }

    if ((fs_dir->fs_file =
            tsk_fs_file_open_meta(a_fs, NULL, a_addr)) == NULL) {
        tsk_error_reset();
        tsk_error_errstr2_concat("- ext2fs_dir_open_meta");
        return TSK_COR;
    }

    size = roundup(fs_dir->fs_file->meta->size, a_fs->block_size);
    if ((dirbuf = tsk_malloc((size_t) size)) == NULL) {
        return TSK_ERR;
    }

    /* make a copy of the directory contents that we can process */
    load_file.left = load_file.total = (size_t) size;
    load_file.base = load_file.cur = dirbuf;

    if (tsk_fs_file_walk(fs_dir->fs_file,
            TSK_FS_FILE_WALK_FLAG_SLACK,
            tsk_fs_load_file_action, (void *) &load_file)) {
        tsk_error_reset();
        tsk_error_errstr2_concat("- ext2fs_dir_open_meta");
        free(dirbuf);
        return TSK_COR;
    }

    /* Not all of the directory was copied, so we exit */
    if (load_file.left > 0) {
        tsk_error_reset();
        tsk_error_set_errno(TSK_ERR_FS_FWALK);
        tsk_error_set_errstr
            ("ext2fs_dir_open_meta: Error reading directory contents: %"
            PRIuINUM "\n", a_addr);
        free(dirbuf);
        return TSK_COR;
    }
    dirptr = dirbuf;

    while ((int64_t) size > 0) {
        int len =
            (a_fs->block_size < size) ? a_fs->block_size : (int) size;

        retval_tmp =
            ext2fs_dent_parse_block(ext2fs, fs_dir,
            (fs_dir->fs_file->meta->
                flags & TSK_FS_META_FLAG_UNALLOC) ? 1 : 0, &list_seen,
            dirptr, len);

        if (retval_tmp == TSK_ERR) {
            retval_final = TSK_ERR;
            break;
        }
        else if (retval_tmp == TSK_COR) {
            retval_final = TSK_COR;
        }

        size -= len;
        dirptr = (char *) ((uintptr_t) dirptr + len);
    }
    free(dirbuf);


    // if we are listing the root directory, add the Orphan directory entry
    if (a_addr == a_fs->root_inum) {
        TSK_FS_NAME *fs_name = tsk_fs_name_alloc(256, 0);
        if (fs_name == NULL)
            return TSK_ERR;

        if (tsk_fs_dir_make_orphan_dir_name(a_fs, fs_name)) {
            tsk_fs_name_free(fs_name);
            return TSK_ERR;
        }

        if (tsk_fs_dir_add(fs_dir, fs_name)) {
            tsk_fs_name_free(fs_name);
            return TSK_ERR;
        }
        tsk_fs_name_free(fs_name);
    }

    return retval_final;
}
コード例 #13
0
/* 
 * Limitations for 1st version: start must equal end and action is ignored
 *
 * Return 0 on success and 1 on error
 */
uint8_t
ext2fs_jblk_walk(TSK_FS_INFO * fs, TSK_DADDR_T start, TSK_DADDR_T end,
    int flags, TSK_FS_JBLK_WALK_CB action, void *ptr)
{
    EXT2FS_INFO *ext2fs = (EXT2FS_INFO *) fs;
    EXT2FS_JINFO *jinfo = ext2fs->jinfo;
    char *journ;
    TSK_FS_LOAD_FILE buf1;
    TSK_DADDR_T i;
    ext2fs_journ_head *head;

    // clean up any error messages that are lying around
    tsk_error_reset();

    if ((jinfo == NULL) || (jinfo->fs_file == NULL)
        || (jinfo->fs_file->meta == NULL)) {
        tsk_error_reset();
        tsk_errno = TSK_ERR_FS_ARG;
        snprintf(tsk_errstr, TSK_ERRSTR_L,
            "ext2fs_jblk_walk: journal is not open");
        return 1;
    }

    if (jinfo->last_block < end) {
        tsk_error_reset();
        tsk_errno = TSK_ERR_FS_WALK_RNG;
        snprintf(tsk_errstr, TSK_ERRSTR_L,
            "ext2fs_jblk_walk: end is too large ");
        return 1;
    }

    if (start != end) {
        tsk_error_reset();
        tsk_errno = TSK_ERR_FS_ARG;
        snprintf(tsk_errstr, TSK_ERRSTR_L,
            "ext2fs_blk_walk: only start == end is currently supported");
        return 1;
    }

    if (jinfo->fs_file->meta->size !=
        (jinfo->last_block + 1) * jinfo->bsize) {
        tsk_error_reset();
        tsk_errno = TSK_ERR_FS_UNSUPFUNC;
        snprintf(tsk_errstr, TSK_ERRSTR_L,
            "ext2fs_jblk_walk: journal file size is different from size reported in journal super block");
        return 1;
    }


    /* Load into buffer and then process it 
     * Only get the minimum needed
     */
    buf1.left = buf1.total = (size_t) ((end + 1) * jinfo->bsize);
    journ = buf1.cur = buf1.base = tsk_malloc(buf1.left);
    if (journ == NULL) {
        return 1;
    }

    if (tsk_fs_file_walk(jinfo->fs_file, 0, tsk_fs_load_file_action,
            (void *) &buf1)) {
        free(journ);
        return 1;
    }

    if (buf1.left > 0) {
        tsk_error_reset();
        tsk_errno = TSK_ERR_FS_FWALK;
        snprintf(tsk_errstr, TSK_ERRSTR_L,
            "ext2fs_jblk_walk: Buffer not fully copied");
        free(journ);
        return 1;
    }

    head = (ext2fs_journ_head *) & journ[end * jinfo->bsize];


    /* Check if our target block is a journal data structure.
     * 
     * If not, 
     * we need to look for its descriptor to see if it has been
     * escaped
     */
    if (big_tsk_getu32(head->magic) != EXT2_JMAGIC) {

        /* cycle backwards until we find a desc block */
        for (i = end - 1; i >= 0; i--) {
            ext2fs_journ_dentry *dentry;
            TSK_DADDR_T diff;

            head = (ext2fs_journ_head *) & journ[i * jinfo->bsize];

            if (big_tsk_getu32(head->magic) != EXT2_JMAGIC)
                continue;

            /* If we get a commit, then any desc we find will not
             * be for our block, so forget about it */
            if (big_tsk_getu32(head->entry_type) == EXT2_J_ETYPE_COM)
                break;

            /* Skip any other data structure types */
            if (big_tsk_getu32(head->entry_type) != EXT2_J_ETYPE_DESC)
                continue;

            /* We now have the previous descriptor 
             *
             * NOTE: We have no clue if this is the correct 
             * descriptor if it is not the current 'run' of 
             * transactions, but this is the best we can do
             */
            diff = end - i;

            dentry =
                (ext2fs_journ_dentry *) (&journ[i * jinfo->bsize] +
                sizeof(ext2fs_journ_head));

            while ((uintptr_t) dentry <=
                ((uintptr_t) & journ[(i + 1) * jinfo->bsize] -
                    sizeof(ext2fs_journ_head))) {

                if (--diff == 0) {
                    if (big_tsk_getu32(dentry->flag) & EXT2_J_DENTRY_ESC) {
                        journ[end * jinfo->bsize] = 0xC0;
                        journ[end * jinfo->bsize + 1] = 0x3B;
                        journ[end * jinfo->bsize + 2] = 0x39;
                        journ[end * jinfo->bsize + 3] = 0x98;
                    }
                    break;
                }

                /* If the SAMEID value is set, then we advance by the size of the entry, otherwise add 16 for the ID */
                if (big_tsk_getu32(dentry->flag) & EXT2_J_DENTRY_SAMEID)
                    dentry =
                        (ext2fs_journ_dentry *) ((uintptr_t) dentry +
                        sizeof(ext2fs_journ_dentry));
                else
                    dentry =
                        (ext2fs_journ_dentry *) ((uintptr_t) dentry +
                        sizeof(ext2fs_journ_dentry) + 16);

            }
            break;
        }
    }

    if (fwrite(&journ[end * jinfo->bsize], jinfo->bsize, 1, stdout) != 1) {
        tsk_error_reset();
        tsk_errno = TSK_ERR_FS_WRITE;
        snprintf(tsk_errstr, TSK_ERRSTR_L,
            "ext2fs_jblk_walk: error writing buffer block");
        free(journ);
        return 1;
    }

    free(journ);
    return 0;
}
コード例 #14
0
/* Limitations: does not use the action or any flags 
 *
 * return 0 on success and 1 on error
 * */
uint8_t
ext2fs_jentry_walk(TSK_FS_INFO * fs, int flags,
    TSK_FS_JENTRY_WALK_CB action, void *ptr)
{
    EXT2FS_INFO *ext2fs = (EXT2FS_INFO *) fs;
    EXT2FS_JINFO *jinfo = ext2fs->jinfo;
    char *journ;
    TSK_FS_LOAD_FILE buf1;
    TSK_DADDR_T i;
    int b_desc_seen = 0;

    // clean up any error messages that are lying around
    tsk_error_reset();


    if ((jinfo == NULL) || (jinfo->fs_file == NULL)
        || (jinfo->fs_file->meta == NULL)) {
        tsk_error_reset();
        tsk_errno = TSK_ERR_FS_ARG;
        snprintf(tsk_errstr, TSK_ERRSTR_L,
            "ext2fs_jentry_walk: journal is not open");
        return 1;
    }

    if (jinfo->fs_file->meta->size !=
        (jinfo->last_block + 1) * jinfo->bsize) {
        tsk_error_reset();
        tsk_errno = TSK_ERR_FS_ARG;
        snprintf(tsk_errstr, TSK_ERRSTR_L,
            "ext2fs_jentry_walk: journal file size is different from \nsize reported in journal super block");
        return 1;
    }

    /* Load the journal into a buffer */
    buf1.left = buf1.total = (size_t) jinfo->fs_file->meta->size;
    journ = buf1.cur = buf1.base = tsk_malloc(buf1.left);
    if (journ == NULL) {
        return 1;
    }

    if (tsk_fs_file_walk(jinfo->fs_file,
            0, tsk_fs_load_file_action, (void *) &buf1)) {
        free(journ);
        return 1;
    }

    if (buf1.left > 0) {
        tsk_error_reset();
        tsk_errno = TSK_ERR_FS_FWALK;
        snprintf(tsk_errstr, TSK_ERRSTR_L,
            "ext2fs_jentry_walk: Buffer not fully copied");
        free(journ);
        return 1;
    }


    /* Process the journal 
     * Cycle through each block
     */
    tsk_printf("JBlk\tDescriptrion\n");

    /* Note that 'i' is incremented when we find a descriptor block and
     * process its contents. */
    for (i = 0; i < jinfo->last_block; i++) {
        ext2fs_journ_head *head;


        /* if there is no magic, then it is a normal block 
         * These should be accounted for when we see its corresponding
         * descriptor.  We get the 'unknown' when its desc has
         * been reused, it is in the next batch to be overwritten,
         * or if it has not been used before
         */
        head = (ext2fs_journ_head *) & journ[i * jinfo->bsize];
        if (big_tsk_getu32(head->magic) != EXT2_JMAGIC) {
            if (i < jinfo->first_block) {
                tsk_printf("%" PRIuDADDR ":\tUnused\n", i);
            }

#if 0
            /* For now, we ignore the case of the iitial entries before a descriptor, it is too hard ... */

            else if (b_desc_seen == 0) {
                ext2fs_journ_head *head2 = NULL;
                TSK_DADDR_T a;
                int next_head = 0, next_seq = 0;
                ext2fs_journ_dentry *dentry;

                /* This occurs when the log cycled around 
                 * We need to find out where the descriptor is
                 * and where we need to end */
                b_desc_seen = 1;

                for (a = i; a < jinfo->last_block; a++) {
                    head2 =
                        (ext2fs_journ_head *) & journ[a * jinfo->bsize];
                    if ((big_tsk_getu32(head2->magic) == EXT2_JMAGIC)) {
                        next_head = a;
                        next_seq = big_tsk_getu32(head2->entry_seq);
                        break;
                    }

                }
                if (next_head == 0) {
                    tsk_printf("%" PRIuDADDR ":\tFS Block Unknown\n", i);
                }

                /* Find the last descr in the journ */
                for (a = jinfo->last_block; a > i; a--) {
                    head2 =
                        (ext2fs_journ_head *) & journ[a * jinfo->bsize];
                    if ((big_tsk_getu32(head2->magic) == EXT2_JMAGIC)
                        && (big_tsk_getu32(head2->entry_type) ==
                            EXT2_J_ETYPE_DESC)
                        && (next_seq == big_tsk_getu32(head2->entry_seq))) {
                        break;

// @@@@ We should abort if we reach a commit before  descriptor

                    }
                }

                /* We did not find a descriptor in the journ! 
                 * print unknown for the rest of the journ
                 */
                if (a == i) {
                    tsk_printf("%" PRIuDADDR ":\tFS Block Unknown\n", i);
                    continue;
                }


                dentry =
                    (ext2fs_journ_dentry *) ((uintptr_t) head2 +
                    sizeof(ext2fs_journ_head));;


                /* Cycle through the descriptor entries */
                while ((uintptr_t) dentry <=
                    ((uintptr_t) head2 + jinfo->bsize -
                        sizeof(ext2fs_journ_head))) {


                    /* Only start to look after the index in the desc has looped */
                    if (++a <= jinfo->last_block) {
                        ext2fs_journ_head *head3;

                        /* Look at the block that this entry refers to */
                        head3 =
                            (ext2fs_journ_head *) & journ[i *
                            jinfo->bsize];
                        if ((big_tsk_getu32(head3->magic) == EXT2_JMAGIC)) {
                            i--;
                            break;
                        }

                        /* If it doesn't have the magic, then it is a
                         * journal entry and we print the FS info */
                        tsk_printf("%" PRIuDADDR ":\tFS Block %" PRIu32
                            "\n", i, big_tsk_getu32(dentry->fs_blk));

                        /* Our counter is over the end of the journ */
                        if (++i > jinfo->last_block)
                            break;

                    }

                    /* Increment to the next */
                    if (big_tsk_getu32(dentry->flag) & EXT2_J_DENTRY_LAST)
                        break;

                    /* If the SAMEID value is set, then we advance by the size of the entry, otherwise add 16 for the ID */
                    else if (big_tsk_getu32(dentry->flag) &
                        EXT2_J_DENTRY_SAMEID)
                        dentry =
                            (ext2fs_journ_dentry *) ((uintptr_t) dentry +
                            sizeof(ext2fs_journ_dentry));

                    else
                        dentry =
                            (ext2fs_journ_dentry *) ((uintptr_t) dentry +
                            sizeof(ext2fs_journ_dentry)
                            + 16);

                }
            }
#endif
            else {
                tsk_printf("%" PRIuDADDR
                    ":\tUnallocated FS Block Unknown\n", i);
            }
        }

        /* The super block */
        else if ((big_tsk_getu32(head->entry_type) == EXT2_J_ETYPE_SB1) ||
            (big_tsk_getu32(head->entry_type) == EXT2_J_ETYPE_SB2)) {
            tsk_printf("%" PRIuDADDR ":\tSuperblock (seq: %" PRIu32 ")\n",
                i, big_tsk_getu32(head->entry_seq));
        }

        /* Revoke Block */
        else if (big_tsk_getu32(head->entry_type) == EXT2_J_ETYPE_REV) {
            tsk_printf("%" PRIuDADDR ":\t%sRevoke Block (seq: %" PRIu32
                ")\n", i, ((i < jinfo->start_blk)
                    || (big_tsk_getu32(head->entry_seq) <
                        jinfo->start_seq)) ? "Unallocated " : "Allocated ",
                big_tsk_getu32(head->entry_seq));
        }

        /* The commit is the end of the entries */
        else if (big_tsk_getu32(head->entry_type) == EXT2_J_ETYPE_COM) {
            tsk_printf("%" PRIuDADDR ":\t%sCommit Block (seq: %" PRIu32
                ")\n", i, ((i < jinfo->start_blk)
                    || (big_tsk_getu32(head->entry_seq) <
                        jinfo->start_seq)) ? "Unallocated " : "Allocated ",
                big_tsk_getu32(head->entry_seq));
        }

        /* The descriptor describes the FS blocks that follow it */
        else if (big_tsk_getu32(head->entry_type) == EXT2_J_ETYPE_DESC) {
            ext2fs_journ_dentry *dentry;
            ext2fs_journ_head *head2;
            int unalloc = 0;

            b_desc_seen = 1;


            /* Is this an unallocated journ block or sequence */
            if ((i < jinfo->start_blk) ||
                (big_tsk_getu32(head->entry_seq) < jinfo->start_seq))
                unalloc = 1;

            tsk_printf("%" PRIuDADDR ":\t%sDescriptor Block (seq: %" PRIu32
                ")\n", i, (unalloc) ? "Unallocated " : "Allocated ",
                big_tsk_getu32(head->entry_seq));

            dentry =
                (ext2fs_journ_dentry *) ((uintptr_t) head +
                sizeof(ext2fs_journ_head));;

            /* Cycle through the descriptor entries to account for the journal blocks */
            while ((uintptr_t) dentry <=
                ((uintptr_t) head + jinfo->bsize -
                    sizeof(ext2fs_journ_head))) {


                /* Our counter is over the end of the journ */
                if (++i > jinfo->last_block)
                    break;


                /* Look at the block that this entry refers to */
                head2 = (ext2fs_journ_head *) & journ[i * jinfo->bsize];
                if ((big_tsk_getu32(head2->magic) == EXT2_JMAGIC) &&
                    (big_tsk_getu32(head2->entry_seq) >=
                        big_tsk_getu32(head->entry_seq))) {
                    i--;
                    break;
                }

                /* If it doesn't have the magic, then it is a
                 * journal entry and we print the FS info */
                tsk_printf("%" PRIuDADDR ":\t%sFS Block %" PRIu32 "\n", i,
                    (unalloc) ? "Unallocated " : "Allocated ",
                    big_tsk_getu32(dentry->fs_blk));

                /* Increment to the next */
                if (big_tsk_getu32(dentry->flag) & EXT2_J_DENTRY_LAST)
                    break;

                /* If the SAMEID value is set, then we advance by the size of the entry, otherwise add 16 for the ID */
                else if (big_tsk_getu32(dentry->flag) &
                    EXT2_J_DENTRY_SAMEID)
                    dentry =
                        (ext2fs_journ_dentry *) ((uintptr_t) dentry +
                        sizeof(ext2fs_journ_dentry));

                else
                    dentry =
                        (ext2fs_journ_dentry *) ((uintptr_t) dentry +
                        sizeof(ext2fs_journ_dentry) + 16);
            }
        }
    }

    free(journ);
    return 0;
}
コード例 #15
0
ファイル: callback-style.cpp プロジェクト: 0xNF/sleuthkit
/**
 * Process the contents of a file.
 *
 * @return 1 on error and 0 on success 
 */
static uint8_t
proc_file(TSK_FS_FILE * fs_file, const char *path)
{
    TSK_MD5_CTX md;

    if ((fs_file->meta == NULL) || (fs_file->name == NULL))
        return 1;

    if (fs_file->meta->type != TSK_FS_META_TYPE_REG)
        return 0;

    //printf("Processing %s%s\n", path, fs_file->name->name);

    int myflags = TSK_FS_FILE_WALK_FLAG_NOID;

    TSK_MD5_Init(&md);

    /* Note that we could also cycle through all of the attributes in the
     * file by using one of the tsk_fs_attr_get() functions and walking it
     * with tsk_fs_attr_walk(). See the File Systems section of the Library
     * User's Guide for more details: 
     * http://www.sleuthkit.org/sleuthkit/docs/api-docs/ */
    if (tsk_fs_file_walk
        (fs_file, (TSK_FS_FILE_WALK_FLAG_ENUM) myflags, file_act,
            (void *) &md)) {
        // ignore errors from deleted files that were being recovered
        if (tsk_error_get_errno() != TSK_ERR_FS_RECOVER) {
            printf("Processing: %s/%s (%" PRIuINUM ")\n", path,
                fs_file->name->name, fs_file->meta->addr);
            tsk_error_print(stderr);
        }
        tsk_error_reset();
    }
    // otherwise, compute the hash of the file.
    else {
        unsigned char hash[16];

        TSK_MD5_Final(hash, &md);
#if 0
        {
            int i;
            printf("Hash of %s/%s: ", path, fs_file->name->name);

            for (i = 0; i < 16; i++) {
                printf("%x%x", (hash[i] >> 4) & 0xf, hash[i] & 0xf);
            }
            printf("\n");
        }
#endif
#if DO_HASHLOOKUP
        {
            int retval;
            retval = tsk_hdb_lookup_raw(hdb_info, (uint8_t *) hash, 16,
                TSK_HDB_FLAG_QUICK, NULL, NULL);
            if (retval == 1) {
                //printf("Ignoring file %s\n", fs_dent->name);
            }
            else if (retval == 0) {
//            printf("Not Ignoring: %s/%s\n", path, name);
            }
        }
#endif
    }

    return 0;
}