#include <codeglob.h>
Inheritance diagram for CodeParser:
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 ¶m) 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) |
|
Definition at line 164 of file codeglob.h. Referenced by CheckCode(), CheckCodeRecursively(), and ScanCode().
00164 { 00165 scanCodeAlreadyProcessed, scanCodeNoError, scanCodeOverlapped, 00166 scanCodeInvalidJump, scanCodeInvalid, scanCodeMax = scanCodeInvalid }; |
|
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 } |
|
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 } |
|
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 } |
|
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 ¶m = 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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |