mirror of
https://github.com/Cisco-Talos/clamav.git
synced 2025-10-19 10:23:17 +00:00
Record names of extracted files
A way is needed to record scanned file names for two purposes: 1. File names (and extensions) must be stored in the json metadata properties recorded when using the --gen-json clamscan option. Future work may use this to compare file extensions with detected file types. 2. File names are useful when interpretting tmp directory output when using the --leave-temps option. This commit enables file name retention for later use by storing file names in the fmap header structure, if a file name exists. To store the names in fmaps, an optional name argument has been added to any internal scan API's that create fmaps and every call to these APIs has been modified to pass a file name or NULL if a file name is not required. The zip and gpt parsers required some modification to record file names. The NSIS and XAR parsers fail to collect file names at all and will require future work to support file name extraction. Also: - Added recursive extraction to the tmp directory when the --leave-temps option is enabled. When not enabled, the tmp directory structure remains flat so as to prevent the likelihood of exceeding MAX_PATH. The current tmp directory is stored in the scan context. - Made the cli_scanfile() internal API non-static and added it to scanners.h so it would be accessible outside of scanners.c in order to remove code duplication within libmspack.c. - Added function comments to scanners.h and matcher.h - Converted a TDB-type macros and LSIG-type macros to enums for improved type safey. - Converted more return status variables from `int` to `cl_error_t` for improved type safety, and corrected ooxml file typing functions so they use `cli_file_t` exclusively rather than mixing types with `cl_error_t`. - Restructured the magic_scandesc() function to use goto's for error handling and removed the early_ret_from_magicscan() macro and magic_scandesc_cleanup() function. This makes the code easier to read and made it easier to add the recursive tmp directory cleanup to magic_scandesc(). - Corrected zip, egg, rar filename extraction issues. - Removed use of extra sub-directory layer for zip, egg, and rar file extraction. For Zip, this also involved changing the extracted filenames to be randomly generated rather than using the "zip.###" file name scheme.
This commit is contained in:
parent
9f2de39e04
commit
005cbf5a37
67 changed files with 1054 additions and 722 deletions
|
@ -431,7 +431,7 @@ int main(int argc, char *argv[])
|
|||
optfree(opts);
|
||||
exit(5);
|
||||
}
|
||||
map = fmap(fd, 0, 0);
|
||||
map = fmap(fd, 0, 0, opt->strarg);
|
||||
if (!map) {
|
||||
fprintf(stderr, "Unable to map input file %s\n", opt->strarg);
|
||||
exit(5);
|
||||
|
|
|
@ -123,6 +123,7 @@ int cli_7unz(cli_ctx *ctx, size_t offset)
|
|||
size_t outSizeProcessed = 0;
|
||||
const CSzFileItem *f = db.db.Files + i;
|
||||
char *name;
|
||||
char *tmp_name;
|
||||
size_t j;
|
||||
int newnamelen, fd;
|
||||
|
||||
|
@ -184,19 +185,19 @@ int cli_7unz(cli_ctx *ctx, size_t offset)
|
|||
else if ((outBuffer == NULL) || (outSizeProcessed == 0)) {
|
||||
cli_dbgmsg("cli_unz: extracted empty file\n");
|
||||
} else {
|
||||
if ((found = cli_gentempfd(ctx->engine->tmpdir, &name, &fd)))
|
||||
if ((found = cli_gentempfd(ctx->sub_tmpdir, &tmp_name, &fd)))
|
||||
break;
|
||||
|
||||
cli_dbgmsg("cli_7unz: Saving to %s\n", name);
|
||||
cli_dbgmsg("cli_7unz: Saving to %s\n", tmp_name);
|
||||
if (cli_writen(fd, outBuffer + offset, outSizeProcessed) != outSizeProcessed)
|
||||
found = CL_EWRITE;
|
||||
else if ((found = cli_magic_scandesc(fd, name, ctx)) == CL_VIRUS)
|
||||
else if ((found = cli_magic_scandesc(fd, tmp_name, ctx, name)) == CL_VIRUS)
|
||||
viruses_found++;
|
||||
close(fd);
|
||||
if (!ctx->engine->keeptmp && cli_unlink(name))
|
||||
if (!ctx->engine->keeptmp && cli_unlink(tmp_name))
|
||||
found = CL_EUNLINK;
|
||||
|
||||
free(name);
|
||||
free(tmp_name);
|
||||
if (found != CL_CLEAN)
|
||||
if (!(SCAN_ALLMATCHES && found == CL_VIRUS))
|
||||
break;
|
||||
|
|
|
@ -223,7 +223,7 @@ int cli_scanapm(cli_ctx *ctx)
|
|||
apentry.pBlockStart, apentry.pBlockCount, (long unsigned)partoff, (long unsigned)partsize);
|
||||
|
||||
/* send the partition to cli_map_scan */
|
||||
ret = cli_map_scan(*ctx->fmap, partoff, partsize, ctx, CL_TYPE_PART_ANY);
|
||||
ret = cli_map_scan(*ctx->fmap, partoff, partsize, ctx, CL_TYPE_PART_ANY, (const char *)apentry.name);
|
||||
if (ret != CL_CLEAN) {
|
||||
if (SCAN_ALLMATCHES && (ret == CL_VIRUS))
|
||||
detection = CL_VIRUS;
|
||||
|
|
|
@ -808,12 +808,12 @@ static int ea05(cli_ctx *ctx, const uint8_t *base, char *tmpd)
|
|||
|
||||
free(UNP.inputbuf);
|
||||
/* Sometimes the autoit exe is in turn packed/lamed with a runtime compressor and similar shit.
|
||||
* However, since the autoit script doesn't compress a second time very well, chances are we're
|
||||
* still able to match the headers and unpack something (see sample 0811129)
|
||||
* I'd rather unpack something (although possibly highly corrupted) than nothing at all
|
||||
*
|
||||
* - Fortuna audaces iuvat -
|
||||
*/
|
||||
* However, since the autoit script doesn't compress a second time very well, chances are we're
|
||||
* still able to match the headers and unpack something (see sample 0811129)
|
||||
* I'd rather unpack something (although possibly highly corrupted) than nothing at all
|
||||
*
|
||||
* - Fortuna audaces iuvat -
|
||||
*/
|
||||
if (UNP.error) {
|
||||
cli_dbgmsg("autoit: decompression error after %u bytes - partial file may exist\n", UNP.cur_output);
|
||||
UNP.usize = UNP.cur_output;
|
||||
|
@ -858,7 +858,7 @@ static int ea05(cli_ctx *ctx, const uint8_t *base, char *tmpd)
|
|||
close(i);
|
||||
return CL_ESEEK;
|
||||
}
|
||||
if (cli_magic_scandesc(i, tempfile, ctx) == CL_VIRUS) {
|
||||
if (cli_magic_scandesc(i, tempfile, ctx, NULL) == CL_VIRUS) {
|
||||
if (!SCAN_ALLMATCHES) {
|
||||
close(i);
|
||||
if (!ctx->engine->keeptmp)
|
||||
|
@ -1467,7 +1467,7 @@ static int ea06(cli_ctx *ctx, const uint8_t *base, char *tmpd)
|
|||
close(i);
|
||||
return CL_ESEEK;
|
||||
}
|
||||
if (cli_magic_scandesc(i, tempfile, ctx) == CL_VIRUS) {
|
||||
if (cli_magic_scandesc(i, tempfile, ctx, NULL) == CL_VIRUS) {
|
||||
if (!SCAN_ALLMATCHES) {
|
||||
close(i);
|
||||
if (!ctx->engine->keeptmp)
|
||||
|
@ -1499,7 +1499,7 @@ int cli_scanautoit(cli_ctx *ctx, off_t offset)
|
|||
if (!(version = fmap_need_off_once(map, offset, sizeof(*version))))
|
||||
return CL_EREAD;
|
||||
|
||||
if (!(tmpd = cli_gentemp(ctx->engine->tmpdir)))
|
||||
if (!(tmpd = cli_gentemp(ctx->sub_tmpdir)))
|
||||
return CL_ETMPDIR;
|
||||
if (mkdir(tmpd, 0700)) {
|
||||
cli_dbgmsg("autoit: Can't create temporary directory %s\n", tmpd);
|
||||
|
|
|
@ -68,10 +68,10 @@ int cli_binhex(cli_ctx *ctx)
|
|||
cli_dbgmsg("in cli_binhex\n");
|
||||
if (!map->len) return CL_CLEAN;
|
||||
|
||||
if ((ret = cli_gentempfd(ctx->engine->tmpdir, &dname, &datafd)) != CL_SUCCESS)
|
||||
if ((ret = cli_gentempfd(ctx->sub_tmpdir, &dname, &datafd)) != CL_SUCCESS)
|
||||
return ret;
|
||||
|
||||
if ((ret = cli_gentempfd(ctx->engine->tmpdir, &rname, &resfd)) != CL_SUCCESS) {
|
||||
if ((ret = cli_gentempfd(ctx->sub_tmpdir, &rname, &resfd)) != CL_SUCCESS) {
|
||||
close(datafd);
|
||||
if (cli_unlink(dname)) ret = CL_EUNLINK;
|
||||
free(dname);
|
||||
|
@ -122,7 +122,7 @@ int cli_binhex(cli_ctx *ctx)
|
|||
ret = CL_ESEEK;
|
||||
break;
|
||||
}
|
||||
ret = cli_magic_scandesc(datafd, dname, ctx);
|
||||
ret = cli_magic_scandesc(datafd, dname, ctx, NULL);
|
||||
if (ret == CL_VIRUS) break;
|
||||
}
|
||||
if (dec_done)
|
||||
|
@ -168,7 +168,7 @@ int cli_binhex(cli_ctx *ctx)
|
|||
ret = CL_ESEEK;
|
||||
break;
|
||||
}
|
||||
ret = cli_magic_scandesc(resfd, rname, ctx);
|
||||
ret = cli_magic_scandesc(resfd, rname, ctx, NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -180,7 +180,7 @@ int cli_binhex(cli_ctx *ctx)
|
|||
ret = CL_ESEEK;
|
||||
break;
|
||||
}
|
||||
ret = cli_magic_scandesc(datafd, dname, ctx);
|
||||
ret = cli_magic_scandesc(datafd, dname, ctx, NULL);
|
||||
} else if (write_phase == IN_RES) {
|
||||
cli_dbgmsg("cli_binhex: scanning partially extracted resource fork\n");
|
||||
if (lseek(resfd, 0, SEEK_SET) == -1) {
|
||||
|
@ -188,7 +188,7 @@ int cli_binhex(cli_ctx *ctx)
|
|||
ret = CL_ESEEK;
|
||||
break;
|
||||
}
|
||||
ret = cli_magic_scandesc(resfd, rname, ctx);
|
||||
ret = cli_magic_scandesc(resfd, rname, ctx, NULL);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -505,7 +505,7 @@ void fileblobPartialSet(fileblob *fb, const char *fullname, const char *arg)
|
|||
close(fb->fd);
|
||||
return;
|
||||
}
|
||||
blobSetFilename(&fb->b, fb->ctx ? fb->ctx->engine->tmpdir : NULL, fullname);
|
||||
blobSetFilename(&fb->b, fb->ctx ? fb->ctx->sub_tmpdir : NULL, fullname);
|
||||
if (fb->b.data)
|
||||
if (fileblobAddData(fb, fb->b.data, fb->b.len) == 0) {
|
||||
free(fb->b.data);
|
||||
|
@ -649,7 +649,7 @@ int fileblobScan(const fileblob *fb)
|
|||
virus_found = 1;
|
||||
}
|
||||
|
||||
rc = cli_magic_scandesc(fb->fd, fb->fullname, fb->ctx);
|
||||
rc = cli_magic_scandesc(fb->fd, fb->fullname, fb->ctx, fb->b.name);
|
||||
if (rc == CL_VIRUS || virus_found != 0) {
|
||||
cli_dbgmsg("%s is infected\n", fb->fullname);
|
||||
return CL_VIRUS;
|
||||
|
|
|
@ -164,12 +164,12 @@ static int cli_bytecode_context_reset(struct cli_bc_ctx *ctx)
|
|||
snprintf(fullname, 1024, "%s" PATHSEP "javascript", ctx->jsnormdir);
|
||||
fd = open(fullname, O_RDONLY | O_BINARY);
|
||||
if (fd >= 0) {
|
||||
ret = cli_scandesc(fd, cctx, CL_TYPE_HTML, 0, NULL, AC_SCAN_VIR, NULL);
|
||||
ret = cli_scandesc(fd, cctx, CL_TYPE_HTML, 0, NULL, AC_SCAN_VIR, NULL, NULL);
|
||||
if (ret == CL_CLEAN) {
|
||||
if (lseek(fd, 0, SEEK_SET) == -1)
|
||||
cli_dbgmsg("cli_bytecode: call to lseek() has failed\n");
|
||||
else
|
||||
ret = cli_scandesc(fd, cctx, CL_TYPE_TEXT_ASCII, 0, NULL, AC_SCAN_VIR, NULL);
|
||||
ret = cli_scandesc(fd, cctx, CL_TYPE_TEXT_ASCII, 0, NULL, AC_SCAN_VIR, NULL, NULL);
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
|
@ -2906,7 +2906,7 @@ int cli_bytecode_runhook(cli_ctx *cctx, const struct cl_engine *engine, struct c
|
|||
lseek(fd, 0, SEEK_SET);
|
||||
cli_dbgmsg("***** Scanning unpacked file ******\n");
|
||||
cctx->recursion++;
|
||||
ret = cli_magic_scandesc(fd, tempfile, cctx);
|
||||
ret = cli_magic_scandesc(fd, tempfile, cctx, NULL);
|
||||
cctx->recursion--;
|
||||
if (!cctx->engine->keeptmp)
|
||||
if (ftruncate(fd, 0) == -1)
|
||||
|
|
|
@ -552,7 +552,7 @@ int32_t cli_bcapi_extract_new(struct cli_bc_ctx *ctx, int32_t id)
|
|||
size_t csize = cli_get_container_size(cctx, -2);
|
||||
cli_set_container(cctx, ctx->containertype, csize);
|
||||
}
|
||||
res = cli_magic_scandesc(ctx->outfd, ctx->tempfile, cctx);
|
||||
res = cli_magic_scandesc(ctx->outfd, ctx->tempfile, cctx, NULL);
|
||||
cctx->recursion--;
|
||||
if (res == CL_VIRUS) {
|
||||
ctx->virname = cli_get_last_virus(cctx);
|
||||
|
@ -1728,7 +1728,7 @@ int32_t cli_bcapi_input_switch(struct cli_bc_ctx *ctx, int32_t extracted_file)
|
|||
}
|
||||
|
||||
/* Create fmap for the extracted file */
|
||||
map = fmap(ctx->outfd, 0, 0);
|
||||
map = fmap(ctx->outfd, 0, 0, NULL);
|
||||
if (!map) {
|
||||
cli_warnmsg("can't mmap() extracted temporary file %s\n", ctx->tempfile);
|
||||
return -1;
|
||||
|
|
|
@ -340,6 +340,8 @@ typedef struct cli_stats_sections {
|
|||
/**
|
||||
* @brief Set a numerical engine option.
|
||||
*
|
||||
* Caution: changing options for an engine that is in-use is not thread-safe!
|
||||
*
|
||||
* @param engine An initialized scan engine.
|
||||
* @param cl_engine_field A CL_ENGINE option.
|
||||
* @param num The new engine option value.
|
||||
|
@ -362,6 +364,11 @@ extern long long cl_engine_get_num(const struct cl_engine *engine, enum cl_engin
|
|||
/**
|
||||
* @brief Set a string engine option.
|
||||
*
|
||||
* If the string option has already been set, the existing string will be free'd
|
||||
* and the new string will replace it.
|
||||
*
|
||||
* Caution: changing options for an engine that is in-use is not thread-safe!
|
||||
*
|
||||
* @param engine An initialized scan engine.
|
||||
* @param cl_engine_field A CL_ENGINE option.
|
||||
* @param str The new engine option value.
|
||||
|
@ -395,6 +402,8 @@ extern struct cl_settings *cl_engine_settings_copy(const struct cl_engine *engin
|
|||
/**
|
||||
* @brief Apply settings from a settings structure to a scan engine.
|
||||
*
|
||||
* Caution: changing options for an engine that is in-use is not thread-safe!
|
||||
*
|
||||
* @param engine A scan engine.
|
||||
* @param settings The settings.
|
||||
* @return cl_error_t CL_SUCCESS if successful.
|
||||
|
@ -471,6 +480,8 @@ typedef cl_error_t (*clcb_pre_cache)(int fd, const char *type, void *context);
|
|||
/**
|
||||
* @brief Set a custom pre-cache callback function.
|
||||
*
|
||||
* Caution: changing options for an engine that is in-use is not thread-safe!
|
||||
*
|
||||
* @param engine The initialized scanning engine.
|
||||
* @param callback The callback function pointer.
|
||||
*/
|
||||
|
@ -495,6 +506,8 @@ typedef cl_error_t (*clcb_pre_scan)(int fd, const char *type, void *context);
|
|||
/**
|
||||
* @brief Set a custom pre-scan callback function.
|
||||
*
|
||||
* Caution: changing options for an engine that is in-use is not thread-safe!
|
||||
*
|
||||
* @param engine The initialized scanning engine.
|
||||
* @param callback The callback function pointer.
|
||||
*/
|
||||
|
@ -520,6 +533,8 @@ typedef cl_error_t (*clcb_post_scan)(int fd, int result, const char *virname, vo
|
|||
/**
|
||||
* @brief Set a custom post-scan callback function.
|
||||
*
|
||||
* Caution: changing options for an engine that is in-use is not thread-safe!
|
||||
*
|
||||
* @param engine The initialized scanning engine.
|
||||
* @param callback The callback function pointer.
|
||||
*/
|
||||
|
@ -543,6 +558,8 @@ typedef void (*clcb_virus_found)(int fd, const char *virname, void *context);
|
|||
/**
|
||||
* @brief Set a custom virus-found callback function.
|
||||
*
|
||||
* Caution: changing options for an engine that is in-use is not thread-safe!
|
||||
*
|
||||
* @param engine The initialized scanning engine.
|
||||
* @param callback The callback function pointer.
|
||||
*/
|
||||
|
@ -568,6 +585,8 @@ typedef int (*clcb_sigload)(const char *type, const char *name, unsigned int cus
|
|||
/**
|
||||
* @brief Set a custom signature-load callback function.
|
||||
*
|
||||
* Caution: changing options for an engine that is in-use is not thread-safe!
|
||||
*
|
||||
* @param engine The initialized scanning engine.
|
||||
* @param callback The callback function pointer.
|
||||
* @param context Opaque application provided data.
|
||||
|
@ -628,6 +647,8 @@ typedef void (*clcb_hash)(int fd, unsigned long long size, const unsigned char *
|
|||
/**
|
||||
* @brief Set a custom hash stats callback function.
|
||||
*
|
||||
* Caution: changing options for an engine that is in-use is not thread-safe!
|
||||
*
|
||||
* @param engine The initialized scanning engine.
|
||||
* @param callback The callback function pointer.
|
||||
*/
|
||||
|
@ -657,6 +678,8 @@ typedef cl_error_t (*clcb_meta)(const char *container_type, unsigned long fsize_
|
|||
/**
|
||||
* @brief Set a custom archive metadata matching callback function.
|
||||
*
|
||||
* Caution: changing options for an engine that is in-use is not thread-safe!
|
||||
*
|
||||
* @param engine The initialized scanning engine.
|
||||
* @param callback The callback function pointer.
|
||||
*/
|
||||
|
@ -676,6 +699,8 @@ typedef int (*clcb_file_props)(const char *j_propstr, int rc, void *cbdata);
|
|||
/**
|
||||
* @brief Set a custom file properties callback function.
|
||||
*
|
||||
* Caution: changing options for an engine that is in-use is not thread-safe!
|
||||
*
|
||||
* @param engine The initialized scanning engine.
|
||||
* @param callback The callback function pointer.
|
||||
*/
|
||||
|
@ -697,6 +722,8 @@ extern void cl_engine_set_clcb_file_props(struct cl_engine *engine, clcb_file_pr
|
|||
* The data must persist at least until `clcb_stats_submit()` is called, or
|
||||
* `clcb_stats_flush()` is called (optional).
|
||||
*
|
||||
* Caution: changing options for an engine that is in-use is not thread-safe!
|
||||
*
|
||||
* @param engine The scanning engine.
|
||||
* @param cbdata The statistics data. Probably a pointer to a malloc'd struct.
|
||||
*/
|
||||
|
@ -715,6 +742,8 @@ typedef void (*clcb_stats_add_sample)(const char *virname, const unsigned char *
|
|||
/**
|
||||
* @brief Set a custom callback function to add sample metadata to a statistics report.
|
||||
*
|
||||
* Caution: changing options for an engine that is in-use is not thread-safe!
|
||||
*
|
||||
* @param engine The initialized scanning engine.
|
||||
* @param callback The callback function pointer.
|
||||
*/
|
||||
|
@ -732,6 +761,8 @@ typedef void (*clcb_stats_remove_sample)(const char *virname, const unsigned cha
|
|||
/**
|
||||
* @brief Set a custom callback function to remove sample metadata from a statistics report.
|
||||
*
|
||||
* Caution: changing options for an engine that is in-use is not thread-safe!
|
||||
*
|
||||
* @param engine The initialized scanning engine.
|
||||
* @param callback The callback function pointer.
|
||||
*/
|
||||
|
@ -766,6 +797,8 @@ typedef void (*clcb_stats_submit)(struct cl_engine *engine, void *cbdata);
|
|||
/**
|
||||
* @brief Set a custom callback function to submit the statistics report.
|
||||
*
|
||||
* Caution: changing options for an engine that is in-use is not thread-safe!
|
||||
*
|
||||
* @param engine The initialized scanning engine.
|
||||
* @param callback The callback function pointer.
|
||||
*/
|
||||
|
@ -781,6 +814,8 @@ typedef void (*clcb_stats_flush)(struct cl_engine *engine, void *cbdata);
|
|||
/**
|
||||
* @brief Set a custom callback function to flush/free the statistics report data.
|
||||
*
|
||||
* Caution: changing options for an engine that is in-use is not thread-safe!
|
||||
*
|
||||
* @param engine The initialized scanning engine.
|
||||
* @param callback The callback function pointer.
|
||||
*/
|
||||
|
@ -795,6 +830,8 @@ typedef size_t (*clcb_stats_get_num)(void *cbdata);
|
|||
/**
|
||||
* @brief Set a custom callback function to get the number of samples listed in the statistics report.
|
||||
*
|
||||
* Caution: changing options for an engine that is in-use is not thread-safe!
|
||||
*
|
||||
* @param engine The initialized scanning engine.
|
||||
* @param callback The callback function pointer.
|
||||
*/
|
||||
|
@ -809,6 +846,8 @@ typedef size_t (*clcb_stats_get_size)(void *cbdata);
|
|||
/**
|
||||
* @brief Set a custom callback function to get the size of memory used to store the statistics report.
|
||||
*
|
||||
* Caution: changing options for an engine that is in-use is not thread-safe!
|
||||
*
|
||||
* @param engine The initialized scanning engine.
|
||||
* @param callback The callback function pointer.
|
||||
*/
|
||||
|
@ -823,6 +862,8 @@ typedef char *(*clcb_stats_get_hostid)(void *cbdata);
|
|||
/**
|
||||
* @brief Set a custom callback function to get the machine's unique host ID.
|
||||
*
|
||||
* Caution: changing options for an engine that is in-use is not thread-safe!
|
||||
*
|
||||
* @param engine The initialized scanning engine.
|
||||
* @param callback The callback function pointer.
|
||||
*/
|
||||
|
@ -850,7 +891,7 @@ extern void cl_engine_stats_enable(struct cl_engine *engine);
|
|||
* @param scanoptions Scanning options.
|
||||
* @return cl_error_t CL_CLEAN, CL_VIRUS, or an error code if an error occured during the scan.
|
||||
*/
|
||||
extern int cl_scandesc(int desc, const char *filename, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, struct cl_scan_options *scanoptions);
|
||||
extern cl_error_t cl_scandesc(int desc, const char *filename, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, struct cl_scan_options *scanoptions);
|
||||
|
||||
/**
|
||||
* @brief Scan a file, given a file descriptor.
|
||||
|
@ -866,7 +907,7 @@ extern int cl_scandesc(int desc, const char *filename, const char **virname, uns
|
|||
* @param[in/out] context An opaque context structure allowing the caller to record details about the sample being scanned.
|
||||
* @return cl_error_t CL_CLEAN, CL_VIRUS, or an error code if an error occured during the scan.
|
||||
*/
|
||||
extern int cl_scandesc_callback(int desc, const char *filename, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, struct cl_scan_options *scanoptions, void *context);
|
||||
extern cl_error_t cl_scandesc_callback(int desc, const char *filename, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, struct cl_scan_options *scanoptions, void *context);
|
||||
|
||||
/**
|
||||
* @brief Scan a file, given a filename.
|
||||
|
@ -878,7 +919,7 @@ extern int cl_scandesc_callback(int desc, const char *filename, const char **vir
|
|||
* @param scanoptions Scanning options.
|
||||
* @return cl_error_t CL_CLEAN, CL_VIRUS, or an error code if an error occured during the scan.
|
||||
*/
|
||||
extern int cl_scanfile(const char *filename, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, struct cl_scan_options *scanoptions);
|
||||
extern cl_error_t cl_scanfile(const char *filename, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, struct cl_scan_options *scanoptions);
|
||||
|
||||
/**
|
||||
* @brief Scan a file, given a filename.
|
||||
|
@ -893,7 +934,7 @@ extern int cl_scanfile(const char *filename, const char **virname, unsigned long
|
|||
* @param[in/out] context An opaque context structure allowing the caller to record details about the sample being scanned.
|
||||
* @return cl_error_t CL_CLEAN, CL_VIRUS, or an error code if an error occured during the scan.
|
||||
*/
|
||||
extern int cl_scanfile_callback(const char *filename, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, struct cl_scan_options *scanoptions, void *context);
|
||||
extern cl_error_t cl_scanfile_callback(const char *filename, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, struct cl_scan_options *scanoptions, void *context);
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Database handling.
|
||||
|
@ -1122,7 +1163,7 @@ extern void cl_fmap_close(cl_fmap_t *);
|
|||
* signature matched. Another CL_E* error code if an
|
||||
* error occured.
|
||||
*/
|
||||
extern int cl_scanmap_callback(cl_fmap_t *map, const char *filename, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, struct cl_scan_options *scanoptions, void *context);
|
||||
extern cl_error_t cl_scanmap_callback(cl_fmap_t *map, const char *filename, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, struct cl_scan_options *scanoptions, void *context);
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Crypto/hashing functions
|
||||
|
|
|
@ -163,7 +163,7 @@ int cli_scancpio_old(cli_ctx *ctx)
|
|||
if (ret == CL_EMAXFILES) {
|
||||
goto leave;
|
||||
} else if (ret == CL_SUCCESS) {
|
||||
ret = cli_map_scan(*ctx->fmap, pos, filesize, ctx, CL_TYPE_ANY);
|
||||
ret = cli_map_scan(*ctx->fmap, pos, filesize, ctx, CL_TYPE_ANY, name);
|
||||
if (ret == CL_VIRUS) {
|
||||
if (!SCAN_ALLMATCHES)
|
||||
return ret;
|
||||
|
@ -252,7 +252,7 @@ int cli_scancpio_odc(cli_ctx *ctx)
|
|||
if (ret == CL_EMAXFILES) {
|
||||
goto leave;
|
||||
} else if (ret == CL_SUCCESS) {
|
||||
ret = cli_map_scan(*ctx->fmap, pos, filesize, ctx, CL_TYPE_ANY);
|
||||
ret = cli_map_scan(*ctx->fmap, pos, filesize, ctx, CL_TYPE_ANY, name);
|
||||
if (ret == CL_VIRUS) {
|
||||
if (!SCAN_ALLMATCHES)
|
||||
return ret;
|
||||
|
@ -345,7 +345,7 @@ int cli_scancpio_newc(cli_ctx *ctx, int crc)
|
|||
if (ret == CL_EMAXFILES) {
|
||||
goto leave;
|
||||
} else if (ret == CL_SUCCESS) {
|
||||
ret = cli_map_scan(*ctx->fmap, pos, filesize, ctx, CL_TYPE_ANY);
|
||||
ret = cli_map_scan(*ctx->fmap, pos, filesize, ctx, CL_TYPE_ANY, name);
|
||||
if (ret == CL_VIRUS) {
|
||||
if (!SCAN_ALLMATCHES)
|
||||
return ret;
|
||||
|
|
|
@ -156,7 +156,7 @@ int cli_scandmg(cli_ctx *ctx)
|
|||
}
|
||||
|
||||
/* Create temp folder for contents */
|
||||
if (!(dirname = cli_gentemp(ctx->engine->tmpdir))) {
|
||||
if (!(dirname = cli_gentemp(ctx->sub_tmpdir))) {
|
||||
return CL_ETMPDIR;
|
||||
}
|
||||
if (mkdir(dirname, 0700)) {
|
||||
|
@ -178,8 +178,8 @@ int cli_scandmg(cli_ctx *ctx)
|
|||
}
|
||||
}
|
||||
|
||||
/* scan XML with cli_map_scandesc */
|
||||
ret = cli_map_scan(*ctx->fmap, (off_t)hdr.xmlOffset, (size_t)hdr.xmlLength, ctx, CL_TYPE_ANY);
|
||||
/* scan XML with cli_map_scan */
|
||||
ret = cli_map_scan(*ctx->fmap, (off_t)hdr.xmlOffset, (size_t)hdr.xmlLength, ctx, CL_TYPE_ANY, NULL);
|
||||
if (ret != CL_CLEAN) {
|
||||
cli_dbgmsg("cli_scandmg: retcode from scanning TOC xml: %s\n", cl_strerror(ret));
|
||||
if (!ctx->engine->keeptmp)
|
||||
|
@ -1082,7 +1082,8 @@ static int dmg_handle_mish(cli_ctx *ctx, unsigned int mishblocknum, char *dir,
|
|||
|
||||
/* If okay so far, scan rebuilt partition */
|
||||
if (ret == CL_CLEAN) {
|
||||
ret = cli_partition_scandesc(ofd, outfile, ctx);
|
||||
/* Have to keep partition typing separate */
|
||||
ret = cli_base_scandesc(ofd, outfile, ctx, CL_TYPE_PART_ANY, NULL);
|
||||
}
|
||||
|
||||
close(ofd);
|
||||
|
|
|
@ -881,7 +881,7 @@ int cli_unpackelf(cli_ctx *ctx)
|
|||
cli_dbgmsg("cli_scanelf: Unpacked and rebuilt executable\n");
|
||||
lseek(ndesc, 0, SEEK_SET);
|
||||
cli_dbgmsg("***** Scanning rebuilt ELF file *****\n");
|
||||
if (cli_magic_scandesc(ndesc, tempfile, ctx) == CL_VIRUS) {
|
||||
if (cli_magic_scandesc(ndesc, tempfile, ctx, NULL) == CL_VIRUS) {
|
||||
close(ndesc);
|
||||
CLI_TMPUNLK();
|
||||
free(tempfile);
|
||||
|
|
|
@ -1065,8 +1065,8 @@ char *cli_utf16toascii(const char *str, unsigned int length)
|
|||
char *cli_utf16_to_utf8(const char *utf16, size_t length, encoding_t type)
|
||||
{
|
||||
/* utf8 -
|
||||
* 4 bytes for utf16 high+low surrogate (4 bytes input)
|
||||
* 3 bytes for utf16 otherwise (2 bytes input) */
|
||||
* 4 bytes for utf16 high+low surrogate (4 bytes input)
|
||||
* 3 bytes for utf16 otherwise (2 bytes input) */
|
||||
size_t i, j;
|
||||
size_t needed = length * 3 / 2 + 2;
|
||||
char *s2;
|
||||
|
|
|
@ -357,7 +357,7 @@ cli_file_t cli_filetype2(fmap_t *map, const struct cl_engine *engine, cli_file_t
|
|||
/* if likely, check full archive */
|
||||
if (likely_ooxml) {
|
||||
cli_dbgmsg("Likely OOXML, checking additional zip headers\n");
|
||||
if ((ret2 = cli_ooxml_filetype(NULL, map)) != CL_SUCCESS) {
|
||||
if ((ret2 = cli_ooxml_filetype(NULL, map)) != CL_TYPE_ANY) {
|
||||
/* either an error or retyping has occurred, return error or just CL_TYPE_ZIP? */
|
||||
OOXML_FTIDENTIFIED(ret2);
|
||||
/* falls-through to additional filetyping */
|
||||
|
@ -405,8 +405,8 @@ cli_file_t cli_filetype2(fmap_t *map, const struct cl_engine *engine, cli_file_t
|
|||
|
||||
if (ret >= CL_TYPE_TEXT_ASCII && ret <= CL_TYPE_BINARY_DATA) {
|
||||
/* HTML files may contain special characters and could be
|
||||
* misidentified as BINARY_DATA by cli_filetype()
|
||||
*/
|
||||
* misidentified as BINARY_DATA by cli_filetype()
|
||||
*/
|
||||
root = engine->root[0];
|
||||
if (!root)
|
||||
return ret;
|
||||
|
@ -437,8 +437,8 @@ cli_file_t cli_filetype2(fmap_t *map, const struct cl_engine *engine, cli_file_t
|
|||
const char *encoding;
|
||||
|
||||
/* check if we can autodetect this encoding.
|
||||
* If we can't don't try to detect HTML sig, since
|
||||
* we just tried that above, and failed */
|
||||
* If we can't don't try to detect HTML sig, since
|
||||
* we just tried that above, and failed */
|
||||
if ((encoding = encoding_detect_bom(buff, bread))) {
|
||||
unsigned char decodedbuff[(MAGIC_BUFFER_SIZE + 1) * 2];
|
||||
m_area_t in_area, out_area;
|
||||
|
@ -453,9 +453,9 @@ cli_file_t cli_filetype2(fmap_t *map, const struct cl_engine *engine, cli_file_t
|
|||
out_area.offset = 0;
|
||||
|
||||
/* in htmlnorm we simply skip over \0 chars, allowing HTML parsing in any unicode
|
||||
* (multibyte characters will not be exactly handled, but that is not a problem).
|
||||
* However when detecting whether a file is HTML or not, we need exact conversion.
|
||||
* (just eliminating zeros and matching would introduce false positives */
|
||||
* (multibyte characters will not be exactly handled, but that is not a problem).
|
||||
* However when detecting whether a file is HTML or not, we need exact conversion.
|
||||
* (just eliminating zeros and matching would introduce false positives */
|
||||
if (encoding_normalize_toascii(&in_area, encoding, &out_area) >= 0 && out_area.length > 0) {
|
||||
if (cli_ac_initdata(&mdata, root->ac_partsigs, root->ac_lsigs, root->ac_reloff_num, CLI_DEFAULT_AC_TRACKLEN))
|
||||
return ret;
|
||||
|
|
|
@ -108,7 +108,7 @@ static off_t pread_cb(void *handle, void *buf, size_t count, off_t offset)
|
|||
return pread((int)(ssize_t)handle, buf, count, offset);
|
||||
}
|
||||
|
||||
fmap_t *fmap_check_empty(int fd, off_t offset, size_t len, int *empty)
|
||||
fmap_t *fmap_check_empty(int fd, off_t offset, size_t len, int *empty, const char *name)
|
||||
{
|
||||
STATBUF st;
|
||||
fmap_t *m = NULL;
|
||||
|
@ -143,6 +143,14 @@ fmap_t *fmap_check_empty(int fd, off_t offset, size_t len, int *empty)
|
|||
}
|
||||
memcpy(m->maphash, hash, 16);
|
||||
|
||||
if (NULL != name) {
|
||||
m->name = cli_strdup(name);
|
||||
if (NULL == m->name) {
|
||||
funmap(m);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return m;
|
||||
}
|
||||
#else
|
||||
|
@ -156,11 +164,14 @@ static void unmap_win32(fmap_t *m)
|
|||
if (NULL != m->mh) {
|
||||
CloseHandle(m->mh);
|
||||
}
|
||||
if (NULL != m->name) {
|
||||
free(m->name);
|
||||
}
|
||||
free((void *)m);
|
||||
}
|
||||
}
|
||||
|
||||
fmap_t *fmap_check_empty(int fd, off_t offset, size_t len, int *empty)
|
||||
fmap_t *fmap_check_empty(int fd, off_t offset, size_t len, int *empty, const char *name)
|
||||
{ /* WIN32 */
|
||||
unsigned int pages, mapsz;
|
||||
int pgsz = cli_getpagesize();
|
||||
|
@ -228,13 +239,21 @@ fmap_t *fmap_check_empty(int fd, off_t offset, size_t len, int *empty)
|
|||
}
|
||||
memcpy(m->maphash, hash, 16);
|
||||
|
||||
if (NULL != name) {
|
||||
m->name = cli_strdup(name);
|
||||
if (NULL == m->name) {
|
||||
funmap(m);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return m;
|
||||
}
|
||||
#endif /* _WIN32 */
|
||||
|
||||
/* vvvvv SHARED STUFF BELOW vvvvv */
|
||||
|
||||
fmap_t *fmap_duplicate(cl_fmap_t *map, off_t offset, size_t length)
|
||||
fmap_t *fmap_duplicate(cl_fmap_t *map, off_t offset, size_t length, const char *name)
|
||||
{
|
||||
cl_error_t status = CL_ERROR;
|
||||
cl_fmap_t *duplicate_map = NULL;
|
||||
|
@ -275,6 +294,16 @@ fmap_t *fmap_duplicate(cl_fmap_t *map, off_t offset, size_t length)
|
|||
}
|
||||
memcpy(duplicate_map->maphash, hash, 16);
|
||||
|
||||
if (NULL != name) {
|
||||
map->name = cli_strdup(name);
|
||||
if (NULL == map->name) {
|
||||
funmap(map);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
map->name = NULL;
|
||||
}
|
||||
|
||||
status = CL_SUCCESS;
|
||||
|
||||
done:
|
||||
|
@ -288,6 +317,17 @@ done:
|
|||
return duplicate_map;
|
||||
}
|
||||
|
||||
void free_duplicate_fmap(cl_fmap_t *map)
|
||||
{
|
||||
if (NULL != map) {
|
||||
if (NULL != map->name) {
|
||||
free(map->name);
|
||||
map->name = NULL;
|
||||
}
|
||||
free(map);
|
||||
}
|
||||
}
|
||||
|
||||
static void unmap_handle(fmap_t *m)
|
||||
{
|
||||
if (NULL != m) {
|
||||
|
@ -303,6 +343,9 @@ static void unmap_handle(fmap_t *m)
|
|||
free(m->bitmap);
|
||||
m->bitmap = NULL;
|
||||
}
|
||||
if (NULL != m->name) {
|
||||
free(m->name);
|
||||
}
|
||||
free((void *)m);
|
||||
}
|
||||
}
|
||||
|
@ -687,6 +730,9 @@ static void unmap_mmap(fmap_t *m)
|
|||
static void unmap_malloc(fmap_t *m)
|
||||
{
|
||||
if (NULL != m) {
|
||||
if (NULL != m->name) {
|
||||
free(m->name);
|
||||
}
|
||||
free((void *)m);
|
||||
}
|
||||
}
|
||||
|
@ -787,7 +833,7 @@ static void mem_unneed_off(fmap_t *m, size_t at, size_t len);
|
|||
static const void *mem_need_offstr(fmap_t *m, size_t at, size_t len_hint);
|
||||
static const void *mem_gets(fmap_t *m, char *dst, size_t *at, size_t max_len);
|
||||
|
||||
extern cl_fmap_t *cl_fmap_open_memory(const void *start, size_t len)
|
||||
fmap_t *fmap_open_memory(const void *start, size_t len, const char *name)
|
||||
{
|
||||
int pgsz = cli_getpagesize();
|
||||
cl_fmap_t *m = cli_calloc(1, sizeof(*m));
|
||||
|
@ -805,9 +851,23 @@ extern cl_fmap_t *cl_fmap_open_memory(const void *start, size_t len)
|
|||
m->need_offstr = mem_need_offstr;
|
||||
m->gets = mem_gets;
|
||||
m->unneed_off = mem_unneed_off;
|
||||
|
||||
if (NULL != name) {
|
||||
m->name = cli_strdup(name);
|
||||
if (NULL == m->name) {
|
||||
free(m);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
extern cl_fmap_t *cl_fmap_open_memory(const void *start, size_t len)
|
||||
{
|
||||
return (cl_fmap_t *)fmap_open_memory(start, len, NULL);
|
||||
}
|
||||
|
||||
static const void *mem_need(fmap_t *m, size_t at, size_t len, int lock)
|
||||
{ /* WIN32 */
|
||||
UNUSEDPARAM(lock);
|
||||
|
@ -865,10 +925,10 @@ static const void *mem_gets(fmap_t *m, char *dst, size_t *at, size_t max_len)
|
|||
return dst;
|
||||
}
|
||||
|
||||
fmap_t *fmap(int fd, off_t offset, size_t len)
|
||||
fmap_t *fmap(int fd, off_t offset, size_t len, const char *name)
|
||||
{
|
||||
int unused;
|
||||
return fmap_check_empty(fd, offset, len, &unused);
|
||||
return fmap_check_empty(fd, offset, len, &unused, name);
|
||||
}
|
||||
|
||||
static inline unsigned int fmap_align_items(unsigned int sz, unsigned int al)
|
||||
|
|
|
@ -82,10 +82,44 @@ struct cl_fmap {
|
|||
#endif
|
||||
unsigned char maphash[16];
|
||||
uint32_t *bitmap;
|
||||
char *name;
|
||||
};
|
||||
|
||||
fmap_t *fmap(int fd, off_t offset, size_t len);
|
||||
fmap_t *fmap_check_empty(int fd, off_t offset, size_t len, int *empty);
|
||||
/**
|
||||
* @brief Create a new fmap given a file descriptor.
|
||||
*
|
||||
* @param fd File descriptor of file to be mapped.
|
||||
* @param offset Offset into file for start of map.
|
||||
* @param len Length from offset for size of map.
|
||||
* @param name (optional) Original name of the file (to set fmap name metadata)
|
||||
* @return fmap_t* The newly created fmap. Free it with `funmap()`
|
||||
*/
|
||||
fmap_t *fmap(int fd, off_t offset, size_t len, const char *name);
|
||||
|
||||
/**
|
||||
* @brief Create new fmap given a file descriptor.
|
||||
*
|
||||
* This variant of fmap() provides a boolean output variable to indicate on
|
||||
* failure if the failure was because the file is empty (not really a failure).
|
||||
*
|
||||
* @param fd File descriptor of file to be mapped.
|
||||
* @param offset Offset into file for start of map.
|
||||
* @param len Length from offset for size of map.
|
||||
* @param empty [out] Boolean will be non-zero if the file couldn't be mapped because it is empty.
|
||||
* @param name (optional) Original name of the file (to set fmap name metadata)
|
||||
* @return fmap_t* The newly created fmap. Free it with `funmap()`
|
||||
*/
|
||||
fmap_t *fmap_check_empty(int fd, off_t offset, size_t len, int *empty, const char *name);
|
||||
|
||||
/**
|
||||
* @brief Create a new fmap given a buffer.
|
||||
*
|
||||
* @param start Start of a buffer that the fmap will reference.
|
||||
* @param len Length of the buffer.
|
||||
* @param name (optional) Original name of the file (to set fmap name metadata)
|
||||
* @return fmap_t*
|
||||
*/
|
||||
fmap_t *fmap_open_memory(const void *start, size_t len, const char *name);
|
||||
|
||||
/**
|
||||
* @brief Create a new fmap view into another fmap.
|
||||
|
@ -93,10 +127,25 @@ fmap_t *fmap_check_empty(int fd, off_t offset, size_t len, int *empty);
|
|||
* @param map The parent fmap.
|
||||
* @param offset Offset for the start of the new fmap into the parent fmap.
|
||||
* @param length Length of the data from the offset for the new fmap.
|
||||
* @return fmap_t* NULL if failure, an allocated fmap that must be free'd if success.
|
||||
* @param name (optional) Original name of the file (to set fmap name metadata)
|
||||
* @return fmap_t* NULL if failure or a special fmap that the caller must free with free_duplicate_fmap()
|
||||
*/
|
||||
fmap_t *fmap_duplicate(cl_fmap_t *map, off_t offset, size_t length);
|
||||
fmap_t *fmap_duplicate(cl_fmap_t *map, off_t offset, size_t length, const char *name);
|
||||
|
||||
/**
|
||||
* @brief Deallocate a _duplicated_ fmap. Does not unmap the mapped region.
|
||||
*
|
||||
* This function should be used instead of `free()` to cleanup the optional fmap name.
|
||||
*
|
||||
* @param m The map to be free'd.
|
||||
*/
|
||||
void free_duplicate_fmap(cl_fmap_t *map);
|
||||
|
||||
/**
|
||||
* @brief Unmap/deallocate an fmap.
|
||||
*
|
||||
* @param m The map to be free'd.
|
||||
*/
|
||||
static inline void funmap(fmap_t *m)
|
||||
{
|
||||
m->unmap(m);
|
||||
|
@ -114,7 +163,7 @@ static inline const void *fmap_need_off_once(fmap_t *m, size_t at, size_t len)
|
|||
|
||||
static inline size_t fmap_ptr2off(const fmap_t *m, const void *ptr)
|
||||
{
|
||||
return ((const char *)ptr - (const char *)m->data) - m->nested_offset;
|
||||
return (size_t)((const char *)ptr - (const char *)m->data) - m->nested_offset;
|
||||
}
|
||||
|
||||
static inline const void *fmap_need_ptr(fmap_t *m, const void *ptr, size_t len)
|
||||
|
|
|
@ -80,14 +80,14 @@ struct gif_image_desc {
|
|||
} \
|
||||
}
|
||||
|
||||
int cli_parsegif(cli_ctx *ctx)
|
||||
cl_error_t cli_parsegif(cli_ctx *ctx)
|
||||
{
|
||||
fmap_t *map = *ctx->fmap;
|
||||
unsigned char v = 0;
|
||||
unsigned int offset = 6;
|
||||
struct gif_screen_desc screen_desc;
|
||||
struct gif_image_desc image_desc;
|
||||
int retVal = CL_SUCCESS;
|
||||
cl_error_t retVal = CL_SUCCESS;
|
||||
|
||||
cli_dbgmsg("in cli_parsegif()\n");
|
||||
|
||||
|
@ -151,7 +151,7 @@ scan_overlay:
|
|||
|
||||
// Is there an overlay?
|
||||
if (offset < map->len) {
|
||||
int recRetVal = cli_map_scan(map, offset, map->len - offset, ctx, CL_TYPE_ANY);
|
||||
cl_error_t recRetVal = cli_map_scan(map, offset, map->len - offset, ctx, CL_TYPE_ANY, NULL);
|
||||
retVal = recRetVal != CL_SUCCESS ? recRetVal : retVal;
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,6 @@
|
|||
|
||||
#include "others.h"
|
||||
|
||||
int cli_parsegif(cli_ctx *ctx);
|
||||
cl_error_t cli_parsegif(cli_ctx *ctx);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -67,7 +67,6 @@ static int gpt_scan_partitions(cli_ctx *ctx, struct gpt_header hdr, size_t secto
|
|||
static int gpt_validate_header(cli_ctx *ctx, struct gpt_header hdr, size_t sectorsize);
|
||||
static int gpt_check_mbr(cli_ctx *ctx, size_t sectorsize);
|
||||
static void gpt_printSectors(cli_ctx *ctx, size_t sectorsize);
|
||||
static void gpt_printName(uint16_t name[], const char *msg);
|
||||
static void gpt_printGUID(uint8_t GUID[], const char *msg);
|
||||
static int gpt_prtn_intxn(cli_ctx *ctx, struct gpt_header hdr, size_t sectorsize);
|
||||
|
||||
|
@ -328,9 +327,13 @@ static int gpt_scan_partitions(cli_ctx *ctx, struct gpt_header hdr, size_t secto
|
|||
} else if (((gpe.lastLBA + 1) * sectorsize) > maplen) {
|
||||
/* partition exists outside bounds of the file map */
|
||||
} else {
|
||||
char *namestr = NULL;
|
||||
|
||||
namestr = (char *)cli_utf16toascii((char *)gpe.name, 72);
|
||||
|
||||
/* print partition entry data for debug */
|
||||
cli_dbgmsg("GPT Partition Entry %u:\n", i);
|
||||
gpt_printName(gpe.name, "Name");
|
||||
cli_dbgmsg("Name: %s\n", namestr);
|
||||
gpt_printGUID(gpe.typeGUID, "Type GUID");
|
||||
gpt_printGUID(gpe.uniqueGUID, "Unique GUID");
|
||||
cli_dbgmsg("Attributes: %llx\n", (long long unsigned)gpe.attributes);
|
||||
|
@ -341,7 +344,10 @@ static int gpt_scan_partitions(cli_ctx *ctx, struct gpt_header hdr, size_t secto
|
|||
/* send the partition to cli_map_scan */
|
||||
part_off = gpe.firstLBA * sectorsize;
|
||||
part_size = (gpe.lastLBA - gpe.firstLBA + 1) * sectorsize;
|
||||
ret = cli_map_scan(*ctx->fmap, part_off, part_size, ctx, CL_TYPE_PART_ANY);
|
||||
ret = cli_map_scan(*ctx->fmap, part_off, part_size, ctx, CL_TYPE_PART_ANY, namestr);
|
||||
if (NULL != namestr) {
|
||||
free(namestr);
|
||||
}
|
||||
if (ret != CL_CLEAN) {
|
||||
if (SCAN_ALLMATCHES && (ret == CL_VIRUS))
|
||||
detection = CL_VIRUS;
|
||||
|
@ -567,16 +573,6 @@ static void gpt_printSectors(cli_ctx *ctx, size_t sectorsize)
|
|||
#endif
|
||||
}
|
||||
|
||||
static void gpt_printName(uint16_t name[], const char *msg)
|
||||
{
|
||||
char *namestr;
|
||||
|
||||
namestr = (char *)cli_utf16toascii((char *)name, 72);
|
||||
cli_dbgmsg("%s: %s\n", msg, namestr);
|
||||
|
||||
free(namestr);
|
||||
}
|
||||
|
||||
static void gpt_printGUID(uint8_t GUID[], const char *msg)
|
||||
{
|
||||
cli_dbgmsg("%s: %02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n",
|
||||
|
|
|
@ -434,7 +434,7 @@ static cl_error_t hfsplus_scanfile(cli_ctx *ctx, hfsPlusVolumeHeader *volHeader,
|
|||
}
|
||||
else {
|
||||
if (ret == CL_CLEAN) {
|
||||
ret = cli_magic_scandesc(ofd, tmpname, ctx);
|
||||
ret = cli_magic_scandesc(ofd, tmpname, ctx, orig_filename);
|
||||
}
|
||||
|
||||
if (!ctx->engine->keeptmp) {
|
||||
|
@ -1336,7 +1336,7 @@ static cl_error_t hfsplus_walk_catalog(cli_ctx *ctx, hfsPlusVolumeHeader *volHea
|
|||
cli_dbgmsg("hfsplus_walk_catalog: Extracted to %s\n", tmpname);
|
||||
|
||||
/* if successful so far, scan the output */
|
||||
ret = cli_magic_scandesc(ofd, tmpname, ctx);
|
||||
ret = cli_magic_scandesc(ofd, tmpname, ctx, name_utf8);
|
||||
|
||||
if (ret == CL_VIRUS) {
|
||||
has_alerts = 1;
|
||||
|
@ -1495,7 +1495,7 @@ cli_dbgmsg("sizeof(hfsNodeDescriptor) is %lu\n", sizeof(hfsNodeDescriptor));
|
|||
|
||||
|
||||
/* Create temp folder for contents */
|
||||
if (!(targetdir = cli_gentemp(ctx->engine->tmpdir))) {
|
||||
if (!(targetdir = cli_gentemp(ctx->sub_tmpdir))) {
|
||||
cli_errmsg("cli_scandmg: cli_gentemp failed\n");
|
||||
ret = CL_ETMPDIR;
|
||||
goto freeHeader;
|
||||
|
|
|
@ -92,7 +92,7 @@ static cl_error_t decompress_and_callback(cli_ctx *ctx, fmap_t *input, size_t at
|
|||
remain = len;
|
||||
|
||||
/* reserve tempfile for output and callback */
|
||||
if ((ret = cli_gentempfd(ctx->engine->tmpdir, &tmpname, &ofd)) != CL_SUCCESS) {
|
||||
if ((ret = cli_gentempfd(ctx->sub_tmpdir, &tmpname, &ofd)) != CL_SUCCESS) {
|
||||
cli_errmsg("%s: Can't generate temporary file\n", parent);
|
||||
return ret;
|
||||
}
|
||||
|
@ -175,7 +175,7 @@ static cl_error_t decompress_and_callback(cli_ctx *ctx, fmap_t *input, size_t at
|
|||
ret = cb(cbdata, ofd, tmpname, ctx);
|
||||
} else {
|
||||
/* default to scanning what we got */
|
||||
ret = cli_magic_scandesc(ofd, tmpname, ctx);
|
||||
ret = cli_magic_scandesc(ofd, tmpname, ctx, NULL);
|
||||
}
|
||||
|
||||
/* clean-up */
|
||||
|
@ -293,7 +293,7 @@ cl_error_t cli_scanhwpole2(cli_ctx *ctx)
|
|||
else
|
||||
cli_dbgmsg("HWPOLE2: Matched uncompressed prefix and size: %u == %u\n", usize, asize);
|
||||
|
||||
return cli_map_scandesc(map, 4, 0, ctx, CL_TYPE_ANY);
|
||||
return cli_map_scandesc(map, 4, 0, ctx, CL_TYPE_ANY, NULL);
|
||||
//return cli_map_scandesc(map, 4, 0, ctx, CL_TYPE_OLE2);
|
||||
}
|
||||
|
||||
|
@ -377,7 +377,7 @@ static cl_error_t hwp5_cb(void *cbdata, int fd, const char *filepath, cli_ctx *c
|
|||
if (fd < 0 || !ctx)
|
||||
return CL_ENULLARG;
|
||||
|
||||
return cli_magic_scandesc(fd, filepath, ctx);
|
||||
return cli_magic_scandesc(fd, filepath, ctx, NULL);
|
||||
}
|
||||
|
||||
cl_error_t cli_scanhwp5_stream(cli_ctx *ctx, hwp5_header_t *hwp5, char *name, int fd, const char *filepath)
|
||||
|
@ -397,7 +397,7 @@ cl_error_t cli_scanhwp5_stream(cli_ctx *ctx, hwp5_header_t *hwp5, char *name, in
|
|||
|
||||
if (hwp5->flags & HWP5_PASSWORD) {
|
||||
cli_dbgmsg("HWP5.x: Password encrypted stream, scanning as-is\n");
|
||||
return cli_magic_scandesc(fd, filepath, ctx);
|
||||
return cli_magic_scandesc(fd, filepath, ctx, name);
|
||||
}
|
||||
|
||||
if (hwp5->flags & HWP5_COMPRESSED) {
|
||||
|
@ -414,7 +414,7 @@ cl_error_t cli_scanhwp5_stream(cli_ctx *ctx, hwp5_header_t *hwp5, char *name, in
|
|||
return CL_ESTAT;
|
||||
}
|
||||
|
||||
input = fmap(fd, 0, statbuf.st_size);
|
||||
input = fmap(fd, 0, statbuf.st_size, NULL);
|
||||
if (!input) {
|
||||
cli_errmsg("HWP5.x: Failed to get fmap for input stream\n");
|
||||
return CL_EMAP;
|
||||
|
@ -440,7 +440,7 @@ cl_error_t cli_scanhwp5_stream(cli_ctx *ctx, hwp5_header_t *hwp5, char *name, in
|
|||
}
|
||||
|
||||
/* normal streams */
|
||||
return cli_magic_scandesc(fd, filepath, ctx);
|
||||
return cli_magic_scandesc(fd, filepath, ctx, name);
|
||||
}
|
||||
|
||||
/*** HWP3 ***/
|
||||
|
@ -1645,7 +1645,7 @@ static inline cl_error_t parsehwp3_infoblk_1(cli_ctx *ctx, fmap_t *dmap, size_t
|
|||
#endif
|
||||
/* 32 bytes for extra data fields */
|
||||
if (infolen > 0)
|
||||
ret = cli_map_scan(map, *offset + 32, infolen - 32, ctx, CL_TYPE_ANY);
|
||||
ret = cli_map_scan(map, *offset + 32, infolen - 32, ctx, CL_TYPE_ANY, NULL);
|
||||
break;
|
||||
case 2: /* OLE2 Data */
|
||||
hwp3_debug("HWP3.x: Information Block[%llu]: TYPE: OLE2 Data\n", infoloc);
|
||||
|
@ -1654,7 +1654,7 @@ static inline cl_error_t parsehwp3_infoblk_1(cli_ctx *ctx, fmap_t *dmap, size_t
|
|||
cli_jsonstr(entry, "Type", "OLE2 Data");
|
||||
#endif
|
||||
if (infolen > 0)
|
||||
ret = cli_map_scan(map, *offset, infolen, ctx, CL_TYPE_ANY);
|
||||
ret = cli_map_scan(map, *offset, infolen, ctx, CL_TYPE_ANY, NULL);
|
||||
break;
|
||||
case 3: /* Hypertext/Hyperlink Information */
|
||||
hwp3_debug("HWP3.x: Information Block[%llu]: TYPE: Hypertext/Hyperlink Information\n", infoloc);
|
||||
|
@ -1682,7 +1682,7 @@ static inline cl_error_t parsehwp3_infoblk_1(cli_ctx *ctx, fmap_t *dmap, size_t
|
|||
hwp3_debug("HWP3.x: Information Block[%llu]: %d: NAME: %s\n", infoloc, i, field);
|
||||
#endif
|
||||
/* scanning macros - TODO - check numbers */
|
||||
ret = cli_map_scan(map, *offset + (617 * i) + 288, 325, ctx, CL_TYPE_ANY);
|
||||
ret = cli_map_scan(map, *offset + (617 * i) + 288, 325, ctx, CL_TYPE_ANY, NULL);
|
||||
}
|
||||
break;
|
||||
case 4: /* Presentation Information */
|
||||
|
@ -1719,7 +1719,7 @@ static inline cl_error_t parsehwp3_infoblk_1(cli_ctx *ctx, fmap_t *dmap, size_t
|
|||
#endif
|
||||
/* 324 bytes for extra data fields */
|
||||
if (infolen > 0)
|
||||
ret = cli_map_scan(map, *offset + 324, infolen - 324, ctx, CL_TYPE_ANY);
|
||||
ret = cli_map_scan(map, *offset + 324, infolen - 324, ctx, CL_TYPE_ANY, NULL);
|
||||
break;
|
||||
case 0x100: /* Table Extension */
|
||||
hwp3_debug("HWP3.x: Information Block[%llu]: TYPE: Table Extension\n", infoloc);
|
||||
|
@ -1740,7 +1740,7 @@ static inline cl_error_t parsehwp3_infoblk_1(cli_ctx *ctx, fmap_t *dmap, size_t
|
|||
default:
|
||||
cli_warnmsg("HWP3.x: Information Block[%llu]: TYPE: UNKNOWN(%u)\n", infoloc, infoid);
|
||||
if (infolen > 0)
|
||||
ret = cli_map_scan(map, *offset, infolen, ctx, CL_TYPE_ANY);
|
||||
ret = cli_map_scan(map, *offset, infolen, ctx, CL_TYPE_ANY, NULL);
|
||||
}
|
||||
|
||||
*offset += infolen;
|
||||
|
@ -1774,7 +1774,7 @@ static cl_error_t hwp3_cb(void *cbdata, int fd, const char *filepath, cli_ctx *c
|
|||
return CL_ESTAT;
|
||||
}
|
||||
|
||||
map = dmap = fmap(fd, 0, statbuf.st_size);
|
||||
map = dmap = fmap(fd, 0, statbuf.st_size, NULL);
|
||||
if (!map) {
|
||||
cli_errmsg("HWP3.x: Failed to get fmap for uncompressed stream\n");
|
||||
return CL_EMAP;
|
||||
|
@ -1863,7 +1863,7 @@ static cl_error_t hwp3_cb(void *cbdata, int fd, const char *filepath, cli_ctx *c
|
|||
cl_error_t subret = ret;
|
||||
size_t dlen = offset - start;
|
||||
|
||||
ret = cli_map_scandesc(map, start, dlen, ctx, CL_TYPE_ANY);
|
||||
ret = cli_map_scandesc(map, start, dlen, ctx, CL_TYPE_ANY, NULL);
|
||||
//ret = cli_map_scandesc(map, 0, 0, ctx, CL_TYPE_ANY);
|
||||
|
||||
if (ret == CL_SUCCESS)
|
||||
|
@ -1978,7 +1978,7 @@ static cl_error_t hwpml_scan_cb(void *cbdata, int fd, const char *filepath, cli_
|
|||
if (fd < 0 || !ctx)
|
||||
return CL_ENULLARG;
|
||||
|
||||
return cli_magic_scandesc(fd, filepath, ctx);
|
||||
return cli_magic_scandesc(fd, filepath, ctx, NULL);
|
||||
}
|
||||
|
||||
static cl_error_t hwpml_binary_cb(int fd, const char *filepath, cli_ctx *ctx, int num_attribs, struct attrib_entry *attribs, void *cbdata)
|
||||
|
@ -2014,7 +2014,7 @@ static cl_error_t hwpml_binary_cb(int fd, const char *filepath, cli_ctx *ctx, in
|
|||
/* decode the binary data if needed - base64 */
|
||||
if (enc < 0) {
|
||||
cli_errmsg("HWPML: Unrecognized encoding method\n");
|
||||
return cli_magic_scandesc(fd, filepath, ctx);
|
||||
return cli_magic_scandesc(fd, filepath, ctx, NULL);
|
||||
} else if (enc == 1) {
|
||||
STATBUF statbuf;
|
||||
fmap_t *input;
|
||||
|
@ -2030,7 +2030,7 @@ static cl_error_t hwpml_binary_cb(int fd, const char *filepath, cli_ctx *ctx, in
|
|||
return CL_ESTAT;
|
||||
}
|
||||
|
||||
if (!(input = fmap(fd, 0, statbuf.st_size))) {
|
||||
if (!(input = fmap(fd, 0, statbuf.st_size, NULL))) {
|
||||
cli_errmsg("HWPML: Failed to get fmap for binary data\n");
|
||||
return CL_EMAP;
|
||||
}
|
||||
|
@ -2046,11 +2046,11 @@ static cl_error_t hwpml_binary_cb(int fd, const char *filepath, cli_ctx *ctx, in
|
|||
funmap(input);
|
||||
if (!decoded) {
|
||||
cli_errmsg("HWPML: Failed to get base64 decode binary data\n");
|
||||
return cli_magic_scandesc(fd, filepath, ctx);
|
||||
return cli_magic_scandesc(fd, filepath, ctx, NULL);
|
||||
}
|
||||
|
||||
/* open file for writing and scanning */
|
||||
if ((ret = cli_gentempfd(ctx->engine->tmpdir, &tempfile, &df)) != CL_SUCCESS) {
|
||||
if ((ret = cli_gentempfd(ctx->sub_tmpdir, &tempfile, &df)) != CL_SUCCESS) {
|
||||
cli_warnmsg("HWPML: Failed to create temporary file for decoded stream scanning\n");
|
||||
return ret;
|
||||
}
|
||||
|
@ -2082,7 +2082,7 @@ static cl_error_t hwpml_binary_cb(int fd, const char *filepath, cli_ctx *ctx, in
|
|||
goto hwpml_end;
|
||||
}
|
||||
|
||||
input = fmap(fd, 0, statbuf.st_size);
|
||||
input = fmap(fd, 0, statbuf.st_size, NULL);
|
||||
if (!input) {
|
||||
cli_errmsg("HWPML: Failed to get fmap for binary data\n");
|
||||
ret = CL_EMAP;
|
||||
|
|
|
@ -210,6 +210,7 @@ int cli_scanishield_msi(cli_ctx *ctx, off_t off)
|
|||
while (fcount--) {
|
||||
struct IS_FB fb;
|
||||
uint8_t obuf[BUFSIZ], *key = (uint8_t *)&fb.fname;
|
||||
char *filename = NULL;
|
||||
char *tempfile;
|
||||
unsigned int i, lameidx = 0, keylen;
|
||||
int ofd;
|
||||
|
@ -235,9 +236,12 @@ int cli_scanishield_msi(cli_ctx *ctx, off_t off)
|
|||
|
||||
keylen = strlen((const char *)key);
|
||||
if (!keylen) return CL_CLEAN;
|
||||
|
||||
filename = cli_strdup((const char *)key);
|
||||
|
||||
/* FIXMEISHIELD: cleanup the spam below */
|
||||
cli_dbgmsg("ishield-msi: File %s (csize: %llx, unk1:%x unk2:%x unk3:%x unk4:%x unk5:%x unk6:%x unk7:%x unk8:%x unk9:%x unk10:%x unk11:%x)\n", key, (long long)csize, fb.unk1, fb.unk2, fb.unk3, fb.unk4, fb.unk5, fb.unk6, fb.unk7, fb.unk8, fb.unk9, fb.unk10, fb.unk11);
|
||||
if (!(tempfile = cli_gentemp(ctx->engine->tmpdir))) return CL_EMEM;
|
||||
if (!(tempfile = cli_gentemp(ctx->sub_tmpdir))) return CL_EMEM;
|
||||
if ((ofd = open(tempfile, O_RDWR | O_CREAT | O_TRUNC | O_BINARY, S_IRUSR | S_IWUSR)) < 0) {
|
||||
cli_dbgmsg("ishield-msi: failed to create file %s\n", tempfile);
|
||||
free(tempfile);
|
||||
|
@ -299,14 +303,21 @@ int cli_scanishield_msi(cli_ctx *ctx, off_t off)
|
|||
cli_dbgmsg("ishield-msi: call to lseek() failed\n");
|
||||
ret = CL_ESEEK;
|
||||
}
|
||||
ret = cli_magic_scandesc(ofd, tempfile, ctx);
|
||||
ret = cli_magic_scandesc(ofd, tempfile, ctx, filename);
|
||||
}
|
||||
close(ofd);
|
||||
|
||||
if (!ctx->engine->keeptmp)
|
||||
if (cli_unlink(tempfile)) ret = CL_EUNLINK;
|
||||
if (!ctx->engine->keeptmp) {
|
||||
if (cli_unlink(tempfile)) {
|
||||
ret = CL_EUNLINK;
|
||||
}
|
||||
}
|
||||
free(tempfile);
|
||||
|
||||
if (NULL != filename) {
|
||||
free(filename);
|
||||
}
|
||||
|
||||
if (ret != CL_CLEAN)
|
||||
return ret;
|
||||
|
||||
|
@ -455,7 +466,7 @@ static int is_dump_and_scan(cli_ctx *ctx, off_t off, size_t fsize)
|
|||
cli_dbgmsg("ishield: skipping empty file\n");
|
||||
return CL_CLEAN;
|
||||
}
|
||||
if (!(fname = cli_gentemp(ctx->engine->tmpdir)))
|
||||
if (!(fname = cli_gentemp(ctx->sub_tmpdir)))
|
||||
return CL_EMEM;
|
||||
|
||||
if ((ofd = open(fname, O_RDWR | O_CREAT | O_TRUNC | O_BINARY, S_IRUSR | S_IWUSR)) < 0) {
|
||||
|
@ -483,7 +494,7 @@ static int is_dump_and_scan(cli_ctx *ctx, off_t off, size_t fsize)
|
|||
cli_dbgmsg("ishield: call to lseek() failed\n");
|
||||
ret = CL_ESEEK;
|
||||
}
|
||||
ret = cli_magic_scandesc(ofd, fname, ctx);
|
||||
ret = cli_magic_scandesc(ofd, fname, ctx, NULL);
|
||||
}
|
||||
close(ofd);
|
||||
if (!ctx->engine->keeptmp)
|
||||
|
@ -704,7 +715,7 @@ static int is_extract_cab(cli_ctx *ctx, uint64_t off, uint64_t size, uint64_t cs
|
|||
return CL_EMEM;
|
||||
}
|
||||
|
||||
if (!(tempfile = cli_gentemp(ctx->engine->tmpdir))) {
|
||||
if (!(tempfile = cli_gentemp(ctx->sub_tmpdir))) {
|
||||
free(outbuf);
|
||||
return CL_EMEM;
|
||||
}
|
||||
|
@ -783,7 +794,7 @@ static int is_extract_cab(cli_ctx *ctx, uint64_t off, uint64_t size, uint64_t cs
|
|||
cli_dbgmsg("is_extract_cab: extracted to %s\n", tempfile);
|
||||
if (lseek(ofd, 0, SEEK_SET) == -1)
|
||||
cli_dbgmsg("is_extract_cab: call to lseek() failed\n");
|
||||
ret = cli_magic_scandesc(ofd, tempfile, ctx);
|
||||
ret = cli_magic_scandesc(ofd, tempfile, ctx, NULL);
|
||||
}
|
||||
|
||||
close(ofd);
|
||||
|
|
|
@ -59,7 +59,7 @@ static int iso_scan_file(const iso9660_t *iso, unsigned int block, unsigned int
|
|||
char *tmpf;
|
||||
int fd, ret = CL_SUCCESS;
|
||||
|
||||
if (cli_gentempfd(iso->ctx->engine->tmpdir, &tmpf, &fd) != CL_SUCCESS)
|
||||
if (cli_gentempfd(iso->ctx->sub_tmpdir, &tmpf, &fd) != CL_SUCCESS)
|
||||
return CL_ETMPFILE;
|
||||
|
||||
cli_dbgmsg("iso_scan_file: dumping to %s\n", tmpf);
|
||||
|
@ -82,7 +82,7 @@ static int iso_scan_file(const iso9660_t *iso, unsigned int block, unsigned int
|
|||
}
|
||||
|
||||
if (!len)
|
||||
ret = cli_magic_scandesc(fd, tmpf, iso->ctx);
|
||||
ret = cli_magic_scandesc(fd, tmpf, iso->ctx, iso->buf);
|
||||
|
||||
close(fd);
|
||||
if (!iso->ctx->engine->keeptmp) {
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
return CL_EPARSE; \
|
||||
}
|
||||
|
||||
int cli_parsejpeg(cli_ctx *ctx)
|
||||
cl_error_t cli_parsejpeg(cli_ctx *ctx)
|
||||
{
|
||||
fmap_t *map = *ctx->fmap;
|
||||
unsigned char marker, prev_marker, prev_segment = 0, v1, v2, buff[8];
|
||||
|
|
|
@ -24,6 +24,6 @@
|
|||
|
||||
#include "others.h"
|
||||
|
||||
int cli_parsejpeg(cli_ctx *ctx);
|
||||
cl_error_t cli_parsejpeg(cli_ctx *ctx);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -331,21 +331,6 @@ static struct mspack_system mspack_sys_fmap_ops = {
|
|||
.copy = mspack_fmap_copy,
|
||||
};
|
||||
|
||||
static int cli_scanfile(const char *filename, cli_ctx *ctx)
|
||||
{
|
||||
int fd, ret = 0;
|
||||
|
||||
/* internal version of cl_scanfile with arec/mrec preserved */
|
||||
fd = safe_open(filename, O_RDONLY | O_BINARY);
|
||||
if (fd < 0)
|
||||
return ret;
|
||||
|
||||
ret = cli_magic_scandesc(fd, filename, ctx);
|
||||
|
||||
close(fd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int cli_scanmscab(cli_ctx *ctx, off_t sfx_offset)
|
||||
{
|
||||
struct mscab_decompressor *cab_d;
|
||||
|
@ -410,7 +395,7 @@ int cli_scanmscab(cli_ctx *ctx, off_t sfx_offset)
|
|||
else
|
||||
max_size = ctx->engine->maxfilesize ? ctx->engine->maxfilesize : 0xffffffff;
|
||||
|
||||
tmp_fname = cli_gentemp(ctx->engine->tmpdir);
|
||||
tmp_fname = cli_gentemp(ctx->sub_tmpdir);
|
||||
if (!tmp_fname) {
|
||||
ret = CL_EMEM;
|
||||
break;
|
||||
|
@ -423,9 +408,12 @@ int cli_scanmscab(cli_ctx *ctx, off_t sfx_offset)
|
|||
/* Failed to extract. Try to scan what is there */
|
||||
cli_dbgmsg("%s() failed to extract %d\n", __func__, ret);
|
||||
|
||||
ret = cli_scanfile(tmp_fname, ctx);
|
||||
if (ret == CL_VIRUS)
|
||||
ret = cli_scanfile(tmp_fname, ctx, cab_f->filename);
|
||||
if (CL_EOPEN == ret) {
|
||||
ret = CL_CLEAN;
|
||||
} else if (CL_VIRUS == ret) {
|
||||
virus_num++;
|
||||
}
|
||||
|
||||
if (!ctx->engine->keeptmp) {
|
||||
if (!access(tmp_fname, R_OK) && cli_unlink(tmp_fname)) {
|
||||
|
@ -511,7 +499,7 @@ int cli_scanmschm(cli_ctx *ctx)
|
|||
|
||||
ops_ex.max_size = max_size;
|
||||
|
||||
tmp_fname = cli_gentemp(ctx->engine->tmpdir);
|
||||
tmp_fname = cli_gentemp(ctx->sub_tmpdir);
|
||||
if (!tmp_fname) {
|
||||
ret = CL_EMEM;
|
||||
break;
|
||||
|
@ -523,9 +511,12 @@ int cli_scanmschm(cli_ctx *ctx)
|
|||
/* Failed to extract. Try to scan what is there */
|
||||
cli_dbgmsg("%s() failed to extract %d\n", __func__, ret);
|
||||
|
||||
ret = cli_scanfile(tmp_fname, ctx);
|
||||
if (ret == CL_VIRUS)
|
||||
ret = cli_scanfile(tmp_fname, ctx, mschm_f->filename);
|
||||
if (CL_EOPEN == ret) {
|
||||
ret = CL_CLEAN;
|
||||
} else if (CL_VIRUS == ret) {
|
||||
virus_num++;
|
||||
}
|
||||
|
||||
if (!ctx->engine->keeptmp) {
|
||||
if (!access(tmp_fname, R_OK) && cli_unlink(tmp_fname)) {
|
||||
|
|
|
@ -562,7 +562,7 @@ int cli_scanmacho_unibin(cli_ctx *ctx)
|
|||
cli_dbgmsg("UNIBIN: Binary %u of %u\n", i + 1, fat_header.nfats);
|
||||
cli_dbgmsg("UNIBIN: File offset: %u\n", fat_arch.offset);
|
||||
cli_dbgmsg("UNIBIN: File size: %u\n", fat_arch.size);
|
||||
ret = cli_map_scan(map, fat_arch.offset, fat_arch.size, ctx, CL_TYPE_ANY);
|
||||
ret = cli_map_scan(map, fat_arch.offset, fat_arch.size, ctx, CL_TYPE_ANY, NULL);
|
||||
if (ret == CL_VIRUS)
|
||||
break;
|
||||
}
|
||||
|
@ -602,7 +602,7 @@ int cli_unpackmacho(cli_ctx *ctx)
|
|||
cli_dbgmsg("cli_scanmacho: Unpacked and rebuilt executable\n");
|
||||
lseek(ndesc, 0, SEEK_SET);
|
||||
cli_dbgmsg("***** Scanning rebuilt Mach-O file *****\n");
|
||||
if (cli_magic_scandesc(ndesc, tempfile, ctx) == CL_VIRUS) {
|
||||
if (cli_magic_scandesc(ndesc, tempfile, ctx, NULL) == CL_VIRUS) {
|
||||
close(ndesc);
|
||||
CLI_TMPUNLK();
|
||||
free(tempfile);
|
||||
|
|
|
@ -60,14 +60,14 @@
|
|||
|
||||
#ifdef CLI_PERF_LOGGING
|
||||
|
||||
static inline void PERF_LOG_FILTER(int32_t pos, int32_t length, int8_t trie)
|
||||
static inline void perf_log_filter(int32_t pos, int32_t length, int8_t trie)
|
||||
{
|
||||
cli_perf_log_add(RAW_BYTES_SCANNED, length);
|
||||
cli_perf_log_add(FILTER_BYTES_SCANNED, length - pos);
|
||||
cli_perf_log_count2(TRIE_SCANNED, trie, length - pos);
|
||||
}
|
||||
|
||||
static inline int PERF_LOG_TRIES(int8_t acmode, int8_t bm_called, int32_t length)
|
||||
static inline int perf_log_tries(int8_t acmode, int8_t bm_called, int32_t length)
|
||||
{
|
||||
if (bm_called)
|
||||
cli_perf_log_add(BM_SCANNED, length);
|
||||
|
@ -77,14 +77,14 @@ static inline int PERF_LOG_TRIES(int8_t acmode, int8_t bm_called, int32_t length
|
|||
}
|
||||
|
||||
#else
|
||||
static inline void PERF_LOG_FILTER(int32_t pos, uint32_t length, int8_t trie)
|
||||
static inline void perf_log_filter(int32_t pos, uint32_t length, int8_t trie)
|
||||
{
|
||||
UNUSEDPARAM(pos);
|
||||
UNUSEDPARAM(length);
|
||||
UNUSEDPARAM(trie);
|
||||
}
|
||||
|
||||
static inline int PERF_LOG_TRIES(int8_t acmode, int8_t bm_called, int32_t length)
|
||||
static inline int perf_log_tries(int8_t acmode, int8_t bm_called, int32_t length)
|
||||
{
|
||||
UNUSEDPARAM(acmode);
|
||||
UNUSEDPARAM(bm_called);
|
||||
|
@ -121,16 +121,16 @@ static inline int matcher_run(const struct cli_matcher *root,
|
|||
/* for safety always scan last maxpatlen bytes */
|
||||
pos = length - root->maxpatlen - 1;
|
||||
if (pos < 0) pos = 0;
|
||||
PERF_LOG_FILTER(pos, length, root->type);
|
||||
perf_log_filter(pos, length, root->type);
|
||||
} else {
|
||||
/* must not cut buffer for 64[4-4]6161, because we must be able to check
|
||||
* 64! */
|
||||
* 64! */
|
||||
pos = info.first_match - root->maxpatlen - 1;
|
||||
if (pos < 0) pos = 0;
|
||||
PERF_LOG_FILTER(pos, length, root->type);
|
||||
perf_log_filter(pos, length, root->type);
|
||||
}
|
||||
} else {
|
||||
PERF_LOG_FILTER(0, length, root->type);
|
||||
perf_log_filter(0, length, root->type);
|
||||
}
|
||||
|
||||
orig_length = length;
|
||||
|
@ -140,11 +140,11 @@ static inline int matcher_run(const struct cli_matcher *root,
|
|||
buffer += pos;
|
||||
offset += pos;
|
||||
if (!root->ac_only) {
|
||||
PERF_LOG_TRIES(0, 1, length);
|
||||
perf_log_tries(0, 1, length);
|
||||
if (root->bm_offmode) {
|
||||
/* Don't use prefiltering for BM offset mode, since BM keeps tracks
|
||||
* of offsets itself, and doesn't work if we skip chunks of input
|
||||
* data */
|
||||
* of offsets itself, and doesn't work if we skip chunks of input
|
||||
* data */
|
||||
ret = cli_bm_scanbuff(orig_buffer, orig_length, virname, NULL, root, orig_offset, tinfo, offdata, ctx);
|
||||
} else {
|
||||
ret = cli_bm_scanbuff(buffer, length, virname, NULL, root, offset, tinfo, offdata, ctx);
|
||||
|
@ -163,7 +163,7 @@ static inline int matcher_run(const struct cli_matcher *root,
|
|||
}
|
||||
}
|
||||
}
|
||||
PERF_LOG_TRIES(acmode, 0, length);
|
||||
perf_log_tries(acmode, 0, length);
|
||||
ret = cli_ac_scanbuff(buffer, length, virname, NULL, acres, root, mdata, offset, ftype, ftoffset, acmode, ctx);
|
||||
if (ret != CL_CLEAN) {
|
||||
if (ret == CL_VIRUS) {
|
||||
|
@ -759,14 +759,14 @@ int32_t cli_bcapi_matchicon(struct cli_bc_ctx *ctx, const uint8_t *grp1, int32_t
|
|||
return ret;
|
||||
}
|
||||
|
||||
cl_error_t cli_scandesc(int desc, cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struct cli_matched_type **ftoffset, unsigned int acmode, struct cli_ac_result **acres)
|
||||
cl_error_t cli_scandesc(int desc, cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struct cli_matched_type **ftoffset, unsigned int acmode, struct cli_ac_result **acres, const char *name)
|
||||
{
|
||||
cl_error_t ret = CL_EMEM;
|
||||
int empty;
|
||||
fmap_t *map = *ctx->fmap; /* Store off the parent fmap for easy reference */
|
||||
|
||||
ctx->fmap++; /* Perform scan with child fmap */
|
||||
if (NULL != (*ctx->fmap = fmap_check_empty(desc, 0, 0, &empty))) {
|
||||
if (NULL != (*ctx->fmap = fmap_check_empty(desc, 0, 0, &empty, name))) {
|
||||
ret = cli_fmap_scandesc(ctx, ftype, ftonly, ftoffset, acmode, acres, NULL);
|
||||
map->dont_cache_flag = (*ctx->fmap)->dont_cache_flag;
|
||||
funmap(*ctx->fmap);
|
||||
|
@ -795,7 +795,7 @@ static int intermediates_eval(cli_ctx *ctx, struct cli_ac_lsig *ac_lsig)
|
|||
return 1;
|
||||
}
|
||||
|
||||
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)
|
||||
static cl_error_t 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;
|
||||
|
@ -803,7 +803,7 @@ static int lsig_eval(cli_ctx *ctx, struct cli_matcher *root, struct cli_ac_data
|
|||
struct cli_ac_lsig *ac_lsig = root->ac_lsigtable[lsid];
|
||||
char *exp = ac_lsig->u.logic;
|
||||
char *exp_end = exp + strlen(exp);
|
||||
int rc;
|
||||
cl_error_t rc;
|
||||
|
||||
rc = cli_ac_chkmacro(root, acdata, lsid);
|
||||
if (rc != CL_SUCCESS)
|
||||
|
@ -826,7 +826,7 @@ static int lsig_eval(cli_ctx *ctx, struct cli_matcher *root, struct cli_ac_data
|
|||
}
|
||||
|
||||
if (hash && ac_lsig->tdb.handlertype) {
|
||||
if (memcmp(ctx->handlertype_hash, hash, 16)) {
|
||||
if (0 != 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) {
|
||||
|
@ -1038,7 +1038,8 @@ cl_error_t cli_fmap_scandesc(cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, str
|
|||
}
|
||||
|
||||
if (!ftonly) {
|
||||
if ((ret = cli_ac_initdata(&gdata, groot->ac_partsigs, groot->ac_lsigs, groot->ac_reloff_num, CLI_DEFAULT_AC_TRACKLEN)) || (ret = cli_ac_caloff(groot, &gdata, &info))) {
|
||||
if ((ret = cli_ac_initdata(&gdata, groot->ac_partsigs, groot->ac_lsigs, groot->ac_reloff_num, CLI_DEFAULT_AC_TRACKLEN)) ||
|
||||
(ret = cli_ac_caloff(groot, &gdata, &info))) {
|
||||
cli_targetinfo_destroy(&info);
|
||||
cl_hash_destroy(md5ctx);
|
||||
cl_hash_destroy(sha1ctx);
|
||||
|
@ -1056,7 +1057,8 @@ cl_error_t cli_fmap_scandesc(cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, str
|
|||
}
|
||||
|
||||
if (troot) {
|
||||
if ((ret = cli_ac_initdata(&tdata, troot->ac_partsigs, troot->ac_lsigs, troot->ac_reloff_num, CLI_DEFAULT_AC_TRACKLEN)) || (ret = cli_ac_caloff(troot, &tdata, &info))) {
|
||||
if ((ret = cli_ac_initdata(&tdata, troot->ac_partsigs, troot->ac_lsigs, troot->ac_reloff_num, CLI_DEFAULT_AC_TRACKLEN)) ||
|
||||
(ret = cli_ac_caloff(troot, &tdata, &info))) {
|
||||
if (!ftonly) {
|
||||
cli_ac_freedata(&gdata);
|
||||
cli_pcre_freeoff(&gpoff);
|
||||
|
@ -1108,7 +1110,10 @@ cl_error_t cli_fmap_scandesc(cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, str
|
|||
|
||||
if (!ftonly && hdb) {
|
||||
if (!refhash) {
|
||||
if (cli_hm_have_size(hdb, CLI_HASH_MD5, map->len) || cli_hm_have_size(fp, CLI_HASH_MD5, map->len) || cli_hm_have_wild(hdb, CLI_HASH_MD5) || cli_hm_have_wild(fp, CLI_HASH_MD5)) {
|
||||
if (cli_hm_have_size(hdb, CLI_HASH_MD5, map->len) ||
|
||||
cli_hm_have_size(fp, CLI_HASH_MD5, map->len) ||
|
||||
cli_hm_have_wild(hdb, CLI_HASH_MD5) ||
|
||||
cli_hm_have_wild(fp, CLI_HASH_MD5)) {
|
||||
compute_hash[CLI_HASH_MD5] = 1;
|
||||
} else {
|
||||
compute_hash[CLI_HASH_MD5] = 0;
|
||||
|
@ -1118,13 +1123,19 @@ cl_error_t cli_fmap_scandesc(cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, str
|
|||
memcpy(digest[CLI_HASH_MD5], refhash, 16);
|
||||
}
|
||||
|
||||
if (cli_hm_have_size(hdb, CLI_HASH_SHA1, map->len) || cli_hm_have_wild(hdb, CLI_HASH_SHA1) || cli_hm_have_size(fp, CLI_HASH_SHA1, map->len) || cli_hm_have_wild(fp, CLI_HASH_SHA1)) {
|
||||
if (cli_hm_have_size(hdb, CLI_HASH_SHA1, map->len) ||
|
||||
cli_hm_have_wild(hdb, CLI_HASH_SHA1) ||
|
||||
cli_hm_have_size(fp, CLI_HASH_SHA1, map->len) ||
|
||||
cli_hm_have_wild(fp, CLI_HASH_SHA1)) {
|
||||
compute_hash[CLI_HASH_SHA1] = 1;
|
||||
} else {
|
||||
compute_hash[CLI_HASH_SHA1] = 0;
|
||||
}
|
||||
|
||||
if (cli_hm_have_size(hdb, CLI_HASH_SHA256, map->len) || cli_hm_have_wild(hdb, CLI_HASH_SHA256) || cli_hm_have_size(fp, CLI_HASH_SHA256, map->len) || cli_hm_have_wild(fp, CLI_HASH_SHA256)) {
|
||||
if (cli_hm_have_size(hdb, CLI_HASH_SHA256, map->len) ||
|
||||
cli_hm_have_wild(hdb, CLI_HASH_SHA256) ||
|
||||
cli_hm_have_size(fp, CLI_HASH_SHA256, map->len) ||
|
||||
cli_hm_have_wild(fp, CLI_HASH_SHA256)) {
|
||||
compute_hash[CLI_HASH_SHA256] = 1;
|
||||
} else {
|
||||
compute_hash[CLI_HASH_SHA256] = 0;
|
||||
|
|
|
@ -58,17 +58,19 @@ void cli_targetinfo_destroy(struct cli_target_info *info);
|
|||
#define CLI_MATCH_NIBBLE_HIGH 0x0300
|
||||
#define CLI_MATCH_NIBBLE_LOW 0x0400
|
||||
|
||||
#define CLI_TDB_UINT 0
|
||||
#define CLI_TDB_RANGE 1
|
||||
#define CLI_TDB_STR 2
|
||||
#define CLI_TDB_RANGE2 3
|
||||
#define CLI_TDB_FTYPE 4
|
||||
#define CLI_TDB_FTYPE_EXPR 5
|
||||
typedef enum tdb_type {
|
||||
CLI_TDB_UINT,
|
||||
CLI_TDB_RANGE,
|
||||
CLI_TDB_STR,
|
||||
CLI_TDB_RANGE2,
|
||||
CLI_TDB_FTYPE,
|
||||
CLI_TDB_FTYPE_EXPR
|
||||
} tdb_type_t;
|
||||
|
||||
struct cli_lsig_tdb {
|
||||
uint32_t *val, *range;
|
||||
char *str;
|
||||
uint32_t cnt[3];
|
||||
tdb_type_t cnt[3];
|
||||
uint32_t subsigs;
|
||||
|
||||
const uint32_t *target;
|
||||
|
@ -90,14 +92,17 @@ struct cli_lsig_tdb {
|
|||
|
||||
#define CLI_LSIG_FLAG_PRIVATE 0x01
|
||||
|
||||
typedef enum lsig_type {
|
||||
CLI_LSIG_NORMAL,
|
||||
CLI_YARA_NORMAL,
|
||||
CLI_YARA_OFFSET
|
||||
} lsig_type_t;
|
||||
|
||||
struct cli_bc;
|
||||
struct cli_ac_lsig {
|
||||
#define CLI_LSIG_NORMAL 0
|
||||
#define CLI_YARA_NORMAL 1
|
||||
#define CLI_YARA_OFFSET 2
|
||||
uint32_t id;
|
||||
unsigned bc_idx;
|
||||
uint8_t type;
|
||||
lsig_type_t type;
|
||||
uint8_t flag;
|
||||
union {
|
||||
char *logic;
|
||||
|
@ -215,11 +220,74 @@ static const struct cli_mtarget cli_mtargets[CLI_MTARGETS] = {
|
|||
|
||||
// clang-format on
|
||||
|
||||
/**
|
||||
* @brief Non-magic scan matching using a file buffer for input. Older API
|
||||
*
|
||||
* This function is lower-level, requiring a call to `cli_exp_eval()` after the
|
||||
* match to evaluate logical signatures and yara rules.
|
||||
*
|
||||
* This function does not perform file type magic identification and does not use
|
||||
* the file format scanners.
|
||||
*
|
||||
* @param buffer The buffer to be matched.
|
||||
* @param length The length of the buffer or amount of bytets to match.
|
||||
* @param offset Offset into the buffer from which to start matching.
|
||||
* @param ctx The scanning context.
|
||||
* @param ftype If specified, may limit signature matching trie by target type corresponding with the specified CL_TYPE
|
||||
* @param acdata [in/out] A list of pattern maching data structs to contain match results, one for each pattern matching trie.
|
||||
* @return cl_error_t
|
||||
*/
|
||||
cl_error_t cli_scanbuff(const unsigned char *buffer, uint32_t length, uint32_t offset, cli_ctx *ctx, cli_file_t ftype, struct cli_ac_data **acdata);
|
||||
|
||||
cl_error_t cli_scandesc(int desc, cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struct cli_matched_type **ftoffset, unsigned int acmode, struct cli_ac_result **acres);
|
||||
/**
|
||||
* @brief Non-magic scan matching using a file descriptor for input.
|
||||
*
|
||||
* This function does not perform file type magic identification and does not use
|
||||
* the file format scanners.
|
||||
*
|
||||
* This function uses the newer cli_fmap_scandesc() scanning API.
|
||||
*
|
||||
* @param desc File descriptor to be used for input
|
||||
* @param ctx The scanning context.
|
||||
* @param ftype If specified, may limit signature matching trie by target type corresponding with the specified CL_TYPE
|
||||
* @param ftonly Boolean indicating if the scan is for file-type detection only.
|
||||
* @param ftoffset [out] A list of file type signature matches with their corresponding offsets.
|
||||
* @param acmode Use AC_SCAN_VIR and AC_SCAN_FT to set scanning modes.
|
||||
* @param acres [out] A list of cli_ac_result AC pattern matching results.
|
||||
* @param name (optional) Original name of the file (to set fmap name metadata)
|
||||
* @return cl_error_t
|
||||
*/
|
||||
cl_error_t cli_scandesc(int desc, cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struct cli_matched_type **ftoffset, unsigned int acmode, struct cli_ac_result **acres, const char *name);
|
||||
|
||||
/**
|
||||
* @brief Non-magic scan matching of the current fmap in the scan context. Newer API.
|
||||
*
|
||||
* This API will invoke cli_exp_eval() for you.
|
||||
*
|
||||
* @param ctx The scanning context.
|
||||
* @param ftype If specified, may limit signature matching trie by target type corresponding with the specified CL_TYPE
|
||||
* @param ftonly Boolean indicating if the scan is for file-type detection only.
|
||||
* @param ftoffset [out] A list of file type signature matches with their corresponding offsets.
|
||||
* @param acmode Use AC_SCAN_VIR and AC_SCAN_FT to set scanning modes.
|
||||
* @param acres [out] A list of cli_ac_result AC pattern matching results.
|
||||
* @param refhash MD5 hash of the current file, used to save time creating hashes and to limit scan recursion for the HandlerType logical signature FTM feature.
|
||||
* @return cl_error_t
|
||||
*/
|
||||
cl_error_t cli_fmap_scandesc(cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struct cli_matched_type **ftoffset, unsigned int acmode, struct cli_ac_result **acres, unsigned char *refhash);
|
||||
|
||||
/**
|
||||
* @brief Evaluate logical signatures and yara rules given the AC matching results
|
||||
* from cli_scanbuff() / matcher_run().
|
||||
*
|
||||
* @param ctx The scanning context.
|
||||
* @param root The AC trie root to match with.
|
||||
* @param acdata AC match results for a specific AC trie.
|
||||
* @param target_info File metadata used to evaluate logical sig and yara rule options.
|
||||
* @param hash Reference hash of the current file, used to limit recursion for the HandlerType logical signature FTM feature.
|
||||
* @return cl_error_t
|
||||
*/
|
||||
cl_error_t cli_exp_eval(cli_ctx *ctx, struct cli_matcher *root, struct cli_ac_data *acdata, struct cli_target_info *target_info, const char *hash);
|
||||
|
||||
cl_error_t cli_caloff(const char *offstr, const struct cli_target_info *info, unsigned int target, uint32_t *offdata, uint32_t *offset_min, uint32_t *offset_max);
|
||||
|
||||
cl_error_t cli_checkfp(unsigned char *digest, size_t size, cli_ctx *ctx);
|
||||
|
|
|
@ -184,7 +184,7 @@ int cli_scanmbr(cli_ctx *ctx, size_t sectorsize)
|
|||
}
|
||||
|
||||
/* MBR is valid, examine bootstrap code */
|
||||
ret = cli_map_scan(*ctx->fmap, 0, sectorsize, ctx, CL_TYPE_ANY);
|
||||
ret = cli_map_scan(*ctx->fmap, 0, sectorsize, ctx, CL_TYPE_ANY, NULL);
|
||||
if (ret != CL_CLEAN) {
|
||||
if (SCAN_ALLMATCHES && (ret == CL_VIRUS))
|
||||
detection = CL_VIRUS;
|
||||
|
@ -240,7 +240,7 @@ int cli_scanmbr(cli_ctx *ctx, size_t sectorsize)
|
|||
partoff = mbr.entries[i].firstLBA * sectorsize;
|
||||
partsize = mbr.entries[i].numLBA * sectorsize;
|
||||
mbr_parsemsg("cli_map_scan: [%u, +%u)\n", partoff, partsize);
|
||||
ret = cli_map_scan(*ctx->fmap, partoff, partsize, ctx, CL_TYPE_PART_ANY);
|
||||
ret = cli_map_scan(*ctx->fmap, partoff, partsize, ctx, CL_TYPE_PART_ANY, NULL);
|
||||
if (ret != CL_CLEAN) {
|
||||
if (SCAN_ALLMATCHES && (ret == CL_VIRUS))
|
||||
detection = CL_VIRUS;
|
||||
|
@ -381,7 +381,7 @@ static int mbr_scanextprtn(cli_ctx *ctx, unsigned *prtncount, off_t extlba, size
|
|||
return CL_EFORMAT;
|
||||
}
|
||||
|
||||
ret = cli_map_scan(*ctx->fmap, partoff, partsize, ctx, CL_TYPE_PART_ANY);
|
||||
ret = cli_map_scan(*ctx->fmap, partoff, partsize, ctx, CL_TYPE_PART_ANY, NULL);
|
||||
if (ret != CL_CLEAN) {
|
||||
if (SCAN_ALLMATCHES && (ret == CL_VIRUS))
|
||||
detection = CL_VIRUS;
|
||||
|
|
|
@ -57,7 +57,8 @@ ole2_convert_utf(summary_ctx_t *sctx, char *begin, size_t sz, const char *encodi
|
|||
char *buf, *p1, *p2;
|
||||
off_t offset;
|
||||
size_t inlen, outlen, nonrev, sz2;
|
||||
int i, attempt;
|
||||
size_t i;
|
||||
int attempt;
|
||||
iconv_t cd;
|
||||
#else
|
||||
UNUSEDPARAM(encoding);
|
||||
|
@ -705,7 +706,7 @@ static int ole2_summary_propset_json(summary_ctx_t *sctx, off_t offset)
|
|||
off_t foff = offset, psoff = 0;
|
||||
uint32_t poffset;
|
||||
int ret;
|
||||
unsigned int i;
|
||||
uint32_t i;
|
||||
|
||||
cli_dbgmsg("in ole2_summary_propset_json\n");
|
||||
|
||||
|
@ -894,7 +895,7 @@ int cli_ole2_summary_json(cli_ctx *ctx, int fd, int mode)
|
|||
return CL_ESTAT;
|
||||
}
|
||||
|
||||
sctx.sfmap = fmap(fd, 0, statbuf.st_size);
|
||||
sctx.sfmap = fmap(fd, 0, statbuf.st_size, NULL);
|
||||
if (!sctx.sfmap) {
|
||||
cli_dbgmsg("ole2_summary_json: failed to get fmap\n");
|
||||
return CL_EMAP;
|
||||
|
|
|
@ -93,7 +93,7 @@ struct msexp_hdr {
|
|||
return CL_SUCCESS; \
|
||||
w = 0;
|
||||
|
||||
int cli_msexpand(cli_ctx *ctx, int ofd)
|
||||
cl_error_t cli_msexpand(cli_ctx *ctx, int ofd)
|
||||
{
|
||||
const struct msexp_hdr *hdr;
|
||||
uint8_t i, mask, bits;
|
||||
|
|
|
@ -26,6 +26,6 @@
|
|||
|
||||
#include "others.h"
|
||||
|
||||
int cli_msexpand(cli_ctx *ctx, int ofd);
|
||||
cl_error_t cli_msexpand(cli_ctx *ctx, int ofd);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -400,7 +400,7 @@ static int msxml_parse_element(struct msxml_ctx *mxctx, xmlTextReaderPtr reader,
|
|||
|
||||
cli_msxmlmsg("BINARY CALLBACK DATA!\n");
|
||||
|
||||
if ((ret = cli_gentempfd(ctx->engine->tmpdir, &tempfile, &of)) != CL_SUCCESS) {
|
||||
if ((ret = cli_gentempfd(ctx->sub_tmpdir, &tempfile, &of)) != CL_SUCCESS) {
|
||||
cli_warnmsg("msxml_parse_element: failed to create temporary file %s\n", tempfile);
|
||||
return ret;
|
||||
}
|
||||
|
@ -444,7 +444,7 @@ static int msxml_parse_element(struct msxml_ctx *mxctx, xmlTextReaderPtr reader,
|
|||
break;
|
||||
}
|
||||
|
||||
if ((ret = cli_gentempfd(ctx->engine->tmpdir, &tempfile, &of)) != CL_SUCCESS) {
|
||||
if ((ret = cli_gentempfd(ctx->sub_tmpdir, &tempfile, &of)) != CL_SUCCESS) {
|
||||
cli_warnmsg("msxml_parse_element: failed to create temporary file %s\n", tempfile);
|
||||
free(decoded);
|
||||
return ret;
|
||||
|
@ -462,7 +462,7 @@ static int msxml_parse_element(struct msxml_ctx *mxctx, xmlTextReaderPtr reader,
|
|||
|
||||
cli_dbgmsg("msxml_parse_element: extracted binary data to %s\n", tempfile);
|
||||
|
||||
ret = cli_magic_scandesc(of, tempfile, ctx);
|
||||
ret = cli_magic_scandesc(of, tempfile, ctx, NULL);
|
||||
close(of);
|
||||
if (!(ctx->engine->keeptmp))
|
||||
cli_unlink(tempfile);
|
||||
|
|
|
@ -521,7 +521,7 @@ int cli_scannulsft(cli_ctx *ctx, off_t offset)
|
|||
memset(&nsist, 0, sizeof(struct nsis_st));
|
||||
|
||||
nsist.off = offset;
|
||||
if (!(nsist.dir = cli_gentemp(ctx->engine->tmpdir)))
|
||||
if (!(nsist.dir = cli_gentemp(ctx->sub_tmpdir)))
|
||||
return CL_ETMPDIR;
|
||||
if (mkdir(nsist.dir, 0700)) {
|
||||
cli_dbgmsg("NSIS: Can't create temporary directory %s\n", nsist.dir);
|
||||
|
@ -546,9 +546,9 @@ int cli_scannulsft(cli_ctx *ctx, off_t offset)
|
|||
return CL_ESEEK;
|
||||
}
|
||||
if (nsist.fno == 1)
|
||||
ret = cli_scandesc(nsist.ofd, ctx, 0, 0, NULL, AC_SCAN_VIR, NULL);
|
||||
ret = cli_scandesc(nsist.ofd, ctx, 0, 0, NULL, AC_SCAN_VIR, NULL, NULL); /// TODO: Extract file names
|
||||
else
|
||||
ret = cli_magic_scandesc(nsist.ofd, nsist.ofn, ctx);
|
||||
ret = cli_magic_scandesc(nsist.ofd, nsist.ofn, ctx, NULL); /// TODO: Extract file names
|
||||
close(nsist.ofd);
|
||||
if (!ctx->engine->keeptmp)
|
||||
if (cli_unlink(nsist.ofn)) ret = CL_EUNLINK;
|
||||
|
|
|
@ -1326,7 +1326,7 @@ static cl_error_t scan_mso_stream(int fd, cli_ctx *ctx)
|
|||
return CL_ESTAT;
|
||||
}
|
||||
|
||||
input = fmap(fd, 0, statbuf.st_size);
|
||||
input = fmap(fd, 0, statbuf.st_size, NULL);
|
||||
if (!input) {
|
||||
cli_dbgmsg("scan_mso_stream: Failed to get fmap for input stream\n");
|
||||
return CL_EMAP;
|
||||
|
@ -1334,7 +1334,7 @@ static cl_error_t scan_mso_stream(int fd, cli_ctx *ctx)
|
|||
}
|
||||
|
||||
/* reserve tempfile for output and scanning */
|
||||
if ((ret = cli_gentempfd(ctx->engine->tmpdir, &tmpname, &ofd)) != CL_SUCCESS) {
|
||||
if ((ret = cli_gentempfd(ctx->sub_tmpdir, &tmpname, &ofd)) != CL_SUCCESS) {
|
||||
cli_errmsg("scan_mso_stream: Can't generate temporary file\n");
|
||||
funmap(input);
|
||||
return ret;
|
||||
|
@ -1425,7 +1425,7 @@ static cl_error_t scan_mso_stream(int fd, cli_ctx *ctx)
|
|||
}
|
||||
|
||||
/* scanning inflated stream */
|
||||
ret = cli_magic_scandesc(ofd, tmpname, ctx);
|
||||
ret = cli_magic_scandesc(ofd, tmpname, ctx, NULL);
|
||||
|
||||
/* clean-up */
|
||||
mso_end:
|
||||
|
@ -1459,7 +1459,7 @@ handler_otf(ole2_header_t *hdr, property_t *prop, const char *dir, cli_ctx *ctx)
|
|||
}
|
||||
print_ole2_property(prop);
|
||||
|
||||
if (!(tempfile = cli_gentemp(ctx ? ctx->engine->tmpdir : NULL)))
|
||||
if (!(tempfile = cli_gentemp(ctx ? ctx->sub_tmpdir : NULL)))
|
||||
return CL_EMEM;
|
||||
|
||||
if ((ofd = open(tempfile, O_RDWR | O_CREAT | O_TRUNC | O_BINARY, S_IRWXU)) < 0) {
|
||||
|
@ -1627,7 +1627,7 @@ handler_otf(ole2_header_t *hdr, property_t *prop, const char *dir, cli_ctx *ctx)
|
|||
ret = scan_mso_stream(ofd, ctx);
|
||||
} else {
|
||||
/* Normal File Scan */
|
||||
ret = cli_magic_scandesc(ofd, tempfile, ctx);
|
||||
ret = cli_magic_scandesc(ofd, tempfile, ctx, NULL);
|
||||
}
|
||||
if (name)
|
||||
free(name);
|
||||
|
|
|
@ -106,7 +106,7 @@ static size_t num_ooxml_hwp_keys = sizeof(ooxml_hwp_keys) / sizeof(struct key_en
|
|||
|
||||
// clang-format on
|
||||
|
||||
static int ooxml_updatelimits(int fd, cli_ctx *ctx)
|
||||
static cl_error_t ooxml_updatelimits(int fd, cli_ctx *ctx)
|
||||
{
|
||||
STATBUF sb;
|
||||
if (FSTAT(fd, &sb) == -1) {
|
||||
|
@ -117,9 +117,9 @@ static int ooxml_updatelimits(int fd, cli_ctx *ctx)
|
|||
return cli_updatelimits(ctx, sb.st_size);
|
||||
}
|
||||
|
||||
static int ooxml_parse_document(int fd, cli_ctx *ctx)
|
||||
static cl_error_t ooxml_parse_document(int fd, cli_ctx *ctx)
|
||||
{
|
||||
int ret = CL_SUCCESS;
|
||||
cl_error_t ret = CL_SUCCESS;
|
||||
xmlTextReaderPtr reader = NULL;
|
||||
|
||||
cli_dbgmsg("in ooxml_parse_document\n");
|
||||
|
@ -145,11 +145,12 @@ static int ooxml_parse_document(int fd, cli_ctx *ctx)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int ooxml_core_cb(int fd, const char *filepath, cli_ctx *ctx)
|
||||
static cl_error_t ooxml_core_cb(int fd, const char *filepath, cli_ctx *ctx, const char *name)
|
||||
{
|
||||
int ret;
|
||||
cl_error_t ret;
|
||||
|
||||
UNUSEDPARAM(filepath);
|
||||
UNUSEDPARAM(name);
|
||||
|
||||
cli_dbgmsg("in ooxml_core_cb\n");
|
||||
ret = ooxml_parse_document(fd, ctx);
|
||||
|
@ -161,11 +162,12 @@ static int ooxml_core_cb(int fd, const char *filepath, cli_ctx *ctx)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int ooxml_extn_cb(int fd, const char *filepath, cli_ctx *ctx)
|
||||
static cl_error_t ooxml_extn_cb(int fd, const char *filepath, cli_ctx *ctx, const char *name)
|
||||
{
|
||||
int ret;
|
||||
cl_error_t ret;
|
||||
|
||||
UNUSEDPARAM(filepath);
|
||||
UNUSEDPARAM(name);
|
||||
|
||||
cli_dbgmsg("in ooxml_extn_cb\n");
|
||||
ret = ooxml_parse_document(fd, ctx);
|
||||
|
@ -177,16 +179,18 @@ static int ooxml_extn_cb(int fd, const char *filepath, cli_ctx *ctx)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int ooxml_content_cb(int fd, const char *filepath, cli_ctx *ctx)
|
||||
static cl_error_t ooxml_content_cb(int fd, const char *filepath, cli_ctx *ctx, const char *name)
|
||||
{
|
||||
int ret = CL_SUCCESS, tmp, toval = 0, state;
|
||||
cl_error_t ret = CL_SUCCESS;
|
||||
int tmp, toval = 0, state;
|
||||
int core = 0, extn = 0, cust = 0, dsig = 0;
|
||||
int mcore = 0, mextn = 0, mcust = 0;
|
||||
const xmlChar *name, *value, *CT, *PN;
|
||||
const xmlChar *localname, *value, *CT, *PN;
|
||||
xmlTextReaderPtr reader = NULL;
|
||||
uint32_t loff;
|
||||
|
||||
UNUSEDPARAM(filepath);
|
||||
UNUSEDPARAM(name);
|
||||
|
||||
unsigned long sav_scansize = ctx->scansize;
|
||||
unsigned int sav_scannedfiles = ctx->scannedfiles;
|
||||
|
@ -218,26 +222,26 @@ static int ooxml_content_cb(int fd, const char *filepath, cli_ctx *ctx)
|
|||
goto ooxml_content_exit;
|
||||
}
|
||||
|
||||
name = xmlTextReaderConstLocalName(reader);
|
||||
if (name == NULL) continue;
|
||||
localname = xmlTextReaderConstLocalName(reader);
|
||||
if (localname == NULL) continue;
|
||||
|
||||
if (strcmp((const char *)name, "Override")) continue;
|
||||
if (strcmp((const char *)localname, "Override")) continue;
|
||||
|
||||
if (xmlTextReaderHasAttributes(reader) != 1) continue;
|
||||
|
||||
CT = PN = NULL;
|
||||
while (xmlTextReaderMoveToNextAttribute(reader) == 1) {
|
||||
name = xmlTextReaderConstLocalName(reader);
|
||||
localname = xmlTextReaderConstLocalName(reader);
|
||||
value = xmlTextReaderConstValue(reader);
|
||||
if (name == NULL || value == NULL) continue;
|
||||
if (localname == NULL || value == NULL) continue;
|
||||
|
||||
if (!xmlStrcmp(name, (const xmlChar *)"ContentType")) {
|
||||
if (!xmlStrcmp(localname, (const xmlChar *)"ContentType")) {
|
||||
CT = value;
|
||||
} else if (!xmlStrcmp(name, (const xmlChar *)"PartName")) {
|
||||
} else if (!xmlStrcmp(localname, (const xmlChar *)"PartName")) {
|
||||
PN = value;
|
||||
}
|
||||
|
||||
cli_dbgmsg("%s: %s\n", name, value);
|
||||
cli_dbgmsg("%s: %s\n", localname, value);
|
||||
}
|
||||
|
||||
if (!CT && !PN) continue;
|
||||
|
@ -346,12 +350,13 @@ ooxml_content_exit:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int ooxml_hwp_cb(int fd, const char *filepath, cli_ctx *ctx)
|
||||
static cl_error_t ooxml_hwp_cb(int fd, const char *filepath, cli_ctx *ctx, const char *name)
|
||||
{
|
||||
int ret = CL_SUCCESS;
|
||||
cl_error_t ret = CL_SUCCESS;
|
||||
xmlTextReaderPtr reader = NULL;
|
||||
|
||||
UNUSEDPARAM(filepath);
|
||||
UNUSEDPARAM(name);
|
||||
|
||||
cli_dbgmsg("in ooxml_hwp_cb\n");
|
||||
|
||||
|
@ -378,24 +383,24 @@ static int ooxml_hwp_cb(int fd, const char *filepath, cli_ctx *ctx)
|
|||
|
||||
#endif /* HAVE_LIBXML2 && HAVE_JSON */
|
||||
|
||||
int cli_ooxml_filetype(cli_ctx *ctx, fmap_t *map)
|
||||
cli_file_t cli_ooxml_filetype(cli_ctx *ctx, fmap_t *map)
|
||||
{
|
||||
struct zip_requests requests;
|
||||
int ret;
|
||||
cl_error_t ret;
|
||||
|
||||
memset(&requests, 0, sizeof(struct zip_requests));
|
||||
|
||||
if ((ret = unzip_search_add(&requests, "xl/", 3)) != CL_SUCCESS) {
|
||||
return CL_SUCCESS;
|
||||
return CL_TYPE_ANY;
|
||||
}
|
||||
if ((ret = unzip_search_add(&requests, "ppt/", 4)) != CL_SUCCESS) {
|
||||
return CL_SUCCESS;
|
||||
return CL_TYPE_ANY;
|
||||
}
|
||||
if ((ret = unzip_search_add(&requests, "word/", 5)) != CL_SUCCESS) {
|
||||
return CL_SUCCESS;
|
||||
return CL_TYPE_ANY;
|
||||
}
|
||||
if ((ret = unzip_search_add(&requests, "Contents/content.hpf", 22)) != CL_SUCCESS) {
|
||||
return CL_SUCCESS;
|
||||
return CL_TYPE_ANY;
|
||||
}
|
||||
|
||||
if ((ret = unzip_search(ctx, map, &requests)) == CL_VIRUS) {
|
||||
|
@ -409,18 +414,18 @@ int cli_ooxml_filetype(cli_ctx *ctx, fmap_t *map)
|
|||
case 3:
|
||||
return CL_TYPE_OOXML_HWP;
|
||||
default:
|
||||
return CL_SUCCESS;
|
||||
return CL_TYPE_ANY;
|
||||
}
|
||||
}
|
||||
|
||||
return CL_SUCCESS;
|
||||
return CL_TYPE_ANY;
|
||||
}
|
||||
|
||||
int cli_process_ooxml(cli_ctx *ctx, int type)
|
||||
cl_error_t cli_process_ooxml(cli_ctx *ctx, int type)
|
||||
{
|
||||
#if HAVE_LIBXML2 && HAVE_JSON
|
||||
uint32_t loff = 0;
|
||||
int ret = CL_SUCCESS;
|
||||
cl_error_t ret = CL_SUCCESS;
|
||||
|
||||
cli_dbgmsg("in cli_process_ooxml\n");
|
||||
if (!ctx) {
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
|
||||
#include "others.h"
|
||||
|
||||
int cli_ooxml_filetype(cli_ctx *, fmap_t *);
|
||||
int cli_process_ooxml(cli_ctx *, int);
|
||||
cli_file_t cli_ooxml_filetype(cli_ctx *, fmap_t *);
|
||||
cl_error_t cli_process_ooxml(cli_ctx *, int);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -150,8 +150,9 @@ typedef struct cli_ctx_container_tag {
|
|||
|
||||
/* internal clamav context */
|
||||
typedef struct cli_ctx_tag {
|
||||
char *target_filepath;
|
||||
const char *sub_filepath;
|
||||
char *target_filepath; /**< (optional) The filepath of the original scan target */
|
||||
const char *sub_filepath; /**< (optional) The filepath of the current file being parsed. May be a temp file. */
|
||||
char *sub_tmpdir; /**< The directory to store tmp files at this recursion depth. */
|
||||
const char **virname;
|
||||
unsigned int num_viruses;
|
||||
unsigned long int *scanned;
|
||||
|
|
|
@ -1024,7 +1024,6 @@ char *cli_newfilepath(const char *dir, const char *fname)
|
|||
{
|
||||
char *fullpath;
|
||||
const char *mdir;
|
||||
int i;
|
||||
size_t len;
|
||||
|
||||
mdir = dir ? dir : cli_gettmpdir();
|
||||
|
@ -1037,7 +1036,6 @@ char *cli_newfilepath(const char *dir, const char *fname)
|
|||
len = strlen(mdir) + strlen(PATHSEP) + strlen(fname) + 1; /* mdir/fname\0 */
|
||||
fullpath = (char *)cli_calloc(len, sizeof(char));
|
||||
if (!fullpath) {
|
||||
free(fname);
|
||||
cli_dbgmsg("cli_newfilepath('%s'): out of memory\n", mdir);
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -1060,7 +1060,7 @@ static int run_pdf_hooks(struct pdf_struct *pdf, enum pdf_phase phase, int fd, i
|
|||
|
||||
map = *ctx->fmap;
|
||||
if (fd != -1) {
|
||||
map = fmap(fd, 0, 0);
|
||||
map = fmap(fd, 0, 0, NULL);
|
||||
if (!map) {
|
||||
cli_dbgmsg("run_pdf_hooks: can't mmap pdf extracted obj\n");
|
||||
map = *ctx->fmap;
|
||||
|
@ -1412,7 +1412,7 @@ static int pdf_scan_contents(int fd, struct pdf_struct *pdf)
|
|||
cli_writen(fout, s.out, s.out_pos);
|
||||
|
||||
lseek(fout, 0, SEEK_SET);
|
||||
rc = cli_magic_scandesc(fout, fullname, pdf->ctx);
|
||||
rc = cli_magic_scandesc(fout, fullname, pdf->ctx, NULL);
|
||||
close(fout);
|
||||
|
||||
if (!pdf->ctx->engine->keeptmp)
|
||||
|
@ -1422,7 +1422,7 @@ static int pdf_scan_contents(int fd, struct pdf_struct *pdf)
|
|||
return rc;
|
||||
}
|
||||
|
||||
int pdf_extract_obj(struct pdf_struct *pdf, struct pdf_obj *obj, uint32_t flags)
|
||||
cl_error_t pdf_extract_obj(struct pdf_struct *pdf, struct pdf_obj *obj, uint32_t flags)
|
||||
{
|
||||
cli_ctx *ctx = pdf->ctx;
|
||||
char fullname[NAME_MAX + 1];
|
||||
|
@ -1801,7 +1801,7 @@ done:
|
|||
|
||||
/* TODO: invoke bytecode on this pdf obj with metainformation associated */
|
||||
lseek(fout, 0, SEEK_SET);
|
||||
rc2 = cli_magic_scandesc(fout, fullname, pdf->ctx);
|
||||
rc2 = cli_magic_scandesc(fout, fullname, pdf->ctx, NULL);
|
||||
if (rc2 == CL_VIRUS || rc == CL_SUCCESS)
|
||||
rc = rc2;
|
||||
|
||||
|
@ -3424,7 +3424,7 @@ done:
|
|||
*
|
||||
* @return int Returns cl_error_t status value.
|
||||
*/
|
||||
int cli_pdf(const char *dir, cli_ctx *ctx, off_t offset)
|
||||
cl_error_t cli_pdf(const char *dir, cli_ctx *ctx, off_t offset)
|
||||
{
|
||||
cl_error_t rc = CL_SUCCESS;
|
||||
struct pdf_struct pdf;
|
||||
|
|
|
@ -175,9 +175,9 @@ struct pdf_struct {
|
|||
#define PDF_EXTRACT_OBJ_NONE 0x0
|
||||
#define PDF_EXTRACT_OBJ_SCAN 0x1
|
||||
|
||||
int cli_pdf(const char *dir, cli_ctx *ctx, off_t offset);
|
||||
cl_error_t cli_pdf(const char *dir, cli_ctx *ctx, off_t offset);
|
||||
void pdf_parseobj(struct pdf_struct *pdf, struct pdf_obj *obj);
|
||||
int pdf_extract_obj(struct pdf_struct *pdf, struct pdf_obj *obj, uint32_t flags);
|
||||
cl_error_t pdf_extract_obj(struct pdf_struct *pdf, struct pdf_obj *obj, uint32_t flags);
|
||||
cl_error_t pdf_findobj(struct pdf_struct *pdf);
|
||||
struct pdf_obj *find_obj(struct pdf_struct *pdf, struct pdf_obj *obj, uint32_t objid);
|
||||
|
||||
|
|
|
@ -126,7 +126,7 @@
|
|||
}
|
||||
|
||||
#define CLI_UNPTEMP(NAME, FREEME) \
|
||||
if (!(tempfile = cli_gentemp(ctx->engine->tmpdir))) { \
|
||||
if (!(tempfile = cli_gentemp(ctx->sub_tmpdir))) { \
|
||||
cli_exe_info_destroy(peinfo); \
|
||||
cli_multifree FREEME; \
|
||||
return CL_EMEM; \
|
||||
|
@ -206,7 +206,7 @@
|
|||
lseek(ndesc, 0, SEEK_SET); \
|
||||
cli_dbgmsg("***** Scanning rebuilt PE file *****\n"); \
|
||||
SHA_OFF; \
|
||||
if (cli_magic_scandesc(ndesc, tempfile, ctx) == CL_VIRUS) { \
|
||||
if (cli_magic_scandesc(ndesc, tempfile, ctx, NULL) == CL_VIRUS) { \
|
||||
close(ndesc); \
|
||||
SHA_RESET; \
|
||||
CLI_TMPUNLK(); \
|
||||
|
@ -3979,7 +3979,7 @@ int cli_scanpe(cli_ctx *ctx)
|
|||
|
||||
cli_dbgmsg("***** Scanning decompressed file *****\n");
|
||||
SHA_OFF;
|
||||
if ((ret = cli_magic_scandesc(ndesc, tempfile, ctx)) == CL_VIRUS) {
|
||||
if ((ret = cli_magic_scandesc(ndesc, tempfile, ctx, NULL)) == CL_VIRUS) {
|
||||
close(ndesc);
|
||||
SHA_RESET;
|
||||
CLI_TMPUNLK();
|
||||
|
|
|
@ -1369,7 +1369,7 @@ static int parseicon(struct ICON_ENV *icon_env, uint32_t rva)
|
|||
if (!ctx || !ctx->engine || !(matcher = ctx->engine->iconcheck))
|
||||
return CL_SUCCESS;
|
||||
map = *ctx->fmap;
|
||||
tempd = (cli_debug_flag && ctx->engine->keeptmp) ? (ctx->engine->tmpdir ? ctx->engine->tmpdir : cli_gettmpdir()) : NULL;
|
||||
tempd = (cli_debug_flag && ctx->engine->keeptmp) ? (ctx->sub_tmpdir ? ctx->sub_tmpdir : cli_gettmpdir()) : NULL;
|
||||
icoff = cli_rawaddr(rva, peinfo->sections, peinfo->nsections, &err, map->len, peinfo->hdr_size);
|
||||
|
||||
/* read the bitmap header */
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
|
||||
#define BUFFER_SIZE 128000 /* size of read block */
|
||||
|
||||
int cli_parsepng(cli_ctx *ctx)
|
||||
cl_error_t cli_parsepng(cli_ctx *ctx)
|
||||
{
|
||||
uint64_t sz = 0;
|
||||
char chunkid[5] = {'\0', '\0', '\0', '\0', '\0'};
|
||||
|
|
|
@ -22,6 +22,6 @@
|
|||
|
||||
#include "others.h"
|
||||
|
||||
int cli_parsepng(cli_ctx *ctx);
|
||||
cl_error_t cli_parsepng(cli_ctx *ctx);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -3125,13 +3125,15 @@ static int cli_loadmscat(FILE *fs, const char *dbname, struct cl_engine *engine,
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (!(map = fmap(fileno(fs), 0, 0))) {
|
||||
if (!(map = fmap(fileno(fs), 0, 0, dbname))) {
|
||||
cli_dbgmsg("Can't map cat: %s\n", dbname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (asn1_load_mscat(map, engine))
|
||||
if (asn1_load_mscat(map, engine)) {
|
||||
cli_dbgmsg("Failed to load certificates from cat: %s\n", dbname);
|
||||
}
|
||||
|
||||
funmap(map);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -246,7 +246,7 @@ static int decode_and_scan(struct rtf_object_data* data, cli_ctx* ctx)
|
|||
cli_dbgmsg("Decoding ole object\n");
|
||||
ret = cli_scan_ole10(data->fd, ctx);
|
||||
} else if (data->fd > 0)
|
||||
ret = cli_magic_scandesc(data->fd, data->name, ctx);
|
||||
ret = cli_magic_scandesc(data->fd, data->name, ctx, NULL);
|
||||
if (data->fd > 0)
|
||||
close(data->fd);
|
||||
data->fd = -1;
|
||||
|
@ -526,7 +526,7 @@ int cli_scanrtf(cli_ctx* ctx)
|
|||
return CL_EMEM;
|
||||
}
|
||||
|
||||
if (!(tempname = cli_gentemp(ctx->engine->tmpdir)))
|
||||
if (!(tempname = cli_gentemp(ctx->sub_tmpdir)))
|
||||
return CL_EMEM;
|
||||
|
||||
if (mkdir(tempname, 0700)) {
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -27,54 +27,72 @@
|
|||
#include "filetypes.h"
|
||||
|
||||
/**
|
||||
* @brief Scan a tempfile / sub-file of _any_ type, passing in the fd, filepath (if available), and the scanning context.
|
||||
* @brief Perform a magic scan of a file given a file descriptor.
|
||||
*
|
||||
* This API allows you to specify the file type in advance if you know it.
|
||||
*
|
||||
* @param desc File descriptor
|
||||
* @param filepath (optional) Full file path.
|
||||
* @param ctx Scanning context structure.
|
||||
* @return int CL_SUCCESS, or an error code.
|
||||
* @param type CL_TYPE of data to be scanned.
|
||||
* @param name (optional) Original name of the file (to set fmap name metadata)
|
||||
* @return cl_error_t
|
||||
*/
|
||||
int cli_magic_scandesc(int desc, const char *filepath, cli_ctx *ctx);
|
||||
cl_error_t cli_base_scandesc(int desc, const char *filepath, cli_ctx *ctx, cli_file_t type, const char *name);
|
||||
|
||||
/**
|
||||
* @brief Like cli_magic_scandesc(), but where the file type is known to be a partition.
|
||||
* @brief Scan a tempfile / sub-file of _any_ type, passing in the fd, filepath (if available), and the scanning context.
|
||||
*
|
||||
* @param desc File descriptor
|
||||
* @param filepath (optional) Full file path.
|
||||
* @param ctx Scanning context structure.
|
||||
* @param name (optional) Original name of the file (to set fmap name metadata)
|
||||
* @return int CL_SUCCESS, or an error code.
|
||||
*/
|
||||
int cli_partition_scandesc(int desc, const char *filepath, cli_ctx *ctx);
|
||||
cl_error_t cli_magic_scandesc(int desc, const char *filepath, cli_ctx *ctx, const char *name);
|
||||
|
||||
int cli_magic_scandesc_type(cli_ctx *ctx, cli_file_t type);
|
||||
/**
|
||||
* @brief Shim to make magic_scandesc callable outside of scanners.c.
|
||||
*
|
||||
* @param ctx Scanning context structure.
|
||||
* @param type CL_TYPE of data to be scanned.
|
||||
* @return int CL_SUCCESS, or an error code.
|
||||
*/
|
||||
cl_error_t cli_magic_scandesc_type(cli_ctx *ctx, cli_file_t type);
|
||||
|
||||
/**
|
||||
* @brief Scan an offset/length into a file map.
|
||||
*
|
||||
* For map scans that are not forced to disk.
|
||||
* Magic-scan some portion of an existing fmap.
|
||||
*
|
||||
* @param map File map.
|
||||
* @param offset Offset into file map.
|
||||
* @param length Length from offset.
|
||||
* @param ctx Scanning context structure.
|
||||
* @param type CL_TYPE of data to be scanned.
|
||||
* @param name (optional) Original name of the file (to set fmap name metadata)
|
||||
* @return int CL_SUCCESS, or an error code.
|
||||
*/
|
||||
int cli_map_scandesc(cl_fmap_t *map, off_t offset, size_t length, cli_ctx *ctx, cli_file_t type);
|
||||
cl_error_t cli_map_scandesc(cl_fmap_t *map, off_t offset, size_t length, cli_ctx *ctx, cli_file_t type, const char *name);
|
||||
|
||||
/**
|
||||
* @brief Scan an offset/length into a file map.
|
||||
*
|
||||
* Like cli_man_scandesc(), but for map scans that may be forced to disk.
|
||||
* Useful for scanning files or other type-able data embedded plainly in an existing fmap.
|
||||
*
|
||||
* Makes use of cli_map_scandesc() for map scans when not forced to disk,
|
||||
* or if force-to-disk IS enabled, it will write the file to a temp file and then
|
||||
* will scan with cli_base_scandesc().
|
||||
*
|
||||
* @param map File map.
|
||||
* @param offset Offset into file map.
|
||||
* @param length Length from offset.
|
||||
* @param ctx Scanning context structure.
|
||||
* @param type CL_TYPE of data to be scanned.
|
||||
* @param name (optional) Original name of the file (to set fmap name metadata)
|
||||
* @return int CL_SUCCESS, or an error code.
|
||||
*/
|
||||
int cli_map_scan(cl_fmap_t *map, off_t offset, size_t length, cli_ctx *ctx, cli_file_t type);
|
||||
cl_error_t cli_map_scan(cl_fmap_t *map, off_t offset, size_t length, cli_ctx *ctx, cli_file_t type, const char *name);
|
||||
|
||||
/**
|
||||
* @brief Convenience wrapper for cli_map_scan().
|
||||
|
@ -84,10 +102,23 @@ int cli_map_scan(cl_fmap_t *map, off_t offset, size_t length, cli_ctx *ctx, cli_
|
|||
* @param buffer Pointer to the buffer to be scanned.
|
||||
* @param length Size in bytes of the buffer being scanned.
|
||||
* @param ctx Scanning context structure.
|
||||
* @param name (optional) Original name of the file (to set fmap name metadata)
|
||||
* @return int CL_SUCCESS, or an error code.
|
||||
*/
|
||||
int cli_mem_scandesc(const void *buffer, size_t length, cli_ctx *ctx);
|
||||
cl_error_t cli_mem_scandesc(const void *buffer, size_t length, cli_ctx *ctx, const char *name);
|
||||
|
||||
int cli_found_possibly_unwanted(cli_ctx *ctx);
|
||||
cl_error_t cli_found_possibly_unwanted(cli_ctx *ctx);
|
||||
|
||||
/**
|
||||
* @brief Internal-use version of cl_scanfile.
|
||||
*
|
||||
* This function will do a magic scan of an extracted file, given the file path.
|
||||
*
|
||||
* @param filename Filepath of the file to be scanned.
|
||||
* @param ctx Scanning context structure.
|
||||
* @param original_name (optional) Original name of the file (to set fmap name metadata)
|
||||
* @return cl_error_t
|
||||
*/
|
||||
cl_error_t cli_scanfile(const char *filename, cli_ctx *ctx, const char *original_name);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -64,7 +64,7 @@ int cli_scansis(cli_ctx *ctx)
|
|||
|
||||
cli_dbgmsg("in scansis()\n");
|
||||
|
||||
if (!(tmpd = cli_gentemp(ctx->engine->tmpdir)))
|
||||
if (!(tmpd = cli_gentemp(ctx->sub_tmpdir)))
|
||||
return CL_ETMPDIR;
|
||||
if (mkdir(tmpd, 0700)) {
|
||||
cli_dbgmsg("SIS: Can't create temporary directory %s\n", tmpd);
|
||||
|
@ -496,7 +496,7 @@ static int real_scansis(cli_ctx *ctx, const char *tmpd)
|
|||
return CL_EWRITE;
|
||||
}
|
||||
free(decomp);
|
||||
if (cli_magic_scandesc(fd, ofn, ctx) == CL_VIRUS) {
|
||||
if (cli_magic_scandesc(fd, ofn, ctx, NULL) == CL_VIRUS) {
|
||||
close(fd);
|
||||
FREE(ptrs);
|
||||
free(alangs);
|
||||
|
@ -805,7 +805,7 @@ static int real_scansis9x(cli_ctx *ctx, const char *tmpd)
|
|||
break;
|
||||
}
|
||||
free(dst);
|
||||
if (cli_magic_scandesc(fd, tempf, ctx) == CL_VIRUS) {
|
||||
if (cli_magic_scandesc(fd, tempf, ctx, NULL) == CL_VIRUS) {
|
||||
close(fd);
|
||||
return CL_VIRUS;
|
||||
}
|
||||
|
|
|
@ -133,7 +133,7 @@ static int scanzws(cli_ctx *ctx, struct swf_file_hdr *hdr)
|
|||
char *tmpname;
|
||||
int fd;
|
||||
|
||||
if ((ret = cli_gentempfd(ctx->engine->tmpdir, &tmpname, &fd)) != CL_SUCCESS) {
|
||||
if ((ret = cli_gentempfd(ctx->sub_tmpdir, &tmpname, &fd)) != CL_SUCCESS) {
|
||||
cli_errmsg("scanzws: Can't generate temporary file\n");
|
||||
return ret;
|
||||
}
|
||||
|
@ -286,7 +286,7 @@ static int scanzws(cli_ctx *ctx, struct swf_file_hdr *hdr)
|
|||
hdr->filesize, (long long unsigned)outsize);
|
||||
}
|
||||
|
||||
ret = cli_magic_scandesc(fd, tmpname, ctx);
|
||||
ret = cli_magic_scandesc(fd, tmpname, ctx, NULL);
|
||||
|
||||
close(fd);
|
||||
if (!(ctx->engine->keeptmp)) {
|
||||
|
@ -310,7 +310,7 @@ static int scancws(cli_ctx *ctx, struct swf_file_hdr *hdr)
|
|||
char *tmpname;
|
||||
int fd;
|
||||
|
||||
if ((ret = cli_gentempfd(ctx->engine->tmpdir, &tmpname, &fd)) != CL_SUCCESS) {
|
||||
if ((ret = cli_gentempfd(ctx->sub_tmpdir, &tmpname, &fd)) != CL_SUCCESS) {
|
||||
cli_errmsg("scancws: Can't generate temporary file\n");
|
||||
return ret;
|
||||
}
|
||||
|
@ -419,7 +419,7 @@ static int scancws(cli_ctx *ctx, struct swf_file_hdr *hdr)
|
|||
hdr->filesize, outsize);
|
||||
}
|
||||
|
||||
ret = cli_magic_scandesc(fd, tmpname, ctx);
|
||||
ret = cli_magic_scandesc(fd, tmpname, ctx, NULL);
|
||||
|
||||
close(fd);
|
||||
if (!ctx->engine->keeptmp) {
|
||||
|
|
|
@ -35,7 +35,7 @@ struct tiff_ifd {
|
|||
uint32_t value;
|
||||
};
|
||||
|
||||
int cli_parsetiff(cli_ctx *ctx)
|
||||
cl_error_t cli_parsetiff(cli_ctx *ctx)
|
||||
{
|
||||
fmap_t *map = *ctx->fmap;
|
||||
unsigned char magic[4];
|
||||
|
|
|
@ -23,6 +23,6 @@
|
|||
|
||||
#include "others.h"
|
||||
|
||||
int cli_parsetiff(cli_ctx *ctx);
|
||||
cl_error_t cli_parsetiff(cli_ctx *ctx);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -159,7 +159,7 @@ int cli_tnef(const char *dir, cli_ctx *ctx)
|
|||
*/
|
||||
if (cli_debug_flag) {
|
||||
int fout = -1;
|
||||
char *filename = cli_gentemp(ctx->engine->tmpdir);
|
||||
char *filename = cli_gentemp(ctx->sub_tmpdir);
|
||||
char buffer[BUFSIZ];
|
||||
|
||||
if (filename)
|
||||
|
|
|
@ -134,6 +134,7 @@ cl_error_t cli_untar(const char *dir, unsigned int posix, cli_ctx *ctx)
|
|||
int limitnear = 0;
|
||||
unsigned int files = 0;
|
||||
char fullname[NAME_MAX + 1];
|
||||
char name[101];
|
||||
size_t pos = 0;
|
||||
size_t currsize = 0;
|
||||
char zero[BLOCKSIZE];
|
||||
|
@ -167,12 +168,12 @@ cl_error_t cli_untar(const char *dir, unsigned int posix, cli_ctx *ctx)
|
|||
char type;
|
||||
int directory, skipEntry = 0;
|
||||
int checksum = -1;
|
||||
char magic[7], name[101], osize[TARSIZELEN + 1];
|
||||
char magic[7], osize[TARSIZELEN + 1];
|
||||
currsize = 0;
|
||||
|
||||
if (fout >= 0) {
|
||||
lseek(fout, 0, SEEK_SET);
|
||||
ret = cli_magic_scandesc(fout, fullname, ctx);
|
||||
ret = cli_magic_scandesc(fout, fullname, ctx, name);
|
||||
close(fout);
|
||||
if (!ctx->engine->keeptmp)
|
||||
if (cli_unlink(fullname)) return CL_EUNLINK;
|
||||
|
@ -367,7 +368,7 @@ cl_error_t cli_untar(const char *dir, unsigned int posix, cli_ctx *ctx)
|
|||
}
|
||||
if (fout >= 0) {
|
||||
lseek(fout, 0, SEEK_SET);
|
||||
ret = cli_magic_scandesc(fout, fullname, ctx);
|
||||
ret = cli_magic_scandesc(fout, fullname, ctx, name);
|
||||
close(fout);
|
||||
if (!ctx->engine->keeptmp)
|
||||
if (cli_unlink(fullname)) return CL_EUNLINK;
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
#include "matcher.h"
|
||||
#include "fmap.h"
|
||||
#include "json_api.h"
|
||||
#include "str.h"
|
||||
|
||||
#define UNZIP_PRIVATE
|
||||
#include "unzip.h"
|
||||
|
@ -78,6 +79,7 @@ struct zip_record {
|
|||
uint16_t method;
|
||||
uint16_t flags;
|
||||
int encrypted;
|
||||
char *original_filename;
|
||||
};
|
||||
|
||||
static int wrap_inflateinit2(void *a, int b)
|
||||
|
@ -108,23 +110,31 @@ static cl_error_t unz(
|
|||
unsigned int *num_files_unzipped,
|
||||
cli_ctx *ctx,
|
||||
char *tmpd,
|
||||
zip_cb zcb)
|
||||
zip_cb zcb,
|
||||
const char *original_filename)
|
||||
{
|
||||
char name[1024], obuf[BUFSIZ];
|
||||
char *tempfile = name;
|
||||
char obuf[BUFSIZ];
|
||||
char *tempfile = NULL;
|
||||
int out_file, ret = CL_CLEAN;
|
||||
int res = 1;
|
||||
size_t written = 0;
|
||||
|
||||
if (tmpd) {
|
||||
snprintf(name, sizeof(name), "%s" PATHSEP "zip.%03u", tmpd, *num_files_unzipped);
|
||||
name[sizeof(name) - 1] = '\0';
|
||||
if (ctx->engine->keeptmp && (NULL != original_filename)) {
|
||||
if (!(tempfile = cli_gentemp_with_prefix(tmpd, original_filename))) return CL_EMEM;
|
||||
} else {
|
||||
if (!(tempfile = cli_gentemp(tmpd))) return CL_EMEM;
|
||||
}
|
||||
} else {
|
||||
if (!(tempfile = cli_gentemp(ctx->engine->tmpdir))) return CL_EMEM;
|
||||
if (ctx->engine->keeptmp && (NULL != original_filename)) {
|
||||
if (!(tempfile = cli_gentemp_with_prefix(ctx->sub_tmpdir, original_filename))) return CL_EMEM;
|
||||
} else {
|
||||
if (!(tempfile = cli_gentemp(ctx->sub_tmpdir))) return CL_EMEM;
|
||||
}
|
||||
}
|
||||
if ((out_file = open(tempfile, O_RDWR | O_CREAT | O_TRUNC | O_BINARY, S_IRUSR | S_IWUSR)) == -1) {
|
||||
cli_warnmsg("cli_unzip: failed to create temporary file %s\n", tempfile);
|
||||
if (!tmpd) free(tempfile);
|
||||
free(tempfile);
|
||||
return CL_ETMPFILE;
|
||||
}
|
||||
switch (method) {
|
||||
|
@ -132,7 +142,7 @@ static cl_error_t unz(
|
|||
if (csize < usize) {
|
||||
unsigned int fake = *num_files_unzipped + 1;
|
||||
cli_dbgmsg("cli_unzip: attempting to inflate stored file with inconsistent size\n");
|
||||
if ((ret = unz(src, csize, usize, ALG_DEFLATE, 0, &fake, ctx, tmpd, zcb)) == CL_CLEAN) {
|
||||
if ((ret = unz(src, csize, usize, ALG_DEFLATE, 0, &fake, ctx, tmpd, zcb, original_filename)) == CL_CLEAN) {
|
||||
(*num_files_unzipped)++;
|
||||
res = fake - (*num_files_unzipped);
|
||||
} else
|
||||
|
@ -336,23 +346,22 @@ static cl_error_t unz(
|
|||
cli_dbgmsg("cli_unzip: extracted to %s\n", tempfile);
|
||||
if (lseek(out_file, 0, SEEK_SET) == -1) {
|
||||
cli_dbgmsg("cli_unzip: call to lseek() failed\n");
|
||||
if (!(tmpd))
|
||||
free(tempfile);
|
||||
free(tempfile);
|
||||
close(out_file);
|
||||
return CL_ESEEK;
|
||||
}
|
||||
ret = zcb(out_file, tempfile, ctx);
|
||||
ret = zcb(out_file, tempfile, ctx, original_filename);
|
||||
close(out_file);
|
||||
if (!ctx->engine->keeptmp)
|
||||
if (cli_unlink(tempfile)) ret = CL_EUNLINK;
|
||||
if (!tmpd) free(tempfile);
|
||||
free(tempfile);
|
||||
return ret;
|
||||
}
|
||||
|
||||
close(out_file);
|
||||
if (!ctx->engine->keeptmp)
|
||||
if (cli_unlink(tempfile)) ret = CL_EUNLINK;
|
||||
if (!tmpd) free(tempfile);
|
||||
free(tempfile);
|
||||
cli_dbgmsg("cli_unzip: extraction failed\n");
|
||||
return ret;
|
||||
}
|
||||
|
@ -418,7 +427,8 @@ static inline cl_error_t zdecrypt(
|
|||
unsigned int *num_files_unzipped,
|
||||
cli_ctx *ctx,
|
||||
char *tmpd,
|
||||
zip_cb zcb)
|
||||
zip_cb zcb,
|
||||
const char *original_filename)
|
||||
{
|
||||
cl_error_t ret;
|
||||
int v = 0;
|
||||
|
@ -494,7 +504,7 @@ static inline cl_error_t zdecrypt(
|
|||
snprintf(name, sizeof(name), "%s" PATHSEP "zip.decrypt.%03u", tmpd, *num_files_unzipped);
|
||||
name[sizeof(name) - 1] = '\0';
|
||||
} else {
|
||||
if (!(tempfile = cli_gentemp(ctx->engine->tmpdir))) return CL_EMEM;
|
||||
if (!(tempfile = cli_gentemp(ctx->sub_tmpdir))) return CL_EMEM;
|
||||
}
|
||||
if ((out_file = open(tempfile, O_RDWR | O_CREAT | O_TRUNC | O_BINARY, S_IRUSR | S_IWUSR)) == -1) {
|
||||
cli_warnmsg("cli_unzip: decrypt - failed to create temporary file %s\n", tempfile);
|
||||
|
@ -528,7 +538,7 @@ static inline cl_error_t zdecrypt(
|
|||
cli_dbgmsg("cli_unzip: decrypt - decrypted %zu bytes to %s\n", total, tempfile);
|
||||
|
||||
/* decrypt data to new fmap -> buffer */
|
||||
if (!(dcypt_map = fmap(out_file, 0, total))) {
|
||||
if (!(dcypt_map = fmap(out_file, 0, total, NULL))) {
|
||||
cli_warnmsg("cli_unzip: decrypt - failed to create fmap on decrypted file %s\n", tempfile);
|
||||
ret = CL_EMAP;
|
||||
goto zd_clean;
|
||||
|
@ -542,7 +552,7 @@ static inline cl_error_t zdecrypt(
|
|||
}
|
||||
|
||||
/* call unz on decrypted output */
|
||||
ret = unz(dcypt_zip, csize - SIZEOF_ENCRYPTION_HEADER, usize, LOCAL_HEADER_method, LOCAL_HEADER_flags, num_files_unzipped, ctx, tmpd, zcb);
|
||||
ret = unz(dcypt_zip, csize - SIZEOF_ENCRYPTION_HEADER, usize, LOCAL_HEADER_method, LOCAL_HEADER_flags, num_files_unzipped, ctx, tmpd, zcb, original_filename);
|
||||
|
||||
/* clean-up and return */
|
||||
funmap(dcypt_map);
|
||||
|
@ -602,6 +612,7 @@ static unsigned int parse_local_file_header(
|
|||
{
|
||||
const uint8_t *local_header, *zip;
|
||||
char name[256];
|
||||
char *original_filename = NULL;
|
||||
uint32_t csize, usize;
|
||||
int virus_found = 0;
|
||||
|
||||
|
@ -626,12 +637,15 @@ static unsigned int parse_local_file_header(
|
|||
fmap_unneed_off(map, loff, SIZEOF_LOCAL_HEADER);
|
||||
return 0;
|
||||
}
|
||||
if (ctx->engine->cdb || cli_debug_flag) {
|
||||
if (ctx->engine->cdb || cli_debug_flag || ctx->engine->keeptmp || ctx->options->general & CL_SCAN_GENERAL_COLLECT_METADATA) {
|
||||
uint32_t nsize = (LOCAL_HEADER_flen >= sizeof(name)) ? sizeof(name) - 1 : LOCAL_HEADER_flen;
|
||||
const char *src;
|
||||
if (nsize && (src = fmap_need_ptr_once(map, zip, nsize))) {
|
||||
memcpy(name, zip, nsize);
|
||||
name[nsize] = '\0';
|
||||
name[nsize] = '\0';
|
||||
if (CL_SUCCESS != cli_basename(name, nsize, &original_filename)) {
|
||||
original_filename = NULL;
|
||||
}
|
||||
} else
|
||||
name[0] = '\0';
|
||||
}
|
||||
|
@ -702,12 +716,16 @@ static unsigned int parse_local_file_header(
|
|||
if (NULL == record) {
|
||||
if (LOCAL_HEADER_flags & F_ENCR) {
|
||||
if (fmap_need_ptr_once(map, zip, csize))
|
||||
*ret = zdecrypt(zip, csize, usize, local_header, num_files_unzipped, ctx, tmpd, zcb);
|
||||
*ret = zdecrypt(zip, csize, usize, local_header, num_files_unzipped, ctx, tmpd, zcb, original_filename);
|
||||
} else {
|
||||
if (fmap_need_ptr_once(map, zip, csize))
|
||||
*ret = unz(zip, csize, usize, LOCAL_HEADER_method, LOCAL_HEADER_flags, num_files_unzipped, ctx, tmpd, zcb);
|
||||
*ret = unz(zip, csize, usize, LOCAL_HEADER_method, LOCAL_HEADER_flags, num_files_unzipped, ctx, tmpd, zcb, original_filename);
|
||||
}
|
||||
} else {
|
||||
if ((NULL == original_filename) ||
|
||||
(CL_SUCCESS != cli_basename(original_filename, strlen(original_filename), &record->original_filename))) {
|
||||
record->original_filename = NULL;
|
||||
}
|
||||
record->local_header_offset = loff;
|
||||
record->local_header_size = zip - local_header;
|
||||
record->compressed_size = csize;
|
||||
|
@ -721,6 +739,10 @@ static unsigned int parse_local_file_header(
|
|||
zsize -= csize;
|
||||
}
|
||||
|
||||
if (NULL != original_filename) {
|
||||
free(original_filename);
|
||||
}
|
||||
|
||||
if (virus_found != 0)
|
||||
*ret = CL_VIRUS;
|
||||
|
||||
|
@ -1093,15 +1115,6 @@ cl_error_t cli_unzip(cli_ctx *ctx)
|
|||
ret = CL_CLEAN;
|
||||
goto done;
|
||||
}
|
||||
if (!(tmpd = cli_gentemp(ctx->engine->tmpdir))) {
|
||||
ret = CL_ETMPDIR;
|
||||
goto done;
|
||||
}
|
||||
if (mkdir(tmpd, 0700)) {
|
||||
cli_dbgmsg("cli_unzip: Can't create temporary directory %s\n", tmpd);
|
||||
ret = CL_ETMPDIR;
|
||||
goto done;
|
||||
}
|
||||
|
||||
for (coff = fsize - 22; coff > 0; coff--) { /* sizeof(EOC)==22 */
|
||||
if (!(ptr = fmap_need_off_once(map, coff, 20)))
|
||||
|
@ -1159,7 +1172,8 @@ cl_error_t cli_unzip(cli_ctx *ctx)
|
|||
&num_files_unzipped,
|
||||
ctx,
|
||||
tmpd,
|
||||
zip_scan_cb);
|
||||
zip_scan_cb,
|
||||
zip_catalogue[i].original_filename);
|
||||
} else {
|
||||
if (fmap_need_ptr_once(map, compressed_data, zip_catalogue[i].compressed_size))
|
||||
ret = unz(
|
||||
|
@ -1171,7 +1185,8 @@ cl_error_t cli_unzip(cli_ctx *ctx)
|
|||
&num_files_unzipped,
|
||||
ctx,
|
||||
tmpd,
|
||||
zip_scan_cb);
|
||||
zip_scan_cb,
|
||||
zip_catalogue[i].original_filename);
|
||||
}
|
||||
|
||||
file_count++;
|
||||
|
@ -1243,6 +1258,13 @@ cl_error_t cli_unzip(cli_ctx *ctx)
|
|||
done:
|
||||
|
||||
if (NULL != zip_catalogue) {
|
||||
/* Clean up zip record resources */
|
||||
for (i = 0; i < records_count; i++) {
|
||||
if (NULL != zip_catalogue[i].original_filename) {
|
||||
free(zip_catalogue[i].original_filename);
|
||||
zip_catalogue[i].original_filename = NULL;
|
||||
}
|
||||
}
|
||||
free(zip_catalogue);
|
||||
zip_catalogue = NULL;
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
#include "others.h"
|
||||
|
||||
typedef int (*zip_cb)(int fd, const char *filepath, cli_ctx *ctx);
|
||||
typedef cl_error_t (*zip_cb)(int fd, const char *filepath, cli_ctx *ctx, const char *name);
|
||||
#define zip_scan_cb cli_magic_scandesc
|
||||
|
||||
#define MAX_ZIP_REQUESTS 10
|
||||
|
|
|
@ -1585,7 +1585,7 @@ int cli_scan_ole10(int fd, cli_ctx *ctx)
|
|||
if (!read_uint32(fd, &object_size, FALSE))
|
||||
return CL_CLEAN;
|
||||
}
|
||||
if (!(fullname = cli_gentemp(ctx ? ctx->engine->tmpdir : NULL))) {
|
||||
if (!(fullname = cli_gentemp(ctx ? ctx->sub_tmpdir : NULL))) {
|
||||
return CL_EMEM;
|
||||
}
|
||||
ofd = open(fullname, O_RDWR | O_CREAT | O_TRUNC | O_BINARY | O_EXCL,
|
||||
|
@ -1598,7 +1598,7 @@ int cli_scan_ole10(int fd, cli_ctx *ctx)
|
|||
cli_dbgmsg("cli_decode_ole_object: decoding to %s\n", fullname);
|
||||
ole_copy_file_data(fd, ofd, object_size);
|
||||
lseek(ofd, 0, SEEK_SET);
|
||||
ret = cli_magic_scandesc(ofd, fullname, ctx);
|
||||
ret = cli_magic_scandesc(ofd, fullname, ctx, NULL);
|
||||
close(ofd);
|
||||
if (ctx && !ctx->engine->keeptmp)
|
||||
if (cli_unlink(fullname))
|
||||
|
@ -1762,7 +1762,7 @@ cli_ppt_vba_read(int ifd, cli_ctx *ctx)
|
|||
const char *ret;
|
||||
|
||||
/* Create a directory to store the extracted OLE2 objects */
|
||||
dir = cli_gentemp(ctx ? ctx->engine->tmpdir : NULL);
|
||||
dir = cli_gentemp(ctx ? ctx->sub_tmpdir : NULL);
|
||||
if (dir == NULL)
|
||||
return NULL;
|
||||
if (mkdir(dir, 0700)) {
|
||||
|
|
|
@ -308,13 +308,13 @@ static int xar_scan_subdocuments(xmlTextReaderPtr reader, cli_ctx *ctx)
|
|||
}
|
||||
subdoc_len = xmlStrlen(subdoc);
|
||||
cli_dbgmsg("cli_scanxar: in-memory scan of xml subdocument, len %i.\n", subdoc_len);
|
||||
rc = cli_mem_scandesc(subdoc, subdoc_len, ctx);
|
||||
rc = cli_mem_scandesc(subdoc, subdoc_len, ctx, NULL);
|
||||
if (rc == CL_VIRUS && SCAN_ALLMATCHES)
|
||||
rc = CL_SUCCESS;
|
||||
|
||||
/* make a file to leave if --leave-temps in effect */
|
||||
if (ctx->engine->keeptmp) {
|
||||
if ((rc = cli_gentempfd(ctx->engine->tmpdir, &tmpname, &fd)) != CL_SUCCESS) {
|
||||
if ((rc = cli_gentempfd(ctx->sub_tmpdir, &tmpname, &fd)) != CL_SUCCESS) {
|
||||
cli_dbgmsg("cli_scanxar: Can't create temporary file for subdocument.\n");
|
||||
} else {
|
||||
cli_dbgmsg("cli_scanxar: Writing subdoc to temp file %s.\n", tmpname);
|
||||
|
@ -515,7 +515,7 @@ int cli_scanxar(cli_ctx *ctx)
|
|||
|
||||
/* scan the xml */
|
||||
cli_dbgmsg("cli_scanxar: scanning xar TOC xml in memory.\n");
|
||||
rc = cli_mem_scandesc(toc, hdr.toc_length_decompressed, ctx);
|
||||
rc = cli_mem_scandesc(toc, hdr.toc_length_decompressed, ctx, NULL);
|
||||
if (rc != CL_SUCCESS) {
|
||||
if (rc != CL_VIRUS || !SCAN_ALLMATCHES)
|
||||
goto exit_toc;
|
||||
|
@ -523,7 +523,7 @@ int cli_scanxar(cli_ctx *ctx)
|
|||
|
||||
/* make a file to leave if --leave-temps in effect */
|
||||
if (ctx->engine->keeptmp) {
|
||||
if ((rc = cli_gentempfd(ctx->engine->tmpdir, &tmpname, &fd)) != CL_SUCCESS) {
|
||||
if ((rc = cli_gentempfd(ctx->sub_tmpdir, &tmpname, &fd)) != CL_SUCCESS) {
|
||||
cli_dbgmsg("cli_scanxar: Can't create temporary file for TOC.\n");
|
||||
goto exit_toc;
|
||||
}
|
||||
|
@ -572,7 +572,7 @@ int cli_scanxar(cli_ctx *ctx)
|
|||
|
||||
at = offset + hdr.toc_length_compressed + hdr.size;
|
||||
|
||||
if ((rc = cli_gentempfd(ctx->engine->tmpdir, &tmpname, &fd)) != CL_SUCCESS) {
|
||||
if ((rc = cli_gentempfd(ctx->sub_tmpdir, &tmpname, &fd)) != CL_SUCCESS) {
|
||||
cli_dbgmsg("cli_scanxar: Can't generate temporary file.\n");
|
||||
goto exit_reader;
|
||||
}
|
||||
|
@ -843,7 +843,7 @@ int cli_scanxar(cli_ctx *ctx)
|
|||
}
|
||||
}
|
||||
|
||||
rc = cli_magic_scandesc(fd, tmpname, ctx);
|
||||
rc = cli_magic_scandesc(fd, tmpname, ctx, NULL); /// TODO: collect file names in xar_get_toc_data_values()
|
||||
if (rc != CL_SUCCESS) {
|
||||
if (rc == CL_VIRUS) {
|
||||
cli_dbgmsg("cli_scanxar: Infected with %s\n", cli_get_last_virus(ctx));
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
* OpenSSL library under certain conditions as described in each
|
||||
* individual source file, and distribute linked combinations
|
||||
* including the two.
|
||||
*
|
||||
*
|
||||
* You must obey the GNU General Public License in all respects
|
||||
* for all of the code used other than OpenSSL. If you modify
|
||||
* file(s) with this exception, you may extend this exception to your
|
||||
|
@ -64,7 +64,7 @@ static char *dump_xdp(cli_ctx *ctx, const char *start, size_t sz)
|
|||
size_t nwritten = 0;
|
||||
ssize_t writeret;
|
||||
|
||||
if (cli_gentempfd(ctx->engine->tmpdir, &filename, &fd) != CL_SUCCESS)
|
||||
if (cli_gentempfd(ctx->sub_tmpdir, &filename, &fd) != CL_SUCCESS)
|
||||
return NULL;
|
||||
|
||||
while (nwritten < sz) {
|
||||
|
@ -90,7 +90,7 @@ static char *dump_xdp(cli_ctx *ctx, const char *start, size_t sz)
|
|||
return filename;
|
||||
}
|
||||
|
||||
int cli_scanxdp(cli_ctx *ctx)
|
||||
cl_error_t cli_scanxdp(cli_ctx *ctx)
|
||||
{
|
||||
#if HAVE_LIBXML2
|
||||
xmlTextReaderPtr reader = NULL;
|
||||
|
@ -160,7 +160,7 @@ int cli_scanxdp(cli_ctx *ctx)
|
|||
break;
|
||||
}
|
||||
|
||||
rc = cli_mem_scandesc(decoded, decodedlen, ctx);
|
||||
rc = cli_mem_scandesc(decoded, decodedlen, ctx, NULL);
|
||||
free(decoded);
|
||||
if (rc != CL_SUCCESS || rc == CL_BREAK) {
|
||||
xmlFree((void *)value);
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
* OpenSSL library under certain conditions as described in each
|
||||
* individual source file, and distribute linked combinations
|
||||
* including the two.
|
||||
*
|
||||
*
|
||||
* You must obey the GNU General Public License in all respects
|
||||
* for all of the code used other than OpenSSL. If you modify
|
||||
* file(s) with this exception, you may extend this exception to your
|
||||
|
@ -35,6 +35,6 @@
|
|||
#ifndef _XDP_H
|
||||
#define _XDP_H
|
||||
|
||||
int cli_scanxdp(cli_ctx *ctx);
|
||||
cl_error_t cli_scanxdp(cli_ctx *ctx);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -4378,7 +4378,7 @@ cli_xlm_extract_macros(const char *dir, cli_ctx *ctx, struct uniq *U, char *hash
|
|||
ctx->recursion += 1;
|
||||
cli_set_container(ctx, CL_TYPE_MSOLE2, 0); //TODO: set correct container size
|
||||
|
||||
if (cli_scandesc(out_fd, ctx, CL_TYPE_SCRIPT, 0, NULL, AC_SCAN_VIR, NULL) == CL_VIRUS) {
|
||||
if (cli_scandesc(out_fd, ctx, CL_TYPE_SCRIPT, 0, NULL, AC_SCAN_VIR, NULL, NULL) == CL_VIRUS) {
|
||||
ctx->recursion -= 1;
|
||||
ret = CL_VIRUS;
|
||||
goto done;
|
||||
|
|
|
@ -234,7 +234,7 @@ static int hashpe(const char *filename, unsigned int class, int type)
|
|||
|
||||
lseek(fd, 0, SEEK_SET);
|
||||
FSTAT(fd, &sb);
|
||||
if (!(*ctx.fmap = fmap(fd, 0, sb.st_size))) {
|
||||
if (!(*ctx.fmap = fmap(fd, 0, sb.st_size, filename))) {
|
||||
free(ctx.containers);
|
||||
free(ctx.fmap);
|
||||
close(fd);
|
||||
|
@ -354,7 +354,7 @@ static int htmlnorm(const struct optstruct *opts)
|
|||
return -1;
|
||||
}
|
||||
|
||||
if ((map = fmap(fd, 0, 0))) {
|
||||
if ((map = fmap(fd, 0, 0, optget(opts, "html-normalise")->strarg))) {
|
||||
html_normalise_map(map, ".", NULL, NULL);
|
||||
funmap(map);
|
||||
} else
|
||||
|
@ -388,7 +388,7 @@ static int asciinorm(const struct optstruct *opts)
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (!(map = fmap(fd, 0, 0))) {
|
||||
if (!(map = fmap(fd, 0, 0, fname))) {
|
||||
mprintf("!fmap: Could not map fd %d\n", fd);
|
||||
close(fd);
|
||||
free(norm_buff);
|
||||
|
@ -2259,7 +2259,7 @@ static void matchsig(const char *sig, const char *offset, int fd)
|
|||
}
|
||||
lseek(fd, 0, SEEK_SET);
|
||||
FSTAT(fd, &sb);
|
||||
if (!(*ctx.fmap = fmap(fd, 0, sb.st_size))) {
|
||||
if (!(*ctx.fmap = fmap(fd, 0, sb.st_size, NULL))) {
|
||||
free(ctx.containers);
|
||||
free(ctx.fmap);
|
||||
cl_engine_free(engine);
|
||||
|
@ -3456,7 +3456,7 @@ static int dumpcerts(const struct optstruct *opts)
|
|||
|
||||
lseek(fd, 0, SEEK_SET);
|
||||
FSTAT(fd, &sb);
|
||||
if (!(*ctx.fmap = fmap(fd, 0, sb.st_size))) {
|
||||
if (!(*ctx.fmap = fmap(fd, 0, sb.st_size, filename))) {
|
||||
free(ctx.containers);
|
||||
free(ctx.fmap);
|
||||
close(fd);
|
||||
|
|
|
@ -114,7 +114,7 @@ cli_ctx *convenience_ctx(int fd)
|
|||
ctx->options->general |= CL_SCAN_GENERAL_HEURISTICS;
|
||||
ctx->options->parse = ~(0);
|
||||
|
||||
if (!(*ctx->fmap = fmap(fd, 0, 0))) {
|
||||
if (!(*ctx->fmap = fmap(fd, 0, 0, NULL))) {
|
||||
printf("convenience_ctx: fmap failed\n");
|
||||
goto done;
|
||||
}
|
||||
|
|
|
@ -118,7 +118,7 @@ static void runtest(const char *file, uint64_t expected, int fail, int nojit,
|
|||
if (fdin < 0 && errno == ENOENT)
|
||||
fdin = open_testfile(infile);
|
||||
ck_assert_msg(fdin >= 0, "failed to open infile");
|
||||
map = fmap(fdin, 0, 0);
|
||||
map = fmap(fdin, 0, 0, filestr);
|
||||
ck_assert_msg(!!map, "unable to fmap infile");
|
||||
if (pedata)
|
||||
ctx->hooks.pedata = pedata;
|
||||
|
|
|
@ -115,7 +115,7 @@ START_TEST(test_htmlnorm_api)
|
|||
fd = open_testfile(tests[_i].input);
|
||||
ck_assert_msg(fd > 0, "open_testfile failed");
|
||||
|
||||
map = fmap(fd, 0, 0);
|
||||
map = fmap(fd, 0, 0, tests[_i].input);
|
||||
ck_assert_msg(!!map, "fmap failed");
|
||||
|
||||
ck_assert_msg(mkdir(dir, 0700) == 0, "mkdir failed");
|
||||
|
@ -151,7 +151,7 @@ START_TEST(test_screnc_nullterminate)
|
|||
fmap_t *map;
|
||||
|
||||
ck_assert_msg(mkdir(dir, 0700) == 0, "mkdir failed");
|
||||
map = fmap(fd, 0, 0);
|
||||
map = fmap(fd, 0, 0, "screnc_test");
|
||||
ck_assert_msg(!!map, "fmap failed");
|
||||
ck_assert_msg(html_screnc_decode(map, dir) == 1, "html_screnc_decode failed");
|
||||
funmap(map);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue