Beispiel #1
0
/**
 * \ingroup fslib
 * Read a file system block into a char* buffer.  
 * This is actually a wrapper around the fs_read_random function,
 * but it allows the starting location to be specified as a block address. 
 *
 * @param a_fs The file system structure.
 * @param a_addr The starting block file system address. 
 * @param a_buf The char * buffer to store the block data in.
 * @param a_len The number of bytes to read (must be a multiple of the block size)
 * @return The number of bytes read or -1 on error. 
 */
ssize_t
tsk_fs_read_block(TSK_FS_INFO * a_fs, TSK_DADDR_T a_addr, char *a_buf,
    size_t a_len)
{
    if (a_len % a_fs->block_size) {
        tsk_error_reset();
        tsk_errno = TSK_ERR_FS_READ;
        snprintf(tsk_errstr, TSK_ERRSTR_L,
            "tsk_fs_read_block: length %" PRIuSIZE ""
            " not a multiple of %d", a_len, a_fs->block_size);
        return -1;
    }

    if (a_addr > a_fs->last_block_act) {
        tsk_error_reset();
        tsk_errno = TSK_ERR_FS_READ;
        if (a_addr <= a_fs->last_block)
            snprintf(tsk_errstr, TSK_ERRSTR_L,
                "tsk_fs_read_block: Address missing in partial image: %"
                PRIuDADDR ")", a_addr);
        else
            snprintf(tsk_errstr, TSK_ERRSTR_L,
                "tsk_fs_read_block: Address is too large for image: %"
                PRIuDADDR ")", a_addr);
        return -1;
    }

    return tsk_img_read(a_fs->img_info,
        a_fs->offset + (TSK_OFF_T) a_addr * a_fs->block_size, a_buf,
        a_len);
}
/**
 * \ingroup fslib
 * Read arbitrary data from inside of the file system. 
 * @param a_fs The file system handle.
 * @param a_off The byte offset to start reading from (relative to start of file system)
 * @param a_buf The buffer to store the block in.
 * @param a_len The number of bytes to read
 * @return The number of bytes read or -1 on error. 
 */
ssize_t
tsk_fs_read(TSK_FS_INFO * a_fs, TSK_OFF_T a_off, char *a_buf, size_t a_len)
{
    // do a sanity check on the read bounds, but only if the block
    // value has been set. 
    // note that this could prevent us from viewing the FS slack...
    if ((a_fs->last_block_act > 0)
        && ((TSK_DADDR_T) a_off >=
            ((a_fs->last_block_act + 1) * a_fs->block_size))) {
        tsk_error_reset();
        tsk_error_set_errno(TSK_ERR_FS_READ);
        if ((TSK_DADDR_T) a_off <
            ((a_fs->last_block + 1) * a_fs->block_size))
            tsk_error_set_errstr
                ("tsk_fs_read: Offset missing in partial image: %"
                PRIuDADDR ")", a_off);
        else
            tsk_error_set_errstr
                ("tsk_fs_read: Offset is too large for image: %" PRIuDADDR
                ")", a_off);
        return -1;
    }

    if (((a_fs->block_pre_size) || (a_fs->block_post_size))
        && (a_fs->block_size)) {
        return fs_prepost_read(a_fs, a_off, a_buf, a_len);
    }
    else {
        return tsk_img_read(a_fs->img_info, a_off + a_fs->offset, a_buf,
            a_len);
    }
}
Beispiel #3
0
/**
 * \ingroup fslib
 * Read arbitrary data from inside of the file system. 
 * @param a_fs The file system handle.
 * @param a_off The byte offset to start reading from (relative to start of file system)
 * @param a_buf The buffer to store the block in.
 * @param a_len The number of bytes to read
 * @return The number of bytes read or -1 on error. 
 */
ssize_t
tsk_fs_read(TSK_FS_INFO * a_fs, TSK_OFF_T a_off, char *a_buf, size_t a_len)
{
    TSK_OFF_T off;

    // do a sanity check on the read bounds, but only if the block
    // value has been set. 
    // note that this could prevent us from viewing the FS slack...
    if ((a_fs->last_block_act > 0)
        && ((TSK_DADDR_T) a_off >=
            ((a_fs->last_block_act + 1) * a_fs->block_size))) {
        tsk_error_reset();
        tsk_errno = TSK_ERR_FS_READ;
        if ((TSK_DADDR_T) a_off <
            ((a_fs->last_block + 1) * a_fs->block_size))
            snprintf(tsk_errstr, TSK_ERRSTR_L,
                "tsk_fs_read: Offset missing in partial image: %" PRIuDADDR
                ")", a_off);
        else
            snprintf(tsk_errstr, TSK_ERRSTR_L,
                "tsk_fs_read: Offset is too large for image: %"
                PRIuDADDR ")", a_off);
        return -1;
    }

    off = a_off + a_fs->offset;
    return tsk_img_read(a_fs->img_info, off, a_buf, a_len);
}
Beispiel #4
0
/**
 * \ingroup fslib
 * Get the contents and flags of a specific file system block. Note that if the block contains
 * compressed data, then this function will return the compressed data with the RAW flag set. 
 * The uncompressed data can be obtained only from the file-level functions.
 *
 * @param a_fs The file system to read the block from.
 * @param a_fs_block The structure to write the block data into or NULL to have one created.
 * @param a_addr The file system address to read.
 * @param a_flags Flag to assign to the returned TSK_FS_BLOCK (use if you already have it as part of a block_walk-type scenario)
 * @return The TSK_FS_BLOCK with the data or NULL on error.  (If a_fs_block was not NULL, this will
 * be the same structure). 
 */
