Make your own free website on Tripod.com
Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

persrc.cpp

Go to the documentation of this file.
00001 /*
00002 PeRdr - PE file disassembler
00003 Copyright (C) 1999-2002 Frediano Ziglio
00004 -----
00005 
00006 This program is free software; you can redistribute it and/or modify
00007 it under the terms of the GNU General Public License as published by
00008 the Free Software Foundation; either version 2 of the License, or
00009 (at your option) any later version.
00010 
00011 This program is distributed in the hope that it will be useful,
00012 but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 GNU General Public License for more details.
00015 
00016 You should have received a copy of the GNU General Public License
00017 along with this program; if not, write to the Free Software
00018 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00019 -----
00020 
00021 INFORMATION
00022   www: http://freddy77.tripod.com/perdr/
00023   e-mail: freddy77@angelfire.com
00024 */
00025 #include "global.h"
00026 #ifdef HAVE_HDRSTOP
00027 #pragma hdrstop
00028 #endif
00029 
00030 #include "persrc.h"
00031 #include <stdexcept>
00032 #include <list>
00033 #include "utils/f77auto_ptr"
00034 
00035 struct iconinfo
00036 {
00037   // id of icon must be numeric
00038   unsigned id;
00039   long pos;
00040   uint32_t size;
00041 };
00042 
00043 typedef std::list<iconinfo> TIconInfos;
00044 
00045 static void CollectIconInfos(ICFile& file,const PeResourceDirectoryData* data,const PeResourceDirectoryInfo* info,unsigned level,void* param)
00046 {
00047   _DEBUG_(fprintf(stderr,"data %p level %d name %p id %d\n", data, level, info->name, info->id ));
00048   if (data != NULL && level == 3 && info->name == NULL && info->highLevel->id == 3)
00049   {
00050     _DEBUG_(fprintf(stderr,"---data %p level %d name %p id %d\n", data, level, info->name, info->highLevel->id));
00051     iconinfo iinfo;
00052     iinfo.id = info->id;
00053     iinfo.pos = file.Tell();
00054     iinfo.size = data->data.Size;
00055     _DEBUG_(fprintf(stderr,"---id %d pos %ld size %d\n", iinfo.id, iinfo.pos, iinfo.size));
00056     
00057     (*reinterpret_cast<TIconInfos*>(param)).push_back(iinfo);
00058   }
00059 }
00060 
00061 struct WriteIconParam
00062 {
00063   TIconInfos iconInfos;
00064   int n;
00065   WriteIconParam():n(1) {};
00066 
00067 };
00068   
00069 static const iconinfo* findIconInfo(const TIconInfos& infos,unsigned id)
00070 {
00071   TIconInfos::const_iterator end = infos.end();
00072   for(TIconInfos::const_iterator i = infos.begin(); i != end; ++i)
00073     if ( (*i).id == id )
00074       return &(*i);
00075   return NULL;
00076 }
00077 
00078 static void CopyFileToFile(const ICFile& from,ICFile& to,size_t bytes)
00079 {
00080   char buffer[128];
00081   while(bytes > 0)
00082   {
00083     size_t len = f77_min(bytes,(size_t)128);
00084     from.RawRead(buffer,len);
00085     to.RawWrite(buffer,len);
00086     bytes -= len;
00087   }
00088 }
00089 
00090 static void WriteIcons(ICFile& file,const PeResourceDirectoryData* data,const PeResourceDirectoryInfo* info,unsigned level,void* param)
00091 {
00092   static const char zeroes[2] = { 0, 0 };
00093   if (data != NULL && level == 3 && info->highLevel->id == 14)
00094   {
00095     WriteIconParam *p = reinterpret_cast<WriteIconParam*>(param);
00096     
00097     // ok, write this icon
00098     NEWHEADER hdr;
00099     RawRead(file,hdr);
00100     
00101     char buffer[128];
00102     sprintf(buffer,"resico%d.ico",p->n);
00103     ++p->n;
00104     CFile ico(buffer,"wb");
00105     
00106     // save header
00107     RawWrite(ico,hdr);
00108     
00109     
00110     freddy77::auto_delete_ptr<const iconinfo*> icons(new const iconinfo*[hdr.ResCount]);
00111     int i;
00112     for( i = 0; i < hdr.ResCount; ++i )
00113     {
00114       RESDIR resico;
00115       // !!! fix pack problem
00116       file.RawRead(&resico,14);
00117       
00118       // save icon header
00119       // !!! fix pack problem
00120       ico.RawWrite(&resico,14);
00121       ico.RawWrite(zeroes,2);
00122       
00123       // find icon and save it
00124       const iconinfo* info = findIconInfo(p->iconInfos,resico.IconCursorId);
00125       *(icons.get()+i) = info;
00126       if (!info)
00127         throw std::runtime_error("icon not found for icon group");
00128       if (resico.BytesInRes != info->size)
00129         throw std::runtime_error("icon with wrong size");
00130       // !!! check icon dimension and colors
00131     }
00132     for( i = 0; i < hdr.ResCount; ++i )
00133     {
00134       const iconinfo* info = *(icons.get()+i);
00135       file.Seek(info->pos);
00136       CopyFileToFile(file,ico,info->size);
00137     }
00138   }
00139 }
00140 
00141 void ResourceExtract::ExtractIcons(PeFile& peFile)
00142 {
00143 //  fprintf(stderr,"sizeof hdr %d\n",sizeof(RESDIR));
00144 //  throw std::runtime_error("ferma");
00145   // parse first for information retrieval (position and size of resources)
00146   WriteIconParam param;
00147   peFile.ParseResource(CollectIconInfos,&param.iconInfos);
00148 
00149   // parse for output files
00150   peFile.ParseResource(WriteIcons,&param);
00151 }

Generated on Mon Jan 13 22:20:34 2003 for perdr by doxygen1.2.15