pasco_20040505_1/0040755000076500007650000000000010046207141012737 5ustar kjoneskjonespasco_20040505_1/bin/0040755000076500007650000000000010046224202013504 5ustar kjoneskjonespasco_20040505_1/CHANGES0100755000076500007650000000044310046207141013733 0ustar kjoneskjones5 May 2004 - Bugfixed the directory name offset for v5.2 index.dat files (kjj) 5 May 2004 - Changed the date output for easier sorting in spreadsheets (kjj) 5 May 2003 - Added support for v4 index.dat files (kjj) 5 May 2003 - Fixed problem when HTTP headers and filenames are missing. (kjj) pasco_20040505_1/Readme.txt0100755000076500007650000000035107770147151014712 0ustar kjoneskjonesEnter the "src" directory. Type "make installwin" within Cygwin to make Pasco for Windows. Type "make install" to make Pasco for Unix. The binaries will be located in the "bin" directory. Keith J. Jones keith.jones@foundstone.compasco_20040505_1/src/0040755000076500007650000000000010046224232013526 5ustar kjoneskjonespasco_20040505_1/src/Makefile0100755000076500007650000000030307770147151015200 0ustar kjoneskjonesall: install install: pasco.c gcc -o pasco pasco.c -lm -lc;cp pasco ../bin installwin: pasco.c gcc -DCYGWIN -o pasco.exe pasco.c -lm -lc;cp pasco.exe ../bin clean: rm -f pasco.exe pasco pasco_20040505_1/src/pasco.c0100755000076500007650000003053410046207026015006 0ustar kjoneskjones/* * Copyright (C) 2003, by Keith J. Jones. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include #include #include #include #include #include #include #include // /* This is the default block size for an activity record */ // #define BLOCK_SIZE 0x80 #ifdef CYGWIN ssize_t pread( int d, void *buf, size_t nbytes, off_t offset) { lseek( d, offset, SEEK_SET ); read( d, buf, nbytes ); } #endif // /* Backwards ASCII Hex to Integer */ // unsigned int bah_to_i( char *val, int size ) { int total; int i; total = 0; for ( i=0; i < size; i++ ) { total += ((unsigned char)val[i] << 8*i); } return total; } // /* Backwards 8 byte ASCII Hex to time_t */ // time_t win_time_to_unix( char *val ) { unsigned long low, high; double dbl; time_t total; char fourbytes[4]; fourbytes[0] = val[0]; fourbytes[1] = val[1]; fourbytes[2] = val[2]; fourbytes[3] = val[3]; low = bah_to_i( fourbytes, 4 ); fourbytes[0] = val[4]; fourbytes[1] = val[5]; fourbytes[2] = val[6]; fourbytes[3] = val[7]; high = bah_to_i( fourbytes, 4 ); dbl = ((double)high)*(pow(2,32)); dbl += (double)(low); if ( dbl==0 ) { return 0; } dbl *= 1.0e-7; dbl -= 11644473600; total = (double)dbl; return total; } // /* This function prepares a string for nice output */ // int printablestring( char *str ) { int i; i = 0; while ( str[i] != '\0' ) { if ( (unsigned char)str[i] < 32 || (unsigned char)str[i] > 127 ) { str[i] = ' '; } i++; } return 0; } // /* This function parses a REDR record. */ // int parse_redr( int history_file, double filever, int currrecoff, char *delim, int filesize, char *type ) { char fourbytes[4]; char hashrecflagsstr[4]; char chr; int filenameoff; int httpheadersoff; int i; int reclen; int dirnameoff; time_t modtime; time_t accesstime; char *url; char *filename; char *httpheaders; char ascmodtime[26], ascaccesstime[26]; char dirname[9]; pread( history_file, fourbytes, 4, currrecoff+4 ); reclen = bah_to_i( fourbytes, 4 )*BLOCK_SIZE; url = (char *)malloc( reclen+1 ); i = 0; pread( history_file, &chr, 1, currrecoff+0x10 ); while ( chr != '\0' && currrecoff+0x10+i+1 < filesize ) { url[i] = chr; pread( history_file, &chr, 1, currrecoff+0x10+i+1 ); i++; } url[i] = '\0'; filename = (char *)malloc( 1 ); filename[0] = '\0'; httpheaders = (char *)malloc( 1 ); httpheaders[0] = '\0'; dirname[0] = '\0'; ascmodtime[0] = '\0'; ascaccesstime[0] = '\0'; dirname[0] = '\0'; printablestring( type ); printablestring( url ); printablestring( ascmodtime ); printablestring( ascaccesstime ); printablestring( filename ); printablestring( dirname ); printablestring( httpheaders ); printf( "%s%s%s%s%s%s%s%s%s%s%s%s%s\n", type, delim, url, delim, ascmodtime, delim, ascaccesstime, delim, filename, delim, dirname, delim, httpheaders ); type[0] = '\0'; free( url ); free( filename ); free( httpheaders ); } // /* This function parses a URL and LEAK activity record. */ // int parse_url( int history_file, double filever, int currrecoff, char *delim, int filesize, char *type ) { char fourbytes[4]; char hashrecflagsstr[4]; char eightbytes[8]; char chr; int filenameoff; int httpheadersoff; int urloff; int i; int reclen; int dirnameoff; time_t modtime; time_t accesstime; char ascmodtime[26], ascaccesstime[26]; char dirname[9]; char *url; char *filename; char *httpheaders; int year, mon; struct tm *accesstm, *modtm; pread( history_file, fourbytes, 4, currrecoff+4 ); reclen = bah_to_i( fourbytes, 4 )*BLOCK_SIZE; pread( history_file, eightbytes, 8, currrecoff+8 ); modtime = win_time_to_unix( eightbytes ); pread( history_file, eightbytes, 8, currrecoff+16 ); accesstime = win_time_to_unix( eightbytes ); accesstm = localtime( &accesstime ); year = accesstm->tm_year + 1900; mon = accesstm->tm_mon + 1; sprintf( ascaccesstime, "%02d/%02d/%02d %02d:%02d:%02d", mon, accesstm->tm_mday, year, accesstm->tm_hour, accesstm->tm_min, accesstm->tm_sec ); modtm = localtime( &modtime ); year = modtm->tm_year + 1900; mon = modtm->tm_mon + 1; sprintf( ascmodtime, "%02d/%02d/%02d %02d:%02d:%02d", mon, modtm->tm_mday, year, modtm->tm_hour, modtm->tm_min, modtm->tm_sec ); if (accesstime == 0) { ascaccesstime[0] = '\0'; } if (modtime == 0) { ascmodtime[0] = '\0'; } url = (char *)malloc( reclen+1 ); if (filever >= 5) { pread( history_file, &chr, 1, currrecoff+0x34 ); } else { pread( history_file, &chr, 1, currrecoff+0x38 ); } urloff = (unsigned char)chr; i = 0; pread( history_file, &chr, 1, currrecoff+urloff ); while ( chr != '\0' && currrecoff+urloff+i+1 < filesize ) { url[i] = chr; pread( history_file, &chr, 1, currrecoff+urloff+i+1 ); i++; } url[i] = '\0'; filename = (char *)malloc( reclen+1 ); if (filever >= 5) { pread( history_file, fourbytes, 4, currrecoff+0x3C ); } else { pread( history_file, fourbytes, 4, currrecoff+0x40 ); } filenameoff = bah_to_i( fourbytes, 4 ) + currrecoff; i = 0; if (filenameoff > currrecoff+0x3C) { pread( history_file, &chr, 1, filenameoff ); while ( chr != '\0' && filenameoff+i+1 < filesize ) { filename[i] = chr; pread( history_file, &chr, 1, filenameoff+i+1 ); i++; } } filename[i] = '\0'; if (filever >= 5.2) { pread( history_file, &chr, 1, currrecoff+0x38 ); } else if (filever >= 5) { pread( history_file, &chr, 1, currrecoff+0x39 ); } else { pread( history_file, &chr, 1, currrecoff+0x3C ); } dirnameoff = (unsigned char)chr; if (0x50+(12*dirnameoff)+8 < filesize) { pread( history_file, dirname, 8, 0x50+(12*dirnameoff) ); dirname[8] = '\0'; } else { dirname[0] = '\0'; } httpheaders = (char *)malloc( reclen+1 ); if (filever >= 5) { pread( history_file, fourbytes, 4, currrecoff+0x44 ); } else { pread( history_file, fourbytes, 4, currrecoff+0x48 ); } httpheadersoff = bah_to_i( fourbytes, 4 ) + currrecoff; i = 0; if (httpheadersoff > currrecoff+0x44) { pread( history_file, &chr, 1, httpheadersoff ); while ( chr != '\0' && httpheadersoff+i+1 < currrecoff+reclen && httpheadersoff+i+1 < filesize ) { httpheaders[i] = chr; pread( history_file, &chr, 1, httpheadersoff+i+1 ); i++; } } httpheaders[i] = '\0'; printablestring( type ); printablestring( url ); printablestring( ascmodtime ); printablestring( ascaccesstime ); printablestring( filename ); printablestring( dirname ); printablestring( httpheaders ); if (type[3] == ' ') { type[3] = '\0'; } printf( "%s%s%s%s%s%s%s%s%s%s%s%s%s\n", type, delim, url, delim, ascmodtime, delim, ascaccesstime, delim, filename, delim, dirname, delim, httpheaders ); type[0] = '\0'; dirname[0] = '\0'; ascmodtime[0] = '\0'; ascaccesstime[0] = '\0'; free( url ); free( filename ); free( httpheaders ); } int parse_unknown( int history_file, double filever, int currrecoff, char *delim, int filesize, char *type ) { type[0] = '\0'; } // /* This function prints the usage message */ // void usage( void ) { printf("\nUsage: pasco [options] \n" ); printf("\t-d Undelete Activity Records\n" ); printf("\t-t Field Delimiter (TAB by default)\n" ); printf("\n\n"); } // /* MAIN function */ // int main( int argc, char **argv ) { int history_file; char fourbytes[4]; char chr; char delim[10]; int currrecoff; int filesize; int i; int opt; time_t modtime; time_t accesstime; char type[5]; char hashrecflagsstr[4]; int hashoff; int hashsize; int nexthashoff; int offset; int hashrecflags; int deleted = 0; double filever; if (argc < 2) { usage(); exit( -2 ); } strcpy( delim, "\t" ); history_file = open( argv[argc-1], O_RDONLY, 0 ); if ( history_file <= 0 ) { printf("ERROR - The index.dat file cannot be opened!\n\n"); usage(); exit( -3 ); } pread( history_file, fourbytes, 4, 0x18 ); filever = atof( fourbytes ); printf("History File: %s Version: %.1f\n\n", argv[argc-1], filever); pread( history_file, fourbytes, 4, 0x1C ); filesize = bah_to_i( fourbytes, 4 ); while ((opt = getopt( argc, argv, "dt:f:")) != -1) { switch(opt) { case 't': strncpy( delim, optarg, 10 ); break; case 'd': deleted = 1; break; default: usage(); exit(-1); } } printf( "TYPE%sURL%sMODIFIED TIME%sACCESS TIME%sFILENAME%sDIRECTORY%sHTTP HEADERS\n", delim, delim, delim, delim, delim, delim ); if (deleted == 0) { pread( history_file, fourbytes, 4, 0x20 ); hashoff = bah_to_i( fourbytes, 4 ); while (hashoff != 0 ) { pread( history_file, fourbytes, 4, hashoff+8 ); nexthashoff = bah_to_i( fourbytes, 4 ); pread( history_file, fourbytes, 4, hashoff+4 ); hashsize = bah_to_i( fourbytes, 4 )*BLOCK_SIZE; for (offset = hashoff + 16; offset < hashoff+hashsize; offset = offset+8) { pread( history_file, hashrecflagsstr, 4, offset ); hashrecflags = bah_to_i( hashrecflagsstr, 4 ); pread( history_file, fourbytes, 4, offset+4 ); currrecoff = bah_to_i( fourbytes, 4 ); if (hashrecflagsstr[0] != 0x03 && currrecoff != 0xBADF00D ) { if (currrecoff != 0) { pread( history_file, fourbytes, 4, currrecoff ); for (i=0;i < 4;i++) { type[i] = fourbytes[i]; } type[4] = '\0'; if (type[0] == 'R' && type[1] == 'E' && type[2] == 'D' && type[3] == 'R' ) { parse_redr( history_file, filever, currrecoff, delim, filesize, type ); } else if ( (type[0] == 'U' && type[1] == 'R' && type[2] == 'L') || (type[0] == 'L' && type[1] == 'E' && type[2] == 'A' && type[3] == 'K') ) { parse_url( history_file, filever, currrecoff, delim, filesize, type ); } else { parse_unknown( history_file, filever, currrecoff, delim, filesize, type ); } } } } hashoff = nexthashoff; } } else if (deleted == 1) { currrecoff = 0; while (currrecoff < filesize ) { pread( history_file, fourbytes, 4, currrecoff ); for (i=0;i < 4;i++) { type[i] = fourbytes[i]; } type[4] = '\0'; if (type[0] == 'R' && type[1] == 'E' && type[2] == 'D' && type[3] == 'R' ) { parse_redr( history_file, filever, currrecoff, delim, filesize, type ); } else if ( (type[0] == 'U' && type[1] == 'R' && type[2] == 'L') || (type[0] == 'L' && type[1] == 'E' && type[2] == 'A' && type[3] == 'K') ) { parse_url( history_file, filever, currrecoff, delim, filesize, type ); } else { parse_unknown( history_file, filever, currrecoff, delim, filesize, type ); } currrecoff = currrecoff + BLOCK_SIZE; } } close (history_file); }