📄 ntfs.c
字号:
ntfs_uncompress_reset(comp); for (a = 0; a < comp_unit_size; a++) { ssize_t cnt; if (comp_unit[a] == 0) break; /* To get the uncompressed size, we must uncompress the * data -- even if addresses are only needed */ cnt = tsk_fs_read_block(fs, comp_unit[a], &comp->comp_buf[comp->comp_len], fs->block_size); if (cnt != fs->block_size) { if (cnt >= 0) { tsk_error_reset(); tsk_errno = TSK_ERR_FS_READ; } snprintf(tsk_errstr2, TSK_ERRSTR_L, "ntfs_proc_compunit: Error reading block at %" PRIuDADDR, comp_unit[a]); return 1; } comp->comp_len += fs->block_size; } if (ntfs_uncompress_compunit(comp)) { return 1; } } /* Uncompressed data */ else { if (tsk_verbose) tsk_fprintf(stderr, "ntfs_proc_compunit: Unit is not compressed\n"); comp->uncomp_idx = 0; for (a = 0; a < comp_unit_size; a++) { ssize_t cnt; cnt = tsk_fs_read_block(fs, comp_unit[a], &comp->uncomp_buf[comp->uncomp_idx], fs->block_size); if (cnt != fs->block_size) { if (cnt >= 0) { tsk_error_reset(); tsk_errno = TSK_ERR_FS_READ; } snprintf(tsk_errstr2, TSK_ERRSTR_L, "ntfs_proc_compunit: Error reading block at %" PRIuDADDR, comp_unit[a]); return 1; } comp->uncomp_idx += fs->block_size; } } return 0;}/** * Currently ignores the SPARSE flag */uint8_tntfs_attr_walk_special(const TSK_FS_ATTR * fs_attr, int flags, TSK_FS_FILE_WALK_CB a_action, void *ptr){ TSK_FS_INFO *fs; NTFS_INFO *ntfs; // clean up any error messages that are lying around tsk_error_reset(); if ((fs_attr == NULL) || (fs_attr->fs_file == NULL) || (fs_attr->fs_file->meta == NULL) || (fs_attr->fs_file->fs_info == NULL)) { tsk_errno = TSK_ERR_FS_ARG; snprintf(tsk_errstr, TSK_ERRSTR_L, "ntfs_attr_walk_special: Null arguments given\n"); return 1; } fs = fs_attr->fs_file->fs_info; ntfs = (NTFS_INFO *) fs; /* Process the compressed buffer * * The compsize value equal to 0 can occur if we are processing an * isolated entry that is part of an attribute list. The first * sequence of the attribute has the compsize and the latter ones * do not. So, if one of the non-base MFT entries is processed by * itself, we have that case. I tried to assume it was 16, but it * caused decompression problems -- likely because this sequence * did not start on a compression unit boundary. So, now we just * dump the compressed data instead of giving an error. */ if (fs_attr->flags & TSK_FS_ATTR_COMP) { TSK_DADDR_T addr; TSK_FS_ATTR_RUN *fs_attr_run; TSK_DADDR_T *comp_unit; uint32_t comp_unit_idx = 0; NTFS_COMP_INFO comp; TSK_OFF_T off = 0; int retval; uint8_t stop_loop = 0; if (fs_attr->nrd.compsize <= 0) { tsk_errno = TSK_ERR_FS_FWALK; snprintf(tsk_errstr, TSK_ERRSTR_L, "ntfs_attrwalk_special: Compressed attribute has compsize of 0"); return 1; } /* Allocate the buffers and state structure */ if (ntfs_uncompress_setup(fs, &comp, fs_attr->nrd.compsize)) { return 1; } comp_unit = (TSK_DADDR_T *) tsk_malloc(fs_attr->nrd.compsize * sizeof(TSK_DADDR_T)); if (comp_unit == NULL) { ntfs_uncompress_done(&comp); return 1; } retval = TSK_WALK_CONT; /* cycle through the number of runs we have */ for (fs_attr_run = fs_attr->nrd.run; fs_attr_run; fs_attr_run = fs_attr_run->next) { size_t len_idx; /* We may get a FILLER entry at the beginning of the run * if we are processing a non-base file record since * this $DATA attribute could not be the first sequence in the * attribute. Therefore, do not error if it starts at 0 */ if (fs_attr_run->flags & TSK_FS_ATTR_RUN_FLAG_FILLER) { if (fs_attr_run->addr != 0) { tsk_error_reset(); if (fs_attr->fs_file->meta-> flags & TSK_FS_META_FLAG_UNALLOC) tsk_errno = TSK_ERR_FS_RECOVER; else tsk_errno = TSK_ERR_FS_GENFS; snprintf(tsk_errstr, TSK_ERRSTR_L, "Filler Entry exists in fs_attr_run %" PRIuDADDR "@%" PRIuDADDR " - type: %" PRIu32 " id: %d", fs_attr_run->len, fs_attr_run->addr, fs_attr->type, fs_attr->id); free(comp_unit); ntfs_uncompress_done(&comp); return 1; } else { off += (fs_attr_run->len * fs->block_size); continue; } } addr = fs_attr_run->addr; /* cycle through each cluster in the run */ for (len_idx = 0; len_idx < fs_attr_run->len; len_idx++) { if (addr > fs->last_block) { tsk_error_reset(); if (fs_attr->fs_file->meta-> flags & TSK_FS_META_FLAG_UNALLOC) tsk_errno = TSK_ERR_FS_RECOVER; else tsk_errno = TSK_ERR_FS_BLK_NUM; snprintf(tsk_errstr, TSK_ERRSTR_L, "Invalid address in run (too large): %" PRIuDADDR "", addr); free(comp_unit); ntfs_uncompress_done(&comp); return 1; } // queue up the addresses until we get a full unit comp_unit[comp_unit_idx++] = addr; // time to decompress (if queue is full or this is the last block) if ((comp_unit_idx == fs_attr->nrd.compsize) || ((len_idx == fs_attr_run->len - 1) && (fs_attr_run->next == NULL))) { size_t i; // decompress the unit if (ntfs_proc_compunit(ntfs, &comp, comp_unit, comp_unit_idx)) { free(comp_unit); ntfs_uncompress_done(&comp); return 1; } // now call the callback with the uncompressed data for (i = 0; i < comp_unit_idx; i++) { int myflags; size_t read_len; myflags = TSK_FS_BLOCK_FLAG_CONT | TSK_FS_BLOCK_FLAG_COMP; retval = is_clustalloc(ntfs, comp_unit[i]); if (retval == -1) { if (fs_attr->fs_file->meta-> flags & TSK_FS_META_FLAG_UNALLOC) tsk_errno = TSK_ERR_FS_RECOVER; free(comp_unit); ntfs_uncompress_done(&comp); return 1; } else if (retval == 1) { myflags |= TSK_FS_BLOCK_FLAG_ALLOC; } else if (retval == 0) { myflags |= TSK_FS_BLOCK_FLAG_UNALLOC; } if (fs_attr->size - off > fs->block_size) read_len = fs->block_size; else read_len = (size_t) (fs_attr->size - off); if (i * fs->block_size + read_len > comp.uncomp_idx) { tsk_errno = TSK_ERR_FS_FWALK; snprintf(tsk_errstr, TSK_ERRSTR_L, "ntfs_attrwalk_special: Trying to read past end of uncompressed buffer: %" PRIuSIZE " %" PRIuSIZE "", i * fs->block_size + read_len, comp.uncomp_idx); free(comp_unit); ntfs_uncompress_done(&comp); return 1; } // call the callback retval = a_action(fs_attr->fs_file, off, comp_unit[i], &comp.uncomp_buf[i * fs->block_size], read_len, myflags, ptr); off += read_len; if (off >= fs_attr->size) { stop_loop = 1; break; } if (retval != TSK_WALK_CONT) { stop_loop = 1; break; } } comp_unit_idx = 0; } if (stop_loop) break; /* If it is a sparse run, don't increment the addr so that * it remains 0 */ if (((fs_attr_run->flags & TSK_FS_ATTR_RUN_FLAG_SPARSE) == 0) && ((fs_attr_run-> flags & TSK_FS_ATTR_RUN_FLAG_FILLER) == 0)) addr++; } if (stop_loop) break; } ntfs_uncompress_done(&comp); free(comp_unit); if (retval == TSK_WALK_ERROR) return 1; else return 0; } else { tsk_errno = TSK_ERR_FS_FWALK; snprintf(tsk_errstr, TSK_ERRSTR_L, "ntfs_attrwalk_special: called with non-special attribute: %x", fs_attr->flags); return 1; }}ssize_tntfs_file_read_special(const TSK_FS_ATTR * a_fs_attr, TSK_OFF_T a_offset, char *a_buf, size_t a_len){ TSK_FS_INFO *fs; NTFS_INFO *ntfs; if ((a_fs_attr == NULL) || (a_fs_attr->fs_file == NULL) || (a_fs_attr->fs_file->meta == NULL) || (a_fs_attr->fs_file->fs_info == NULL)) { } fs = a_fs_attr->fs_file->fs_info; ntfs = (NTFS_INFO *) fs; if (a_fs_attr->flags & TSK_FS_ATTR_COMP) { TSK_FS_ATTR_RUN *data_run_cur; TSK_OFF_T cu_blkoffset; // block offset of starting compression unit to start reading from size_t byteoffset; // byte offset in compression unit of where we want to start reading from TSK_DADDR_T *comp_unit; uint32_t comp_unit_idx = 0; NTFS_COMP_INFO comp; size_t buf_idx = 0; if (a_fs_attr->nrd.compsize <= 0) { tsk_errno = TSK_ERR_FS_FWALK; snprintf(tsk_errstr, TSK_ERRSTR_L, "ntfs_file_read_special: Compressed attribute has compsize of 0"); return -1; } if (a_offset > a_fs_attr->nrd.allocsize) { return 0; } // we return 0s for reads past the initsize if (a_offset >= a_fs_attr->nrd.initsize) { ssize_t len; if (tsk_verbose) fprintf(stderr, "ntfs_file_read_special: Returning 0s for read past end of initsize (%" PRIuINUM ")\n", a_fs_attr->fs_file->meta->addr); if (a_offset + a_len > a_fs_attr->nrd.allocsize) len = (ssize_t) (a_fs_attr->nrd.allocsize - a_offset); else len = (ssize_t) a_len; memset(a_buf, 0, a_len); return len; } /* Allocate the buffers and state structure */ if (ntfs_uncompress_setup(fs, &comp, a_fs_attr->nrd.compsize)) { return -1; } comp_unit = (TSK_DADDR_T *) tsk_malloc(a_fs_attr->nrd.compsize * sizeof(TSK_DADDR_T)); if (comp_unit == NULL) { ntfs_uncompress_done(&comp); return -1; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -