📄 hfs_dent.c
字号:
/*** The Sleuth Kit**** This software is subject to the IBM Public License ver. 1.0,** which was displayed prior to download and is included in the readme.txt** file accompanying the Sleuth Kit files. It may also be requested from:** Crucial Security Inc.** 14900 Conference Center Drive** Chantilly, VA 20151**** Judson Powers [jpowers@atc-nycorp.com]** Copyright (c) 2008 ATC-NY. All rights reserved.** This file contains data developed with support from the National** Institute of Justice, Office of Justice Programs, U.S. Department of Justice.** ** Wyatt Banks [wbanks@crucialsecurity.com]** Copyright (c) 2005 Crucial Security Inc. All rights reserved.**** Brian Carrier [carrier@sleuthkit.org]** Copyright (c) 2003-2005 Brian Carrier. All rights reserved**** Copyright (c) 1997,1998,1999, International Business Machines** Corporation and others. All Rights Reserved.*//* TCT * LICENSE * This software is distributed under the IBM Public License. * AUTHOR(S) * Wietse Venema * IBM T.J. Watson Research * P.O. Box 704 * Yorktown Heights, NY 10598, USA --*//*** You may distribute the Sleuth Kit, or other software that incorporates** part of all of the Sleuth Kit, in object code form under a license agreement,** provided that:** a) you comply with the terms and conditions of the IBM Public License** ver 1.0; and** b) the license agreement** i) effectively disclaims on behalf of all Contributors all warranties** and conditions, express and implied, including warranties or** conditions of title and non-infringement, and implied warranties** or conditions of merchantability and fitness for a particular** purpose.** ii) effectively excludes on behalf of all Contributors liability for** damages, including direct, indirect, special, incidental and** consequential damages such as lost profits.** iii) states that any provisions which differ from IBM Public License** ver. 1.0 are offered by that Contributor alone and not by any** other party; and** iv) states that the source code for the program is available from you,** and informs licensees how to obtain it in a reasonable manner on or** through a medium customarily used for software exchange.**** When the Sleuth Kit or other software that incorporates part or all of** the Sleuth Kit is made available in source code form:** a) it must be made available under IBM Public License ver. 1.0; and** b) a copy of the IBM Public License ver. 1.0 must be included with** each copy of the program.*//** \file hfs_dent.c * Contains the file name layer code for HFS+ file systems -- not included in * code by default. */#include "tsk_fs_i.h"#include "tsk_hfs.h"#define UTF16_NULL 0x0000#define UTF16_NULL_REPLACE 0xfffd#define UTF16_SLASH 0x002f#define UTF16_COLON 0x001a/* convert HFS+'s UTF16 to UTF8 * replaces null characters with another character (0xfffd) * replaces slashes (permitted by HFS+ but causes problems with TSK) * with colons (generally not allowed by Mac OS X) * note that at least one directory on HFS+ volumes begins with * four nulls, so we do need to handle nulls; also, Apple chooses * to encode nulls as UTF8 \xC0\x80, which is not a valid UTF8 sequence * returns 0 on success, 1 on failure; sets up to error string 1 */uint8_thfs_uni2ascii(TSK_FS_INFO * fs, uint8_t * uni, int ulen, char *asc, int alen){ char *aptr; uint8_t *uniclean; uint8_t *uptr; int i; TSKConversionResult r; // remove nulls from the Unicode string // convert / to : uniclean = (uint8_t *) tsk_malloc(ulen * 2); memcpy(uniclean, uni, ulen * 2); for (i = 0; i < ulen; ++i) { uint16_t uc = tsk_getu16(fs->endian, uniclean + i * 2); int changed = 0; if (uc == UTF16_NULL) { uc = UTF16_NULL_REPLACE; changed = 1; } else if (uc == UTF16_SLASH) { uc = UTF16_COLON; changed = 1; } if (changed) *((uint16_t *) (uniclean + i * 2)) = tsk_getu16(fs->endian, (uint8_t *) & uc); } memset(asc, 0, alen); aptr = asc; uptr = uniclean; r = tsk_UTF16toUTF8(fs->endian, (const UTF16 **) &uptr, (const UTF16 *) (uptr + ulen * 2), (UTF8 **) & aptr, (UTF8 *) aptr + alen - 1, TSKstrictConversion); if (r != TSKconversionOK) { tsk_errno = TSK_ERR_FS_UNICODE; snprintf(tsk_errstr, TSK_ERRSTR_L, "hfs_uni2ascii: unicode conversion failed (%" PRIu8 ")", r); free(uniclean); return 1; } free(uniclean); return 0;}static TSK_FS_NAME_TYPE_ENUMhfsmode2tsknametype(uint16_t a_mode){ switch (a_mode & HFS_IN_IFMT) { case HFS_IN_IFIFO: return TSK_FS_NAME_TYPE_FIFO; case HFS_IN_IFCHR: return TSK_FS_NAME_TYPE_CHR; case HFS_IN_IFDIR: return TSK_FS_NAME_TYPE_DIR; case HFS_IN_IFBLK: return TSK_FS_NAME_TYPE_BLK; case HFS_IN_IFREG: return TSK_FS_NAME_TYPE_REG; case HFS_IN_IFLNK: return TSK_FS_NAME_TYPE_LNK; case HFS_IN_IFSOCK: return TSK_FS_NAME_TYPE_SOCK; case HFS_IFWHT: return TSK_FS_NAME_TYPE_WHT; case HFS_IFXATTR: return TSK_FS_NAME_TYPE_UNDEF; default: /* error */ return TSK_FS_NAME_TYPE_UNDEF; }}/** \internal * Process a directory and load up FS_DIR with the entries. If a pointer to * an already allocated FS_DIR struture is given, it will be cleared. If no existing * FS_DIR structure is passed (i.e. NULL), then a new one will be created. If the return * value is error or corruption, then the FS_DIR structure could * have entries (depending on when the error occured). * * @param a_fs File system to analyze * @param a_fs_dir Pointer to FS_DIR pointer. Can contain an already allocated * structure or a new structure. * @param a_addr Address of directory to process. * @returns error, corruption, ok etc. */TSK_RETVAL_ENUMhfs_dir_open_meta(TSK_FS_INFO * fs, TSK_FS_DIR ** a_fs_dir, TSK_INUM_T a_addr){ HFS_INFO *hfs = (HFS_INFO *) fs; hfs_cat_key needle; /* current catalog key */ uint32_t cnid; /* catalog node ID of the entry (= inum) */ hfs_thread thread; /* thread record */ hfs_btree_header_record header; /* header for the Catalog btree */ uint16_t leafsize; /* size of nodes (all, regardless of the name) */ uint32_t cur_node; /* node id of the current node */ TSK_OFF_T cur_off; /* start offset of cur_node */ hfs_btree_node node; /* data of the current node */ uint16_t num_rec; /* number of records in this node */ hfs_cat_key key; /* current key */ HFS_ENTRY entry; TSK_OFF_T off; char buf[4]; TSK_FS_DIR *fs_dir; TSK_FS_NAME *fs_name; uint32_t *temp_32ptr; tsk_error_reset(); cnid = (uint32_t) a_addr; if (tsk_verbose) fprintf(stderr, "hfs_dir_open_meta: called for directory %" PRIu32 "\n", cnid); if (a_addr < fs->first_inum || a_addr > fs->last_inum) { tsk_error_reset(); tsk_errno = TSK_ERR_FS_WALK_RNG; snprintf(tsk_errstr, TSK_ERRSTR_L, "hfs_dir_open_meta: Invalid inode value: %" PRIuINUM, a_addr); return TSK_ERR; } else if (a_fs_dir == NULL) { tsk_error_reset(); tsk_errno = TSK_ERR_FS_ARG; snprintf(tsk_errstr, TSK_ERRSTR_L, "hfs_dir_open_meta: NULL fs_data argument given"); return TSK_ERR; } if (tsk_verbose) tsk_fprintf(stderr, "hfs_dir_open_meta: Processing directory %" PRIuINUM "\n", a_addr); fs_dir = *a_fs_dir; if (fs_dir) { tsk_fs_dir_reset(fs_dir); } else { if ((*a_fs_dir = fs_dir = tsk_fs_dir_alloc(fs, 128)) == NULL) { return TSK_ERR; } } fs_name = tsk_fs_name_alloc(HFS_MAXNAMLEN, 0); if ((fs_dir->fs_file = tsk_fs_file_open_meta(fs, NULL, a_addr)) == NULL) { strncat(tsk_errstr2, " - hfs_dir_open_meta", TSK_ERRSTR_L - strlen(tsk_errstr2)); tsk_fs_dir_close(fs_dir); return TSK_ERR; } /* set up the thread record key */ memset((char *) &needle, 0, sizeof(hfs_cat_key)); temp_32ptr = (uint32_t *) (needle.parent_cnid); *temp_32ptr = tsk_getu32(fs->endian, (char *) &cnid); // @@@@ I'm not sure that this works... /*** navigate to thread record ***/ /* read catalog header record */ off = hfs_cat_find_node_offset(hfs, 0); if (off == 0) { snprintf(tsk_errstr2, TSK_ERRSTR_L, "hfs_dir_open_meta: find catalog header node"); return 1; } off += 14; if (hfs_checked_read_random(fs, (char *) &header, sizeof(header), off)) { snprintf(tsk_errstr2, TSK_ERRSTR_L, "hfs_dir_open_meta: read catalog header node at %" PRIuDADDR, off); return 1; } leafsize = tsk_getu16(fs->endian, header.nodesize); /* start at root node */ cur_node = tsk_getu32(fs->endian, header.root);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -