📄 ext2fs_journal.c
字号:
/* @@@ UNALLOC only if seq is less - alloc can be less than block if it wrapped around ...** ext2fs_journal** The Sleuth Kit **** Journaling code for TSK_FS_INFO_TYPE_EXT_3 image**** Brian Carrier [carrier <at> sleuthkit [dot] org]** Copyright (c) 2006-2008 Brian Carrier, Basis Technology. All Rights reserved** Copyright (c) 2004-2005 Brian Carrier. All rights reserved ****** This software is distributed under the Common Public License 1.0***//** \file ext2fs_journal.c * Contains the internal TSK Ext3 journal walking code. */#include "tsk_fs_i.h"#include "tsk_ext2fs.h"/* Everything in the journal is in big endian */#define big_tsk_getu32(x) \ (uint32_t)((((uint8_t *)x)[3] << 0) + \ (((uint8_t *)x)[2] << 8) + \ (((uint8_t *)x)[1] << 16) + \ (((uint8_t *)x)[0] << 24) )/* * */static TSK_WALK_RET_ENUMload_sb_action(TSK_FS_FILE * fs_file, TSK_OFF_T a_off, TSK_DADDR_T addr, char *buf, size_t size, TSK_FS_BLOCK_FLAG_ENUM flags, void *ptr){ TSK_FS_INFO *fs = fs_file->fs_info; ext2fs_journ_sb *sb; EXT2FS_INFO *ext2fs = (EXT2FS_INFO *) fs; EXT2FS_JINFO *jinfo = ext2fs->jinfo; if (size < 1024) { tsk_error_reset(); tsk_errno = TSK_ERR_FS_UNSUPFUNC; snprintf(tsk_errstr, TSK_ERRSTR_L, "FS block size is less than 1024, not supported in journal yet"); return TSK_WALK_ERROR; } sb = (ext2fs_journ_sb *) buf; if (big_tsk_getu32(sb->magic) != EXT2_JMAGIC) { tsk_error_reset(); tsk_errno = TSK_ERR_FS_MAGIC; snprintf(tsk_errstr, TSK_ERRSTR_L, "Journal inode %" PRIuINUM " does not have a valid magic value: %" PRIx32, jinfo->j_inum, big_tsk_getu32(sb->magic)); return TSK_WALK_ERROR; } jinfo->bsize = big_tsk_getu32(sb->bsize); jinfo->first_block = big_tsk_getu32(sb->first_blk); jinfo->last_block = big_tsk_getu32(sb->num_blk) - 1; jinfo->start_blk = big_tsk_getu32(sb->start_blk); jinfo->start_seq = big_tsk_getu32(sb->start_seq); return TSK_WALK_STOP;}/* Place journal data in *fs * * Return 0 on success and 1 on error * */uint8_text2fs_jopen(TSK_FS_INFO * fs, TSK_INUM_T inum){ EXT2FS_INFO *ext2fs = (EXT2FS_INFO *) fs; EXT2FS_JINFO *jinfo; // clean up any error messages that are lying around tsk_error_reset(); if (!fs) { tsk_error_reset(); tsk_errno = TSK_ERR_FS_ARG; snprintf(tsk_errstr, TSK_ERRSTR_L, "ext2fs_jopen: fs is null"); return 1; } ext2fs->jinfo = jinfo = (EXT2FS_JINFO *) tsk_malloc(sizeof(EXT2FS_JINFO)); if (jinfo == NULL) { return 1; } jinfo->j_inum = inum; jinfo->fs_file = tsk_fs_file_open_meta(fs, NULL, inum); if (!jinfo->fs_file) { free(jinfo); return 1;// error("error finding journal inode %" PRIu32, inum); } if (tsk_fs_file_walk(jinfo->fs_file, 0, load_sb_action, NULL)) { tsk_error_reset(); tsk_errno = TSK_ERR_FS_FWALK; snprintf(tsk_errstr, TSK_ERRSTR_L, "Error loading ext3 journal"); tsk_fs_file_close(jinfo->fs_file); free(jinfo); return 1; } if (tsk_verbose) tsk_fprintf(stderr, "journal opened at inode %" PRIuINUM " bsize: %" PRIu32 " First JBlk: %" PRIuDADDR " Last JBlk: %" PRIuDADDR "\n", inum, jinfo->bsize, jinfo->first_block, jinfo->last_block); return 0;}/* Limitations: does not use the action or any flags * * return 0 on success and 1 on error * */uint8_text2fs_jentry_walk(TSK_FS_INFO * fs, int flags, TSK_FS_JENTRY_WALK_CB action, void *ptr){ EXT2FS_INFO *ext2fs = (EXT2FS_INFO *) fs; EXT2FS_JINFO *jinfo = ext2fs->jinfo; char *journ; TSK_FS_LOAD_FILE buf1; TSK_DADDR_T i; int b_desc_seen = 0; // clean up any error messages that are lying around tsk_error_reset(); if ((jinfo == NULL) || (jinfo->fs_file == NULL) || (jinfo->fs_file->meta == NULL)) { tsk_error_reset(); tsk_errno = TSK_ERR_FS_ARG; snprintf(tsk_errstr, TSK_ERRSTR_L, "ext2fs_jentry_walk: journal is not open"); return 1; } if (jinfo->fs_file->meta->size != (jinfo->last_block + 1) * jinfo->bsize) { tsk_error_reset(); tsk_errno = TSK_ERR_FS_ARG; snprintf(tsk_errstr, TSK_ERRSTR_L, "ext2fs_jentry_walk: journal file size is different from \nsize reported in journal super block"); return 1; } /* Load the journal into a buffer */ buf1.left = buf1.total = (size_t) jinfo->fs_file->meta->size; journ = buf1.cur = buf1.base = tsk_malloc(buf1.left); if (journ == NULL) { return 1; } if (tsk_fs_file_walk(jinfo->fs_file, 0, tsk_fs_load_file_action, (void *) &buf1)) { free(journ); return 1; } if (buf1.left > 0) { tsk_error_reset(); tsk_errno = TSK_ERR_FS_FWALK; snprintf(tsk_errstr, TSK_ERRSTR_L, "ext2fs_jentry_walk: Buffer not fully copied"); free(journ); return 1; } /* Process the journal * Cycle through each block */ tsk_printf("JBlk\tDescriptrion\n"); /* Note that 'i' is incremented when we find a descriptor block and * process its contents. */ for (i = 0; i < jinfo->last_block; i++) { ext2fs_journ_head *head; /* if there is no magic, then it is a normal block * These should be accounted for when we see its corresponding * descriptor. We get the 'unknown' when its desc has * been reused, it is in the next batch to be overwritten, * or if it has not been used before */ head = (ext2fs_journ_head *) & journ[i * jinfo->bsize]; if (big_tsk_getu32(head->magic) != EXT2_JMAGIC) { if (i < jinfo->first_block) { tsk_printf("%" PRIuDADDR ":\tUnused\n", i); }#if 0 /* For now, we ignore the case of the iitial entries before a descriptor, it is too hard ... */ else if (b_desc_seen == 0) { ext2fs_journ_head *head2 = NULL; TSK_DADDR_T a; int next_head = 0, next_seq = 0; ext2fs_journ_dentry *dentry; /* This occurs when the log cycled around * We need to find out where the descriptor is * and where we need to end */ b_desc_seen = 1; for (a = i; a < jinfo->last_block; a++) { head2 = (ext2fs_journ_head *) & journ[a * jinfo->bsize]; if ((big_tsk_getu32(head2->magic) == EXT2_JMAGIC)) { next_head = a; next_seq = big_tsk_getu32(head2->entry_seq); break; } } if (next_head == 0) { tsk_printf("%" PRIuDADDR ":\tFS Block Unknown\n", i); } /* Find the last descr in the journ */ for (a = jinfo->last_block; a > i; a--) { head2 = (ext2fs_journ_head *) & journ[a * jinfo->bsize]; if ((big_tsk_getu32(head2->magic) == EXT2_JMAGIC) && (big_tsk_getu32(head2->entry_type) == EXT2_J_ETYPE_DESC) && (next_seq == big_tsk_getu32(head2->entry_seq))) { break;// @@@@ We should abort if we reach a commit before descriptor } } /* We did not find a descriptor in the journ! * print unknown for the rest of the journ */ if (a == i) { tsk_printf("%" PRIuDADDR ":\tFS Block Unknown\n", i); continue; } dentry = (ext2fs_journ_dentry *) ((uintptr_t) head2 + sizeof(ext2fs_journ_head));; /* Cycle through the descriptor entries */ while ((uintptr_t) dentry <= ((uintptr_t) head2 + jinfo->bsize - sizeof(ext2fs_journ_head))) { /* Only start to look after the index in the desc has looped */ if (++a <= jinfo->last_block) { ext2fs_journ_head *head3; /* Look at the block that this entry refers to */ head3 = (ext2fs_journ_head *) & journ[i * jinfo->bsize]; if ((big_tsk_getu32(head3->magic) == EXT2_JMAGIC)) { i--; break; } /* If it doesn't have the magic, then it is a * journal entry and we print the FS info */ tsk_printf("%" PRIuDADDR ":\tFS Block %" PRIu32 "\n", i, big_tsk_getu32(dentry->fs_blk)); /* Our counter is over the end of the journ */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -