00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "global.h"
00026 #ifdef HAVE_HDRSTOP
00027 #pragma hdrstop
00028 #endif
00029
00030 #include "heuristic.h"
00031
00032 using namespace std;
00033
00034 THeuristicMotor::THeuristicMotor(const CodeParser& codeInfo)
00035 {
00036
00037
00038
00039
00040 FOR_EACH_SECTION_CODE_BEGIN(codeInfo.module,p)
00041 vma_t address = (*p).begin;
00042 vma_t end = (*p).end;
00043 for(; address<end; )
00044 {
00045 bool processed = false;
00046
00047 int len = 1,l;
00048 if ( (l=codeInfo.byteInfo.GetIstrLen(address)) != 0)
00049 {
00050 len = l;
00051 processed = true;
00052
00053
00054 if (codeInfo.byteInfo[address].GetType() != ByteInfo::typeInstruction)
00055 {
00056 address += len;
00057 continue;
00058 }
00059
00060
00061 }
00062
00063 Instruction instruction;
00064 int res = GetInstruction(*codeInfo.module,address,instruction);
00065
00066
00067 if (res > addr_bytes)
00068 {
00069 enum FlowTypes flow = instruction.GetFlowType();
00070 switch (flow)
00071 {
00072 case FLOW_CALL:
00073 _PRG_ASSERT(instruction.numArg == 1);
00074
00075
00076
00077 if (res==5 && instruction.Args[0].type == Param::t_literal)
00078 {
00079 if (codeInfo.module->GetSection(instruction.Args[0].literal)->IsCode())
00080 constCallCount[instruction.Args[0].literal].push_back(address+res);
00081 }
00082 if (codeInfo.IsApiReference(instruction.Args[0]))
00083 {
00084 callApi.insert(address+res);
00085 }
00086 case FLOW_JUMP:
00087
00088
00089
00090
00091 break;
00092 }
00093 }
00094
00095
00096 for (int n=0; n < instruction.numArg; ++n)
00097 if (instruction.Args[n].GetType() == Param::t_memory)
00098 {
00099
00100 Param ¶m = instruction.Args[n];
00101 if (param.mem_reg1 == null_reg && param.mem_reg2 == null_reg)
00102 {
00103 if (codeInfo.ContainValidAddress(param))
00104 globalVarCount[param.literal].push_back(address+res);
00105 }
00106 }
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134 address += len;
00135 }
00136 FOR_EACH_SECTION_CODE_END(module,p)
00137 }
00138
00139 bool THeuristicMotor::Process(unsigned minimun,enum ByteInfo::TPriority priority,CodeParser& codeInfo)
00140 {
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152 while(callApi.begin() != callApi.end())
00153 {
00154
00155 vma_t address = *callApi.begin();
00156 callApi.erase(callApi.begin());
00157
00158
00159
00160 codeInfo.CheckCodeRecursively(address,priority,false);
00161 }
00162
00163 unsigned maxConstCount = 0;
00164 FOR_EACH_BEGIN(TConstCallCount,constCallCount,p)
00165 if ( (*p).second.size() > maxConstCount )
00166 maxConstCount = (*p).second.size();
00167 FOR_EACH_END(TConstCallCount,constCallCount,p)
00168
00169
00170 FOR_EACH_BEGIN(TConstCallCount,globalVarCount,p)
00171 if ( (*p).second.size() > maxConstCount )
00172 maxConstCount = (*p).second.size();
00173 FOR_EACH_END(TConstCallCount,globalVarCount,p)
00174
00175
00176
00177 bool bResult = false;;
00178 if (maxConstCount >= minimun)
00179 {
00180 maxConstCount = f77_min(maxConstCount,4u);
00181
00182 bool bFinded;
00183 do
00184 {
00185 bFinded = false;
00186 FOR_EACH_BEGIN(TConstCallCount,constCallCount,p)
00187 if ( (*p).second.size() >= maxConstCount )
00188 {
00189 codeInfo.CheckCodeRecursively((*p).first,priority);
00190 FOR_EACH_BEGIN(TAddress,(*p).second,i)
00191
00192 codeInfo.CheckCodeRecursively(*i,priority,false);
00193 FOR_EACH_END(TAddress,(*p).second,i)
00194 constCallCount.erase(p);
00195 bFinded = true;
00196 bResult = true;
00197 break;
00198 }
00199 FOR_EACH_END(TConstCallCount,(*constCallCount),p)
00200 } while (bFinded);
00201
00202
00203 do
00204 {
00205 bFinded = false;
00206 FOR_EACH_BEGIN(TConstCallCount,globalVarCount,p)
00207 if ( (*p).second.size() >= maxConstCount )
00208 {
00209
00210 FOR_EACH_BEGIN(TAddress,(*p).second,i)
00211
00212 codeInfo.CheckCodeRecursively(*i,priority,false);
00213 FOR_EACH_END(TAddress,(*p).second,i)
00214 globalVarCount.erase(p);
00215 bFinded = true;
00216 bResult = true;
00217 break;
00218 }
00219 FOR_EACH_END(TConstCallCount,globalVarCount,p)
00220 } while (bFinded);
00221 }
00222 return bResult;
00223 }
00224