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

perdr.cpp

Go to the documentation of this file.
00001 /*
00002 PeRdr - PE file disassembler
00003 Copyright (C) 1999-2003 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 <stdexcept>
00031 #include <ctime>
00032 #include <cstdarg>
00033 #include "rva.h"
00034 #include "symbols.h"
00035 #include "code.h"
00036 #include "rawdump.h"
00037 #include "x86dasm.h"
00038 #include "module.h" // !!! only for exception
00039 #include "relocationinfo.h"
00040 #include "perdroptions.h"
00041 #include "signfile.hpp"
00042 #include "peformat.h"
00043 #include "pefile.hpp"
00044 #include "persrc.h"
00045 
00046 using namespace std;
00047 
00048 #define ZERO(a) memset(&(a),0,sizeof(a))
00049 
00050 void Error(const char* msg,...)
00051 {
00052   va_list argptr;
00053   va_start(argptr, msg);
00054   vfprintf(stderr, msg, argptr);
00055   va_end(argptr);
00056   fprintf(stderr,"\n");
00057 
00058   exit(1);
00059 }
00060 
00061 struct OutImportParam
00062 {
00063         OutImportParam(CFile& _file,uint32_t _imageBase):
00064         file(&_file),imagebase(_imageBase) {};
00065   CFile* file;
00066   uint32_t imagebase;
00067 };
00068 
00069 void OutputImport(uint32_t address,uint32_t hint,const char* dll_name,const char* func_name,void* param)
00070 {
00071   OutImportParam *p = (OutImportParam*)param;
00072   if (address != 0)
00073   {
00074     if (func_name != NULL)
00075       fprintf(p->file->GetFile(),"%08lX %s.%s\n",(long int)address+p->imagebase,dll_name,func_name);
00076     else
00077       fprintf(p->file->GetFile(),"%08lX %s.%04X\n",(long int)address+p->imagebase,dll_name,(int)hint);
00078   }
00079 }
00080 
00081 // !!! other file ?
00082 struct AddRelocationParam
00083 {
00084   AddRelocationParam(RelocationInfos* _infos,uint32_t _imageBase):
00085     infos(_infos),imageBase(_imageBase),relocationExist(false) {};
00086         RelocationInfos* infos;
00087   uint32_t imageBase;
00088   bool relocationExist;
00089 };
00090 
00091 void AddRelocationInfo(uint32_t address,unsigned type,void* _param)
00092 {
00093   AddRelocationParam* param = (AddRelocationParam*)_param;
00094   param->relocationExist = true;
00095   if ( type == IMAGE_REL_BASED_HIGHLOW )
00096   {
00097     param->infos->AddRelocation(
00098       Relocation(Relocation::relRelative),address+param->imageBase);
00099   }
00100 }
00101 
00102 struct MarkImportParam
00103 {
00104   CSignFile* file;
00105   RVAFileTranslator* rva;
00106   uint32_t imageBase;
00107 };
00108 
00109 // read import location to strip from code parsing
00110 static void MarkImport(uint32_t address,uint32_t hint,const char* dll_name,const char* func_name,void* param)
00111 {
00112   MarkImportParam* p = (MarkImportParam*)param;
00113   if (address != 0)
00114   {
00115     p->file->Seek(p->rva->RVA2FileSafe(address));
00116     uint32_t addr;
00117     RawRead(*(p->file),addr);
00118   }
00119 }
00120 
00121 extern char szBuild[];
00122 extern char szVersion[];
00123 
00124 int main(int argc,char** argv)
00125 {
00126 #ifdef DEBUG
00127 //  unsigned totalLen = 0;
00128 //  unsigned maxStrLen = 0;
00129 //  for (int i=0;i<num_instructions;++i)
00130 //  {
00131 //    int len = strlen(x86instructions_names[i]) +1;
00132 //    totalLen += len;
00133 //    if (maxStrLen < len )
00134 //      maxStrLen = len;
00135 //  }
00136 //  fprintf(stderr,"Debug: (Test) MaxLen: %u Len ptr: %u Len array: %u\n",maxStrLen,sizeof(void*)*num_instructions+totalLen,maxStrLen*num_instructions);
00137 #endif
00138   try {
00139     fprintf(stderr,"PeRdr by Frediano Ziglio. Build %s\n",szBuild);
00140 #ifdef DEBUG
00141     fprintf(stderr,"Debug version use only for testing!!\n");
00142 #endif
00143 
00144     int arg = ReadOptions(argc,argv);
00145 
00146     // if wrong param or not filename
00147     // print help and exit
00148     bool badParam = false;
00149     if ( arg <= 0 || (arg==argc && !options.showVersion && !options.showHelp) )
00150     {
00151       options.showHelp = true;
00152       badParam = true;
00153     }
00154 
00155     if (options.showHelp)
00156     {
00157       fprintf(badParam?stderr:stdout,"PeRdr version %s\n"
00158 "\n"
00159 "usage: perdr [options] <filename>\n"
00160 "   --help                  - print this message\n"
00161 "   --version               - print the version of PeRdr being used\n"
00162 "   -b, --bytes             - show bytes on disassembly\n"
00163 "   --show-priority         - show priority in disassembly\n"
00164 "   --raw-dump              - don't disassemble, print only raw bytes\n"
00165 "   --extract-icon-resource - extract icon into separate files (resicoX.ico)\n"
00166 " Disable some instruction sets decode:\n"
00167 "   --disable-3dnow         - disable 3DNow! disassembly (even enhanced)\n"
00168 "   --disable-enh3dnow      - disable enhanced 3DNow! disassembly\n"
00169 "   --disable-pentium3      - disable PentiumIII disassembly\n"
00170 "   --disable-athlon        - disable Athlon disassembly\n"
00171 " Select what show (if none show all):\n"
00172 "   --show-headers          - show headers\n"
00173 "   --show-imports          - show imports\n"
00174 "   --show-relocations      - show relocations\n"
00175 "   --show-exports          - show exports\n"
00176 "   --show-resources        - show resources\n"
00177 "   --show-code             - show code or dump\n"
00178       ,szVersion);
00179       return badParam ? 1: 0;
00180     }
00181 
00182     if (options.showVersion)
00183     {
00184       fprintf(stderr,"PeRdr version %s\n",szVersion);
00185       return 0;
00186     }
00187 
00188     // set CPU options
00189     p3enable           = !options.disableP3;
00190     k6_en_3DNow_enable = !options.disableEnh3DNow;
00191     k6_3DNow_enable    = !options.disable3DNow;
00192     athlon_enable      = !options.disableAthlon;
00193 
00194     CSignFile file(argv[arg],"rb");
00195 
00196     PeFile peFile(file);
00197 
00198     // write info
00199     if (options.showHeaders)
00200     {
00201       PeFile::WriteFileHdr(peFile.GetFileHeader());
00202       PeFile::WriteOptionalHdr(peFile.GetOptionalHeader());
00203       for (unsigned i=0; i<peFile.GetSectionCount(); ++i)
00204       {
00205         printf("Section %i\n",i);
00206         PeFile::WriteSectionHdr(peFile.GetSection(i));
00207       }
00208     }
00209     RVAFileTranslator& rva = peFile.GetRVA();
00210 
00211     Symbols symbols,exportedSymbols;
00212 
00213     // parse imports
00214     const PE_IMAGE_DATA_DIRECTORY& imports =
00215       peFile.GetDataDirectory(IMAGE_DIRECTORY_ENTRY_IMPORT);
00216     if ( imports.VirtualAddress != 0 && imports.Size != 0 )
00217     {
00218       SymbolsAddImportParam param = { &symbols,peFile.GetImageBase() };
00219       peFile.ParseImport(SymbolsAddImport,&param);
00220 
00221       MarkImportParam markParam = { &file,&rva,peFile.GetImageBase() };
00222       peFile.ParseImport(MarkImport,&markParam);
00223 
00224       if (options.showImports)
00225         peFile.ParseImport(PeFile::WriteImport,NULL);
00226     }
00227 
00228     // parse exports
00229     const PE_IMAGE_DATA_DIRECTORY& export_ =
00230       peFile.GetDataDirectory(IMAGE_DIRECTORY_ENTRY_EXPORT);
00231     if ( export_.VirtualAddress != 0 && export_.Size != 0 )
00232     {
00233                         SymbolsAddImportParam param = { &exportedSymbols,peFile.GetImageBase() };
00234       peFile.ParseExport(SymbolsAddImport,&param);
00235 
00236       if (options.showExports)
00237         peFile.ParseExport(PeFile::WriteImport,NULL);
00238     }
00239 
00240     bool hasRelocation = (peFile.GetFileHeader().Characteristics&IMAGE_FILE_RELOCS_STRIPPED)==0;
00241                 RelocationInfos relocationInfos;
00242 
00243     // parse relocations
00244     const PE_IMAGE_DATA_DIRECTORY& relocations =
00245       peFile.GetDataDirectory(IMAGE_DIRECTORY_ENTRY_BASERELOC);
00246     if ( relocations.VirtualAddress != 0 && relocations.Size != 0 )
00247     {
00248       hasRelocation = true;
00249       if (options.showRelocations)
00250          peFile.ParseRelocations(PeFile::WriteRelocation,NULL);
00251       // add relocation info to object
00252       // also check if exist some relocation
00253       // some driver not mark relocation stripping on header, 
00254       //  have relocation section without relocation
00255       AddRelocationParam param(&relocationInfos,peFile.GetImageBase());
00256       peFile.ParseRelocations(AddRelocationInfo,&param);
00257             hasRelocation = param.relocationExist;
00258     }
00259           else
00260             hasRelocation = false;
00261 
00262     // parse resources
00263     const PE_IMAGE_DATA_DIRECTORY& resources =
00264       peFile.GetDataDirectory(IMAGE_DIRECTORY_ENTRY_RESOURCE);
00265     if ( resources.VirtualAddress != 0 && resources.Size != 0 )
00266     {
00267       if (options.showResources)
00268         peFile.WriteResource();
00269       if (options.extractIconRes)
00270       {
00271         ResourceExtract::ExtractIcons(peFile);
00272       }
00273     }
00274 
00275     // transfer to byte level
00276     if (!options.showCode)
00277       return 0;
00278     if (options.rawDumping)
00279     {
00280       RawDump(file,peFile.GetImageBase(),rva);
00281     }
00282     else
00283     {
00284 //    FileByte();
00285 //    ParseCode(file,nt_hdr.OptionalHeader.ImageBase,
00286 //      nt_hdr.OptionalHeader.AddressOfEntryPoint,rva,api);
00287       ParseCode(file,peFile.GetImageBase(),
00288         peFile.GetOptionalHeader().AddressOfEntryPoint,rva,symbols,exportedSymbols,
00289         hasRelocation,relocationInfos);
00290     }
00291     return 0;
00292   }
00293   catch(runtime_error& error)
00294   {
00295     fprintf(stderr,"Runtime Error: %s\n",error.what());
00296     return 2;
00297   }
00298   catch(const ObjectModule::OutOfAddress& error)
00299   {
00300     fprintf(stderr,"Runtime Error: Out of file %08X\n",error.address);
00301     return 1;
00302   }
00303 }

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