diff --git a/bindings/java/doxygen/Doxyfile b/bindings/java/doxygen/Doxyfile index 1dd8a6ec0696cab85b6778aee7945167fab39dad..9db930b74764779fc3af49bc6f52b37d68e8dd41 100644 --- a/bindings/java/doxygen/Doxyfile +++ b/bindings/java/doxygen/Doxyfile @@ -38,7 +38,7 @@ PROJECT_NAME = "Sleuth Kit Java Bindings (JNI)" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 4.0 +PROJECT_NUMBER = 4.3 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a @@ -760,7 +760,7 @@ WARN_LOGFILE = INPUT = main.dox \ query_database.dox \ - blackboard.dox \ + blackboard.dox \ insert_and_update_database.dox \ ../src diff --git a/bindings/java/doxygen/main.dox b/bindings/java/doxygen/main.dox index 18603b4b19e21f0fe60b7e3f706f83c537c4471d..545b1109cadbe5bb38575362af2528c54d7fabb8 100644 --- a/bindings/java/doxygen/main.dox +++ b/bindings/java/doxygen/main.dox @@ -34,7 +34,7 @@ Flush out here on general layout. \section jni_blackboard The Blackboard -\ref mod_bbpage +\subpage mod_bbpage \section the_database The Database diff --git a/rejistry++/src/VKRecord.cpp b/rejistry++/src/VKRecord.cpp index c959da5d5b2a4d1745b676490752ad574de19ab3..e222e7ccea00962da3f5a64482ac74da95c555fe 100644 --- a/rejistry++/src/VKRecord.cpp +++ b/rejistry++/src/VKRecord.cpp @@ -34,6 +34,7 @@ namespace Rejistry { const std::string VKRecord::MAGIC = "vk"; + const std::wstring VKRecord::DEFAULT_VALUE_NAME = L"(Default)"; VKRecord::VKRecord(RegistryByteBuffer * buf, uint32_t offset) : Record(buf, offset) { if (!(getMagic() == MAGIC)) { @@ -54,7 +55,7 @@ namespace Rejistry { std::wstring VKRecord::getName() const { if (! hasName()) { - return L""; + return VKRecord::DEFAULT_VALUE_NAME; } uint32_t nameLength = getWord(NAME_LENGTH_OFFSET); diff --git a/rejistry++/src/VKRecord.h b/rejistry++/src/VKRecord.h index ecccafaa4d1171eadb325f94f0a1ba810f0ab36a..c0a048fb0adb2bb07bc434af4905e4e31445b506 100644 --- a/rejistry++/src/VKRecord.h +++ b/rejistry++/src/VKRecord.h @@ -43,6 +43,8 @@ namespace Rejistry { */ class VKRecord : public Record { public: + static const std::wstring DEFAULT_VALUE_NAME; + typedef VKRecord * VKRecordPtr; typedef std::vector< VKRecordPtr > VKRecordPtrList; @@ -82,7 +84,6 @@ namespace Rejistry { VKRecord(RegistryByteBuffer * buf, uint32_t offset); VKRecord(const VKRecord &); - virtual ~VKRecord() {} /** diff --git a/rejistry++/src/ValueListRecord.cpp b/rejistry++/src/ValueListRecord.cpp index 306414932eaca77bba4ddac955fc7986b91343fe..cdfce00ec3347cb79e1302e7dce862faf962f76b 100644 --- a/rejistry++/src/ValueListRecord.cpp +++ b/rejistry++/src/ValueListRecord.cpp @@ -61,7 +61,10 @@ namespace Rejistry { VKRecord::VKRecordPtrList::iterator it = recordList.begin(); for (; it != recordList.end(); ++it) { - if (_wcsicmp(name.c_str(), (*it)->getName().c_str()) == 0) { + // If we have a name match or we are searching for the "default" entry + // (which matches a record with no name) we are done. + if ((!(*it)->hasName() && name == VKRecord::DEFAULT_VALUE_NAME) || + (_wcsicmp(name.c_str(), (*it)->getName().c_str()) == 0)) { // Create a copy of the record to return as the records // in the list will be deleted. foundRecord = new VKRecord(*(*it)); diff --git a/tsk/fs/ext2fs.c b/tsk/fs/ext2fs.c index 8b5f4e2b112f7fc25d478458b561844b5eb3d7da..99d557412312d0ee1a5020fcc3537df90a70b861 100644 --- a/tsk/fs/ext2fs.c +++ b/tsk/fs/ext2fs.c @@ -97,38 +97,24 @@ ext2fs_bg_has_super(uint32_t feature_ro_compat, uint32_t group_block) -/* ext2fs_group_load - load block group descriptor into cache +/* ext2fs_group_load - load 32-bit or 64-bit block group descriptor into cache * * Note: This routine assumes &ext2fs->lock is locked by the caller. * - * return 1 on error and 0 on success + * return 1 on error and 0 on success. On success one of either ext2fs->grp_buf or ext2fs->ext4_grp_buf will + * be non-null and contain the valid data. Because Ext4 can have 32-bit group descriptors, check which buffer is + * non-null to determine what to read instead of duplicating the logic everywhere. * * */ static uint8_t -ext2fs_group_load(EXT2FS_INFO * ext2fs, EXT2_GRPNUM_T grp_num) + ext2fs_group_load(EXT2FS_INFO * ext2fs, EXT2_GRPNUM_T grp_num) { - void *gd; - TSK_OFF_T offs; - ssize_t cnt; TSK_FS_INFO *fs = (TSK_FS_INFO *) ext2fs; int gd_size = tsk_getu16(fs->endian, ext2fs->fs->s_desc_size); - ext4fs_gd *ext4_gd = NULL; - - if (!gd_size) { - if (fs->ftype == TSK_FS_TYPE_EXT4 && - EXT2FS_HAS_INCOMPAT_FEATURE(fs, ext2fs->fs, - EXT2FS_FEATURE_INCOMPAT_64BIT)) { - gd_size = sizeof(ext4fs_gd); - } - else { - gd_size = sizeof(ext2fs_gd); - } - } - /* - * Sanity check - */ + * Sanity check + */ if (grp_num < 0 || grp_num >= ext2fs->groups_count) { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_FS_ARG); @@ -137,103 +123,109 @@ ext2fs_group_load(EXT2FS_INFO * ext2fs, EXT2_GRPNUM_T grp_num) PRI_EXT2GRP "", grp_num); return 1; } - - if (ext2fs->grp_buf == NULL) { - if (fs->ftype == TSK_FS_TYPE_EXT4) { - ext2fs->ext4_grp_buf = (ext4fs_gd *) tsk_malloc(gd_size); - } - else { - ext2fs->grp_buf = (ext2fs_gd *) tsk_malloc(gd_size); - } - if (ext2fs->grp_buf == NULL && ext2fs->ext4_grp_buf == NULL) { - return 1; - } - - } + // already loaded else if (ext2fs->grp_num == grp_num) { return 0; } - gd = ext2fs->grp_buf; - /* - * We're not reading group descriptors often, so it is OK to do small - * reads instead of cacheing group descriptors in a large buffer. - */ - offs = ext2fs->groups_offset + grp_num * gd_size; - if (fs->ftype == TSK_FS_TYPE_EXT4) - gd = ext2fs->ext4_grp_buf; - cnt = tsk_fs_read(&ext2fs->fs_info, offs, (char *) gd, gd_size); - /*DEBUG*/ + // 64-bit version. + if (((fs->ftype == TSK_FS_TYPE_EXT4)) && (EXT2FS_HAS_INCOMPAT_FEATURE(fs, ext2fs->fs, + EXT2FS_FEATURE_INCOMPAT_64BIT) + && (tsk_getu16(fs->endian, ext2fs->fs->s_desc_size) >= 64))) { + TSK_OFF_T offs; + ssize_t cnt; + + if (!gd_size) + gd_size = sizeof(ext4fs_gd); + + if (ext2fs->ext4_grp_buf == NULL) { + if ((ext2fs->ext4_grp_buf = (ext4fs_gd *) tsk_malloc(gd_size)) == NULL) + return 1; + } + offs = ext2fs->groups_offset + grp_num * gd_size; + + cnt = tsk_fs_read(&ext2fs->fs_info, offs, (char *) ext2fs->ext4_grp_buf, gd_size); + #ifdef Ext4_DBG - debug_print_buf((char *) ext2fs->ext4_grp_buf, gd_size); + debug_print_buf((char *) ext2fs->ext4_grp_buf, gd_size); #endif - if (cnt != gd_size) { - if (cnt >= 0) { - tsk_error_reset(); - tsk_error_set_errno(TSK_ERR_FS_READ); - } - tsk_error_set_errstr2("ext2fs_group_load: Group descriptor %" - PRI_EXT2GRP " at %" PRIuOFF, grp_num, offs); - return 1; + if (cnt != gd_size) { + if (cnt >= 0) { + tsk_error_reset(); + tsk_error_set_errno(TSK_ERR_FS_READ); + } + tsk_error_set_errstr2("ext2fs_group_load: Group descriptor %" + PRI_EXT2GRP " at %" PRIuOFF, grp_num, offs); + return 1; + } + + // sanity checks + if ((ext4_getu64(fs->endian, + ext2fs->ext4_grp_buf->bg_block_bitmap_hi, + ext2fs->ext4_grp_buf->bg_block_bitmap_lo) > fs->last_block) || + (ext4_getu64(fs->endian, + ext2fs->ext4_grp_buf->bg_inode_bitmap_hi, + ext2fs->ext4_grp_buf->bg_inode_bitmap_lo) > fs->last_block) || + (ext4_getu64(fs->endian, + ext2fs->ext4_grp_buf->bg_inode_table_hi, + ext2fs->ext4_grp_buf->bg_inode_table_lo) > fs->last_block)) { + tsk_error_reset(); + tsk_error_set_errno(TSK_ERR_FS_CORRUPT); + tsk_error_set_errstr("extXfs_group_load: Ext4 Group %" PRI_EXT2GRP + " descriptor block locations too large at byte offset %" + PRIuDADDR, grp_num, offs); + return 1; + } } - /* Perform a sanity check on the data to make sure offsets are in range */ - if (fs->ftype == TSK_FS_TYPE_EXT4) { - ext2fs->grp_buf = (ext2fs_gd *) ext2fs->ext4_grp_buf; - gd = ext2fs->ext4_grp_buf; - ext4_gd = ext2fs->ext4_grp_buf; - if (EXT2FS_HAS_INCOMPAT_FEATURE(fs, ext2fs->fs, - EXT2FS_FEATURE_INCOMPAT_64BIT)) { -#ifdef Ext4_DBG - printf("DEBUG hi: %04X\n", *ext4_gd->bg_block_bitmap_hi); - printf("DEBUG lo: %08X\n", *ext4_gd->bg_block_bitmap_lo); - printf("block_bitmap :%012lX\n", - ext4_getu48(fs->endian, - ext4_gd->bg_block_bitmap_hi, - ext4_gd->bg_block_bitmap_lo)); -#endif + else { + TSK_OFF_T offs; + ssize_t cnt; + if (!gd_size) + gd_size = sizeof(ext2fs_gd); + + if (ext2fs->grp_buf == NULL) { + if ((ext2fs->grp_buf = (ext2fs_gd *) tsk_malloc(gd_size)) == NULL) + return 1; } - else { -#ifdef Ext4_DBG - printf("block_bitmap:%08lX\n", tsk_getu32(fs->endian, - ext4_gd->bg_block_bitmap_lo)); - printf("stored checksum: %X\n", tsk_getu16(fs->endian, - ext4_gd->bg_checksum)); -#endif + offs = ext2fs->groups_offset + grp_num * gd_size; + + cnt = tsk_fs_read(&ext2fs->fs_info, offs, (char *) ext2fs->grp_buf, gd_size); + + if (cnt != gd_size) { + if (cnt >= 0) { + tsk_error_reset(); + tsk_error_set_errno(TSK_ERR_FS_READ); + } + tsk_error_set_errstr2("ext2fs_group_load: Group descriptor %" + PRI_EXT2GRP " at %" PRIuOFF, grp_num, offs); + return 1; } - } - else { - ext2fs_gd *ext2_gd = (ext2fs_gd *) gd; + + // sanity checks if ((tsk_getu32(fs->endian, - ext2_gd->bg_block_bitmap) > fs->last_block) || + ext2fs->grp_buf->bg_block_bitmap) > fs->last_block) || (tsk_getu32(fs->endian, - ext2_gd->bg_inode_bitmap) > fs->last_block) || + ext2fs->grp_buf->bg_inode_bitmap) > fs->last_block) || (tsk_getu32(fs->endian, - ext2_gd->bg_inode_table) > fs->last_block)) { - tsk_error_reset(); - tsk_error_set_errno(TSK_ERR_FS_CORRUPT); - tsk_error_set_errstr("extXfs_group_load: Group %" PRI_EXT2GRP - " descriptor block locations too large at byte offset %" - PRIuDADDR, grp_num, offs); - return 1; + ext2fs->grp_buf->bg_inode_table) > fs->last_block)) { + tsk_error_reset(); + tsk_error_set_errno(TSK_ERR_FS_CORRUPT); + tsk_error_set_errstr("extXfs_group_load: Group %" PRI_EXT2GRP + " descriptor block locations too large at byte offset %" + PRIuDADDR, grp_num, offs); + return 1; } - } - - ext2fs->grp_num = grp_num; - if (fs->ftype == TSK_FS_TYPE_EXT4) { - - } - else { - ext2fs_gd *ext2_gd = (ext2fs_gd *) gd; if (tsk_verbose) { TSK_FS_INFO *fs = (TSK_FS_INFO *) & ext2fs->fs_info; tsk_fprintf(stderr, "\tgroup %" PRI_EXT2GRP ": %" PRIu16 "/%" PRIu16 " free blocks/inodes\n", grp_num, tsk_getu16(fs->endian, - ext2_gd->bg_free_blocks_count), - tsk_getu16(fs->endian, ext2_gd->bg_free_inodes_count)); + ext2fs->grp_buf->bg_free_blocks_count), + tsk_getu16(fs->endian, ext2fs->grp_buf->bg_free_inodes_count)); } } + ext2fs->grp_num = grp_num; return 0; } @@ -338,6 +330,7 @@ ext2fs_bmap_load(EXT2FS_INFO * ext2fs, EXT2_GRPNUM_T grp_num) { TSK_FS_INFO *fs = (TSK_FS_INFO *) & ext2fs->fs_info; ssize_t cnt; + TSK_DADDR_T addr; /* * Look up the group descriptor info. The load will do the sanity check. @@ -355,44 +348,25 @@ ext2fs_bmap_load(EXT2FS_INFO * ext2fs, EXT2_GRPNUM_T grp_num) else if (ext2fs->bmap_grp_num == grp_num) { return 0; } - - if (tsk_verbose) { - TSK_DADDR_T dbase = 0; /* first block number in group */ - TSK_DADDR_T dmin = 0; /* first block after inodes */ - - dbase = ext2_cgbase_lcl(fs, ext2fs->fs, grp_num); - dmin = tsk_getu32(fs->endian, - ext2fs->grp_buf->bg_inode_table) + INODE_TABLE_SIZE(ext2fs); - - tsk_fprintf(stderr, - "ext2_bmap_load: loading group %" PRI_EXT2GRP - " dbase %" PRIuDADDR " bmap +%" PRIuDADDR - " imap +%" PRIuDADDR " inos +%" PRIuDADDR "..%" - PRIuDADDR "\n", grp_num, dbase, - (TSK_DADDR_T) tsk_getu32(fs->endian, - ext2fs->grp_buf->bg_block_bitmap) - - dbase, (TSK_DADDR_T) tsk_getu32(fs->endian, - ext2fs->grp_buf->bg_inode_bitmap) - dbase, - (TSK_DADDR_T) tsk_getu32(fs->endian, - ext2fs->grp_buf->bg_inode_table) - dbase, - dmin - 1 - dbase); + + if (ext2fs->ext4_grp_buf != NULL) { + addr = ext4_getu64(fs->endian, + ext2fs->ext4_grp_buf->bg_block_bitmap_hi, + ext2fs->ext4_grp_buf->bg_block_bitmap_lo); + } + else { + addr = (TSK_DADDR_T) tsk_getu32(fs->endian, ext2fs->grp_buf->bg_block_bitmap); } - /* - * Look up the block allocation bitmap. - */ - if (tsk_getu32(fs->endian, - ext2fs->grp_buf->bg_block_bitmap) > fs->last_block) { + if (addr > fs->last_block) { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_FS_BLK_NUM); tsk_error_set_errstr - ("ext2fs_bmap_load: Block too large for image: %" PRIu32 "", - tsk_getu32(fs->endian, ext2fs->grp_buf->bg_block_bitmap)); + ("ext2fs_bmap_load: Block too large for image: %" PRIu64, addr); return 1; } - cnt = tsk_fs_read(fs, (TSK_DADDR_T) tsk_getu32(fs->endian, - ext2fs->grp_buf->bg_block_bitmap) * fs->block_size, + cnt = tsk_fs_read(fs, addr * fs->block_size, (char *) ext2fs->bmap_buf, ext2fs->fs_info.block_size); if (cnt != ext2fs->fs_info.block_size) { @@ -400,17 +374,15 @@ ext2fs_bmap_load(EXT2FS_INFO * ext2fs, EXT2_GRPNUM_T grp_num) tsk_error_reset(); tsk_error_set_errno(TSK_ERR_FS_READ); } - tsk_error_set_errstr2("ext2fs_bmap_load: Bitmap group %" - PRI_EXT2GRP " at %" PRIu32, grp_num, tsk_getu32(fs->endian, - ext2fs->grp_buf->bg_block_bitmap)); + tsk_error_set_errstr2("ext2fs_bmap_load: block bitmap %" + PRI_EXT2GRP " at %" PRIu64, grp_num, addr); + return 1; } ext2fs->bmap_grp_num = grp_num; - if (tsk_verbose > 1) ext2fs_print_map(ext2fs->bmap_buf, - tsk_getu32(fs->endian, ext2fs->fs->s_blocks_per_group)); - + tsk_getu32(fs->endian, ext2fs->fs->s_blocks_per_group)); return 0; } @@ -422,14 +394,15 @@ ext2fs_bmap_load(EXT2FS_INFO * ext2fs, EXT2_GRPNUM_T grp_num) * return 0 on success and 1 on error * */ static uint8_t -ext2fs_imap_load(EXT2FS_INFO * ext2fs, EXT2_GRPNUM_T grp_num) + ext2fs_imap_load(EXT2FS_INFO * ext2fs, EXT2_GRPNUM_T grp_num) { TSK_FS_INFO *fs = (TSK_FS_INFO *) & ext2fs->fs_info; ssize_t cnt; + TSK_DADDR_T addr; /* - * Look up the group descriptor info. - */ + * Look up the group descriptor info. + */ if (ext2fs_group_load(ext2fs, grp_num)) { return 1; } @@ -437,8 +410,8 @@ ext2fs_imap_load(EXT2FS_INFO * ext2fs, EXT2_GRPNUM_T grp_num) /* Allocate the cache buffer and exit if map is already loaded */ if (ext2fs->imap_buf == NULL) { if ((ext2fs->imap_buf = - (uint8_t *) tsk_malloc(fs->block_size)) == NULL) { - return 1; + (uint8_t *) tsk_malloc(fs->block_size)) == NULL) { + return 1; } } else if (ext2fs->imap_grp_num == grp_num) { @@ -446,71 +419,42 @@ ext2fs_imap_load(EXT2FS_INFO * ext2fs, EXT2_GRPNUM_T grp_num) } /* - * Look up the inode allocation bitmap. - */ - if (EXT2FS_HAS_INCOMPAT_FEATURE(fs, ext2fs->fs, - EXT2FS_FEATURE_INCOMPAT_64BIT)) { - if (ext4_getu64(fs->endian, - ext2fs->ext4_grp_buf->bg_block_bitmap_hi, - ext2fs->ext4_grp_buf->bg_block_bitmap_lo) - > fs->last_block) { - tsk_error_reset(); - tsk_error_set_errno(TSK_ERR_FS_BLK_NUM); - tsk_error_set_errstr - ("ext2fs_imap_load: Block too large for image: %" PRIu64 - "", ext4_getu64(fs->endian, - ext2fs->ext4_grp_buf->bg_block_bitmap_hi, - ext2fs->ext4_grp_buf->bg_block_bitmap_lo)); - } - - cnt = tsk_fs_read(fs, - (TSK_DADDR_T) ext4_getu64(fs->endian, - ext2fs->ext4_grp_buf->bg_inode_bitmap_hi, - ext2fs->ext4_grp_buf->bg_block_bitmap_lo) * fs->block_size, - (char *) ext2fs->imap_buf, ext2fs->fs_info.block_size); - - if (cnt != ext2fs->fs_info.block_size) { - if (cnt >= 0) { - tsk_error_reset(); - tsk_error_set_errno(TSK_ERR_FS_READ); - } - tsk_error_set_errstr2("ext2fs_imap_load: Inode bitmap %" - PRI_EXT2GRP " at %" PRIu32, grp_num, tsk_getu32(fs->endian, - ext2fs->grp_buf->bg_inode_bitmap)); - } + * Look up the inode allocation bitmap. + */ + if (ext2fs->ext4_grp_buf != NULL) { + addr = ext4_getu64(fs->endian, + ext2fs->ext4_grp_buf->bg_inode_bitmap_hi, + ext2fs->ext4_grp_buf->bg_inode_bitmap_lo); } else { - if (tsk_getu32(fs->endian, - ext2fs->grp_buf->bg_inode_bitmap) > fs->last_block) { - tsk_error_reset(); - tsk_error_set_errno(TSK_ERR_FS_BLK_NUM); - tsk_error_set_errstr - ("ext2fs_imap_load: Block too large for image: %" PRIu32 - "", tsk_getu32(fs->endian, - ext2fs->grp_buf->bg_inode_bitmap)); - } + addr = (TSK_DADDR_T) tsk_getu32(fs->endian, ext2fs->grp_buf->bg_inode_bitmap); + } - cnt = tsk_fs_read(fs, - (TSK_DADDR_T) tsk_getu32(fs->endian, - ext2fs->grp_buf->bg_inode_bitmap) * fs->block_size, - (char *) ext2fs->imap_buf, ext2fs->fs_info.block_size); + if (addr > fs->last_block) { + tsk_error_reset(); + tsk_error_set_errno(TSK_ERR_FS_BLK_NUM); + tsk_error_set_errstr + ("ext2fs_imap_load: Block too large for image: %" PRIu64, addr); + return 1; + } - if (cnt != ext2fs->fs_info.block_size) { - if (cnt >= 0) { - tsk_error_reset(); - tsk_error_set_errno(TSK_ERR_FS_READ); - } - tsk_error_set_errstr2("ext2fs_imap_load: Inode bitmap %" - PRI_EXT2GRP " at %" PRIu32, grp_num, tsk_getu32(fs->endian, - ext2fs->grp_buf->bg_inode_bitmap)); + cnt = tsk_fs_read(fs, addr * fs->block_size, + (char *) ext2fs->imap_buf, ext2fs->fs_info.block_size); + + if (cnt != ext2fs->fs_info.block_size) { + if (cnt >= 0) { + tsk_error_reset(); + tsk_error_set_errno(TSK_ERR_FS_READ); } + tsk_error_set_errstr2("ext2fs_imap_load: Inode bitmap %" + PRI_EXT2GRP " at %" PRIu64, grp_num, addr); + return 1; } - ext2fs->imap_grp_num = grp_num; if (tsk_verbose > 1) ext2fs_print_map(ext2fs->imap_buf, - tsk_getu32(fs->endian, ext2fs->fs->s_inodes_per_group)); + tsk_getu32(fs->endian, ext2fs->fs->s_inodes_per_group)); return 0; } @@ -572,9 +516,7 @@ ext2fs_dinode_load(EXT2FS_INFO * ext2fs, TSK_INUM_T dino_inum, rel_inum = (dino_inum - 1) - tsk_getu32(fs->endian, ext2fs->fs->s_inodes_per_group) * grp_num; - if (EXT2FS_HAS_INCOMPAT_FEATURE(fs, ext2fs->fs, - EXT2FS_FEATURE_INCOMPAT_64BIT) - && (tsk_getu16(fs->endian, ext2fs->fs->s_desc_size) >= 64)) { + if (ext2fs->ext4_grp_buf != NULL) { #ifdef Ext4_DBG printf("DEBUG: d_inode_load 64bit gd_size=%d\n", tsk_getu16(fs->endian, ext2fs->fs->s_desc_size)); @@ -1241,10 +1183,9 @@ ext2fs_block_getflags(TSK_FS_INFO * a_fs, TSK_DADDR_T a_addr) * s_first_data_block field. */ dbase = ext2_cgbase_lcl(a_fs, ext2fs->fs, grp_num); - dmin = - tsk_getu32(a_fs->endian, - ext2fs->grp_buf->bg_inode_table) + INODE_TABLE_SIZE(ext2fs); - + flags = (isset(ext2fs->bmap_buf, a_addr - dbase) ? + TSK_FS_BLOCK_FLAG_ALLOC : TSK_FS_BLOCK_FLAG_UNALLOC); + /* * Identify meta blocks * (any blocks that can't be allocated for file/directory data). @@ -1262,25 +1203,52 @@ ext2fs_block_getflags(TSK_FS_INFO * a_fs, TSK_DADDR_T a_addr) * locations of superblocks and group descriptor blocks are reserved. * They just happen to be reserved for something else :-) */ - flags = (isset(ext2fs->bmap_buf, a_addr - dbase) ? - TSK_FS_BLOCK_FLAG_ALLOC : TSK_FS_BLOCK_FLAG_UNALLOC); - if ((a_addr >= dbase - && a_addr < tsk_getu32(a_fs->endian, - ext2fs->grp_buf->bg_block_bitmap)) - || (a_addr == tsk_getu32(a_fs->endian, - ext2fs->grp_buf->bg_block_bitmap)) - || (a_addr == tsk_getu32(a_fs->endian, - ext2fs->grp_buf->bg_inode_bitmap)) - || (a_addr >= tsk_getu32(a_fs->endian, - ext2fs->grp_buf->bg_inode_table) - && a_addr < dmin)) - flags |= TSK_FS_BLOCK_FLAG_META; - else - flags |= TSK_FS_BLOCK_FLAG_CONT; + if (ext2fs->ext4_grp_buf != NULL) { + dmin = ext4_getu64(a_fs->endian, ext2fs->ext4_grp_buf->bg_inode_table_hi, + ext2fs->ext4_grp_buf->bg_inode_table_lo) + + INODE_TABLE_SIZE(ext2fs); + + if ((a_addr >= dbase + && a_addr < ext4_getu64(a_fs->endian, + ext2fs->ext4_grp_buf->bg_block_bitmap_hi, + ext2fs->ext4_grp_buf->bg_block_bitmap_lo)) + || (a_addr == ext4_getu64(a_fs->endian, + ext2fs->ext4_grp_buf->bg_block_bitmap_hi, + ext2fs->ext4_grp_buf->bg_block_bitmap_lo)) + || (a_addr == ext4_getu64(a_fs->endian, + ext2fs->ext4_grp_buf->bg_inode_bitmap_hi, + ext2fs->ext4_grp_buf->bg_inode_bitmap_lo)) + || (a_addr >= ext4_getu64(a_fs->endian, + ext2fs->ext4_grp_buf->bg_inode_table_hi, + ext2fs->ext4_grp_buf->bg_inode_table_lo) + && a_addr < dmin)) + flags |= TSK_FS_BLOCK_FLAG_META; + else + flags |= TSK_FS_BLOCK_FLAG_CONT; + + } + else { + dmin = + tsk_getu32(a_fs->endian, + ext2fs->grp_buf->bg_inode_table) + INODE_TABLE_SIZE(ext2fs); + if ((a_addr >= dbase + && a_addr < tsk_getu32(a_fs->endian, + ext2fs->grp_buf->bg_block_bitmap)) + || (a_addr == tsk_getu32(a_fs->endian, + ext2fs->grp_buf->bg_block_bitmap)) + || (a_addr == tsk_getu32(a_fs->endian, + ext2fs->grp_buf->bg_inode_bitmap)) + || (a_addr >= tsk_getu32(a_fs->endian, + ext2fs->grp_buf->bg_inode_table) + && a_addr < dmin)) + flags |= TSK_FS_BLOCK_FLAG_META; + else + flags |= TSK_FS_BLOCK_FLAG_CONT; + } + tsk_release_lock(&ext2fs->lock); - return flags; + return (TSK_FS_BLOCK_FLAG_ENUM)flags; } @@ -1760,6 +1728,10 @@ ext4_fsstat_datablock_helper(TSK_FS_INFO * fs, FILE * hFile, uint64_t db_offset = 0; unsigned int num_groups = 0, left_over = 0; + if (ext4_gd == NULL) { + return; + } + #ifdef Ext4_DBG printf("\nDEBUG 64bit:%d, gd_size %d, combined %d\n", EXT2FS_HAS_INCOMPAT_FEATURE(fs, sb, EXT2FS_FEATURE_INCOMPAT_64BIT), @@ -1774,9 +1746,9 @@ ext4_fsstat_datablock_helper(TSK_FS_INFO * fs, FILE * hFile, 1) / fs->block_size; /* number of blocks group descriptors consume */ gd_blocks = - (gd_size * ext2fs->groups_count + fs->block_size - - 1) / fs->block_size; - num_flex_bg = (ext2fs->groups_count / gpfbg); + (unsigned int)((gd_size * ext2fs->groups_count + fs->block_size - + 1) / fs->block_size); + num_flex_bg = (unsigned int)(ext2fs->groups_count / gpfbg); if (ext2fs->groups_count % gpfbg) num_flex_bg++; curr_flex_bg = i / gpfbg; @@ -1798,64 +1770,39 @@ ext4_fsstat_datablock_helper(TSK_FS_INFO * fs, FILE * hFile, //{ if (i % gpfbg == 0) { if (curr_flex_bg == (num_flex_bg - 1)) { - num_groups = - fs->last_block / tsk_getu32(fs->endian, - sb->s_blocks_per_group); + num_groups = (unsigned int) + (fs->last_block / tsk_getu32(fs->endian, + sb->s_blocks_per_group)); if (num_groups % tsk_getu32(fs->endian, sb->s_blocks_per_group)) num_groups++; left_over = (num_groups % gpfbg); - if (EXT2FS_HAS_INCOMPAT_FEATURE(fs, sb, - EXT2FS_FEATURE_INCOMPAT_64BIT) && gd_size >= 64) { -//DEBUG printf("DEBUG processing 64bit file system with 64 bit group descriptors"); - tsk_fprintf(hFile, " Uninit Data Bitmaps: "); - tsk_fprintf(hFile, "%" PRIu64 " - %" PRIu64 "\n", - ext4_getu64(fs->endian, ext4_gd->bg_block_bitmap_hi, - ext2fs->ext4_grp_buf->bg_block_bitmap_lo) - + (left_over), ext4_getu64(fs->endian, - ext4_gd->bg_block_bitmap_hi, - ext2fs->ext4_grp_buf->bg_block_bitmap_lo) - + gpfbg - 1); - tsk_fprintf(hFile, " Uninit Inode Bitmaps: "); - tsk_fprintf(hFile, "%" PRIu64 " - %" PRIu64 "\n", - ext4_getu64(fs->endian, ext4_gd->bg_inode_bitmap_hi, - ext2fs->ext4_grp_buf->bg_inode_bitmap_lo) - + (left_over), ext4_getu64(fs->endian, - ext4_gd->bg_inode_bitmap_hi, - ext2fs->ext4_grp_buf->bg_inode_bitmap_lo) - + gpfbg - 1); - tsk_fprintf(hFile, " Uninit Inode Table: "); - tsk_fprintf(hFile, "%" PRIu64 " - %" PRIu64 "\n", - ext4_getu64(fs->endian, ext4_gd->bg_inode_table_hi, - ext2fs->ext4_grp_buf->bg_inode_table_lo) - + ((left_over) * ibpg), ext4_getu64(fs->endian, - ext4_gd->bg_inode_table_hi, - ext2fs->ext4_grp_buf->bg_inode_table_lo) - + (gpfbg * ibpg) - 1); - } - else { - tsk_fprintf(hFile, " Uninit Data Bitmaps: "); - tsk_fprintf(hFile, "%" PRIu32 " - %" PRIu32 "\n", - tsk_getu32(fs->endian, - ext2fs->ext4_grp_buf->bg_block_bitmap_lo) - + (left_over), tsk_getu32(fs->endian, - ext2fs->ext4_grp_buf->bg_block_bitmap_lo) - + gpfbg - 1); - tsk_fprintf(hFile, " Uninit Inode Bitmaps: "); - tsk_fprintf(hFile, "%" PRIu32 " - %" PRIu32 "\n", - tsk_getu32(fs->endian, - ext2fs->ext4_grp_buf->bg_inode_bitmap_lo) - + (left_over), tsk_getu32(fs->endian, - ext2fs->ext4_grp_buf->bg_inode_bitmap_lo) - + gpfbg - 1); - tsk_fprintf(hFile, " Uninit Inode Table: "); - tsk_fprintf(hFile, "%" PRIu32 " - %" PRIu32 "\n", - tsk_getu32(fs->endian, - ext2fs->ext4_grp_buf->bg_inode_table_lo) - + ((left_over) * ibpg), tsk_getu32(fs->endian, - ext2fs->ext4_grp_buf->bg_inode_table_lo) - + (gpfbg * ibpg) - 1); - } + + tsk_fprintf(hFile, " Uninit Data Bitmaps: "); + tsk_fprintf(hFile, "%" PRIu64 " - %" PRIu64 "\n", + ext4_getu64(fs->endian, ext4_gd->bg_block_bitmap_hi, + ext2fs->ext4_grp_buf->bg_block_bitmap_lo) + + (left_over), ext4_getu64(fs->endian, + ext4_gd->bg_block_bitmap_hi, + ext2fs->ext4_grp_buf->bg_block_bitmap_lo) + + gpfbg - 1); + tsk_fprintf(hFile, " Uninit Inode Bitmaps: "); + tsk_fprintf(hFile, "%" PRIu64 " - %" PRIu64 "\n", + ext4_getu64(fs->endian, ext4_gd->bg_inode_bitmap_hi, + ext2fs->ext4_grp_buf->bg_inode_bitmap_lo) + + (left_over), ext4_getu64(fs->endian, + ext4_gd->bg_inode_bitmap_hi, + ext2fs->ext4_grp_buf->bg_inode_bitmap_lo) + + gpfbg - 1); + tsk_fprintf(hFile, " Uninit Inode Table: "); + tsk_fprintf(hFile, "%" PRIu64 " - %" PRIu64 "\n", + ext4_getu64(fs->endian, ext4_gd->bg_inode_table_hi, + ext2fs->ext4_grp_buf->bg_inode_table_lo) + + ((left_over) * ibpg), ext4_getu64(fs->endian, + ext4_gd->bg_inode_table_hi, + ext2fs->ext4_grp_buf->bg_inode_table_lo) + + (gpfbg * ibpg) - 1); + } tsk_fprintf(hFile, " Data Blocks: "); db_offset = 0; @@ -2195,15 +2142,15 @@ ext2fs_fsstat(TSK_FS_INFO * fs, FILE * hFile) 1) / fs->block_size; /* number of blocks group descriptors consume */ gd_blocks = - (gd_size * ext2fs->groups_count + fs->block_size - - 1) / fs->block_size; + (unsigned int)((gd_size * ext2fs->groups_count + fs->block_size - + 1) / fs->block_size); #ifdef Ext4_DBG tsk_fprintf(hFile, "\n\tDEBUG: Group Descriptor Size: %d\n", gd_size); //DEBUG tsk_fprintf(hFile, "\n\tDEBUG: Group Descriptor Size: %d\n", *sb->s_desc_size); //DEBUG debug_print_buf((unsigned char *) &sb->pad_or_gdt, 16); printf("\n\tDEBUG: gdt_growth: %d\n", tsk_getu16(fs->endian, - sb->pad_or_gdt.s_reserved_gdt_blocks)); + sb->pad_or_gdt.s_reserved_gdt_blocks)); #endif for (i = 0; i < ext2fs->groups_count; i++) { @@ -2218,16 +2165,16 @@ ext2fs_fsstat(TSK_FS_INFO * fs, FILE * hFile) return 1; } tsk_fprintf(hFile, "\nGroup: %d:\n", i); - if (fs->ftype == TSK_FS_TYPE_EXT4) { + if (ext2fs->ext4_grp_buf != NULL) { tsk_fprintf(hFile, " Block Group Flags: ["); if (EXT4BG_HAS_FLAG(fs, ext2fs->ext4_grp_buf, - EXT4_BG_INODE_UNINIT)) + EXT4_BG_INODE_UNINIT)) tsk_fprintf(hFile, "INODE_UNINIT, "); if (EXT4BG_HAS_FLAG(fs, ext2fs->ext4_grp_buf, - EXT4_BG_BLOCK_UNINIT)) + EXT4_BG_BLOCK_UNINIT)) tsk_fprintf(hFile, "BLOCK_UNINIT, "); if (EXT4BG_HAS_FLAG(fs, ext2fs->ext4_grp_buf, - EXT4_BG_INODE_ZEROED)) + EXT4_BG_INODE_ZEROED)) tsk_fprintf(hFile, "INODE_ZEROED, "); tsk_fprintf(hFile, "\b\b]\n"); } @@ -2239,32 +2186,32 @@ ext2fs_fsstat(TSK_FS_INFO * fs, FILE * hFile) if ((inum + tsk_gets32(fs->endian, sb->s_inodes_per_group) - 1) < fs->last_inum) tsk_fprintf(hFile, "%" PRIuINUM "\n", - inum + tsk_gets32(fs->endian, sb->s_inodes_per_group) - 1); + inum + tsk_gets32(fs->endian, sb->s_inodes_per_group) - 1); else tsk_fprintf(hFile, "%" PRIuINUM "\n", fs->last_inum); if (tsk_getu32(fs->endian, - ext2fs->fs-> - s_feature_incompat) & EXT2FS_FEATURE_INCOMPAT_64BIT) { - cg_base = ext4_cgbase_lcl(fs, sb, i); + ext2fs->fs-> + s_feature_incompat) & EXT2FS_FEATURE_INCOMPAT_64BIT) { + cg_base = ext4_cgbase_lcl(fs, sb, i); #ifdef Ext4_DBG - printf("DEBUG64: ext2_cgbase_lcl %" PRIuDADDR "\n", cg_base); - printf("DEBUG64: fs->s_first_data_block %" PRIuDADDR "\n", - tsk_getu32(fs->endian, sb->s_first_data_block)); - printf("DEBUG64: blocks_per_group %" PRIuDADDR "\n", - tsk_getu32(fs->endian, sb->s_blocks_per_group)); - printf("DEBUG64: i %" PRIuDADDR " %" PRIuDADDR " %" PRIuDADDR - "\n", i, tsk_getu32(fs->endian, sb->s_blocks_per_group), - (uint64_t) i * (uint64_t) tsk_getu32(fs->endian, + printf("DEBUG64: ext2_cgbase_lcl %" PRIuDADDR "\n", cg_base); + printf("DEBUG64: fs->s_first_data_block %" PRIuDADDR "\n", + tsk_getu32(fs->endian, sb->s_first_data_block)); + printf("DEBUG64: blocks_per_group %" PRIuDADDR "\n", + tsk_getu32(fs->endian, sb->s_blocks_per_group)); + printf("DEBUG64: i %" PRIuDADDR " %" PRIuDADDR " %" PRIuDADDR + "\n", i, tsk_getu32(fs->endian, sb->s_blocks_per_group), + (uint64_t) i * (uint64_t) tsk_getu32(fs->endian, sb->s_blocks_per_group)); - //printf("DEBUG: calculated %"PRIuDADDR"\n", ) + //printf("DEBUG: calculated %"PRIuDADDR"\n", ) #endif - tsk_fprintf(hFile, - " Block Range: %" PRIuDADDR " - %" PRIuDADDR "\n", - cg_base, ((ext4_cgbase_lcl(fs, sb, - i + 1) - 1) < + tsk_fprintf(hFile, + " Block Range: %" PRIuDADDR " - %" PRIuDADDR "\n", + cg_base, ((ext4_cgbase_lcl(fs, sb, + i + 1) - 1) < fs->last_block) ? (ext4_cgbase_lcl(fs, sb, - i + 1) - 1) : fs->last_block); + i + 1) - 1) : fs->last_block); } else { cg_base = ext2_cgbase_lcl(fs, sb, i); @@ -2279,15 +2226,15 @@ ext2fs_fsstat(TSK_FS_INFO * fs, FILE * hFile) " i*blocks_per_group: %" PRIu32 "\n", i, tsk_getu32(fs->endian, sb->s_blocks_per_group), (uint64_t) i * (uint64_t) tsk_getu32(fs->endian, - sb->s_blocks_per_group)); + sb->s_blocks_per_group)); //printf("DEBUG: calculated %"PRIuDADDR"\n", ) #endif tsk_fprintf(hFile, " Block Range: %" PRIuDADDR " - %" PRIuDADDR "\n", cg_base, ((ext2_cgbase_lcl(fs, sb, - i + 1) - 1) < - fs->last_block) ? (ext2_cgbase_lcl(fs, sb, - i + 1) - 1) : fs->last_block); + i + 1) - 1) < + fs->last_block) ? (ext2_cgbase_lcl(fs, sb, + i + 1) - 1) : fs->last_block); } @@ -2295,97 +2242,97 @@ ext2fs_fsstat(TSK_FS_INFO * fs, FILE * hFile) tsk_fprintf(hFile, " Layout:\n"); /* only print the super block data if we are not in a sparse - * group - */ + * group + */ #ifdef Ext4_DBG printf("DEBUG: ext2fs_super: %d\n", ext2fs_bg_has_super(tsk_getu32(fs->endian, - sb->s_feature_ro_compat), i)); + sb->s_feature_ro_compat), i)); #endif -/* if (((tsk_getu32(fs->endian, ext2fs->fs->s_feature_ro_compat) & - EXT2FS_FEATURE_RO_COMPAT_SPARSE_SUPER) && - (cg_base != tsk_getu32(fs->endian, - ext2fs->grp_buf->bg_block_bitmap))) - || ((tsk_getu32(fs->endian, - ext2fs->fs->s_feature_ro_compat) & - EXT2FS_FEATURE_RO_COMPAT_SPARSE_SUPER) == 0)) { -*/ + /* if (((tsk_getu32(fs->endian, ext2fs->fs->s_feature_ro_compat) & + EXT2FS_FEATURE_RO_COMPAT_SPARSE_SUPER) && + (cg_base != tsk_getu32(fs->endian, + ext2fs->grp_buf->bg_block_bitmap))) + || ((tsk_getu32(fs->endian, + ext2fs->fs->s_feature_ro_compat) & + EXT2FS_FEATURE_RO_COMPAT_SPARSE_SUPER) == 0)) { + */ if (ext2fs_bg_has_super(tsk_getu32(fs->endian, - sb->s_feature_ro_compat), i)) { - TSK_OFF_T boff; + sb->s_feature_ro_compat), i)) { + TSK_OFF_T boff; - /* the super block is the first 1024 bytes */ - tsk_fprintf(hFile, - " Super Block: %" PRIuDADDR " - %" PRIuDADDR "\n", - cg_base, - cg_base + - ((sizeof(ext2fs_sb) + fs->block_size - - 1) / fs->block_size) - 1); + /* the super block is the first 1024 bytes */ + tsk_fprintf(hFile, + " Super Block: %" PRIuDADDR " - %" PRIuDADDR "\n", + cg_base, + cg_base + + ((sizeof(ext2fs_sb) + fs->block_size - + 1) / fs->block_size) - 1); - boff = roundup(sizeof(ext2fs_sb), fs->block_size); + boff = roundup(sizeof(ext2fs_sb), fs->block_size); - /* Group Descriptors */ - tsk_fprintf(hFile, - " Group Descriptor Table: %" PRIuDADDR " - ", - (cg_base + (boff + fs->block_size - 1) / fs->block_size)); - -// printf("DEBUG: Groups Count: %u * gd_size: %u = %u\n", ext2fs->groups_count, gd_size, ext2fs->groups_count * gd_size); - boff += (ext2fs->groups_count * gd_size); - tsk_fprintf(hFile, "%" PRIuDADDR "\n", - ((cg_base + - (boff + fs->block_size - 1) / fs->block_size) - - 1)); - if (fs->ftype == TSK_FS_TYPE_EXT4) { + /* Group Descriptors */ tsk_fprintf(hFile, - " Group Descriptor Growth Blocks: %" PRIuDADDR - " - ", - cg_base + (boff + fs->block_size - - 1) / fs->block_size); - boff += - tsk_getu16(fs->endian, - ext2fs->fs->pad_or_gdt.s_reserved_gdt_blocks) * - fs->block_size; + " Group Descriptor Table: %" PRIuDADDR " - ", + (cg_base + (boff + fs->block_size - 1) / fs->block_size)); + + // printf("DEBUG: Groups Count: %u * gd_size: %u = %u\n", ext2fs->groups_count, gd_size, ext2fs->groups_count * gd_size); + boff += (ext2fs->groups_count * gd_size); tsk_fprintf(hFile, "%" PRIuDADDR "\n", - ((cg_base + (boff + fs->block_size - - 1) / fs->block_size) - 1)); - } + ((cg_base + + (boff + fs->block_size - 1) / fs->block_size) - + 1)); + if (fs->ftype == TSK_FS_TYPE_EXT4) { + tsk_fprintf(hFile, + " Group Descriptor Growth Blocks: %" PRIuDADDR + " - ", + cg_base + (boff + fs->block_size - + 1) / fs->block_size); + boff += + tsk_getu16(fs->endian, + ext2fs->fs->pad_or_gdt.s_reserved_gdt_blocks) * + fs->block_size; + tsk_fprintf(hFile, "%" PRIuDADDR "\n", + ((cg_base + (boff + fs->block_size - + 1) / fs->block_size) - 1)); + } } - if (tsk_getu32(fs->endian, - ext2fs->fs-> - s_feature_incompat) & EXT2FS_FEATURE_INCOMPAT_64BIT) { + if (ext2fs->ext4_grp_buf != NULL) { /* The block bitmap is a full block */ tsk_fprintf(hFile, " Data bitmap: %" PRIu64 " - %" PRIu64 "\n", ext4_getu64(fs->endian, - ext2fs->ext4_grp_buf->bg_block_bitmap_hi, - ext2fs->ext4_grp_buf->bg_block_bitmap_lo), + ext2fs->ext4_grp_buf->bg_block_bitmap_hi, + ext2fs->ext4_grp_buf->bg_block_bitmap_lo), ext4_getu64(fs->endian, - ext2fs->ext4_grp_buf->bg_block_bitmap_hi, - ext2fs->ext4_grp_buf->bg_block_bitmap_lo)); + ext2fs->ext4_grp_buf->bg_block_bitmap_hi, + ext2fs->ext4_grp_buf->bg_block_bitmap_lo)); /* The inode bitmap is a full block */ tsk_fprintf(hFile, " Inode bitmap: %" PRIu64 " - %" PRIu64 "\n", ext4_getu64(fs->endian, - ext2fs->ext4_grp_buf->bg_inode_bitmap_hi, - ext2fs->ext4_grp_buf->bg_inode_bitmap_lo), + ext2fs->ext4_grp_buf->bg_inode_bitmap_hi, + ext2fs->ext4_grp_buf->bg_inode_bitmap_lo), ext4_getu64(fs->endian, - ext2fs->ext4_grp_buf->bg_inode_bitmap_hi, - ext2fs->ext4_grp_buf->bg_inode_bitmap_lo)); + ext2fs->ext4_grp_buf->bg_inode_bitmap_hi, + ext2fs->ext4_grp_buf->bg_inode_bitmap_lo)); tsk_fprintf(hFile, " Inode Table: %" PRIu64 " - %" PRIu64 "\n", ext4_getu64(fs->endian, - ext2fs->ext4_grp_buf->bg_inode_table_hi, - ext2fs->ext4_grp_buf->bg_inode_table_lo), + ext2fs->ext4_grp_buf->bg_inode_table_hi, + ext2fs->ext4_grp_buf->bg_inode_table_lo), ext4_getu64(fs->endian, - ext2fs->ext4_grp_buf->bg_inode_table_hi, - ext2fs->ext4_grp_buf->bg_inode_table_lo) + ext2fs->ext4_grp_buf->bg_inode_table_hi, + ext2fs->ext4_grp_buf->bg_inode_table_lo) + ibpg - 1); + + ext4_fsstat_datablock_helper(fs, hFile, i, cg_base, gd_size); } else { /* The block bitmap is a full block */ @@ -2406,80 +2353,95 @@ ext2fs_fsstat(TSK_FS_INFO * fs, FILE * hFile) " Inode Table: %" PRIu32 " - %" PRIu32 "\n", tsk_getu32(fs->endian, ext2fs->grp_buf->bg_inode_table), tsk_getu32(fs->endian, - ext2fs->grp_buf->bg_inode_table) + ibpg - 1); - } - /* If we are in a sparse group, display the other addresses */ - if (fs->ftype == TSK_FS_TYPE_EXT4) { - ext4_fsstat_datablock_helper(fs, hFile, i, cg_base, gd_size); - } - else { + ext2fs->grp_buf->bg_inode_table) + ibpg - 1); + tsk_fprintf(hFile, " Data Blocks: "); // BC: Commented out from Ext4 commit because it produced // bad data on Ext2 test image. //if (ext2fs_bg_has_super(tsk_getu32(fs->endian, // sb->s_feature_ro_compat), i)) { - if ((tsk_getu32(fs->endian, ext2fs->fs->s_feature_ro_compat) & + if ((tsk_getu32(fs->endian, ext2fs->fs->s_feature_ro_compat) & EXT2FS_FEATURE_RO_COMPAT_SPARSE_SUPER) && - (cg_base == tsk_getu32(fs->endian, - ext2fs->grp_buf->bg_block_bitmap))) { - - /* it goes from the end of the inode bitmap to before the - * table - * - * This hard coded aspect does not scale ... - */ - - tsk_fprintf(hFile, "%" PRIu32 " - %" PRIu32 ", ", - tsk_getu32(fs->endian, + (cg_base == tsk_getu32(fs->endian, + ext2fs->grp_buf->bg_block_bitmap))) { + + /* it goes from the end of the inode bitmap to before the + * table + * + * This hard coded aspect does not scale ... + */ + + tsk_fprintf(hFile, "%" PRIu32 " - %" PRIu32 ", ", + tsk_getu32(fs->endian, ext2fs->grp_buf->bg_inode_bitmap) + 1, - tsk_getu32(fs->endian, + tsk_getu32(fs->endian, ext2fs->grp_buf->bg_inode_table) - 1); } tsk_fprintf(hFile, "%" PRIu32 " - %" PRIu32 "\n", (uint64_t) tsk_getu32(fs->endian, - ext2fs->grp_buf->bg_inode_table) + ibpg, + ext2fs->grp_buf->bg_inode_table) + ibpg, ((ext2_cgbase_lcl(fs, sb, i + 1) - 1) < - fs->last_block) ? (ext2_cgbase_lcl(fs, sb, - i + 1) - 1) : fs->last_block); + fs->last_block) ? (ext2_cgbase_lcl(fs, sb, + i + 1) - 1) : fs->last_block); } - /* Print the free info */ + /* Print the free info */ /* The last group may not have a full number of blocks */ if (i != (ext2fs->groups_count - 1)) { + uint64_t tmpInt; + + if (ext2fs->ext4_grp_buf != NULL) + // @@@ Should be 32-bit + tmpInt = tsk_getu16(fs->endian, + ext2fs->ext4_grp_buf->bg_free_inodes_count_lo); + else + tmpInt = tsk_getu16(fs->endian, + ext2fs->grp_buf->bg_free_inodes_count); + tsk_fprintf(hFile, - " Free Inodes: %" PRIu16 " (%" PRIu32 "%%)\n", - tsk_getu16(fs->endian, - ext2fs->grp_buf->bg_free_inodes_count), - (100 * tsk_getu16(fs->endian, - ext2fs->grp_buf->bg_free_inodes_count)) / + " Free Inodes: %" PRIu32 " (%" PRIu32 "%%)\n", + tmpInt, (100 * tmpInt) / tsk_getu32(fs->endian, sb->s_inodes_per_group)); + + if (ext2fs->ext4_grp_buf != NULL) + // @@@ Should be 32-bit + tmpInt = tsk_getu16(fs->endian, + ext2fs->ext4_grp_buf->bg_free_blocks_count_lo); + else + tmpInt = tsk_getu16(fs->endian, + ext2fs->grp_buf->bg_free_blocks_count); + tsk_fprintf(hFile, - " Free Blocks: %" PRIu16 " (%" PRIu32 "%%)\n", - tsk_getu16(fs->endian, - ext2fs->grp_buf->bg_free_blocks_count), - (100 * tsk_getu16(fs->endian, - ext2fs->grp_buf->bg_free_blocks_count)) / + " Free Blocks: %" PRIu32 " (%" PRIu32 "%%)\n", + tmpInt, + (100 * tmpInt) / tsk_getu32(fs->endian, sb->s_blocks_per_group)); } else { TSK_INUM_T inum_left; TSK_DADDR_T blk_left; + uint64_t tmpInt; inum_left = (fs->last_inum % tsk_gets32(fs->endian, - sb->s_inodes_per_group)) - 1; + sb->s_inodes_per_group)) - 1; if (inum_left == 0) inum_left = tsk_getu32(fs->endian, sb->s_inodes_per_group); - tsk_fprintf(hFile, " Free Inodes: %" PRIu16 " (%d%%)\n", - tsk_getu16(fs->endian, - ext2fs->grp_buf->bg_free_inodes_count), - 100 * tsk_getu16(fs->endian, - ext2fs->grp_buf->bg_free_inodes_count) / inum_left); + if (ext2fs->ext4_grp_buf != NULL) + // @@@ Should be 32-bit + tmpInt = tsk_getu16(fs->endian, + ext2fs->ext4_grp_buf->bg_free_inodes_count_lo); + else + tmpInt = tsk_getu16(fs->endian, + ext2fs->grp_buf->bg_free_inodes_count); + + tsk_fprintf(hFile, " Free Inodes: %" PRIu32 " (%d%%)\n", + tmpInt, 100 * tmpInt / inum_left); /* Now blocks */ blk_left = @@ -2488,25 +2450,36 @@ ext2fs_fsstat(TSK_FS_INFO * fs, FILE * hFile) if (blk_left == 0) blk_left = tsk_getu32(fs->endian, sb->s_blocks_per_group); - tsk_fprintf(hFile, " Free Blocks: %" PRIu16 " (%d%%)\n", - tsk_getu16(fs->endian, - ext2fs->grp_buf->bg_free_blocks_count), - 100 * tsk_getu16(fs->endian, - ext2fs->grp_buf->bg_free_blocks_count) / blk_left); + if (ext2fs->ext4_grp_buf != NULL) + // @@@ Should be 32-bit + tmpInt = tsk_getu16(fs->endian, + ext2fs->ext4_grp_buf->bg_free_blocks_count_lo); + else + tmpInt = tsk_getu16(fs->endian, + ext2fs->grp_buf->bg_free_blocks_count); + + tsk_fprintf(hFile, " Free Blocks: %" PRIu32 " (%d%%)\n", + tmpInt, 100 * tmpInt / blk_left); } - tsk_fprintf(hFile, " Total Directories: %" PRIu16 "\n", - tsk_getu16(fs->endian, ext2fs->grp_buf->bg_used_dirs_count)); - if (fs->ftype == TSK_FS_TYPE_EXT4) { + if (ext2fs->ext4_grp_buf != NULL) { + // @@@@ Sould be 32-bit + tsk_fprintf(hFile, " Total Directories: %" PRIu16 "\n", + tsk_getu16(fs->endian, ext2fs->ext4_grp_buf->bg_used_dirs_count_lo)); + tsk_fprintf(hFile, " Stored Checksum: 0x%04" PRIX16 "\n", tsk_getu16(fs->endian, ext2fs->ext4_grp_buf->bg_checksum)); #ifdef EXT4_CHECKSUMS -//Need Non-GPL CRC16 + //Need Non-GPL CRC16 tsk_fprintf(hFile, " Calculated Checksum: 0x%04" PRIX16 "\n", ext4_group_desc_csum(ext2fs->fs, i, ext2fs->ext4_grp_buf)); #endif } + else { + tsk_fprintf(hFile, " Total Directories: %" PRIu16 "\n", + tsk_getu16(fs->endian, ext2fs->grp_buf->bg_used_dirs_count)); + } tsk_release_lock(&ext2fs->lock); } @@ -3134,6 +3107,9 @@ ext2fs_close(TSK_FS_INFO * fs) if (ext2fs->grp_buf != NULL) free((char *) ext2fs->grp_buf); + if (ext2fs->ext4_grp_buf != NULL) + free((char *) ext2fs->ext4_grp_buf); + if (ext2fs->bmap_buf != NULL) free((char *) ext2fs->bmap_buf); @@ -3338,6 +3314,30 @@ ext2fs_open(TSK_IMG_INFO * img_info, TSK_OFF_T offset, ext2fs->groups_offset = roundup((EXT2FS_SBOFF + sizeof(ext2fs_sb)), fs->block_size); + // sanity check to avoid divide by zero issues + if (tsk_getu32(fs->endian, ext2fs->fs->s_blocks_per_group) == 0) { + fs->tag = 0; + free(ext2fs->fs); + tsk_fs_free((TSK_FS_INFO *)ext2fs); + tsk_error_reset(); + tsk_error_set_errno(TSK_ERR_FS_MAGIC); + tsk_error_set_errstr("Not an EXTxFS file system (blocks per group)"); + if (tsk_verbose) + fprintf(stderr, "ext2fs_open: blocks per group is 0\n"); + return NULL; + } + if (tsk_getu32(fs->endian, ext2fs->fs->s_inodes_per_group) == 0) { + fs->tag = 0; + free(ext2fs->fs); + tsk_fs_free((TSK_FS_INFO *)ext2fs); + tsk_error_reset(); + tsk_error_set_errno(TSK_ERR_FS_MAGIC); + tsk_error_set_errstr("Not an EXTxFS file system (inodes per group)"); + if (tsk_verbose) + fprintf(stderr, "ext2fs_open: inodes per group is 0\n"); + return NULL; + } + if (tsk_getu32(fs->endian, ext2fs->fs-> s_feature_incompat) & EXT2FS_FEATURE_INCOMPAT_64BIT) { diff --git a/tsk/fs/ext2fs_journal.c b/tsk/fs/ext2fs_journal.c index 2b3b24af4fc34389ae8fbe5691a92f9d8729db04..e9238789a503e0afef8e783f4a43e96a1b48542a 100644 --- a/tsk/fs/ext2fs_journal.c +++ b/tsk/fs/ext2fs_journal.c @@ -327,7 +327,7 @@ ext2fs_jentry_walk(TSK_FS_INFO * fs, int flags, (big_tsk_getu32(head->entry_type) == EXT2_J_ETYPE_SB2)) { tsk_printf("%" PRIuDADDR ":\tSuperblock (seq: %" PRIu32 ")\n", i, big_tsk_getu32(head->entry_seq)); - journ_sb = head; + journ_sb = (ext2fs_journ_sb *)head; tsk_printf("sb version: %d\n", big_tsk_getu32(head->entry_type)); tsk_printf("sb version: %d\n", @@ -368,7 +368,7 @@ ext2fs_jentry_walk(TSK_FS_INFO * fs, int flags, || (big_tsk_getu32(head->entry_seq) < jinfo->start_seq)) ? "Unallocated " : "Allocated ", big_tsk_getu32(head->entry_seq)); - commit_head = head; + commit_head = (ext4fs_journ_commit_head *)head; //tsk_printf("commit seq %" PRIu32 "\n", big_tsk_getu32(commit_head->c_header.entry_seq)); if (big_tsk_getu32(journ_sb-> feature_compat) & JBD2_FEATURE_COMPAT_CHECKSUM) { diff --git a/tsk/fs/hfs.c b/tsk/fs/hfs.c index 3463908fbdb9aa8744c2c7271be749b26044cbbd..c875992131908cc72c535540ba8d90e0d79c1b3a 100644 --- a/tsk/fs/hfs.c +++ b/tsk/fs/hfs.c @@ -817,14 +817,17 @@ hfs_cat_compare_keys(HFS_INFO * hfs, const hfs_btree_key_cat * key1, /** \internal + * + * Traverse the HFS catalog file. Call the callback for each + * record. + * * @param hfs File system - * @param targ_data can be null * @param a_cb callback * @param ptr Pointer to pass to callback * @returns 1 on error */ uint8_t -hfs_cat_traverse(HFS_INFO * hfs, const void *targ_data, +hfs_cat_traverse(HFS_INFO * hfs, TSK_HFS_BTREE_CB a_cb, void *ptr) { TSK_FS_INFO *fs = &(hfs->fs_info); @@ -921,6 +924,7 @@ hfs_cat_traverse(HFS_INFO * hfs, const void *targ_data, size_t rec_off; hfs_btree_key_cat *key; uint8_t retval; + uint16_t keylen; // get the record offset in the node rec_off = @@ -935,8 +939,20 @@ hfs_cat_traverse(HFS_INFO * hfs, const void *targ_data, free(node); return 1; } + key = (hfs_btree_key_cat *) & node[rec_off]; + keylen = 2 + tsk_getu16(hfs->fs_info.endian, key->key_len); + if ((keylen) > nodesize) { + tsk_error_set_errno(TSK_ERR_FS_GENFS); + tsk_error_set_errstr + ("hfs_cat_traverse: length of key %d in index node %d too large (%d vs %" + PRIu16 ")", rec, cur_node, keylen, nodesize); + free(node); + return 1; + } + + /* if (tsk_verbose) tsk_fprintf(stderr, @@ -946,9 +962,10 @@ hfs_cat_traverse(HFS_INFO * hfs, const void *targ_data, tsk_getu32(fs->endian, key->parent_cnid)); */ + /* save the info from this record unless it is too big */ retval = - a_cb(hfs, HFS_BT_NODE_TYPE_IDX, targ_data, key, + a_cb(hfs, HFS_BT_NODE_TYPE_IDX, key, cur_off + rec_off, ptr); if (retval == HFS_BTREE_CB_ERR) { tsk_error_set_errno(TSK_ERR_FS_GENFS); @@ -1012,6 +1029,7 @@ hfs_cat_traverse(HFS_INFO * hfs, const void *targ_data, size_t rec_off; hfs_btree_key_cat *key; uint8_t retval; + uint16_t keylen; // get the record offset in the node rec_off = @@ -1028,6 +1046,16 @@ hfs_cat_traverse(HFS_INFO * hfs, const void *targ_data, } key = (hfs_btree_key_cat *) & node[rec_off]; + keylen = 2 + tsk_getu16(hfs->fs_info.endian, key->key_len); + if ((keylen) > nodesize) { + tsk_error_set_errno(TSK_ERR_FS_GENFS); + tsk_error_set_errstr + ("hfs_cat_traverse: length of key %d in leaf node %d too large (%d vs %" + PRIu16 ")", rec, cur_node, keylen, nodesize); + free(node); + return 1; + } + /* if (tsk_verbose) tsk_fprintf(stderr, @@ -1039,7 +1067,7 @@ hfs_cat_traverse(HFS_INFO * hfs, const void *targ_data, // rec_cnid = tsk_getu32(fs->endian, key->file_id); retval = - a_cb(hfs, HFS_BT_NODE_TYPE_LEAF, targ_data, key, + a_cb(hfs, HFS_BT_NODE_TYPE_LEAF, key, cur_off + rec_off, ptr); if (retval == HFS_BTREE_CB_LEAF_STOP) { is_done = 1; @@ -1078,13 +1106,19 @@ hfs_cat_traverse(HFS_INFO * hfs, const void *targ_data, return 0; } +typedef struct { + const hfs_btree_key_cat *targ_key; + TSK_OFF_T off; +} HFS_CAT_GET_RECORD_OFFSET_DATA; static uint8_t hfs_cat_get_record_offset_cb(HFS_INFO * hfs, int8_t level_type, - const void *targ_data, const hfs_btree_key_cat * cur_key, + const hfs_btree_key_cat * cur_key, TSK_OFF_T key_off, void *ptr) { - const hfs_btree_key_cat *targ_key = (hfs_btree_key_cat *) targ_data; + HFS_CAT_GET_RECORD_OFFSET_DATA *offset_data = (HFS_CAT_GET_RECORD_OFFSET_DATA *)ptr; + const hfs_btree_key_cat *targ_key = offset_data->targ_key; + if (tsk_verbose) tsk_fprintf(stderr, "hfs_cat_get_record_offset_cb: %s node want: %" PRIu32 @@ -1108,8 +1142,7 @@ hfs_cat_get_record_offset_cb(HFS_INFO * hfs, int8_t level_type, return HFS_BTREE_CB_LEAF_GO; } else if (diff == 0) { - TSK_OFF_T *off = (TSK_OFF_T *) ptr; - *off = + offset_data->off = key_off + 2 + tsk_getu16(hfs->fs_info.endian, cur_key->key_len); } @@ -1129,11 +1162,13 @@ hfs_cat_get_record_offset_cb(HFS_INFO * hfs, int8_t level_type, static TSK_OFF_T hfs_cat_get_record_offset(HFS_INFO * hfs, const hfs_btree_key_cat * needle) { - TSK_OFF_T off = 0; - if (hfs_cat_traverse(hfs, needle, hfs_cat_get_record_offset_cb, &off)) { + HFS_CAT_GET_RECORD_OFFSET_DATA offset_data; + offset_data.off = 0; + offset_data.targ_key = needle; + if (hfs_cat_traverse(hfs, hfs_cat_get_record_offset_cb, &offset_data)) { return 0; } - return off; + return offset_data.off; } diff --git a/tsk/fs/hfs_dent.c b/tsk/fs/hfs_dent.c index c322901c95cf1f16e8c1a9a98d68c6d09dde4651..c1a04e4eb3701f3ba3b9f83f8c7102822aa4680e 100644 --- a/tsk/fs/hfs_dent.c +++ b/tsk/fs/hfs_dent.c @@ -193,27 +193,27 @@ hfsmode2tsknametype(uint16_t a_mode) typedef struct { TSK_FS_DIR *fs_dir; TSK_FS_NAME *fs_name; + uint32_t cnid; } HFS_DIR_OPEN_META_INFO; static uint8_t hfs_dir_open_meta_cb(HFS_INFO * hfs, int8_t level_type, - const void *targ_data, const hfs_btree_key_cat * cur_key, + const hfs_btree_key_cat * cur_key, TSK_OFF_T key_off, void *ptr) { - uint32_t *cnid_p = (uint32_t *) targ_data; HFS_DIR_OPEN_META_INFO *info = (HFS_DIR_OPEN_META_INFO *) ptr; TSK_FS_INFO *fs = &hfs->fs_info; if (tsk_verbose) fprintf(stderr, "hfs_dir_open_meta_cb: want %" PRIu32 " vs got %" PRIu32 - " (%s node)\n", *cnid_p, tsk_getu32(hfs->fs_info.endian, + " (%s node)\n", info->cnid, tsk_getu32(hfs->fs_info.endian, cur_key->parent_cnid), (level_type == HFS_BT_NODE_TYPE_IDX) ? "Index" : "Leaf"); if (level_type == HFS_BT_NODE_TYPE_IDX) { if (tsk_getu32(hfs->fs_info.endian, - cur_key->parent_cnid) < *cnid_p) { + cur_key->parent_cnid) < info->cnid) { return HFS_BTREE_CB_IDX_LT; } else { @@ -226,26 +226,14 @@ hfs_dir_open_meta_cb(HFS_INFO * hfs, int8_t level_type, size_t rec_off2; if (tsk_getu32(hfs->fs_info.endian, - cur_key->parent_cnid) < *cnid_p) { + cur_key->parent_cnid) < info->cnid) { return HFS_BTREE_CB_LEAF_GO; } else if (tsk_getu32(hfs->fs_info.endian, - cur_key->parent_cnid) > *cnid_p) { + cur_key->parent_cnid) > info->cnid) { return HFS_BTREE_CB_LEAF_STOP; } rec_off2 = 2 + tsk_getu16(hfs->fs_info.endian, cur_key->key_len); - // @@@ NEED TO REPLACE THIS SOMEHOW, but need to figure out the max length - /* - if (rec_off2 > nodesize) { - tsk_error_set_errno(TSK_ERR_FS_GENFS); - tsk_error_set_errstr( - "hfs_dir_open_meta: offset of record+keylen %d in leaf node %d too large (%"PRIuSIZE" vs %" - PRIu16 ")", rec, cur_node, rec_off2, nodesize); - tsk_fs_name_free(fs_name); - free(node); - return TSK_COR; - } - */ rec_type = tsk_getu16(hfs->fs_info.endian, &rec_buf[rec_off2]); // Catalog entry is for a file @@ -488,7 +476,8 @@ hfs_dir_open_meta(TSK_FS_INFO * fs, TSK_FS_DIR ** a_fs_dir, } } - if (hfs_cat_traverse(hfs, &cnid, hfs_dir_open_meta_cb, &info)) { + info.cnid = cnid; + if (hfs_cat_traverse(hfs, hfs_dir_open_meta_cb, &info)) { tsk_fs_name_free(fs_name); return TSK_ERR; } diff --git a/tsk/fs/tsk_ext2fs.h b/tsk/fs/tsk_ext2fs.h index b9b622807f5d6b81e634f1221209bcd0836879c7..b937a8e43c0a6d9927c83a9cfc308e3b8d0df851 100644 --- a/tsk/fs/tsk_ext2fs.h +++ b/tsk/fs/tsk_ext2fs.h @@ -644,9 +644,9 @@ extern "C" { /* lock protects grp_buf, grp_num, bmap_buf, bmap_grp_num, imap_buf, imap_grp_num */ tsk_lock_t lock; - void *v_grp_buf; - ext4fs_gd *ext4_grp_buf; - ext2fs_gd *grp_buf; /* cached group descriptor r/w shared - lock */ + // one of the below will be allocated and populated by ext2fs_group_load depending on the FS type + ext4fs_gd *ext4_grp_buf; /* cached group descriptor for 64-bit ext4 r/w shared - lock */ + ext2fs_gd *grp_buf; /* cached group descriptor for ext2,ext3,32-bit ext4 r/w shared - lock */ EXT2_GRPNUM_T grp_num; /* cached group number r/w shared - lock */ diff --git a/tsk/fs/tsk_hfs.h b/tsk/fs/tsk_hfs.h index 9d64ccc789fc64c8e645880a7d65e5904cf38a4d..21dec3135a4e2ab9b0f6503f4c2d226a47efa2be 100644 --- a/tsk/fs/tsk_hfs.h +++ b/tsk/fs/tsk_hfs.h @@ -774,9 +774,16 @@ extern uint8_t hfs_cat_file_lookup(HFS_INFO * hfs, TSK_INUM_T inum, extern void error_returned(char *errstr, ...); extern void error_detected(uint32_t errnum, char *errstr, ...); +/** + * @param hfs + * @param level_type Type of node the records are from + * @param cur_key Key currently being analyzed (record data follows it) + * @param key_off Byte offset in tree that this key is located in + * @param ptr Pointer to data that was passed into parent + */ typedef uint8_t(*TSK_HFS_BTREE_CB) (HFS_INFO *, int8_t level_type, - const void *targ_key, const hfs_btree_key_cat * cur_key, - TSK_OFF_T key_off, void *); + const hfs_btree_key_cat * cur_key, + TSK_OFF_T key_off, void *ptr); // return values for callback #define HFS_BTREE_CB_IDX_LT 1 // current key is less than target (keeps looking in node) #define HFS_BTREE_CB_IDX_EQGT 2 // current key is equal or greater than target (stops) @@ -784,7 +791,7 @@ typedef uint8_t(*TSK_HFS_BTREE_CB) (HFS_INFO *, int8_t level_type, #define HFS_BTREE_CB_LEAF_STOP 4 // stop processing keys in the leaf node #define HFS_BTREE_CB_ERR 5 -extern uint8_t hfs_cat_traverse(HFS_INFO * hfs, const void *targ_data, +extern uint8_t hfs_cat_traverse(HFS_INFO * hfs, TSK_HFS_BTREE_CB a_cb, void *ptr); diff --git a/win32/BUILDING.txt b/win32/BUILDING.txt index b6c87031a985e4b9efa76378673958638ee98c5a..5f050f92c9d4e1078b7df37537eb75bd84bc9928 100755 --- a/win32/BUILDING.txt +++ b/win32/BUILDING.txt @@ -14,9 +14,15 @@ The SDK installation may fail, particularly if Visual Studio 2010 Service Pack 1 -The Visual Studio Solution file has five build targets: Debug, Debug_NoLibs, Release, Debug_PostgreSQL, and Release_PostgreSQL. Debug and Release require that libewf exists (to provide support for E01 image files) and that zlib exists (to provide support for HFS+ compressed data). Debug_NoLibs does not require libewf or zlib and you should be able to compile Debug_NoLibs without any additional setup. Debug_PostgreSQL and Release_PostgreSQL require a 64-bit version of PostgreSQL 9.4 or above installed. See the PostgreSQL section below. +There are six build targets: +- Debug_NoLibs and Release_NoLibs do not depend on any third-party libraries. +- Debug and Release depend on libewf and zlib to be built so that E01 images aresupported. +- Debug_PostgreSQL and Release_PostegreSQL depend on libewf for E01 and PostgreSQL libraries. This target is needed by Autopsy and other programs that want to write database results to a central PostgreSQL database instead of just SQLite. +------------------------------------------------------------------------ +Debug and Release Targets + The steps below outline the process required to compile the Debug and Release targets. @@ -46,35 +52,26 @@ If you want to build 64-bit libraries though, download a version that we've upgr -The steps below outline the process required to compile the Debug_PostgreSQL and Release_PostgreSQL targets. - -1) Download libewf-20130128 (or later). The official releases are from: - http://sourceforge.net/projects/libewf/ - -If you want to build 64-bit libraries though, download a version that we've upgraded: - https://github.com/sleuthkit/libewf_64bit +------------------------------------------------------------------------ +PostgreSQL Targets +The steps below outline the process required to compile the Debug_PostgreSQL and Release_PostgreSQL targets. -2) Open archive file and follow the README instructions in libewf to build libewf_dll (at the time of this writing, that includes downloading the zlib dll). Note that TSK will use only the Release version of libewf_dll. Later steps also depend on the zlib dll being built inside of libewf. Note that libewf will need to be converted to Visual Studio 2010 and be upgraded to support a 64-bit build. - - -3) Set the LIBEWF_HOME environment variable to point to the libewf folder that you created and built in step 2. - -4) If you want to build libtsk_jni for the Java JNI bindings, then set the JDK_HOME environment variable to point to the top directory of your Java SDK. +1) Follow all of the steps outlined above that are required to build the Release and Debug targets. -5) Download and install PostgreSQL 9.4 or above. The official releases are from: +2) Download and install PostgreSQL 9.4 or above. You can either download the full installer or just the ZIP file. The official releases are from: http://www.postgresql.org/download/ -6) Set the POSTGRESQL_HOME_64 environment variable to point to the PostgreSQL folder containing, but not including, the bin folder. +3) Set the POSTGRESQL_HOME_64 environment variable to point to the PostgreSQL folder containing, but not including, the bin folder. Example: POSTGRESQL_HOME_64=C:\Program Files\PostgreSQL\9.4 -7) Open the TSK Visual Studio Solution file, tsk-win.sln, in the win32 directory. +4) Open the TSK Visual Studio Solution file, tsk-win.sln, in the win32 directory. -8) Compile a Debug_PostgreSQL x64 or Release_PostgreSQL x64 version of the libraries and executables. The resulting libraries and executables will be put in win32/x64/Debug_PostgreSQL and win32/x64/Release_PostgreSQL folders as appropriate. You can change the type of build using the pulldown in Visual Studio. +5) Compile a Debug_PostgreSQL x64 or Release_PostgreSQL x64 version of the libraries and executables. The resulting libraries and executables will be put in win32/x64/Debug_PostgreSQL and win32/x64/Release_PostgreSQL folders as appropriate. You can change the type of build using the pulldown in Visual Studio. -9) Note that the libraries and executables will depend on the libewf, zlib, libpq, libintl-8, libeay32, and ssleay32 DLL files (which are copied to the TSK build directories). +6) Note that the libraries and executables will depend on the libewf, zlib, libpq, libintl-8, libeay32, and ssleay32 DLL files (which are copied to the TSK build directories). -10) If you are using JNI along with the PostgreSQL build, in NetBeans build the DataModel PostgreSQL target or in ant 'ant PostgreSQL'. +7) If you are using JNI along with the PostgreSQL build, in NetBeans build the DataModel PostgreSQL target or in ant 'ant PostgreSQL'. Refer to the API docs at http://sleuthkit.org/sleuthkit/docs/api-docs/ for details on how to use the library in an application.