int32_t cli_bcapi_matchicon(struct cli_bc_ctx *ctx , const uint8_t* grp1, int32_t grp1len, const uint8_t* grp2, int32_t grp2len) { int ret; char group1[128], group2[128]; const char **oldvirname; struct cli_exe_info info; if (!ctx->hooks.pedata->ep) { cli_dbgmsg("bytecode: matchicon only works with PE files\n"); return -1; } if ((size_t) grp1len > sizeof(group1)-1 || (size_t) grp2len > sizeof(group2)-1) return -1; oldvirname = ((cli_ctx*)ctx->ctx)->virname; ((cli_ctx*)ctx->ctx)->virname = NULL; memcpy(group1, grp1, grp1len); memcpy(group2, grp2, grp2len); group1[grp1len] = 0; group2[grp2len] = 0; memset(&info, 0, sizeof(info)); if (ctx->bc->kind == BC_PE_UNPACKER || ctx->bc->kind == BC_PE_ALL) { if(le16_to_host(ctx->hooks.pedata->file_hdr.Characteristics) & 0x2000 || !ctx->hooks.pedata->dirs[2].Size) info.res_addr = 0; else info.res_addr = le32_to_host(ctx->hooks.pedata->dirs[2].VirtualAddress); } else info.res_addr = ctx->resaddr; /* from target_info */ info.section = (struct cli_exe_section*)ctx->sections; info.nsections = ctx->hooks.pedata->nsections; info.hdr_size = ctx->hooks.pedata->hdr_size; cli_dbgmsg("bytecode matchicon %s %s\n", group1, group2); ret = matchicon(ctx->ctx, &info, group1[0] ? group1 : NULL, group2[0] ? group2 : NULL); ((cli_ctx*)ctx->ctx)->virname = oldvirname; return ret; }
static int lsig_eval(cli_ctx *ctx, struct cli_matcher *root, struct cli_ac_data *acdata, struct cli_target_info *target_info, const char *hash, uint32_t lsid) { unsigned evalcnt = 0; uint64_t evalids = 0; fmap_t *map = *ctx->fmap; struct cli_ac_lsig *ac_lsig = root->ac_lsigtable[lsid]; char * exp = ac_lsig->u.logic; char* exp_end = exp + strlen(exp); int rc; rc = cli_ac_chkmacro(root, acdata, lsid); if (rc != CL_SUCCESS) return rc; if (cli_ac_chklsig(exp, exp_end, acdata->lsigcnt[lsid], &evalcnt, &evalids, 0) == 1) { if(ac_lsig->tdb.container && ac_lsig->tdb.container[0] != ctx->container_type) return CL_CLEAN; if(ac_lsig->tdb.filesize && (ac_lsig->tdb.filesize[0] > map->len || ac_lsig->tdb.filesize[1] < map->len)) return CL_CLEAN; if(ac_lsig->tdb.ep || ac_lsig->tdb.nos) { if(!target_info || target_info->status != 1) return CL_CLEAN; if(ac_lsig->tdb.ep && (ac_lsig->tdb.ep[0] > target_info->exeinfo.ep || ac_lsig->tdb.ep[1] < target_info->exeinfo.ep)) return CL_CLEAN; if(ac_lsig->tdb.nos && (ac_lsig->tdb.nos[0] > target_info->exeinfo.nsections || ac_lsig->tdb.nos[1] < target_info->exeinfo.nsections)) return CL_CLEAN; } if(hash && ac_lsig->tdb.handlertype) { if(memcmp(ctx->handlertype_hash, hash, 16)) { ctx->recursion++; memcpy(ctx->handlertype_hash, hash, 16); if(cli_magic_scandesc_type(ctx, ac_lsig->tdb.handlertype[0]) == CL_VIRUS) { ctx->recursion--; return CL_VIRUS; } ctx->recursion--; return CL_CLEAN; } } if(ac_lsig->tdb.icongrp1 || ac_lsig->tdb.icongrp2) { if(!target_info || target_info->status != 1) return CL_CLEAN; if(matchicon(ctx, &target_info->exeinfo, ac_lsig->tdb.icongrp1, ac_lsig->tdb.icongrp2) == CL_VIRUS) { if(!ac_lsig->bc_idx) { cli_append_virus(ctx, ac_lsig->virname); return CL_VIRUS; } else if(cli_bytecode_runlsig(ctx, target_info, &ctx->engine->bcs, ac_lsig->bc_idx, acdata->lsigcnt[lsid], acdata->lsigsuboff_first[lsid], map) == CL_VIRUS) { return CL_VIRUS; } } return CL_CLEAN; } if(!ac_lsig->bc_idx) { cli_append_virus(ctx, ac_lsig->virname); return CL_VIRUS; } if(cli_bytecode_runlsig(ctx, target_info, &ctx->engine->bcs, ac_lsig->bc_idx, acdata->lsigcnt[lsid], acdata->lsigsuboff_first[lsid], map) == CL_VIRUS) { return CL_VIRUS; } } return CL_CLEAN; }
int cli_lsig_eval(cli_ctx *ctx, struct cli_matcher *root, struct cli_ac_data *acdata, struct cli_target_info *target_info, const char *hash) { unsigned int i, evalcnt; uint64_t evalids; fmap_t *map = *ctx->fmap; unsigned int viruses_found = 0; for(i = 0; i < root->ac_lsigs; i++) { evalcnt = 0; evalids = 0; cli_ac_chkmacro(root, acdata, i); if(cli_ac_chklsig(root->ac_lsigtable[i]->logic, root->ac_lsigtable[i]->logic + strlen(root->ac_lsigtable[i]->logic), acdata->lsigcnt[i], &evalcnt, &evalids, 0) == 1) { if(root->ac_lsigtable[i]->tdb.container && root->ac_lsigtable[i]->tdb.container[0] != ctx->container_type) continue; if(root->ac_lsigtable[i]->tdb.filesize && (root->ac_lsigtable[i]->tdb.filesize[0] > map->len || root->ac_lsigtable[i]->tdb.filesize[1] < map->len)) continue; if(root->ac_lsigtable[i]->tdb.ep || root->ac_lsigtable[i]->tdb.nos) { if(!target_info || target_info->status != 1) continue; if(root->ac_lsigtable[i]->tdb.ep && (root->ac_lsigtable[i]->tdb.ep[0] > target_info->exeinfo.ep || root->ac_lsigtable[i]->tdb.ep[1] < target_info->exeinfo.ep)) continue; if(root->ac_lsigtable[i]->tdb.nos && (root->ac_lsigtable[i]->tdb.nos[0] > target_info->exeinfo.nsections || root->ac_lsigtable[i]->tdb.nos[1] < target_info->exeinfo.nsections)) continue; } if(hash && root->ac_lsigtable[i]->tdb.handlertype) { if(memcmp(ctx->handlertype_hash, hash, 16)) { ctx->recursion++; memcpy(ctx->handlertype_hash, hash, 16); if(cli_magic_scandesc_type(ctx, root->ac_lsigtable[i]->tdb.handlertype[0]) == CL_VIRUS) { ctx->recursion--; if (SCAN_ALL) { viruses_found++; continue; } return CL_VIRUS; } ctx->recursion--; continue; } } if(root->ac_lsigtable[i]->tdb.icongrp1 || root->ac_lsigtable[i]->tdb.icongrp2) { if(!target_info || target_info->status != 1) continue; if(matchicon(ctx, &target_info->exeinfo, root->ac_lsigtable[i]->tdb.icongrp1, root->ac_lsigtable[i]->tdb.icongrp2) == CL_VIRUS) { if(!root->ac_lsigtable[i]->bc_idx) { cli_append_virus(ctx, root->ac_lsigtable[i]->virname); if (SCAN_ALL) { viruses_found++; continue; } return CL_VIRUS; } else if(cli_bytecode_runlsig(ctx, target_info, &ctx->engine->bcs, root->ac_lsigtable[i]->bc_idx, acdata->lsigcnt[i], acdata->lsigsuboff_first[i], map) == CL_VIRUS) { if (SCAN_ALL) { viruses_found++; continue; } return CL_VIRUS; } } continue; } if(!root->ac_lsigtable[i]->bc_idx) { cli_append_virus(ctx, root->ac_lsigtable[i]->virname); if (SCAN_ALL) { viruses_found++; continue; } return CL_VIRUS; } if(cli_bytecode_runlsig(ctx, target_info, &ctx->engine->bcs, root->ac_lsigtable[i]->bc_idx, acdata->lsigcnt[i], acdata->lsigsuboff_first[i], map) == CL_VIRUS) { if (SCAN_ALL) { viruses_found++; continue; } return CL_VIRUS; } } } if (SCAN_ALL && viruses_found) return CL_VIRUS; return CL_CLEAN; }