⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 oledecod.c

📁 harvest是一个下载html网页得机器人
💻 C
📖 第 1 页 / 共 2 页
字号:
/*   OLEdecode - Decode Microsoft OLE files into its components.   Copyright (C) 1998, 1999  Andrew Scriven   This program is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation; either version 2 of the License, or   (at your option) any later version.   This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.   You should have received a copy of the GNU General Public License   along with this program; if not, write to the Free Software   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA *//*   Released under GPL, written by    Andrew Scriven <andy.scriven@research.natpower.co.uk>   Copyright (C) 1998, 1999   Andrew Scriven *//*   -----------------------------------------------------------------------   Andrew Scriven   Research and Engineering   Electron Building, Windmill Hill, Whitehill Way, Swindon, SN5 6PB, UK   Phone (44) 1793 896206, Fax (44) 1793 896251   ----------------------------------------------------------------------- *//*   *Extremely* modified by Arturo Tena <arturo@directmail.org> */#include <stdio.h>#include <stdarg.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#include <sys/types.h>#include <assert.h>#if !(defined( __BORLANDC__ ) || defined( __WIN32__ ))#include "cole.h"#include "config.h"#include <unistd.h>		/* for unlink() */#else#include "cole.h.in"#endif/* FIXME: replace all VERBOSE with COLE_VERBOSE */#ifdef COLE_VERBOSE#define VERBOSE#else#undef VERBOSE#endif#include "support.h"#include "internal.h"#define ENTRYCHUNK 20		/* number of entries in root_list and sbd_list				   will be added each time. must be at least 1 */#define MIN(a,b) ((a)<(b) ? (a) : (b))	/* reorder pps tree, from tree structure to a linear one,	   and write the level numbers, returns zero if OLE format fails,	   returns no zero if success */static int reorder_pps_tree (pps_entry * root_pps, U16 level);	/* free memory used (except the pps tree) */static void ends (void);	/* close and remove files in the tree *//* closeOLEtreefiles --- outdated because not to generate the   real files by now --- cole 2.0.0 *//*  static void closeOLEtreefiles (pps_entry * tree, U32 root); *//*   Verbose pps tree.   Input: pps_list: stream list.          root_pps: root pps.          level:    how much levels will be extracted.   Output: none. */static void verbosePPSTree (pps_entry * pps_list, U32 root_pps, int level);static FILE *input;static U8 *Block;static U8 *Blockx;static U8 *BDepot, *SDepot, *Root;static pps_entry *pps_list;static U32 num_of_pps;static FILE *sbfile;/* sbfilename is stored in *_sbfilename instead -- cole 2.0.0 *//* static char sbfilename[L_tmpnam]; */static U32 *sbd_list;static U32 *root_list;int __OLEdecode (char *OLEfilename, pps_entry ** stream_list, U32 * root,	     U8 **_BDepot, U8 **_SDepot, FILE **_sbfile, char **_sbfilename,	     FILE **_input,	     U16 max_level){  int c;  U32 num_bbd_blocks;  U32 num_xbbd_blocks;  U32 bl;  U32 i, j, len;  U8 *s, *p, *t;  long FilePos;  /* FilePos is long, not U32, because second argument of fseek is long */  /* initialize static variables */  input = sbfile = NULL;  Block = Blockx = BDepot = SDepot = Root = NULL;  pps_list = NULL;  num_of_pps = 0;/* sbfilename is stored in *_sbfilename instead -- cole 2.0.0 *//*  sbfilename[0] = 0; */  root_list = sbd_list = NULL;  /* initalize return parameters */  *stream_list = NULL;  /* open input file */  verbose ("open input file");  input = fopen (OLEfilename, "rb");  test_exitf (input != NULL, 4, ends ());  *_input = input;  /* fast check type of file */  verbose ("fast testing type of file");  test_exitf ((c = getc (input)) != EOF, 5, ends ());  test_exitf (ungetc (c, input) != EOF, 5, ends ());/* test_exitf (!isprint (c), 8, ends ()); OpenBSD suggestion to comment this out */  test_exitf (c == 0xd0, 9, ends ());  /* read header block */  verbose ("read header block");  Block = (U8 *) malloc (0x0200);  test_exitf (Block != NULL, 10, ends ());  fread (Block, 0x0200, 1, input);  test_exitf (!ferror (input), 5, ends ());  /* really check type of file */  rewind (input);  verbose ("testing type of file");  test_exitf (fil_sreadU32 (Block) != 0xd0cf11e0UL, 9, ends ());  test_exitf (fil_sreadU32 (Block + 0x04) != 0xa1b11ae1UL, 9, ends ());  /* read big block depot */  verbose ("read big block depot (bbd)");  num_bbd_blocks = fil_sreadU32 (Block + 0x2c);  num_xbbd_blocks = fil_sreadU32 (Block + 0x48);  verboseU32 (num_bbd_blocks);  verboseU32 (num_xbbd_blocks);  BDepot = (U8 *) malloc (0x0200 * (num_bbd_blocks + num_xbbd_blocks));  test_exitf (BDepot != NULL, 10, ends ());  *_BDepot = BDepot;  s = BDepot;  assert (num_bbd_blocks <=  (0x0200 / 4 - 1) * num_xbbd_blocks +			     (0x0200 / 4) - 19);  /* the first 19 U32 in header does not belong to bbd_list */  for (i = 0; i < MIN (num_bbd_blocks, 0x0200 / 4 - 19); i++)    {      /* note: next line may be needed to be cast to long in right side */      FilePos = 0x0200 * (1 + fil_sreadU32 (Block + 0x4c + (i * 4)));      assert (FilePos >= 0);      test_exitf (!fseek (input, FilePos, SEEK_SET), 5, ends ());      fread (s, 0x0200, 1, input);      test_exitf (!ferror (input), 5, ends ());      s += 0x0200;    }  Blockx = (U8 *) malloc (0x0200);  test_exitf (Blockx != NULL, 10, ends ());  bl = fil_sreadU32 (Block + 0x44);  for (i = 0; i < num_xbbd_blocks; i++)  {      FilePos = 0x0200 * (1 + bl);	 assert (FilePos >= 0);      test_exitf (!fseek (input, FilePos, SEEK_SET), 5, ends ());      fread (Blockx, 0x0200, 1, input);      test_exitf (!ferror (input), 5, ends ());    for (j=0; j < 0x0200 / 4 - 1;j++)                             /* last U32 is for the next bl */    {      if (fil_sreadU32 (Blockx + (j * 4)) == 0xfffffffeUL ||          fil_sreadU32 (Blockx + (j * 4)) == 0xfffffffdUL ||          fil_sreadU32 (Blockx + (j * 4)) == 0xffffffffUL)	break;      /* note: next line may be needed to be cast to long in right side */      FilePos = 0x0200 * (1 + fil_sreadU32 (Blockx + (j * 4)));      assert (FilePos >= 0);      test_exitf (!fseek (input, FilePos, SEEK_SET), 5, ends ());      fread (s, 0x0200, 1, input);      test_exitf (!ferror (input), 5, ends ());      s += 0x0200;    }    bl = fil_sreadU32 (Blockx + 0x0200 - 4);  }  verboseU8Array (BDepot, (num_bbd_blocks+num_xbbd_blocks), 0x0200);  /* extract the sbd block list */  verbose ("extract small block depot (sbd) block list");  sbd_list = (U32 *) malloc (ENTRYCHUNK * 4);  test_exitf (sbd_list != NULL, 10, ends ());  sbd_list[0] = fil_sreadU32 (Block + 0x3c);  /* -2 signed long int == 0xfffffffe unsinged long int */  for (len = 1; sbd_list[len - 1] != 0xfffffffeUL; len++)    {      test_exitf (len != 0, 5, ends ());	/* means file is too big */      /* if memory allocated in sbd_list is all used, allocate more memory */      if (!(len % ENTRYCHUNK))	{	  U32 *newspace;	  newspace = realloc (sbd_list,			      (1 + len / ENTRYCHUNK) * ENTRYCHUNK * 4);	  test_exitf (newspace != NULL, 10, ends ());	  sbd_list = newspace;	}	 sbd_list[len] = fil_sreadU32 (BDepot + (sbd_list[len - 1] * 4));      /*verboseU32 (len);*/      /*verboseU32 (sbd_list[0]);*/      /*verboseU32 (sbd_list[1]);*/      if (sbd_list[len] != 0xfffffffeUL)	test_exitf (sbd_list[len] <= num_bbd_blocks * 0x0200 - 4, 5, ends ());      test_exitf (sbd_list[len] != 0xfffffffdUL &&		  sbd_list[len] != 0xffffffffUL,		  5, ends ());    }  len--;  verboseU32Array (sbd_list, len+1);  /* read in small block depot, if there's any small block */  if (len == 0)    {      SDepot = NULL;      verbose ("not read small block depot (sbd): there's no small blocks");    }  else    {      verbose ("read small block depot (sbd)");      SDepot = (U8 *) malloc (0x0200 * len);	 test_exitf (SDepot != NULL, 10, ends ());      s = SDepot;      for (i = 0; i < len; i++)	{	  FilePos = 0x0200 * (1 + sbd_list[i]);	  assert (FilePos >= 0);	  test_exitf (!fseek (input, FilePos, SEEK_SET), 5, ends ());	  fread (s, 0x0200, 1, input);	  test_exitf (!ferror (input), 5, ends ());	  s += 0x200;	}      verboseU8Array (SDepot, len, 0x0200);    }  *_SDepot = SDepot;  /* extract the root block list */  verbose ("extract root block depot (root) block list");  root_list = (U32 *) malloc (ENTRYCHUNK * 4);  test_exitf (root_list != NULL, 10, ends ());  root_list[0] = fil_sreadU32 (Block + 0x30);  for (len = 1; root_list[len - 1] != 0xfffffffeUL; len++)    {      test_exitf (len != 0, 5, ends ());	/* means file is too long */      /* if memory allocated in root_list is all used, allocate more memory */      if (!(len % ENTRYCHUNK))	{	  U32 *newspace;	  newspace = realloc (root_list,			      (1 + len / ENTRYCHUNK) * ENTRYCHUNK * 4);	  test_exitf (newspace != NULL, 10, ends ());	  root_list = newspace;	}      root_list[len] = fil_sreadU32 (BDepot + (root_list[len - 1] * 4));      test_exitf (root_list[len] != 0xfffffffdUL && root_list[len] !=		  0xffffffffUL, 5, ends ());    }  len--;  verboseU32Array (root_list, len+1);  /* read in root block depot */  verbose ("read in root block depot (Root)");  Root = (U8 *) malloc (0x0200 * len);  test_exitf (Root != NULL, 10, ends ());  s = Root;  for (i = 0; i < len; i++)    {      FilePos = 0x0200 * (root_list[i] + 1);      assert (FilePos >= 0);      test_exitf (!fseek (input, FilePos, SEEK_SET), 5, ends ());      fread (s, 0x0200, 1, input);      test_exitf (!ferror (input), 5, ends ());      s += 0x200;    }  verboseU8Array (Root, len, 0x0200);  /* assign space for pps list */  verbose ("read pps list");  num_of_pps = len * 4;		/* each sbd block have 4 pps */  *stream_list = pps_list = (pps_entry *)malloc(num_of_pps*sizeof(pps_entry));  test_exitf (pps_list != NULL, 10, ends ());  /* read pss entry details and look out for "Root Entry" */  verbose ("read pps entry details");  for (i = 0; i < num_of_pps; i++)    {	 U16 size_of_name;      s = Root + (i * 0x80);      /* read the number */      pps_list[i].ppsnumber = i;      /* read the name */      size_of_name = (U16)MIN (0x40, fil_sreadU16 (s + 0x40));	 pps_list[i].name[0] = 0;      if (size_of_name == 0)	continue;      for (p = (U8 *) pps_list[i].name, t = s;	   t < s + size_of_name; t++)	*p++ = *t++;      /* makes visible the non printable first character */      /* if (!isprint (pps_list[i].name[0]) && pps_list[i].name[0])	pps_list[i].name[0] += 'a'; */	 /* read the pps type */	 pps_list[i].type = *(s + 0x42);	 if (pps_list[i].type == 5)	{	  assert (i == 0);	  *root = i;		/* this pps is the root */	}	 /* read the others fields */	 pps_list[i].previous = fil_sreadU32 (s + 0x44);	 pps_list[i].next = fil_sreadU32 (s + 0x48);	 pps_list[i].dir = fil_sreadU32 (s + 0x4c);	 pps_list[i].start = fil_sreadU32 (s + 0x74);	 pps_list[i].size = fil_sreadU32 (s + 0x78);	 pps_list[i].seconds1 = fil_sreadU32 (s + 0x64);	 pps_list[i].seconds2 = fil_sreadU32 (s + 0x6c);	 pps_list[i].days1 = fil_sreadU32 (s + 0x68);	 pps_list[i].days2 = fil_sreadU32 (s + 0x70);    }  /* NEXT IS VERBOSE verbose */#ifdef VERBOSE  {    U32 i;    printf ("before reorder pps tree\n");    printf ("pps    type    prev     next      dir start   level size     name\n");    for (i = 0; i < num_of_pps; i++)	 {	if (!pps_list[i].name[0])	{	  printf (" -\n");	  continue;	}	printf ("%08lx ", pps_list[i].ppsnumber);	printf ("%d ", pps_list[i].type);	printf ("%08lx ", pps_list[i].previous);	printf ("%08lx ", pps_list[i].next);	printf ("%08lx ", pps_list[i].dir);	printf ("%08lx ", pps_list[i].start);	printf ("%04x ", pps_list[i].level);	printf ("%08lx ", pps_list[i].size);	printf ("'%c", !isprint (pps_list[i].name[0]) ? ' ' : pps_list[i].name[0]);	printf ("%s'\n", pps_list[i].name+1);      }  }#endif  /* go through the tree made with pps entries, and reorder it so only the     next link is used (move the previous-link-children to the last visited     next-link-children) */  test_exitf (reorder_pps_tree (&pps_list[*root], 0), 9, ends ());  /* NEXT IS VERBOSE verbose */#ifdef VERBOSE  {    U32 i;    printf ("after reorder pps tree\n");    printf ("pps    type    prev     next      dir start   level size     name\n");    for (i = 0; i < num_of_pps; i++)      {        if (!pps_list[i].name[0])	   {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -