1 /* 2 * The Sleuth Kit 3 * 4 * Brian Carrier [carrier <at> sleuthkit [dot] org] 5 * Copyright (c) 2007-2011 Brian Carrier. All Rights reserved 6 * 7 * This software is distributed under the Common Public License 1.0 8 */ 9 10 /** \file tsk_base.h 11 * Contains the type and function definitions that are needed 12 * by external programs to use the TSK library. 13 * Note that this file is not meant to be directly included. 14 * It is included by both libtsk.h and tsk_base_i.h. 15 */ 16 17 18 /** 19 * \defgroup baselib C Base TSK Library Functions 20 * \defgroup baselib_cpp C++ Base TSK Library Classes 21 */ 22 23 #ifndef _TSK_BASE_H 24 #define _TSK_BASE_H 25 26 // standard C header files 27 #include <stdio.h> 28 #include <stdlib.h> 29 #include <stdarg.h> 30 31 /** Version of code in number form. 32 * Upper byte is A, next is B, and next byte is C in version A.B.C. 33 * Lowest byte is 0xff, except in beta releases, in which case it 34 * increments from 1. Nightly snapshots will have upper byte as 35 * 0xff and next bytes with year, month, and date, respectively. 36 * Note that you will not be able to differentiate between snapshots 37 * from the trunk or branches with this method... 38 * For example, 3.1.2 would be stored as 0x030102FF. 39 * 3.1.2b1 would be 0x03010201. Snapshot from Jan 2, 2003 would be 40 * 0xFF030102. 41 * See TSK_VERSION_STR for string form. */ 42 #define TSK_VERSION_NUM 0x040700ff 43 44 /** Version of code in string form. See TSK_VERSION_NUM for 45 * integer form. */ 46 #define TSK_VERSION_STR "4.7.0" 47 48 49 /* include the TSK-specific header file that we created in autoconf 50 * On Win32 (Visual Studio) though, we will not have this file... 51 */ 52 #if !defined(_MSC_VER) 53 #include "tsk/tsk_incs.h" 54 #endif 55 56 // get some other TSK / OS settings 57 #include "tsk_os.h" 58 59 #ifdef __cplusplus 60 extern "C" { 61 #endif 62 63 #define TSK_ERROR_STRING_MAX_LENGTH 1024 64 65 typedef struct { 66 uint32_t t_errno; 67 char errstr[TSK_ERROR_STRING_MAX_LENGTH + 1]; 68 char errstr2[TSK_ERROR_STRING_MAX_LENGTH + 1]; 69 char errstr_print[TSK_ERROR_STRING_MAX_LENGTH + 1]; 70 } TSK_ERROR_INFO; 71 72 /* The core function here is to retrieve the per-thread error structure. Other functions to follow 73 * are for convenience of performing common operations. */ 74 extern TSK_ERROR_INFO *tsk_error_get_info(); 75 76 extern uint32_t tsk_error_get_errno(); 77 extern void tsk_error_set_errno(uint32_t t_errno); 78 79 #ifdef __GNUC__ 80 #define TSK_ERROR_FORMAT_ATTRIBUTE(n,m) __attribute__((format (printf, n, m))) 81 #else 82 #define TSK_ERROR_FORMAT_ATTRIBUTE(n,m) 83 #endif 84 85 extern char *tsk_error_get_errstr(); 86 extern void tsk_error_set_errstr(const char *format, 87 ...) TSK_ERROR_FORMAT_ATTRIBUTE(1, 2); 88 extern void tsk_error_vset_errstr(const char *format, va_list args); 89 extern char *tsk_error_get_errstr2(); 90 extern void tsk_error_set_errstr2(const char *format, 91 ...) TSK_ERROR_FORMAT_ATTRIBUTE(1, 2); 92 extern void tsk_error_vset_errstr2(const char *format, va_list args); 93 extern void tsk_error_errstr2_concat(const char *format, 94 ...) TSK_ERROR_FORMAT_ATTRIBUTE(1, 2); 95 96 /** Return a human-readable form of tsk_error_get_errno **/ 97 extern const char *tsk_error_get(); 98 99 extern void tsk_error_print(FILE *); 100 extern void tsk_error_reset(); 101 102 103 #ifdef TSK_MULTITHREAD_LIB 104 #ifdef TSK_WIN32 105 void *tsk_error_win32_get_per_thread_(unsigned struct_size); 106 typedef struct { 107 CRITICAL_SECTION critical_section; 108 } tsk_lock_t; 109 110 // non-windows 111 #else 112 /* Note that there is an assumption that TSK_MULTITHREADED_LIB was 113 * set only if we have pthreads. If we add a check for HAVE_PTHREAD 114 * here, it causes problems when you try to include the library in 115 * a tool because they do not have tsk_config.h included. 116 */ 117 #include <pthread.h> 118 typedef struct { 119 pthread_mutex_t mutex; 120 } tsk_lock_t; 121 122 #endif 123 124 // single threaded lib 125 #else 126 typedef struct { 127 void *dummy; 128 } tsk_lock_t; 129 #endif 130 131 /** 132 * Return values for some TSK functions that need to differentiate between errors and corrupt data. 133 */ 134 typedef enum { 135 TSK_OK, ///< Ok -- success 136 TSK_ERR, ///< System error -- should abort 137 TSK_COR, ///< Data is corrupt, can still process another set of data 138 TSK_STOP ///< Stop further processing, not an error though. 139 } TSK_RETVAL_ENUM; 140 141 142 typedef struct TSK_LIST TSK_LIST; 143 /** 144 * Linked list structure that holds a 'key' and optional 'length'. 145 * Note that the data is stored in reverse sort order so that inserts 146 * are faster. Also note that the length is a negative number. A key of 147 * '6' and a len of '2' means that the run contains 6 and 5. 148 */ 149 struct TSK_LIST { 150 TSK_LIST *next; ///< Pointer to next entry in list 151 uint64_t key; ///< Largest value in this run 152 uint64_t len; ///< Length of run (negative number, stored as positive) 153 }; 154 extern uint8_t tsk_list_find(TSK_LIST * list, uint64_t key); 155 extern uint8_t tsk_list_add(TSK_LIST ** list, uint64_t key); 156 extern void tsk_list_free(TSK_LIST * list); 157 158 159 // note that the stack code is in this file and not internal for convenience to users 160 /** 161 * Basic stack structure to push and pop (used for finding loops in recursion). 162 */ 163 typedef struct { 164 uint64_t *vals; ///< Array that contains the values in the stack 165 size_t top; ///< Index to the top stack entry 166 size_t len; ///< Number of entries in the stack 167 } TSK_STACK; 168 169 extern uint8_t tsk_stack_push(TSK_STACK * stack, uint64_t key); 170 extern void tsk_stack_pop(TSK_STACK * stack); 171 extern uint8_t tsk_stack_find(TSK_STACK * stack, uint64_t key); 172 extern void tsk_stack_free(TSK_STACK * stack); 173 extern TSK_STACK *tsk_stack_create(); 174 175 176 // print internal UTF-8 strings to local platform Unicode format 177 extern void tsk_fprintf(FILE * fd, const char *msg, ...); 178 extern void tsk_printf(const char *msg, ...); 179 180 // print path removing special characters 181 extern int tsk_print_sanitized(FILE * fd, const char *str); 182 183 184 /** \name printf macros if system does not define them */ 185 //@{ 186 #ifndef PRIx64 187 #define PRIx64 "llx" 188 #endif 189 190 #ifndef PRIX64 191 #define PRIX64 "llX" 192 #endif 193 194 #ifndef PRIu64 195 #define PRIu64 "llu" 196 #endif 197 198 #ifndef PRId64 199 #define PRId64 "lld" 200 #endif 201 202 #ifndef PRIo64 203 #define PRIo64 "llo" 204 #endif 205 206 #ifndef PRIx32 207 #define PRIx32 "x" 208 #endif 209 210 #ifndef PRIX32 211 #define PRIX32 "X" 212 #endif 213 214 #ifndef PRIu32 215 #define PRIu32 "u" 216 #endif 217 218 #ifndef PRId32 219 #define PRId32 "d" 220 #endif 221 222 #ifndef PRIx16 223 #define PRIx16 "hx" 224 #endif 225 226 #ifndef PRIX16 227 #define PRIX16 "hX" 228 #endif 229 230 #ifndef PRIu16 231 #define PRIu16 "hu" 232 #endif 233 234 #ifndef PRIu8 235 #define PRIu8 "hhu" 236 #endif 237 238 #ifndef PRIx8 239 #define PRIx8 "hhx" 240 #endif 241 //@} 242 243 244 245 /** @name Internal integer types and printf macros*/ 246 //@{ 247 typedef uint64_t TSK_INUM_T; ///< Data type used to internally store metadata / inode addresses 248 #define PRIuINUM PRIu64 249 #define PRIxINUM PRIx64 250 251 typedef uint32_t TSK_UID_T; ///< Data type used to internally store User IDs 252 #define PRIuUID PRIu32 253 #define PRIxUID PRIx32 254 255 typedef uint32_t TSK_GID_T; ///< Data type used to internally store Group IDs 256 #define PRIuGID PRIu32 257 #define PRIxGID PRIx32 258 259 typedef uint64_t TSK_DADDR_T; ///< Data type used to internally store sector and block addresses 260 #define PRIuDADDR PRIu64 261 #define PRIxDADDR PRIx64 262 263 typedef int64_t TSK_OFF_T; ///< Data type used to internally store volume, file, etc. sizes and offsets 264 #define PRIxOFF PRIx64 265 #define PRIdOFF PRId64 266 267 typedef uint32_t TSK_PNUM_T; ///< Data type used to internally store partition addresses 268 #define PRIuPNUM PRIu32 269 #define PRIxPNUM PRIx32 270 //@} 271 272 273 extern void tsk_version_print(FILE *); 274 extern const char *tsk_version_get_str(); 275 276 277 /*********** RETURN VALUES ************/ 278 279 /** 280 * Values that callback functions can return to calling walk function. 281 */ 282 typedef enum { 283 TSK_WALK_CONT = 0x0, ///< Walk function should continue to next object 284 TSK_WALK_STOP = 0x1, ///< Walk function should stop processing units and return OK 285 TSK_WALK_ERROR = 0x2 ///< Walk function should stop processing units and return error 286 } TSK_WALK_RET_ENUM; 287 288 289 /************ ERROR HANDLING *************/ 290 //TODO: make this per-thread? 291 extern int tsk_verbose; ///< Set to 1 to have verbose debug messages printed to stderr 292 293 294 #define TSK_ERR_AUX 0x01000000 295 #define TSK_ERR_IMG 0x02000000 296 #define TSK_ERR_VS 0x04000000 297 #define TSK_ERR_FS 0x08000000 298 #define TSK_ERR_HDB 0x10000000 299 #define TSK_ERR_AUTO 0x20000000 300 #define TSK_ERR_MASK 0x00ffffff 301 302 #define TSK_ERR_AUX_MALLOC (TSK_ERR_AUX | 0) 303 #define TSK_ERR_AUX_GENERIC (TSK_ERR_AUX | 2) 304 #define TSK_ERR_AUX_MAX 2 305 306 #define TSK_ERR_IMG_NOFILE (TSK_ERR_IMG | 0) 307 #define TSK_ERR_IMG_OFFSET (TSK_ERR_IMG | 1) 308 #define TSK_ERR_IMG_UNKTYPE (TSK_ERR_IMG | 2) 309 #define TSK_ERR_IMG_UNSUPTYPE (TSK_ERR_IMG | 3) 310 #define TSK_ERR_IMG_OPEN (TSK_ERR_IMG | 4) 311 #define TSK_ERR_IMG_STAT (TSK_ERR_IMG | 5) 312 #define TSK_ERR_IMG_SEEK (TSK_ERR_IMG | 6) 313 #define TSK_ERR_IMG_READ (TSK_ERR_IMG | 7) 314 #define TSK_ERR_IMG_READ_OFF (TSK_ERR_IMG | 8) 315 #define TSK_ERR_IMG_ARG (TSK_ERR_IMG | 9) 316 #define TSK_ERR_IMG_MAGIC (TSK_ERR_IMG | 10) 317 #define TSK_ERR_IMG_WRITE (TSK_ERR_IMG | 11) 318 #define TSK_ERR_IMG_CONVERT (TSK_ERR_IMG | 12) 319 #define TSK_ERR_IMG_PASSWD (TSK_ERR_IMG | 13) 320 #define TSK_ERR_IMG_MAX 14 321 322 #define TSK_ERR_VS_UNKTYPE (TSK_ERR_VS | 0) 323 #define TSK_ERR_VS_UNSUPTYPE (TSK_ERR_VS | 1) 324 #define TSK_ERR_VS_READ (TSK_ERR_VS | 2) 325 #define TSK_ERR_VS_MAGIC (TSK_ERR_VS | 3) 326 #define TSK_ERR_VS_WALK_RNG (TSK_ERR_VS | 4) 327 #define TSK_ERR_VS_BUF (TSK_ERR_VS | 5) 328 #define TSK_ERR_VS_BLK_NUM (TSK_ERR_VS | 6) 329 #define TSK_ERR_VS_ARG (TSK_ERR_VS | 7) 330 #define TSK_ERR_VS_MAX 8 331 332 #define TSK_ERR_FS_UNKTYPE (TSK_ERR_FS | 0) 333 #define TSK_ERR_FS_UNSUPTYPE (TSK_ERR_FS | 1) 334 #define TSK_ERR_FS_UNSUPFUNC (TSK_ERR_FS | 2) 335 #define TSK_ERR_FS_WALK_RNG (TSK_ERR_FS | 3) 336 #define TSK_ERR_FS_READ (TSK_ERR_FS | 4) 337 #define TSK_ERR_FS_READ_OFF (TSK_ERR_FS | 5) 338 #define TSK_ERR_FS_ARG (TSK_ERR_FS | 6) 339 #define TSK_ERR_FS_BLK_NUM (TSK_ERR_FS | 7) 340 #define TSK_ERR_FS_INODE_NUM (TSK_ERR_FS | 8) 341 #define TSK_ERR_FS_INODE_COR (TSK_ERR_FS | 9) 342 #define TSK_ERR_FS_MAGIC (TSK_ERR_FS | 10) 343 #define TSK_ERR_FS_FWALK (TSK_ERR_FS | 11) 344 #define TSK_ERR_FS_WRITE (TSK_ERR_FS | 12) 345 #define TSK_ERR_FS_UNICODE (TSK_ERR_FS | 13) 346 #define TSK_ERR_FS_RECOVER (TSK_ERR_FS | 14) 347 #define TSK_ERR_FS_GENFS (TSK_ERR_FS | 15) 348 #define TSK_ERR_FS_CORRUPT (TSK_ERR_FS | 16) 349 #define TSK_ERR_FS_ATTR_NOTFOUND (TSK_ERR_FS | 17) 350 #define TSK_ERR_FS_MAX 18 351 352 353 #define TSK_ERR_HDB_UNKTYPE (TSK_ERR_HDB | 0) 354 #define TSK_ERR_HDB_UNSUPTYPE (TSK_ERR_HDB | 1) 355 #define TSK_ERR_HDB_READDB (TSK_ERR_HDB | 2) 356 #define TSK_ERR_HDB_READIDX (TSK_ERR_HDB | 3) 357 #define TSK_ERR_HDB_ARG (TSK_ERR_HDB | 4) 358 #define TSK_ERR_HDB_WRITE (TSK_ERR_HDB | 5) 359 #define TSK_ERR_HDB_CREATE (TSK_ERR_HDB | 6) 360 #define TSK_ERR_HDB_DELETE (TSK_ERR_HDB | 7) 361 #define TSK_ERR_HDB_MISSING (TSK_ERR_HDB | 8) 362 #define TSK_ERR_HDB_PROC (TSK_ERR_HDB | 9) 363 #define TSK_ERR_HDB_OPEN (TSK_ERR_HDB | 10) 364 #define TSK_ERR_HDB_CORRUPT (TSK_ERR_HDB | 11) 365 #define TSK_ERR_HDB_UNSUPFUNC (TSK_ERR_HDB | 11) 366 #define TSK_ERR_HDB_MAX 13 367 368 #define TSK_ERR_AUTO_DB (TSK_ERR_AUTO | 0) 369 #define TSK_ERR_AUTO_CORRUPT (TSK_ERR_AUTO | 1) 370 #define TSK_ERR_AUTO_UNICODE (TSK_ERR_AUTO | 2) 371 #define TSK_ERR_AUTO_NOTOPEN (TSK_ERR_AUTO | 3) 372 #define TSK_ERR_AUTO_MAX 4 373 //@} 374 375 376 /** \name Endian Ordering Functions */ 377 //@{ 378 /** 379 * Flag that identifies the endian ordering of the data being read. 380 */ 381 typedef enum { 382 TSK_UNKNOWN_ENDIAN = 0x00, ///< Endianness is unknown 383 TSK_LIT_ENDIAN = 0x01, ///< Data is in little endian 384 TSK_BIG_ENDIAN = 0x02 ///< Data is in big endian 385 } TSK_ENDIAN_ENUM; 386 387 //@} 388 389 390 391 extern TSK_OFF_T tsk_parse_offset(const TSK_TCHAR *); 392 extern int tsk_parse_pnum(const TSK_TCHAR * a_pnum_str, 393 TSK_PNUM_T * a_pnum); 394 395 396 397 /** \name MD5 and SHA-1 hashing */ 398 //@{ 399 400 /* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All 401 rights reserved. 402 403 License to copy and use this software is granted provided that it 404 is identified as the "RSA Data Security, Inc. MD5 Message-Digest 405 Algorithm" in all material mentioning or referencing this software 406 or this function. 407 408 License is also granted to make and use derivative works provided 409 that such works are identified as "derived from the RSA Data 410 Security, Inc. MD5 Message-Digest Algorithm" in all material 411 mentioning or referencing the derived work. 412 413 RSA Data Security, Inc. makes no representations concerning either 414 the merchantability of this software or the suitability of this 415 software for any particular purpose. It is provided "as is" 416 without express or implied warranty of any kind. 417 418 These notices must be retained in any copies of any part of this 419 documentation and/or software. 420 */ 421 422 423 /* POINTER defines a generic pointer type */ 424 typedef unsigned char *POINTER; 425 426 /* UINT2 defines a two byte word */ 427 //typedef unsigned short int UINT2; 428 typedef uint16_t UINT2; 429 430 /* UINT4 defines a four byte word */ 431 typedef uint32_t UINT4; 432 433 /* Added for sha1 */ 434 /* BYTE defines a unsigned character */ 435 typedef uint8_t BYTE; 436 437 #ifndef TRUE 438 #define FALSE 0 439 #define TRUE ( !FALSE ) 440 #endif /* TRUE */ 441 442 443 444 /* MD5 context. */ 445 #define TSK_MD5_DIGEST_LENGTH 16 446 typedef struct { 447 UINT4 state[4]; /* state (ABCD) */ 448 UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */ 449 unsigned char buffer[64]; /* input buffer */ 450 } TSK_MD5_CTX; 451 452 void TSK_MD5_Init(TSK_MD5_CTX *); 453 void TSK_MD5_Update(TSK_MD5_CTX *, unsigned char *, unsigned int); 454 void TSK_MD5_Final(unsigned char[16], TSK_MD5_CTX *); 455 456 457 458 /* sha.h */ 459 460 /* The structure for storing SHS info */ 461 #define TSK_SHA_DIGEST_LENGTH 32 462 typedef struct { 463 UINT4 digest[5]; /* Message digest */ 464 UINT4 countLo, countHi; /* 64-bit bit count */ 465 UINT4 data[16]; /* SHS data buffer */ 466 int Endianness; 467 } TSK_SHA_CTX; 468 469 /* Message digest functions */ 470 471 void TSK_SHA_Init(TSK_SHA_CTX *); 472 void TSK_SHA_Update(TSK_SHA_CTX *, BYTE * buffer, int count); 473 void TSK_SHA_Final(BYTE * output, TSK_SHA_CTX *); 474 475 /* Flags for which type of hash(es) to run */ 476 typedef enum{ 477 TSK_BASE_HASH_INVALID_ID = 0, 478 TSK_BASE_HASH_MD5 = 0x01, 479 TSK_BASE_HASH_SHA1 = 0x02 480 //TSK_BASE_HASH_SHA256 = 0x04, 481 } TSK_BASE_HASH_ENUM; 482 483 484 //@} 485 486 #ifdef __cplusplus 487 } 488 #endif 489 #ifdef __cplusplus 490 #if 0 491 class TskStack { 492 private: 493 TSK_STACK * m_stack; 494 495 public: 496 /** 497 * Create a TSK_STACK structure. See tsk_stack_create() for details. 498 * @returns Pointer to structure or NULL on error 499 */ 500 TskStack() { 501 m_stack = tsk_stack_create(); 502 }; 503 /** 504 * Free an allocated TSK_STACK structure. See tsk_stack_free() for details. 505 */ 506 ~TskStack() { 507 tsk_stack_free(m_stack); 508 }; 509 /** 510 * Pop a value from the top of the stack. See tsk_stack_pop() for details. 511 */ 512 void pop() { 513 tsk_stack_pop(m_stack); 514 }; 515 /** 516 * Push a value to the top of TSK_STACK. See tsk_stack_push() for details. 517 * @param a_val Value to push on 518 * @returns 1 on error 519 */ 520 uint8_t push(uint64_t a_val) { 521 return tsk_stack_push(m_stack, a_val); 522 }; 523 /** 524 * Search a TSK_STACK for a given value. See tsk_stack_find() for details. 525 * @param a_val Value to search for 526 * @returns 1 if found and 0 if not 527 */ 528 uint8_t find(uint64_t a_val) { 529 return tsk_stack_find(m_stack, a_val); 530 }; 531 /** 532 * Return Number of entries in the stack 533 * @returns number of entries in the stack 534 */ 535 size_t length() { 536 if (m_stack != NULL) 537 return m_stack->len; 538 else 539 return 0; 540 }; 541 }; 542 #endif 543 544 /** 545 * \ingroup baselib_cpp 546 * Allows access to most recent error message and code in the thread. 547 */ 548 class TskError { 549 public: 550 /** 551 * Return the string with the current error message. The string does not end with a 552 * newline. See tsk_error_get() for details. 553 * 554 * @returns String with error message or NULL if there is no error 555 */ get()556 static const char *get() { 557 return tsk_error_get(); 558 }; 559 560 /** 561 * Print the current error message to a file. See tsk_error_print() for details. 562 * 563 * @param a_hFile File to print message to 564 */ print(FILE * a_hFile)565 static void print(FILE * a_hFile) { 566 tsk_error_print(a_hFile); 567 }; 568 569 /** 570 * Clear the error number and error message. See tsk_error_reset() for details. 571 */ reset()572 static void reset() { 573 tsk_error_reset(); 574 }; 575 }; 576 577 #endif 578 #endif 579