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

CodeParser Class Reference

#include <codeglob.h>

Inheritance diagram for CodeParser:

CodeInfo List of all members.

Public Methods

void AddExportTempFlow (vma_t to, enum ByteInfo::TPriority priority)
bool AddTempFlow (enum FlowTypes flow, vma_t from, const Instruction &instruction, vma_t instAddress, enum ByteInfo::TPriority priority, bool bAddComplex=true)
void AddTempFlow (enum FlowTypes flow, vma_t from, vma_t to, enum ByteInfo::TPriority priority)
bool ExtractTempRef (TempReference &tempRef)
void _ReverseScan (IScanning *scanning, vma_t address, IMachineStatus *status)
void ReverseScan (IScanning *scanning, vma_t address)
bool ExecuteComplexReference (vma_t address)
bool ExecuteComplexReferenceMemory (vma_t address, const Instruction &instruction)
bool ExecuteComplexReferenceReg (vma_t address, const Instruction &instruction)
bool CheckCodeRecursively (vma_t address, ByteInfo::TPriority priority, bool _bSetLabel=true)
bool CheckCode (vma_t &address, ByteInfo::TPriority priority, bool bSetLabel=true)
bool IsApiReference (const Param &arg) const
bool ContainValidAddress (const Param &param) const

Private Types

enum  TScanCodeResult {
  scanCodeAlreadyProcessed, scanCodeNoError, scanCodeOverlapped, scanCodeInvalidJump,
  scanCodeInvalid, scanCodeMax = scanCodeInvalid
}

Private Methods

void Parse (CSignFile &_file, uint32_t imageBase, vma_t entryPoint, const RVAFileTranslator &rva, const Symbols &api, const Symbols &exportedApi, bool hasRelocation, const RelocationInfos &relocationInfos)
void ExcludeFileRange (CSignFile &_file, const RVAFileTranslator &rva, uint32_t imageBase)
enum TScanCodeResult ScanCode (vma_t &address, ByteInfo::TPriority priority, bool bSetLabel=true)
void CheckForAddress (vma_t instAddress, const Instruction &instruction, enum ByteInfo::TPriority priority)
void SetCodeRange (const range< vma_t > &r, ByteInfo::TPriority priority, bool bSetLabel=true)
void ResetCodeRange (const range< vma_t > &r)
void CheckImmediateCodeAddress (const Instruction &instruction)
void GetStringStats (vma_t address, unsigned &len, unsigned &num_printable)
void GetPointerArrayStats (vma_t address, PointerArrayStat &stat)
void GetBitStat (vma_t address, unsigned numBytes, BitStat &stat)
void CheckReference (vma_t address)
void CheckJumpReference (vma_t address, const Instruction &instruction)
void WriteCode ()
void WriteString (vma_t address, int len) const
void WriteBegin (vma_t address, int num_bytes) const

Friends

void ParseCode (CSignFile &file, uint32_t imageBase, vma_t entryPoint, const RVAFileTranslator &rva, const Symbols &symbols, const Symbols &exportedSymbols, bool hasRelocation, const RelocationInfos &relocationInfos)

Member Enumeration Documentation

enum CodeParser::TScanCodeResult [private]
 

Enumeration values:
scanCodeAlreadyProcessed 
scanCodeNoError 
scanCodeOverlapped 
scanCodeInvalidJump 
scanCodeInvalid 
scanCodeMax 

Definition at line 164 of file codeglob.h.

Referenced by CheckCode(), CheckCodeRecursively(), and ScanCode().


Member Function Documentation

void CodeParser::_ReverseScan IScanning   scanning,
vma_t    address,
IMachineStatus   status
 

Definition at line 53 of file codescan.cpp.

References _DEBUG_, _PRG_ASSERT, IstrReferences::beginReferenceTo(), CodeInfo::byteInfo, IMachineStatus::Clone(), IstrReferences::endReferenceTo(), GetInstruction(), ByteInfos::GetIstrLen(), CodeInfo::istrReferences, IstrReferences::iterator, CodeInfo::module, IScanning::ProcessInstruction(), and vma_t.

Referenced by ReverseScan().

00054 {
00055   _PRG_ASSERT(scanning != NULL);
00056   _PRG_ASSERT(status != NULL);
00057   _PRG_ASSERT(&*module != NULL);
00058   vma_t addr = address;
00059   // !!! check for loop
00060   for(;;)
00061   {
00062           // processa riferimenti
00063     IstrReferences::iterator i   =
00064       istrReferences.beginReferenceTo(addr);
00065     IstrReferences::iterator end =
00066       istrReferences.endReferenceTo(addr);
00067     for(;i != end; ++i)
00068     {
00069       if ( !(*i).direct )
00070       {
00071         IMachineStatus* newStatus = status->Clone();
00072         _ReverseScan(scanning,(*i).to,newStatus);
00073         delete newStatus;
00074       }
00075     }
00076 
00077     // testa se esiste un'istruzione precedente
00078     if (!byteInfo[addr].IsPrevInstruction())
00079       break;
00080 
00081     // cerca istruzione precedente
00082     _DEBUG_(vma_t debug_temp_addr = addr);
00083     while (byteInfo.GetIstrLen(--addr) == 0);
00084     // !!! bug this can be a bastard overlapped code or non exit call
00085     // !!! only in max priority
00086     _PRG_ASSERT(byteInfo.GetIstrLen(addr) == (debug_temp_addr-addr));
00087 
00088     // leggi istruzione precedente
00089     Instruction currInstruction;
00090     int result = GetInstruction(*module,addr,currInstruction);
00091     if (!result)
00092     {
00093       _PRG_ASSERT(0);
00094       return;
00095     }
00096 
00097     // processa istruzione
00098     if (!scanning->ProcessInstruction(addr,currInstruction,status,*this))
00099       break;
00100   }
00101 }

void CodeParser::AddExportTempFlow vma_t    to,
enum ByteInfo::TPriority    priority
 

Definition at line 233 of file code.cpp.

References _PRG_ASSERT, IstrReferences::beginReferenceTo(), IstrReferences::endReferenceTo(), FLOW_NONE, IstrReference::from, CodeInfo::istrReferences, TempReference::priority, CodeInfo::pTempRefs, IstrReference::to, ByteInfo::TPriority, IstrReference::type, and vma_t.

Referenced by CheckCodeRecursively(), and Parse().

00234 {
00235   _PRG_ASSERT(pTempRefs != NULL);
00236 
00237   // !!! funzione ??
00238   if ( istrReferences.beginReferenceTo(to) !=
00239        istrReferences.endReferenceTo(to) )
00240     return;
00241 
00242         TempReference tempRef;
00243   tempRef.from     = 0; // !!!
00244   tempRef.type     = FLOW_NONE;
00245   tempRef.to       = to;
00246   tempRef.priority = static_cast<uchar>(priority);
00247 
00248   pTempRefs->push(tempRef);
00249 }

void CodeParser::AddTempFlow enum FlowTypes    flow,
vma_t    from,
vma_t    to,
enum ByteInfo::TPriority    priority
 

Definition at line 144 of file code.cpp.

References FLOW_CALL, FLOW_CJUMP, FLOW_JUMP, FLOW_NONE, FLOW_RET, FlowTypes, IstrReference::from, IstrReferences::IsPresent(), CodeInfo::istrReferences, ByteInfo::priCheckOnly, TempReference::priority, CodeInfo::pTempRefs, IstrReference::to, ByteInfo::TPriority, IstrReference::type, and vma_t.

00146 {
00147   if (flow == FLOW_NONE || flow == FLOW_RET)
00148     return;
00149 
00150   // non aggiungere se usato solo per check
00151 #ifdef DEBUG
00152   int inc = (priority == ByteInfo::priCheckOnly)?0:1;
00153 #endif
00154 
00155   TempReference tempRef;
00156   tempRef.from     = from;
00157   tempRef.type     = flow;
00158   tempRef.to       = to;
00159   tempRef.priority = static_cast<uchar>(priority);
00160 
00161   if (istrReferences.IsPresent(tempRef.from,tempRef.to))
00162     return;
00163 
00164         switch(flow)
00165   {
00166   case FLOW_CALL:
00167         pTempRefs->push(tempRef);
00168 #ifdef DEBUG
00169         calls += inc;
00170 #endif
00171         break;
00172   case FLOW_CJUMP:
00173   case FLOW_JUMP:
00174         pTempRefs->push(tempRef);
00175 #ifdef DEBUG
00176         jumps += inc;
00177 #endif
00178         break;
00179   }
00180 }

bool CodeParser::AddTempFlow enum FlowTypes    flow,
vma_t    from,
const Instruction   instruction,
vma_t    instAddress,
enum ByteInfo::TPriority    priority,
bool    bAddComplex = true
 

Definition at line 183 of file code.cpp.

References CodeInfo::apiAlias, Instruction::Args, CodeInfo::complexReference, ContainValidAddress(), FLOW_JUMP, FLOW_NONE, FLOW_RET, FlowTypes, ObjectModule::GetSymbols(), Param::literal, Param::mem_reg1, Param::mem_reg2, CodeInfo::module, null_reg, ByteInfo::priCheckOnly, Param::t_literal, Param::t_memory, ByteInfo::TPriority, Param::type, vma_t, and WriteInstruction().

Referenced by ExecuteComplexReferenceMemory(), ScanningComplexReg::ProcessInstruction(), and ScanCode().

00186 {
00187   if (flow == FLOW_NONE || flow == FLOW_RET)
00188     return true;
00189 
00190   const Param &param = instruction.Args[0];
00191   if (param.type != Param::t_literal)
00192   {
00193     // se memoria e solo offset registra indirizzo, vedi se chiamata DLL
00194     if (param.type == Param::t_memory)
00195       if (param.mem_reg1 == null_reg && param.mem_reg2 == null_reg)
00196       {
00197         if ( ContainValidAddress(param) )
00198         {
00199           pair<Symbols::iterator,Symbols::iterator> sym = module->GetSymbols()[param.literal];
00200           if ( sym.first != sym.second )
00201           {
00202             if (flow == FLOW_JUMP)
00203             {
00204               apiAlias[from] = param.literal;
00205             }
00206             return true; // ok! chiamata/salto a DLL
00207           }
00208         }
00209       }
00210 
00211     // !!! finish
00212     // se registro scandire indietro e vedere possibili valori
00213     //   (se costanti o variabili caricate)
00214     // se memoria del tipo [4*reg+const] provare tabella
00215     if (bAddComplex && priority != ByteInfo::priCheckOnly)
00216       complexReference.insert(instAddress);
00217 #if 0
00218 #ifdef DEBUG
00219     fprintf(stderr,"Debug: (Flow) ");
00220     WriteInstruction(instruction,stderr);
00221 #endif
00222 #endif
00223     return false;
00224   }
00225 
00226   // !!! check relocation ??
00227   // !!! se codice a 16 bit e chiamata far dovrebbe esserci rilocazione
00228 
00229   AddTempFlow(flow,from,instruction.Args[0].literal,priority);
00230   return true;
00231 }

bool CodeParser::CheckCode vma_t   address,
ByteInfo::TPriority    priority,
bool    bSetLabel = true
 

Definition at line 506 of file code.cpp.

References _PRG_ASSERT, ExtractTempRef(), ByteInfo::priCheckOnly, CodeInfo::pTempRefs, ResetCodeRange(), ScanCode(), scanCodeInvalid, scanCodeNoError, SetCodeRange(), ByteInfo::TPriority, TScanCodeResult, and vma_t.

Referenced by Parse().

00507 {
00508   _PRG_ASSERT(pTempRefs->size() == 0);
00509   TScanCodeResult lastResult = scanCodeNoError;
00510 
00511   // testa se il codice e' corretto
00512   vma_t start = address;
00513   vma_t scanAddress;
00514   try
00515   {
00516     scanAddress = start;
00517     lastResult = ScanCode(scanAddress,ByteInfo::priCheckOnly,bSetLabel);
00518   }
00519   catch(const ObjectModule::OutOfAddress&)
00520   {
00521     lastResult = scanCodeInvalid;
00522   }
00523   for (TempReference tempRef;ExtractTempRef(tempRef););
00524 
00525   // setta o resetta codice
00526   if (lastResult <= scanCodeNoError)
00527     SetCodeRange(range<vma_t>(start,scanAddress),priority,bSetLabel);
00528   else
00529     ResetCodeRange(range<vma_t>(start,scanAddress));
00530   {for (TempReference tempRef;ExtractTempRef(tempRef););}
00531 
00532   address = scanAddress;
00533 
00534   return (lastResult <= scanCodeNoError);
00535 }

bool CodeParser::CheckCodeRecursively vma_t    address,
ByteInfo::TPriority    priority,
bool    _bSetLabel = true
 

Definition at line 549 of file code.cpp.

References _PRG_ASSERT, AddExportTempFlow(), range_set< T >::begin(), range_set< T >::end(), ExtractTempRef(), range_set< T >::insert(), ByteInfo::priCheckOnly, CodeInfo::pTempRefs, ResetCodeRange(), ScanCode(), scanCodeInvalid, scanCodeNoError, SetCodeRange(), TAddresses, IstrReference::to, ByteInfo::TPriority, TScanCodeResult, and vma_t.

Referenced by Parse(), and THeuristicMotor::Process().

00550 {
00551   _PRG_ASSERT(pTempRefs->size() == 0);
00552 
00553   // insieme di codice scannato
00554   range_set<vma_t> ranges;
00555   // handle one instruction (jmp/ret) process
00556   TAddresses addresses;
00557   TScanCodeResult lastResult = scanCodeNoError;
00558   bool bSetLabel = _bSetLabel;
00559 
00560   // scandisci a partire dall'entry
00561   AddExportTempFlow(address,ByteInfo::priCheckOnly);
00562   for (;;)
00563   {
00564     TempReference tempRef;
00565     if (!ExtractTempRef(tempRef))
00566       break;
00567 
00568     // scandisci il codice
00569     vma_t address = tempRef.to;
00570     try
00571     {
00572       lastResult = ScanCode(address,ByteInfo::priCheckOnly,bSetLabel);
00573     }
00574     catch(const ObjectModule::OutOfAddress&)
00575     {
00576       lastResult = scanCodeInvalid;
00577     }
00578 
00579     // solo al primo non marcare label
00580     bSetLabel = true;
00581 
00582     // marca il codice scandito
00583     _PRG_ASSERT(tempRef.to <= address);
00584     if ( tempRef.to == address)
00585       addresses.insert(tempRef.to);
00586     else
00587       ranges.insert(range<vma_t>(tempRef.to,address));
00588 
00589     // se errore fermati
00590     if (lastResult > scanCodeNoError)
00591       break;
00592   }
00593 
00594   // scandisce tutti i range possibili
00595   {
00596   typedef range_set<vma_t>::iterator iterator;
00597   iterator i   = ranges.begin();
00598   iterator end = ranges.end();
00599   for(;i!=end;++i)
00600   {
00601     if (lastResult <= scanCodeNoError)
00602       SetCodeRange(*i,priority,_bSetLabel || (*i).begin != address);
00603     else
00604       // !!! se il codice e' scandito con successo setta priorita' anche
00605       // nella cella end. Non inserisce inst_offset+1 in ranges altrimenti
00606       // se e' un ret ScanCode successivo si ferma a meta' range
00607       ResetCodeRange(*i);
00608   }
00609   }
00610 
00611   // scandisce tutti gli indirizzi possibili
00612   {
00613   typedef TAddresses::iterator iterator;
00614   iterator i   = addresses.begin();
00615   iterator end = addresses.end();
00616   for(;i!=end;++i)
00617   {
00618     if (lastResult <= scanCodeNoError)
00619       SetCodeRange(range<vma_t>(*i,*i),priority,_bSetLabel || (*i) != address);
00620     else
00621       // !!! se il codice e' scandito con successo setta priorita' anche
00622       // nella cella end. Non inserisce inst_offset+1 in ranges altrimenti
00623       // se e' un ret ScanCode successivo si ferma a meta' range
00624       ResetCodeRange(range<vma_t>(*i,*i));
00625   }
00626   }
00627 
00628   // estrae tutti i reference temporanei
00629   for (TempReference tempRef;ExtractTempRef(tempRef););
00630 
00631   return (lastResult <= scanCodeNoError);
00632 }

void CodeParser::CheckForAddress vma_t    instAddress,
const Instruction   instruction,
enum ByteInfo::TPriority    priority
[private]
 

Definition at line 60 of file code.cpp.

References IstrReferences::Add(), CodeInfo::addrGeneral, Instruction::Args, CodeInfo::byteInfo, ContainValidAddress(), FLOW_NONE, Param::GetLiteralSize(), Param::GetMemSize(), ByteInfo::GetPriority(), ByteInfos::IsOccupied(), ByteInfo::len, Param::literal, Param::mem_reg1, Param::mem_reg2, null_reg, Instruction::numArg, ByteInfo::SetIsLabel(), ByteInfo::SetPriority(), ByteInfo::SetType(), Param::t_literal, Param::t_memory, ByteInfo::TPriority, Param::type, ByteInfo::typeInteger, CodeInfo::varReferences, and vma_t.

Referenced by ScanCode().

00061 {
00062   for (int n=0; n < instruction.numArg; ++n)
00063   {
00064     const Param *param = &instruction.Args[n];
00065     switch (param->type)
00066     {
00067     case Param::t_literal:
00068           if (param->GetLiteralSize() != addr_bytes)
00069           break;
00070       // testa indirizzo
00071       if (!ContainValidAddress(*param))
00072         break;
00073       // inserisci indirizzo corrente
00074                   addrGeneral.insert(param->literal);
00075       break;
00076     case Param::t_memory:
00077       // testa indirizzo
00078       if (!ContainValidAddress(*param))
00079         break;
00080       // testa indirizzamento diretto
00081       if (param->mem_reg1 == null_reg && param->mem_reg2 == null_reg)
00082       {
00083         // verifica che la memoria punti effettivamente a qualcosa,
00084         // altrimenti e' solo un riferimento
00085         if ( param->GetMemSize() != 0 )
00086         {
00087           varReferences.Add(instAddress,param->literal,FLOW_NONE);
00088 
00089           // !!! se priorita' piu alta ?
00090           if (!byteInfo.IsOccupied(param->literal,param->GetMemSize()))
00091           {
00092             ByteInfo& info = byteInfo[param->literal];
00093             if (info.GetPriority() < priority)
00094             {
00095               info.len = param->GetMemSize();
00096               // !!! not only Integer, can be float or a structure (for save state)
00097               info.SetType(ByteInfo::typeInteger);
00098               info.SetPriority(priority);
00099               info.SetIsLabel();
00100             }
00101           }
00102           break;
00103         }
00104       }
00105       // inserisci indirizzo corrente
00106                   addrGeneral.insert(param->literal);
00107       break;
00108     }
00109   }
00110 }

void CodeParser::CheckImmediateCodeAddress const Instruction   instruction [private]
 

Definition at line 113 of file code.cpp.

References _PRG_ASSERT, CodeInfo::addrConstants, Instruction::Args, ContainValidAddress(), Param::GetLiteralSize(), Instruction::instruction, Param::literal, Instruction::numArg, Param::t_literal, Param::type, and vma_t.

Referenced by ScanCode().

00114 {
00115   vma_t address;
00116   const Param *param;
00117   switch(instruction.instruction)
00118   {
00119   // solo mov e push dato che il parametro non e' usato per operazioni
00120   // (presuppongono assegnazione o copia)
00121   // !!! non portatile
00122   case istr_mov:
00123     _PRG_ASSERT(instruction.numArg >= 2);
00124     _PRG_ASSERT(instruction.Args[1].type != Param::t_literal || instruction.Args[1].GetLiteralSize() != 0);
00125         param = &instruction.Args[1];
00126     goto addr_ok;
00127   case istr_push:
00128         param = &instruction.Args[0];
00129   addr_ok:
00130     // verifica dimensione e
00131         if ( param->type != Param::t_literal || param->GetLiteralSize() != addr_bytes )
00132         break;
00133     address = param->literal;
00134 
00135     // testa codice
00136     if (!ContainValidAddress(*param))
00137       break;
00138     // inserisci indirizzo corrente
00139                 addrConstants.insert(address);
00140         break;
00141   }
00142 }

void CodeParser::CheckJumpReference vma_t    address,
const Instruction   instruction
[private]
 

Definition at line 129 of file codeprn.cpp.

