If sigs A*B, A{n-}B, etc. generate multiple matches, the reported offset
will be always for the first occurrence of A.
... | ... |
@@ -1121,7 +1121,7 @@ int cli_ac_scanbuff(const unsigned char *buffer, uint32_t length, const char **v |
1121 | 1121 |
struct cli_ac_patt *patt, *pt; |
1122 | 1122 |
uint32_t i, bp, realoff, matchend; |
1123 | 1123 |
uint16_t j; |
1124 |
- int32_t **offmatrix; |
|
1124 |
+ int32_t **offmatrix, swap; |
|
1125 | 1125 |
uint8_t found; |
1126 | 1126 |
int type = CL_CLEAN; |
1127 | 1127 |
struct cli_ac_result *newres; |
... | ... |
@@ -1231,7 +1231,7 @@ int cli_ac_scanbuff(const unsigned char *buffer, uint32_t length, const char **v |
1231 | 1231 |
if(pt->partno != 1) { |
1232 | 1232 |
found = 0; |
1233 | 1233 |
for(j = 1; j <= CLI_DEFAULT_AC_TRACKLEN && offmatrix[pt->partno - 2][j] != -1; j++) { |
1234 |
- found = 1; |
|
1234 |
+ found = j; |
|
1235 | 1235 |
if(pt->maxdist) |
1236 | 1236 |
if(realoff - offmatrix[pt->partno - 2][j] > pt->maxdist) |
1237 | 1237 |
found = 0; |
... | ... |
@@ -1245,6 +1245,16 @@ int cli_ac_scanbuff(const unsigned char *buffer, uint32_t length, const char **v |
1245 | 1245 |
} |
1246 | 1246 |
} |
1247 | 1247 |
|
1248 |
+ if(pt->partno == 2 && found > 1) { |
|
1249 |
+ swap = offmatrix[pt->parts - 1][1]; |
|
1250 |
+ offmatrix[pt->parts - 1][1] = offmatrix[pt->parts - 1][found]; |
|
1251 |
+ offmatrix[pt->parts - 1][found] = swap; |
|
1252 |
+ |
|
1253 |
+ swap = offmatrix[0][1]; |
|
1254 |
+ offmatrix[0][1] = offmatrix[0][found]; |
|
1255 |
+ offmatrix[0][found] = swap; |
|
1256 |
+ } |
|
1257 |
+ |
|
1248 | 1258 |
if(pt->partno == 1 || (found && (pt->partno != pt->parts))) { |
1249 | 1259 |
offmatrix[pt->partno - 1][0] %= CLI_DEFAULT_AC_TRACKLEN; |
1250 | 1260 |
offmatrix[pt->partno - 1][0]++; |
... | ... |
@@ -1262,7 +1272,9 @@ int cli_ac_scanbuff(const unsigned char *buffer, uint32_t length, const char **v |
1262 | 1262 |
cli_dbgmsg("Matched signature for file type %s\n", pt->virname); |
1263 | 1263 |
type = pt->type; |
1264 | 1264 |
if(ftoffset && (!*ftoffset || (*ftoffset)->cnt < MAX_EMBEDDED_OBJ || type == CL_TYPE_ZIPSFX) && (type >= CL_TYPE_SFX || ((ftype == CL_TYPE_MSEXE || ftype == CL_TYPE_ZIP || ftype == CL_TYPE_MSOLE2) && type == CL_TYPE_MSEXE))) { |
1265 |
- /* FIXME: we don't know which offset of the first part is the correct one */ |
|
1265 |
+ /* FIXME: the first offset in the array is most likely the correct one but |
|
1266 |
+ * it may happen it is not |
|
1267 |
+ */ |
|
1266 | 1268 |
for(j = 1; j <= CLI_DEFAULT_AC_TRACKLEN && offmatrix[0][j] != -1; j++) |
1267 | 1269 |
if(ac_addtype(ftoffset, type, offmatrix[pt->parts - 1][j], ctx)) |
1268 | 1270 |
return CL_EMEM; |
... | ... |
@@ -1287,7 +1299,7 @@ int cli_ac_scanbuff(const unsigned char *buffer, uint32_t length, const char **v |
1287 | 1287 |
newres->virname = pt->virname; |
1288 | 1288 |
newres->customdata = pt->customdata; |
1289 | 1289 |
newres->next = *res; |
1290 |
- newres->offset = realoff; |
|
1290 |
+ newres->offset = offmatrix[pt->parts - 1][1]; |
|
1291 | 1291 |
*res = newres; |
1292 | 1292 |
|
1293 | 1293 |
pt = pt->next_same; |