#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 }
|
1.2.15