diff --git a/sleuthKitJars/4.10.1/sleuthkit-4.10.1.jar b/sleuthKitJars/4.10.1/sleuthkit-4.10.1.jar new file mode 100644 index 0000000000..9bdb431419 Binary files /dev/null and b/sleuthKitJars/4.10.1/sleuthkit-4.10.1.jar differ diff --git a/sleuthKitJars/4.13/sleuthkit-4.13.0.jar b/sleuthKitJars/4.13/sleuthkit-4.13.0.jar new file mode 100644 index 0000000000..e23a21354f Binary files /dev/null and b/sleuthKitJars/4.13/sleuthkit-4.13.0.jar differ diff --git a/sleuthKitJars/4.14/sleuthkit-4.14.0.jar b/sleuthKitJars/4.14/sleuthkit-4.14.0.jar new file mode 100644 index 0000000000..568fd55d26 Binary files /dev/null and b/sleuthKitJars/4.14/sleuthkit-4.14.0.jar differ diff --git a/sleuthKitJars/4.14/sleuthkit-caseuco-4.14.0.jar b/sleuthKitJars/4.14/sleuthkit-caseuco-4.14.0.jar new file mode 100644 index 0000000000..03cb181b54 Binary files /dev/null and b/sleuthKitJars/4.14/sleuthkit-caseuco-4.14.0.jar differ diff --git a/sleuthKitLibs/4.10.1/Makefile b/sleuthKitLibs/4.10.1/Makefile new file mode 100644 index 0000000000..c88a1abf47 --- /dev/null +++ b/sleuthKitLibs/4.10.1/Makefile @@ -0,0 +1,722 @@ +# Makefile.in generated by automake 1.18 from Makefile.am. +# bindings/java/jni/Makefile. Generated from Makefile.in by configure. + +# Copyright (C) 1994-2025 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + + + +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +am__rm_f = rm -f $(am__rm_f_notfound) +am__rm_rf = rm -rf $(am__rm_f_notfound) +pkgdatadir = $(datadir)/sleuthkit +pkgincludedir = $(includedir)/sleuthkit +pkglibdir = $(libdir)/sleuthkit +pkglibexecdir = $(libexecdir)/sleuthkit +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = aarch64-apple-darwin23.2.0 +host_triplet = aarch64-apple-darwin23.2.0 +subdir = bindings/java/jni +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_pthread.m4 \ + $(top_srcdir)/m4/cppunit.m4 \ + $(top_srcdir)/m4/ax_jni_include_dir.m4 \ + $(top_srcdir)/m4/ac_prog_javac_works.m4 \ + $(top_srcdir)/m4/ac_prog_javac.m4 \ + $(top_srcdir)/m4/ac_prog_java_works.m4 \ + $(top_srcdir)/m4/ac_prog_java.m4 \ + $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/tsk/tsk_config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && echo $$files | $(am__xargs_n) 40 $(am__rm_f); }; \ + } +am__installdirs = "$(DESTDIR)$(libdir)" +LTLIBRARIES = $(lib_LTLIBRARIES) +libtsk_jni_la_DEPENDENCIES = ../../../tsk/libtsk.la +am_libtsk_jni_la_OBJECTS = dataModel_SleuthkitJNI.lo auto_db_java.lo +libtsk_jni_la_OBJECTS = $(am_libtsk_jni_la_OBJECTS) +AM_V_lt = $(am__v_lt_$(V)) +am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY)) +am__v_lt_0 = --silent +am__v_lt_1 = +AM_V_P = $(am__v_P_$(V)) +am__v_P_ = $(am__v_P_$(AM_DEFAULT_VERBOSITY)) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_$(V)) +am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_$(V)) +am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I. -I$(top_builddir)/tsk +depcomp = $(SHELL) $(top_srcdir)/config/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/auto_db_java.Plo \ + ./$(DEPDIR)/dataModel_SleuthkitJNI.Plo +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CXXFLAGS) $(CXXFLAGS) +AM_V_CXX = $(am__v_CXX_$(V)) +am__v_CXX_ = $(am__v_CXX_$(AM_DEFAULT_VERBOSITY)) +am__v_CXX_0 = @echo " CXX " $@; +am__v_CXX_1 = +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ + $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CXXLD = $(am__v_CXXLD_$(V)) +am__v_CXXLD_ = $(am__v_CXXLD_$(AM_DEFAULT_VERBOSITY)) +am__v_CXXLD_0 = @echo " CXXLD " $@; +am__v_CXXLD_1 = +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_$(V)) +am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY)) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_$(V)) +am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY)) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libtsk_jni_la_SOURCES) +DIST_SOURCES = $(libtsk_jni_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/config/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = ${SHELL} '/Users/hollybeja/Code/sleuthkit10/config/missing' aclocal-1.18 +ALLOCA = +AMTAR = $${TAR-tar} +AM_CFLAGS = -Wall -Wextra -Wno-unused-parameter +AM_CXXFLAGS = -Wall -Wextra -Wno-unused-parameter -Wno-unused-command-line-argument \ + -Wno-overloaded-virtual +AM_DEFAULT_VERBOSITY = 1 +ANT_FOUND = /opt/homebrew/bin/ant +AR = ar +AUTOCONF = ${SHELL} '/Users/hollybeja/Code/sleuthkit10/config/missing' autoconf +AUTOHEADER = ${SHELL} '/Users/hollybeja/Code/sleuthkit10/config/missing' autoheader +AUTOMAKE = ${SHELL} '/Users/hollybeja/Code/sleuthkit10/config/missing' automake-1.18 +AWK = awk +CC = gcc +CCDEPMODE = depmode=gcc3 +CFLAGS = -g -O2 +CPP = gcc -E +CPPFLAGS = -D_THREAD_SAFE -pthread -I/usr/local/include +CPPUNIT_CFLAGS = +CPPUNIT_CONFIG = no +CPPUNIT_LIBS = +CSCOPE = cscope +CTAGS = ctags +CXX = g++ -std=gnu++11 -std=c++14 +CXXCPP = g++ -std=gnu++11 -E -std=c++14 +CXXDEPMODE = depmode=gcc3 +CXXFLAGS = -g -O2 +CYGPATH_W = echo +DEFS = -DHAVE_CONFIG_H +DEPDIR = .deps +DLLTOOL = false +DSYMUTIL = dsymutil +DUMPBIN = +ECHO_C = \c +ECHO_N = +ECHO_T = +EGREP = /usr/bin/grep -E +ETAGS = etags +EXEEXT = +FGREP = /usr/bin/grep -F +FILECMD = file +GREP = /usr/bin/grep +HAVE_CXX14 = 1 +INSTALL = /usr/bin/install -c +INSTALL_DATA = ${INSTALL} -m 644 +INSTALL_PROGRAM = ${INSTALL} +INSTALL_SCRIPT = ${INSTALL} +INSTALL_STRIP_PROGRAM = $(install_sh) -c -s +JAVA = java +JAVAC = javac +JNI_CPPFLAGS = -I/opt/homebrew/Cellar/openjdk@17/17.0.15/libexec/openjdk.jdk/Contents/Home/include -I/opt/homebrew/Cellar/openjdk@17/17.0.15/libexec/openjdk.jdk/Contents/Home/include/darwin +LD = /Library/Developer/CommandLineTools/usr/bin/ld +LDFLAGS = -D_THREAD_SAFE -pthread -L/usr/local/lib +LIBOBJS = ${LIBOBJDIR}error$U.o ${LIBOBJDIR}lstat$U.o +LIBS = -ldl -lz -lsqlite3 -ldl -lstdc++ +LIBTOOL = $(SHELL) $(top_builddir)/libtool +LIBTSK_LDFLAGS = +LIPO = lipo +LN_S = ln -s +LTLIBOBJS = ${LIBOBJDIR}error$U.lo ${LIBOBJDIR}lstat$U.lo +LT_SYS_LIBRARY_PATH = +MAINT = # +MAKEINFO = ${SHELL} '/Users/hollybeja/Code/sleuthkit10/config/missing' makeinfo +MANIFEST_TOOL = : +MKDIR_P = mkdir -p +NM = /usr/bin/nm -B +NMEDIT = nmedit +OBJDUMP = objdump +OBJEXT = o +OTOOL = otool +OTOOL64 = : +PACKAGE = sleuthkit +PACKAGE_BUGREPORT = +PACKAGE_NAME = sleuthkit +PACKAGE_STRING = sleuthkit 4.10.1 +PACKAGE_TARNAME = sleuthkit +PACKAGE_URL = +PACKAGE_VERSION = 4.10.1 +PATH_SEPARATOR = : +PERL = /usr/bin/perl +PTHREAD_CC = gcc +PTHREAD_CFLAGS = -D_THREAD_SAFE -pthread +PTHREAD_LIBS = +RANLIB = ranlib +SED = /usr/bin/sed +SET_MAKE = +SHELL = /bin/sh +STRIP = strip +VERSION = 4.10.1 +Z_PATH = yes/lib +_ACJNI_JAVAC = +abs_builddir = /Users/hollybeja/Code/sleuthkit10/bindings/java/jni +abs_srcdir = /Users/hollybeja/Code/sleuthkit10/bindings/java/jni +abs_top_builddir = /Users/hollybeja/Code/sleuthkit10 +abs_top_srcdir = /Users/hollybeja/Code/sleuthkit10 +ac_ct_AR = ar +ac_ct_CC = gcc +ac_ct_CXX = g++ +ac_ct_DUMPBIN = +am__include = include +am__leading_dot = . +am__quote = +am__rm_f_notfound = +am__tar = tar --format=ustar -chf - "$$tardir" +am__untar = tar -xf - +am__xargs_n = xargs -n +ax_pthread_config = +bindir = ${exec_prefix}/bin +build = aarch64-apple-darwin23.2.0 +build_alias = +build_cpu = aarch64 +build_os = darwin23.2.0 +build_vendor = apple +builddir = . +datadir = ${datarootdir} +datarootdir = ${prefix}/share +docdir = ${datarootdir}/doc/${PACKAGE_TARNAME} +dvidir = ${docdir} +exec_prefix = ${prefix} +host = aarch64-apple-darwin23.2.0 +host_alias = +host_cpu = aarch64 +host_os = darwin23.2.0 +host_vendor = apple +htmldir = ${docdir} +includedir = ${prefix}/include +infodir = ${datarootdir}/info +install_sh = ${SHELL} /Users/hollybeja/Code/sleuthkit10/config/install-sh +libdir = ${exec_prefix}/lib +libexecdir = ${exec_prefix}/libexec +localedir = ${datarootdir}/locale +localstatedir = ${prefix}/var +mandir = ${datarootdir}/man +mkdir_p = $(MKDIR_P) +oldincludedir = /usr/include +pdfdir = ${docdir} +prefix = /usr/local +program_transform_name = s,x,x, +psdir = ${docdir} +runstatedir = ${localstatedir}/run +sbindir = ${exec_prefix}/sbin +sharedstatedir = ${prefix}/com +srcdir = . +sysconfdir = ${prefix}/etc +target_alias = +top_build_prefix = ../../../ +top_builddir = ../../.. +top_srcdir = ../../.. +uudecode = yes +AM_CPPFLAGS = -I../../.. -I$(srcdir)/../../.. $(JNI_CPPFLAGS) +EXTRA_DIST = .indent.pro +lib_LTLIBRARIES = libtsk_jni.la +libtsk_jni_la_SOURCES = dataModel_SleuthkitJNI.cpp dataModel_SleuthkitJNI.h auto_db_java.h auto_db_java.cpp +libtsk_jni_la_LIBADD = ../../../tsk/libtsk.la +all: all-am + +.SUFFIXES: +.SUFFIXES: .cpp .lo .o .obj +$(srcdir)/Makefile.in: # $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign bindings/java/jni/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign bindings/java/jni/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: # $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): # $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ + } + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ + done + +clean-libLTLIBRARIES: + -$(am__rm_f) $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + echo rm -f $${locs}; \ + $(am__rm_f) $${locs} + +libtsk_jni.la: $(libtsk_jni_la_OBJECTS) $(libtsk_jni_la_DEPENDENCIES) $(EXTRA_libtsk_jni_la_DEPENDENCIES) + $(AM_V_CXXLD)$(CXXLINK) -rpath $(libdir) $(libtsk_jni_la_OBJECTS) $(libtsk_jni_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +include ./$(DEPDIR)/auto_db_java.Plo # am--include-marker +include ./$(DEPDIR)/dataModel_SleuthkitJNI.Plo # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @: >>$@ + +am--depfiles: $(am__depfiles_remade) + +.cpp.o: + $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< + $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +# $(AM_V_CXX)source='$<' object='$@' libtool=no \ +# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \ +# $(AM_V_CXX_no)$(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: + $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` + $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +# $(AM_V_CXX)source='$<' object='$@' libtool=no \ +# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \ +# $(AM_V_CXX_no)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cpp.lo: + $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< + $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +# $(AM_V_CXX)source='$<' object='$@' libtool=yes \ +# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \ +# $(AM_V_CXX_no)$(LTCXXCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(libdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -$(am__rm_f) $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libLTLIBRARIES clean-libtool clean-local \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/auto_db_java.Plo + -rm -f ./$(DEPDIR)/dataModel_SleuthkitJNI.Plo + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-libLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/auto_db_java.Plo + -rm -f ./$(DEPDIR)/dataModel_SleuthkitJNI.Plo + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-libLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libLTLIBRARIES clean-libtool clean-local \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-libLTLIBRARIES \ + install-man install-pdf install-pdf-am install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-libLTLIBRARIES + +.PRECIOUS: Makefile + + +indent: + indent *.cpp *.h + +clean-local: + -rm -f *.c~ *.h~ + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: + +# Tell GNU make to disable its built-in pattern rules. +%:: %,v +%:: RCS/%,v +%:: RCS/% +%:: s.% +%:: SCCS/s.% diff --git a/sleuthKitLibs/4.10.1/Makefile.am b/sleuthKitLibs/4.10.1/Makefile.am new file mode 100644 index 0000000000..8057baf1cf --- /dev/null +++ b/sleuthKitLibs/4.10.1/Makefile.am @@ -0,0 +1,13 @@ +AM_CPPFLAGS = -I../../.. -I$(srcdir)/../../.. $(JNI_CPPFLAGS) +AM_CXXFLAGS += -Wno-unused-command-line-argument -Wno-overloaded-virtual +EXTRA_DIST = .indent.pro + +lib_LTLIBRARIES = libtsk_jni.la +libtsk_jni_la_SOURCES = dataModel_SleuthkitJNI.cpp dataModel_SleuthkitJNI.h auto_db_java.h auto_db_java.cpp +libtsk_jni_la_LIBADD = ../../../tsk/libtsk.la + +indent: + indent *.cpp *.h + +clean-local: + -rm -f *.c~ *.h~ diff --git a/sleuthKitLibs/4.10.1/Makefile.in b/sleuthKitLibs/4.10.1/Makefile.in new file mode 100644 index 0000000000..78742f4f56 --- /dev/null +++ b/sleuthKitLibs/4.10.1/Makefile.in @@ -0,0 +1,722 @@ +# Makefile.in generated by automake 1.18 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2025 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +am__rm_f = rm -f $(am__rm_f_notfound) +am__rm_rf = rm -rf $(am__rm_f_notfound) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = bindings/java/jni +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_pthread.m4 \ + $(top_srcdir)/m4/cppunit.m4 \ + $(top_srcdir)/m4/ax_jni_include_dir.m4 \ + $(top_srcdir)/m4/ac_prog_javac_works.m4 \ + $(top_srcdir)/m4/ac_prog_javac.m4 \ + $(top_srcdir)/m4/ac_prog_java_works.m4 \ + $(top_srcdir)/m4/ac_prog_java.m4 \ + $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/tsk/tsk_config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && echo $$files | $(am__xargs_n) 40 $(am__rm_f); }; \ + } +am__installdirs = "$(DESTDIR)$(libdir)" +LTLIBRARIES = $(lib_LTLIBRARIES) +libtsk_jni_la_DEPENDENCIES = ../../../tsk/libtsk.la +am_libtsk_jni_la_OBJECTS = dataModel_SleuthkitJNI.lo auto_db_java.lo +libtsk_jni_la_OBJECTS = $(am_libtsk_jni_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/tsk +depcomp = $(SHELL) $(top_srcdir)/config/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/auto_db_java.Plo \ + ./$(DEPDIR)/dataModel_SleuthkitJNI.Plo +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CXXFLAGS) $(CXXFLAGS) +AM_V_CXX = $(am__v_CXX_@AM_V@) +am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) +am__v_CXX_0 = @echo " CXX " $@; +am__v_CXX_1 = +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ + $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) +am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) +am__v_CXXLD_0 = @echo " CXXLD " $@; +am__v_CXXLD_1 = +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libtsk_jni_la_SOURCES) +DIST_SOURCES = $(libtsk_jni_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/config/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +AM_CFLAGS = @AM_CFLAGS@ +AM_CXXFLAGS = @AM_CXXFLAGS@ -Wno-unused-command-line-argument \ + -Wno-overloaded-virtual +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +ANT_FOUND = @ANT_FOUND@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CPPUNIT_CFLAGS = @CPPUNIT_CFLAGS@ +CPPUNIT_CONFIG = @CPPUNIT_CONFIG@ +CPPUNIT_LIBS = @CPPUNIT_LIBS@ +CSCOPE = @CSCOPE@ +CTAGS = @CTAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ETAGS = @ETAGS@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +FILECMD = @FILECMD@ +GREP = @GREP@ +HAVE_CXX14 = @HAVE_CXX14@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +JAVA = @JAVA@ +JAVAC = @JAVAC@ +JNI_CPPFLAGS = @JNI_CPPFLAGS@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBTSK_LDFLAGS = @LIBTSK_LDFLAGS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ +PTHREAD_CC = @PTHREAD_CC@ +PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ +PTHREAD_LIBS = @PTHREAD_LIBS@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +Z_PATH = @Z_PATH@ +_ACJNI_JAVAC = @_ACJNI_JAVAC@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__rm_f_notfound = @am__rm_f_notfound@ +am__tar = @am__tar@ +am__untar = @am__untar@ +am__xargs_n = @am__xargs_n@ +ax_pthread_config = @ax_pthread_config@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +uudecode = @uudecode@ +AM_CPPFLAGS = -I../../.. -I$(srcdir)/../../.. $(JNI_CPPFLAGS) +EXTRA_DIST = .indent.pro +lib_LTLIBRARIES = libtsk_jni.la +libtsk_jni_la_SOURCES = dataModel_SleuthkitJNI.cpp dataModel_SleuthkitJNI.h auto_db_java.h auto_db_java.cpp +libtsk_jni_la_LIBADD = ../../../tsk/libtsk.la +all: all-am + +.SUFFIXES: +.SUFFIXES: .cpp .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign bindings/java/jni/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign bindings/java/jni/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ + } + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ + done + +clean-libLTLIBRARIES: + -$(am__rm_f) $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + echo rm -f $${locs}; \ + $(am__rm_f) $${locs} + +libtsk_jni.la: $(libtsk_jni_la_OBJECTS) $(libtsk_jni_la_DEPENDENCIES) $(EXTRA_libtsk_jni_la_DEPENDENCIES) + $(AM_V_CXXLD)$(CXXLINK) -rpath $(libdir) $(libtsk_jni_la_OBJECTS) $(libtsk_jni_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/auto_db_java.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dataModel_SleuthkitJNI.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @: >>$@ + +am--depfiles: $(am__depfiles_remade) + +.cpp.o: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cpp.lo: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(libdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -$(am__rm_f) $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libLTLIBRARIES clean-libtool clean-local \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/auto_db_java.Plo + -rm -f ./$(DEPDIR)/dataModel_SleuthkitJNI.Plo + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-libLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/auto_db_java.Plo + -rm -f ./$(DEPDIR)/dataModel_SleuthkitJNI.Plo + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-libLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libLTLIBRARIES clean-libtool clean-local \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-libLTLIBRARIES \ + install-man install-pdf install-pdf-am install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-libLTLIBRARIES + +.PRECIOUS: Makefile + + +indent: + indent *.cpp *.h + +clean-local: + -rm -f *.c~ *.h~ + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: + +# Tell GNU make to disable its built-in pattern rules. +%:: %,v +%:: RCS/%,v +%:: RCS/% +%:: s.% +%:: SCCS/s.% diff --git a/sleuthKitLibs/4.10.1/auto_db_java.cpp b/sleuthKitLibs/4.10.1/auto_db_java.cpp new file mode 100644 index 0000000000..7cc3888cf3 --- /dev/null +++ b/sleuthKitLibs/4.10.1/auto_db_java.cpp @@ -0,0 +1,1965 @@ +/* + ** The Sleuth Kit + ** + ** Brian Carrier [carrier sleuthkit [dot] org] + ** Copyright (c) 2020 Brian Carrier. All Rights reserved + ** + ** This software is distributed under the Common Public License 1.0 + ** + */ + +/** + * \file auto_db_java.cpp + * Contains code to populate database with volume and file system information from a specific image. + */ + +#include "auto_db_java.h" +#include "jni.h" +#include "tsk/img/img_writer.h" +#if HAVE_LIBEWF +#include "tsk/img/ewf.h" +#include "tsk/img/tsk_img_i.h" +#endif +#include + +#include +#include + +using std::stringstream; +using std::for_each; + +/** + */ +TskAutoDbJava::TskAutoDbJava() +{ + m_curImgId = 0; + m_curVsId = 0; + m_curVolId = 0; + m_curFsId = 0; + m_curFileId = 0; + m_curUnallocDirId = 0; + m_curDirAddr = 0; + m_curDirPath = ""; + m_vsFound = false; + m_volFound = false; + m_poolFound = false; + m_stopped = false; + m_foundStructure = false; + m_attributeAdded = false; + m_addFileSystems = true; + m_noFatFsOrphans = false; + m_addUnallocSpace = false; + m_minChunkSize = -1; + m_maxChunkSize = -1; + + m_jniEnv = NULL; + + tsk_init_lock(&m_curDirPathLock); +} + +TskAutoDbJava::~TskAutoDbJava() +{ + closeImage(); + tsk_deinit_lock(&m_curDirPathLock); +} + +/** +* Look up all callback method IDs +* @param jniEnv pointer to java environment this was called from +* @param jobj the TskCaseDbBridge object this was called from +*/ +TSK_RETVAL_ENUM +TskAutoDbJava::initializeJni(JNIEnv * jniEnv, jobject jobj) { + m_jniEnv = jniEnv; + m_javaDbObj = m_jniEnv->NewGlobalRef(jobj); + + jclass localCallbackClass = m_jniEnv->FindClass("org/sleuthkit/datamodel/TskCaseDbBridge"); + if (localCallbackClass == NULL) { + return TSK_ERR; + } + m_callbackClass = (jclass)m_jniEnv->NewGlobalRef(localCallbackClass); + + m_addImageMethodID = m_jniEnv->GetMethodID(m_callbackClass, "addImageInfo", "(IJLjava/lang/String;JLjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;)J"); + if (m_addImageMethodID == NULL) { + return TSK_ERR; + } + + m_addAcquisitionDetailsMethodID = m_jniEnv->GetMethodID(m_callbackClass, "addAcquisitionDetails", "(JLjava/lang/String;)V"); + if (m_addAcquisitionDetailsMethodID == NULL) { + return TSK_ERR; + } + + m_addVolumeSystemMethodID = m_jniEnv->GetMethodID(m_callbackClass, "addVsInfo", "(JIJJ)J"); + if (m_addVolumeSystemMethodID == NULL) { + return TSK_ERR; + } + + m_addVolumeMethodID = m_jniEnv->GetMethodID(m_callbackClass, "addVolume", "(JJJJLjava/lang/String;J)J"); + if (m_addVolumeMethodID == NULL) { + return TSK_ERR; + } + + m_addPoolMethodID = m_jniEnv->GetMethodID(m_callbackClass, "addPool", "(JI)J"); + if (m_addPoolMethodID == NULL) { + return TSK_ERR; + } + + + m_addFileSystemMethodID = m_jniEnv->GetMethodID(m_callbackClass, "addFileSystem", "(JJIJJJJJ)J"); + if (m_addFileSystemMethodID == NULL) { + return TSK_ERR; + } + + m_addFileMethodID = m_jniEnv->GetMethodID(m_callbackClass, "addFile", "(JJJIIILjava/lang/String;JJIIIIJJJJJIIILjava/lang/String;Ljava/lang/String;JJJ)J"); + if (m_addFileMethodID == NULL) { + return TSK_ERR; + } + + m_addUnallocParentMethodID = m_jniEnv->GetMethodID(m_callbackClass, "addUnallocFsBlockFilesParent", "(JLjava/lang/String;)J"); + if (m_addUnallocParentMethodID == NULL) { + return TSK_ERR; + } + + m_addLayoutFileMethodID = m_jniEnv->GetMethodID(m_callbackClass, "addLayoutFile", "(JJJILjava/lang/String;J)J"); + if (m_addLayoutFileMethodID == NULL) { + return TSK_ERR; + } + + m_addLayoutFileRangeMethodID = m_jniEnv->GetMethodID(m_callbackClass, "addLayoutFileRange", "(JJJJ)J"); + if (m_addLayoutFileRangeMethodID == NULL) { + return TSK_ERR; + } + return TSK_OK; +} + +/** +* Cache a database object for later use. Should be called on image, volume system, volume, +* pool, and file system. +* @param objId The object ID of the new object +* @param parObjId The object ID of the new object's parent +* @param type The type of object +*/ +void +TskAutoDbJava::saveObjectInfo(int64_t objId, int64_t parObjId, TSK_DB_OBJECT_TYPE_ENUM type) { + TSK_DB_OBJECT objectInfo; + objectInfo.objId = objId; + objectInfo.parObjId = parObjId; + objectInfo.type = type; + m_savedObjects.push_back(objectInfo); +} + +/** +* Get a previously cached database object. +* @param objId The object ID of the object being loaded +*/ +TSK_RETVAL_ENUM +TskAutoDbJava::getObjectInfo(int64_t objId, TSK_DB_OBJECT** obj_info) { + for (vector::iterator itObjs = m_savedObjects.begin(); + itObjs != m_savedObjects.end(); ++itObjs) { + TSK_DB_OBJECT* tskDbObj = &(*itObjs); + if (tskDbObj->objId == objId) { + *obj_info = tskDbObj; + return TSK_OK; + } + } + + // Object not found + return TSK_ERR; +} + +/** +* Adds image details to the existing database tables. Object ID for new image stored in objId. +* +* @param type Image type +* @param ssize Size of device sector in bytes (or 0 for default) +* @param objId The object id assigned to the image (out param) +* @param timeZone The timezone the image is from +* @param size The size of the image in bytes. +* @param md5 MD5 hash of the image +* @param sha1 SHA1 hash of the image +* @param sha256 SHA256 hash of the image +* @param deviceId An ASCII-printable identifier for the device associated with the data source that is intended to be unique across multiple cases (e.g., a UUID). +* @param collectionDetails collection details +* @returns TSK_ERR on error, TSK_OK on success +*/ +TSK_RETVAL_ENUM +TskAutoDbJava::addImageInfo(int type, TSK_OFF_T ssize, int64_t & objId, const string & timezone, TSK_OFF_T size, const string &md5, + const string& sha1, const string& sha256, const string& deviceId, const string& collectionDetails, + char** img_ptrs, int num_imgs) { + + const char *tz_cstr = timezone.c_str(); + jstring tzj = m_jniEnv->NewStringUTF(tz_cstr); + + const char *md5_cstr = md5.c_str(); + jstring md5j = m_jniEnv->NewStringUTF(md5_cstr); + + const char *sha1_cstr = sha1.c_str(); + jstring sha1j = m_jniEnv->NewStringUTF(sha1_cstr); + + const char *sha256_cstr = sha256.c_str(); + jstring sha256j = m_jniEnv->NewStringUTF(sha256_cstr); + + const char *devId_cstr = deviceId.c_str(); + jstring devIdj = m_jniEnv->NewStringUTF(devId_cstr); + + const char *coll_cstr = collectionDetails.c_str(); + jstring collj = m_jniEnv->NewStringUTF(coll_cstr); + + jobjectArray imgNamesj = (jobjectArray)m_jniEnv->NewObjectArray( + num_imgs, + m_jniEnv->FindClass("java/lang/String"), + m_jniEnv->NewStringUTF("")); + + for (int i = 0; i < num_imgs; i++) { + m_jniEnv->SetObjectArrayElement( + imgNamesj, i, m_jniEnv->NewStringUTF(img_ptrs[i])); + } + + jlong objIdj = m_jniEnv->CallLongMethod(m_javaDbObj, m_addImageMethodID, + type, ssize, tzj, size, md5j, sha1j, sha256j, devIdj, collj, imgNamesj); + objId = (int64_t)objIdj; + + if (objId < 0) { + return TSK_ERR; + } + + saveObjectInfo(objId, 0, TSK_DB_OBJECT_TYPE_IMG); + return TSK_OK; +} + +void +TskAutoDbJava::addAcquisitionDetails(int64_t imgId, const string& collectionDetails) { + + const char *coll_cstr = collectionDetails.c_str(); + jstring collj = m_jniEnv->NewStringUTF(coll_cstr); + + m_jniEnv->CallLongMethod(m_javaDbObj, m_addAcquisitionDetailsMethodID, + imgId, collj); +} + +/** +* Adds volume system to database. Object ID for new vs stored in objId. +* +* @param vs_info Struct containing info for this volume system +* @param parObjId Parent object ID for the volume system +* @param objId Object ID of new volume system +* @returns TSK_ERR on error, TSK_OK on success +*/ +TSK_RETVAL_ENUM +TskAutoDbJava::addVsInfo(const TSK_VS_INFO* vs_info, int64_t parObjId, int64_t& objId) { + + jlong objIdj = m_jniEnv->CallLongMethod(m_javaDbObj, m_addVolumeSystemMethodID, + parObjId, vs_info->vstype, vs_info->offset, (uint64_t)vs_info->block_size); + objId = (int64_t)objIdj; + + if (objId < 0) { + return TSK_ERR; + } + + // Save the vs info to use for unallocated blocks later + TSK_DB_VS_INFO vs_db; + vs_db.objId = objId; + vs_db.offset = vs_info->offset; + vs_db.vstype = vs_info->vstype; + vs_db.block_size = vs_info->block_size; + m_savedVsInfo.push_back(vs_db); + + saveObjectInfo(objId, parObjId, TSK_DB_OBJECT_TYPE_VS); + return TSK_OK; +} + +/** +* Adds pool and pool volume system to database. Object ID for new pool vs stored in objId. +* +* @param pool_info Struct containing info for this pool +* @param parObjId Parent object ID for the pool +* @param objId Object ID of new pool volume system +* @returns TSK_ERR on error, TSK_OK on success +*/ +TSK_RETVAL_ENUM +TskAutoDbJava::addPoolInfoAndVS(const TSK_POOL_INFO *pool_info, int64_t parObjId, int64_t& objId) { + + // Add the pool + jlong poolObjIdj = m_jniEnv->CallLongMethod(m_javaDbObj, m_addPoolMethodID, + parObjId, pool_info->ctype); + int64_t poolObjId = (int64_t)poolObjIdj; + + if (poolObjId < 0) { + return TSK_ERR; + } + saveObjectInfo(poolObjId, parObjId, TSK_DB_OBJECT_TYPE_POOL); + + // Add the pool volume + jlong objIdj = m_jniEnv->CallLongMethod(m_javaDbObj, m_addVolumeSystemMethodID, + poolObjIdj, TSK_VS_TYPE_APFS, pool_info->img_offset, (uint64_t)pool_info->block_size); + objId = (int64_t)objIdj; + + saveObjectInfo(objId, poolObjId, TSK_DB_OBJECT_TYPE_VS); + return TSK_OK; +} + +/** +* Adds a pool volume to database. Object ID for new pool volume stored in objId. +* +* @param pool_vol Struct containing info for this pool volume +* @param parObjId Parent object ID +* @param objId Object ID of new pool volume +* @returns TSK_ERR on error, TSK_OK on success +*/ +TSK_RETVAL_ENUM +TskAutoDbJava::addPoolVolumeInfo(const TSK_POOL_VOLUME_INFO* pool_vol, + int64_t parObjId, int64_t& objId) { + + jstring descj = m_jniEnv->NewStringUTF(pool_vol->desc); + + jlong objIdj = m_jniEnv->CallLongMethod(m_javaDbObj, m_addVolumeMethodID, + parObjId, (int64_t)pool_vol->index, pool_vol->block, pool_vol->num_blocks, + descj, pool_vol->flags); + objId = (int64_t)objIdj; + + if (objId < 0) { + return TSK_ERR; + } + + saveObjectInfo(objId, parObjId, TSK_DB_OBJECT_TYPE_VOL); + return TSK_OK; +} + +/** +* Adds a volume to database. Object ID for new volume stored in objId. +* +* @param vs_part Struct containing info for this volume +* @param parObjId Parent object ID +* @param objId Object ID of new volume +* @returns TSK_ERR on error, TSK_OK on success +*/ +TSK_RETVAL_ENUM +TskAutoDbJava::addVolumeInfo(const TSK_VS_PART_INFO* vs_part, + int64_t parObjId, int64_t& objId) { + + jstring descj = m_jniEnv->NewStringUTF(vs_part->desc); + + jlong objIdj = m_jniEnv->CallLongMethod(m_javaDbObj, m_addVolumeMethodID, + parObjId, (uint64_t)vs_part->addr, vs_part->start, vs_part->len, + descj, vs_part->flags); + objId = (int64_t)objIdj; + + if (objId < 0) { + return TSK_ERR; + } + + // Save the volume info for creating unallocated blocks later + TSK_DB_VS_PART_INFO vs_part_db; + vs_part_db.objId = objId; + vs_part_db.addr = vs_part->addr; + vs_part_db.start = vs_part->start; + vs_part_db.len = vs_part->len; + strncpy(vs_part_db.desc, vs_part->desc, TSK_MAX_DB_VS_PART_INFO_DESC_LEN - 1); + vs_part_db.flags = vs_part->flags; + m_savedVsPartInfo.push_back(vs_part_db); + + saveObjectInfo(objId, parObjId, TSK_DB_OBJECT_TYPE_VOL); + return TSK_OK; +} + +/** +* Adds a file system to database. Object ID for new file system stored in objId. +* +* @param fs_info Struct containing info for this file system +* @param parObjId Parent object ID +* @param objId Object ID of new file system +* @returns TSK_ERR on error, TSK_OK on success +*/ +TSK_RETVAL_ENUM +TskAutoDbJava::addFsInfo(const TSK_FS_INFO* fs_info, int64_t parObjId, + int64_t& objId) { + + jlong objIdj = m_jniEnv->CallLongMethod(m_javaDbObj, m_addFileSystemMethodID, + parObjId, fs_info->offset, (int)fs_info->ftype, (uint64_t)fs_info->block_size, + fs_info->block_count, fs_info->root_inum, fs_info->first_inum, + fs_info->last_inum); + objId = (int64_t)objIdj; + + if (objId < 0) { + return TSK_ERR; + } + + // Save the file system info for creating unallocated blocks later + TSK_DB_FS_INFO fs_info_db; + fs_info_db.objId = objId; + fs_info_db.imgOffset = fs_info->offset; + fs_info_db.fType = fs_info->ftype; + fs_info_db.block_size = fs_info->block_size; + fs_info_db.block_count = fs_info->block_count; + fs_info_db.root_inum = fs_info->root_inum; + fs_info_db.first_inum = fs_info->first_inum; + fs_info_db.last_inum = fs_info->last_inum; + m_savedFsInfo.push_back(fs_info_db); + + saveObjectInfo(objId, parObjId, TSK_DB_OBJECT_TYPE_FS); + return TSK_OK; +} + +/** +* Adds a file to database. Object ID for new file stored in objId. +* +* @param fs_file +* @param fs_attr +* @param path File path +* @param parObjId Parent object ID +* @param fsObjId Object ID of the file system +* @param objId Object ID of new file +* @param dataSourceObjId Object ID of the data source +* @returns TSK_ERR on error, TSK_OK on success +*/ +TSK_RETVAL_ENUM +TskAutoDbJava::addFsFile(TSK_FS_FILE* fs_file, + const TSK_FS_ATTR* fs_attr, const char* path, + int64_t fsObjId, int64_t& objId, int64_t dataSourceObjId) { + + if (fs_file->name == NULL) + return TSK_ERR; + + // The object id for the parent folder. Will stay as zero if not the root folder + int64_t parObjId = 0; + + // Root directory's parent should be the file system object. + // Make sure it doesn't have a name, so that we don't pick up ".." entries + if ((fs_file->fs_info->root_inum == fs_file->name->meta_addr) && + ((fs_file->name->name == NULL) || (strlen(fs_file->name->name) == 0))) { + // File is in the root directory + parObjId = fsObjId; + } + + // Add the file to the database + return addFile(fs_file, fs_attr, path, fsObjId, parObjId, dataSourceObjId); +} + +/** +* Extract the extension from the given file name and store it in the supplied string. +* @param name A file name +* @param extension The file name extension will be extracted to extension. +*/ +void extractExtension(char *name, char *extension) { + char *ext = strrchr(name, '.'); + + //if ext is not null and is not the entire filename... + if (ext && (name != ext)) { + size_t extLen = strlen(ext); + //... and doesn't only contain the '.' and isn't too long to be a real extension. + if ((1 < extLen) && (extLen < 15)) { + strncpy(extension, ext + 1, extLen - 1); + //normalize to lower case, only works for ascii + for (int i = 0; extension[i]; i++) { + extension[i] = tolower(extension[i]); + } + } + } +} + +/** +* Convert a sequence of characters to a jstring object. +* We first convert the character sequence to UTF16 and then +* use the JNI NewString() method to create the jstring. +* We do it this way because we encountered data that contained +* 4 byte (or more) UTF8 encoded characters and the JNI NewStringUTF() +* method does not handle 4 byte UTF8 encoding. +* +* @param input The sequence of characters to be turned into a jstring. +* @param newJString The new jstring object created from the input. +* @returns TSK_ERR on error, TSK_OK on success +*/ +TSK_RETVAL_ENUM TskAutoDbJava::createJString(const char * input, jstring & newJString) { + size_t input_len = strlen(input) + 1; + UTF16 * utf16_input; + + if ((utf16_input = (UTF16 *)tsk_malloc(input_len * sizeof(UTF16))) == NULL) { + return TSK_ERR; + } + + UTF8 * source = (UTF8 *)input; + UTF16 * target = utf16_input; + + if (tsk_UTF8toUTF16((const UTF8 **)&source, (const UTF8 *)&source[input_len], &target, &target[input_len], TSKlenientConversion) != TSKconversionOK) { + free(utf16_input); + return TSK_ERR; + } + + /* + * To determine the length of the new string we we subtract the address + * of the start of the UTF16 buffer from the address at the end of the + * UTF16 buffer (target is advanced in the call to the conversion routine + * above). + */ + newJString = m_jniEnv->NewString(utf16_input, (target - utf16_input) - 1); + + free(utf16_input); + return TSK_OK; +} + +/** +* Adds a file and its associated slack file to database. +* Does not learn object ID for new files, and files may +* not be added to the database immediately. +* +* @param fs_file +* @param fs_attr +* @param path File path +* @param fsObjId Object ID of the file system +* @param parObjId Parent object ID if known, 0 otherwise +* @param dataSourceObjId Object ID of the data source +* @returns TSK_ERR on error, TSK_OK on success +*/ +TSK_RETVAL_ENUM +TskAutoDbJava::addFile(TSK_FS_FILE* fs_file, + const TSK_FS_ATTR* fs_attr, const char* path, + int64_t fsObjId, int64_t parObjId, + int64_t dataSourceObjId) +{ + time_t mtime = 0; + time_t crtime = 0; + time_t ctime = 0; + time_t atime = 0; + TSK_OFF_T size = 0; + int meta_type = 0; + int meta_flags = 0; + int meta_mode = 0; + int meta_seq = 0; + int gid = 0; + int uid = 0; + int type = TSK_FS_ATTR_TYPE_NOT_FOUND; + int idx = 0; + + if (fs_file->name == NULL) + return TSK_OK; + + if (fs_file->meta) { + mtime = fs_file->meta->mtime; + atime = fs_file->meta->atime; + ctime = fs_file->meta->ctime; + crtime = fs_file->meta->crtime; + meta_type = fs_file->meta->type; + meta_flags = fs_file->meta->flags; + meta_mode = fs_file->meta->mode; + gid = fs_file->meta->gid; + uid = fs_file->meta->uid; + meta_seq = fs_file->meta->seq; + } + + size_t attr_nlen = 0; + if (fs_attr) { + type = fs_attr->type; + idx = fs_attr->id; + size = fs_attr->size; + if (fs_attr->name) { + if ((fs_attr->type != TSK_FS_ATTR_TYPE_NTFS_IDXROOT) || + (strcmp(fs_attr->name, "$I30") != 0)) { + attr_nlen = strlen(fs_attr->name); + } + } + } + + // sanity check + if (size < 0) { + size = 0; + } + + // combine name and attribute name + size_t len = strlen(fs_file->name->name); + char * name; + size_t nlen = len + attr_nlen + 11; // Extra space for possible colon and '-slack' + if ((name = (char *)tsk_malloc(nlen)) == NULL) { + return TSK_ERR; + } + + strncpy(name, fs_file->name->name, nlen); + + char extension[24] = ""; + extractExtension(name, extension); + + // Add the attribute name + if (attr_nlen > 0) { + strncat(name, ":", nlen - strlen(name)); + if (fs_attr != NULL) { + strncat(name, fs_attr->name, nlen - strlen(name)); + } + } + + jstring namej; + if (createJString(name, namej) != TSK_OK) { + free(name); + return TSK_ERR; + } + + // clean up path + // +2 = space for leading slash and terminating null + size_t path_len = strlen(path) + 2; + char* escaped_path; + if ((escaped_path = (char *)tsk_malloc(path_len)) == NULL) { + free(name); + return TSK_ERR; + } + strncpy(escaped_path, "/", path_len); + strncat(escaped_path, path, path_len - strlen(escaped_path)); + + jstring pathj; + if (createJString(escaped_path, pathj) != TSK_OK) { + free(name); + free(escaped_path); + return TSK_ERR; + } + + // Escaped path is not needed beyond this point so free it. + free(escaped_path); + + jstring extj; + if (createJString(extension, extj) != TSK_OK) { + free(name); + return TSK_ERR; + } + + /* NTFS uses sequence, otherwise we hash the path. We do this to map to the + * correct parent folder if there are two from the root dir that eventually point to + * the same folder (one deleted and one allocated) or two hard links. */ + jlong par_seqj; + if (TSK_FS_TYPE_ISNTFS(fs_file->fs_info->ftype)) + { + par_seqj = fs_file->name->par_seq; + } + else { + par_seqj = -1; + } + TSK_INUM_T par_meta_addr = fs_file->name->par_addr; + + // Add the file to the database + jlong ret_val = m_jniEnv->CallLongMethod(m_javaDbObj, m_addFileMethodID, + parObjId, fsObjId, + dataSourceObjId, + TSK_DB_FILES_TYPE_FS, + type, idx, namej, + fs_file->name->meta_addr, (uint64_t)fs_file->name->meta_seq, + fs_file->name->type, meta_type, fs_file->name->flags, meta_flags, + size, + (unsigned long long)crtime, (unsigned long long)ctime, (unsigned long long) atime, (unsigned long long) mtime, + meta_mode, gid, uid, + pathj, extj, + (uint64_t)meta_seq, par_meta_addr, par_seqj); + + if (ret_val < 0) { + free(name); + return TSK_ERR; + } + + // Add entry for the slack space. + // Current conditions for creating a slack file: + // - File name is not empty, "." or ".." + // - Data is non-resident + // - The allocated size is greater than the initialized file size + // See github issue #756 on why initsize and not size. + // - The data is not compressed + if ((fs_attr != NULL) + && ((strlen(name) > 0) && (!TSK_FS_ISDOT(name))) + && (!(fs_file->meta->flags & TSK_FS_META_FLAG_COMP)) + && (fs_attr->flags & TSK_FS_ATTR_NONRES) + && (fs_attr->nrd.allocsize > fs_attr->nrd.initsize)) { + strncat(name, "-slack", 6); + if (strlen(extension) > 0) { + strncat(extension, "-slack", 6); + } + jstring slackNamej; + if (createJString(name, slackNamej) != TSK_OK) { + free(name); + return TSK_ERR; + } + jstring slackExtj; + if (createJString(extension, slackExtj) != TSK_OK) { + free(name); + return TSK_ERR; + } + TSK_OFF_T slackSize = fs_attr->nrd.allocsize - fs_attr->nrd.initsize; + + // Add slack file to database + jlong ret_val = m_jniEnv->CallLongMethod(m_javaDbObj, m_addFileMethodID, + parObjId, fsObjId, + dataSourceObjId, + TSK_DB_FILES_TYPE_SLACK, + type, idx, slackNamej, + fs_file->name->meta_addr, (uint64_t)fs_file->name->meta_seq, + TSK_FS_NAME_TYPE_REG, TSK_FS_META_TYPE_REG, fs_file->name->flags, meta_flags, + slackSize, + (unsigned long long)crtime, (unsigned long long)ctime, (unsigned long long) atime, (unsigned long long) mtime, + meta_mode, gid, uid, // md5TextPtr, known, + pathj, slackExtj, + (uint64_t)meta_seq, par_meta_addr, par_seqj); + + if (ret_val < 0) { + free(name); + return TSK_ERR; + } + } + + free(name); + + return TSK_OK; +} + +// Internal function object to check for range overlap +typedef struct _checkFileLayoutRangeOverlap { + const vector & ranges; + bool hasOverlap; + + explicit _checkFileLayoutRangeOverlap(const vector & ranges) + : ranges(ranges), hasOverlap(false) {} + + bool getHasOverlap() const { return hasOverlap; } + void operator() (const TSK_DB_FILE_LAYOUT_RANGE & range) { + if (hasOverlap) + return; //no need to check other + + uint64_t start = range.byteStart; + uint64_t end = start + range.byteLen; + + vector::const_iterator it; + for (it = ranges.begin(); it != ranges.end(); ++it) { + const TSK_DB_FILE_LAYOUT_RANGE * otherRange = &(*it); + if (&range == otherRange) + continue; //skip, it's the same range + uint64_t otherStart = otherRange->byteStart; + uint64_t otherEnd = otherStart + otherRange->byteLen; + if (start <= otherEnd && end >= otherStart) { + hasOverlap = true; + break; + } + } + } + +} checkFileLayoutRangeOverlap; + +/** +* Internal helper method to add unalloc, unused and carved files with layout ranges to db +* Generates file_name and populates tsk_files, tsk_objects and tsk_file_layout tables +* Adds a single entry to tsk_files table with an auto-generated file name, tsk_objects table, and one or more entries to tsk_file_layout table +* @param dbFileType Type of file +* @param parentObjId Id of the parent object in the database (fs, volume, or image) +* @param fsObjId parent fs, or NULL if the file is not associated with fs +* @param size Number of bytes in file +* @param ranges vector containing one or more TSK_DB_FILE_LAYOUT_RANGE layout ranges (in) +* @param objId object id of the file object created (output) +* @param dataSourceObjId The object ID for the data source +* @returns TSK_OK on success or TSK_ERR on error. +*/ +TSK_RETVAL_ENUM +TskAutoDbJava::addFileWithLayoutRange(const TSK_DB_FILES_TYPE_ENUM dbFileType, const int64_t parentObjId, + const int64_t fsObjId, const uint64_t size, + vector& ranges, int64_t& objId, + int64_t dataSourceObjId) { + + const size_t numRanges = ranges.size(); + + if (numRanges < 1) { + tsk_error_reset(); + tsk_error_set_errno(TSK_ERR_AUTO_DB); + tsk_error_set_errstr("Error addFileWithLayoutRange() - no ranges present"); + return TSK_ERR; + } + + stringstream fileNameSs; + switch (dbFileType) { + case TSK_DB_FILES_TYPE_UNALLOC_BLOCKS: + fileNameSs << "Unalloc"; + break; + + case TSK_DB_FILES_TYPE_UNUSED_BLOCKS: + fileNameSs << "Unused"; + break; + + case TSK_DB_FILES_TYPE_CARVED: + fileNameSs << "Carved"; + break; + default: + stringstream sserr; + tsk_error_reset(); + tsk_error_set_errno(TSK_ERR_AUTO_DB); + sserr << "Error addFileWithLayoutRange() - unsupported file type for file layout range: "; + sserr << (int)dbFileType; + tsk_error_set_errstr("%s", sserr.str().c_str()); + return TSK_ERR; + } + + //ensure layout ranges are sorted (to generate file name and to be inserted in sequence order) + sort(ranges.begin(), ranges.end()); + + //dome some checking + //ensure there is no overlap and each range has unique byte range + const checkFileLayoutRangeOverlap & overlapRes = + for_each(ranges.begin(), ranges.end(), checkFileLayoutRangeOverlap(ranges)); + if (overlapRes.getHasOverlap()) { + tsk_error_reset(); + tsk_error_set_errno(TSK_ERR_AUTO_DB); + tsk_error_set_errstr("Error addFileWithLayoutRange() - overlap detected between ranges"); + return TSK_ERR; + } + + //construct filename with parent obj id, start byte of first range, end byte of last range + fileNameSs << "_" << parentObjId << "_" << ranges[0].byteStart; + fileNameSs << "_" << (ranges[numRanges - 1].byteStart + ranges[numRanges - 1].byteLen); + + jstring namej = m_jniEnv->NewStringUTF(fileNameSs.str().c_str()); + + // Insert into tsk files and tsk objects + jlong objIdj = m_jniEnv->CallLongMethod(m_javaDbObj, m_addLayoutFileMethodID, + parentObjId, fsObjId, dataSourceObjId, dbFileType, namej, size); + objId = (int64_t)objIdj; + + if (objId < 0) { + return TSK_ERR; + } + + // Fill in fileObjId and insert ranges + for (vector::iterator it = ranges.begin(); + it != ranges.end(); ++it) { + TSK_DB_FILE_LAYOUT_RANGE & range = *it; + range.fileObjId = objId; + if (-1 == m_jniEnv->CallLongMethod(m_javaDbObj, m_addLayoutFileRangeMethodID, + objId, range.byteStart, range.byteLen, (uint64_t)range.sequence)) { + return TSK_ERR; + } + } + + return TSK_OK; +} + +/** +* Adds information about a unallocated file with layout ranges into the database. +* Adds a single entry to tsk_files table with an auto-generated file name, tsk_objects table, and one or more entries to tsk_file_layout table +* @param parentObjId Id of the parent object in the database (fs, volume, or image) +* @param fsObjId parent fs, or NULL if the file is not associated with fs +* @param size Number of bytes in file +* @param ranges vector containing one or more TSK_DB_FILE_LAYOUT_RANGE layout ranges (in) +* @param objId object id of the file object created (output) +* @param dataSourceObjId The object ID for the data source +* @returns TSK_OK on success or TSK_ERR on error. +*/ +TSK_RETVAL_ENUM +TskAutoDbJava::addUnallocBlockFile(const int64_t parentObjId, const int64_t fsObjId, const uint64_t size, + vector& ranges, int64_t& objId, + int64_t dataSourceObjId) { + return addFileWithLayoutRange(TSK_DB_FILES_TYPE_UNALLOC_BLOCKS, parentObjId, fsObjId, size, ranges, objId, + dataSourceObjId); +} + +/** +* Adds information about a unused file with layout ranges into the database. +* Adds a single entry to tsk_files table with an auto-generated file name, tsk_objects table, and one or more entries to tsk_file_layout table +* @param parentObjId Id of the parent object in the database (fs, volume, or image) +* @param fsObjId parent fs, or NULL if the file is not associated with fs +* @param size Number of bytes in file +* @param ranges vector containing one or more TSK_DB_FILE_LAYOUT_RANGE layout ranges (in) +* @param objId object id of the file object created (output) +* @param dataSourceObjId The object ID for the data source +* @returns TSK_OK on success or TSK_ERR on error. +*/ +TSK_RETVAL_ENUM +TskAutoDbJava::addUnusedBlockFile(const int64_t parentObjId, const int64_t fsObjId, const uint64_t size, + vector& ranges, int64_t& objId, + int64_t dataSourceObjId) { + return addFileWithLayoutRange(TSK_DB_FILES_TYPE_UNUSED_BLOCKS, parentObjId, fsObjId, size, ranges, objId, + dataSourceObjId); +} + + + +/** +* Add a virtual dir to hold unallocated block files for this file system. +* @param fsObjId Object ID of the file system +* @param objId Object ID of the created virtual dir +* @param dataSourceObjId Object ID of the data source +*/ +TSK_RETVAL_ENUM +TskAutoDbJava::addUnallocFsBlockFilesParent(const int64_t fsObjId, int64_t& objId, + int64_t dataSourceObjId) { + + const char * const unallocDirName = "$Unalloc"; + jstring namej = m_jniEnv->NewStringUTF(unallocDirName); + + jlong objIdj = m_jniEnv->CallLongMethod(m_javaDbObj, m_addUnallocParentMethodID, + fsObjId, namej); + objId = (int64_t)objIdj; + + if (objId < 0) { + return TSK_ERR; + } + return TSK_OK; +} + +/** +* Adds a new volume that will hold the unallocated blocks for the pool. +* +* @param vol_index The index for the new volume (should be one higher than the number of pool volumes) +* @param parObjId The object ID of the parent volume system +* @param objId Will be set to the object ID of the new volume +* +* @returns TSK_ERR on error, TSK_OK on success +*/ +TSK_RETVAL_ENUM +TskAutoDbJava::addUnallocatedPoolVolume(int vol_index, int64_t parObjId, int64_t& objId) +{ + const char *desc = "Unallocated Blocks"; + jstring descj = m_jniEnv->NewStringUTF(desc); + + jlong objIdj = m_jniEnv->CallLongMethod(m_javaDbObj, m_addVolumeMethodID, + parObjId, vol_index, 0, 0, + descj, 0); + objId = (int64_t)objIdj; + + if (objId < 0) { + return TSK_ERR; + } + return TSK_OK; +} + +void TskAutoDbJava::close() { + if (m_jniEnv == NULL) { + return; + } + + if (m_javaDbObj != NULL) { + m_jniEnv->DeleteGlobalRef(m_javaDbObj); + } + + if (m_callbackClass != NULL) { + m_jniEnv->DeleteGlobalRef(m_callbackClass); + } +} + +int64_t TskAutoDbJava::getImageID() { + return m_curImgId; +} + +void TskAutoDbJava::closeImage() { + TskAuto::closeImage(); +} + +void TskAutoDbJava::setAddFileSystems(bool addFileSystems) { + m_addFileSystems = addFileSystems; +} + +void TskAutoDbJava::setNoFatFsOrphans(bool noFatFsOrphans) { + m_noFatFsOrphans = noFatFsOrphans; +} + +void TskAutoDbJava::setAddUnallocSpace(bool addUnallocSpace) { + setAddUnallocSpace(addUnallocSpace, -1); +} + +void TskAutoDbJava::setAddUnallocSpace(bool addUnallocSpace, int64_t minChunkSize) { + m_addUnallocSpace = addUnallocSpace; + m_minChunkSize = minChunkSize; + m_maxChunkSize = -1; +} + +void TskAutoDbJava::setAddUnallocSpace(int64_t minChunkSize, int64_t maxChunkSize) { + m_addUnallocSpace = true; + m_minChunkSize = minChunkSize; + m_maxChunkSize = maxChunkSize; +} + +/** + * Adds an image to the database. + * + * @param a_num Number of image parts + * @param a_images Array of paths to the image parts + * @param a_type Image type + * @param a_ssize Size of device sector in bytes (or 0 for default) + * @param a_deviceId An ASCII-printable identifier for the device associated with the data source that is intended to be unique across multiple cases (e.g., a UUID). + * @return 0 for success, 1 for failure + */ +uint8_t + TskAutoDbJava::openImageUtf8(int a_num, const char *const a_images[], + TSK_IMG_TYPE_ENUM a_type, unsigned int a_ssize, const char* a_deviceId) +{ + uint8_t retval = + TskAuto::openImageUtf8(a_num, a_images, a_type, a_ssize); + if (retval != 0) { + return retval; + } + + if (addImageDetails(a_deviceId)) { + return 1; + } + return 0; +} + +/** + * Adds an image to the database. + * + * @param a_num Number of image parts + * @param a_images Array of paths to the image parts + * @param a_type Image type + * @param a_ssize Size of device sector in bytes (or 0 for default) + * @param a_deviceId An ASCII-printable identifier for the device associated with the data source that is intended to be unique across multiple cases (e.g., a UUID). + * @return 0 for success, 1 for failure + */ +uint8_t + TskAutoDbJava::openImage(int a_num, const TSK_TCHAR * const a_images[], + TSK_IMG_TYPE_ENUM a_type, unsigned int a_ssize, const char* a_deviceId) +{ + +#ifdef TSK_WIN32 + + uint8_t retval = TskAuto::openImage(a_num, a_images, a_type, a_ssize); + + if (retval != 0) { + return retval; + } + + return (addImageDetails(a_deviceId)); +#else + return openImageUtf8(a_num, a_images, a_type, a_ssize, a_deviceId); +#endif +} + +/** +* Adds an image to the database. Requires that m_img_info is already initialized +* +* @param a_deviceId An ASCII-printable identifier for the device associated with the data source that is intended to be unique across multiple cases (e.g., a UUID). +* @return 0 for success, 1 for failure +*/ +uint8_t +TskAutoDbJava::openImage(const char* a_deviceId) +{ + if (m_img_info == NULL) { + return 1; + } + + return(addImageDetails(a_deviceId)); +} + +/** + * Adds image details to the existing database tables. + * + * @param deviceId An ASCII-printable identifier for the device associated with the data source that is intended to be unique across multiple cases (e.g., a UUID). + * @return Returns 0 for success, 1 for failure + */ +uint8_t +TskAutoDbJava::addImageDetails(const char* deviceId) +{ + string md5 = ""; + string sha1 = ""; + string collectionDetails = ""; +#if HAVE_LIBEWF + if (m_img_info->itype == TSK_IMG_TYPE_EWF_EWF) { + // @@@ This should really probably be inside of a tsk_img_ method + IMG_EWF_INFO *ewf_info = (IMG_EWF_INFO *)m_img_info; + if (ewf_info->md5hash_isset) { + md5 = ewf_info->md5hash; + } + if (ewf_info->sha1hash_isset) { + sha1 = ewf_info->sha1hash; + } + + collectionDetails = ewf_get_details(ewf_info); + } +#endif + + // If the image has already been added to the database, update the acquisition details and return. + if (m_curImgId > 0) { + addAcquisitionDetails(m_curImgId, collectionDetails); + return 0; + } + + string devId; + if (NULL != deviceId) { + devId = deviceId; + } else { + devId = ""; + } + + char **img_ptrs; +#ifdef TSK_WIN32 + // convert image paths to UTF-8 + img_ptrs = (char **)tsk_malloc(m_img_info->num_img * sizeof(char *)); + if (img_ptrs == NULL) { + return 1; + } + + for (int i = 0; i < m_img_info->num_img; i++) { + char * img2 = (char*)tsk_malloc(1024 * sizeof(char)); + UTF8 *ptr8; + UTF16 *ptr16; + + ptr8 = (UTF8 *)img2; + ptr16 = (UTF16 *)m_img_info->images[i]; + + uint8_t retval = + tsk_UTF16toUTF8_lclorder((const UTF16 **)&ptr16, (UTF16 *) + & ptr16[TSTRLEN(m_img_info->images[i]) + 1], &ptr8, + (UTF8 *)((uintptr_t)ptr8 + 1024), TSKlenientConversion); + if (retval != TSKconversionOK) { + tsk_error_reset(); + tsk_error_set_errno(TSK_ERR_AUTO_UNICODE); + tsk_error_set_errstr("Error converting image to UTF-8\n"); + return 1; + } + img_ptrs[i] = img2; + } +#else + img_ptrs = m_img_info->images; +#endif + + + if (TSK_OK != addImageInfo(m_img_info->itype, m_img_info->sector_size, + m_curImgId, m_curImgTZone, m_img_info->size, md5, sha1, "", devId, collectionDetails, + img_ptrs, m_img_info->num_img)) { + registerError(); + return 1; + } + +#ifdef TSK_WIN32 + //cleanup + for (int i = 0; i < m_img_info->num_img; ++i) { + free(img_ptrs[i]); + } + free(img_ptrs); +#endif + + return 0; +} + + +TSK_FILTER_ENUM +TskAutoDbJava::filterVs(const TSK_VS_INFO * vs_info) +{ + m_vsFound = true; + if (TSK_OK != addVsInfo(vs_info, m_curImgId, m_curVsId)) { + registerError(); + return TSK_FILTER_STOP; + } + + return TSK_FILTER_CONT; +} + +TSK_FILTER_ENUM +TskAutoDbJava::filterPool(const TSK_POOL_INFO * pool_info) +{ + m_poolFound = true; + + if (m_volFound && m_vsFound) { + // there's a volume system and volume + if (TSK_OK != addPoolInfoAndVS(pool_info, m_curVolId, m_curPoolVs)) { + registerError(); + return TSK_FILTER_STOP; + } + // Save the parent obj ID for the pool + m_poolOffsetToParentId[pool_info->img_offset] = m_curVolId; + } + else { + // pool doesn't live in a volume, use image as parent + if (TSK_OK != addPoolInfoAndVS(pool_info, m_curImgId, m_curPoolVs)) { + registerError(); + return TSK_FILTER_STOP; + } + // Save the parent obj ID for the pool + m_poolOffsetToParentId[pool_info->img_offset] = m_curImgId; + } + + // Store the volume system object ID for later use + m_poolOffsetToVsId[pool_info->img_offset] = m_curPoolVs; + + return TSK_FILTER_CONT; +} + +/** +* Adds unallocated pool blocks to a new volume. +* +* @param numPool Will be updated with the number of pools processed +* +* @return Returns 0 for success, 1 for failure +*/ +TSK_RETVAL_ENUM +TskAutoDbJava::addUnallocatedPoolBlocksToDb(size_t & numPool) { + + for (size_t i = 0; i < m_poolInfos.size(); i++) { + const TSK_POOL_INFO * pool_info = m_poolInfos[i]; + if (m_poolOffsetToVsId.find(pool_info->img_offset) == m_poolOffsetToVsId.end()) { + tsk_error_reset(); + tsk_error_set_errno(TSK_ERR_AUTO_DB); + tsk_error_set_errstr("Error addUnallocatedPoolBlocksToDb() - could not find volume system object ID for pool at offset %lld", pool_info->img_offset); + return TSK_ERR; + } + int64_t curPoolVs = m_poolOffsetToVsId[pool_info->img_offset]; + + /* Make sure the pool_info is still allocated */ + if (pool_info->tag != TSK_POOL_INFO_TAG) { + tsk_error_reset(); + tsk_error_set_errno(TSK_ERR_AUTO_DB); + tsk_error_set_errstr("Error addUnallocatedPoolBlocksToDb() - pool_info is not allocated"); + return TSK_ERR; + } + + /* Only APFS pools are currently supported */ + if (pool_info->ctype != TSK_POOL_TYPE_APFS) { + continue; + } + + /* Increment the count of pools found */ + numPool++; + + /* Create the volume */ + int64_t unallocVolObjId; + if (TSK_ERR == addUnallocatedPoolVolume(pool_info->num_vols, curPoolVs, unallocVolObjId)) { + tsk_error_reset(); + tsk_error_set_errno(TSK_ERR_AUTO_DB); + tsk_error_set_errstr("Error addUnallocatedPoolBlocksToDb() - error createing unallocated space pool volume"); + return TSK_ERR; + } + + /* Create the unallocated space files */ + TSK_FS_ATTR_RUN * unalloc_runs = tsk_pool_unallocated_runs(pool_info); + TSK_FS_ATTR_RUN * current_run = unalloc_runs; + vector ranges; + while (current_run != NULL) { + + TSK_DB_FILE_LAYOUT_RANGE tempRange(current_run->addr * pool_info->block_size, current_run->len * pool_info->block_size, 0); + + ranges.push_back(tempRange); + int64_t fileObjId = 0; + if (TSK_ERR == addUnallocBlockFile(unallocVolObjId, 0, current_run->len * pool_info->block_size, ranges, fileObjId, m_curImgId)) { + registerError(); + tsk_fs_attr_run_free(unalloc_runs); + return TSK_ERR; + } + + current_run = current_run->next; + ranges.clear(); + } + tsk_fs_attr_run_free(unalloc_runs); + } + + return TSK_OK; +} + +TSK_FILTER_ENUM +TskAutoDbJava::filterPoolVol(const TSK_POOL_VOLUME_INFO * pool_vol) +{ + + if (TSK_OK != addPoolVolumeInfo(pool_vol, m_curPoolVs, m_curPoolVol)) { + registerError(); + return TSK_FILTER_STOP; + } + + return TSK_FILTER_CONT; +} + +TSK_FILTER_ENUM +TskAutoDbJava::filterVol(const TSK_VS_PART_INFO * vs_part) +{ + m_volFound = true; + m_foundStructure = true; + m_poolFound = false; + + if (TSK_OK != addVolumeInfo(vs_part, m_curVsId, m_curVolId)) { + registerError(); + return TSK_FILTER_STOP; + } + + return TSK_FILTER_CONT; +} + + +TSK_FILTER_ENUM +TskAutoDbJava::filterFs(TSK_FS_INFO * fs_info) +{ + TSK_FS_FILE *file_root; + m_foundStructure = true; + + if (m_poolFound) { + // there's a pool + if (TSK_OK != addFsInfo(fs_info, m_curPoolVol, m_curFsId)) { + registerError(); + return TSK_FILTER_STOP; + } + } + else if (m_volFound && m_vsFound) { + // there's a volume system and volume + if (TSK_OK != addFsInfo(fs_info, m_curVolId, m_curFsId)) { + registerError(); + return TSK_FILTER_STOP; + } + } + else { + // file system doesn't live in a volume, use image as parent + if (TSK_OK != addFsInfo(fs_info, m_curImgId, m_curFsId)) { + registerError(); + return TSK_FILTER_STOP; + } + } + + + // We won't hit the root directory on the walk, so open it now + if ((file_root = tsk_fs_file_open(fs_info, NULL, "/")) != NULL) { + processFile(file_root, ""); + tsk_fs_file_close(file_root); + file_root = NULL; + } + + + // make sure that flags are set to get all files -- we need this to + // find parent directory + + TSK_FS_DIR_WALK_FLAG_ENUM filterFlags = (TSK_FS_DIR_WALK_FLAG_ENUM) + (TSK_FS_DIR_WALK_FLAG_ALLOC | TSK_FS_DIR_WALK_FLAG_UNALLOC); + + //check if to skip processing of FAT orphans + if (m_noFatFsOrphans + && TSK_FS_TYPE_ISFAT(fs_info->ftype) ) { + filterFlags = (TSK_FS_DIR_WALK_FLAG_ENUM) (filterFlags | TSK_FS_DIR_WALK_FLAG_NOORPHAN); + } + + setFileFilterFlags(filterFlags); + + return TSK_FILTER_CONT; +} + +/* Insert the file data into the file table. + * @param fs_file + * @param fs_attr + * @param path + * Returns TSK_ERR on error. + */ +TSK_RETVAL_ENUM + TskAutoDbJava::insertFileData(TSK_FS_FILE * fs_file, + const TSK_FS_ATTR * fs_attr, const char *path) +{ + if (TSK_ERR == addFsFile(fs_file, fs_attr, path, m_curFsId, m_curFileId, + m_curImgId)) { + registerError(); + return TSK_ERR; + } + + return TSK_OK; +} + +/** + * Analyzes the open image and adds image info to a database. + * Does not deal with transactions and such. Refer to startAddImage() + * for more control. + * @returns 1 if a critical error occurred (DB doesn't exist, no file system, etc.), 2 if errors occurred at some point adding files to the DB (corrupt file, etc.), and 0 otherwise. Errors will have been registered. + */ +uint8_t TskAutoDbJava::addFilesInImgToDb() +{ + // @@@ This seems bad because we are overriding what the user may + // have set. We should remove the public API if we are going to + // override it -- presumably this was added so that we always have + // unallocated volume space... + setVolFilterFlags((TSK_VS_PART_FLAG_ENUM) (TSK_VS_PART_FLAG_ALLOC | + TSK_VS_PART_FLAG_UNALLOC)); + + uint8_t retVal = 0; + if (findFilesInImg()) { + // map the boolean return value from findFiles to the three-state return value we use + // @@@ findFiles should probably return this three-state enum too + if (m_foundStructure == false) { + retVal = 1; + } + else { + retVal = 2; + } + } + + TSK_RETVAL_ENUM addUnallocRetval = TSK_OK; + if (m_addUnallocSpace) + addUnallocRetval = addUnallocSpaceToDb(); + + // findFiles return value trumps unalloc since it can return either 2 or 1. + if (retVal) { + return retVal; + } + else if (addUnallocRetval == TSK_ERR) { + return 2; + } + else { + return 0; + } +} + + +/** + * Start the process to add image/file metadata to database inside of a transaction. + * User must call either commitAddImage() to commit the changes, + * or revertAddImage() to revert them. + * + * @param numImg Number of image parts + * @param imagePaths Array of paths to the image parts + * @param imgType Image type + * @param sSize Size of device sector in bytes (or 0 for default) + * @param deviceId An ASCII-printable identifier for the device associated with the data source that is intended to be unique across multiple cases (e.g., a UUID) + * @return 0 for success, 1 for failure + */ +uint8_t + TskAutoDbJava::startAddImage(int numImg, const TSK_TCHAR * const imagePaths[], + TSK_IMG_TYPE_ENUM imgType, unsigned int sSize, const char* deviceId) +{ + if (tsk_verbose) + tsk_fprintf(stderr, "TskAutoDbJava::startAddImage: Starting add image process\n"); + + if (openImage(numImg, imagePaths, imgType, sSize, deviceId)) { + tsk_error_set_errstr2("TskAutoDbJava::startAddImage"); + registerError(); + return 1; + } + + if (m_imageWriterEnabled) { + tsk_img_writer_create(m_img_info, m_imageWriterPath); + } + + if (m_addFileSystems) { + return addFilesInImgToDb(); + } else { + return 0; + } +} + +/** +* Start the process to add image/file metadata to database inside of a transaction. +* User must call either commitAddImage() to commit the changes, +* or revertAddImage() to revert them. +* +* @param img_info Previously initialized TSK_IMG_INFO object +* @param deviceId An ASCII-printable identifier for the device associated with the data source that is intended to be unique across multiple cases (e.g., a UUID) +* @return 0 for success, 1 for failure +*/ +uint8_t +TskAutoDbJava::startAddImage(TSK_IMG_INFO * img_info, const char* deviceId) +{ + openImageHandle(img_info); + + if (m_img_info == NULL) { + return 1; + } + + if (tsk_verbose) + tsk_fprintf(stderr, "TskAutoDbJava::startAddImage: Starting add image process\n"); + + if (openImage(deviceId)) { + tsk_error_set_errstr2("TskAutoDbJava::startAddImage"); + registerError(); + return 1; + } + + if (m_imageWriterEnabled) { + if (tsk_img_writer_create(m_img_info, m_imageWriterPath)) { + registerError(); + return 1; + } + } + + if (m_addFileSystems) { + return addFilesInImgToDb(); + } + else { + return 0; + } +} + + +#ifdef WIN32 +/** + * Start the process to add image/file metadata to database inside of a transaction. + * Same functionality as addFilesInImgToDb(). Reverts + * all changes on error. User must call either commitAddImage() to commit the changes, + * or revertAddImage() to revert them. + * + * @param numImg Number of image parts + * @param imagePaths Array of paths to the image parts + * @param imgType Image type + * @param sSize Size of device sector in bytes (or 0 for default) + * @param deviceId An ASCII-printable identifier for the device associated with the data source that is intended to be unique across multiple cases (e.g., a UUID) + * @return 0 for success 1, for failure + */ +uint8_t + TskAutoDbJava::startAddImage(int numImg, const char *const imagePaths[], + TSK_IMG_TYPE_ENUM imgType, unsigned int sSize, const char* deviceId) +{ + if (tsk_verbose) + tsk_fprintf(stderr, "TskAutoDbJava::startAddImage_utf8: Starting add image process\n"); + + if (openImageUtf8(numImg, imagePaths, imgType, sSize, deviceId)) { + tsk_error_set_errstr2("TskAutoDbJava::startAddImage"); + registerError(); + return 1; + } + if (m_imageWriterEnabled) { + tsk_img_writer_create(m_img_info, m_imageWriterPath); + } + + if (m_addFileSystems) { + return addFilesInImgToDb(); + } else { + return 0; + } +} +#endif + + +/** + * Cancel the running process. Will not be handled immediately. + */ +void + TskAutoDbJava::stopAddImage() +{ + if (tsk_verbose) + tsk_fprintf(stderr, "TskAutoDbJava::stopAddImage: Stop request received\n"); + + m_stopped = true; + setStopProcessing(); + // flag is checked every time processFile() is called +} + +/** + * Set the current image's timezone + */ +void +TskAutoDbJava::setTz(string tzone) +{ + m_curImgTZone = tzone; +} + +/** + * Set the object ID for the data source + */ +void +TskAutoDbJava::setDatasourceObjId(int64_t img_id) +{ + m_curImgId = img_id; +} + +TSK_RETVAL_ENUM +TskAutoDbJava::processFile(TSK_FS_FILE * fs_file, const char *path) +{ + // Check if the process has been canceled + if (m_stopped) { + if (tsk_verbose) + tsk_fprintf(stderr, "TskAutoDbJava::processFile: Stop request detected\n"); + return TSK_STOP; + } + + /* Update the current directory, which can be used to show + * progress. If we get a directory, then use its name. We + * do this so that when we are searching for orphan files, then + * we at least show $OrphanFiles as status. The secondary check + * is to grab the parent folder from files once we return back + * into a folder when we are doing our depth-first recursion. */ + if (isDir(fs_file)) { + m_curDirAddr = fs_file->name->meta_addr; + tsk_take_lock(&m_curDirPathLock); + m_curDirPath = string(path) + fs_file->name->name; + tsk_release_lock(&m_curDirPathLock); + } + else if (m_curDirAddr != fs_file->name->par_addr) { + m_curDirAddr = fs_file->name->par_addr; + tsk_take_lock(&m_curDirPathLock); + m_curDirPath = path; + tsk_release_lock(&m_curDirPathLock); + } + + /* process the attributes. The case of having 0 attributes can occur + * with virtual / sparse files and HFS directories. + * At some point, this can probably be cleaned + * up if TSK is more consistent about if there should always be an + * attribute or not. Sometimes, none of the attributes are added + * because of their type and we always want to add a reference to + * every file. */ + TSK_RETVAL_ENUM retval = TSK_OK; + m_attributeAdded = false; + if (tsk_fs_file_attr_getsize(fs_file) > 0) { + retval = processAttributes(fs_file, path); + } + + // insert a general row if we didn't add a specific attribute one + if ((retval == TSK_OK) && (m_attributeAdded == false)) { + retval = insertFileData(fs_file, NULL, path); + } + + // reset the file id + m_curFileId = 0; + + if (retval == TSK_STOP) + return TSK_STOP; + else + return TSK_OK; +} + + +// we return only OK or STOP -- errors are registered only and OK is returned. +TSK_RETVAL_ENUM +TskAutoDbJava::processAttribute(TSK_FS_FILE * fs_file, + const TSK_FS_ATTR * fs_attr, const char *path) +{ + // add the file metadata for the default attribute type + if (isDefaultType(fs_file, fs_attr)) { + + if (insertFileData(fs_attr->fs_file, fs_attr, path) == TSK_ERR) { + registerError(); + return TSK_OK; + } + else { + m_attributeAdded = true; + } + } + + return TSK_OK; +} + + +/** +* Callback invoked per every unallocated block in the filesystem +* Creates file ranges and file entries +* A single file entry per consecutive range of blocks +* @param a_block block being walked +* @param a_ptr a pointer to an UNALLOC_BLOCK_WLK_TRACK struct +* @returns TSK_WALK_CONT if continue, otherwise TSK_WALK_STOP if stop processing requested +*/ +TSK_WALK_RET_ENUM TskAutoDbJava::fsWalkUnallocBlocksCb(const TSK_FS_BLOCK *a_block, void *a_ptr) { + UNALLOC_BLOCK_WLK_TRACK * unallocBlockWlkTrack = (UNALLOC_BLOCK_WLK_TRACK *) a_ptr; + + if (unallocBlockWlkTrack->tskAutoDbJava.m_stopAllProcessing) + return TSK_WALK_STOP; + + // initialize if this is the first block + if (unallocBlockWlkTrack->isStart) { + unallocBlockWlkTrack->isStart = false; + unallocBlockWlkTrack->curRangeStart = a_block->addr; + unallocBlockWlkTrack->prevBlock = a_block->addr; + unallocBlockWlkTrack->size = unallocBlockWlkTrack->fsInfo.block_size; + unallocBlockWlkTrack->nextSequenceNo = 0; + return TSK_WALK_CONT; + } + + // We want to keep consecutive blocks in the same run, so simply update prevBlock and the size + // if this one is consecutive with the last call. But, if we have hit the max chunk + // size, then break up this set of consecutive blocks. + if ((a_block->addr == unallocBlockWlkTrack->prevBlock + 1) && ((unallocBlockWlkTrack->maxChunkSize <= 0) || + (unallocBlockWlkTrack->size < unallocBlockWlkTrack->maxChunkSize))) { + unallocBlockWlkTrack->prevBlock = a_block->addr; + unallocBlockWlkTrack->size += unallocBlockWlkTrack->fsInfo.block_size; + return TSK_WALK_CONT; + } + + // this block is not contiguous with the previous one or we've hit the maximum size; create and add a range object + const uint64_t rangeStartOffset = unallocBlockWlkTrack->curRangeStart * unallocBlockWlkTrack->fsInfo.block_size + + unallocBlockWlkTrack->fsInfo.offset; + const uint64_t rangeSizeBytes = (1 + unallocBlockWlkTrack->prevBlock - unallocBlockWlkTrack->curRangeStart) + * unallocBlockWlkTrack->fsInfo.block_size; + unallocBlockWlkTrack->ranges.push_back(TSK_DB_FILE_LAYOUT_RANGE(rangeStartOffset, rangeSizeBytes, unallocBlockWlkTrack->nextSequenceNo++)); + + // Return (instead of adding this run) if we are going to: + // a) Make one big file with all unallocated space (minChunkSize == 0) + // or + // b) Only make an unallocated file once we have at least chunkSize bytes + // of data in our current run (minChunkSize > 0) + // In either case, reset the range pointers and add this block to the size + if ((unallocBlockWlkTrack->minChunkSize == 0) || + ((unallocBlockWlkTrack->minChunkSize > 0) && + (unallocBlockWlkTrack->size < unallocBlockWlkTrack->minChunkSize))) { + + unallocBlockWlkTrack->size += unallocBlockWlkTrack->fsInfo.block_size; + unallocBlockWlkTrack->curRangeStart = a_block->addr; + unallocBlockWlkTrack->prevBlock = a_block->addr; + return TSK_WALK_CONT; + } + + // at this point we are either chunking and have reached the chunk limit + // or we're not chunking. Either way we now add what we've got to the DB + int64_t fileObjId = 0; + TskAutoDbJava & tskAutoDbJava = unallocBlockWlkTrack->tskAutoDbJava; + if (tskAutoDbJava.addUnallocBlockFile(tskAutoDbJava.m_curUnallocDirId, + unallocBlockWlkTrack->fsObjId, unallocBlockWlkTrack->size, unallocBlockWlkTrack->ranges, fileObjId, tskAutoDbJava.m_curImgId) == TSK_ERR) { + // @@@ Handle error -> Don't have access to registerError() though... + } + + // reset + unallocBlockWlkTrack->curRangeStart = a_block->addr; + unallocBlockWlkTrack->prevBlock = a_block->addr; + unallocBlockWlkTrack->size = unallocBlockWlkTrack->fsInfo.block_size; // The current block is part of the new range + unallocBlockWlkTrack->ranges.clear(); + unallocBlockWlkTrack->nextSequenceNo = 0; + + //we don't know what the last unalloc block is in advance + //and will handle the last range in addFsInfoUnalloc() + + return TSK_WALK_CONT; +} + + +/** +* Add unallocated space for the given file system to the database. +* Create files for consecutive unalloc block ranges. +* @param dbFsInfo fs to process +* @returns TSK_OK on success, TSK_ERR on error +*/ +TSK_RETVAL_ENUM TskAutoDbJava::addFsInfoUnalloc(const TSK_DB_FS_INFO & dbFsInfo) { + + // Unalloc space is handled separately for APFS + if (dbFsInfo.fType == TSK_FS_TYPE_APFS) { + return TSK_OK; + } + + //open the fs we have from database + TSK_FS_INFO * fsInfo = tsk_fs_open_img(m_img_info, dbFsInfo.imgOffset, dbFsInfo.fType); + if (fsInfo == NULL) { + tsk_error_set_errstr2("TskAutoDbJava::addFsInfoUnalloc: error opening fs at offset %" PRIdOFF, dbFsInfo.imgOffset); + registerError(); + return TSK_ERR; + } + + //create a "fake" dir to hold the unalloc files for the fs + if (addUnallocFsBlockFilesParent(dbFsInfo.objId, m_curUnallocDirId, m_curImgId) == TSK_ERR) { + tsk_error_set_errstr2("addFsInfoUnalloc: error creating dir for unallocated space"); + registerError(); + return TSK_ERR; + } + + //walk unalloc blocks on the fs and process them + //initialize the unalloc block walk tracking + UNALLOC_BLOCK_WLK_TRACK unallocBlockWlkTrack(*this, *fsInfo, dbFsInfo.objId, m_minChunkSize, m_maxChunkSize); + uint8_t block_walk_ret = tsk_fs_block_walk(fsInfo, fsInfo->first_block, fsInfo->last_block, (TSK_FS_BLOCK_WALK_FLAG_ENUM)(TSK_FS_BLOCK_WALK_FLAG_UNALLOC | TSK_FS_BLOCK_WALK_FLAG_AONLY), + fsWalkUnallocBlocksCb, &unallocBlockWlkTrack); + + if (block_walk_ret == 1) { + stringstream errss; + tsk_fs_close(fsInfo); + errss << "TskAutoDbJava::addFsInfoUnalloc: error walking fs unalloc blocks, fs id: "; + errss << unallocBlockWlkTrack.fsObjId; + tsk_error_set_errstr2("%s", errss.str().c_str()); + registerError(); + return TSK_ERR; + } + + if(m_stopAllProcessing) { + tsk_fs_close(fsInfo); + return TSK_OK; + } + + // handle creation of the last range + // make range inclusive from curBlockStart to prevBlock + const uint64_t byteStart = unallocBlockWlkTrack.curRangeStart * fsInfo->block_size + fsInfo->offset; + const uint64_t byteLen = (1 + unallocBlockWlkTrack.prevBlock - unallocBlockWlkTrack.curRangeStart) * fsInfo->block_size; + unallocBlockWlkTrack.ranges.push_back(TSK_DB_FILE_LAYOUT_RANGE(byteStart, byteLen, unallocBlockWlkTrack.nextSequenceNo++)); + int64_t fileObjId = 0; + + if (addUnallocBlockFile(m_curUnallocDirId, dbFsInfo.objId, unallocBlockWlkTrack.size, unallocBlockWlkTrack.ranges, fileObjId, m_curImgId) == TSK_ERR) { + registerError(); + tsk_fs_close(fsInfo); + return TSK_ERR; + } + + //cleanup + tsk_fs_close(fsInfo); + + return TSK_OK; +} + +/** +* Process all unallocated space for this disk image and create "virtual" files with layouts +* @returns TSK_OK on success, TSK_ERR on error +*/ +TSK_RETVAL_ENUM TskAutoDbJava::addUnallocSpaceToDb() { + if (m_stopAllProcessing) { + return TSK_OK; + } + + size_t numVsP = 0; + size_t numFs = 0; + size_t numPool = 0; + + TSK_RETVAL_ENUM retFsSpace = addUnallocFsSpaceToDb(numFs); + TSK_RETVAL_ENUM retVsSpace = addUnallocVsSpaceToDb(numVsP); + TSK_RETVAL_ENUM retPoolSpace = addUnallocatedPoolBlocksToDb(numPool); + + //handle case when no fs and no vs partitions and no pools + TSK_RETVAL_ENUM retImgFile = TSK_OK; + if (numVsP == 0 && numFs == 0 && numPool == 0) { + retImgFile = addUnallocImageSpaceToDb(); + } + + + if (retFsSpace == TSK_ERR || retVsSpace == TSK_ERR || retPoolSpace == TSK_ERR || retImgFile == TSK_ERR) + return TSK_ERR; + else + return TSK_OK; +} + + +/** +* Process each file system in the database and add its unallocated sectors to virtual files. +* @param numFs (out) number of filesystems found +* @returns TSK_OK on success, TSK_ERR on error (if some or all fs could not be processed) +*/ +TSK_RETVAL_ENUM TskAutoDbJava::addUnallocFsSpaceToDb(size_t & numFs) { + + if(m_stopAllProcessing) { + return TSK_OK; + } + + numFs = m_savedFsInfo.size(); + TSK_RETVAL_ENUM allFsProcessRet = TSK_OK; + for (vector::iterator it = m_savedFsInfo.begin(); it!= m_savedFsInfo.end(); ++it) { + if (m_stopAllProcessing) { + break; + } + if (addFsInfoUnalloc(*it) == TSK_ERR) + allFsProcessRet = TSK_ERR; + } + + //TODO set parent_path for newly created virt dir/file hierarchy for consistency + + return allFsProcessRet; +} + +/** +* Process each volume in the database and add its unallocated sectors to virtual files. +* @param numVsP (out) number of vs partitions found +* @returns TSK_OK on success, TSK_ERR on error +*/ +TSK_RETVAL_ENUM TskAutoDbJava::addUnallocVsSpaceToDb(size_t & numVsP) { + + numVsP = m_savedVsPartInfo.size(); + + //get fs infos to see if this vspart has fs + for (vector::const_iterator it = m_savedVsPartInfo.begin(); + it != m_savedVsPartInfo.end(); ++it) { + if (m_stopAllProcessing) { + break; + } + const TSK_DB_VS_PART_INFO &vsPart = *it; + + //interested in unalloc, meta, or alloc and no fs + if ( (vsPart.flags & (TSK_VS_PART_FLAG_UNALLOC | TSK_VS_PART_FLAG_META)) == 0 ) { + //check if vspart has no fs + bool hasFs = false; + for (vector::const_iterator itFs = m_savedFsInfo.begin(); + itFs != m_savedFsInfo.end(); ++itFs) { + const TSK_DB_FS_INFO & fsInfo = *itFs; + + TSK_DB_OBJECT* fsObjInfo = NULL; + if (getObjectInfo(fsInfo.objId, &fsObjInfo) == TSK_ERR ) { + stringstream errss; + errss << "addUnallocVsSpaceToDb: error getting object info for fs from db, objId: " << fsInfo.objId; + tsk_error_set_errstr2("%s", errss.str().c_str()); + registerError(); + return TSK_ERR; + } + + if (fsObjInfo->parObjId == vsPart.objId) { + hasFs = true; + break; + } + } + + if (hasFs == true) { + //skip processing this vspart + continue; + } + + // Check if the volume contains a pool + bool hasPool = false; + for (std::map::iterator iter = m_poolOffsetToParentId.begin(); iter != m_poolOffsetToParentId.end(); ++iter) { + if (iter->second == vsPart.objId) { + hasPool = true; + } + } + if (hasPool) { + // Skip processing this vspart + continue; + } + + } + + // Get sector size and image offset from parent vs info + // Get parent id of this vs part + TSK_DB_OBJECT* vsPartObj = NULL; + if (getObjectInfo(vsPart.objId, &vsPartObj) == TSK_ERR) { + stringstream errss; + errss << "addUnallocVsSpaceToDb: error getting object info for vs part from db, objId: " << vsPart.objId; + tsk_error_set_errstr2("%s", errss.str().c_str()); + registerError(); + return TSK_ERR; + } + if (vsPartObj == NULL) { + return TSK_ERR; + } + + TSK_DB_VS_INFO* vsInfo = NULL; + for (vector::iterator itVs = m_savedVsInfo.begin(); + itVs != m_savedVsInfo.end(); ++itVs) { + TSK_DB_VS_INFO* temp_vs_info = &(*itVs); + if (temp_vs_info->objId == vsPartObj->parObjId) { + vsInfo = temp_vs_info; + } + } + + if (vsInfo == NULL ) { + stringstream errss; + errss << "addUnallocVsSpaceToDb: error getting volume system info from db, objId: " << vsPartObj->parObjId; + tsk_error_set_errstr2("%s", errss.str().c_str()); + registerError(); + return TSK_ERR; + } + + // Create an unalloc file with unalloc part, with vs part as parent + vector ranges; + const uint64_t byteStart = vsInfo->offset + vsInfo->block_size * vsPart.start; + const uint64_t byteLen = vsInfo->block_size * vsPart.len; + TSK_DB_FILE_LAYOUT_RANGE tempRange(byteStart, byteLen, 0); + ranges.push_back(tempRange); + int64_t fileObjId = 0; + if (addUnallocBlockFile(vsPart.objId, 0, tempRange.byteLen, ranges, fileObjId, m_curImgId) == TSK_ERR) { + registerError(); + return TSK_ERR; + } + } + + return TSK_OK; +} + + +/** +* Adds unalloc space for the image if there is no volumes and no file systems. +* +* @returns TSK_OK on success, TSK_ERR on error +*/ +TSK_RETVAL_ENUM TskAutoDbJava::addUnallocImageSpaceToDb() { + + const TSK_OFF_T imgSize = getImageSize(); + if (imgSize == -1) { + tsk_error_set_errstr("addUnallocImageSpaceToDb: error getting current image size, can't create unalloc block file for the image."); + registerError(); + return TSK_ERR; + } + else { + TSK_DB_FILE_LAYOUT_RANGE tempRange(0, imgSize, 0); + //add unalloc block file for the entire image + vector ranges; + ranges.push_back(tempRange); + int64_t fileObjId = 0; + if (TSK_ERR == addUnallocBlockFile(m_curImgId, 0, imgSize, ranges, fileObjId, m_curImgId)) { + return TSK_ERR; + } + } + return TSK_OK; +} + +/** +* Returns the directory currently being analyzed by processFile(). +* Safe to use from another thread than processFile(). +* +* @returns curDirPath string representing currently analyzed directory +*/ +const std::string TskAutoDbJava::getCurDir() { + string curDirPath; + tsk_take_lock(&m_curDirPathLock); + curDirPath = m_curDirPath; + tsk_release_lock(&m_curDirPathLock); + return curDirPath; +} diff --git a/sleuthKitLibs/4.10.1/auto_db_java.h b/sleuthKitLibs/4.10.1/auto_db_java.h new file mode 100644 index 0000000000..b324a71c43 --- /dev/null +++ b/sleuthKitLibs/4.10.1/auto_db_java.h @@ -0,0 +1,240 @@ +/* + ** The Sleuth Kit + ** + ** Brian Carrier [carrier sleuthkit [dot] org] + ** Copyright (c) 2020 Brian Carrier. All Rights reserved + ** + ** This software is distributed under the Common Public License 1.0 + ** + */ + +/** + * \file auto_db_java.h + * Contains the class that creates a case-level database of file system + * data from the JNI code. + */ + +#ifndef _AUTO_DB_JAVA_H +#define _AUTO_DB_JAVA_H + +#include +using std::map; + +#include +using std::string; + +#include "tsk/auto/tsk_auto_i.h" +#include "tsk/auto/tsk_db.h" +#include "jni.h" + + +/** \internal + * C++ class that implements TskAuto to load file metadata into a database. + * This is used by the TskCaseDb class. + */ +class TskAutoDbJava :public TskAuto { + public: + TskAutoDbJava(); + virtual ~TskAutoDbJava(); + virtual uint8_t openImage(int, const TSK_TCHAR * const images[], + TSK_IMG_TYPE_ENUM, unsigned int a_ssize, const char* deviceId = NULL); + virtual uint8_t openImage(const char* a_deviceId = NULL); + virtual uint8_t openImageUtf8(int, const char *const images[], + TSK_IMG_TYPE_ENUM, unsigned int a_ssize, const char* deviceId = NULL); + virtual void closeImage(); + void close(); + virtual void setTz(string tzone); + virtual void setDatasourceObjId(int64_t img_id); + + virtual TSK_FILTER_ENUM filterVs(const TSK_VS_INFO * vs_info); + virtual TSK_FILTER_ENUM filterVol(const TSK_VS_PART_INFO * vs_part); + virtual TSK_FILTER_ENUM filterPool(const TSK_POOL_INFO * pool_info); + virtual TSK_FILTER_ENUM filterPoolVol(const TSK_POOL_VOLUME_INFO * pool_vol); + virtual TSK_FILTER_ENUM filterFs(TSK_FS_INFO * fs_info); + virtual TSK_RETVAL_ENUM processFile(TSK_FS_FILE * fs_file, + const char *path); + const std::string getCurDir(); + + /** + * Sets whether or not the file systems for an image should be added when + * the image is added to the case database. The default value is true. + */ + void setAddFileSystems(bool addFileSystems); + + /** + * Skip processing of orphans on FAT filesystems. + * This will make the loading of the database much faster + * but you will not have all deleted files. Default value is false. + * @param noFatFsOrphans flag set to true if to skip processing orphans on FAT fs + */ + virtual void setNoFatFsOrphans(bool noFatFsOrphans); + + /** + * When enabled, records for unallocated file system space will be added to the database. Default value is false. + * @param addUnallocSpace If true, create records for contiguous unallocated file system sectors. + */ + virtual void setAddUnallocSpace(bool addUnallocSpace); + + /** + * When enabled, records for unallocated file system space will be added to the database. Default value is false. + * @param addUnallocSpace If true, create records for contiguous unallocated file system sectors. + * @param minChunkSize the number of bytes to group unallocated data into. A value of 0 will create + * one large chunk and group only on volume boundaries. A value of -1 will group each consecutive + * chunk. + */ + virtual void setAddUnallocSpace(bool addUnallocSpace, int64_t minChunkSize); + + /** + * When enabled, records for unallocated file system space will be added to the database with the given parameters. + * Automatically sets the flag to create records for contiguous unallocated file system sectors. + * @param minChunkSize the number of bytes to group unallocated data into. A value of 0 will create + * one large chunk and group only on volume boundaries. A value of -1 will group each consecutive + * chunk. + * @param maxChunkSize the maximum number of bytes in one record of unallocated data. A value of -1 will not + * split the records based on size + */ + virtual void setAddUnallocSpace(int64_t minChunkSize, int64_t maxChunkSize); + + uint8_t addFilesInImgToDb(); + + /** + * + */ + uint8_t startAddImage(int numImg, const TSK_TCHAR * const imagePaths[], + TSK_IMG_TYPE_ENUM imgType, unsigned int sSize, const char* deviceId = NULL); + uint8_t startAddImage(TSK_IMG_INFO * img_info, const char* deviceId = NULL); +#ifdef WIN32 + uint8_t startAddImage(int numImg, const char *const imagePaths[], + TSK_IMG_TYPE_ENUM imgType, unsigned int sSize, const char* deviceId = NULL); +#endif + void stopAddImage(); + + int64_t getImageID(); + + TSK_RETVAL_ENUM initializeJni(JNIEnv *, jobject); + + private: + int64_t m_curImgId; ///< Object ID of image currently being processed + int64_t m_curVsId; ///< Object ID of volume system currently being processed + int64_t m_curVolId; ///< Object ID of volume currently being processed + int64_t m_curPoolVol; ///< Object ID of the pool volume currently being processed + int64_t m_curPoolVs; ///< Object ID of the pool volume system currently being processed + int64_t m_curFsId; ///< Object ID of file system currently being processed + int64_t m_curFileId; ///< Object ID of file currently being processed + TSK_INUM_T m_curDirAddr; ///< Meta address the directory currently being processed + int64_t m_curUnallocDirId; + string m_curDirPath; //< Path of the current directory being processed + tsk_lock_t m_curDirPathLock; //< protects concurrent access to m_curDirPath + string m_curImgTZone; + bool m_vsFound; + bool m_volFound; + bool m_poolFound; + bool m_stopped; + bool m_addFileSystems; + bool m_noFatFsOrphans; + bool m_addUnallocSpace; + int64_t m_minChunkSize; ///< -1 for no minimum, 0 for no chunking at all, greater than 0 to wait for that number of chunks before writing to the database + int64_t m_maxChunkSize; ///< Max number of unalloc bytes to process before writing to the database, even if there is no natural break. -1 for no chunking + bool m_foundStructure; ///< Set to true when we find either a volume or file system + bool m_attributeAdded; ///< Set to true when an attribute was added by processAttributes + + // These are used to write unallocated blocks for pools at the end of the add image + // process. We can't load the pool_info objects directly from the database so we will + // store info about them here. + std::map m_poolOffsetToParentId; + std::map m_poolOffsetToVsId; + + // JNI data + JNIEnv * m_jniEnv = NULL; + jclass m_callbackClass = NULL; + jobject m_javaDbObj = NULL; + jmethodID m_addImageMethodID = NULL; + jmethodID m_addImageNameMethodID = NULL; + jmethodID m_addAcquisitionDetailsMethodID = NULL; + jmethodID m_addVolumeSystemMethodID = NULL; + jmethodID m_addVolumeMethodID = NULL; + jmethodID m_addPoolMethodID = NULL; + jmethodID m_addFileSystemMethodID = NULL; + jmethodID m_addFileMethodID = NULL; + jmethodID m_addUnallocParentMethodID = NULL; + jmethodID m_addLayoutFileMethodID = NULL; + jmethodID m_addLayoutFileRangeMethodID = NULL; + + // Cached objects + vector m_savedFsInfo; + vector m_savedVsInfo; + vector m_savedVsPartInfo; + vector m_savedObjects; + + void saveObjectInfo(int64_t objId, int64_t parObjId, TSK_DB_OBJECT_TYPE_ENUM type); + TSK_RETVAL_ENUM getObjectInfo(int64_t objId, TSK_DB_OBJECT** obj_info); + + TSK_RETVAL_ENUM createJString(const char * inputString, jstring & newJString); + + // prevent copying until we add proper logic to handle it + TskAutoDbJava(const TskAutoDbJava&); + TskAutoDbJava & operator=(const TskAutoDbJava&); + + //internal structure to keep track of temp. unalloc block range + typedef struct _UNALLOC_BLOCK_WLK_TRACK { + _UNALLOC_BLOCK_WLK_TRACK(TskAutoDbJava & tskAutoDbJava, const TSK_FS_INFO & fsInfo, const int64_t fsObjId, int64_t minChunkSize, int64_t maxChunkSize) + : tskAutoDbJava(tskAutoDbJava),fsInfo(fsInfo),fsObjId(fsObjId),curRangeStart(0), minChunkSize(minChunkSize), maxChunkSize(maxChunkSize), prevBlock(0), isStart(true), nextSequenceNo(0) {} + TskAutoDbJava & tskAutoDbJava; + const TSK_FS_INFO & fsInfo; + const int64_t fsObjId; + vector ranges; + TSK_DADDR_T curRangeStart; + int64_t size; + const int64_t minChunkSize; + const int64_t maxChunkSize; + TSK_DADDR_T prevBlock; + bool isStart; + uint32_t nextSequenceNo; + } UNALLOC_BLOCK_WLK_TRACK; + + uint8_t addImageDetails(const char *); + TSK_RETVAL_ENUM insertFileData(TSK_FS_FILE * fs_file, + const TSK_FS_ATTR *, const char *path); + virtual TSK_RETVAL_ENUM processAttribute(TSK_FS_FILE *, + const TSK_FS_ATTR * fs_attr, const char *path); + + TSK_RETVAL_ENUM addUnallocatedPoolBlocksToDb(size_t & numPool); + static TSK_WALK_RET_ENUM fsWalkUnallocBlocksCb(const TSK_FS_BLOCK *a_block, void *a_ptr); + TSK_RETVAL_ENUM addFsInfoUnalloc(const TSK_DB_FS_INFO & dbFsInfo); + TSK_RETVAL_ENUM addUnallocFsSpaceToDb(size_t & numFs); + TSK_RETVAL_ENUM addUnallocVsSpaceToDb(size_t & numVsP); + TSK_RETVAL_ENUM addUnallocImageSpaceToDb(); + TSK_RETVAL_ENUM addUnallocSpaceToDb(); + + // JNI methods + TSK_RETVAL_ENUM addImageInfo(int type, TSK_OFF_T ssize, int64_t & objId, const string & timezone, TSK_OFF_T size, const string &md5, + const string& sha1, const string& sha256, const string& deviceId, const string& collectionDetails, char** img_ptrs, int num_imgs); + void addAcquisitionDetails(int64_t imgId, const string& collectionDetails); + TSK_RETVAL_ENUM addVsInfo(const TSK_VS_INFO* vs_info, int64_t parObjId, int64_t& objId); + TSK_RETVAL_ENUM addPoolInfoAndVS(const TSK_POOL_INFO *pool_info, int64_t parObjId, int64_t& objId); + TSK_RETVAL_ENUM addPoolVolumeInfo(const TSK_POOL_VOLUME_INFO* pool_vol, int64_t parObjId, int64_t& objId); + TSK_RETVAL_ENUM addVolumeInfo(const TSK_VS_PART_INFO* vs_part, int64_t parObjId, int64_t& objId); + TSK_RETVAL_ENUM addFsInfo(const TSK_FS_INFO* fs_info, int64_t parObjId, int64_t& objId); + TSK_RETVAL_ENUM addFsFile(TSK_FS_FILE* fs_file, + const TSK_FS_ATTR* fs_attr, const char* path, + int64_t fsObjId, int64_t& objId, int64_t dataSourceObjId); + TSK_RETVAL_ENUM addFile(TSK_FS_FILE* fs_file, + const TSK_FS_ATTR* fs_attr, const char* path, + int64_t fsObjId, int64_t parObjId, + int64_t dataSourceObjId); + TSK_RETVAL_ENUM addFileWithLayoutRange(const TSK_DB_FILES_TYPE_ENUM dbFileType, const int64_t parentObjId, + const int64_t fsObjId, const uint64_t size, + vector& ranges, int64_t& objId, + int64_t dataSourceObjId); + TSK_RETVAL_ENUM addUnallocBlockFile(const int64_t parentObjId, const int64_t fsObjId, const uint64_t size, + vector& ranges, int64_t& objId, + int64_t dataSourceObjId); + TSK_RETVAL_ENUM addUnusedBlockFile(const int64_t parentObjId, const int64_t fsObjId, const uint64_t size, + vector& ranges, int64_t& objId, + int64_t dataSourceObjId); + TSK_RETVAL_ENUM addUnallocFsBlockFilesParent(const int64_t fsObjId, int64_t& objId, int64_t dataSourceObjId); + TSK_RETVAL_ENUM addUnallocatedPoolVolume(int vol_index, int64_t parObjId, int64_t& objId); + +}; + +#endif diff --git a/sleuthKitLibs/4.10.1/auto_db_java.lo b/sleuthKitLibs/4.10.1/auto_db_java.lo new file mode 100644 index 0000000000..8c0a93cf6c --- /dev/null +++ b/sleuthKitLibs/4.10.1/auto_db_java.lo @@ -0,0 +1,12 @@ +# auto_db_java.lo - a libtool object file +# Generated by libtool (GNU libtool) 2.5.4 +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# Name of the PIC object. +pic_object='.libs/auto_db_java.o' + +# Name of the non-PIC object +non_pic_object='auto_db_java.o' + diff --git a/sleuthKitLibs/4.10.1/auto_db_java.o b/sleuthKitLibs/4.10.1/auto_db_java.o new file mode 100644 index 0000000000..19af499f4c Binary files /dev/null and b/sleuthKitLibs/4.10.1/auto_db_java.o differ diff --git a/sleuthKitLibs/4.10.1/dataModel_SleuthkitJNI.cpp b/sleuthKitLibs/4.10.1/dataModel_SleuthkitJNI.cpp new file mode 100644 index 0000000000..f4da3b4b62 --- /dev/null +++ b/sleuthKitLibs/4.10.1/dataModel_SleuthkitJNI.cpp @@ -0,0 +1,2353 @@ +/* + ** dataModel_SleuthkitJNI + ** The Sleuth Kit + ** + ** Brian Carrier [carrier sleuthkit [dot] org] + ** Copyright (c) 2010-2018 Brian Carrier. All Rights reserved + ** + ** This software is distributed under the Common Public License 1.0 + ** + */ +#include "tsk/tsk_tools_i.h" +#include "tsk/auto/tsk_case_db.h" +#include "tsk/hashdb/tsk_hash_info.h" +#include "tsk/auto/tsk_is_image_supported.h" +#include "tsk/img/img_writer.h" +#include "tsk/img/raw.h" +#include "auto_db_java.h" +#if HAVE_LIBEWF +#include "tsk/img/ewf.h" +#include "tsk/img/tsk_img_i.h" +#endif +#include "jni.h" +#include "dataModel_SleuthkitJNI.h" +#include +#include +#include +#include +#include +#include +#include + +using std::string; +using std::vector; +using std::map; +using std::stringstream; + +static std::vector hashDbs; + +/* +* JNI file handle structure encapsulates both +* TSK_FS_FILE file handle and TSK_FS_ATTR attribute +* to support multiple attributes for the same file. +* TSK_FS_FILE still needs be maintained for opening and closing. +*/ +typedef struct { + uint32_t tag; + TSK_FS_FILE *fs_file; + TSK_FS_ATTR *fs_attr; +} TSK_JNI_FILEHANDLE; +#define TSK_JNI_FILEHANDLE_TAG 0x10101214 + +//stack-allocated buffer size for read method +#define FIXED_BUF_SIZE (16 * 1024) + +/** +* Sets flag to throw an TskCoreException back up to the Java code with a specific message. +* Note: exception is thrown to Java code after the native function returns +* not when setThrowTskCoreError() is invoked - this must be addressed in the code following the exception +* @param the java environment to send the exception to +* @param msg message string + */ +static void +setThrowTskCoreError(JNIEnv * env, const char *msg) +{ + jclass exception; + exception = env->FindClass("org/sleuthkit/datamodel/TskCoreException"); + env->ThrowNew(exception, msg); +} + +/** +* Sets flag to throw an TskCoreException back up to the Java code with the currently set error message. +* Note: exception is thrown to Java code after the native function returns +* not when setThrowTskCoreError() is invoked - this must be addressed in the code following the exception +* @param the java environment to send the exception to +*/ +static void +setThrowTskCoreError(JNIEnv * env) +{ + const char *msg = tsk_error_get(); + setThrowTskCoreError(env, msg); +} + +/** +* Sets flag to throw an TskDataException back up to the Java code with a specific message. +* Note: exception is thrown to Java code after the native function returns +* not when setThrowTskDataError() is invoked - this must be addressed in the code following the exception +* @param the java environment to send the exception to +* @param msg message string + */ +static void +setThrowTskDataError(JNIEnv * env, const char *msg) +{ + jclass exception; + exception = env->FindClass("org/sleuthkit/datamodel/TskDataException"); + env->ThrowNew(exception, msg); +} + +#if 0 +/** +* Sets flag to throw an TskDataException back up to the Java code with the currently set error message. +* Note: exception is thrown to Java code after the native function returns +* not when setThrowTskDataError() is invoked - this must be addressed in the code following the exception +* @param the java environment to send the exception to +*/ +static void +setThrowTskDataError(JNIEnv * env) +{ + const char *msg = tsk_error_get(); + setThrowTskDataError(env, msg); +} +#endif + + +/***** Methods to cast from jlong to data type and check tags + They all throw an exception if the incorrect type is passed in. *****/ +static TSK_IMG_INFO * +castImgInfo(JNIEnv * env, jlong ptr) +{ + TSK_IMG_INFO *lcl = (TSK_IMG_INFO *) ptr; + if (!lcl || lcl->tag != TSK_IMG_INFO_TAG) { + setThrowTskCoreError(env, "Invalid IMG_INFO object"); + return 0; + } + return lcl; +} + + +static TSK_VS_INFO * +castVsInfo(JNIEnv * env, jlong ptr) +{ + TSK_VS_INFO *lcl = (TSK_VS_INFO *) ptr; + if (!lcl || lcl->tag != TSK_VS_INFO_TAG) { + setThrowTskCoreError(env, "Invalid VS_INFO object"); + return 0; + } + // verify that image handle is still open + if (!castImgInfo(env, (jlong) lcl->img_info)) { + return 0; + } + return lcl; +} + +static TSK_VS_PART_INFO * +castVsPartInfo(JNIEnv * env, jlong ptr) +{ + TSK_VS_PART_INFO *lcl = (TSK_VS_PART_INFO *) ptr; + if (!lcl || lcl->tag != TSK_VS_PART_INFO_TAG) { + setThrowTskCoreError(env, "Invalid VS_PART_INFO object"); + return 0; + } + // verify that all handles are still open + if (!castVsInfo(env, (jlong) lcl->vs)) { + return 0; + } + return lcl; +} + +static TSK_POOL_INFO * +castPoolInfo(JNIEnv * env, jlong ptr) +{ + TSK_POOL_INFO *lcl = (TSK_POOL_INFO *)ptr; + if (!lcl || lcl->tag != TSK_POOL_INFO_TAG) { + setThrowTskCoreError(env, "Invalid TSK_POOL_INFO object"); + return 0; + } + return lcl; +} + +static TSK_FS_INFO * +castFsInfo(JNIEnv * env, jlong ptr) +{ + TSK_FS_INFO *lcl = (TSK_FS_INFO *) ptr; + if (!lcl || lcl->tag != TSK_FS_INFO_TAG) { + setThrowTskCoreError(env, "Invalid FS_INFO object"); + return 0; + } + // verify that image handle is still open + if (!castImgInfo(env, (jlong) lcl->img_info)) { + return 0; + } + return lcl; +} + + +static TSK_FS_FILE * +castFsFile(JNIEnv * env, jlong ptr) +{ + TSK_FS_FILE *lcl = (TSK_FS_FILE *)ptr; + if (lcl == NULL || lcl->tag != TSK_FS_FILE_TAG) { + setThrowTskCoreError(env, "Invalid FS_FILE object"); + return 0; + } + // verify that file system handle is still open + if (!castFsInfo(env, (jlong)lcl->fs_info)) { + return 0; + } + return lcl; +} + +static TSK_JNI_FILEHANDLE * +castJniFileHandle(JNIEnv * env, jlong ptr) +{ + TSK_JNI_FILEHANDLE *lcl = (TSK_JNI_FILEHANDLE *) ptr; + if (!lcl || lcl->tag != TSK_JNI_FILEHANDLE_TAG) { + setThrowTskCoreError(env, "Invalid TSK_JNI_FILEHANDLE object"); + return 0; + } + // verify that all handles are still open + if (!castFsFile(env, (jlong) lcl->fs_file)) { + return 0; + } + return lcl; +} + +static TskCaseDb * +castCaseDb(JNIEnv * env, jlong ptr) +{ + TskCaseDb *lcl = ((TskCaseDb *) ptr); + if (lcl == NULL || lcl->m_tag != TSK_CASE_DB_TAG) { + setThrowTskCoreError(env, + "Invalid TskCaseDb object"); + return 0; + } + + return lcl; +} + +/** + * Convert a jstring (UTF-8) to a TCHAR to pass into TSK methods. + * @param buffer Buffer to store resulting string into + * @param size Length of buffer + * @param strJ string to convert + * @returns 1 on error + */ +static int +toTCHAR(JNIEnv * env, TSK_TCHAR * buffer, size_t size, jstring strJ) +{ + jboolean isCopy; + char *str8 = (char *) env->GetStringUTFChars(strJ, &isCopy); + +#ifdef TSK_WIN32 + // Windows TCHAR is UTF16 in Windows, so convert + UTF16 *utf16 = (UTF16 *) buffer; + UTF8 *utf8 = (UTF8 *) str8;; + TSKConversionResult retval; + size_t lengthOfUtf8 = strlen(str8); + + retval = + tsk_UTF8toUTF16((const UTF8 **) &utf8, &utf8[lengthOfUtf8], + &utf16, &utf16[size], TSKlenientConversion); + if (retval != TSKconversionOK) { + tsk_error_set_errno(TSK_ERR_IMG_CONVERT); + tsk_error_set_errstr + ("toTCHAR: Error converting UTF8 %s to UTF16, error %d", + utf8, retval); + env->ReleaseStringUTFChars(strJ, str8); + return 1; + } + + // "utf16" now points to last char. Need to NULL terminate the string. + *utf16 = '\0'; + +#else + // nothing to convert. Keep it as UTF8 + strncpy((char *)&buffer[0], str8, size); +#endif + + env->ReleaseStringUTFChars(strJ, str8); + return 0; +} + +/** + * Opens an existing hash database. + * @param env Pointer to Java environment from which this method was called. + * @param obj The Java object from which this method was called. + * @param pathJ The path to the hash database. + * @return A handle for the hash database. + */ +JNIEXPORT jint JNICALL + Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbOpenNat(JNIEnv * env, + jclass obj, jstring pathJ) +{ + TSK_TCHAR pathT[1024]; + toTCHAR(env, pathT, 1024, pathJ); + TSK_HDB_INFO *db = tsk_hdb_open(pathT, TSK_HDB_OPEN_NONE); + if (!db) + { + setThrowTskCoreError(env, tsk_error_get_errstr()); + return -1; + } + + // The index of the pointer in the vector is used as a handle for the + // database. + hashDbs.push_back(db); + return (jint)hashDbs.size(); +} + +/** + * Creates a new hash database. + * @param env Pointer to Java environment from which this method was called. + * @param obj The Java object from which this method was called. + * @param pathJ The path to the hash database. + * @return A handle for the hash database. + */ +JNIEXPORT jint JNICALL + Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbNewNat(JNIEnv * env, + jclass obj, jstring pathJ) +{ + TSK_TCHAR pathT[1024]; + toTCHAR(env, pathT, 1024, pathJ); + if (tsk_hdb_create(pathT)) { + setThrowTskCoreError(env, tsk_error_get_errstr()); + return -1; + } + + TSK_HDB_INFO *db = tsk_hdb_open(pathT, TSK_HDB_OPEN_NONE); + if (!db) { + setThrowTskCoreError(env, tsk_error_get_errstr()); + return -1; + } + + // The index of the pointer in the vector is used as a handle for the + // database. + hashDbs.push_back(db); + return (jint)hashDbs.size(); +} + +/** + * Begins a hash database transaction. + * @param env Pointer to Java environment from which this method was called. + * @param obj The Java object from which this method was called. + * @param dbHandle A handle for the hash database. + * @return 1 on error and 0 on success. + */ +JNIEXPORT jint JNICALL +Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbBeginTransactionNat( + JNIEnv *env, jclass obj, jint dbHandle) +{ + if((size_t)dbHandle > hashDbs.size()) { + setThrowTskCoreError(env, "Invalid database handle"); + return 1; + } + + TSK_HDB_INFO *db = hashDbs.at(dbHandle - 1); + if (!db) { + setThrowTskCoreError(env, "Invalid database handle"); + return 1; + } + + return tsk_hdb_begin_transaction(db); +} + +/** + * Commits a hash database transaction. + * @param env Pointer to Java environment from which this method was called. + * @param obj The Java object from which this method was called. + * @param dbHandle A handle for the hash database. + * @return 1 on error and 0 on success. + */ +JNIEXPORT jint JNICALL +Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbCommitTransactionNat( + JNIEnv *env, jclass obj, jint dbHandle) +{ + if((size_t)dbHandle > hashDbs.size()) { + setThrowTskCoreError(env, "Invalid database handle"); + return 1; + } + + TSK_HDB_INFO *db = hashDbs.at(dbHandle - 1); + if (!db) { + setThrowTskCoreError(env, "Invalid database handle"); + return 1; + } + + return tsk_hdb_commit_transaction(db); +} + +/** + * Rolls back a hash database transaction. + * @param env Pointer to Java environment from which this method was called. + * @param obj The Java object from which this method was called. + * @param dbHandle A handle for the hash database. + * @return 1 on error and 0 on success. + */ +JNIEXPORT jint JNICALL +Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbRollbackTransactionNat( + JNIEnv *env, jclass obj, jint dbHandle) +{ + if((size_t)dbHandle > hashDbs.size()) { + setThrowTskCoreError(env, "Invalid database handle"); + return 1; + } + + TSK_HDB_INFO *db = hashDbs.at(dbHandle-1); + if (!db) { + setThrowTskCoreError(env, "Invalid database handle"); + return 1; + } + + return tsk_hdb_rollback_transaction(db); +} + +/** + * Adds data to a hash database. + * @param env Pointer to Java environment from which this method was called. + * @param obj The Java object from which this method was called. + * @param filenameJ Name of the file that was hashed (can be null). + * @param hashMd5J MD5 hash of file contents (can be null). + * @param hashSha1J SHA-1 hash of file contents (can be null). + * @param hashSha256J Text of SHA256 hash (can be null). + * @param dbHandle A handle for the hash database. + * @return 1 on error and 0 on success. + */ +JNIEXPORT jint JNICALL + Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbAddEntryNat(JNIEnv * env, + jclass obj, jstring filenameJ, jstring hashMd5J, jstring hashSha1J, jstring hashSha256J, + jstring commentJ, jint dbHandle) +{ + if((size_t) dbHandle > hashDbs.size()) { + setThrowTskCoreError(env, "Invalid database handle"); + return 1; + } + + TSK_HDB_INFO * db = hashDbs.at(dbHandle-1); + if(!db) { + setThrowTskCoreError(env, "Invalid database handle"); + return 1; + } + + if(!db->accepts_updates()) { + setThrowTskCoreError(env, "Database does not accept updates"); + return 1; + } + + jboolean isCopy; + const char * name = filenameJ ? (const char *) env->GetStringUTFChars(filenameJ, &isCopy) : NULL; + const char * md5 = hashMd5J ? (const char *) env->GetStringUTFChars(hashMd5J, &isCopy) : NULL; + const char * sha1 = hashSha1J ? (const char *) env->GetStringUTFChars(hashSha1J, &isCopy) : NULL; + const char * sha256 = hashSha256J ? (const char *) env->GetStringUTFChars(hashSha256J, &isCopy) : NULL; + const char * comment = commentJ ? (const char *) env->GetStringUTFChars(commentJ, &isCopy) : NULL; + + if (tsk_hdb_add_entry(db, name, md5, sha1, sha256, comment)) { + setThrowTskCoreError(env, tsk_error_get_errstr()); + } + + if (filenameJ) { + env->ReleaseStringUTFChars(filenameJ, (const char *) name); + } + + if (hashMd5J) { + env->ReleaseStringUTFChars(hashMd5J, (const char *) md5); + } + + if (hashSha1J) { + env->ReleaseStringUTFChars(hashSha1J, (const char *) sha1); + } + + if (hashSha256J) { + env->ReleaseStringUTFChars(hashSha256J, (const char *) sha256); + } + + if (commentJ) { + env->ReleaseStringUTFChars(commentJ, (const char *) comment); + } + + return 0; +} + +/** + * Queries whether or not a hash database accepts updates. + * @param env Pointer to Java environment from which this method was called. + * @param obj The Java object from which this method was called. + * @param dbHandle A handle for the hash database. + * @return True if hash database can be updated. + */ +JNIEXPORT jboolean JNICALL + Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbIsUpdateableNat(JNIEnv * env, + jclass obj, jint dbHandle) +{ + if((size_t)dbHandle > hashDbs.size()) { + setThrowTskCoreError(env, "Invalid database handle"); + return (jboolean)false; + } + + TSK_HDB_INFO *db = hashDbs.at(dbHandle-1); + if (db == NULL) { + setThrowTskCoreError(env, "Invalid database handle"); + return (jboolean)false; + } + + return (jboolean)(tsk_hdb_accepts_updates(db) == static_cast(1)); +} + +/** + * Queries whether or not a hash database can be re-indexed. Only text-format + * databases with external indexes can be re-indexed. + * @param env Pointer to Java environment from which this method was called. + * @param obj The Java object from which this method was called. + * @param dbHandle A handle for the hash database. + * @return True if hash database can be indexed. + */ +JNIEXPORT jboolean JNICALL + Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbIsReindexableNat(JNIEnv * env, + jclass obj, jint dbHandle) +{ + if((size_t)dbHandle > hashDbs.size()) { + setThrowTskCoreError(env, "Invalid database handle"); + return (jboolean)false; + } + + TSK_HDB_INFO *db = hashDbs.at(dbHandle-1); + if (db == NULL) { + setThrowTskCoreError(env, "Invalid database handle"); + return (jboolean)false; + } + + return (jboolean)((tsk_hdb_uses_external_indexes(db) == 1) && + (tsk_hdb_is_idx_only(db) == 0)); +} + +/** + * Gets the path of a hash database. + * @param env Pointer to Java environment from which this method was called. + * @param obj The Java object from which this method was called. + * @param dbHandle A handle for the hash database. + * @return Path to the hash database or "None" if no path is available. + */ +JNIEXPORT jstring JNICALL + Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbPathNat(JNIEnv * env, + jclass obj, jint dbHandle) +{ + if((size_t)dbHandle > hashDbs.size()) { + setThrowTskCoreError(env, "Invalid database handle"); + return NULL; + } + + TSK_HDB_INFO *db = hashDbs.at(dbHandle-1); + if (db == NULL) { + setThrowTskCoreError(env, "Invalid database handle"); + return NULL; + } + + jstring jPath = NULL; + const TSK_TCHAR *dbPath = tsk_hdb_get_db_path(db); + if (NULL != dbPath) { + const size_t pathLength = TSTRLEN(dbPath); + char *cPath = (char*)tsk_malloc((pathLength + 1) * sizeof(char)); + snprintf(cPath, pathLength + 1, "%" PRIttocTSK, dbPath); + jPath = env->NewStringUTF(cPath); + free(cPath); + } + else { + jPath = env->NewStringUTF("None"); + } + return jPath; +} + +/* + * Gets the path of the external MD5 hash index for a text-format database. + * @param env Pointer to Java environment from which this method was called. + * @param obj The Java object from which this method was called. + * @param dbHandle A handle for the hash database. + * @return Path to the requested index or "None" if no path is available. + */ +JNIEXPORT jstring JNICALL + Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbIndexPathNat(JNIEnv * env, + jclass obj, jint dbHandle) +{ + if((size_t)dbHandle > hashDbs.size()) { + setThrowTskCoreError(env, "Invalid database handle"); + return NULL; + } + + TSK_HDB_INFO *db = hashDbs.at(dbHandle-1); + if (db == NULL) { + setThrowTskCoreError(env, "Invalid database handle"); + return NULL; + } + + // Currently only supporting md5 indexes through Java binding. + jstring jPath = NULL; + const TSK_TCHAR *indexPath = tsk_hdb_get_idx_path(db, TSK_HDB_HTYPE_MD5_ID); + if (NULL != indexPath) { + const size_t pathLength = TSTRLEN(indexPath); + char *cPath = (char*)tsk_malloc((pathLength + 1) * sizeof(char)); + snprintf(cPath, pathLength + 1, "%" PRIttocTSK, indexPath); + jPath = env->NewStringUTF(cPath); + free(cPath); + } + else { + jPath = env->NewStringUTF("None"); + } + return jPath; +} + +/** + * Queries whether the hash database is actually an external index for a + * text-format database that is being used for simple yes/no look ups in + * place of the roginal hash database. + * @param env Pointer to Java environment from which this method was called. + * @param obj The Java object from which this method was called. + * @param dbHandle A handle for the hash database. + * @return True if the hash database is an external index serving as a + * database. + */ +JNIEXPORT jboolean JNICALL + Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbIsIdxOnlyNat(JNIEnv * env, + jclass obj, jint dbHandle) +{ + if((size_t)dbHandle > hashDbs.size()) { + setThrowTskCoreError(env, "Invalid database handle"); + return (jboolean)false; + } + + TSK_HDB_INFO *db = hashDbs.at(dbHandle-1); + if (db == NULL) { + setThrowTskCoreError(env, "Invalid database handle"); + return (jboolean)false; + } + + return (jboolean)(tsk_hdb_is_idx_only(db) == static_cast(1)); +} + +/** + * Gets the display name of a hash database. + * @param env Pointer to Java environment from which this method was called. + * @param obj The Java object from which this method was called. + * @param dbHandle A handle for the hash database. + * @return The display name. + */ +JNIEXPORT jstring JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbGetDisplayName + (JNIEnv * env, jclass obj, jint dbHandle) +{ + if((size_t)dbHandle > hashDbs.size()) { + setThrowTskCoreError(env, "Invalid database handle"); + return NULL; + } + + TSK_HDB_INFO *db = hashDbs.at(dbHandle-1); + if (db == NULL) { + setThrowTskCoreError(env, "Invalid database handle"); + return NULL; + } + + jstring j_name = NULL; + const char *db_name = tsk_hdb_get_display_name(db); + if (NULL != db_name) { + j_name = env->NewStringUTF(db_name); + } + return j_name; +} + +/** + * Closes all open hash databases. + * @param env Pointer to Java environment from which this method was called. + * @param obj The Java object from which this method was called. + * @param dbHandle A handle for the hash database. + */ +JNIEXPORT void JNICALL + Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbCloseAll(JNIEnv * env, + jclass obj) +{ + for (std::vector::iterator it = hashDbs.begin(); it != hashDbs.end(); ++it) { + if (NULL != *it) { + tsk_hdb_close(*it); + } + } + + hashDbs.clear(); +} + +/** + * Closes a hash database. + * @param env Pointer to Java environment from which this method was called. + * @param obj The Java object from which this method was called. + * @param dbHandle A handle for the hash database. + */ +JNIEXPORT void JNICALL + Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbClose(JNIEnv * env, + jclass obj, jint dbHandle) +{ + if((size_t)dbHandle > hashDbs.size()) { + setThrowTskCoreError(env, "Invalid database handle"); + return; + } + + TSK_HDB_INFO *db = hashDbs.at(dbHandle-1); + if (db == NULL) { + setThrowTskCoreError(env, "Invalid database handle"); + return; + } + + tsk_hdb_close(db); + + // Do NOT erase the element because that would shift the indices, + // messing up the existing handles. + hashDbs.at(dbHandle-1) = NULL; +} + +/** + * Looks up a hash in a hash database. + * @param env Pointer to Java environment from which this method was called. + * @param obj The Java object from which this method was called. + * @param dbHandle A handle for the hash database. + * @return True if the hash is found in the hash database, false otherwise. + */ +JNIEXPORT jboolean JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbLookup +(JNIEnv * env, jclass obj, jstring hash, jint dbHandle) +{ + if ((size_t)dbHandle > hashDbs.size()) { + setThrowTskCoreError(env, "Invalid database handle"); + return (jboolean)false; + } + + TSK_HDB_INFO *db = hashDbs.at(dbHandle-1); + if (db == NULL) { + setThrowTskCoreError(env, "Invalid database handle"); + return (jboolean)false; + } + + jboolean isCopy; + const char *cHashStr = (const char *) env->GetStringUTFChars(hash, &isCopy); + jboolean file_known = false; + int8_t retval = tsk_hdb_lookup_str(db, cHashStr, TSK_HDB_FLAG_QUICK, NULL, NULL); + if (retval == -1) { + setThrowTskCoreError(env, tsk_error_get_errstr()); + } + else if (retval) { + file_known = true; + } + + env->ReleaseStringUTFChars(hash, (const char *) cHashStr); + + return file_known; +} + +/** + * Looks up a hash in a hash database. + * @param env Pointer to Java environment from which this method was called. + * @param obj The Java object from which this method was called. + * @param dbHandle A handle for the hash database. + * @return A HashInfo object if the hash is found, NULL otherwise. + */ +JNIEXPORT jobject JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbLookupVerbose +(JNIEnv * env, jclass obj, jstring hash, jint dbHandle) { + if ((size_t)dbHandle > hashDbs.size()) { + setThrowTskCoreError(env, "Invalid database handle"); + return NULL; + } + + TSK_HDB_INFO *db = hashDbs.at(dbHandle-1); + if (db == NULL) { + setThrowTskCoreError(env, "Invalid database handle"); + return NULL; + } + + jboolean isCopy; + const char *inputHash = (const char *) env->GetStringUTFChars(hash, &isCopy); + TskHashInfo result; + int8_t returnCode = tsk_hdb_lookup_verbose_str(db, inputHash, (void*)&result); + env->ReleaseStringUTFChars(hash, (const char *) inputHash); + + if (returnCode == -1) { + setThrowTskCoreError(env, tsk_error_get_errstr()); + return NULL; + } + else if (returnCode == 0) { + return NULL; + } + + // Convert the hashes from the hash database so they can be written into + // the Java version of a HashInfo object. + const char *md5 = result.hashMd5.c_str(); + jstring md5j = env->NewStringUTF(md5); + + const char *sha1 = result.hashSha1.c_str(); + jstring sha1j = env->NewStringUTF(sha1); + + const char *sha256 = result.hashSha2_256.c_str(); + jstring sha256j = env->NewStringUTF(sha256); + + // Create and return a Java HashInfo object. + jclass clazz; + clazz = env->FindClass("org/sleuthkit/datamodel/HashHitInfo"); + jmethodID ctor = env->GetMethodID(clazz, "", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V"); + jmethodID addName = env->GetMethodID(clazz, "addName", "(Ljava/lang/String;)V"); + jmethodID addComment = env->GetMethodID(clazz, "addComment", "(Ljava/lang/String;)V"); + jobject hashInfo = env->NewObject(clazz, ctor, md5j, sha1j, sha256j); + for (std::vector::iterator it = result.fileNames.begin(); it != result.fileNames.end(); ++it) { + jstring namej = env->NewStringUTF((*it).c_str()); + env->CallVoidMethod(hashInfo, addName, namej); + } + for (std::vector::iterator it = result.comments.begin(); it != result.comments.end(); ++it) { + jstring commentj = env->NewStringUTF((*it).c_str()); + env->CallVoidMethod(hashInfo, addComment, commentj); + } + return hashInfo; +} + +/* + * Initialize a process for adding an image to a case database. + * + * @param env Pointer to java environment. + * @param obj Pointer the Java class object. + * @param timeZone The time zone for the image. + * @param addUnallocSpace Pass true to create virtual files for unallocated space. Ignored if addFileSystems is false. + * @param skipFatFsOrphans Pass true to skip processing of orphan files for FAT file systems. Ignored if addFileSystems is false. + * + * @return A pointer to the process (TskAutoDbJava object) or NULL on error. + */ +JNIEXPORT jlong JNICALL + Java_org_sleuthkit_datamodel_SleuthkitJNI_initAddImgNat(JNIEnv * env, + jclass obj, jobject callbackObj, jstring timeZone, jboolean addUnallocSpace, jboolean skipFatFsOrphans) { + return Java_org_sleuthkit_datamodel_SleuthkitJNI_initializeAddImgNat(env, obj, callbackObj, timeZone, true, addUnallocSpace, skipFatFsOrphans); +} + +/* + * Initialize a process for adding an image to a case database. + * + * @param env Pointer to java environment. + * @param obj Pointer the Java class object. + * @param timeZone The time zone for the image. + * @param addFileSystems Pass true to attempt to add file systems within the image to the case database. + * @param addUnallocSpace Pass true to create virtual files for unallocated space. Ignored if addFileSystems is false. + * @param skipFatFsOrphans Pass true to skip processing of orphan files for FAT file systems. Ignored if addFileSystems is false. + * + * @return A pointer to the process (TskAutoDbJava object) or NULL on error. + */ +JNIEXPORT jlong JNICALL +Java_org_sleuthkit_datamodel_SleuthkitJNI_initializeAddImgNat(JNIEnv * env, jclass obj, + jobject callbackObj, jstring timeZone, jboolean addFileSystems, jboolean addUnallocSpace, jboolean skipFatFsOrphans) { + jboolean isCopy; + + if (env->GetStringUTFLength(timeZone) > 0) { + const char *tzstr = env->GetStringUTFChars(timeZone, &isCopy); + + if (strlen(tzstr) > 64) { + env->ReleaseStringUTFChars(timeZone, tzstr); + stringstream ss; + ss << "Timezone is too long"; + setThrowTskCoreError(env, ss.str().c_str()); + return 0; + } + + char envstr[70]; + snprintf(envstr, 70, "TZ=%s", tzstr); + env->ReleaseStringUTFChars(timeZone, tzstr); + + if (0 != putenv(envstr)) { + stringstream ss; + ss << "Error setting timezone environment, using: "; + ss << envstr; + setThrowTskCoreError(env, ss.str().c_str()); + return 0; + } + + /* we should be checking this somehow */ + TZSET(); + } + + TskAutoDbJava *tskAutoJava = new TskAutoDbJava(); + if (tskAutoJava == NULL) { + setThrowTskCoreError(env, "Error creating TskAutoDbJava"); + return 0; + } + + // set the options flags + tskAutoJava->setAddFileSystems(addFileSystems?true:false); + if (addFileSystems) { + if (addUnallocSpace) { + // Minimum size of unalloc files: 500 MB, maximum size: 1 GB + tskAutoJava->setAddUnallocSpace((int64_t)500 * 1024 * 1024, (int64_t)1024 * 1024 * 1024); + } + else { + tskAutoJava->setAddUnallocSpace(false); + } + tskAutoJava->setNoFatFsOrphans(skipFatFsOrphans?true:false); + } else { + tskAutoJava->setAddUnallocSpace(false); + tskAutoJava->setNoFatFsOrphans(true); + } + + // Set up the callbacks + if (TSK_ERR == tskAutoJava->initializeJni(env, callbackObj)) { + setThrowTskCoreError(env, "Error initializing JNI callbacks"); + return 0; + } + + return (jlong)tskAutoJava; +} + +/* + * Add an image to a database using a pre-created process, which can be cancelled. + * MUST call commitAddImg or revertAddImg afterwards once runAddImg returns. If there is an + * error, you do not need to call revert or commit and the 'process' handle will be deleted. + * + * @param env pointer to java environment this was called from + * @param obj the java object this was called from + * @param process the add-image process created by initAddImgNat + * @param deviceId An ASCII-printable identifier for the device associated with the data source that is intended to be unique across multiple cases (e.g., a UUID) + * @param paths array of strings from java, the paths to the image parts + * @param numImgs number of image parts + * @param timeZone the timezone the image is from + */ +JNIEXPORT void JNICALL + Java_org_sleuthkit_datamodel_SleuthkitJNI_runOpenAndAddImgNat(JNIEnv * env, + jclass obj, jlong process, jstring deviceId, jobjectArray paths, jint numImgs, jstring timeZone) { + + TskAutoDbJava *tskAuto = ((TskAutoDbJava *) process); + if (!tskAuto || tskAuto->m_tag != TSK_AUTO_TAG) { + setThrowTskCoreError(env, + "runOpenAndAddImgNat: Invalid TskAutoDbJava object passed in"); + return; + } + + jboolean isCopy; + const char *device_id = NULL; + if (NULL != deviceId) { + device_id = (const char *) env->GetStringUTFChars(deviceId, &isCopy); + if (NULL == device_id) { + setThrowTskCoreError(env, "runOpenAndAddImgNat: Can't convert data source id string"); + return; + } + } + + // Get pointers to each of the image file names. + char **imagepaths8 = (char **) tsk_malloc(numImgs * sizeof(char *)); + if (imagepaths8 == NULL) { + setThrowTskCoreError(env); + return; + } + for (int i = 0; i < numImgs; i++) { + jstring jsPath = (jstring) env->GetObjectArrayElement(paths, + i); + imagepaths8[i] = + (char *) env-> + GetStringUTFChars(jsPath, &isCopy); + if (imagepaths8[i] == NULL) { + setThrowTskCoreError(env, + "runOpenAndAddImgNat: Can't convert path strings."); + // @@@ should cleanup here paths that have been converted in imagepaths8[i] + return; + } + } + + // Set the time zone. + if (env->GetStringLength(timeZone) > 0) { + const char *time_zone = env->GetStringUTFChars(timeZone, &isCopy); + tskAuto->setTz(string(time_zone)); + env->ReleaseStringUTFChars(timeZone, time_zone); + } + + // Add the data source. + uint8_t ret = 0; + if ( (ret = tskAuto->startAddImage((int) numImgs, imagepaths8, + TSK_IMG_TYPE_DETECT, 0, device_id)) != 0) { + stringstream msgss; + msgss << "Errors occurred while ingesting image " << std::endl; + vector errors = tskAuto->getErrorList(); + for (size_t i = 0; i < errors.size(); i++) { + msgss << (i+1) << ". "; + msgss << (TskAuto::errorRecordToString(errors[i])); + msgss << " " << std::endl; + } + + if (ret == 1) { + // Fatal error + setThrowTskCoreError(env, msgss.str().c_str()); + } + else if (ret == 2) { + // Non-fatal error + setThrowTskDataError(env, msgss.str().c_str()); + } + } + + // @@@ SHOULD WE CLOSE HERE before we commit / revert etc. + //close image first before freeing the image paths + tskAuto->closeImage(); + + // Cleanup + for (int i = 0; i < numImgs; i++) { + jstring jsPath = (jstring) + env->GetObjectArrayElement(paths, i); + env-> + ReleaseStringUTFChars(jsPath, imagepaths8[i]); + env->DeleteLocalRef(jsPath); + } + free(imagepaths8); + env->ReleaseStringUTFChars(deviceId, (const char *) device_id); + + // // Must call finishAddImgNat to free the TskAutoDb +} + +/* +* Add an image to a database using a pre-created process, which can be cancelled. +* MUST call commitAddImg or revertAddImg afterwards once runAddImg returns. If there is an +* error, you do not need to call revert or commit and the 'process' handle will be deleted. +* +* @param env pointer to java environment this was called from +* @param obj the java object this was called from +* @param process the add-image process created by initAddImgNat +* @param deviceId An ASCII-printable identifier for the device associated with the data source that is intended to be unique across multiple cases (e.g., a UUID) +* @param a_img_info image info object +* @param img_id The object ID of the image in the database +* @param timeZone the timezone the image is from +*/ +JNIEXPORT void JNICALL +Java_org_sleuthkit_datamodel_SleuthkitJNI_runAddImgNat(JNIEnv * env, + jclass obj, jlong process, jstring deviceId, jlong a_img_info, jlong img_id, jstring timeZone, jstring imageWriterPathJ) { + + TskAutoDbJava *tskAuto = ((TskAutoDbJava *)process); + if (!tskAuto || tskAuto->m_tag != TSK_AUTO_TAG) { + setThrowTskCoreError(env, + "runAddImgNat: Invalid TskAutoDbJava object passed in"); + return; + } + + jboolean isCopy; + const char *device_id = NULL; + if (NULL != deviceId) { + device_id = (const char *)env->GetStringUTFChars(deviceId, &isCopy); + if (NULL == device_id) { + setThrowTskCoreError(env, "runAddImgNat: Can't convert data source id string"); + return; + } + } + + // Set the data source object ID + tskAuto->setDatasourceObjId(img_id); + + // Set the time zone. + if (env->GetStringLength(timeZone) > 0) { + const char *time_zone = env->GetStringUTFChars(timeZone, &isCopy); + tskAuto->setTz(string(time_zone)); + env->ReleaseStringUTFChars(timeZone, time_zone); + } + + // Set up the TSK_IMG_INFO object + TSK_IMG_INFO *img_info = castImgInfo(env, a_img_info); + + // Set up image writer, if the output path is present + if (env->GetStringLength(imageWriterPathJ) > 0) { + const char *imageWriterPath = env->GetStringUTFChars(imageWriterPathJ, &isCopy); + if (TSK_OK != tskAuto->enableImageWriter(imageWriterPath)) { + env->ReleaseStringUTFChars(imageWriterPathJ, imageWriterPath); + setThrowTskCoreError(env, + "runAddImgNat: error enabling image writer."); + return; + } + env->ReleaseStringUTFChars(imageWriterPathJ, imageWriterPath); + } + else { + tskAuto->disableImageWriter(); + } + + // Add the data source. + uint8_t ret = 0; + if ((ret = tskAuto->startAddImage(img_info, device_id)) != 0) { + stringstream msgss; + msgss << "Errors occurred while ingesting image " << std::endl; + vector errors = tskAuto->getErrorList(); + for (size_t i = 0; i < errors.size(); i++) { + msgss << (i + 1) << ". "; + msgss << (TskAuto::errorRecordToString(errors[i])); + msgss << " " << std::endl; + } + + if (ret == 1) { + // Fatal error + setThrowTskCoreError(env, msgss.str().c_str()); + } + else if (ret == 2) { + // Non-fatal error + setThrowTskDataError(env, msgss.str().c_str()); + } + } + + // @@@ SHOULD WE CLOSE HERE before we commit / revert etc. + //close image first before freeing the image paths + tskAuto->closeImage(); + + // Cleanup + env->ReleaseStringUTFChars(deviceId, (const char *)device_id); + + // Must call finishAddImgNat to free the TskAutoDb +} + + +/* + * Cancel the given add-image process. + * @param env pointer to java environment this was called from + * @param obj the java object this was called from + * @param process the add-image process created by initAddImgNat + */ +JNIEXPORT void JNICALL + Java_org_sleuthkit_datamodel_SleuthkitJNI_stopAddImgNat(JNIEnv * env, + jclass obj, jlong process) { + TskAutoDbJava *tskAuto = ((TskAutoDbJava *) process); + if (!tskAuto || tskAuto->m_tag != TSK_AUTO_TAG) { + setThrowTskCoreError(env, + "stopAddImgNat: Invalid TskAutoDbJava object passed in"); + return; + } + tskAuto->stopAddImage(); +} + + +/* +* Completes the given add-image process. Deletes the 'process' handle and +* returns the ID of the added image. +* @param env pointer to java environment this was called from +* @param obj the java object this was called from +* @param process the add-image process created by initAddImgNat +*/ +JNIEXPORT jlong JNICALL +Java_org_sleuthkit_datamodel_SleuthkitJNI_finishAddImgNat(JNIEnv * env, + jclass obj, jlong process) { + TskAutoDbJava *tskAuto = ((TskAutoDbJava *)process); + if (!tskAuto || tskAuto->m_tag != TSK_AUTO_TAG) { + setThrowTskCoreError(env, + "commitAddImgNat: Invalid TskAutoDb object passed in"); + return -1; + } + int64_t imgId = tskAuto->getImageID(); + tskAuto->close(); + delete tskAuto; + tskAuto = 0; + if (imgId == -1) { + setThrowTskCoreError(env); + return -1; + } + return imgId; +} + + +/* + * Open an image pointer for the given image. + * @return the created TSK_IMG_INFO pointer + * @param env pointer to java environment this was called from + * @param obj the java object this was called from + * @param paths the paths to the image parts + * @param num_imgs number of image parts + * @param sector_size the sector size (use '0' for autodetect) + */ +JNIEXPORT jlong JNICALL + Java_org_sleuthkit_datamodel_SleuthkitJNI_openImgNat(JNIEnv * env, + jclass obj, jobjectArray paths, jint num_imgs, jint sector_size) { + TSK_IMG_INFO *img_info; + jboolean isCopy; + + // get pointers to each of the file names + char **imagepaths8 = (char **)tsk_malloc(num_imgs * sizeof(char *)); + if (imagepaths8 == NULL) { + setThrowTskCoreError(env); + return 0; + } + for (int i = 0; i < num_imgs; i++) { + imagepaths8[i] = + (char *)env-> + GetStringUTFChars((jstring)env->GetObjectArrayElement(paths, + i), &isCopy); + // @@@ Error check + } + + // open the image + img_info = + tsk_img_open_utf8((int)num_imgs, imagepaths8, TSK_IMG_TYPE_DETECT, + sector_size); + if (img_info == NULL) { + setThrowTskCoreError(env, tsk_error_get()); + } + + // cleanup + for (int i = 0; i < num_imgs; i++) { + env-> + ReleaseStringUTFChars((jstring) + env->GetObjectArrayElement(paths, i), imagepaths8[i]); + } + free(imagepaths8); + + return (jlong) img_info; +} + +/* + * Get the full list of paths associated with an image. + */ +JNIEXPORT jobjectArray JNICALL +Java_org_sleuthkit_datamodel_SleuthkitJNI_getPathsForImageNat(JNIEnv * env, + jclass obj, jlong a_img_info) { + + TSK_IMG_INFO *img_info = castImgInfo(env, a_img_info); + if (img_info == 0) { + //exception already set + return 0; + } + + char **img_ptrs; +#ifdef TSK_WIN32 + // convert image paths to UTF-8 + img_ptrs = (char **)tsk_malloc(img_info->num_img * sizeof(char *)); + if (img_ptrs == NULL) { + return (jobjectArray)env->NewObjectArray(0, env->FindClass("java/lang/String"), env->NewStringUTF("")); + } + + for (int i = 0; i < img_info->num_img; i++) { + char * img2 = (char*)tsk_malloc(1024 * sizeof(char)); + UTF8 *ptr8; + UTF16 *ptr16; + + ptr8 = (UTF8 *)img2; + ptr16 = (UTF16 *)img_info->images[i]; + + uint8_t retval = + tsk_UTF16toUTF8_lclorder((const UTF16 **)&ptr16, (UTF16 *) + & ptr16[TSTRLEN(img_info->images[i]) + 1], &ptr8, + (UTF8 *)((uintptr_t)ptr8 + 1024), TSKlenientConversion); + if (retval != TSKconversionOK) { + tsk_error_reset(); + tsk_error_set_errno(TSK_ERR_AUTO_UNICODE); + tsk_error_set_errstr("Error converting image to UTF-8\n"); + return (jobjectArray)env->NewObjectArray(0, env->FindClass("java/lang/String"), env->NewStringUTF("")); + } + img_ptrs[i] = img2; + } +#else + img_ptrs = img_info->images; +#endif + + jobjectArray path_list = (jobjectArray)env->NewObjectArray(img_info->num_img, env->FindClass("java/lang/String"), env->NewStringUTF("")); + for (int i = 0; i < img_info->num_img; i++) { + env->SetObjectArrayElement(path_list, i, env->NewStringUTF(img_ptrs[i])); + } + + return path_list; +} + + +/* + * Get the size of an image. + */ +JNIEXPORT jlong JNICALL +Java_org_sleuthkit_datamodel_SleuthkitJNI_getSizeForImageNat(JNIEnv * env, + jclass obj, jlong a_img_info) { + + TSK_IMG_INFO *img_info = castImgInfo(env, a_img_info); + if (img_info == 0) { + //exception already set + return 0; + } + + return img_info->size; +} + + +/* + * Get the type of an image. + */ +JNIEXPORT jlong JNICALL +Java_org_sleuthkit_datamodel_SleuthkitJNI_getTypeForImageNat(JNIEnv * env, + jclass obj, jlong a_img_info) { + + TSK_IMG_INFO *img_info = castImgInfo(env, a_img_info); + if (img_info == 0) { + //exception already set + return 0; + } + + return img_info->itype; +} + + +/* +* Get the computed sector size of an image. +*/ +JNIEXPORT jlong JNICALL +Java_org_sleuthkit_datamodel_SleuthkitJNI_getSectorSizeForImageNat(JNIEnv * env, + jclass obj, jlong a_img_info) { + + TSK_IMG_INFO *img_info = castImgInfo(env, a_img_info); + if (img_info == 0) { + //exception already set + return 0; + } + + return img_info->sector_size; +} + +/* +* Get the md5 hash of an image. +*/ +JNIEXPORT jstring JNICALL +Java_org_sleuthkit_datamodel_SleuthkitJNI_getMD5HashForImageNat(JNIEnv * env, + jclass obj, jlong a_img_info) { + + TSK_IMG_INFO *img_info = castImgInfo(env, a_img_info); + if (img_info == 0) { + //exception already set + return 0; + } + // env->NewStringUTF(img_ptrs[i]) +#if HAVE_LIBEWF + if (img_info->itype == TSK_IMG_TYPE_EWF_EWF) { + IMG_EWF_INFO *ewf_info = (IMG_EWF_INFO *)img_info; + if (ewf_info->md5hash_isset) { + return env->NewStringUTF(ewf_info->md5hash); + } + } +#endif + return env->NewStringUTF(""); +} + +/* +* Get the sha1 hash of an image. +*/ +JNIEXPORT jstring JNICALL +Java_org_sleuthkit_datamodel_SleuthkitJNI_getSha1HashForImageNat(JNIEnv * env, + jclass obj, jlong a_img_info) { + + TSK_IMG_INFO *img_info = castImgInfo(env, a_img_info); + if (img_info == 0) { + //exception already set + return 0; + } + // env->NewStringUTF(img_ptrs[i]) +#if HAVE_LIBEWF + if (img_info->itype == TSK_IMG_TYPE_EWF_EWF) { + IMG_EWF_INFO *ewf_info = (IMG_EWF_INFO *)img_info; + if (ewf_info->sha1hash_isset) { + return env->NewStringUTF(ewf_info->sha1hash); + } + } +#endif + return env->NewStringUTF(""); +} + +/* +* Get the collection details of an image. +*/ +JNIEXPORT jstring JNICALL +Java_org_sleuthkit_datamodel_SleuthkitJNI_getCollectionDetailsForImageNat(JNIEnv * env, + jclass obj, jlong a_img_info) { + + TSK_IMG_INFO *img_info = castImgInfo(env, a_img_info); + if (img_info == 0) { + //exception already set + return 0; + } + // env->NewStringUTF(img_ptrs[i]) +#if HAVE_LIBEWF + if (img_info->itype == TSK_IMG_TYPE_EWF_EWF) { + IMG_EWF_INFO *ewf_info = (IMG_EWF_INFO *)img_info; + ewf_get_details(ewf_info); + } +#endif + return env->NewStringUTF(""); +} + +/* + * Open the volume system at the given offset + * @return the created TSK_VS_INFO pointer + * @param env pointer to java environment this was called from + * @param obj the java object this was called from + * @param a_img_info the pointer to the parent img object + * @param vsOffset the offset of the volume system in bytes + */ +JNIEXPORT jlong JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_openVsNat + (JNIEnv * env, jclass obj, jlong a_img_info, jlong vsOffset) { + TSK_IMG_INFO *img_info = castImgInfo(env, a_img_info); + if (img_info == 0) { + //exception already set + return 0; + } + TSK_VS_INFO *vs_info; + + vs_info = tsk_vs_open(img_info, vsOffset, TSK_VS_TYPE_DETECT); + if (vs_info == NULL) { + setThrowTskCoreError(env, tsk_error_get()); + } + return (jlong) vs_info; +} + + +/* + * Open volume with the given id from the given volume system + * @return the created TSK_VS_PART_INFO pointer + * @param env pointer to java environment this was called from + * @param obj the java object this was called from + * @param a_vs_info the pointer to the parent vs object + * @param vol_id the id of the volume to get + */ +JNIEXPORT jlong JNICALL +Java_org_sleuthkit_datamodel_SleuthkitJNI_openVolNat(JNIEnv * env, + jclass obj, jlong a_vs_info, jlong vol_id) +{ + TSK_VS_INFO *vs_info = castVsInfo(env, a_vs_info); + if (vs_info == 0) { + //exception already set + return 0; + } + const TSK_VS_PART_INFO *vol_part_info; + + vol_part_info = tsk_vs_part_get(vs_info, (TSK_PNUM_T) vol_id); + if (vol_part_info == NULL) { + setThrowTskCoreError(env, tsk_error_get()); + } + return (jlong) vol_part_info; +} + +/* +* Open pool with the given offset +* @return the created TSK_POOL_INFO pointer +* @param env pointer to java environment this was called from +* @param obj the java object this was called from +* @param a_img_info the pointer to the parent img object +* @param offset the offset in bytes to the pool +*/ +JNIEXPORT jlong JNICALL +Java_org_sleuthkit_datamodel_SleuthkitJNI_openPoolNat(JNIEnv * env, + jclass obj, jlong a_img_info, jlong offset) +{ + TSK_IMG_INFO *img_info = castImgInfo(env, a_img_info); + if (img_info == 0) { + //exception already set + return 0; + } + + const TSK_POOL_INFO *pool = tsk_pool_open_img_sing(img_info, offset, TSK_POOL_TYPE_DETECT); + if (pool == NULL) { + tsk_error_print(stderr); + if (tsk_error_get_errno() == TSK_ERR_POOL_UNSUPTYPE) + tsk_pool_type_print(stderr); + setThrowTskCoreError(env, tsk_error_get()); + } + return (jlong) pool; +} + +/* +* Create new image info to use with a specific pool volume +* @return the created TSK_IMG_INFO pointer +* @param env pointer to java environment this was called from +* @param obj the java object this was called from +* @param a_pool_info the pointer to the pool object +* @param pool_block the block number of the pool volume +*/ +JNIEXPORT jlong JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_getImgInfoForPoolNat +(JNIEnv * env, jclass obj, jlong a_pool_info, jlong pool_block) { + + TSK_POOL_INFO *pool_info = castPoolInfo(env, a_pool_info); + if (pool_info == 0) { + //exception already set + return 0; + } + TSK_IMG_INFO *img_info = pool_info->get_img_info(pool_info, pool_block); + + return (jlong)img_info; +} + +/* + * Open file system with the given offset + * @return the created TSK_FS_INFO pointer + * @param env pointer to java environment this was called from + * @param obj the java object this was called from + * @param a_img_info the pointer to the parent img object + * @param fs_offset the offset in bytes to the file system + */ +JNIEXPORT jlong JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_openFsNat + (JNIEnv * env, jclass obj, jlong a_img_info, jlong fs_offset) { + TSK_IMG_INFO *img_info = castImgInfo(env, a_img_info); + if (img_info == 0) { + //exception already set + return 0; + } + TSK_FS_INFO *fs_info; + fs_info = + tsk_fs_open_img(img_info, (TSK_OFF_T) fs_offset, + TSK_FS_TYPE_DETECT); + if (fs_info == NULL) { + setThrowTskCoreError(env, tsk_error_get()); + } + return (jlong) fs_info; +} + + +/* + * Open the file with the given id in the given file system + * @return the created TSK_JNI_FILEHANDLE pointer, set throw exception on error + * @param env pointer to java environment this was called from + * @param obj the java object this was called from + * @param a_fs_info the pointer to the parent file system object + * @param file_id id of the file to open + * @param attr_type type of the file attribute to open + * @param attr_id id of the file attribute to open + */ +JNIEXPORT jlong JNICALL +Java_org_sleuthkit_datamodel_SleuthkitJNI_openFileNat(JNIEnv * env, + jclass obj, jlong a_fs_info, jlong file_id, jint attr_type, jint attr_id) +{ + TSK_FS_INFO *fs_info = castFsInfo(env, a_fs_info); + if (fs_info == 0) { + //exception already set + return 0; + } + + + TSK_FS_FILE *file_info; + //open file + file_info = tsk_fs_file_open_meta(fs_info, NULL, (TSK_INUM_T) file_id); + if (file_info == NULL) { + setThrowTskCoreError(env, tsk_error_get()); + return 0; + } + + //open attribute + const TSK_FS_ATTR * tsk_fs_attr = + tsk_fs_file_attr_get_type(file_info, (TSK_FS_ATTR_TYPE_ENUM)attr_type, (uint16_t)attr_id, 1); + if (tsk_fs_attr == NULL) { + tsk_fs_file_close(file_info); + setThrowTskCoreError(env, tsk_error_get()); + return 0; + } + + //allocate file handle structure to encapsulate file and attribute + TSK_JNI_FILEHANDLE * fileHandle = + (TSK_JNI_FILEHANDLE *) tsk_malloc(sizeof(TSK_JNI_FILEHANDLE)); + if (fileHandle == NULL) { + tsk_fs_file_close(file_info); + setThrowTskCoreError(env, "Could not allocate memory for TSK_JNI_FILEHANDLE"); + return 0; + } + + fileHandle->tag = TSK_JNI_FILEHANDLE_TAG; + fileHandle->fs_file = file_info; + fileHandle->fs_attr = const_cast(tsk_fs_attr); + + return (jlong)fileHandle; +} + + +/** move a local buffer into a new Java array. + * @param env JNI env + * @param buf Buffer to copy from + * @param len Length of bytes in buf + * @returns Pointer to newly created java byte array or NULL if there is an error + */ +#if 0 +static jbyteArray +copyBufToByteArray(JNIEnv * env, const char *buf, ssize_t len) +{ + jbyteArray return_array = env->NewByteArray(len); + if (return_array == NULL) { + setThrowTskCoreError(env, "NewByteArray returned error while getting an array to copy buffer into."); + return 0; + } + env->SetByteArrayRegion(return_array, 0, len, (jbyte*)buf); + + return return_array; +} +#endif + +/** move a local buffer into an existing Java array. + * @param env JNI env + * @param jbuf Buffer to copy to + * @param buf Buffer to copy from + * @param len Length of bytes in buf + * @returns number of bytes copied or -1 on error + */ +inline static ssize_t +copyBufToByteArray(JNIEnv * env, jbyteArray jbuf, const char *buf, ssize_t len) +{ + env->SetByteArrayRegion(jbuf, 0, (jsize)len, (jbyte*)buf); + return len; +} + +/* + * Read bytes from the given image + * @return number of bytes read from the image, -1 on error + * @param env pointer to java environment this was called from + * @param obj the java object this was called from + * @param a_img_info the pointer to the image object + * @param offset the offset in bytes to start at + * @param len number of bytes to read + */ +JNIEXPORT jint JNICALL +Java_org_sleuthkit_datamodel_SleuthkitJNI_readImgNat(JNIEnv * env, + jclass obj, jlong a_img_info, jbyteArray jbuf, jlong offset, jlong len) +{ + //use fixed size stack-allocated buffer if possible + char fixed_buf [FIXED_BUF_SIZE]; + + char * buf = fixed_buf; + bool dynBuf = false; + if (len > FIXED_BUF_SIZE) { + dynBuf = true; + buf = (char *) tsk_malloc((size_t) len); + if (buf == NULL) { + setThrowTskCoreError(env); + return -1; + } + } + + TSK_IMG_INFO *img_info = castImgInfo(env, a_img_info); + if (img_info == 0) { + if (dynBuf) { + free(buf); + } + //exception already set + return -1; + } + + ssize_t bytesread = + tsk_img_read(img_info, (TSK_OFF_T) offset, buf, (size_t) len); + if (bytesread == -1) { + if (dynBuf) { + free(buf); + } + setThrowTskCoreError(env, tsk_error_get()); + return -1; + } + + // package it up for return + // adjust number bytes to copy + ssize_t copybytes = bytesread; + jsize jbuflen = env->GetArrayLength(jbuf); + if (jbuflen < copybytes) + copybytes = jbuflen; + + ssize_t copiedbytes = copyBufToByteArray(env, jbuf, buf, copybytes); + if (dynBuf) { + free(buf); + } + if (copiedbytes == -1) { + setThrowTskCoreError(env, tsk_error_get()); + } + return (jint)copiedbytes; +} + +/* +* Read bytes from the given pool +* @return number of bytes read from the pool, -1 on error +* @param env pointer to java environment this was called from +* @param obj the java object this was called from +* @param a_pool_info the pointer to the pool object +* @param jbuf the buffer to write to +* @param offset the offset in bytes to start at +* @param len number of bytes to read +*/ +JNIEXPORT jint JNICALL +Java_org_sleuthkit_datamodel_SleuthkitJNI_readPoolNat(JNIEnv * env, + jclass obj, jlong a_pool_info, jbyteArray jbuf, jlong offset, jlong len) +{ + //use fixed size stack-allocated buffer if possible + char fixed_buf[FIXED_BUF_SIZE]; + + char * buf = fixed_buf; + bool dynBuf = false; + if (len > FIXED_BUF_SIZE) { + dynBuf = true; + buf = (char *)tsk_malloc((size_t)len); + if (buf == NULL) { + setThrowTskCoreError(env); + return -1; + } + } + + TSK_POOL_INFO *pool_info = castPoolInfo(env, a_pool_info); + if (pool_info == 0) { + //exception already set + if (dynBuf) { + free(buf); + } + return -1; + } + + ssize_t bytesread = tsk_pool_read(pool_info, (TSK_DADDR_T)offset, buf, + (size_t)len); + if (bytesread == -1) { + setThrowTskCoreError(env, tsk_error_get()); + if (dynBuf) { + free(buf); + } + return -1; + } + + // package it up for return + // adjust number bytes to copy + ssize_t copybytes = bytesread; + jsize jbuflen = env->GetArrayLength(jbuf); + if (jbuflen < copybytes) + copybytes = jbuflen; + + ssize_t copiedbytes = copyBufToByteArray(env, jbuf, buf, copybytes); + if (dynBuf) { + free(buf); + } + if (copiedbytes == -1) { + setThrowTskCoreError(env, tsk_error_get()); + } + return (jint)copiedbytes; +} + + +/* + * Read bytes from the given volume system + * @return number of bytes read from the volume system, -1 on error + * @param env pointer to java environment this was called from + * @param obj the java object this was called from + * @param a_vs_info the pointer to the volume system object + * @param offset the offset in bytes to start at + * @param len number of bytes to read + */ +JNIEXPORT jint JNICALL +Java_org_sleuthkit_datamodel_SleuthkitJNI_readVsNat(JNIEnv * env, + jclass obj, jlong a_vs_info, jbyteArray jbuf, jlong offset, jlong len) +{ + //use fixed size stack-allocated buffer if possible + char fixed_buf [FIXED_BUF_SIZE]; + + char * buf = fixed_buf; + bool dynBuf = false; + if (len > FIXED_BUF_SIZE) { + dynBuf = true; + buf = (char *) tsk_malloc((size_t) len); + if (buf == NULL) { + setThrowTskCoreError(env); + return -1; + } + } + + TSK_VS_INFO *vs_info = castVsInfo(env, a_vs_info); + if (vs_info == 0) { + //exception already set + if (dynBuf) { + free(buf); + } + return -1; + } + + ssize_t bytesread = tsk_vs_read_block(vs_info, (TSK_DADDR_T) offset, buf, + (size_t) len); + if (bytesread == -1) { + setThrowTskCoreError(env, tsk_error_get()); + if (dynBuf) { + free(buf); + } + return -1; + } + + // package it up for return + // adjust number bytes to copy + ssize_t copybytes = bytesread; + jsize jbuflen = env->GetArrayLength(jbuf); + if (jbuflen < copybytes) + copybytes = jbuflen; + + ssize_t copiedbytes = copyBufToByteArray(env, jbuf, buf, copybytes); + if (dynBuf) { + free(buf); + } + if (copiedbytes == -1) { + setThrowTskCoreError(env, tsk_error_get()); + } + return (jint)copiedbytes; +} + + +/* + * Read bytes from the given volume + * @return number of bytes read from the volume or -1 on error + * @param env pointer to java environment this was called from + * @param obj the java object this was called from + * @param a_vol_info the pointer to the volume object + * @param offset the offset in bytes to start at + * @param len number of bytes to read + */ + +JNIEXPORT jint JNICALL +Java_org_sleuthkit_datamodel_SleuthkitJNI_readVolNat(JNIEnv * env, + jclass obj, jlong a_vol_info, jbyteArray jbuf, jlong offset, jlong len) +{ + //use fixed size stack-allocated buffer if possible + char fixed_buf [FIXED_BUF_SIZE]; + + char * buf = fixed_buf; + bool dynBuf = false; + if (len > FIXED_BUF_SIZE) { + dynBuf = true; + buf = (char *) tsk_malloc((size_t) len); + if (buf == NULL) { + setThrowTskCoreError(env); + return -1; + } + } + + TSK_VS_PART_INFO *vol_part_info = castVsPartInfo(env, a_vol_info); + if (vol_part_info == 0) { + if (dynBuf) { + free(buf); + } + //exception already set + return -1; + } + ssize_t bytesread = + tsk_vs_part_read(vol_part_info, (TSK_OFF_T) offset, buf, + (size_t) len); + if (bytesread == -1) { + setThrowTskCoreError(env, tsk_error_get()); + if (dynBuf) { + free(buf); + } + return -1; + } + + // package it up for return + // adjust number bytes to copy + ssize_t copybytes = bytesread; + jsize jbuflen = env->GetArrayLength(jbuf); + if (jbuflen < copybytes) + copybytes = jbuflen; + + ssize_t copiedbytes = copyBufToByteArray(env, jbuf, buf, copybytes); + if (dynBuf) { + free(buf); + } + if (copiedbytes == -1) { + setThrowTskCoreError(env, tsk_error_get()); + } + return (jint)copiedbytes; +} + + +/* + * Read bytes from the given file system + * @return number of bytes read from the file system, -1 on error + * @param env pointer to java environment this was called from + * @param obj the java object this was called from + * @param a_fs_info the pointer to the file system object + * @param offset the offset in bytes to start at + * @param len number of bytes to read + */ +JNIEXPORT jint JNICALL +Java_org_sleuthkit_datamodel_SleuthkitJNI_readFsNat(JNIEnv * env, + jclass obj, jlong a_fs_info, jbyteArray jbuf, jlong offset, jlong len) +{ + //use fixed size stack-allocated buffer if possible + char fixed_buf [FIXED_BUF_SIZE]; + + char * buf = fixed_buf; + bool dynBuf = false; + if (len > FIXED_BUF_SIZE) { + dynBuf = true; + buf = (char *) tsk_malloc((size_t) len); + if (buf == NULL) { + setThrowTskCoreError(env); + return -1; + } + } + + TSK_FS_INFO *fs_info = castFsInfo(env, a_fs_info); + if (fs_info == 0) { + if (dynBuf) { + free(buf); + } + //exception already set + return -1; + } + + ssize_t bytesread = + tsk_fs_read(fs_info, (TSK_OFF_T) offset, buf, (size_t) len); + if (bytesread == -1) { + if (dynBuf) { + free(buf); + } + setThrowTskCoreError(env, tsk_error_get()); + return -1; + } + + // package it up for return + // adjust number bytes to copy + ssize_t copybytes = bytesread; + jsize jbuflen = env->GetArrayLength(jbuf); + if (jbuflen < copybytes) + copybytes = jbuflen; + + ssize_t copiedbytes = copyBufToByteArray(env, jbuf, buf, copybytes); + if (dynBuf) { + free(buf); + } + if (copiedbytes == -1) { + setThrowTskCoreError(env, tsk_error_get()); + } + return (jint)copiedbytes; +} + + +/** + * Flag used by readFileNat to specify if the offset is relative to the start of the file + * or the start of the slack space + */ +typedef enum { + TSK_FS_FILE_READ_OFFSET_TYPE_START_OF_FILE = 0x00, + TSK_FS_FILE_READ_OFFSET_TYPE_START_OF_SLACK = 0x01, +} TSK_FS_FILE_READ_OFFSET_TYPE_ENUM; + +/* + * Read bytes from the given file + * @return number of bytes read, or -1 on error + * @param env pointer to java environment this was called from + * @param obj the java object this was called from + * @param a_file_handle the pointer to the TSK_JNI_FILEHANDLE object + * @param jbuf jvm allocated buffer to read to + * @param offset the offset in bytes to start at + * @param len number of bytes to read + */ +JNIEXPORT jint JNICALL +Java_org_sleuthkit_datamodel_SleuthkitJNI_readFileNat(JNIEnv * env, + jclass obj, jlong a_file_handle, jbyteArray jbuf, jlong offset, jint offset_type, jlong len) +{ + //use fixed size stack-allocated buffer if possible + char fixed_buf [FIXED_BUF_SIZE]; + + char * buf = fixed_buf; + bool dynBuf = false; + if (len > FIXED_BUF_SIZE) { + dynBuf = true; + buf = (char *) tsk_malloc((size_t) len); + if (buf == NULL) { + setThrowTskCoreError(env); + return -1; + } + } + + const TSK_JNI_FILEHANDLE *file_handle = castJniFileHandle(env, a_file_handle); + if (file_handle == 0) { + if (dynBuf) { + free(buf); + } + //exception already set + return -1; + } + + TSK_FS_ATTR * tsk_fs_attr = file_handle->fs_attr; + + TSK_FS_FILE_READ_FLAG_ENUM readFlag = TSK_FS_FILE_READ_FLAG_NONE; + TSK_OFF_T readOffset = (TSK_OFF_T) offset; + if(offset_type == TSK_FS_FILE_READ_OFFSET_TYPE_START_OF_SLACK){ + readFlag = TSK_FS_FILE_READ_FLAG_SLACK; + readOffset += tsk_fs_attr->nrd.initsize; + } + + //read attribute + ssize_t bytesread = tsk_fs_attr_read(tsk_fs_attr, readOffset, buf, (size_t) len, + readFlag); + if (bytesread == -1) { + if (dynBuf) { + free(buf); + } + setThrowTskCoreError(env, tsk_error_get()); + return -1; + } + + // package it up for return + // adjust number bytes to copy + ssize_t copybytes = bytesread; + jsize jbuflen = env->GetArrayLength(jbuf); + if (jbuflen < copybytes) + copybytes = jbuflen; + + ssize_t copiedbytes = copyBufToByteArray(env, jbuf, buf, copybytes); + if (dynBuf) { + free(buf); + } + if (copiedbytes == -1) { + setThrowTskCoreError(env, tsk_error_get()); + } + return (jint)copiedbytes; +} + + +/** + * Runs istat on a given file and saves the output to a temp file. + * + * @returns -1 on error (and throws exception) + */ +JNIEXPORT jint JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_saveFileMetaDataTextNat + (JNIEnv *env, jclass obj, jlong a_file_handle, jstring a_tmp_path) +{ + const TSK_JNI_FILEHANDLE *file_handle = castJniFileHandle(env, a_file_handle); + if (file_handle == 0) { + //exception already set + return -1; + } + + // check the pointers + if (file_handle->fs_file == NULL || file_handle->fs_file->fs_info == NULL || file_handle->fs_file->meta == NULL) { + setThrowTskCoreError(env, "NULL pointers for istat file."); + return -1; + } + TSK_FS_INFO *fs_info = file_handle->fs_file->fs_info; + + // open a file to write the details to + jboolean isCopy; + char *str8 = (char *) env->GetStringUTFChars(a_tmp_path, &isCopy); + FILE *hFile = fopen(str8, "w"); + if (hFile == NULL) { + env->ReleaseStringUTFChars(a_tmp_path, str8); + setThrowTskCoreError(env, "Couldn't open istat temp file for writing."); + return -1; + } + env->ReleaseStringUTFChars(a_tmp_path, str8); + + if (fs_info->istat(fs_info, TSK_FS_ISTAT_RUNLIST, hFile, file_handle->fs_file->meta->addr, 0, 0) != 0) { + fclose(hFile); + setThrowTskCoreError(env); + return -1; + } + + fclose(hFile); + return 0; +} + +/* + * Close the given image + * @param env pointer to java environment this was called from + * @param obj the java object this was called from + * @param a_img_info the pointer to the image object + */ +JNIEXPORT void JNICALL +Java_org_sleuthkit_datamodel_SleuthkitJNI_closeImgNat(JNIEnv * env, + jclass obj, jlong a_img_info) +{ + TSK_IMG_INFO *img_info = castImgInfo(env, a_img_info); + if (img_info == 0) { + //exception already set + return; + } + tsk_img_close(img_info); +} + +/* + * Close the given volume system + * @param env pointer to java environment this was called from + * @param obj the java object this was called from + * @param a_vs_info the pointer to the volume system object + */ +JNIEXPORT void JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_closeVsNat + (JNIEnv * env, jclass obj, jlong a_vs_info) { + TSK_VS_INFO *vs_info = castVsInfo(env, a_vs_info); + if (vs_info == 0) { + //exception already set + return; + } + tsk_vs_close(vs_info); +} + +/* + * Close the given file system + * @param env pointer to java environment this was called from + * @param obj the java object this was called from + * @param a_fs_info the pointer to the file system object + */ +JNIEXPORT void JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_closeFsNat + (JNIEnv * env, jclass obj, jlong a_fs_info) { + TSK_FS_INFO *fs_info = castFsInfo(env, a_fs_info); + if (fs_info == 0) { + //exception already set + return; + } + tsk_fs_close(fs_info); +} + +/* +* Close the given pool +* @param env pointer to java environment this was called from +* @param obj the java object this was called from +* @param a_pool_info the pointer to the pool object +*/ +JNIEXPORT void JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_closePoolNat +(JNIEnv * env, jclass obj, jlong a_pool_info) { + TSK_POOL_INFO *pool_info = castPoolInfo(env, a_pool_info); + if (pool_info == 0) { + //exception already set + return; + } + tsk_pool_close(pool_info); +} + +/* + * Close the given file + * @param env pointer to java environment this was called from + * @param obj the java object this was called from + * @param a_file_info the pointer to the file object + */ +JNIEXPORT void JNICALL +Java_org_sleuthkit_datamodel_SleuthkitJNI_closeFileNat(JNIEnv * env, + jclass obj, jlong a_file_info) +{ + TSK_JNI_FILEHANDLE *file_handle = castJniFileHandle(env, a_file_info); + if (file_handle == 0) { + //exception already set + return; + } + + TSK_FS_FILE * file_info = file_handle->fs_file; + tsk_fs_file_close(file_info); //also closes the attribute + + file_handle->fs_file = NULL; + file_handle->fs_attr = NULL; + file_handle->tag = 0; + free (file_handle); +} + +/* + * Get the current Sleuthkit version number + * @return the version string + * @param env pointer to java environment this was called from + * @param obj the java object this was called from + */ +JNIEXPORT jstring JNICALL +Java_org_sleuthkit_datamodel_SleuthkitJNI_getVersionNat(JNIEnv * env, + jclass obj) +{ + const char *cversion = tsk_version_get_str(); + jstring jversion = (*env).NewStringUTF(cversion); + return jversion; +} + +/* + * Get the current directory being analyzed during AddImage + * @return the path of the current directory + * + */ +JNIEXPORT jstring JNICALL + Java_org_sleuthkit_datamodel_SleuthkitJNI_getCurDirNat + (JNIEnv * env,jclass obj, jlong dbHandle) +{ + TskAutoDbJava *tskAuto = ((TskAutoDbJava *) dbHandle); + const std::string curDir = tskAuto->getCurDir(); + jstring jdir = (*env).NewStringUTF(curDir.c_str()); + return jdir; +} + +/* + * Enable verbose logging and redirect stderr to the given log file. + * @param env pointer to java environment this was called from + * @param obj the java object this was called from + * @param logPath The log file to append to. + */ +JNIEXPORT void JNICALL +Java_org_sleuthkit_datamodel_SleuthkitJNI_startVerboseLoggingNat + (JNIEnv * env, jclass obj, jstring logPath) +{ + jboolean isCopy; + char *str8 = (char *) env->GetStringUTFChars(logPath, &isCopy); + if (freopen(str8, "a", stderr) == NULL) { + env->ReleaseStringUTFChars(logPath, str8); + setThrowTskCoreError(env, "Couldn't open verbose log file for appending."); + return; + } + env->ReleaseStringUTFChars(logPath, str8); + tsk_verbose++; +} + +/* + * Creates an MD5 index for a hash database. + * @param env Pointer to Java environment from which this method was called. + * @param obj The Java object from which this method was called. + * @param dbHandle A handle for the hash database. + */ +JNIEXPORT void JNICALL +Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbCreateIndexNat (JNIEnv * env, + jclass obj, jint dbHandle) +{ + if((size_t)dbHandle > hashDbs.size()) { + setThrowTskCoreError(env, "Invalid database handle"); + return; + } + + TSK_HDB_INFO *db = hashDbs.at(dbHandle-1); + if (db == NULL) { + setThrowTskCoreError(env, "Invalid database handle"); + return; + } + + TSK_TCHAR idx_type[1024]; + if(db->db_type == TSK_HDB_DBTYPE_MD5SUM_ID) { + TSNPRINTF(idx_type, 1024, _TSK_T("%") PRIcTSK, TSK_HDB_DBTYPE_MD5SUM_STR); + } + else if(db->db_type == TSK_HDB_DBTYPE_HK_ID) { + TSNPRINTF(idx_type, 1024, _TSK_T("%") PRIcTSK, TSK_HDB_DBTYPE_HK_STR); + } + else if(db->db_type == TSK_HDB_DBTYPE_ENCASE_ID) { + TSNPRINTF(idx_type, 1024, _TSK_T("%") PRIcTSK, TSK_HDB_DBTYPE_ENCASE_STR); + } + else { + // The Java bindings only support the generation of md5 indexes for + // an NSRL hash database. + TSNPRINTF(idx_type, 1024, _TSK_T("%") PRIcTSK, TSK_HDB_DBTYPE_NSRL_MD5_STR); + } + + if (tsk_hdb_make_index(db, idx_type) != 0) { + setThrowTskCoreError(env, tsk_error_get_errstr()); + } +} + +/* + * Queries whether or not an index for MD5 look ups exists for a hash database. + * @param env Pointer to Java environment from which this method was called. + * @param obj The Java object from which this method was called. + * @param dbHandle A handle for the hash database. + * @return True if the index exists. + */ +JNIEXPORT jboolean JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbIndexExistsNat + (JNIEnv * env, jclass obj, jint dbHandle) { + if((size_t)dbHandle > hashDbs.size()) { + setThrowTskCoreError(env, "Invalid database handle"); + return (jboolean)false; + } + + TSK_HDB_INFO *db = hashDbs.at(dbHandle-1); + if (db == NULL) { + setThrowTskCoreError(env, "Invalid database handle"); + return (jboolean)false; + } + + return (jboolean)(db->has_index(db, TSK_HDB_HTYPE_MD5_ID) == 1); +} + +/* + * Query and get size of the device (such as physical disk, or image) pointed by the path + * Might require elevated priviletes to work (otherwise will error) + * @param env pointer to java environment this was called from + * @param obj the java object this was called from + * @param devPathJ the device path + * @return size of device, set throw jni exception on error + */ +JNIEXPORT jlong JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_findDeviceSizeNat + (JNIEnv * env, jclass obj, jstring devPathJ) { + + jlong devSize = 0; + const char* devPath = env->GetStringUTFChars(devPathJ, 0); + + // open the image to get the size + TSK_IMG_INFO * img_info = + tsk_img_open_utf8_sing(devPath, TSK_IMG_TYPE_DETECT, 0); + if (img_info == NULL) { + setThrowTskCoreError(env, tsk_error_get()); + env->ReleaseStringUTFChars(devPathJ , devPath); + return -1; + } + + TSK_OFF_T imgSize = img_info->size; + devSize = imgSize; + + //cleanup + tsk_img_close(img_info); + env->ReleaseStringUTFChars(devPathJ , devPath); + + return devSize; +} + +/* + * Test whether an image is supported + * @param env pointer to java environment this was called from + * @param obj the java object this was called from + * @param imagePathJ the image path + * @return true if the image can be processed, false otherwise + */ +JNIEXPORT jboolean JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_isImageSupportedNat + (JNIEnv * env, jclass obj, jstring imagePathJ) { + + TskIsImageSupported tskIsImage; + TSK_TCHAR imagePathT[1024]; + toTCHAR(env, imagePathT, 1024, imagePathJ); + + // It seems like passing &imagePathT should work instead of making this new array, + // but it generated an EXCEPTION_ACCESS_VIOLATION during testing. + TSK_TCHAR ** imagePaths = (TSK_TCHAR**)tsk_malloc((1) * sizeof(TSK_TCHAR*)); + bool result; + imagePaths[0] = imagePathT; + if (tskIsImage.openImage(1, imagePaths, TSK_IMG_TYPE_DETECT, 0)) { + result = false; + } else { + if (tskIsImage.findFilesInImg()) { + result = false; + } else { + if (tskIsImage.isImageSupported()) { + result = true; + } + else { + result = false; + } + } + } + + // Cleanup + free(imagePaths); + + return (jboolean) result; +} + +/* +* Returns the current Sleuthkit version as a long +* @return the current version +*/ +JNIEXPORT jlong JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_getSleuthkitVersionNat +(JNIEnv * env, jclass obj) { + return (jlong)TSK_VERSION_NUM; +} + + +/* + * Finish the image being created by image writer. + * @param env pointer to java environment this was called from + * @param obj the java object this was called from + * @param a_img_info the image info pointer + */ +JNIEXPORT jint JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_finishImageWriterNat +(JNIEnv * env, jclass obj, jlong a_img_info) { + // Set up the TSK_IMG_INFO object + TSK_IMG_INFO *img_info = castImgInfo(env, a_img_info); + return tsk_img_writer_finish(img_info); +} + +/* + * Get the progess of the finishImage process as an integer from 0 to 100 + */ +JNIEXPORT jint JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_getFinishImageProgressNat +(JNIEnv * env, jclass obj, jlong a_img_info) { + // Set up the TSK_IMG_INFO object + TSK_IMG_INFO *img_info = castImgInfo(env, a_img_info); + IMG_RAW_INFO *raw_info = (IMG_RAW_INFO*)img_info; + + if (raw_info->img_writer != NULL) { + return (raw_info->img_writer->finishProgress); + } + return 0; + +} + +/* +* Cancel the finishImage process +*/ +JNIEXPORT void JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_cancelFinishImageNat +(JNIEnv * env, jclass obj, jlong a_img_info) { + // Set up the TSK_IMG_INFO object + TSK_IMG_INFO *img_info = castImgInfo(env, a_img_info); + IMG_RAW_INFO *raw_info = (IMG_RAW_INFO*)img_info; + + if (raw_info->img_writer != NULL) { + raw_info->img_writer->cancelFinish = 1; + } + return ; +} diff --git a/sleuthKitLibs/4.10.1/dataModel_SleuthkitJNI.h b/sleuthKitLibs/4.10.1/dataModel_SleuthkitJNI.h new file mode 100644 index 0000000000..418db74575 --- /dev/null +++ b/sleuthKitLibs/4.10.1/dataModel_SleuthkitJNI.h @@ -0,0 +1,540 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class org_sleuthkit_datamodel_SleuthkitJNI */ + +#ifndef _Included_org_sleuthkit_datamodel_SleuthkitJNI +#define _Included_org_sleuthkit_datamodel_SleuthkitJNI +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: org_sleuthkit_datamodel_SleuthkitJNI + * Method: getVersionNat + * Signature: ()Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_getVersionNat + (JNIEnv *, jclass); + +/* + * Class: org_sleuthkit_datamodel_SleuthkitJNI + * Method: startVerboseLoggingNat + * Signature: (Ljava/lang/String;)V + */ +JNIEXPORT void JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_startVerboseLoggingNat + (JNIEnv *, jclass, jstring); + +/* + * Class: org_sleuthkit_datamodel_SleuthkitJNI + * Method: hashDbOpenNat + * Signature: (Ljava/lang/String;)I + */ +JNIEXPORT jint JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbOpenNat + (JNIEnv *, jclass, jstring); + +/* + * Class: org_sleuthkit_datamodel_SleuthkitJNI + * Method: hashDbNewNat + * Signature: (Ljava/lang/String;)I + */ +JNIEXPORT jint JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbNewNat + (JNIEnv *, jclass, jstring); + +/* + * Class: org_sleuthkit_datamodel_SleuthkitJNI + * Method: hashDbBeginTransactionNat + * Signature: (I)I + */ +JNIEXPORT jint JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbBeginTransactionNat + (JNIEnv *, jclass, jint); + +/* + * Class: org_sleuthkit_datamodel_SleuthkitJNI + * Method: hashDbCommitTransactionNat + * Signature: (I)I + */ +JNIEXPORT jint JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbCommitTransactionNat + (JNIEnv *, jclass, jint); + +/* + * Class: org_sleuthkit_datamodel_SleuthkitJNI + * Method: hashDbRollbackTransactionNat + * Signature: (I)I + */ +JNIEXPORT jint JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbRollbackTransactionNat + (JNIEnv *, jclass, jint); + +/* + * Class: org_sleuthkit_datamodel_SleuthkitJNI + * Method: hashDbAddEntryNat + * Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)I + */ +JNIEXPORT jint JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbAddEntryNat + (JNIEnv *, jclass, jstring, jstring, jstring, jstring, jstring, jint); + +/* + * Class: org_sleuthkit_datamodel_SleuthkitJNI + * Method: hashDbIsUpdateableNat + * Signature: (I)Z + */ +JNIEXPORT jboolean JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbIsUpdateableNat + (JNIEnv *, jclass, jint); + +/* + * Class: org_sleuthkit_datamodel_SleuthkitJNI + * Method: hashDbIsReindexableNat + * Signature: (I)Z + */ +JNIEXPORT jboolean JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbIsReindexableNat + (JNIEnv *, jclass, jint); + +/* + * Class: org_sleuthkit_datamodel_SleuthkitJNI + * Method: hashDbPathNat + * Signature: (I)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbPathNat + (JNIEnv *, jclass, jint); + +/* + * Class: org_sleuthkit_datamodel_SleuthkitJNI + * Method: hashDbIndexPathNat + * Signature: (I)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbIndexPathNat + (JNIEnv *, jclass, jint); + +/* + * Class: org_sleuthkit_datamodel_SleuthkitJNI + * Method: hashDbGetDisplayName + * Signature: (I)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbGetDisplayName + (JNIEnv *, jclass, jint); + +/* + * Class: org_sleuthkit_datamodel_SleuthkitJNI + * Method: hashDbCloseAll + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbCloseAll + (JNIEnv *, jclass); + +/* + * Class: org_sleuthkit_datamodel_SleuthkitJNI + * Method: hashDbClose + * Signature: (I)V + */ +JNIEXPORT void JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbClose + (JNIEnv *, jclass, jint); + +/* + * Class: org_sleuthkit_datamodel_SleuthkitJNI + * Method: hashDbCreateIndexNat + * Signature: (I)V + */ +JNIEXPORT void JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbCreateIndexNat + (JNIEnv *, jclass, jint); + +/* + * Class: org_sleuthkit_datamodel_SleuthkitJNI + * Method: hashDbIndexExistsNat + * Signature: (I)Z + */ +JNIEXPORT jboolean JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbIndexExistsNat + (JNIEnv *, jclass, jint); + +/* + * Class: org_sleuthkit_datamodel_SleuthkitJNI + * Method: hashDbIsIdxOnlyNat + * Signature: (I)Z + */ +JNIEXPORT jboolean JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbIsIdxOnlyNat + (JNIEnv *, jclass, jint); + +/* + * Class: org_sleuthkit_datamodel_SleuthkitJNI + * Method: hashDbLookup + * Signature: (Ljava/lang/String;I)Z + */ +JNIEXPORT jboolean JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbLookup + (JNIEnv *, jclass, jstring, jint); + +/* + * Class: org_sleuthkit_datamodel_SleuthkitJNI + * Method: hashDbLookupVerbose + * Signature: (Ljava/lang/String;I)Lorg/sleuthkit/datamodel/HashHitInfo; + */ +JNIEXPORT jobject JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbLookupVerbose + (JNIEnv *, jclass, jstring, jint); + +/* + * Class: org_sleuthkit_datamodel_SleuthkitJNI + * Method: initAddImgNat + * Signature: (Lorg/sleuthkit/datamodel/TskCaseDbBridge;Ljava/lang/String;ZZ)J + */ +JNIEXPORT jlong JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_initAddImgNat + (JNIEnv *, jclass, jobject, jstring, jboolean, jboolean); + +/* + * Class: org_sleuthkit_datamodel_SleuthkitJNI + * Method: initializeAddImgNat + * Signature: (Lorg/sleuthkit/datamodel/TskCaseDbBridge;Ljava/lang/String;ZZZ)J + */ +JNIEXPORT jlong JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_initializeAddImgNat + (JNIEnv *, jclass, jobject, jstring, jboolean, jboolean, jboolean); + +/* + * Class: org_sleuthkit_datamodel_SleuthkitJNI + * Method: runOpenAndAddImgNat + * Signature: (JLjava/lang/String;[Ljava/lang/String;ILjava/lang/String;)V + */ +JNIEXPORT void JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_runOpenAndAddImgNat + (JNIEnv *, jclass, jlong, jstring, jobjectArray, jint, jstring); + +/* + * Class: org_sleuthkit_datamodel_SleuthkitJNI + * Method: runAddImgNat + * Signature: (JLjava/lang/String;JJLjava/lang/String;Ljava/lang/String;)V + */ +JNIEXPORT void JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_runAddImgNat + (JNIEnv *, jclass, jlong, jstring, jlong, jlong, jstring, jstring); + +/* + * Class: org_sleuthkit_datamodel_SleuthkitJNI + * Method: stopAddImgNat + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_stopAddImgNat + (JNIEnv *, jclass, jlong); + +/* + * Class: org_sleuthkit_datamodel_SleuthkitJNI + * Method: finishAddImgNat + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_finishAddImgNat + (JNIEnv *, jclass, jlong); + +/* + * Class: org_sleuthkit_datamodel_SleuthkitJNI + * Method: openImgNat + * Signature: ([Ljava/lang/String;II)J + */ +JNIEXPORT jlong JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_openImgNat + (JNIEnv *, jclass, jobjectArray, jint, jint); + +/* + * Class: org_sleuthkit_datamodel_SleuthkitJNI + * Method: openVsNat + * Signature: (JJ)J + */ +JNIEXPORT jlong JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_openVsNat + (JNIEnv *, jclass, jlong, jlong); + +/* + * Class: org_sleuthkit_datamodel_SleuthkitJNI + * Method: openVolNat + * Signature: (JJ)J + */ +JNIEXPORT jlong JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_openVolNat + (JNIEnv *, jclass, jlong, jlong); + +/* + * Class: org_sleuthkit_datamodel_SleuthkitJNI + * Method: openPoolNat + * Signature: (JJ)J + */ +JNIEXPORT jlong JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_openPoolNat + (JNIEnv *, jclass, jlong, jlong); + +/* + * Class: org_sleuthkit_datamodel_SleuthkitJNI + * Method: getImgInfoForPoolNat + * Signature: (JJ)J + */ +JNIEXPORT jlong JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_getImgInfoForPoolNat + (JNIEnv *, jclass, jlong, jlong); + +/* + * Class: org_sleuthkit_datamodel_SleuthkitJNI + * Method: openFsNat + * Signature: (JJ)J + */ +JNIEXPORT jlong JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_openFsNat + (JNIEnv *, jclass, jlong, jlong); + +/* + * Class: org_sleuthkit_datamodel_SleuthkitJNI + * Method: openFileNat + * Signature: (JJII)J + */ +JNIEXPORT jlong JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_openFileNat + (JNIEnv *, jclass, jlong, jlong, jint, jint); + +/* + * Class: org_sleuthkit_datamodel_SleuthkitJNI + * Method: readImgNat + * Signature: (J[BJJ)I + */ +JNIEXPORT jint JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_readImgNat + (JNIEnv *, jclass, jlong, jbyteArray, jlong, jlong); + +/* + * Class: org_sleuthkit_datamodel_SleuthkitJNI + * Method: readVsNat + * Signature: (J[BJJ)I + */ +JNIEXPORT jint JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_readVsNat + (JNIEnv *, jclass, jlong, jbyteArray, jlong, jlong); + +/* + * Class: org_sleuthkit_datamodel_SleuthkitJNI + * Method: readPoolNat + * Signature: (J[BJJ)I + */ +JNIEXPORT jint JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_readPoolNat + (JNIEnv *, jclass, jlong, jbyteArray, jlong, jlong); + +/* + * Class: org_sleuthkit_datamodel_SleuthkitJNI + * Method: readVolNat + * Signature: (J[BJJ)I + */ +JNIEXPORT jint JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_readVolNat + (JNIEnv *, jclass, jlong, jbyteArray, jlong, jlong); + +/* + * Class: org_sleuthkit_datamodel_SleuthkitJNI + * Method: readFsNat + * Signature: (J[BJJ)I + */ +JNIEXPORT jint JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_readFsNat + (JNIEnv *, jclass, jlong, jbyteArray, jlong, jlong); + +/* + * Class: org_sleuthkit_datamodel_SleuthkitJNI + * Method: readFileNat + * Signature: (J[BJIJ)I + */ +JNIEXPORT jint JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_readFileNat + (JNIEnv *, jclass, jlong, jbyteArray, jlong, jint, jlong); + +/* + * Class: org_sleuthkit_datamodel_SleuthkitJNI + * Method: saveFileMetaDataTextNat + * Signature: (JLjava/lang/String;)I + */ +JNIEXPORT jint JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_saveFileMetaDataTextNat + (JNIEnv *, jclass, jlong, jstring); + +/* + * Class: org_sleuthkit_datamodel_SleuthkitJNI + * Method: getPathsForImageNat + * Signature: (J)[Ljava/lang/String; + */ +JNIEXPORT jobjectArray JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_getPathsForImageNat + (JNIEnv *, jclass, jlong); + +/* + * Class: org_sleuthkit_datamodel_SleuthkitJNI + * Method: getSizeForImageNat + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_getSizeForImageNat + (JNIEnv *, jclass, jlong); + +/* + * Class: org_sleuthkit_datamodel_SleuthkitJNI + * Method: getTypeForImageNat + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_getTypeForImageNat + (JNIEnv *, jclass, jlong); + +/* + * Class: org_sleuthkit_datamodel_SleuthkitJNI + * Method: getSectorSizeForImageNat + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_getSectorSizeForImageNat + (JNIEnv *, jclass, jlong); + +/* + * Class: org_sleuthkit_datamodel_SleuthkitJNI + * Method: getMD5HashForImageNat + * Signature: (J)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_getMD5HashForImageNat + (JNIEnv *, jclass, jlong); + +/* + * Class: org_sleuthkit_datamodel_SleuthkitJNI + * Method: getSha1HashForImageNat + * Signature: (J)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_getSha1HashForImageNat + (JNIEnv *, jclass, jlong); + +/* + * Class: org_sleuthkit_datamodel_SleuthkitJNI + * Method: getCollectionDetailsForImageNat + * Signature: (J)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_getCollectionDetailsForImageNat + (JNIEnv *, jclass, jlong); + +/* + * Class: org_sleuthkit_datamodel_SleuthkitJNI + * Method: closeImgNat + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_closeImgNat + (JNIEnv *, jclass, jlong); + +/* + * Class: org_sleuthkit_datamodel_SleuthkitJNI + * Method: closePoolNat + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_closePoolNat + (JNIEnv *, jclass, jlong); + +/* + * Class: org_sleuthkit_datamodel_SleuthkitJNI + * Method: closeVsNat + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_closeVsNat + (JNIEnv *, jclass, jlong); + +/* + * Class: org_sleuthkit_datamodel_SleuthkitJNI + * Method: closeFsNat + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_closeFsNat + (JNIEnv *, jclass, jlong); + +/* + * Class: org_sleuthkit_datamodel_SleuthkitJNI + * Method: closeFileNat + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_closeFileNat + (JNIEnv *, jclass, jlong); + +/* + * Class: org_sleuthkit_datamodel_SleuthkitJNI + * Method: findDeviceSizeNat + * Signature: (Ljava/lang/String;)J + */ +JNIEXPORT jlong JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_findDeviceSizeNat + (JNIEnv *, jclass, jstring); + +/* + * Class: org_sleuthkit_datamodel_SleuthkitJNI + * Method: getCurDirNat + * Signature: (J)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_getCurDirNat + (JNIEnv *, jclass, jlong); + +/* + * Class: org_sleuthkit_datamodel_SleuthkitJNI + * Method: isImageSupportedNat + * Signature: (Ljava/lang/String;)Z + */ +JNIEXPORT jboolean JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_isImageSupportedNat + (JNIEnv *, jclass, jstring); + +/* + * Class: org_sleuthkit_datamodel_SleuthkitJNI + * Method: getSleuthkitVersionNat + * Signature: ()J + */ +JNIEXPORT jlong JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_getSleuthkitVersionNat + (JNIEnv *, jclass); + +/* + * Class: org_sleuthkit_datamodel_SleuthkitJNI + * Method: finishImageWriterNat + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_finishImageWriterNat + (JNIEnv *, jclass, jlong); + +/* + * Class: org_sleuthkit_datamodel_SleuthkitJNI + * Method: getFinishImageProgressNat + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_getFinishImageProgressNat + (JNIEnv *, jclass, jlong); + +/* + * Class: org_sleuthkit_datamodel_SleuthkitJNI + * Method: cancelFinishImageNat + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_cancelFinishImageNat + (JNIEnv *, jclass, jlong); + +#ifdef __cplusplus +} +#endif +#endif +/* Header for class org_sleuthkit_datamodel_SleuthkitJNI_TSK_FS_FILE_READ_OFFSET_TYPE_ENUM */ + +#ifndef _Included_org_sleuthkit_datamodel_SleuthkitJNI_TSK_FS_FILE_READ_OFFSET_TYPE_ENUM +#define _Included_org_sleuthkit_datamodel_SleuthkitJNI_TSK_FS_FILE_READ_OFFSET_TYPE_ENUM +#ifdef __cplusplus +extern "C" { +#endif +#ifdef __cplusplus +} +#endif +#endif +/* Header for class org_sleuthkit_datamodel_SleuthkitJNI_CaseDbHandle */ + +#ifndef _Included_org_sleuthkit_datamodel_SleuthkitJNI_CaseDbHandle +#define _Included_org_sleuthkit_datamodel_SleuthkitJNI_CaseDbHandle +#ifdef __cplusplus +extern "C" { +#endif +#ifdef __cplusplus +} +#endif +#endif +/* Header for class org_sleuthkit_datamodel_SleuthkitJNI_CaseDbHandle_AddImageProcess */ + +#ifndef _Included_org_sleuthkit_datamodel_SleuthkitJNI_CaseDbHandle_AddImageProcess +#define _Included_org_sleuthkit_datamodel_SleuthkitJNI_CaseDbHandle_AddImageProcess +#ifdef __cplusplus +extern "C" { +#endif +#ifdef __cplusplus +} +#endif +#endif +/* Header for class org_sleuthkit_datamodel_SleuthkitJNI_HandleCache */ + +#ifndef _Included_org_sleuthkit_datamodel_SleuthkitJNI_HandleCache +#define _Included_org_sleuthkit_datamodel_SleuthkitJNI_HandleCache +#ifdef __cplusplus +extern "C" { +#endif +#ifdef __cplusplus +} +#endif +#endif +/* Header for class org_sleuthkit_datamodel_SleuthkitJNI_CaseHandles */ + +#ifndef _Included_org_sleuthkit_datamodel_SleuthkitJNI_CaseHandles +#define _Included_org_sleuthkit_datamodel_SleuthkitJNI_CaseHandles +#ifdef __cplusplus +extern "C" { +#endif +#ifdef __cplusplus +} +#endif +#endif diff --git a/sleuthKitLibs/4.10.1/dataModel_SleuthkitJNI.lo b/sleuthKitLibs/4.10.1/dataModel_SleuthkitJNI.lo new file mode 100644 index 0000000000..6092729615 --- /dev/null +++ b/sleuthKitLibs/4.10.1/dataModel_SleuthkitJNI.lo @@ -0,0 +1,12 @@ +# dataModel_SleuthkitJNI.lo - a libtool object file +# Generated by libtool (GNU libtool) 2.5.4 +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# Name of the PIC object. +pic_object='.libs/dataModel_SleuthkitJNI.o' + +# Name of the non-PIC object +non_pic_object='dataModel_SleuthkitJNI.o' + diff --git a/sleuthKitLibs/4.10.1/dataModel_SleuthkitJNI.o b/sleuthKitLibs/4.10.1/dataModel_SleuthkitJNI.o new file mode 100644 index 0000000000..def26eaee3 Binary files /dev/null and b/sleuthKitLibs/4.10.1/dataModel_SleuthkitJNI.o differ diff --git a/sleuthKitLibs/4.10.1/libtsk_jni.la b/sleuthKitLibs/4.10.1/libtsk_jni.la new file mode 100644 index 0000000000..facfa79158 --- /dev/null +++ b/sleuthKitLibs/4.10.1/libtsk_jni.la @@ -0,0 +1,42 @@ +# libtsk_jni.la - a libtool library file +# Generated by libtool (GNU libtool) 2.5.4 +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# The name that we can dlopen(3). +dlname='libtsk_jni.0.dylib' + +# Names of this library. +library_names='libtsk_jni.0.dylib libtsk_jni.dylib' + +# The name of the static archive. +old_library='libtsk_jni.a' + +# Linker flags that cannot go in dependency_libs. +inherited_linker_flags=' -pthread' + +# Libraries that this one depends upon. +dependency_libs=' -L/usr/local/lib /Users/hollybeja/Code/sleuthkit10/tsk/libtsk.la -lz -lsqlite3 -ldl -lstdc++' + +# Names of additional weak libraries provided by this library +weak_library_names='' + +# Version information for libtsk_jni. +current=0 +age=0 +revision=0 + +# Is this an already installed library? +installed=no + +# Should we warn about portability when linking against -modules? +shouldnotlink=no + +# Files to dlopen/dlpreopen +dlopen='' +dlpreopen='' + +# Directory that this library needs to be installed in: +libdir='/usr/local/lib' +relink_command="" diff --git a/sleuthKitLibs/4.13/libtsk_jni.0.dylib b/sleuthKitLibs/4.13/libtsk_jni.0.dylib new file mode 100755 index 0000000000..6da755684a Binary files /dev/null and b/sleuthKitLibs/4.13/libtsk_jni.0.dylib differ diff --git a/sleuthKitLibs/4.13/libtsk_jni.a b/sleuthKitLibs/4.13/libtsk_jni.a new file mode 100644 index 0000000000..2bb4b7c0c4 Binary files /dev/null and b/sleuthKitLibs/4.13/libtsk_jni.a differ diff --git a/sleuthKitLibs/4.13/libtsk_jni.dylib b/sleuthKitLibs/4.13/libtsk_jni.dylib new file mode 120000 index 0000000000..84b25b3473 --- /dev/null +++ b/sleuthKitLibs/4.13/libtsk_jni.dylib @@ -0,0 +1 @@ +libtsk_jni.0.dylib \ No newline at end of file diff --git a/sleuthKitLibs/4.13/libtsk_jni.la b/sleuthKitLibs/4.13/libtsk_jni.la new file mode 120000 index 0000000000..8c2f5bc949 --- /dev/null +++ b/sleuthKitLibs/4.13/libtsk_jni.la @@ -0,0 +1 @@ +../libtsk_jni.la \ No newline at end of file diff --git a/sleuthKitLibs/4.13/libtsk_jni.lai b/sleuthKitLibs/4.13/libtsk_jni.lai new file mode 100644 index 0000000000..8631a859db --- /dev/null +++ b/sleuthKitLibs/4.13/libtsk_jni.lai @@ -0,0 +1,41 @@ +# libtsk_jni.la - a libtool library file +# Generated by libtool (GNU libtool) 2.5.4 +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# The name that we can dlopen(3). +dlname='libtsk_jni.0.dylib' + +# Names of this library. +library_names='libtsk_jni.0.dylib libtsk_jni.dylib' + +# The name of the static archive. +old_library='libtsk_jni.a' + +# Linker flags that cannot go in dependency_libs. +inherited_linker_flags=' -pthread' + +# Libraries that this one depends upon. +dependency_libs=' -L/opt/homebrew/Cellar/openjdk/17.0.15/libexec/openjdk.jdk/Contents/Home/lib/server /usr/local/lib/libtsk.la -lpthread -lsqlite3 -ldl -lz -lstdc++' + +# Names of additional weak libraries provided by this library +weak_library_names='' + +# Version information for libtsk_jni. +current=0 +age=0 +revision=0 + +# Is this an already installed library? +installed=yes + +# Should we warn about portability when linking against -modules? +shouldnotlink=no + +# Files to dlopen/dlpreopen +dlopen='' +dlpreopen='' + +# Directory that this library needs to be installed in: +libdir='/usr/local/lib' diff --git a/sleuthKitLibs/4.13/libtsk_jni_la-auto_db_java.lo b/sleuthKitLibs/4.13/libtsk_jni_la-auto_db_java.lo new file mode 100644 index 0000000000..a32b7a7eac --- /dev/null +++ b/sleuthKitLibs/4.13/libtsk_jni_la-auto_db_java.lo @@ -0,0 +1,12 @@ +# bindings/java/jni/libtsk_jni_la-auto_db_java.lo - a libtool object file +# Generated by libtool (GNU libtool) 2.5.4 +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# Name of the PIC object. +pic_object='.libs/libtsk_jni_la-auto_db_java.o' + +# Name of the non-PIC object +non_pic_object='libtsk_jni_la-auto_db_java.o' + diff --git a/sleuthKitLibs/4.13/libtsk_jni_la-auto_db_java.o b/sleuthKitLibs/4.13/libtsk_jni_la-auto_db_java.o new file mode 100644 index 0000000000..0aa32ebd6d Binary files /dev/null and b/sleuthKitLibs/4.13/libtsk_jni_la-auto_db_java.o differ diff --git a/sleuthKitLibs/4.13/libtsk_jni_la-dataModel_SleuthkitJNI.lo b/sleuthKitLibs/4.13/libtsk_jni_la-dataModel_SleuthkitJNI.lo new file mode 100644 index 0000000000..c4ad9efff7 --- /dev/null +++ b/sleuthKitLibs/4.13/libtsk_jni_la-dataModel_SleuthkitJNI.lo @@ -0,0 +1,12 @@ +# bindings/java/jni/libtsk_jni_la-dataModel_SleuthkitJNI.lo - a libtool object file +# Generated by libtool (GNU libtool) 2.5.4 +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# Name of the PIC object. +pic_object='.libs/libtsk_jni_la-dataModel_SleuthkitJNI.o' + +# Name of the non-PIC object +non_pic_object='libtsk_jni_la-dataModel_SleuthkitJNI.o' + diff --git a/sleuthKitLibs/4.13/libtsk_jni_la-dataModel_SleuthkitJNI.o b/sleuthKitLibs/4.13/libtsk_jni_la-dataModel_SleuthkitJNI.o new file mode 100644 index 0000000000..459857adef Binary files /dev/null and b/sleuthKitLibs/4.13/libtsk_jni_la-dataModel_SleuthkitJNI.o differ diff --git a/sleuthKitLibs/4.14/libtsk.22.dylib b/sleuthKitLibs/4.14/libtsk.22.dylib new file mode 100755 index 0000000000..3518456884 Binary files /dev/null and b/sleuthKitLibs/4.14/libtsk.22.dylib differ diff --git a/sleuthKitLibs/4.14/libtsk.23.dylib b/sleuthKitLibs/4.14/libtsk.23.dylib new file mode 100755 index 0000000000..1c69802022 Binary files /dev/null and b/sleuthKitLibs/4.14/libtsk.23.dylib differ diff --git a/sleuthKitLibs/4.14/libtsk.a b/sleuthKitLibs/4.14/libtsk.a new file mode 100644 index 0000000000..5b6967c133 Binary files /dev/null and b/sleuthKitLibs/4.14/libtsk.a differ diff --git a/sleuthKitLibs/4.14/libtsk.dylib b/sleuthKitLibs/4.14/libtsk.dylib new file mode 100755 index 0000000000..1c69802022 Binary files /dev/null and b/sleuthKitLibs/4.14/libtsk.dylib differ diff --git a/sleuthKitLibs/4.14/libtsk.la b/sleuthKitLibs/4.14/libtsk.la new file mode 100755 index 0000000000..8069ca9434 --- /dev/null +++ b/sleuthKitLibs/4.14/libtsk.la @@ -0,0 +1,41 @@ +# libtsk.la - a libtool library file +# Generated by libtool (GNU libtool) 2.5.4 +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# The name that we can dlopen(3). +dlname='libtsk.23.dylib' + +# Names of this library. +library_names='libtsk.23.dylib libtsk.dylib' + +# The name of the static archive. +old_library='libtsk.a' + +# Linker flags that cannot go in dependency_libs. +inherited_linker_flags=' -pthread' + +# Libraries that this one depends upon. +dependency_libs=' -L/opt/homebrew/Cellar/openjdk/24.0.1/libexec/openjdk.jdk/Contents/Home/lib/server -L/usr/local/lib -lz -lsqlite3 -ldl -lstdc++' + +# Names of additional weak libraries provided by this library +weak_library_names='' + +# Version information for libtsk. +current=23 +age=0 +revision=0 + +# Is this an already installed library? +installed=yes + +# Should we warn about portability when linking against -modules? +shouldnotlink=no + +# Files to dlopen/dlpreopen +dlopen='' +dlpreopen='' + +# Directory that this library needs to be installed in: +libdir='/usr/local/lib' diff --git a/sleuthKitLibs/4.14/libtsk_jni.0.dylib b/sleuthKitLibs/4.14/libtsk_jni.0.dylib new file mode 100755 index 0000000000..4ffad7ef0a Binary files /dev/null and b/sleuthKitLibs/4.14/libtsk_jni.0.dylib differ diff --git a/sleuthKitLibs/4.14/libtsk_jni.a b/sleuthKitLibs/4.14/libtsk_jni.a new file mode 100644 index 0000000000..c1302130cf Binary files /dev/null and b/sleuthKitLibs/4.14/libtsk_jni.a differ diff --git a/sleuthKitLibs/4.14/libtsk_jni.dylib b/sleuthKitLibs/4.14/libtsk_jni.dylib new file mode 100755 index 0000000000..4ffad7ef0a Binary files /dev/null and b/sleuthKitLibs/4.14/libtsk_jni.dylib differ diff --git a/sleuthKitLibs/4.14/libtsk_jni.jnilib b/sleuthKitLibs/4.14/libtsk_jni.jnilib new file mode 100644 index 0000000000..4ffad7ef0a Binary files /dev/null and b/sleuthKitLibs/4.14/libtsk_jni.jnilib differ diff --git a/sleuthKitLibs/4.14/libtsk_jni.la b/sleuthKitLibs/4.14/libtsk_jni.la new file mode 100755 index 0000000000..12716ece3b --- /dev/null +++ b/sleuthKitLibs/4.14/libtsk_jni.la @@ -0,0 +1,41 @@ +# libtsk_jni.la - a libtool library file +# Generated by libtool (GNU libtool) 2.5.4 +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# The name that we can dlopen(3). +dlname='libtsk_jni.0.dylib' + +# Names of this library. +library_names='libtsk_jni.0.dylib libtsk_jni.dylib' + +# The name of the static archive. +old_library='libtsk_jni.a' + +# Linker flags that cannot go in dependency_libs. +inherited_linker_flags=' -pthread' + +# Libraries that this one depends upon. +dependency_libs=' -L/opt/homebrew/Cellar/openjdk/24.0.1/libexec/openjdk.jdk/Contents/Home/lib/server -L/usr/local/lib /usr/local/lib/libtsk.la -lz -lsqlite3 -ldl -lstdc++' + +# Names of additional weak libraries provided by this library +weak_library_names='' + +# Version information for libtsk_jni. +current=0 +age=0 +revision=0 + +# Is this an already installed library? +installed=yes + +# Should we warn about portability when linking against -modules? +shouldnotlink=no + +# Files to dlopen/dlpreopen +dlopen='' +dlpreopen='' + +# Directory that this library needs to be installed in: +libdir='/usr/local/lib' diff --git a/test_ntfs.img b/test_ntfs.img new file mode 100644 index 0000000000..3d3c6cf44c Binary files /dev/null and b/test_ntfs.img differ diff --git a/tika-config.xml b/tika-config.xml new file mode 100644 index 0000000000..bdcd481339 --- /dev/null +++ b/tika-config.xml @@ -0,0 +1,13 @@ + + + + + application/x-ntfs + + + + + + + + \ No newline at end of file diff --git a/tika-core/src/main/resources/org/apache/tika/mime/tika-mimetypes.xml b/tika-core/src/main/resources/org/apache/tika/mime/tika-mimetypes.xml index 0978ef5755..d95e000a0e 100644 --- a/tika-core/src/main/resources/org/apache/tika/mime/tika-mimetypes.xml +++ b/tika-core/src/main/resources/org/apache/tika/mime/tika-mimetypes.xml @@ -363,6 +363,14 @@ + + NTFS Disk Image + + + + + + diff --git a/tika-detectors/pom.xml b/tika-detectors/pom.xml index 1e0981b530..85473ac2d3 100644 --- a/tika-detectors/pom.xml +++ b/tika-detectors/pom.xml @@ -36,5 +36,6 @@ tika-detector-siegfried tika-detector-magika + tika-detector-ntfs \ No newline at end of file diff --git a/tika-detectors/tika-detector-ntfs/pom.xml b/tika-detectors/tika-detector-ntfs/pom.xml new file mode 100644 index 0000000000..523cb37431 --- /dev/null +++ b/tika-detectors/tika-detector-ntfs/pom.xml @@ -0,0 +1,29 @@ + + + 4.0.0 + + org.apache.tika + tika + 4.0.0-SNAPSHOT + ../../pom.xml + + + tika-detector-ntfs + + + 17 + 17 + UTF-8 + + + + org.apache.tika + tika-core + 4.0.0-SNAPSHOT + compile + + + + \ No newline at end of file diff --git a/tika-detectors/tika-detector-ntfs/src/main/java/org/apache/tika/detect/ntfs/NTFSDetector.java b/tika-detectors/tika-detector-ntfs/src/main/java/org/apache/tika/detect/ntfs/NTFSDetector.java new file mode 100644 index 0000000000..719f0f50bb --- /dev/null +++ b/tika-detectors/tika-detector-ntfs/src/main/java/org/apache/tika/detect/ntfs/NTFSDetector.java @@ -0,0 +1,89 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.tika.detect.ntfs; + +import java.io.IOException; +import java.io.InputStream; +import java.io.Serial; +import java.util.Arrays; + +import org.apache.tika.detect.Detector; +import org.apache.tika.metadata.Metadata; +import org.apache.tika.mime.MediaType; + +/** + * Detector for identifying NTFS disk image files + * based on boot sector signature. + */ +public class NTFSDetector implements Detector { + + @Serial + private static final long serialVersionUID = 1L; + + /** NTFS Media Type. */ + private static final MediaType NTFS_MEDIA_TYPE = + MediaType.application("x-ntfs"); + + /** Number of bytes to read from the start of the file + * (NTFS boot sector size). */ + private static final int BYTE_COUNT = 512; + + /** Offset where the NTFS signature is expected in the boot sector. */ + private static final int SIGNATURE_OFFSET = 3; + + /** The NTFS signature bytes to detect. */ + private static final byte[] NTFS_SIGNATURE = new byte[] + {'N', 'T', 'F', 'S', ' ', ' ', ' ', ' '}; + + /** + * Detects if the given input stream is an NTFS disk image. + * + * @param input the input stream + * @param metadata the metadata for the stream + * @return the media type if detected, or application/octet-stream + * @throws IOException on I/O error + */ + @Override + public MediaType detect(final InputStream input, final Metadata metadata) + throws IOException { + input.mark(BYTE_COUNT); + // NTFS boot sector is within the first 512 bytes + + var buffer = new byte[BYTE_COUNT]; + var bytesRead = input.read(buffer); + + input.reset(); + + if (bytesRead >= BYTE_COUNT && isNTFSBootSector(buffer)) { + return NTFS_MEDIA_TYPE; + } + + return MediaType.OCTET_STREAM; // fallback + } + + /** + * Checks whether the provided buffer contains the NTFS signature. + * + * @param buffer the byte buffer read from input + * @return true if buffer matches NTFS signature, false otherwise + */ + private boolean isNTFSBootSector(final byte[] buffer) { + var endOfSignature = SIGNATURE_OFFSET + NTFS_SIGNATURE.length; + return Arrays.equals(Arrays.copyOfRange( + buffer, SIGNATURE_OFFSET, endOfSignature), NTFS_SIGNATURE); + } +} diff --git a/tika-detectors/tika-detector-ntfs/src/main/java/org/apache/tika/detect/ntfs/package-info.java b/tika-detectors/tika-detector-ntfs/src/main/java/org/apache/tika/detect/ntfs/package-info.java new file mode 100644 index 0000000000..2dd7f8ebd5 --- /dev/null +++ b/tika-detectors/tika-detector-ntfs/src/main/java/org/apache/tika/detect/ntfs/package-info.java @@ -0,0 +1,17 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.tika.detect.ntfs; diff --git a/tika-detectors/tika-detector-ntfs/src/main/resources/META-INF/services/org.apache.tika.detect.Detector b/tika-detectors/tika-detector-ntfs/src/main/resources/META-INF/services/org.apache.tika.detect.Detector new file mode 100644 index 0000000000..81fe1206de --- /dev/null +++ b/tika-detectors/tika-detector-ntfs/src/main/resources/META-INF/services/org.apache.tika.detect.Detector @@ -0,0 +1,16 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +org.apache.tika.detect.ntfs.NTFSDetector diff --git a/tika-parsers/tika-parsers-extended/pom.xml b/tika-parsers/tika-parsers-extended/pom.xml index 9667377a17..0d605feeb7 100644 --- a/tika-parsers/tika-parsers-extended/pom.xml +++ b/tika-parsers/tika-parsers-extended/pom.xml @@ -36,6 +36,7 @@ tika-parser-sqlite3-package tika-parser-scientific-package tika-parsers-extended-integration-tests + tika-parser-ntfs-module diff --git a/tika-parsers/tika-parsers-extended/tika-parser-ntfs-module/pom.xml b/tika-parsers/tika-parsers-extended/tika-parser-ntfs-module/pom.xml new file mode 100644 index 0000000000..0be49dd2fd --- /dev/null +++ b/tika-parsers/tika-parsers-extended/tika-parser-ntfs-module/pom.xml @@ -0,0 +1,55 @@ + + + 4.0.0 + + org.apache.tika + tika-parsers + 4.0.0-SNAPSHOT + ../../pom.xml + + + tika-parser-ntfs-module + + + 17 + 17 + UTF-8 + + + + org.apache.tika + tika-core + 4.0.0-SNAPSHOT + compile + + + org.sleuthkit + sleuthkit + 4.14.0 + + + org.sleuthkit + sleuthkit-caseuco + 4.14.0 + + + org.jetbrains + annotations + 26.0.2 + compile + + + com.google.guava + guava + 33.4.8-jre + + + org.xerial + sqlite-jdbc + 3.50.1.0 + + + + \ No newline at end of file diff --git a/tika-parsers/tika-parsers-extended/tika-parser-ntfs-module/src/main/java/org/apache/tika/parser/ntfs/NTFSParser.java b/tika-parsers/tika-parsers-extended/tika-parser-ntfs-module/src/main/java/org/apache/tika/parser/ntfs/NTFSParser.java new file mode 100644 index 0000000000..9d9f09998e --- /dev/null +++ b/tika-parsers/tika-parsers-extended/tika-parser-ntfs-module/src/main/java/org/apache/tika/parser/ntfs/NTFSParser.java @@ -0,0 +1,171 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.tika.parser.ntfs; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.Serial; +import java.util.Collections; +import java.util.Set; + +import org.sleuthkit.datamodel.AbstractFile; +import org.sleuthkit.datamodel.SleuthkitCase; +import org.sleuthkit.datamodel.TskCoreException; +import org.sleuthkit.datamodel.TskData; +import org.xml.sax.ContentHandler; + +import org.apache.tika.exception.TikaException; +import org.apache.tika.metadata.Metadata; +import org.apache.tika.mime.MediaType; +import org.apache.tika.parser.AutoDetectParser; +import org.apache.tika.parser.ParseContext; +import org.apache.tika.parser.Parser; +import org.apache.tika.parser.ntfs.utils.stream.AbstractFileInputStream; + +/** + * Tika parser for analyzing NTFS disk images using SleuthKit. + * This parser extracts file metadata and content from an NTFS volume. + */ +public class NTFSParser implements Parser { + + @Serial + private static final long serialVersionUID = 1L; + + /** Auto parser for handling embedded file content. */ + private final Parser autoParser = new AutoDetectParser(); + + /** Maximum buffer size for stream copying. */ + private static final int CHUNK_SIZE = 8192; + + /** + * Returns the set of media types supported by this parser. + * + * @param context the parse context + * @return a singleton set containing {@code application/x-ntfs} + */ + @Override + public Set getSupportedTypes(final ParseContext context) { + return Collections.singleton(MediaType.application("x-ntfs")); + } + + /** + * Parses an NTFS disk image stream using SleuthKit to + * extract and process files. + * + * @param stream the input stream containing the NTFS image + * @param handler the SAX content handler to receive XHTML SAX events + * @param metadata the metadata associated with the document + * @param context the parser context + * @throws IOException if an I/O error occurs + * @throws TikaException if an error occurs during parsing + */ + @Override + public void parse(final InputStream stream, final ContentHandler handler, + final Metadata metadata, final ParseContext context) + throws IOException, TikaException { + + // Copy input stream to a temporary file for SleuthKit + var tempImage = File.createTempFile("ntfs", ".img"); + + try (var out = new FileOutputStream(tempImage)) { + var buffer = new byte[CHUNK_SIZE]; + int len; + while ((len = stream.read(buffer)) != -1) { + out.write(buffer, 0, len); + } + } + + SleuthkitCase skCase = null; + try { + skCase = SleuthkitCase.newCase("ntfs-case.db"); + + var transaction = skCase.beginTransaction(); + var image = skCase.addImage( + TskData.TSK_IMG_TYPE_ENUM.TSK_IMG_TYPE_DETECT, + 0, + tempImage.length(), + tempImage.getName(), + Collections.singletonList(tempImage.getAbsolutePath()), + "UTC", + null, null, null, + null, + transaction + ); + transaction.commit(); + + for (var fileSystem : skCase.getImageFileSystems(image)) { + var root = fileSystem.getRootDirectory(); + if (root != null) { + processFileRecursively(root, handler, context); + } + } + + } catch (TskCoreException e) { + throw new TikaException("SleuthKit parsing failed", e); + } finally { + if (skCase != null) { + try { + skCase.close(); + } catch (Exception ignored) { + // Swallow close exception + } + } + tempImage.delete(); + } + } + + /** + * Recursively traverses and processes files and directories + * within the NTFS volume. + * + * @param file the file or directory to process + * @param handler the content handler to which parsed content is sent + * @param context the parse context for embedded content parsing + */ + private void processFileRecursively(final AbstractFile file, + final ContentHandler handler, + final ParseContext context) { + var metaType = TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_REG; + try { + if (file.isDir()) { + for (AbstractFile child : file.listFiles()) { + processFileRecursively(child, handler, context); + } + } else if (file.getMetaType() == metaType && file.getSize() > 0) { + + var fileMetadata = new Metadata(); + fileMetadata.set("Filename", file.getName()); + fileMetadata.set("Size", String.valueOf(file.getSize())); + fileMetadata.set("Created", + String.valueOf(file.getCrtimeAsDate())); + fileMetadata.set("Modified", + String.valueOf(file.getMtimeAsDate())); + + try (var fileStream = new AbstractFileInputStream(file)) { + autoParser.parse(fileStream, handler, + fileMetadata, context); + } + } + } catch (Exception e) { + // Log and skip problematic files + System.err.println("Failed to parse file: " + + file.getName() + " - " + e.getMessage()); + } + } +} diff --git a/tika-parsers/tika-parsers-extended/tika-parser-ntfs-module/src/main/java/org/apache/tika/parser/ntfs/package-info.java b/tika-parsers/tika-parsers-extended/tika-parser-ntfs-module/src/main/java/org/apache/tika/parser/ntfs/package-info.java new file mode 100644 index 0000000000..de39e9fb30 --- /dev/null +++ b/tika-parsers/tika-parsers-extended/tika-parser-ntfs-module/src/main/java/org/apache/tika/parser/ntfs/package-info.java @@ -0,0 +1,17 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.tika.parser.ntfs; diff --git a/tika-parsers/tika-parsers-extended/tika-parser-ntfs-module/src/main/java/org/apache/tika/parser/ntfs/utils/stream/AbstractFileInputStream.java b/tika-parsers/tika-parsers-extended/tika-parser-ntfs-module/src/main/java/org/apache/tika/parser/ntfs/utils/stream/AbstractFileInputStream.java new file mode 100644 index 0000000000..28061c2676 --- /dev/null +++ b/tika-parsers/tika-parsers-extended/tika-parser-ntfs-module/src/main/java/org/apache/tika/parser/ntfs/utils/stream/AbstractFileInputStream.java @@ -0,0 +1,75 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.tika.parser.ntfs.utils.stream; + +import java.io.IOException; +import java.io.InputStream; + +import org.jetbrains.annotations.NotNull; +import org.sleuthkit.datamodel.AbstractFile; +import org.sleuthkit.datamodel.TskCoreException; + +public class AbstractFileInputStream extends InputStream { + + /** File to be read by stream. */ + private final AbstractFile abstractFile; + + /** + * Creates a new input stream for the given SleuthKit abstract file. + * + * @param file the abstract file to read from + */ + public AbstractFileInputStream(final AbstractFile file) { + this.abstractFile = file; + } + + /** Byte mask. */ + private static final int BYTE_MASK = 0xFF; + + /** + * Reads a single byte from the abstract file. + * + * @return the byte read, or -1 if end of file + * @throws IOException if an I/O error occurs + */ + @Override + public int read() throws IOException { + byte[] buf = new byte[1]; + int bytesRead = read(buf, 0, 1); + return (bytesRead == -1) ? -1 : buf[0] & BYTE_MASK; + } + + /** + * Reads up to len bytes of data into an array of bytes + * from the abstract file. + * + * @param buffer the buffer into which the data is read + * @param off the start offset in the destination array + * @param len the maximum number of bytes to read + * @return the number of bytes read, or -1 if end of file + * @throws IOException if an I/O error occurs + */ + @Override + public int read(final byte @NotNull [] buffer, final int off, final int len) + throws IOException { + try { + return abstractFile.read(buffer, off, len); + } catch (TskCoreException e) { + throw new IOException("Error reading from abstract file", e); + } + } +} diff --git a/tika-parsers/tika-parsers-extended/tika-parser-ntfs-module/src/main/java/org/apache/tika/parser/ntfs/utils/stream/package-info.java b/tika-parsers/tika-parsers-extended/tika-parser-ntfs-module/src/main/java/org/apache/tika/parser/ntfs/utils/stream/package-info.java new file mode 100644 index 0000000000..9e7e604dc0 --- /dev/null +++ b/tika-parsers/tika-parsers-extended/tika-parser-ntfs-module/src/main/java/org/apache/tika/parser/ntfs/utils/stream/package-info.java @@ -0,0 +1,17 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.tika.parser.ntfs.utils.stream; diff --git a/tika-parsers/tika-parsers-extended/tika-parser-ntfs-module/src/main/resources/META-INF.services/org.apache.tika.parser.Parser b/tika-parsers/tika-parsers-extended/tika-parser-ntfs-module/src/main/resources/META-INF.services/org.apache.tika.parser.Parser new file mode 100644 index 0000000000..5dae404923 --- /dev/null +++ b/tika-parsers/tika-parsers-extended/tika-parser-ntfs-module/src/main/resources/META-INF.services/org.apache.tika.parser.Parser @@ -0,0 +1,16 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +org.apache.tika.parser.ntfs.NTFSParser