References CodeInfo::apiAlias, Instruction::Args, ObjectModule::GetExportSymbols(), ObjectModule::GetSymbols(), IsPresent(), Param::literal, Param::mem_reg1, Param::mem_reg2, CodeInfo::module, null_reg, Instruction::numArg, StartBeginComment(), Param::t_literal, Param::t_memory, Param::type, and vma_t.

Referenced by WriteCode().

00130 {
00131         // check for api reference
00132   for (int i=0; i<instruction.numArg; ++i)
00133   {
00134     const Param &arg = instruction.Args[i];
00135     if (arg.type == Param::t_memory)
00136     {
00137       // call/jmp dword ptr [constant]
00138                         if (arg.mem_reg1 == null_reg && arg.mem_reg2 == null_reg)
00139       {
00140         pair<Symbols::iterator,Symbols::iterator> sym = module->GetSymbols()[arg.literal];
00141         for(;sym.first != sym.second;++sym.first)
00142         {
00143           StartBeginComment();
00144           printf("Reference to %s",(*sym.first).name.c_str());
00145         }
00146       }
00147     }
00148     if (arg.type == Param::t_literal)
00149     {
00150       // salti a jmp ad api
00151                         if (IsPresent(apiAlias,arg.literal))
00152       {
00153         pair<Symbols::iterator,Symbols::iterator> sym = module->GetSymbols()[apiAlias[arg.literal]];
00154         for(;sym.first != sym.second;++sym.first)
00155         {
00156           StartBeginComment();
00157           printf("Reference to %s",(*sym.first).name.c_str());
00158         }
00159       }
00160 
00161       // salti a funzioni esportate
00162       pair<Symbols::iterator,Symbols::iterator> sym = module->GetExportSymbols()[arg.literal];
00163       for(;sym.first != sym.second;++sym.first)
00164       {
00165         StartBeginComment();
00166         printf("Reference to %s",(*sym.first).name.c_str());
00167       }
00168     }
00169   }
00170 }

void CodeParser::CheckReference vma_t    address [private]
 

Definition at line 102 of file codeprn.cpp.

References IstrReferences::beginReferenceTo(), IstrReferences::endReferenceTo(), ObjectModule::GetEntryPoint(), ObjectModule::GetExportSymbols(), CodeInfo::istrReferences, CodeInfo::module, StartBeginComment(), and vma_t.

Referenced by WriteCode().

00103 {
00104   // entry point
00105   if (address == module->GetEntryPoint())
00106   {
00107     StartBeginComment();
00108     printf("Program entry point");
00109   }
00110 
00111   // export
00112   // !!! manca ordinal
00113   pair<Symbols::iterator,Symbols::iterator> sym = module->GetExportSymbols()[address];
00114   for(;sym.first != sym.second;++sym.first)
00115   {
00116     StartBeginComment();
00117     printf("Exported function %s",(*sym.first).name.c_str());
00118   }
00119 
00120         // testa presenza riferimento
00121   std::for_each(istrReferences.beginReferenceTo(address),
00122       istrReferences.endReferenceTo(address),
00123       CheckRef());
00124 }

bool CodeParser::ContainValidAddress const Param   param const
 

Definition at line 33 of file codeglob.cpp.

References ObjectModule::HasRelocation(), ObjectModule::IsValid(), Param::literal, CodeInfo::module, and Param::relocation.

Referenced by AddTempFlow(), CheckForAddress(), CheckImmediateCodeAddress(), ExecuteComplexReferenceMemory(), IsApiReference(), and THeuristicMotor::THeuristicMotor().

00034 {
00035   if (!module->HasRelocation())
00036     return module->IsValid(param.literal);
00037   return param.relocation != NULL;
00038 }

void CodeParser::ExcludeFileRange CSignFile   _file,
const RVAFileTranslator   rva,
uint32_t    imageBase
[private]
 

Definition at line 642 of file code.cpp.

References range< T >::begin, range_set< T >::begin(), CodeInfo::byteInfo, range< T >::end, range_set< T >::end(), RVAFileTranslator::File2RVASafe(), CSignFile::GetRanges(), RVAFileTranslator::GetSection(), ByteInfo::priMax, PeSection::RawAddress, PeSection::RawSize, ByteInfo::SetPriority(), ByteInfo::SetType(), ByteInfo::typeLoader, and vma_t.

Referenced by Parse().

00643 {
00644   range_set<long> excludeRange = _file.GetRanges();
00645   range_set<long>::iterator i   = excludeRange.begin();
00646   range_set<long>::iterator end = excludeRange.end();
00647   for( ;i!= end; ++i)
00648   {
00649     // !!! troppo dipendente da formato Pe
00650     vma_t start;
00651     vma_t finish;
00652     try
00653     {
00654       start  = rva.File2RVASafe((*i).begin) + imageBase;
00655       finish = rva.File2RVASafe((*i).end-1) + imageBase;
00656     }
00657     catch(std::runtime_error&)
00658     { continue; }
00659 
00660 //    _DEBUG_(fprintf(stderr,"start: %08lX end: %08lX\n",start,finish));
00661 
00662     range<long> r = *i;
00663 
00664     // !!! bug finire
00665     // testa per piu' sezioni
00666     while( (finish-start+1) != static_cast<unsigned long>(r.end - r.begin) )
00667     {
00668       // trova prima sezione
00669       const PeSection *p;
00670       for(unsigned n=0;; ++n)
00671       {
00672         p = rva.GetSection(n);
00673         if (p == NULL)
00674         {
00675           throw runtime_error("I think there is a bug inside");
00676         }
00677         if ((unsigned long)r.begin >= p->RawAddress && ((unsigned long)r.begin-p->RawAddress) < p->RawSize)
00678         {
00679           // elimina questa sezione
00680           ByteInfo& info = byteInfo[start];
00681           info.SetPriority(ByteInfo::priMax);
00682           info.SetType(ByteInfo::typeLoader);
00683           // setta la lunghezza lunga
00684 //          _DEBUG_(fprintf(stderr,"len setted: %lX\n",p->RawSize - (r.begin-p->RawAddress)));
00685           byteInfo.SetLen(start,p->RawSize - (r.begin-p->RawAddress) );
00686 
00687           // vai alla prossima sezione
00688           r.begin = p->RawAddress+p->RawSize;
00689           start = rva.File2RVASafe(r.begin) + imageBase;
00690           break;
00691         }
00692       }
00693     }
00694 
00695     // setta informazioni
00696     ByteInfo& info = byteInfo[start];
00697     info.SetPriority(ByteInfo::priMax);
00698     info.SetType(ByteInfo::typeLoader);
00699     // setta la lunghezza lunga
00700 //    _DEBUG_(fprintf(stderr,"len setted: %lX\n",finish-start+1));
00701     byteInfo.SetLen(start,finish-start+1);
00702   }
00703 }

bool CodeParser::ExecuteComplexReference vma_t    address
 

Definition at line 400 of file codescan.cpp.

References _PRG_ASSERT, Instruction::Args, ExecuteComplexReferenceMemory(), ExecuteComplexReferenceReg(), GetInstruction(), CodeInfo::module, Instruction::numArg, Param::t_memory, Param::t_registry, Param::type, and vma_t.

Referenced by Parse().

00401 {
00402   _PRG_ASSERT(&*module != NULL);
00403 
00404   // leggi prossima istruzione
00405   Instruction currInstruction;
00406   int result = GetInstruction(*module,address,currInstruction);
00407   if (!result || currInstruction.numArg != 1)
00408   {
00409     // !!!
00410     _PRG_ASSERT(0);
00411     return false;
00412   }
00413 
00414   if ( currInstruction.Args[0].type == Param::t_registry )
00415     return ExecuteComplexReferenceReg(address,currInstruction);
00416 
00417   if ( currInstruction.Args[0].type == Param::t_memory )
00418     return ExecuteComplexReferenceMemory(address,currInstruction);
00419 
00420   return false;
00421 }

bool CodeParser::ExecuteComplexReferenceMemory vma_t    address,
const Instruction   instruction
 

Definition at line 268 of file codescan.cpp.

References _PRG_ASSERT, AddTempFlow(), Instruction::Args, IstrReferences::beginReferenceTo(), CodeInfo::byteInfo, ContainValidAddress(), IstrReferences::endReferenceTo(), f77_min(), Param::factor, ObjectModule::GetDataReader(), Instruction::GetFlowType(), GetInstruction(), Param::GetMemSize(), ByteInfo::GetPriority(), RelocationInfos::GetRelocation(), ObjectModule::GetRelocationInfos(), ObjectModule::GetSection(), ObjectModule::HasRelocation(), Instruction::instruction, IsCodePointer(), IsNullAddress(), ByteInfos::IsOccupied(), IstrReferences::iterator, ByteInfo::len, Param::literal, Param::mem_reg1, Param::mem_reg2, CodeInfo::module, null_reg, Instruction::numArg, ObjectModule::DataReader::ReadDword(), ByteInfo::SetPriority(), ByteInfo::SetType(), Param::t_literal, Param::t_memory, ObjectModule::DataReader::Tell(), ByteInfo::TPriority, Param::type, ByteInfo::typePointer, CodeInfo::varReferences, and vma_t.

Referenced by ExecuteComplexReference(), and ScanningComplexReg::ProcessInstruction().

00269 {
00270   _PRG_ASSERT(instruction.numArg == 1);
00271   _PRG_ASSERT(instruction.Args[0].type == Param::t_memory);
00272   _PRG_ASSERT(&*module != NULL);
00273   const Param& arg = instruction.Args[0];
00274   // check for simple jmp dword ptr[reg*4+const]
00275   // !!! not portable
00276   // !!! un pochino semplificato
00277   if (arg.mem_reg1 == null_reg && arg.mem_reg2 != null_reg && arg.factor == addr_bytes)
00278   {
00279     // !!! gestire sovrapposizioni con codice
00280     if (ContainValidAddress(arg))
00281     {
00282       unsigned count = 0;
00283       bool isFirstValid = true;
00284       // !!! size constant
00285       try
00286       {
00287                                 ObjectModule::DataReader reader = module->GetDataReader(arg.literal);
00288         for(;;)
00289         {
00290           for(;;)
00291           {
00292             vma_t addr;
00293             // !!! la seconda volta sono gia' marcati
00294             if (byteInfo.IsOccupied(reader.Tell(),addr_bytes))
00295             {
00296               if (!IsCodePointer(byteInfo,reader.Tell()))
00297                 break;
00298             }
00299             if (module->HasRelocation() && !module->GetRelocationInfos().GetRelocation(reader.Tell()))
00300               break;
00301             addr = reader.ReadDword();
00302             if (!module->GetSection(addr)->IsCode())
00303               break;
00304             ++count;
00305           }
00306           if (count !=0)
00307             break;
00308           // ignora errore se e' il primo
00309           ++count;
00310           isFirstValid = false;
00311                                         // starting skipping first entry
00312                                         reader = reader = module->GetDataReader(arg.literal+addr_bytes);
00313         }
00314       }
00315       catch(const ObjectModule::OutOfAddress&) {}
00316       if (!isFirstValid)
00317         --count;
00318       if (count<=2) // !!! costante
00319         return false;
00320 
00321       // aggiunge tutti i puntatori per scandire codice
00322       enum ByteInfo::TPriority priority = byteInfo[address].GetPriority();
00323       vma_t tableAddress = arg.literal + (isFirstValid ? 0 : addr_bytes);
00324                         ObjectModule::DataReader reader = module->GetDataReader(tableAddress);
00325       for(; count != 0 ; --count)
00326       {
00327         ByteInfo& info = byteInfo[reader.Tell()];
00328         info.len = addr_bytes;
00329         info.SetType(ByteInfo::typePointer);
00330         info.SetPriority(priority);
00331         vma_t pointer = reader.ReadDword();
00332         AddTempFlow(instruction.GetFlowType(),address,pointer,priority);
00333       }
00334       byteInfo[tableAddress].SetIsLabel();
00335       return true;
00336     }
00337   }
00338 
00339   if (arg.mem_reg1 == null_reg && arg.mem_reg2 == null_reg && arg.GetMemSize() == (unsigned int)addr_bytes)
00340   {
00341     // se non e' un indirizzo invalido esci
00342     if (!ContainValidAddress(arg))
00343       return false;
00344 
00345     // processa contenuto corrente
00346     if (!module->HasRelocation() || module->GetRelocationInfos().GetRelocation(arg.literal))
00347     {
00348       vma_t addr;
00349                         ObjectModule::DataReader reader = module->GetDataReader(arg.literal);
00350       addr = reader.ReadDword();
00351       if (!IsNullAddress(addr) && module->GetSection(addr)->IsCode())
00352       {
00353         AddTempFlow(instruction.GetFlowType(),address,addr,
00354                     byteInfo[address].GetPriority());
00355       }
00356     }
00357 
00358           // processa riferimenti
00359     IstrReferences::iterator i   =
00360       varReferences.beginReferenceTo(arg.literal);
00361     IstrReferences::iterator end =
00362       varReferences.endReferenceTo(arg.literal);
00363 
00364     const ByteInfo& info = byteInfo[arg.literal];
00365 
00366     for(;i != end; ++i)
00367     {
00368       if ( !(*i).direct )
00369       {
00370         // la priorita' della chiamata e' la minima tra chiamata e memoria
00371         enum ByteInfo::TPriority priority = 
00372           f77_min(byteInfo[address].GetPriority(),info.GetPriority());
00373 
00374         // leggi istruzione
00375         Instruction instruction;
00376         int result = GetInstruction(*module,(*i).to,instruction);
00377         if (!result)
00378           return false;
00379 
00380         // !!! test brutale mov [xxx],xxx
00381         if (instruction.instruction == istr_mov && instruction.Args[0].type == Param::t_memory && instruction.Args[1].type == Param::t_literal)
00382         {
00383           _PRG_ASSERT(instruction.Args[0].mem_reg1 == null_reg);
00384           _PRG_ASSERT(instruction.Args[0].mem_reg2 == null_reg);
00385           _PRG_ASSERT(instruction.Args[0].literal  == arg.literal);
00386           if (ContainValidAddress(instruction.Args[1]))
00387             AddTempFlow(instruction.GetFlowType(),address,
00388                     instruction.Args[1].literal,
00389                     priority);
00390         }
00391       }
00392     }
00393     return true;
00394   }
00395 
00396   return false;
00397 }

bool CodeParser::ExecuteComplexReferenceReg vma_t    address,
const Instruction   instruction
 

Definition at line 248 of file codescan.cpp.

References _PRG_ASSERT, Instruction::Args, ScanningComplexReg::GetResult(), Param::mem_reg1, Instruction::numArg, reg_t, ReverseScan(), Param::t_registry, Param::type, and vma_t.

Referenced by ExecuteComplexReference().

00249 {
00250   _PRG_ASSERT(instruction.numArg == 1);
00251   _PRG_ASSERT(instruction.Args[0].type == Param::t_registry);
00252   reg_t reg = instruction.Args[0].mem_reg1;
00253   ScanningComplexReg scan(address,reg);
00254   ReverseScan(&scan,address);
00255   return scan.GetResult();
00256 }

bool CodeParser::ExtractTempRef TempReference   tempRef
 

Definition at line 252 of file code.cpp.

References _PRG_ASSERT, IstrReferences::Add(), FLOW_CALL, FLOW_CJUMP, FLOW_JUMP, IstrReference::from, CodeInfo::istrReferences, ByteInfo::priCheckOnly, TempReference::priority, CodeInfo::pTempRefs, IstrReference::to, and IstrReference::type.

Referenced by CheckCode(), CheckCodeRecursively(), and Parse().

00253 {
00254         // assicurati che riferimenti sia inizializzato
00255   _PRG_ASSERT((pTempRefs!=NULL));
00256 
00257         if (pTempRefs->empty())
00258         return false;
00259 
00260   // estrae elemento
00261   tempRef = pTempRefs->top();
00262   pTempRefs->pop();
00263 
00264   // non aggiungere se usato solo per check
00265   if (tempRef.priority == ByteInfo::priCheckOnly)
00266     return true;
00267 
00268   // decrementa contatori e aggiungere reference fissi
00269   switch(tempRef.type)
00270   {
00271   case FLOW_CALL:
00272     istrReferences.Add(tempRef.from,tempRef.to,tempRef.type);
00273 #ifdef DEBUG
00274         --calls;
00275 #endif
00276         break;
00277   case FLOW_CJUMP:
00278   case FLOW_JUMP:
00279     istrReferences.Add(tempRef.from,tempRef.to,tempRef.type);
00280 #ifdef DEBUG
00281         --jumps;
00282 #endif
00283         break;
00284   }
00285 
00286   return true;
00287 }

void CodeParser::GetBitStat vma_t    address,
unsigned    numBytes,
BitStat   stat
[private]
 

Definition at line 120 of file data.cpp.

References CodeParser::BitStat::bit16, CodeParser::BitStat::bit32, CodeParser::BitStat::bit8, byte, CodeInfo::byteInfo, ObjectModule::GetDataReader(), ByteInfos::IsOccupied(), CodeInfo::module, ObjectModule::DataReader::ReadByte(), ObjectModule::DataReader::Tell(), and vma_t.

00121 {
00122   // init counters
00123   fill(stat.bit8,stat.bit8+8,0);  
00124   fill(stat.bit16,stat.bit16+16,0);  
00125   fill(stat.bit32,stat.bit32+32,0);
00126   
00127   unsigned n;
00128   try
00129   {
00130                 ObjectModule::DataReader reader = module->GetDataReader(address);
00131     for (n=0;n<numBytes;++n)
00132     {
00133       if (byteInfo.IsOccupied(reader.Tell()))
00134         break;
00135       uint8_t byte = reader.ReadByte();
00136 
00137       // increment counters
00138       unsigned *pCount = &stat.bit32[(n%4u)*8u];
00139       for(unsigned n=1;n != (1<<8);++pCount,n<<=1)
00140         if(byte & n)
00141           ++*pCount;
00142     }
00143   }
00144   catch(const ObjectModule::OutOfAddress&) {}; // se errore lettura si ferma
00145 
00146   // group counters
00147   for(n=0;n < 16;++n)
00148     stat.bit16[n] = stat.bit32[n] + stat.bit32[n+16];
00149   for(n=0;n < 8;++n)
00150     stat.bit8[n] = stat.bit16[n] + stat.bit16[n+8];
00151 }

void CodeParser::GetPointerArrayStats vma_t    address,
PointerArrayStat   stat
[private]
 

Definition at line 79 of file data.cpp.

References CodeInfo::byteInfo, ObjectModule::GetDataReader(), ObjectModule::GetSection(), IsNullAddress(), ByteInfos::IsOccupied(), ObjectModule::IsValid(), CodeInfo::module, CodeParser::PointerArrayStat::nCodePointer, CodeParser::PointerArrayStat::nFirstNull, CodeParser::PointerArrayStat::nNull, CodeParser::PointerArrayStat::nPointer, ObjectModule::DataReader::ReadDword(), ObjectModule::DataReader::Tell(), and vma_t.

Referenced by Parse().

00080 {
00081   // inizializza statistiche
00082   stat.nCodePointer = 0;
00083   stat.nPointer     = 0;
00084   stat.nNull        = 0;
00085   stat.nFirstNull   = 0;
00086   bool bFirstNull = false;
00087   try
00088   {
00089                 ObjectModule::DataReader reader = module->GetDataReader(address);
00090     for (unsigned n=0;;++n)
00091     {
00092       // testa sovrapposizione
00093       if (byteInfo.IsOccupied(reader.Tell(),addr_bytes))
00094         break;
00095       // !!!
00096       vma_t addr = reader.ReadDword();
00097       // se puntatore nullo incrementa e testa se primo
00098       if (IsNullAddress(addr))
00099       {
00100         ++stat.nNull;
00101         // se primo puntatore nullo segna posizione
00102         if (!bFirstNull)
00103           stat.nFirstNull = n;
00104         bFirstNull = true;
00105       }
00106       // fermati primo indirizzo invalido non nullo
00107       else if (!module->IsValid(addr))
00108         break;
00109       ++stat.nPointer;
00110       if (module->GetSection(addr)->IsCode())
00111         ++stat.nCodePointer;
00112     }
00113   }
00114   catch(const ObjectModule::OutOfAddress&) {}; // se errore lettura si ferma
00115   // se non trovati puntatori nulli metti il primo puntatore nullo cella dopo
00116   if (!bFirstNull)
00117     stat.nFirstNull = stat.nPointer;
00118 }

