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