Logo Search packages:      
Sourcecode: p3scan version File versions  Download package

olestream-unwrap.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>

#include "logger.h"
#include "pldstr.h"

#include "bytedecoders.h"
#include "olestream-unwrap.h"


struct OLE10_header{
      unsigned char data[6];
      char *attach_name;
      unsigned char data2[8];
      char *fname_1;
      char *fname_2;
      size_t attach_size;
      size_t attach_size_1;
      size_t attach_start_offset;
};


/*-----------------------------------------------------------------\
 Function Name    : OLEUNWRAP_init
 Returns Type     : int
      ----Parameter List
      1. struct OLEUNWRAP_object *oleuw , 
      ------------------
 Exit Codes : 
 Side Effects     : 
--------------------------------------------------------------------
 Comments:
 
--------------------------------------------------------------------
 Changes:
 
\------------------------------------------------------------------*/
int OLEUNWRAP_init( struct OLEUNWRAP_object *oleuw )
{
      oleuw->debug = 0;
      oleuw->verbose = 0;
      oleuw->filename_report_fn = NULL;

      return OLEUW_OK;
}

/*-----------------------------------------------------------------\
 Function Name    : OLEUNWRAP_set_debug
 Returns Type     : int
      ----Parameter List
      1. struct OLEUNWRAP_object *oleuw, 
      2.  int level , 
      ------------------
 Exit Codes : 
 Side Effects     : 
--------------------------------------------------------------------
 Comments:
 
--------------------------------------------------------------------
 Changes:
 
\------------------------------------------------------------------*/
int OLEUNWRAP_set_debug( struct OLEUNWRAP_object *oleuw, int level )
{
      oleuw->debug = level;
      return OLEUW_OK;
}

/*-----------------------------------------------------------------\
 Function Name    : OLEUNWRAP_set_verbose
 Returns Type     : int
      ----Parameter List
      1. struct OLEUNWRAP_object *oleuw, 
      2.  int level , 
      ------------------
 Exit Codes : 
 Side Effects     : 
--------------------------------------------------------------------
 Comments:
 
--------------------------------------------------------------------
 Changes:
 
\------------------------------------------------------------------*/
int OLEUNWRAP_set_verbose( struct OLEUNWRAP_object *oleuw, int level )
{
      oleuw->verbose = level;
      return OLEUW_OK;
}

/*-----------------------------------------------------------------\
 Function Name    : OLEUNWRAP_set_save_unknown_streams
 Returns Type     : int
      ----Parameter List
      1. struct OLEUNWRAP_object *oleuw, 
      2.  int level , 
      ------------------
 Exit Codes : 
 Side Effects     : 
--------------------------------------------------------------------
 Comments:
 
--------------------------------------------------------------------
 Changes:
 
\------------------------------------------------------------------*/
int OLEUNWRAP_set_save_unknown_streams( struct OLEUNWRAP_object *oleuw, int level )
{
      oleuw->save_unknown_streams = level;
      return OLEUW_OK;
}


/*-----------------------------------------------------------------\
 Function Name    : OLEUNWRAP_save_stream
 Returns Type     : int
      ----Parameter List
      1. char *fname, 
      2.  char *stream, 
      3.  size_t bytes , 
      ------------------
 Exit Codes : 
 Side Effects     : 
--------------------------------------------------------------------
 Comments:
 
--------------------------------------------------------------------
 Changes:
 
\------------------------------------------------------------------*/
int OLEUNWRAP_save_stream( struct OLEUNWRAP_object *oleuw, char *fname, char *decode_path, char *stream, size_t bytes )
{
      char *full_name;
      FILE *f;
      int result = 0;

      full_name = PLD_dprintf("%s/%s", decode_path, fname );
      if (full_name == NULL)
      {
            LOGGER_log("%s:%d:OLEUNWRAP_save_stream:ERROR: Unable to create filename string from '%s' and '%s'",FL,fname,decode_path);
            return -1;
      }

      f = fopen(full_name,"w");
      if (f != NULL)
      {
            size_t write_count;

            write_count = fwrite( stream, 1, bytes, f );
            if (write_count != bytes)
            {
                  LOGGER_log("%s:%d:OLEUNWRAP_save_stream:WARNING: Only wrote %d of %d bytes to file %s\n",FL, write_count, bytes, full_name );
                  // Complaining seems to get us segfaulted

            }

            fclose(f);
      } else {
            LOGGER_log("%s:%d:OLEUNWRAP_save_stream:ERROR: Unable to open %s for writing (%s)\n",FL,full_name, strerror(errno));
            result = -1;
      }

      if (full_name) free(full_name);
      return result;
}