void CodeParser::GetStringStats vma_t    address,
unsigned &    len,
unsigned &    num_printable
[private]
 

Definition at line 40 of file data.cpp.

References CodeInfo::byteInfo, ObjectModule::GetDataReader(), RelocationInfos::GetRelocation(), ObjectModule::GetRelocationInfos(), ObjectModule::HasRelocation(), ByteInfos::IsOccupied(), CodeInfo::module, ObjectModule::DataReader::ReadByte(), ObjectModule::DataReader::Tell(), and vma_t.

Referenced by Parse().

00041 {
00042   try
00043   {
00044                 ObjectModule::DataReader reader = module->GetDataReader(address);
00045     unsigned n = 0;
00046     num_printable = 0;
00047     for (;;)
00048     {
00049       // se rilocazioni ritorna
00050       if (module->HasRelocation()
00051           && module->GetRelocationInfos().GetRelocation(reader.Tell()))
00052       {
00053         len = num_printable = 0;
00054         return;
00055       }
00056 
00057       // se codice occupato ritorna
00058       if (byteInfo.IsOccupied(reader.Tell()))
00059       {
00060         len = num_printable = 0;
00061         return;
00062       }
00063 
00064       uint8_t car = reader.ReadByte();
00065       if (isprint(car))
00066         ++num_printable;
00067       ++n;
00068       if (car == 0)
00069         break;
00070     }
00071     len = n;
00072   }
00073   catch(const ObjectModule::OutOfAddress&)
00074   {
00075     len = num_printable = 0;
00076   }
00077 }

bool CodeParser::IsApiReference const Param   arg const
 

Definition at line 290 of file code.cpp.

References _PRG_ASSERT, CodeInfo::apiAlias, ContainValidAddress(), ObjectModule::GetSymbols(), Symbols::IsValid(), Param::literal, Param::mem_reg1, Param::mem_reg2, CodeInfo::module, null_reg, Param::t_literal, Param::t_memory, and Param::type.

Referenced by THeuristicMotor::THeuristicMotor().

00291 {
00292   // !!! aggiungere parametro *string e se valido e true settarlo
00293     if (arg.type == Param::t_memory)
00294     {
00295       // !!! function
00296       if (ContainValidAddress(arg))
00297                           if (arg.mem_reg1 == null_reg && arg.mem_reg2 == null_reg)
00298         {
00299           _PRG_ASSERT(module!=NULL);
00300           if (module->GetSymbols().IsValid(arg.literal))
00301             return true;
00302         }
00303       return false;
00304     }
00305     if (arg.type == Param::t_literal)
00306     {
00307       // salti a jmp ad api
00308       TApiAlias::const_iterator i = apiAlias.find(arg.literal);
00309                         if (i != apiAlias.end())
00310       {
00311         _PRG_ASSERT(module!=NULL);
00312         if (module->GetSymbols().IsValid((*i).second))
00313           return true;
00314       }
00315 //
00316 //      // salti a funzioni esportate
00317 //      _PRG_ASSERT(exportedApi!=NULL);
00318 //      std::string func = (*exportedApi)[arg.literal];
00319 //      if (func != "")
00320 //      {
00321 //        printf("\n* Reference to %s\n|\n",func.c_str());
00322 //      }
00323     }
00324   return false;
00325 }

void CodeParser::Parse CSignFile   _file,
uint32_t    imageBase,
vma_t    entryPoint,
const RVAFileTranslator   rva,
const Symbols   api,
const Symbols   exportedApi,
bool    hasRelocation,
const RelocationInfos   relocationInfos
[private]
 

Definition at line 706 of file code.cpp.

References _DEBUG_, _PRG_ASSERT, AddExportTempFlow(), CodeInfo::addrConstants, CodeInfo::byteInfo, CheckCode(), CheckCodeRecursively(), CodeInfo::complexReference, ExcludeFileRange(), ExecuteComplexReference(), ExtractTempRef(), FOR_EACH_SECTION_CODE_BEGIN, FOR_EACH_SECTION_CODE_END, ObjectModule::GetDataReader(), ObjectModule::GetEntryPoint(), ObjectModule::GetExportSymbols(), GetInstruction(), ByteInfos::GetIstrLen(), Symbols::GetNextValid(), GetPointerArrayStats(), RelocationInfos::GetRelocation(), ObjectModule::GetRelocationInfos(), ObjectModule::GetSection(), GetStringStats(), Instruction::instruction, IsNullAddress(), ByteInfo::len, CodeInfo::module, CodeParser::PointerArrayStat::nCodePointer, CodeParser::PointerArrayStat::nFirstNull, CodeParser::PointerArrayStat::nPointer, ByteInfo::priConstant, ByteInfo::priEntryPoint, ByteInfo::priExport, ByteInfo::priFiller, TempReference::priority, CodeInfo::pTempRefs, ObjectModule::DataReader::ReadByte(), ObjectModule::DataReader::ReadDword(), RelocationInfos::relError, ScanCode(), scanCodeAlreadyProcessed, ByteInfo::SetPriority(), ByteInfo::SetType(), IstrReference::to, TTempRefs, ByteInfo::typeASCIIZ, ByteInfo::typeInteger, ByteInfo::typePointer, vma_t, WriteCode(), and x86instructions_names.

Referenced by ParseCode().

00709 {
00710 //  istrReferences.insert(IstrReference(10,20,true,FLOW_CALL));
00711 //  istrReferences.insert(IstrReference(10,20,false,FLOW_CALL));
00712 //  if ( !(*istrReferences.begin()).direct )
00713 //    printf("0\n");
00714 //  istrReferences.insert(IstrReference(11,20,true,FLOW_CALL));
00715 //  if (istrReferences.lower_bound(IstrReference(10,0)) ==
00716 //      istrReferences.lower_bound(IstrReference(11,0)))
00717 //    printf("1\n");
00718 //  if (istrReferences.lower_bound(IstrReference(9,0)) !=
00719 //      istrReferences.lower_bound(IstrReference(10,0)))
00720 //    printf("2\n");
00721 //  if (istrReferences.lower_bound(IstrReference(11,0)) ==
00722 //      istrReferences.lower_bound(IstrReference(12,0)))
00723 //    printf("3\n");
00724 //  if (istrReferences.lower_bound(IstrReference(12,0)) !=
00725 //      istrReferences.lower_bound(IstrReference(13,0)))
00726 //    printf("4\n");
00727 //  if (istrReferences.lower_bound(IstrReference(12,0)) !=
00728 //      istrReferences.end())
00729 //    printf("5\n");
00730 //  if (!IsPresent(istrReferences,IstrReference(10,20)))
00731 //    printf("6\n");
00732 
00733 #ifdef DEBUG
00734   unsigned maxStringInCode = 0;
00735   unsigned currStringLen = 0;
00736   unsigned istrCount[num_instructions];
00737   memset(&istrCount,0,sizeof(istrCount));
00738 #endif
00739 
00740   // escludi bytes letti da file
00741   ExcludeFileRange(_file,rva,imageBase);
00742 
00743   ObjectModule _module(_file,rva,imageBase,hasRelocation,relocationInfos,
00744                 _symbols,_exportedSymbols,_entryPoint);
00745   // !!! creare interno classe
00746   this->module = &_module;
00747 
00748         vma_t end;
00749 
00750   // verifica che ci sia qualcosa da disassemblare
00751   int numCodeSections = 0;
00752   FOR_EACH_SECTION_CODE_BEGIN(module,p)
00753     if ( (*p).IsCode() )
00754       ++numCodeSections;
00755   FOR_EACH_SECTION_CODE_END(module,p)
00756   if (numCodeSections == 0)
00757     return;
00758 
00759 #ifdef DEBUG
00760   bytes = 0;
00761   bytes = jumps = calls = 0;
00762   loopCount = 0;
00763 #endif
00764   pTempRefs = new TTempRefs;
00765 
00766   // prima scansione, entrypoint ed Export
00767   // !!! solo se punta a codice
00768   for(vma_t address = module->GetExportSymbols().GetNextValid(0); !IsNullAddress(address); address = module->GetExportSymbols().GetNextValid(address))
00769     if (module->GetSection(address)->IsCode())
00770     {
00771       // scandisce testando (elimina export a dati)
00772       CheckCodeRecursively(address,ByteInfo::priExport);
00773     }
00774   if (!IsNullAddress(module->GetEntryPoint()))
00775           AddExportTempFlow(module->GetEntryPoint(),ByteInfo::priEntryPoint);
00776 
00777   bool bProcessed = false;  // processato del codice ?
00778   // ha scandito altro codice dal controllo dei reference??
00779   bool bFlowChangedSinceReference = false;
00780   // ha scandito altro codice dal controllo api??
00781   bool bFlowChangedSinceApi       = false;
00782   // c'e' qualcosa di incognito (reference, api) ?
00783   bool bSomeUnknown               = false;
00784   bool bUseConstantPrinted        = false;
00785 
00786   freddy77::auto_delete_ptr<THeuristicMotor> heuristics;
00787 
00788 
00789   // esegui finche' c'e' qualcos'altro da fare
00790   for(;;)
00791   {
00792     // !!! se processati heuristico o costanti i reference sono gia' eliminati,
00793     // non riprocessa jump complessi e API
00794     // scandisci codici da salti/chiamate incontrate
00795 //    bProcessed = false;
00796     for(;;)
00797     {
00798       // estrae un reference
00799       TempReference tempRef;
00800       if (!ExtractTempRef(tempRef))
00801         break;
00802 
00803       // processa reference
00804       vma_t address = tempRef.to;
00805 
00806       if (ScanCode(address,static_cast<ByteInfo::TPriority>(tempRef.priority)) !=
00807           scanCodeAlreadyProcessed && address != tempRef.to)
00808 //                      if (CheckCode(address,static_cast<ByteInfo::TPriority>(tempRef.priority)) && address != tempRef.to)
00809         bProcessed = true;
00810     }
00811 
00812     // se processato forza riscansione
00813     if (bProcessed)
00814     {
00815       bFlowChangedSinceApi       = true;
00816       bFlowChangedSinceReference = true;
00817       bSomeUnknown               = false;
00818     }
00819 
00820         // cerca di usare chiamate/salti complessi (indirizzo in memoria o registro)
00821                 if (bFlowChangedSinceReference && !bSomeUnknown) for(bProcessed = false;;)
00822     {
00823       bFlowChangedSinceReference = false;
00824 
00825         // !!! la dimensione del container puo' variare dentro il loop
00826         // estrae reference complessi (non leverli dal container??)
00827       if ( complexReference.empty() )
00828         break;
00829 
00830 #if 0
00831 #ifdef DEBUG
00832       {
00833       TTempComplexReference::iterator i = complexReference.begin();
00834       for(int n=1;i != complexReference.end();++i,++n)
00835       {
00836         if ( (n%6) == 1 )
00837           fprintf(stderr,"Debug: (Complex) ");
00838         fprintf(stderr,(n%6==0)?"%08lX\n":"%08lX ",unsigned(*i));
00839       }
00840       fprintf(stderr,"\n");
00841       }
00842 #endif
00843 #endif
00844 
00845       // cerca di "eseguire" reference
00846       TTempComplexReference::iterator i = complexReference.begin();
00847 #ifdef DEBUG
00848       unsigned numUnknown = 0;
00849       unsigned numKnown   = 0;
00850 #endif
00851       for(;i != complexReference.end();++i)
00852       {
00853         if (!ExecuteComplexReference(*i))
00854         {
00855           // se non riuscito a processare tutti i salti possibili
00856           // segnalo
00857           bSomeUnknown = true;
00858           _DEBUG_(++numUnknown);
00859         }
00860         else
00861         {
00862           // se trova altri salti da fare aggiungili alla lista
00863           bProcessed = true;
00864           _DEBUG_(++numKnown);
00865         }
00866       }
00867 #ifdef DEBUG
00868       if ( (numKnown+numUnknown) != 0 )
00869         fprintf(stderr,"Debug: (Complex) Perc %f\n",
00870           float(((double)numKnown*100)/(numKnown+numUnknown)));
00871 #endif
00872 
00873       // se eseguito segna esecuzione e togli
00874       // !!! no, potrebbe variare il flusso del codice
00875       break;
00876     }
00877     if (bProcessed)
00878     {
00879       // !!! fa schifo
00880       bProcessed = false;
00881         continue;
00882     }
00883 
00884     // !!! finish !!!
00885     // cerca di avere tutte le info per il codice delle chiamate alle api
00886     // se c'e' gia' qualcosa di sbagliato alla fine ce ne sara' comunque
00887                 if (bFlowChangedSinceApi && !bSomeUnknown) for(bProcessed = false;;)
00888     {
00889       bFlowChangedSinceApi = false;
00890         bSomeUnknown = true; // !!!
00891         // !!! la dimensione del container puo' variare dentro il loop
00892         // estrae reference complessi (non leverli dal container??)
00893       break;
00894 
00895       // cerca di "eseguire" api
00896 /*
00897       // se trova altri indirizzi codice aggiungili alla lista
00898         bProcessed = true;
00899 
00900       // se non tolti tutti
00901         // segnalo
00902         bSomeUnknown = true;
00903 */
00904     }
00905     if (bProcessed)
00906     {
00907       // !!! fa schifo
00908       bProcessed = false;
00909         continue;
00910     }
00911 
00912 /*
00913     // Il programma non e' abbastanza preciso per questo!!
00914     // non c'e' niente antro da scandire
00915     // !!! e le costanti puntate dal codice sopra ???
00916     if (!bSomeUnknown)
00917     {
00918 #ifdef DEBUG
00919       {
00920       unsigned bytes = 0;
00921       FOR_EACH_SECTION_CODE_BEGIN(module,p)
00922               vma_t address = (*p).begin;
00923             end            = (*p).end;
00924               for(; address<end; )
00925         {
00926           int len = byteInfo.GetIstrLen(address);
00927           if (len != 0)
00928           {
00929             bytes += len;
00930             address += len;
00931           }
00932           else
00933             ++address;
00934         }
00935       FOR_EACH_SECTION_CODE_END(module,p)
00936       unsigned codeSize = 0;
00937       FOR_EACH_SECTION_CODE_BEGIN(module,p)
00938         codeSize += (*p).end - (*p).begin;
00939       FOR_EACH_SECTION_CODE_END(module,p)
00940       if (codeSize)
00941         fprintf(stderr,"\"Secure code\" %.1f%%\n",
00942           float(((double)bytes*100)/codeSize) );
00943       }
00944 #endif
00945         break;
00946     }
00947 */
00948 
00949     // metodo euristico, migliore degli export
00950     // !!! solo se non processato tutto, fa un test globale
00951     if (!&*heuristics)
00952       heuristics = new THeuristicMotor(*this);
00953 //      heuristics.reset(new THeuristicMotor());
00954     if ( (bProcessed=heuristics->ProcessSecure(*this)) != false )
00955       continue;
00956 
00957                 if (!bUseConstantPrinted)
00958     {
00959 #ifdef DEBUG
00960       {
00961       unsigned bytes = 0;
00962       FOR_EACH_SECTION_CODE_BEGIN(module,p)
00963               vma_t address = (*p).begin;
00964             end            = (*p).end;
00965               for(; address<end; )
00966         {
00967           int len = byteInfo.GetIstrLen(address);
00968           if (len != 0)
00969           {
00970             bytes += len;
00971             address += len;
00972           }
00973           else
00974             ++address;
00975         }
00976       FOR_EACH_SECTION_CODE_END(module,p)
00977       unsigned codeSize = 0;
00978       FOR_EACH_SECTION_CODE_BEGIN(module,p)
00979         codeSize += (*p).end - (*p).begin;
00980       FOR_EACH_SECTION_CODE_END(module,p)
00981       if (codeSize)
00982         fprintf(stderr,"\"Secure code\" %.1f%%\n",
00983           float(((double)bytes*100)/codeSize) );
00984       }
00985 #endif
00986         // !!! log windows ??
00987         fprintf(stderr,"Warning: Constant processed\n");
00988       if (complexReference.empty())
00989         fprintf(stderr,"Wow: complex reference is empty\n");
00990       if (addrConstants.empty())
00991         fprintf(stderr,"Wow: Constants address empty\n");
00992         bUseConstantPrinted = true;
00993     }
00994 
00995     // unsafe heuristic code process
00996 // !!! commented for priority reason purpose (less safe than constant??)
00997 //    if ( (bProcessed=heuristics->ProcessUnsecure(*this)) != false )
00998 //      continue;
00999 
01000           // cerca altro codice date le costanti salvate
01001           // questa e' l'ultima risorsa per riempire i buchi
01002           // testa prima che il codice sia valido
01003         for(;;)
01004           {
01005       if ( addrConstants.begin() == addrConstants.end() )
01006         break;
01007 
01008       vma_t address = *addrConstants.begin();
01009       addrConstants.erase(addrConstants.begin());
01010 
01011       // !!! aggiungere caso per indirizzo a dati non inizializzati
01012 
01013       // prova a vedere se e' una stringa
01014       unsigned len,printable;
01015       GetStringStats(address,len,printable);
01016 
01017       // se caratteri stampabili >= 75% assumi stringa
01018       if ( len >0 && printable>2 && printable*100 > (len-1)*75 )
01019       {
01020         ByteInfo& info = byteInfo[address];
01021         //info.len = len;
01022         info.SetPriority(ByteInfo::priConstant);
01023         info.SetType(ByteInfo::typeASCIIZ);
01024         // setta la lunghezza lunga
01025         byteInfo.SetLen(address,len);
01026         continue;
01027       }
01028 
01029       // prova a vedere se array di puntatori
01030       PointerArrayStat pStat;
01031       GetPointerArrayStats(address,pStat);
01032       // piu' di due puntatori non nulli, assumi array puntatori
01033       if ( pStat.nFirstNull >= 2 ) // !!! constant
01034       {
01035         // testa se puntatori a codice
01036         // !!! module non ammette Seek al byte subito dopo end
01037         if (pStat.nCodePointer >= pStat.nFirstNull)
01038         {
01039           for(unsigned n=0; n<pStat.nPointer;++n,address+=addr_bytes)
01040           {
01041             // marca come DWORD
01042             ByteInfo& info = byteInfo[address];
01043             info.len = addr_bytes;
01044             info.SetType(ByteInfo::typePointer);
01045             info.SetPriority(ByteInfo::priConstant);
01046 
01047             // "esegui" puntatore
01048                                                 ObjectModule::DataReader reader = module->GetDataReader(address);
01049             vma_t addr = reader.ReadDword();
01050             if (IsNullAddress(addr)) // fermarsi a ptr nullo
01051             {
01052               // fermati al primo indirizzo non al codice
01053               if (!module->GetSection(addr)->IsCode())
01054                 break;
01055               // !!! prima dovrebbe testarli tutti
01056               if (CheckCodeRecursively(addr,ByteInfo::priConstant))
01057                 bProcessed = true;
01058             }
01059           }
01060         }
01061         continue;
01062       }
01063 
01064       // !!! aggiungere parte check bit & range
01065       //BitStat bitStat;
01066       //GetBitStat(address,16*11,bitStat);
01067 
01068       // !!! assume sia codice
01069       if (module->GetSection(address)->IsCode())
01070         if (CheckCodeRecursively(address,ByteInfo::priConstant))
01071         {
01072           bProcessed = true;
01073         }
01074           }
01075 
01076           if (bProcessed)
01077                 continue;
01078 
01079     _PRG_ASSERT(pTempRefs->empty());
01080     _PRG_ASSERT(addrConstants.empty());
01081 
01082           // !!! testa istruzioni sovrapposte
01083     // !!! test overlapped instruction
01084 
01085     break;
01086   }
01087 
01088   // scandisce tutto il codice alla ricerca di codice non decompilato
01089   // salta bytes tutti a 0
01090   // scan all code for undisassembled code
01091   // skip zeroes bytes
01092   FOR_EACH_SECTION_CODE_BEGIN(module,p)
01093     vma_t address = (*p).begin;
01094     end            = (*p).end;
01095     for(; address<end; )
01096     {
01097                         ObjectModule::DataReader reader = module->GetDataReader(address);
01098 
01099       int len = byteInfo.GetIstrLen(address);
01100 
01101       // se gia' passato salta istruzione
01102             if (len != 0)
01103       {
01104 #ifdef DEBUG
01105                                 // capture some statistics on code
01106         // parse instruction
01107             Instruction currInstruction;
01108         int result = GetInstruction(*module,address,currInstruction);
01109         if (result)
01110         {
01111           _PRG_ASSERT(currInstruction.instruction>=0);
01112           _PRG_ASSERT(currInstruction.instruction<=num_instructions);
01113           ++istrCount[currInstruction.instruction];
01114                                         ObjectModule::DataReader reader = module->GetDataReader(address);
01115           for (int i=0;i<len;++i)
01116           {
01117             int c = reader.ReadByte();
01118             if (isprint(c))
01119             {
01120               ++currStringLen;
01121               if ( currStringLen > maxStringInCode )
01122               {
01123                 maxStringInCode = currStringLen;
01124               }
01125             }
01126             else
01127               currStringLen = 0;
01128           }
01129 
01130         }
01131 #endif
01132                 address += len;
01133           continue;
01134           }
01135       _DEBUG_(currStringLen = 0);
01136 
01137                         // if relocation it must be a pointer to somewhere
01138                         const Relocation *rel = 
01139                                 module->GetRelocationInfos().GetRelocation(address,addr_bytes);
01140                         if (rel && rel != &RelocationInfos::relError)
01141                         {
01142                                 ByteInfo& info = byteInfo[address];
01143                                 info.len = addr_bytes;
01144                                 info.SetType(ByteInfo::typeInteger);
01145                                 info.SetPriority(ByteInfo::priFiller);
01146 
01147                                 address += addr_bytes;
01148                                 continue;
01149                         }
01150                         
01151             // read next byte
01152           int c;
01153                         try {
01154                 c = reader.ReadByte();
01155                         }
01156                         catch (ObjectModule::OutOfAddress&)
01157                         {
01158           return; // !!!
01159                         }
01160 
01161       // se 0 leggi fino a che sono zeri o istruzione occupata
01162                         _PRG_ASSERT(len ==0);
01163             if ( c==0 )
01164           {
01165         _DEBUG_(currStringLen = 0);
01166         do
01167               {
01168                                         try {
01169                                 c = reader.ReadByte();
01170                                         }
01171                                         catch (ObjectModule::OutOfAddress&)
01172                                         {
01173                         c = -1;
01174                                         }
01175                   len = byteInfo.GetIstrLen(++address);
01176             } while ( c==0 && len==0 
01177                                                                 && !module->GetRelocationInfos().GetRelocation(address) 
01178                                                                 && address<end );
01179         continue;
01180       }
01181 
01182           // tutto ok , posso scandire il codice da qui
01183       vma_t checkAddr = address;
01184       if ( !CheckCode(checkAddr,ByteInfo::priFiller) )
01185       {
01186                                 // try on next byte
01187                                 // skipping all code that seam valid 
01188                                 // (doing address = checkAddr+1) can skip relocation
01189                                 ++address;
01190       }
01191 
01192         // se trova qualcosa di meglio da scandire ben venga
01193       // !!! non serve cercare la logica nell'illogico
01194     }
01195   FOR_EACH_SECTION_CODE_END(module,p)
01196 
01197   // estrae tutti i reference temporanei
01198   for (TempReference tempRef;ExtractTempRef(tempRef););
01199 
01200 #ifdef DEBUG
01201   fprintf(stderr,"Stat: (Code) MaxStringLenInCode: %u\n",maxStringInCode);
01202   for (unsigned ni=0; ni<num_instructions; ++ni)
01203     if (istrCount[ni])
01204       fprintf(stderr,"Stat: (Instr) %s: %u\n",
01205         x86instructions_names[ni],istrCount[ni]);
01206 #endif
01207 
01208   WriteCode();
01209 
01210   // mettere nel distruttore !!!
01211   delete pTempRefs;
01212   pTempRefs = NULL;
01213   // !!!
01214   this->module = NULL;
01215 }

void CodeParser::ResetCodeRange const range< vma_t > &    r [private]
 

Definition at line 467 of file code.cpp.

References _PRG_ASSERT, range< T >::begin, CodeInfo::byteInfo, range< T >::end, ByteInfo::GetPriority(), ByteInfo::len, ByteInfo::priCheckOnly, ByteInfo::Reset(), and vma_t.

Referenced by CheckCode(), and CheckCodeRecursively().

00468 {
00469   for(vma_t address = r.begin;;)
00470   {
00471     _PRG_ASSERT(address <= r.end);
00472     ByteInfo& info = byteInfo[address];
00473     _PRG_ASSERT(info.len != 0 || address == r.end);
00474     _PRG_ASSERT(info.GetPriority() == ByteInfo::priCheckOnly || address == r.end);
00475     int len = info.len;
00476     if (info.GetPriority() == ByteInfo::priCheckOnly)
00477     {
00478       // se errore leva marcatura
00479       info.Reset();
00480     }
00481     if (address == r.end)
00482       break;
00483     address += len;
00484   }
00485 }

void CodeParser::ReverseScan IScanning   scanning,
vma_t    address
 

Definition at line 103 of file codescan.cpp.

References _PRG_ASSERT, _ReverseScan(), IScanning::CreateMachineStatus(), CodeInfo::module, and vma_t.

Referenced by ExecuteComplexReferenceReg().

00104 {
00105   _PRG_ASSERT(scanning != NULL);
00106   IMachineStatus* status = scanning->CreateMachineStatus();
00107   _PRG_ASSERT(status != NULL);
00108   _PRG_ASSERT(&*module != NULL);
00109   _ReverseScan(scanning,address,status);
00110   delete status;
00111 }

enum CodeParser::TScanCodeResult CodeParser::ScanCode vma_t   address,
ByteInfo::TPriority    priority,
bool    bSetLabel = true
[private]
 

Definition at line 339 of file code.cpp.

References AddTempFlow(), Instruction::Args, CodeInfo::byteInfo, CheckForAddress(), CheckImmediateCodeAddress(), InstructionDecoder::Decode(), FLOW_CALL, FLOW_CJUMP, FLOW_JUMP, FLOW_RET, FlowTypes, ObjectModule::GetDataReader(), Instruction::GetFlowType(), ByteInfos::GetIstrLen(), ByteInfo::GetPriority(), ObjectModule::GetRelocationInfos(), ObjectModule::GetSection(), ByteInfo::GetType(), ByteInfos::IsOccupied(), ByteInfo::len, Param::literal, CodeInfo::module, ByteInfo::priCheckOnly, ByteInfo::priConstant, ByteInfo::priMax, scanCodeAlreadyProcessed, scanCodeInvalid, scanCodeInvalidJump, scanCodeNoError, scanCodeOverlapped, ByteInfo::SetIsLabel(), ByteInfo::SetIsPrevInstruction(), ByteInfo::SetPriority(), Param::t_literal, ByteInfo::TPriority, TScanCodeResult, Param::type, ByteInfo::typeInstruction, vma_t, and WriteInstruction().

Referenced by CheckCode(), CheckCodeRecursively(), Parse(), and SetCodeRange().

00340 {
00341   InstructionDecoder decoder(module->GetRelocationInfos());
00342 
00343   // verifica se la prima istruzione e' sovrapposta
00344   if ( priority != ByteInfo::priMax && byteInfo.GetIstrLen(address)==0
00345          && byteInfo.IsOccupied(address) )
00346   {
00347     return scanCodeOverlapped;
00348   }
00349 
00350   bool bFirst = true;
00351         ObjectModule::DataReader reader = module->GetDataReader(address);
00352   for(;;)
00353   {
00354 #ifdef DEBUG
00355 //    fprintf(stderr,"%08lX\t",address);
00356 //    printIstr = (address >= 0x7FAC699Alu);
00357 #endif
00358 
00359     ByteInfo &info = byteInfo[address];
00360 
00361     // !!! a volte e' utile non settare label anche se si analizza
00362     // setta label iniziale
00363     if (bFirst && bSetLabel)
00364       info.SetIsLabel();
00365 
00366     // check se l'istruzione e' gia' stata attraversata
00367     if ( info.len != 0 && priority <= info.GetPriority() )
00368     {
00369       // setta istruzione precedente
00370       // !!! priorita' per bCheckOnly
00371       if (!bFirst && priority != ByteInfo::priCheckOnly)
00372         info.SetIsPrevInstruction();
00373       if (bFirst)
00374         return scanCodeAlreadyProcessed;
00375                         if (info.GetType() != ByteInfo::typeInstruction)
00376                                 return scanCodeInvalid;
00377         break; // !!! ritornare un valore diverso ??
00378     }
00379 
00380     // leggi successiva istruzione
00381     Instruction currInstruction;
00382     int result = decoder.Decode(currInstruction,reader);
00383 
00384     // !!!
00385 //    if (result == 0 && priority == ByteInfo::priMax)
00386 //      throw std::runtime_error("Unknown code in max priority");
00387 
00388     if (!result)
00389       return scanCodeInvalid;
00390 
00391 #ifdef DEBUG
00392     if (printIstr)
00393       WriteInstruction(currInstruction);
00394 #endif
00395 
00396     // non sovraporre a codice gia' esistente
00397     if ( priority != ByteInfo::priMax && byteInfo.GetIstrLen(address)==0
00398          && byteInfo.IsOccupied(address+result-1) )
00399     {
00400       // !!! sicuro di questo ? non invalidare precedenti ?
00401       return scanCodeOverlapped;
00402     }
00403 
00404     // calcola tipo istruzione
00405     enum FlowTypes flow = currInstruction.GetFlowType();
00406 
00407     // verifica che il salto sia corretto
00408     // !!! verificare solo che il codice sia esatto ??
00409     if ( priority <= ByteInfo::priConstant )
00410       if ( flow == FLOW_JUMP || flow == FLOW_CJUMP || flow == FLOW_CALL )
00411         if ( currInstruction.Args[0].type == Param::t_literal )
00412         {
00413           if (!module->GetSection(currInstruction.Args[0].literal)->IsCode())
00414             return scanCodeInvalidJump;
00415         }
00416 
00417     // aggiornamento processo
00418 #ifdef DEBUG
00419     if ( ((++loopCount) & 0x3f) == 0 )
00420       fprintf(stderr,"Process: (Code) bytes: %lu calls: %lu jumps: %lu\n",
00421               bytes,calls,jumps);
00422 #endif
00423 
00424       // aggiunge dati sulla lunghezza
00425       info.len      = (uchar)result;
00426 
00427       // setta priorita' massima
00428       if (info.GetPriority() < priority)
00429       {
00430           info.SetPriority(priority);
00431 #ifdef DEBUG
00432         bytes += result;
00433 #endif
00434       }
00435 
00436       // prima di questa esiste un'istruzione
00437       if (!bFirst)
00438         info.SetIsPrevInstruction();
00439 
00440       //bytes += result;
00441 
00442             // aggiungi istruzione di flusso
00443       // !!! un po' strano, o no ?
00444       AddTempFlow(flow,address,currInstruction,address,priority);
00445 
00446       // salva costanti che possano puntare al codice
00447       // !!!
00448       if (priority != ByteInfo::priCheckOnly)
00449       {
00450               CheckImmediateCodeAddress(currInstruction);
00451         CheckForAddress(address,currInstruction,priority);
00452       }
00453 
00454     // fermati se salto incondizionale o ritorno
00455     if (flow == FLOW_JUMP || flow == FLOW_RET)
00456     {
00457        break;
00458     }
00459 
00460     // va avanti
00461     address += result;
00462     bFirst = false;
00463   }
00464   return scanCodeNoError;
00465 }

