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: https://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