📄 iso9660.c
字号:
return count;}/** * Load the raw "inode" into the cached buffer (iso->dinode) * * dinode_load (for now) does not check for extended attribute records... * my issue is I dont have an iso9660 image with extended attr recs, so I * can't test/debug, etc * * @returns 1 if not found and 0 on succuss */uint8_tiso9660_dinode_load(ISO_INFO * iso, TSK_INUM_T inum){ iso9660_inode_node *n; if (tsk_verbose) tsk_fprintf(stderr, "iso9660_dinode_load: iso: %lu" " inum: %" PRIuINUM "\n", (uintptr_t) iso, inum); n = iso->in_list; while (n && (n->inum != inum)) n = n->next; if (n) { memcpy(iso->dinode, &n->inode, sizeof(iso9660_inode)); iso->dinum = inum; return 0; } else { return 1; }}static uint16_tisomode2tskmode(uint16_t a_mode){ uint16_t mode = 0; if (a_mode & ISO_EA_IRUSR) mode |= TSK_FS_META_MODE_IRUSR; if (a_mode & ISO_EA_IWUSR) mode |= TSK_FS_META_MODE_IWUSR; if (a_mode & ISO_EA_IXUSR) mode |= TSK_FS_META_MODE_IXUSR; if (a_mode & ISO_EA_IRGRP) mode |= TSK_FS_META_MODE_IRGRP; if (a_mode & ISO_EA_IWGRP) mode |= TSK_FS_META_MODE_IWGRP; if (a_mode & ISO_EA_IXGRP) mode |= TSK_FS_META_MODE_IXGRP; if (a_mode & ISO_EA_IROTH) mode |= TSK_FS_META_MODE_IROTH; if (a_mode & ISO_EA_IWOTH) mode |= TSK_FS_META_MODE_IWOTH; if (a_mode & ISO_EA_IXOTH) mode |= TSK_FS_META_MODE_IXOTH; return mode;}/** * Copies cached disk inode into generic structure. * * @returns 1 on error and 0 on success */static uint8_tiso9660_dinode_copy(ISO_INFO * iso, TSK_FS_META * fs_meta){ TSK_FS_INFO *fs = (TSK_FS_INFO *) & iso->fs_info; struct tm t; if (tsk_verbose) tsk_fprintf(stderr, "iso9660_dinode_copy: iso: %lu" " inode: %lu\n", (uintptr_t) iso, (uintptr_t) fs_meta); if (fs_meta == NULL) { tsk_errno = TSK_ERR_FS_ARG; snprintf(tsk_errstr, TSK_ERRSTR_L, "iso9660_dinode_copy: fs_file or meta is NULL"); return 1; } fs_meta->attr_state = TSK_FS_META_ATTR_EMPTY; if (fs_meta->attr) { tsk_fs_attrlist_markunused(fs_meta->attr); } if (fs_meta->content_len < ISO9660_FILE_CONTENT_LEN) { if ((fs_meta = tsk_fs_meta_realloc(fs_meta, ISO9660_FILE_CONTENT_LEN)) == NULL) { return 1; } } fs_meta->addr = iso->dinum; fs_meta->size = tsk_getu32(fs->endian, iso->dinode->dr.data_len_m); memset(&t, 0, sizeof(struct tm)); t.tm_sec = iso->dinode->dr.rec_time.sec; t.tm_min = iso->dinode->dr.rec_time.min; t.tm_hour = iso->dinode->dr.rec_time.hour; t.tm_mday = iso->dinode->dr.rec_time.day; t.tm_mon = iso->dinode->dr.rec_time.month - 1; t.tm_year = iso->dinode->dr.rec_time.year; //gmt_hrdiff = iso->dinode->dr.rec_time.gmt_off * 15 / 60; fs_meta->crtime = mktime(&t); fs_meta->mtime = fs_meta->atime = fs_meta->ctime = 0; if (iso->dinode->dr.flags & ISO9660_FLAG_DIR) fs_meta->type = TSK_FS_META_TYPE_DIR; else fs_meta->type = TSK_FS_META_TYPE_REG; if (iso->dinode->ea) { fs_meta->uid = tsk_getu32(fs->endian, iso->dinode->ea->uid); fs_meta->gid = tsk_getu32(fs->endian, iso->dinode->ea->gid); fs_meta->mode = isomode2tskmode(tsk_getu16(fs->endian, iso->dinode->ea->mode)); fs_meta->nlink = 1; } else { fs_meta->uid = 0; fs_meta->gid = 0; fs_meta->mode = 0; fs_meta->nlink = 1; } ((TSK_DADDR_T *) fs_meta->content_ptr)[0] = (TSK_DADDR_T) tsk_getu32(fs->endian, iso->dinode->dr.ext_loc_m); fs_meta->flags = TSK_FS_META_FLAG_ALLOC; return 0;}static uint8_tiso9660_inode_lookup(TSK_FS_INFO * fs, TSK_FS_FILE * a_fs_file, TSK_INUM_T inum){ ISO_INFO *iso = (ISO_INFO *) fs; if (tsk_verbose) tsk_fprintf(stderr, "iso9660_inode_lookup: iso: %lu" " inum: %" PRIuINUM "\n", (uintptr_t) iso, inum); if (a_fs_file == NULL) { tsk_errno = TSK_ERR_FS_ARG; snprintf(tsk_errstr, TSK_ERRSTR_L, "iso9660_inode_lookup: fs_file is NULL"); return 1; } // load the inode into the ISO buffer if (iso9660_dinode_load(iso, inum)) { return 1; } if (a_fs_file->meta == NULL) { if ((a_fs_file->meta = tsk_fs_meta_alloc(ISO9660_FILE_CONTENT_LEN)) == NULL) return 1; } else { tsk_fs_meta_reset(a_fs_file->meta); } // copy into the FS_META structure if (iso9660_dinode_copy(iso, a_fs_file->meta)) { return 1; } return 0;}uint8_tiso9660_inode_walk(TSK_FS_INFO * fs, TSK_INUM_T start, TSK_INUM_T last, TSK_FS_META_FLAG_ENUM flags, TSK_FS_META_WALK_CB action, void *ptr){ char *myname = "iso9660_inode_walk"; ISO_INFO *iso = (ISO_INFO *) fs; TSK_INUM_T inum; TSK_FS_FILE *fs_file; int myflags; // clean up any error messages that are lying around tsk_error_reset(); if (tsk_verbose) tsk_fprintf(stderr, "iso9660_inode_walk: iso: %lu" " start: %" PRIuINUM " last: %" PRIuINUM " flags: %d" " action: %lu ptr: %lu\n", (uintptr_t) fs, start, last, flags, (uintptr_t) action, (uintptr_t) ptr); myflags = TSK_FS_META_FLAG_ALLOC; /* * Sanity checks. */ if (start < fs->first_inum || start > fs->last_inum) { tsk_error_reset(); tsk_errno = TSK_ERR_FS_WALK_RNG; snprintf(tsk_errstr, TSK_ERRSTR_L, "%s: Start inode: %" PRIuINUM "", myname, start); return 1; } if (last < fs->first_inum || last > fs->last_inum || last < start) { tsk_error_reset(); tsk_errno = TSK_ERR_FS_WALK_RNG; snprintf(tsk_errstr, TSK_ERRSTR_L, "%s: End inode: %" PRIuINUM "", myname, last); return 1; } if (flags & TSK_FS_META_FLAG_ORPHAN) { return 0; } else if (((flags & TSK_FS_META_FLAG_ALLOC) == 0) && ((flags & TSK_FS_META_FLAG_UNALLOC) == 0)) { flags |= (TSK_FS_META_FLAG_ALLOC | TSK_FS_META_FLAG_UNALLOC); } /* If neither of the USED or UNUSED flags are set, then set them * both */ if (((flags & TSK_FS_META_FLAG_USED) == 0) && ((flags & TSK_FS_META_FLAG_UNUSED) == 0)) { flags |= (TSK_FS_META_FLAG_USED | TSK_FS_META_FLAG_UNUSED); } if ((fs_file = tsk_fs_file_alloc(fs)) == NULL) return 1; if ((fs_file->meta = tsk_fs_meta_alloc(ISO9660_FILE_CONTENT_LEN)) == NULL) return 1; /* * Iterate. */ for (inum = start; inum <= last; inum++) { int retval; if (iso9660_dinode_load(iso, inum)) { tsk_fs_file_close(fs_file); return 1; } if ((flags & myflags) != myflags) continue; if (iso9660_dinode_copy(iso, fs_file->meta)) return 1; retval = action(fs_file, ptr); if (retval == TSK_WALK_ERROR) { tsk_fs_file_close(fs_file); return 1; } else if (retval == TSK_WALK_STOP) { break; } } /* * Cleanup. */ tsk_fs_file_close(fs_file); return 0;}// @@@ Doesn' thit seem to ignore interleave?/* return 1 if block is allocated in a file's extent, return 0 otherwise */static intiso9660_is_block_alloc(TSK_FS_INFO * fs, TSK_DADDR_T blk_num){ ISO_INFO *iso = (ISO_INFO *) fs; iso9660_inode_node *in_node; if (tsk_verbose) tsk_fprintf(stderr, "iso9660_is_block_alloc: fs: %lu" " blk_num: %" PRIuDADDR "\n", (uintptr_t) fs, blk_num); for (in_node = iso->in_list; in_node; in_node = in_node->next) { TSK_DADDR_T first_block = in_node->offset / fs->block_size; TSK_DADDR_T file_size = tsk_getu32(fs->endian, in_node->inode.dr.data_len_m); TSK_DADDR_T last_block = first_block + (file_size / fs->block_size); if (file_size % fs->block_size) last_block++; if ((blk_num >= first_block) && (blk_num <= last_block)) return 1; } return 0;}TSK_FS_BLOCK_FLAG_ENUMiso9660_block_getflags(TSK_FS_INFO * a_fs, TSK_DADDR_T a_addr){ return (iso9660_is_block_alloc(a_fs, a_addr)) ? TSK_FS_BLOCK_FLAG_ALLOC : TSK_FS_BLOCK_FLAG_UNALLOC;}/* flags: TSK_FS_BLOCK_FLAG_ALLOC and FS_FLAG_UNALLOC * ISO9660 has a LOT of very sparse meta, so in this function a block is only * checked to see if it is part of an inode's extent */uint8_tiso9660_block_walk(TSK_FS_INFO * fs, TSK_DADDR_T start, TSK_DADDR_T last, TSK_FS_BLOCK_WALK_FLAG_ENUM flags, TSK_FS_BLOCK_WALK_CB action, void *ptr){ char *myname = "iso9660_block_walk"; TSK_DADDR_T addr; TSK_FS_BLOCK *fs_block; // clean up any error messages that are lying around tsk_error_reset(); if (tsk_verbose) tsk_fprintf(stderr, "iso9660_block_walk: fs: %lu" " start: %" PRIuDADDR " last: %" PRIuDADDR " flags: %d" " action: %lu ptr: %lu\n", (uintptr_t) fs, start, last, flags, (uintptr_t) action, (uintptr_t) ptr); /* * Sanity checks. */ if (start < fs->first_block || start > fs->last_block) { tsk_error_reset(); tsk_errno = TSK_ERR_FS_WALK_RNG; snprintf(tsk_errstr, TSK_ERRSTR_L, "%s: Start block: %" PRIuDADDR "", myname, start); return 1; } if (last < fs->first_block || last > fs->last_block) { tsk_error_reset(); tsk_errno = TSK_ERR_FS_WALK_RNG; snprintf(tsk_errstr, TSK_ERRSTR_L, "%s: End block: %" PRIuDADDR "", myname, last); return 1; } /* Sanity check on flags -- make sure at least one ALLOC is set */ if (((flags & TSK_FS_BLOCK_WALK_FLAG_ALLOC) == 0) && ((flags & TSK_FS_BLOCK_WALK_FLAG_UNALLOC) == 0)) { flags |= (TSK_FS_BLOCK_WALK_FLAG_ALLOC | TSK_FS_BLOCK_WALK_FLAG_UNALLOC); } if (((flags & TSK_FS_BLOCK_WALK_FLAG_META) == 0) && ((flags & TSK_FS_BLOCK_WALK_FLAG_CONT) == 0)) { flags |= (TSK_FS_BLOCK_WALK_FLAG_CONT | TSK_FS_BLOCK_WALK_FLAG_META); } if ((fs_block = tsk_fs_block_alloc(fs)) == NULL) { return 1; } if (tsk_verbose) tsk_fprintf(stderr, "isofs_block_walk: Block Walking %" PRIuDADDR " to %" PRIuDADDR "\n", start, last); /* cycle through block addresses */ for (addr = start; addr <= last; addr++) { int retval; int myflags = iso9660_block_getflags(fs, addr); // test if we should call the callback with this one if ((myflags & TSK_FS_BLOCK_FLAG_ALLOC) && (!(flags & TSK_FS_BLOCK_WALK_FLAG_ALLOC))) continue; else if ((myflags & TSK_FS_BLOCK_FLAG_UNALLOC) && (!(flags & TSK_FS_BLOCK_WALK_FLAG_UNALLOC))) continue; if (tsk_fs_block_get(fs, fs_block, addr) == NULL) { snprintf(tsk_errstr2, TSK_ERRSTR_L, "iso_block_walk"); tsk_fs_block_free(fs_block); return 1; } retval = action(fs_block, ptr); if (retval == TSK_WALK_ERROR) { tsk_fs_block_free(fs_block); return 1; } else if (retval == TSK_WALK_STOP) { break; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -