File: dcat_lib.c

package info (click to toggle)
sleuthkit 4.12.1%2Bdfsg-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 18,608 kB
  • sloc: ansic: 143,795; cpp: 52,225; java: 37,892; xml: 2,416; python: 1,076; perl: 874; makefile: 439; sh: 184
file content (233 lines) | stat: -rwxr-xr-x 6,652 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
/*
** blkcat
** The  Sleuth Kit
**
** Given an image , block number, and size, display the contents
** of the block to stdout.
**
** Brian Carrier [carrier <at> sleuthkit [dot] org]
** Copyright (c) 2006-2011 Brian Carrier, Basis Technology.  All Rights reserved
** Copyright (c) 2003-2005 Brian Carrier.  All rights reserved
**
** TASK
** Copyright (c) 2002 Brian Carrier, @stake Inc.  All rights reserved
**
** TCTUTILs
** Copyright (c) 2001 Brian Carrier.  All rights reserved
**
**
** This software is distributed under the Common Public License 1.0
**
*/

#include "tsk_fs_i.h"
#include <ctype.h>

/**
 * \file dcat_lib.c
 * Contains the library API functions used by the TSK blkcat command
 * line tool.
 */


/**
 * \internal
 * Print block statistics to stdout
 *
 * @param fs File system to analyze
 */
static void
stats(TSK_FS_INFO * fs)
{
    tsk_printf("%d: Size of Addressable Unit\n", fs->block_size);
}


/**
 * Read a specific number of blocks and print the contents to STDOUT
 *
 * @param fs File system to analyze
 * @param lclflags flags
 * @param addr Starting block address to read from
 * @param read_num_units Number of blocks to read
 *
 * @return 1 on error and 0 on success
 */
uint8_t
tsk_fs_blkcat(TSK_FS_INFO * fs, TSK_FS_BLKCAT_FLAG_ENUM lclflags,
    TSK_DADDR_T addr, TSK_DADDR_T read_num_units)
{
    char *buf;
    TSK_DADDR_T i;

    if (lclflags & TSK_FS_BLKCAT_STAT) {
        stats(fs);
        return 0;
    }

    if (addr + read_num_units - 1 > fs->last_block) {
        tsk_error_reset();
        tsk_error_set_errno(TSK_ERR_FS_ARG);
        tsk_error_set_errstr
            ("tsk_fs_blkcat: requested size is larger than last block in image (%"
            PRIuDADDR ")", fs->last_block);
        return 1;
    }

#ifdef TSK_WIN32
    if (-1 == _setmode(_fileno(stdout), _O_BINARY)) {
        tsk_error_reset();
        tsk_error_set_errno(TSK_ERR_FS_WRITE);
        tsk_error_set_errstr
            ("blkcat_lib: error setting stdout to binary: %s",
            strerror(errno));
        return 1;
    }
#endif

    if (lclflags & TSK_FS_BLKCAT_HTML) {
        tsk_printf("<html>\n");
        tsk_printf("<head>\n");
        tsk_printf("<title>Unit: %" PRIuDADDR "   Size: %" PRIuDADDR
            " bytes</title>\n", addr, read_num_units * fs->block_size);
        tsk_printf("</head>\n");
        tsk_printf("<body>\n");

    }

    if ((lclflags & TSK_FS_BLKCAT_HEX) && (lclflags & TSK_FS_BLKCAT_HTML))
        tsk_printf("<table border=0>\n");

    if ((buf = tsk_malloc(fs->block_size)) == NULL)
        return 1;

    for (i = 0; i < read_num_units; i++) {
        ssize_t cnt;

        /* Read the block */
        cnt = tsk_fs_read_block(fs, addr + i, buf, fs->block_size);
        if (cnt != fs->block_size) {
            if (cnt >= 0) {
                tsk_error_reset();
                tsk_error_set_errno(TSK_ERR_FS_READ);
            }
            tsk_error_set_errstr("blkcat: Error reading block at %"
                PRIuDADDR, addr);
            return 1;
        }

        /* do a hexdump like printout */
        if (lclflags & TSK_FS_BLKCAT_HEX) {
            TSK_OFF_T idx1, idx2;

            for (idx1 = 0; idx1 < fs->block_size; idx1 += 16) {

                /* Print the offset */
                if (lclflags & TSK_FS_BLKCAT_HTML)
                    tsk_printf("<tr><td>%" PRIdOFF "</td>",
                        i * fs->block_size + idx1);
                else
                    tsk_printf("%" PRIdOFF "\t",
                        i * fs->block_size + idx1);


                /* Print the hex */
                for (idx2 = 0; idx2 < 16; idx2++) {
                    if ((lclflags & TSK_FS_BLKCAT_HTML)
                        && (0 == (idx2 % 4)))
                        tsk_printf("<td>");

                    tsk_printf("%.2x", buf[idx2 + idx1] & 0xff);

                    if (3 == (idx2 % 4)) {
                        if (lclflags & TSK_FS_BLKCAT_HTML)
                            tsk_printf("</td>");
                        else
                            tsk_printf(" ");
                    }
                }

                /* Print the ASCII */
                tsk_printf("\t");
                for (idx2 = 0; idx2 < 16; idx2++) {
                    if ((lclflags & TSK_FS_BLKCAT_HTML)
                        && (0 == (idx2 % 4)))
                        tsk_printf("<td>");

                    if ((isascii((int) buf[idx2 + idx1])) &&
                        (!iscntrl((int) buf[idx2 + idx1])))
                        tsk_printf("%c", buf[idx2 + idx1]);
                    else
                        tsk_printf(".");

                    if (3 == (idx2 % 4)) {
                        if (lclflags & TSK_FS_BLKCAT_HTML)
                            tsk_printf("</td>");
                        else
                            tsk_printf(" ");
                    }
                }

                if (lclflags & TSK_FS_BLKCAT_HTML)
                    tsk_printf("</tr>");
                tsk_printf("\n");
            }
        }

        /* print in all ASCII */
        else if (lclflags & TSK_FS_BLKCAT_ASCII) {
            TSK_OFF_T idx;
            for (idx = 0; idx < fs->block_size; idx++) {

                if ((isprint((int) buf[idx]))
                    || (buf[idx] == '\t')) {
                    tsk_printf("%c", buf[idx]);
                }
                else if ((buf[idx] == '\n')
                    || (buf[idx] == '\r')) {
                    if (lclflags & TSK_FS_BLKCAT_HTML)
                        tsk_printf("<br>");
                    tsk_printf("%c", buf[idx]);
                }
                else
                    tsk_printf(".");
            }
        }

        /* print raw */
        else {
            if (fwrite(buf, fs->block_size, 1, stdout) != 1) {
                tsk_error_reset();
                tsk_error_set_errno(TSK_ERR_FS_WRITE);
                tsk_error_set_errstr
                    ("blkcat_lib: error writing to stdout: %s",
                    strerror(errno));
                free(buf);
                return 1;
            }
        }
    }

    free(buf);

    if (lclflags & TSK_FS_BLKCAT_HEX) {
        if (lclflags & TSK_FS_BLKCAT_HTML)
            tsk_printf("</table>\n");
        else
            tsk_printf("\n");
    }
    else if (lclflags & TSK_FS_BLKCAT_ASCII) {
        if (lclflags & TSK_FS_BLKCAT_HTML)
            tsk_printf("<br>");
        tsk_printf("\n");
    }
    else {
        if (lclflags & TSK_FS_BLKCAT_HTML)
            tsk_printf("<br>");
    }

    if (lclflags & TSK_FS_BLKCAT_HTML)
        tsk_printf("</body>\n</html>\n");

    return 0;
}