📄 iso9660.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**** Wyatt Banks [wbanks@crucialsecurity.com]** Copyright (c) 2005 Crucial Security Inc. All rights reserved.**** Brian Carrier [carrier <at> sleuthkit [dot] org]** Copyright (c) 2003-2005 Brian Carrier. All rights reserved** Copyright (c) 2007-2008 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 iso9660.c * Contains the internal TSK ISO9660 file system code to handle basic file * system processing for opening file system, processing sectors, and directory entries. */#include "tsk_fs_i.h"#include "tsk_iso9660.h"#include <ctype.h>/* free all memory used by inode linked list */voidiso9660_inode_list_free(TSK_FS_INFO * fs){ ISO_INFO *iso = (ISO_INFO *) fs; iso9660_inode_node *tmp; while (iso->in_list) { tmp = iso->in_list; iso->in_list = iso->in_list->next; free(tmp); } iso->in_list = NULL;}/** * Process the System Use Sharing Protocol (SUSP) data. Typically, * rockridge data are stored in this. * * @param fs File system to process * @param buf Buffer of data to process * @param count Length of buffer in bytes. * @param hFile File handle to print details to (or NULL for no printing) * @returns NULL on error */rockridge_ext *parse_susp(TSK_FS_INFO * fs, char *buf, int count, FILE * hFile){ rockridge_ext *rr; ISO_INFO *iso = (ISO_INFO *) fs; char *end = buf + count - 1; if (tsk_verbose) tsk_fprintf(stderr, "parse_susp: count is: %d\n", count); // allocate the output data structure rr = (rockridge_ext *) tsk_malloc(sizeof(rockridge_ext)); if (rr == NULL) { return NULL; } while (buf < end) { iso9660_susp_head *head = (iso9660_susp_head *) buf; if (((uintptr_t) & (head->len) >= (uintptr_t) end) || (buf + head->len - 1 > end)) break; /* Identify the entry type -- listed in the order * that they are listed in the specs */ // SUSP Continuation Entry -- NOT SUPPORTED if ((head->sig[0] == 'C') && (head->sig[1] == 'E')) { iso9660_susp_ce *ce = (iso9660_susp_ce *) buf; if (hFile) { fprintf(hFile, "CE Entry\n"); fprintf(hFile, "* Block: %" PRIu32 "\n", tsk_getu32(fs->endian, ce->blk_m)); fprintf(hFile, "* Offset: %" PRIu32 "\n", tsk_getu32(fs->endian, ce->offset_m)); fprintf(hFile, "* Len: %" PRIu32 "\n", tsk_getu32(fs->endian, ce->celen_m)); } if ((tsk_getu32(fs->endian, ce->blk_m) < fs->last_block) && (tsk_getu32(fs->endian, ce->offset_m) < fs->block_size)) { ssize_t cnt; TSK_OFF_T off; char *buf2; off = tsk_getu32(fs->endian, ce->blk_m) * fs->block_size + tsk_getu32(fs->endian, ce->offset_m); buf2 = (char *) tsk_malloc(tsk_getu32(fs->endian, ce->celen_m)); if (buf2 != NULL) { cnt = tsk_fs_read(fs, off, buf2, tsk_getu32(fs->endian, ce->celen_m)); if (cnt == tsk_getu32(fs->endian, ce->celen_m)) { parse_susp(fs, buf2, (int) cnt, hFile); } else if (tsk_verbose) { fprintf(stderr, "parse_susp: error reading CE entry\n"); tsk_error_print(stderr); tsk_error_reset(); } free(buf2); } else { if (tsk_verbose) fprintf(stderr, "parse_susp: error allocating memory to process CE entry\n"); tsk_error_reset(); } } else { if (tsk_verbose) fprintf(stderr, "parse_susp: CE offset or block too large to process\n"); } buf += head->len; } // SUSP Padding Entry else if ((head->sig[0] == 'P') && (head->sig[1] == 'D')) { if (hFile) { fprintf(hFile, "PD Entry\n"); } buf += head->len; } // SUSP Sharing Protocol Entry -- we ignore else if ((head->sig[0] == 'S') && (head->sig[1] == 'P')) { iso9660_susp_sp *sp = (iso9660_susp_sp *) buf; if (hFile) { fprintf(hFile, "SP Entry\n"); fprintf(hFile, "* SKip Len: %d\n", sp->skip); } buf += head->len; } // SUSP System Terminator else if ((head->sig[0] == 'S') && (head->sig[1] == 'T')) { if (hFile) { fprintf(hFile, "ST Entry\n"); } buf += head->len; } // SUSP Extention Registration -- not used else if ((head->sig[0] == 'E') && (head->sig[1] == 'R')) { iso9660_susp_er *er = (iso9660_susp_er *) buf; if (hFile) { char buf[258]; fprintf(hFile, "ER Entry\n"); memcpy(buf, er->ext_id, er->len_id); buf[er->len_id] = '\0'; fprintf(hFile, "* Extension ID: %s\n", buf); memcpy(buf, er->ext_id + er->len_id, er->len_des); buf[er->len_des] = '\0'; fprintf(hFile, "* Extension Descriptor: %s\n", buf); memcpy(buf, er->ext_id + er->len_id + er->len_des, er->len_src); buf[er->len_src] = '\0'; fprintf(hFile, "* Extension Spec Source: %s\n", buf); } buf += head->len; } // SUSP Extention Sigs -- not used else if ((head->sig[0] == 'E') && (head->sig[1] == 'S')) { if (hFile) { fprintf(hFile, "ES Entry\n"); } buf += head->len; } /* * Rock Ridge Extensions */ /* POSIX file attributes */ else if ((head->sig[0] == 'P') && (head->sig[1] == 'X')) { iso9660_rr_px_entry *rr_px; rr_px = (iso9660_rr_px_entry *) buf; rr->uid = tsk_getu32(fs->endian, rr_px->uid_m); rr->gid = tsk_getu32(fs->endian, rr_px->gid_m); rr->mode = tsk_getu16(fs->endian, rr_px->mode_m); rr->nlink = tsk_getu32(fs->endian, rr_px->links_m); if (hFile) { fprintf(hFile, "PX Entry\n"); fprintf(hFile, "* UID: %" PRIuUID "\n", rr->uid); fprintf(hFile, "* GID: %" PRIuGID "\n", rr->gid); fprintf(hFile, "* Mode: %d\n", rr->mode); fprintf(hFile, "* Links: %" PRIu32 "\n", rr->nlink); } buf += head->len; } // RR - device information else if ((head->sig[0] == 'P') && (head->sig[1] == 'N')) { iso9660_rr_pn_entry *rr_pn = (iso9660_rr_pn_entry *) buf; if (hFile) { fprintf(hFile, "PN Entry\n"); fprintf(hFile, "* Device ID High: %" PRIu32 "\n", tsk_getu32(fs->endian, rr_pn->dev_h_m)); fprintf(hFile, "* Device ID Low: %" PRIu32 "\n", tsk_getu32(fs->endian, rr_pn->dev_l_m)); } buf += head->len; } // RR - symbolic link else if ((head->sig[0] == 'S') && (head->sig[1] == 'L')) { //iso9660_rr_sl_entry *rr_sl = (iso9660_rr_sl_entry *) buf; if (hFile) { fprintf(hFile, "SL Entry\n"); } buf += head->len; } // RR -- alternative name else if ((head->sig[0] == 'N') && (head->sig[1] == 'M')) { iso9660_rr_nm_entry *rr_nm; rr_nm = (iso9660_rr_nm_entry *) buf; strncpy(rr->fn, &rr_nm->name[0], (int) rr_nm->len - 5); rr->fn[(int) rr_nm->len - 5] = '\0'; if (hFile) { fprintf(hFile, "NM Entry\n"); fprintf(hFile, "* %s\n", rr->fn); } buf += head->len; } // RR - relocated directory else if ((head->sig[0] == 'C') && (head->sig[1] == 'L')) { if (hFile) { fprintf(hFile, "CL Entry\n"); } buf += head->len; } // RR - parent of relocated directory else if ((head->sig[0] == 'P') && (head->sig[1] == 'L')) { if (hFile) { fprintf(hFile, "PL Entry\n"); } buf += head->len; } // RR - relocation signal else if ((head->sig[0] == 'R') && (head->sig[1] == 'E')) { if (hFile) { fprintf(hFile, "RE Entry\n"); } buf += head->len; } // RR - time stamps else if ((head->sig[0] == 'T') && (head->sig[1] == 'F')) { if (hFile) { fprintf(hFile, "TF Entry\n"); } buf += head->len; } // RR - sparse file else if ((head->sig[0] == 'S') && (head->sig[1] == 'F')) { if (hFile) { fprintf(hFile, "SF Entry\n"); } buf += head->len; } /* RR is a system use field indicating RockRidge, but not part of RockRidge */ else if ((head->sig[0] == 'R') && (head->sig[1] == 'R')) { iso->rr_found = 1; if (hFile) { fprintf(hFile, "RR Entry\n"); } buf += head->len; } else { buf += 2; if ((uintptr_t) buf % 2) buf--; } } return rr;}/* get directory entries from current directory and add them to the inode list. * Type: ISO9660_TYPE_PVD for primary volume descriptor, ISO9660_TYPE_SVD for * supplementary volume descriptor (do Joliet utf-8 conversion). * * @param fs File system to analyze * @param a_offs Byte offset of directory start * @param count previous file count * @param ctype Character set used for the names * @param a_fn Name of the directory (in UTF-8) * * @returns total number of files or -1 on error */intiso9660_load_inodes_dir(TSK_FS_INFO * fs, TSK_OFF_T a_offs, int count, int ctype, char *a_fn){ ISO_INFO *iso = (ISO_INFO *) fs; int s_cnt = 1; // count of sectors needed for dir TSK_OFF_T s_offs = a_offs; // offset for sector reads int i; if (tsk_verbose) tsk_fprintf(stderr, "iso9660_load_inodes_dir: fs: %lu offs: %" PRIuOFF " count: %d ctype: %d fn: %s\n", (uintptr_t) fs, a_offs, count, ctype, a_fn); // cycle through each sector -- entries will not cross them for (i = 0; i < s_cnt; i++) { ssize_t cnt1; int b_offs; // offset in buffer char buf[ISO9660_SSIZE_B]; cnt1 = tsk_fs_read(fs, s_offs, buf, ISO9660_SSIZE_B); if (cnt1 != ISO9660_SSIZE_B) { if (cnt1 >= 0) { tsk_error_reset(); tsk_errno = TSK_ERR_FS_READ; } snprintf(tsk_errstr2, TSK_ERRSTR_L, "iso_get_dentries"); return -1; } // @@@@ We need to add more checks when reading from buf to make sure b_off is still in the buffer /* process the directory entries */ for (b_offs = 0; b_offs < ISO9660_SSIZE_B;) { iso9660_inode_node *in_node; iso9660_dentry *dentry; dentry = (iso9660_dentry *) & buf[b_offs]; if (dentry->entry_len == 0) { b_offs += 2; continue; } b_offs += sizeof(iso9660_dentry); // allocate a node for this entry in_node = (iso9660_inode_node *) tsk_malloc(sizeof(iso9660_inode_node)); if (in_node == NULL) { return -1; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -