1 /*
2 ** blkcalc
3 ** The Sleuth Kit
4 **
5 ** Calculates the corresponding block number between 'blkls' and 'dd' images
6 ** when given an 'blkls' block number, it determines the block number it
7 ** had in a 'dd' image. When given a 'dd' image, it determines the
8 ** value it would have in a 'blkls' image (if the block is unallocated)
9 **
10 ** Brian Carrier [carrier <at> sleuthkit [dot] org]
11 ** Copyright (c) 2006-2011 Brian Carrier, Basis Technology. All Rights reserved
12 ** Copyright (c) 2003-2005 Brian Carrier. All Rights reserved
13 **
14 ** TASK
15 ** Copyright (c) 2002 Brian Carrier, @stake Inc. All Rights reserved
16 **
17 ** TCTUTILs
18 ** Copyright (c) 2001 Brian Carrier. All rights reserved
19 **
20 **
21 ** This software is distributed under the Common Public License 1.0
22 **
23 */
24 #include "tsk/tsk_tools_i.h"
25 #include <locale.h>
26
27 static TSK_TCHAR *progname;
28
29 static void
usage()30 usage()
31 {
32 TFPRINTF(stderr,
33 _TSK_T
34 ("usage: %s [-dsu unit_addr] [-vV] [-f fstype] [-i imgtype] [-b dev_sector_size] [-o imgoffset] image [images]\n"),
35 progname);
36 tsk_fprintf(stderr, "Slowly calculates the opposite block number\n");
37 tsk_fprintf(stderr, "\tOne of the following must be given:\n");
38 tsk_fprintf(stderr,
39 "\t -d: The given address is from a 'dd' image \n");
40 tsk_fprintf(stderr,
41 "\t -s: The given address is from a 'blkls -s' (slack) image\n");
42 tsk_fprintf(stderr,
43 "\t -u: The given address is from a 'blkls' (unallocated) image\n");
44 tsk_fprintf(stderr,
45 "\t-f fstype: The file system type (use '-f list' for supported types)\n");
46 tsk_fprintf(stderr,
47 "\t-i imgtype: The format of the image file (use '-i list' for supported types)\n");
48 tsk_fprintf(stderr,
49 "\t-b dev_sector_size: The size (in bytes) of the device sectors\n");
50 tsk_fprintf(stderr,
51 "\t-o imgoffset: The offset of the file system in the image (in sectors)\n");
52 tsk_fprintf(stderr, "\t-v: verbose output to stderr\n");
53 tsk_fprintf(stderr, "\t-V: Print version\n");
54
55 exit(1);
56 }
57
58
59
60 int
main(int argc,char ** argv1)61 main(int argc, char **argv1)
62 {
63 TSK_IMG_TYPE_ENUM imgtype = TSK_IMG_TYPE_DETECT;
64 TSK_IMG_INFO *img;
65
66 TSK_OFF_T imgaddr = 0;
67 TSK_FS_TYPE_ENUM fstype = TSK_FS_TYPE_DETECT;
68 TSK_FS_INFO *fs;
69
70 int ch;
71 TSK_TCHAR *cp;
72 uint8_t type = 0;
73 int set = 0;
74
75 TSK_DADDR_T count = 0;
76 TSK_TCHAR **argv;
77 unsigned int ssize = 0;
78
79 #ifdef TSK_WIN32
80 // On Windows, get the wide arguments (mingw doesn't support wmain)
81 argv = CommandLineToArgvW(GetCommandLineW(), &argc);
82 if (argv == NULL) {
83 fprintf(stderr, "Error getting wide arguments\n");
84 exit(1);
85 }
86 #else
87 argv = (TSK_TCHAR **) argv1;
88 #endif
89
90
91 progname = argv[0];
92 setlocale(LC_ALL, "");
93
94 while ((ch = GETOPT(argc, argv, _TSK_T("b:d:f:i:o:s:u:vV"))) > 0) {
95 switch (ch) {
96 case _TSK_T('?'):
97 default:
98 TFPRINTF(stderr, _TSK_T("Invalid argument: %s\n"),
99 argv[OPTIND]);
100 usage();
101
102 case _TSK_T('b'):
103 ssize = (unsigned int) TSTRTOUL(OPTARG, &cp, 0);
104 if (*cp || *cp == *OPTARG || ssize < 1) {
105 TFPRINTF(stderr,
106 _TSK_T
107 ("invalid argument: sector size must be positive: %s\n"),
108 OPTARG);
109 usage();
110 }
111 break;
112
113 case _TSK_T('d'):
114 type |= TSK_FS_BLKCALC_DD;
115 count = TSTRTOULL(OPTARG, &cp, 0);
116 if (*cp || *cp == *OPTARG) {
117 TFPRINTF(stderr, _TSK_T("Invalid address: %s\n"), OPTARG);
118 usage();
119 }
120 set = 1;
121 break;
122
123 case _TSK_T('f'):
124 if (TSTRCMP(OPTARG, _TSK_T("list")) == 0) {
125 tsk_fs_type_print(stderr);
126 exit(1);
127 }
128 fstype = tsk_fs_type_toid(OPTARG);
129 if (fstype == TSK_FS_TYPE_UNSUPP) {
130 TFPRINTF(stderr,
131 _TSK_T("Unsupported file system type: %s\n"), OPTARG);
132 usage();
133 }
134 break;
135
136 case _TSK_T('i'):
137 if (TSTRCMP(OPTARG, _TSK_T("list")) == 0) {
138 tsk_img_type_print(stderr);
139 exit(1);
140 }
141 imgtype = tsk_img_type_toid(OPTARG);
142 if (imgtype == TSK_IMG_TYPE_UNSUPP) {
143 TFPRINTF(stderr, _TSK_T("Unsupported image type: %s\n"),
144 OPTARG);
145 usage();
146 }
147 break;
148
149 case _TSK_T('o'):
150 if ((imgaddr = tsk_parse_offset(OPTARG)) == -1) {
151 tsk_error_print(stderr);
152 exit(1);
153 }
154 break;
155
156 case _TSK_T('s'):
157 type |= TSK_FS_BLKCALC_SLACK;
158 count = TSTRTOULL(OPTARG, &cp, 0);
159 if (*cp || *cp == *OPTARG) {
160 TFPRINTF(stderr, _TSK_T("Invalid address: %s\n"), OPTARG);
161 usage();
162 }
163 set = 1;
164 break;
165
166 case _TSK_T('u'):
167 type |= TSK_FS_BLKCALC_BLKLS;
168 count = TSTRTOULL(OPTARG, &cp, 0);
169 if (*cp || *cp == *OPTARG) {
170 TFPRINTF(stderr, _TSK_T("Invalid address: %s\n"), OPTARG);
171 usage();
172 }
173 set = 1;
174 break;
175
176 case _TSK_T('v'):
177 tsk_verbose++;
178 break;
179
180 case _TSK_T('V'):
181 tsk_version_print(stdout);
182 exit(0);
183 }
184 }
185
186 /* We need at least one more argument */
187 if (OPTIND == argc) {
188 tsk_fprintf(stderr, "Missing image name\n");
189 usage();
190 }
191
192 if ((!type) || (set == 0)) {
193 tsk_fprintf(stderr, "Calculation type not given (-u, -d, -s)\n");
194 usage();
195 }
196
197 if ((type & TSK_FS_BLKCALC_DD) && (type & TSK_FS_BLKCALC_BLKLS)
198 && (type & TSK_FS_BLKCALC_SLACK)) {
199 tsk_fprintf(stderr, "Only one block type can be given\n");
200 usage();
201 }
202
203
204 if ((img =
205 tsk_img_open(argc - OPTIND, &argv[OPTIND], imgtype,
206 ssize)) == NULL) {
207 tsk_error_print(stderr);
208 exit(1);
209 }
210 if ((imgaddr * img->sector_size) >= img->size) {
211 tsk_fprintf(stderr,
212 "Sector offset supplied is larger than disk image (maximum: %"
213 PRIu64 ")\n", img->size / img->sector_size);
214 exit(1);
215 }
216
217 if ((fs = tsk_fs_open_img(img, imgaddr * img->sector_size, fstype)) == NULL) {
218 tsk_error_print(stderr);
219 if (tsk_error_get_errno() == TSK_ERR_FS_UNSUPTYPE)
220 tsk_fs_type_print(stderr);
221 img->close(img);
222 exit(1);
223 }
224
225 if (-1 == tsk_fs_blkcalc(fs, (TSK_FS_BLKCALC_FLAG_ENUM) type, count)) {
226 tsk_error_print(stderr);
227 fs->close(fs);
228 img->close(img);
229 exit(1);
230 }
231
232 fs->close(fs);
233 img->close(img);
234
235 exit(0);
236 }
237