TSK_FS_BLOCK *
tsk_fs_block_get_flag(TSK_FS_INFO * a_fs, TSK_FS_BLOCK * a_fs_block,
    TSK_DADDR_T a_addr, TSK_FS_BLOCK_FLAG_ENUM a_flags)
{
    TSK_OFF_T offs;
    size_t len;

    if (a_fs == NULL) {
        tsk_error_reset();
        tsk_error_set_errno(TSK_ERR_FS_READ);
        tsk_error_set_errstr("tsk_fs_block_get: fs unallocated");
        return NULL;
    }
    if (a_fs_block == NULL) {
        a_fs_block = tsk_fs_block_alloc(a_fs);
    }
    else if ((a_fs_block->tag != TSK_FS_BLOCK_TAG)
        || (a_fs_block->buf == NULL)) {
        tsk_error_reset();
        tsk_error_set_errno(TSK_ERR_FS_READ);
        tsk_error_set_errstr("tsk_fs_block_get: fs_block unallocated");
        return NULL;
    }

    len = a_fs->block_size;

    if (a_addr > a_fs->last_block_act) {
        tsk_error_reset();
        tsk_error_set_errno(TSK_ERR_FS_READ);
        if (a_addr <= a_fs->last_block)
            tsk_error_set_errstr
                ("tsk_fs_block_get: Address missing in partial image: %"
                PRIuDADDR ")", a_addr);
        else
            tsk_error_set_errstr
                ("tsk_fs_block_get: Address is too large for image: %"
                PRIuDADDR ")", a_addr);
        return NULL;
    }

    a_fs_block->fs_info = a_fs;
    a_fs_block->addr = a_addr;
    a_fs_block->flags = a_flags;
    a_fs_block->flags |= TSK_FS_BLOCK_FLAG_RAW;
    offs = (TSK_OFF_T) a_addr *a_fs->block_size;

    if ((a_fs_block->flags & TSK_FS_BLOCK_FLAG_AONLY) == 0) {
        ssize_t cnt;
        cnt =
            tsk_img_read(a_fs->img_info, a_fs->offset + offs,
            a_fs_block->buf, len);
        if (cnt != (ssize_t)len) {
            return NULL;
        }
    }
    return a_fs_block;
}
Beispiel #5
0
 size_t StreamPartition::streamRead(char *buf, size_t count)   {
     off_t realoffset=mPartitionOffset+mReadOffset;
     //Make sure not to read past the end of the partition.
     size_t realcount=count;
     off_t dataleft = mSize - mReadOffset;
     if ((((off_t) count) > dataleft) ) {
         realcount= (size_t) dataleft;
     }
     if (realcount == 0) {
        return 0;
     } 
     size_t rdbytes= tsk_img_read(mImage, realoffset,buf,realcount);
     if (rdbytes == (size_t) -1) {
        getLogStream(ocfa::misc::LOG_ERR) << "tsk_img_read returned -1 while requesting for " << realcount << " bytes of data at offset " << realoffset << std::endl;
        return 0;
     }
     mReadOffset+= rdbytes;
     return rdbytes;        
 }   
/*
 * @param byte_start Byte offset to start reading from start of file
 * @param byte_len Number of bytes to read
 * @param buffer Buffer to read into (must be of size byte_len or larger)
 * @returns -1 on error or number of bytes read
 */
int TskImageFileTsk::getByteData(const uint64_t byte_start, 
                                const uint64_t byte_len, 
                                char *buffer)
{
    if (m_img_info == NULL) {
        if (open() != 0)
            return -1;
    }

    int retval = tsk_img_read(m_img_info, byte_start, buffer, (size_t)(byte_len));
    if (retval == -1) {
        std::wstringstream message;
        message << L"TskImageFileTsk::getByteData - tsk_img_read: " << tsk_error_get() << std::endl;
        LOGERROR(message.str());
        return -1;
    }

    return retval;
}
Beispiel #7
0
ssize_t Image::dump(std::ostream& o) const {
  ssize_t rlen;
  char buf[4096]; 
  TSK_OFF_T off = 0;

  while (off < Img->size) {
    rlen = tsk_img_read(Img, off, buf, sizeof(buf));
    if (rlen == -1) {
      return -1;
    }

    off += rlen;

    o.write(buf, rlen);
    if (!o.good()) {
      return -1;
    }
  }

  return Img->size;
}
Beispiel #8
0
/*
 * Inspects a byte address for an XTAF superblock structure.
 *
 * @param offset Offset in sectors.
 *
 * Returns 0 on finding a sane-looking XTAF superblock.
 * Returns 1 on finding non-XTAF-superblock data.
 * Returns <0 on more basic errors (memory, I/O).
 */
int
tsk_vs_xtaf_verifysb(TSK_IMG_INFO * img_info, TSK_DADDR_T offset, unsigned int sector_size){
    ssize_t cnt;
    xtaffs_sb* xtafsb;
    unsigned int xtafsb_len;

    xtafsb_len = sizeof(xtaffs_sb);

    /* Allocate superblock struct. */
    xtafsb = (xtaffs_sb*) tsk_malloc(xtafsb_len);
    if (NULL == xtafsb) {
        tsk_fprintf(stderr, "tsk_vs_xtaf_verifysb: Failed to allocate superblock for partition %d.\n");
        free(xtafsb);
        return -ENOMEM;
    }

    /* Read in superblock. */
    /* NOTE: This is read as a char* instead of a xtaffs_sb to keep img_read() happy. */
    cnt = tsk_img_read(img_info, offset, (char *) xtafsb, xtafsb_len);
    /* Check for a failed read. */
    if (cnt != xtafsb_len) {
        tsk_fprintf(stderr, "tsk_vs_xtaf_verifysb: Failed to read at disk offset %" PRIuDADDR " bytes.\n", offset * sector_size);
        free(xtafsb);
        return -EIO;
    }

    /* Sanity test: Check the magic. */
    if(strncmp((char*) xtafsb->magic, "XTAF", 4)){
        if (tsk_verbose)
            tsk_fprintf(stderr, "tsk_vs_xtaf_verifysb: Partition at %" PRIuDADDR " bytes is not an XTAF file system.\n", offset * sector_size);
        free(xtafsb);
        return 1;
    }

    /* The partition at this point is sane. No further need to check the superblock. */
    free(xtafsb);

    return 0;
}
/** \internal
 * Internal method to deal with calculating correct offset when we have pre and post bytes
 * in teh file system blocks (i.e. RAW Cds)
 * @param a_fs File system being analyzed
 * @param a_off Byte offset into file system (i.e. not offset into image)
 * @param a_buf Buffer to write data into
 * @param a_len Number of bytes to read
 * @retuns Number of bytes read or -1 on error
 */
static ssize_t
fs_prepost_read(TSK_FS_INFO * a_fs, TSK_OFF_T a_off, char *a_buf,
    size_t a_len)
{
    TSK_OFF_T cur_off = a_off;
    TSK_OFF_T end_off = a_off + a_len;
    ssize_t cur_idx = 0;

    // we need to read block by block so that we can skip the needed pre and post bytes
    while (cur_off < end_off) {
        TSK_OFF_T read_off;
        ssize_t retval2 = 0;
        TSK_DADDR_T blk = cur_off / a_fs->block_size;
        size_t read_len = a_fs->block_size - cur_off % a_fs->block_size;

        if (read_len + cur_off > end_off)
            read_len = end_off - cur_off;

        read_off =
            a_fs->offset + cur_off + blk * (a_fs->block_pre_size +
            a_fs->block_post_size) + a_fs->block_pre_size;
        if (tsk_verbose)
            fprintf(stderr,
                "fs_prepost_read: Mapped %" PRIuOFF " to %" PRIuOFF "\n",
                cur_off, read_off);

        retval2 =
            tsk_img_read(a_fs->img_info, read_off, &a_buf[cur_idx],
            read_len);
        if (retval2 == -1)
            return -1;
        else if (retval2 == 0)
            break;
        cur_idx += retval2;
        cur_off += retval2;
    }
    return cur_idx;
}
/*
 * Read bytes from the given image
 * @return array of bytes read from the image
 * @param env pointer to java environment this was called from
 * @param obj the java object this was called from
 * @param a_img_info the pointer to the image object
 * @param offset the offset in bytes to start at
 * @param len number of bytes to read
 */