/*-----------------------------------------------------------------\
 Function Name    : OLEUNWRAP_decode_attachment
 Returns Type     : int
      ----Parameter List
      1. char *stream , 
      ------------------
 Exit Codes : 
 Side Effects     : 
--------------------------------------------------------------------
 Comments:
 
--------------------------------------------------------------------
 Changes:
 
\------------------------------------------------------------------*/
int OLEUNWRAP_decode_attachment( struct OLEUNWRAP_object *oleuw, char *stream, size_t stream_size, char *decode_path )
{
      struct OLE10_header oh;
      char *sp = stream;
      char *data_start_point = stream;
      int result = OLEUW_OK;

      // Get the data size
      oh.attach_size_1 = (size_t)get_4byte_value( sp );
      sp += 4;

//    fprintf(stdout,"%s:%d:DEBUG:attachsize = %d, stream length = %d\n", FL, oh.attach_size_1, stream_size );

      oh.attach_start_offset = (stream_size -oh.attach_size_1);
      data_start_point = stream +oh.attach_start_offset;

      //if (oh.attach_start_offset == 4)
      if (oh.attach_start_offset < 4)
      {
            // If we only had the stream byte-lenght in our header
            //          then we know we don't have a complex header.
            oh.attach_name = PLD_dprintf("unknown-%ld",oh.attach_size_1);
            oh.attach_size = oh.attach_size_1;
      } else {
            // Unknown memory segment
            memcpy( oh.data, sp, 2 );
            sp += 2;
            
            // Full attachment string
            oh.attach_name = strdup( sp );
            sp = sp + strlen(oh.attach_name) +1;

            // Attachment full path
            oh.fname_1 = strdup( sp );
            sp += strlen(oh.fname_1) +1;

            // Unknown memory segment
            memcpy( oh.data2, sp, 8 );
            sp = sp +8;

            // Attachment full path
            oh.fname_2 = strdup( sp );
            sp += strlen(oh.fname_2) +1;

            oh.attach_size = (size_t)get_4byte_value( sp );
            sp += 4;

            if (oh.attach_size > stream_size) oh.attach_size = stream_size;
      } 

      if (oleuw->debug > 0) LOGGER_log("%s:%d:OLEUNWRAP_decode_attachment:DEBUG: Attachment %s:%s:%s size = %d\n",FL, oh.attach_name, oh.fname_1, oh.fname_2, oh.attach_size );

      result = OLEUNWRAP_save_stream( oleuw, oh.attach_name, decode_path, data_start_point, oh.attach_size );
      if (result == OLEUW_OK)
      {
            if (oleuw->debug > 0) LOGGER_log("%s:%d:OLEUNWRAP_decode_attachment:DEBUG: Calling reporter for the filename",FL);
            if ((oleuw->verbose > 0)&&(oleuw->filename_report_fn != NULL))
            {
                  oleuw->filename_report_fn(oh.attach_name);
            }
            // Do call back to reporting function
      }

      // Clean up our previously allocated data
      if (oh.fname_1 != NULL) free(oh.fname_1);
      if (oh.attach_name != NULL) free(oh.attach_name);
      if (oh.fname_2 != NULL) free(oh.fname_2);
      
      return OLEUW_OK;
}

/*-----------------------------------------------------------------\
 Function Name    : OLEUNWRAP_decodestream
 Returns Type     : int
      ----Parameter List
      1. char *element_string, 
      2.  char *stream , 
      ------------------
 Exit Codes : 
 Side Effects     : 
--------------------------------------------------------------------
 Comments:
 
--------------------------------------------------------------------
 Changes:
 
\------------------------------------------------------------------*/
int OLEUNWRAP_decodestream( struct OLEUNWRAP_object *oleuw, char *element_string, char *stream, size_t stream_size, char *decode_path )
{
      int result = OLEUW_OK;

      if (strstr(element_string, OLEUW_ELEMENT_10NATIVE_STRING) != NULL) 
      {
            OLEUNWRAP_decode_attachment( oleuw, stream, stream_size, decode_path );

      } else {
            if (oleuw->debug) LOGGER_log("Unable to decode stream with element string '%s'\n", element_string);
            result = OLEUW_STREAM_NOT_DECODED;
      }

      return result;
}


/*-----------------------------------------------------------------\
 Function Name    : OLEUNWRAP_set_filename_report_fn
 Returns Type     : int
      ----Parameter List
      1. struct OLEUNWRAP_object *oleuw, 
      2.  int (*ptr_to_fn)(char *) , 
      ------------------
 Exit Codes : 
 Side Effects     : 
--------------------------------------------------------------------
 Comments:
 
--------------------------------------------------------------------
 Changes:
 
\------------------------------------------------------------------*/
int OLEUNWRAP_set_filename_report_fn( struct OLEUNWRAP_object *oleuw, int (*ptr_to_fn)(char *) )
{

      oleuw->filename_report_fn = ptr_to_fn;

      return 0;
}


Generated by  Doxygen 1.6.0   Back to index