00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
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"
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
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
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
00128
00129
00130
00131
00132
00133
00134
00135
00136
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
00147
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
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
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
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,¶m);
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
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,¶m);
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
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
00252
00253
00254
00255 AddRelocationParam param(&relocationInfos,peFile.GetImageBase());
00256 peFile.ParseRelocations(AddRelocationInfo,¶m);
00257 hasRelocation = param.relocationExist;
00258 }
00259 else
00260 hasRelocation = false;
00261
00262
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
00276 if (!options.showCode)
00277 return 0;
00278 if (options.rawDumping)
00279 {
00280 RawDump(file,peFile.GetImageBase(),rva);
00281 }
00282 else
00283 {
00284
00285
00286
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 }