JNIEXPORT jbyteArray JNICALL
Java_org_sleuthkit_datamodel_SleuthkitJNI_readImgNat(JNIEnv * env,
    jclass obj, jlong a_img_info, jlong offset, jlong len)
{
    char *buf = (char *) tsk_malloc((size_t) len);
    if (buf == NULL) {
        throwTskError(env, tsk_error_get());
        return NULL;
    }

    TSK_IMG_INFO *img_info = castImgInfo(env, a_img_info);

    ssize_t retval =
        tsk_img_read(img_info, (TSK_OFF_T) offset, buf, (size_t) len);
    if (retval == -1) {
        throwTskError(env, tsk_error_get());
    }

    // package it up for return
    jbyteArray return_array = copyBufToByteArray(env, buf, retval);
    free(buf);
    return return_array;
}
/**
 * \ingroup fslib
 * Read a file system block into a char* buffer.  
 * This is actually a wrapper around the fs_read_random function,
 * but it allows the starting location to be specified as a block address. 
 *
 * @param a_fs The file system structure.
 * @param a_addr The starting block file system address. 
 * @param a_buf The char * buffer to store the block data in.
 * @param a_len The number of bytes to read (must be a multiple of the block size)
 * @return The number of bytes read or -1 on error. 
 */
ssize_t
tsk_fs_read_block(TSK_FS_INFO * a_fs, TSK_DADDR_T a_addr, char *a_buf,
    size_t a_len)
{
    if (a_len % a_fs->block_size) {
        tsk_error_reset();
        tsk_error_set_errno(TSK_ERR_FS_READ);
        tsk_error_set_errstr("tsk_fs_read_block: length %" PRIuSIZE ""
            " not a multiple of %d", a_len, a_fs->block_size);
        return -1;
    }

    if (a_addr > a_fs->last_block_act) {
        tsk_error_reset();
        tsk_error_set_errno(TSK_ERR_FS_READ);
        if (a_addr <= a_fs->last_block)
            tsk_error_set_errstr
                ("tsk_fs_read_block: Address missing in partial image: %"
                PRIuDADDR ")", a_addr);
        else
            tsk_error_set_errstr
                ("tsk_fs_read_block: Address is too large for image: %"
                PRIuDADDR ")", a_addr);
        return -1;
    }


    if ((a_fs->block_pre_size == 0) && (a_fs->block_post_size == 0)) {
        TSK_OFF_T off =
            a_fs->offset + (TSK_OFF_T) (a_addr) * a_fs->block_size;
        return tsk_img_read(a_fs->img_info, off, a_buf, a_len);
    }
    else {
        TSK_OFF_T off = (TSK_OFF_T) (a_addr) * a_fs->block_size;
        return fs_prepost_read(a_fs, off, a_buf, a_len);
    }
}
Beispiel #12
0
/* 
 * Given the path to the file, open it and load the internal
 * partition table structure
 *
 * offset is the byte offset to the start of the volume system
 *
 * If test is 1 then additional tests are performed to make sure 
 * it isn't a FAT or NTFS file system. This is used when autodetection
 * is being used to detect the volume system type. 
 */