void CodeParser::SetCodeRange const range< vma_t > &    r,
ByteInfo::TPriority    priority,
bool    bSetLabel = true
[private]
 

Definition at line 487 of file code.cpp.

References range< T >::begin, ScanCode(), ByteInfo::TPriority, and vma_t.

Referenced by CheckCode(), and CheckCodeRecursively().

00488 {
00489   vma_t begin = r.begin;
00490 #ifdef DEBUG
00491   // TScanCodeResult res =
00492 #endif
00493   ScanCode(begin,priority,bSetLabel);
00494 
00495   // !!! per procedure che non ritornano puo' accadere un errore
00496   //_PRG_ASSERT(res <= scanCodeNoError);
00497   // !!! si processano prima export e poi heuristic,
00498   // ma priorita heuristic > priorita export
00499   //_PRG_ASSERT(begin == (*i).end);
00500 }

void CodeParser::WriteBegin vma_t    address,
int    num_bytes
const [private]
 

Definition at line 213 of file codeprn.cpp.

References EndComment(), ObjectModule::GetDataReader(), CodeInfo::module, ObjectModule::DataReader::ReadByte(), and vma_t.

Referenced by WriteCode().

00214 {
00215   int x=0,c;
00216   EndComment();
00217   printf("%08lX ",(long int)address);
00218   if (::options.showBytes)
00219   {
00220                 ObjectModule::DataReader reader = module->GetDataReader(address);
00221     for (int i=0;i<num_bytes;++i)
00222     {
00223       if ( i%10 == 0 )
00224       {
00225         x = 0;
00226         if (i != 0)
00227           printf("\n         ");
00228       }
00229       c = reader.ReadByte();
00230       printf("%02X",c);
00231       x += 2;
00232     }
00233 
00234     for (;x!=20;x+=2)
00235       printf("  ");
00236   }
00237 
00238   printf("\t");
00239 }

void CodeParser::WriteCode   [private]
 

Definition at line 271 of file codeprn.cpp.

References _DEBUG_, _PRG_ASSERT, CodeInfo::byteInfo, CheckJumpReference(), CheckReference(), InstructionDecoder::Decode(), FOR_EACH_SECTION_CODE_BEGIN, FOR_EACH_SECTION_CODE_END, ObjectModule::GetDataReader(), ByteInfos::GetIstrLen(), ByteInfos::GetLen(), ObjectModule::GetRelocationInfos(), ByteInfo::GetType(), ByteInfos::IsOccupied(), CodeInfo::module, ObjectModule::DataReader::ReadByte(), ObjectModule::DataReader::ReadDword(), ObjectModule::DataReader::ReadWord(), StartBeginComment(), ByteInfo::TPriority, ByteInfo::typeASCIIZ, ByteInfo::typeInteger, ByteInfo::typeLoader, ByteInfo::typePointer, vma_t, WriteBegin(), WriteInstruction(), WritePriority(), and WriteString().

Referenced by Parse().

00272 {
00273         vma_t end;
00274 
00275   // disassembly vero e proprio
00276   FOR_EACH_SECTION_CODE_BEGIN(module,p)
00277 
00278     InstructionDecoder decoder(module->GetRelocationInfos());
00279 
00280     // init as invalid priority
00281     ByteInfo::TPriority priority = ByteInfo::TPriority(-1);
00282 
00283     vma_t pc = (*p).begin;
00284     end      = (*p).end;
00285     for(; pc<end; )
00286     {
00287                         ObjectModule::DataReader reader = module->GetDataReader(pc);
00288           int c;
00289           Instruction currInstruction;
00290 
00291       // testa cambio priorita
00292       if (options.showPriority)
00293       {
00294         ByteInfo::TPriority currPriority = byteInfo[pc].GetPriority();
00295         if (currPriority != priority)
00296         {
00297           WritePriority(currPriority);
00298           priority = currPriority;
00299         }
00300       }
00301 
00302       // test for reference
00303       CheckReference(pc);
00304 
00305       // testa se tipo conosciuto
00306       unsigned len = byteInfo.GetLen(pc);
00307       bool isInstruction = true;
00308 
00309       if (len != 0)
00310       {
00311         isInstruction = false;
00312         const ByteInfo& info = byteInfo[pc];
00313         switch (info.GetType())
00314         {
00315         case ByteInfo::typeInteger:
00316           {
00317             uint32_t i;
00318             switch (len)
00319             {
00320             case 1:
00321               i = reader.ReadByte();
00322               WriteBegin(pc,len);
00323               printf("BYTE %02X\n",i);
00324               break;
00325             case 2:
00326               i = reader.ReadWord();
00327               WriteBegin(pc,len);
00328               printf("WORD %04X\n",i);
00329               break;
00330             case 4:
00331               i = reader.ReadDword();
00332               WriteBegin(pc,len);
00333               printf("DWORD %08X\n",i);
00334               break;
00335 
00336             default:
00337               // !!! scrive come bytes normali
00338               //_PRG_ASSERT(0);
00339               WriteString(pc,len);
00340             }
00341             pc += len;
00342           }
00343           break;
00344         case ByteInfo::typePointer:
00345           {
00346             _PRG_ASSERT(len == (unsigned int)addr_bytes);
00347             vma_t address = reader.ReadDword();
00348             WriteBegin(pc,len);
00349             printf("DWORD %08lX\n",(long int)address);
00350             pc += len;
00351           }
00352           break;
00353         case ByteInfo::typeLoader:
00354           StartBeginComment();
00355           printf("Loader bytes");
00356           WriteString(pc,len);
00357           pc += len;
00358           break;
00359         case ByteInfo::typeASCIIZ:
00360           _DEBUG_(fprintf(stderr,"Debug: (String) reached\n"));
00361           WriteString(pc,len);
00362           pc += len;
00363           break;
00364         default:
00365           isInstruction = true;
00366         }
00367       }
00368 
00369       if (isInstruction)
00370       {
00371         // leggi successiva istruzione
00372         int result = decoder.Decode(currInstruction,reader);
00373 
00374         if ( !result || (byteInfo.GetIstrLen(pc)==0 &&
00375              byteInfo.IsOccupied(pc,result)) )
00376         {
00377                                         reader = module->GetDataReader(pc);
00378           c = reader.ReadByte();
00379           WriteBegin(pc,1);
00380             printf("BYTE\t%02X\n",c);
00381           pc += 1;
00382         }
00383         else
00384         {
00385             CheckJumpReference(pc,currInstruction);
00386           // !!! aggiungere codice per reference a stringhe o altro
00387           WriteBegin(pc,result);
00388                             WriteInstruction(currInstruction);
00389             // va avanti
00390             pc += result;
00391         }
00392       }
00393     }
00394   FOR_EACH_SECTION_CODE_END(module,p)
00395 }

void CodeParser::WriteString vma_t    address,
int    len
const [private]
 

Definition at line 174 of file codeprn.cpp.

References _PRG_ASSERT, EndComment(), ObjectModule::GetDataReader(), CodeInfo::module, ObjectModule::DataReader::ReadByte(), and vma_t.

Referenced by WriteCode().

00175 {
00176   EndComment();
00177 
00178   _PRG_ASSERT(&*module != NULL);
00179   _PRG_ASSERT(len>0);
00180         ObjectModule::DataReader reader = module->GetDataReader(address);
00181   const unsigned nCarInRow = 16;
00182   char buffer[3*nCarInRow+nCarInRow+10];
00183   for(unsigned n=0;;++n)
00184   {
00185     unsigned part = n%nCarInRow;
00186     if (part==0)
00187     {
00188       if (n>=nCarInRow)
00189       {
00190         buffer[nCarInRow*3+nCarInRow+1] = '\0';
00191         printf("%08X %s\n",address+n-nCarInRow,buffer);
00192         if (n>=(unsigned int)len)
00193           return;
00194       }
00195       // inizializza buffer
00196       memset(buffer,' ',sizeof(buffer));
00197     }
00198     if (n<(unsigned int)len)
00199     {
00200       uint8_t car = reader.ReadByte();
00201 
00202       // scrive il carattere in esadecimale e carattere relativo
00203       sprintf(buffer+part*3,"%02X",car);
00204       buffer[part*3+2] = part==(nCarInRow/2-1)?'-':' ';
00205       // !!! settare come opzione carattere ?
00206       buffer[nCarInRow*3+1+part] = isprint(car)?car:'.';
00207     }
00208   }
00209 }


Friends And Related Function Documentation

void ParseCode CSignFile   file,
uint32_t    imageBase,
vma_t    entryPoint,
const RVAFileTranslator   rva,
const Symbols   symbols,
const Symbols   exportedSymbols,
bool    hasRelocation,
const RelocationInfos   relocationInfos
[friend]
 

Definition at line 1217 of file code.cpp.

01218 {
01219   CodeParser* p = new CodeParser;
01220   p->Parse(file,imageBase,entryPoint,rva,symbols,exportedSymbols,hasRelocation,relocationInfos);
01221   delete p;
01222 }


The documentation for this class was generated from the following files:
Generated on Mon Jan 13 22:20:36 2003 for perdr by doxygen1.2.15