TSK_VS_INFO *
tsk_vs_xtaf_open(TSK_IMG_INFO * img_info, TSK_DADDR_T offset, uint8_t test)
{
    TSK_VS_INFO *vs;
    ssize_t cnt = 0;
    char* xtaf_buffer[4];
    
    unsigned int sector_size;
    /* Offsets and lengths are hard-coded, except for the user data partition length. */
    /* Offsets are in bytes */
//    TSK_DADDR_T known_xtaf_offsets[] = {0x80000, 0x80080000, 0x10C080000, 0x118EB0000, 0x120eb0000, 0x130eb0000};
    TSK_DADDR_T known_xtaf_offsets[] = {1024, 4195328, 8782848, 9205120, 9467264, 9991552};
    /* Lengths are in sectors */
    TSK_DADDR_T known_xtaf_lengths[] = {4194304, 4587520, 422272 , 262144 , 524288 , 0};
    /* Partition labels c/o the Free60 Wiki: http://free60.org/FATX */
    char* known_xtaf_labels[] = {
      "XTAF (System Cache)",
      "XTAF (Game Cache)",
      "XTAF (System Extended)",
      "XTAF (System Extended 2)",
      "XTAF (Compatibility)",
      "XTAF (System)"
    }; //AJN: Recall that the label passed to tsk_vs_part_add must be malloc'ed.
    TSK_VS_PART_INFO* part;
    TSK_DADDR_T partition_offset;
    TSK_DADDR_T partition_length;
    int itor;
    char *part_label;
    int rc_verifysb;
    int partition_tally = 0;

    /* Clean up any errors that are lying around. */
    tsk_error_reset();

    /* Zero out buffer before reading */
    memset(xtaf_buffer, 0, sizeof(xtaf_buffer));

    sector_size = img_info->sector_size;
    if (0 == sector_size) {
        tsk_fprintf(stderr, "tsk_vs_xtaf_open: img_info has the sector size of this image as 0 bytes.  Guessing 512 instead, but this should be fixed.\n");
        sector_size = 512;
    }

    vs = (TSK_VS_INFO *) tsk_malloc(sizeof(*vs));
    if (vs == NULL)
        return NULL;

    vs->vstype = TSK_VS_TYPE_XTAF;
    vs->tag = TSK_VS_INFO_TAG;
    vs->img_info = img_info;
    vs->offset = offset;

    /* inititialize settings */
    vs->part_list = NULL;
    vs->endian = 0x02; /*AJN TODO Setting this to TSK_BIG_ENDIAN, which is the same value, causes XTAF recognition to immediately fail...why?*/
    vs->block_size = 512;

    /* Assign functions */
    vs->close = xtaf_close;
    vs->part_count = 0;

    /* Inspect beginning of image for XTAF superblock.  If one is present there, assume we're looking at a partition image, and quit early. */
    rc_verifysb = tsk_vs_xtaf_verifysb(img_info, 0, sector_size);
    if (rc_verifysb == 0) {
        if (tsk_verbose)
            tsk_fprintf(stderr, "tsk_vs_xtaf_open: Encountered XTAF superblock at beginning of image.  Assuming this is a partition image, not a disk image.\n");
        xtaf_close(vs);
        return NULL;
    }

    /* check to see if image is a single partition, in which case XTAF would start at the beginning */
    memset(xtaf_buffer, 0, sizeof(xtaf_buffer));
    cnt = tsk_img_read(img_info, 0x0, (char *) xtaf_buffer, 4);
    if(strncmp(xtaf_buffer, "XTAF", 4) == 0){
        partition_offset = 0;
        partition_length = img_info->size;
        rc_verifysb = tsk_vs_xtaf_verifysb(img_info, partition_offset, sector_size);
        /* Check for XTAF superblock. */
        if (rc_verifysb != 0) {
            if (tsk_verbose)
                tsk_fprintf(stderr, "Superblock incorrect\n");
            xtaf_close(vs);
            return NULL;
        }
        /* Allocate partition label. */
        part_label = (char *) tsk_malloc(XTAF_PART_LABEL_MAX_LENGTH * sizeof(char));
        for (itor = 0; itor < 6; itor++){
            if( (img_info->size/img_info->sector_size) == known_xtaf_lengths[itor]){
                /* Allocate partition label. */
                part_label = (char *) tsk_malloc(XTAF_PART_LABEL_MAX_LENGTH * sizeof(char));
                snprintf(part_label, XTAF_PART_LABEL_MAX_LENGTH, known_xtaf_labels[itor]);
                break;
            }
        }
        vs->part_count = 1;

        /* Populate partition struct and append to partition list. */
        part = tsk_vs_part_add(vs, partition_offset, partition_length, TSK_VS_PART_FLAG_ALLOC, part_label, 0, 0);
        if (NULL == part) {
            tsk_fprintf(stderr, "tsk_vs_xtaf_open: Failed to add partition %d to partition list.\n", itor);
            xtaf_close(vs);
            return NULL;
        }
        partition_tally = 1;
    }else{

        vs->part_count = 6;
        /* Loop through the known partition offsets, looking for XTAF file systems only by a sane XTAF superblock being present. */
        for (itor = 0; itor < 6; itor++) {
            /* Reset. */
            part = NULL;
            part_label = NULL;
    
            partition_offset = known_xtaf_offsets[itor]*512;
    
            /* Check to see if XTAF is at the location it should be */
            memset(xtaf_buffer, 0, sizeof(xtaf_buffer));
            cnt = tsk_img_read(img_info, partition_offset, (char *) xtaf_buffer, 4);
            if(strncmp(xtaf_buffer, "XTAF", 4) != 0){
                continue;
            }
    
            partition_length = known_xtaf_lengths[itor];
            /* Last partition will have variable size depending on the size of drive, this partition will run to the end of the drive */       
            if( partition_offset == 0x130eb0000){
                partition_length = img_info->size - 0x130eb0000;
            }
    
            if (0 == partition_length) {
                if (tsk_verbose) {
                    tsk_fprintf(stderr, "tsk_vs_xtaf_open: Computing partition length.\n");
                    tsk_fprintf(stderr, "tsk_vs_xtaf_open: Image size: %" PRIuOFF " bytes.\n", img_info->size);
                    tsk_fprintf(stderr, "tsk_vs_xtaf_open: Sector size: %u bytes.\n", img_info->sector_size);
                    tsk_fprintf(stderr, "tsk_vs_xtaf_open: Partition offset: %" PRIuDADDR " bytes.\n", partition_offset * img_info->sector_size);
                }
    
                /* Compute partition length of the user data partition differently - based on input image's length. */
                if ((img_info->size / sector_size) < partition_offset) {
                    if (tsk_verbose)
                        tsk_fprintf(stderr, "tsk_vs_xtaf_open: This image is smaller than the offset of the target partition.  Aborting.\n");
                    xtaf_close(vs);
                    return NULL;
                }
                partition_length = (img_info->size / sector_size) - partition_offset;
            }
    
            if (tsk_verbose) {
                tsk_fprintf(stderr, "tsk_vs_xtaf_open: Testing for partition.\n");
                tsk_fprintf(stderr, "tsk_vs_xtaf_open:   itor: %d.\n", itor);
                tsk_fprintf(stderr, "tsk_vs_xtaf_open:   offset: %" PRIuDADDR " sectors.\n", partition_offset);
                tsk_fprintf(stderr, "tsk_vs_xtaf_open:   length: %" PRIuDADDR " sectors.\n", partition_length);
            }
    
            /* Check for XTAF superblock. */
            rc_verifysb = tsk_vs_xtaf_verifysb(img_info, partition_offset, sector_size);
            if (rc_verifysb != 0) {
                continue;
            }
    
            /* Allocate partition label. */
            part_label = (char *) tsk_malloc(XTAF_PART_LABEL_MAX_LENGTH * sizeof(char));
            snprintf(part_label, XTAF_PART_LABEL_MAX_LENGTH, known_xtaf_labels[itor]);
    
            /* Populate partition struct and append to partition list. */
            part = tsk_vs_part_add(vs, (partition_offset/(512)), partition_length, TSK_VS_PART_FLAG_ALLOC, part_label, 0, 0);
//            part->start = (TSK_DADDR_T) partition_offset;
            if (NULL == part) {
                tsk_fprintf(stderr, "tsk_vs_xtaf_open: Failed to add partition %d to partition list.\n", itor);
                break;
            }
    
            partition_tally++;
        }
    }

    /* Don't call this an XTAF volume system if none of the hard-coded partitions were found. */
    if (partition_tally == 0) {
        xtaf_close(vs);
        return NULL;
    }

    /* Denote unallocated space as "Unused" disk area. */
    if (tsk_vs_part_unused(vs)) {
        xtaf_close(vs);
        return NULL;
    }

    return vs;
}
Beispiel #13
0
int main(int argc, char* argv1[])
{
    TSK_VS_INFO* lVsInfo = NULL;
    TSK_OFF_T lCnt = 0;
    char lBuf[32768] = { 0 };
    unsigned lCntRead = 0;
    TSK_IMG_INFO* lImgInfo = OS_FH_INVALID;
    OS_FH_TYPE lOut = OS_FH_INVALID;
    const TSK_TCHAR *const *argv;

#ifdef TSK_WIN32
	argv = CommandLineToArgvW(GetCommandLineW(), &argc);
#else
	argv = (const TSK_TCHAR *const *) argv1;
#endif

	lOut = OS_FOPEN_WRITE(argv[2]);

	if (lOut == OS_FH_INVALID) 
	{
		LOGGING_ERROR("Could not open export image in write mode. \n")
		exit(1);
	}

    lImgInfo = tsk_img_open(
            1, /* number of images */
            (argv + 1), /* path to images */
            TSK_IMG_TYPE_DETECT, /* disk image type */
            0); /* size of device sector in bytes */
    if (lImgInfo != NULL)
    {
        TSK_OFF_T lSizeSectors = lImgInfo->size / lImgInfo->sector_size + \
                                 (lImgInfo->size % lImgInfo->sector_size ? 1 : 0);
        LOGGING_INFO("Image size (Bytes): %lu, Image size (sectors): %lu\n",
                lImgInfo->size,
                lSizeSectors);

        lVsInfo = tsk_vs_open(lImgInfo, 0, TSK_VS_TYPE_DETECT);
        if (lVsInfo != NULL)
        {
            if (tsk_vs_part_walk(lVsInfo,
                    0, /* start */
                    lVsInfo->part_count - 1, /* end */
                    TSK_VS_PART_FLAG_ALL, /* all partitions */
                    part_act, /* callback */
                    (void*) lOut /* data passed to the callback */
                    ) != 0)
            {
                fprintf(stderr, "Problem when walking partitions. \n");
            }
        }
        else
        {
            LOGGING_DEBUG("Volume system cannot be opened.\n");
            for (lCnt = 0; lCnt < lSizeSectors; lCnt++)
            {
                lCntRead = lCnt == lSizeSectors - 1 ? 
                                lImgInfo->size % lImgInfo->sector_size :
                                lImgInfo->sector_size;

				LOGGING_DEBUG("Reading %u bytes\n", lCntRead);

				tsk_img_read(
                        lImgInfo, /* handler */
                        lCnt * lImgInfo->sector_size, /* start address */
                        lBuf, /* buffer to store data in */
                        lCntRead /* amount of data to read */
                        );
                data_act(lBuf, lCntRead, lCnt * lImgInfo->sector_size, lOut);
            }
        }
    }
    else
    {
        LOGGING_ERROR("Problem opening the image. \n");
		tsk_error_print(stderr);
		exit(1);
    }
	if (lOut != OS_FH_INVALID)
	{
		OS_FCLOSE(lOut);
	}

    return EXIT_SUCCESS;
}
Beispiel #14
0
int
main(int argc, char **argv1)
{
    TSK_IMG_INFO *img;
    TSK_IMG_TYPE_ENUM imgtype = TSK_IMG_TYPE_DETECT;
    int ch;
    TSK_OFF_T start_sector = 0;
    TSK_OFF_T end_sector = 0;
    ssize_t cnt;
    TSK_TCHAR **argv;
    unsigned int ssize = 0;
    TSK_TCHAR *cp;

#ifdef TSK_WIN32
    // On Windows, get the wide arguments (mingw doesn't support wmain)
    argv = CommandLineToArgvW(GetCommandLineW(), &argc);
    if (argv == NULL) {
        fprintf(stderr, "Error getting wide arguments\n");
        exit(1);
    }
#else
    argv = (TSK_TCHAR **) argv1;
#endif

    progname = argv[0];

    while ((ch = GETOPT(argc, argv, _TSK_T("b:i:vVs:e:"))) > 0) {
        switch (ch) {
        case _TSK_T('?'):
        default:
            TFPRINTF(stderr, _TSK_T("Invalid argument: %s\n"),
                argv[OPTIND]);
            usage();
        case _TSK_T('b'):
            ssize = (unsigned int) TSTRTOUL(OPTARG, &cp, 0);
            if (*cp || *cp == *OPTARG || ssize < 1) {
                TFPRINTF(stderr,
                    _TSK_T
                    ("invalid argument: sector size must be positive: %s\n"),
                    OPTARG);
                usage();
            }
            break;
        case _TSK_T('i'):
            if (TSTRCMP(OPTARG, _TSK_T("list")) == 0) {
                tsk_img_type_print(stderr);
                exit(1);
            }
            imgtype = tsk_img_type_toid(OPTARG);
            if (imgtype == TSK_IMG_TYPE_UNSUPP) {
                TFPRINTF(stderr, _TSK_T("Unsupported image type: %s\n"),
                    OPTARG);
                usage();
            }
            break;

        case _TSK_T('s'):
            start_sector = TSTRTOUL(OPTARG, &cp, 0);
            if (*cp || *cp == *OPTARG || start_sector < 1) {
                TFPRINTF(stderr,
                    _TSK_T
                    ("invalid argument: start sector must be positive: %s\n"),
                    OPTARG);
                usage();
            }
            break;

        case _TSK_T('e'):
            end_sector = TSTRTOUL(OPTARG, &cp, 0);
            if (*cp || *cp == *OPTARG || end_sector < 1) {
                TFPRINTF(stderr,
                    _TSK_T
                    ("invalid argument: end sector must be positive: %s\n"),
                    OPTARG);
                usage();
            }
            break;


        case _TSK_T('v'):
            tsk_verbose++;
            break;

        case _TSK_T('V'):
            tsk_version_print(stdout);
            exit(0);
        }
    }

    /* We need at least one more argument */
    if (OPTIND >= argc) {
        tsk_fprintf(stderr, "Missing image name\n");
        usage();
    }

    if ((img =
            tsk_img_open(argc - OPTIND, &argv[OPTIND], imgtype,
                ssize)) == NULL) {
        tsk_error_print(stderr);
        exit(1);
    }

#ifdef TSK_WIN32
    if (-1 == _setmode(_fileno(stdout), _O_BINARY)) {
        fprintf(stderr,
            "error setting stdout to binary: %s", strerror(errno));
        exit(1);
    }
#endif

    TSK_OFF_T start_byte = 0;
    if (start_sector)
        start_byte = start_sector * img->sector_size;

    TSK_OFF_T end_byte = 0;
    if (end_sector)
        end_byte = (end_sector + 1) * img->sector_size;
    else
        end_byte = img->size;


    for (TSK_OFF_T done = start_byte; done < end_byte; done += cnt) {
        char buf[16 * 1024];
        size_t len;

        if (done + (TSK_OFF_T) sizeof(buf) > end_byte) {
            len = (size_t) (end_byte - done);
        }
        else {
            len = sizeof(buf);
        }

        cnt = tsk_img_read(img, done, buf, len);
        if (cnt != (ssize_t) len) {
            if (cnt >= 0) {
                tsk_fprintf(stderr,
                    "img_cat: Error reading image file at offset: %"
                    PRIuOFF ", len: %" PRIuOFF ", return: %" PRIuOFF "\n",
                    done, len, cnt);
            }
            else {
                tsk_error_print(stderr);
            }
            tsk_img_close(img);
            exit(1);
        }

        if (fwrite(buf, cnt, 1, stdout) != 1) {
            fprintf(stderr,
                "img_cat: Error writing to stdout:  %s", strerror(errno));
            tsk_img_close(img);
            exit(1);
        }
    }

    tsk_img_close(img);
    exit(0);
}
Beispiel #15
0
static TSK_WALK_RET_ENUM
fw_action1(TSK_FS_FILE * a_fs_file, TSK_OFF_T a_off, TSK_DADDR_T a_addr,
    char *a_buf, size_t a_size, TSK_FS_BLOCK_FLAG_ENUM a_flags,
    void *a_ptr)
{
    TSK_OFF_T tmp_off;
    ssize_t cnt;
    size_t tmp_len;
    TSK_FS_INFO *fs = a_fs_file->fs_info;

    // verify teh offset passed is what we expected
    if (a_off != s_off) {
        fprintf(stderr,
            "offset passed in callback (%" PRIuOFF
            ") diff from internal off (%" PRIuOFF ")\n", a_off, s_off);
    }

    /* The first set of tests is for the file_read API.  We seek
     * to a "random" place to move around any caches, adn then read
     * from the same offset that this call is from.  We compare
     * the buffers. */

    // pick a random place and length
    tmp_off = (s_off * 4 + 1372) % s_file2->meta->size;
    if (s_file2->meta->size - tmp_off > fs->block_size)
        tmp_len = fs->block_size;
    else
        tmp_len = s_file2->meta->size - tmp_off;

    cnt =
        tsk_fs_file_read(s_file2, tmp_off, s_buf, tmp_len,
        (TSK_FS_FILE_READ_FLAG_ENUM) 0);
    if (cnt != (ssize_t) tmp_len) {
        fprintf(stderr,
            "Error reading random offset %" PRIuOFF " in file sized %"
            PRIuOFF " (%zd vs %zd)\n", tmp_off, s_file2->meta->size, cnt,
            tmp_len);
        tsk_error_print(stderr);
        return TSK_WALK_ERROR;
    }

    // now read from the real offset and compare with what we were passed
    if (a_size > fs->block_size)
        tmp_len = fs->block_size;
    else
        tmp_len = a_size;

    cnt =
        tsk_fs_file_read(s_file2, s_off, s_buf, tmp_len,
        (TSK_FS_FILE_READ_FLAG_ENUM) 0);
    if (cnt != (ssize_t) tmp_len) {
        fprintf(stderr,
            "Error reading file offset %" PRIuOFF " in file sized %"
            PRIuOFF "\n", s_off, s_file2->meta->size);
        tsk_error_print(stderr);
        return TSK_WALK_ERROR;
    }

    if (memcmp(s_buf, a_buf, a_size)) {
        fprintf(stderr,
            "Buffers at offset %" PRIuOFF " in file %" PRIuINUM
            " are different\n", s_off, s_file2->meta->addr);
        return TSK_WALK_ERROR;
    }
    s_off += a_size;

    /* IF the block we were passed is RAW (not BAD, resident, compressed etc.,
     * then read using the fs_read() API 
     */
    if (a_flags & TSK_FS_BLOCK_FLAG_RAW) {
        tmp_off = (a_addr * 42 + 82) % fs->last_block;

        cnt = tsk_fs_read_block(fs, tmp_off, s_buf, fs->block_size);
        if (cnt != (ssize_t) fs->block_size) {
            fprintf(stderr,
                "Error reading random block %" PRIuOFF " in file system\n",
                tmp_off);
            tsk_error_print(stderr);
            return TSK_WALK_ERROR;
        }

        cnt = tsk_fs_read_block(fs, a_addr, s_buf, fs->block_size);
        if (cnt != (ssize_t) fs->block_size) {
            fprintf(stderr, "Error reading block %" PRIuOFF "\n", a_addr);
            tsk_error_print(stderr);
            return TSK_WALK_ERROR;
        }

        // compare
        if (memcmp(s_buf, a_buf, a_size)) {
            fprintf(stderr,
                "Buffers at block addr %" PRIuOFF " in file %" PRIuINUM
                " are different\n", a_addr, s_file2->meta->addr);
            return TSK_WALK_ERROR;
        }

        /* Now we also read using the img_read() API, just because we can */
        cnt = tsk_fs_read_block(fs, tmp_off, s_buf, fs->block_size);
        if (cnt != (ssize_t) fs->block_size) {
            fprintf(stderr,
                "Error reading random block %" PRIuOFF " in file system\n",
                tmp_off);
            tsk_error_print(stderr);
            return TSK_WALK_ERROR;
        }

        // get the offset into the image
        tmp_off = a_addr * fs->block_size + fs->offset;
        cnt = tsk_img_read(fs->img_info, tmp_off, s_buf, fs->block_size);
        if (cnt != (ssize_t) fs->block_size) {
            fprintf(stderr,
                "Error reading image offset %" PRIuOFF " in image\n",
                tmp_off);
            tsk_error_print(stderr);
            return TSK_WALK_ERROR;
        }

        // compare
        if (memcmp(s_buf, a_buf, a_size)) {
            fprintf(stderr,
                "Buffers at image offset  %" PRIuOFF " in file %" PRIuINUM
                " are different\n", tmp_off, s_file2->meta->addr);
            return TSK_WALK_ERROR;
        }

    }

    return TSK_WALK_CONT;
}