c4w: add Scan_GetFileType - untested

This commit is contained in:
aCaB
2011-06-15 04:50:54 +02:00
parent a49208e94b
commit 4d08b6d6cf
3 changed files with 110 additions and 6 deletions

View File

@@ -222,7 +222,7 @@ CL_CLEAN = File is scanned
CL_BREAK = Whitelisted by callback - file is skipped and marked as clean
CL_VIRUS = Blacklisted by callback - file is skipped and marked as infected
*/
extern void cl_engine_set_clcb_file_type(struct cl_engine *engine, clcb_pre_cache callback);
extern void cl_engine_set_clcb_pre_cache(struct cl_engine *engine, clcb_pre_cache callback);
typedef cl_error_t (*clcb_pre_scan)(int fd, const char *type, void *context);
/* PRE-SCAN

View File

@@ -254,6 +254,12 @@ int CLAMAPI Scan_ScanObject(CClamAVScanner *pScanner, const wchar_t *pObjectPath
*/
int CLAMAPI Scan_ScanObjectByHandle(CClamAVScanner *pScanner, HANDLE object, int *pScanStatus, PCLAM_SCAN_INFO_LIST *pInfoList);
/*
* Returns the outer file type as an _int64[2] for the give HANDLE
* Scan is not performed and no callback is invoked
*/
int CLAMAPI Scan_GetFileType(HANDLE hFile, _int64 *filetype);
/*
* MANDATORY SUPPORT
* Destroy memory allocated when malicious objects are found during scan

View File

@@ -28,6 +28,58 @@
#include "clscanapi.h"
#include "interface.h"
const char *types[] = {
"HTML",
"HTML_UTF16",
"MSEXE",
"GRAPHICS",
"TEXT_ASCII",
"TEXT_UTF8",
"TEXT_UTF16LE",
"TEXT_UTF16BE",
"PDF",
"SCRIPT",
"RTF",
"RIFF",
"MSCHM",
"MSCAB",
"MSOLE2",
"MSSZDD",
"ZIP",
"RAR",
"7Z",
"BZ",
"GZ",
"ARJ",
"ZIPSFX",
"RARSFX",
"CABSFX",
"ARJSFX",
"NULSFT",
"AUTOIT",
"ISHIELD_MSI",
"SFX",
"BINHEX",
"MAIL",
"TNEF",
"BINARY_DATA",
"CRYPTFF",
"UUENCODED",
"SCRENC",
"POSIX_TAR",
"OLD_TAR",
"ELF",
"MACHO",
"MACHO_UNIBIN",
"SIS",
"SWF",
"CPIO_OLD",
"CPIO_ODC",
"CPIO_NEWC",
"CPIO_CRC",
NULL
};
int WINAPI SHCreateDirectoryExA(HWND, LPCTSTR, SECURITY_ATTRIBUTES *); /* cannot include Shlobj.h due to DATADIR collision */
#define FMT(s) "!"__FUNCTION__": "s"\n"
@@ -55,6 +107,7 @@ typedef struct {
CLAM_SCAN_CALLBACK scancb;
void *scancb_ctx;
unsigned int scanopts;
_int64 *filetype;
} instance;
struct {
@@ -73,6 +126,7 @@ BOOL minimal_definitions = FALSE;
#define lock_instances()(WaitForSingleObject(instance_mutex, INFINITE) == WAIT_FAILED)
#define unlock_instances() do {ReleaseMutex(instance_mutex);} while(0)
cl_error_t filetype_cb(int fd, const char *detected_file_type, void *context);
cl_error_t prescan_cb(int fd, const char *detected_file_type, void *context);
cl_error_t postscan_cb(int fd, int result, const char *virname, void *context);
@@ -355,7 +409,8 @@ int CLAMAPI Scan_Initialize(const wchar_t *pEnginesFolder, const wchar_t *pTempR
unlock_engine();
FAIL(CL_EMEM, "Not enough memory for a new engine");
}
cl_engine_set_clcb_pre_cache(engine, prescan_cb);
cl_engine_set_clcb_pre_cache(engine, filetype_cb);
cl_engine_set_clcb_pre_scan(engine, prescan_cb);
cl_engine_set_clcb_post_scan(engine, postscan_cb);
minimal_definitions = bLoadMinDefs;
@@ -449,7 +504,7 @@ int CLAMAPI Scan_CreateInstance(CClamAVScanner **ppScanner) {
INFN();
if(!ppScanner)
FAIL(CL_ENULLARG, "NULL pScanner");
inst = calloc(1, sizeof(*inst));
inst = (instance *)calloc(1, sizeof(*inst));
if(!inst)
FAIL(CL_EMEM, "CreateInstance: OOM");
if(lock_engine()) {
@@ -887,7 +942,7 @@ int CLAMAPI Scan_ScanObjectByHandle(CClamAVScanner *pScanner, HANDLE object, int
perf = GetTickCount();
res = cl_scandesc_callback(fd, &virname, NULL, engine, inst->scanopts, &sctx);
do {
if(!inst->filetype) do {
CLAM_SCAN_INFO si;
CLAM_ACTION act;
DWORD cbperf;
@@ -935,7 +990,7 @@ int CLAMAPI Scan_ScanObjectByHandle(CClamAVScanner *pScanner, HANDLE object, int
if(res == CL_VIRUS) {
logg("Scan_ScanObjectByHandle (instance %p): file is INFECTED with %s\n", inst, virname);
if(pInfoList) {
CLAM_SCAN_INFO_LIST *infolist = calloc(1, sizeof(CLAM_SCAN_INFO_LIST) + sizeof(CLAM_SCAN_INFO) + MAX_VIRNAME_LEN * 2);
CLAM_SCAN_INFO_LIST *infolist = (CLAM_SCAN_INFO_LIST *)calloc(1, sizeof(CLAM_SCAN_INFO_LIST) + sizeof(CLAM_SCAN_INFO) + MAX_VIRNAME_LEN * 2);
PCLAM_SCAN_INFO scaninfo;
wchar_t *wvirname;
if(!infolist)
@@ -967,6 +1022,16 @@ int CLAMAPI Scan_ScanObjectByHandle(CClamAVScanner *pScanner, HANDLE object, int
WIN();
}
int CLAMAPI Scan_GetFileType(HANDLE hFile, _int64 *filetype) {
instance *inst;
int status, ret = Scan_CreateInstance((CClamAVScanner **)&inst);
if(ret != CLAMAPI_SUCCESS)
return ret;
inst->filetype = filetype;
ret = Scan_ScanObjectByHandle((CClamAVScanner *)inst, hFile, &status, NULL);
Scan_DestroyInstance((CClamAVScanner *)inst);
return ret;
}
int CLAMAPI Scan_DeleteScanInfo(CClamAVScanner *pScanner, PCLAM_SCAN_INFO_LIST pInfoList) {
logg("*in Scan_DeleteScanInfo(pScanner = %p, pInfoList = %p)\n", pScanner, pInfoList);
@@ -989,6 +1054,33 @@ int CLAMAPI Scan_DeleteScanInfo(CClamAVScanner *pScanner, PCLAM_SCAN_INFO_LIST p
WIN();
}
cl_error_t filetype_cb(int fd, const char *type, void *context) {
struct scan_ctx *sctx = (struct scan_ctx *)context;
if(sctx && sctx->inst && sctx->inst->filetype) {
int i=0;
if(strncmp(type, "CL_TYPE_", 8)) {
for(i=0; types[i]; i++) {
if(!strcmp(&type[8], types[i]))
break;
}
if(!types[i]) i = -1;
} else
i = -1;
if(i<0) {
sctx->inst->filetype[0] = -1;
sctx->inst->filetype[1] = -1;
} else if(i<64) {
sctx->inst->filetype[0] = 1LL << i;
sctx->inst->filetype[1] = 0;
} else {
sctx->inst->filetype[0] = 0;
sctx->inst->filetype[1] = 1LL << (i-64);
}
return CL_BREAK;
}
return CL_CLEAN;
}
cl_error_t prescan_cb(int fd, const char *type, void *context) {
struct scan_ctx *sctx = (struct scan_ctx *)context;
char tmpf[4096];
@@ -1003,6 +1095,9 @@ cl_error_t prescan_cb(int fd, const char *type, void *context) {
return CL_CLEAN;
}
inst = sctx->inst;
if(inst && inst->filetype)
return CL_CLEAN; /* Just in case, this shouldn't happen */
logg("*in prescan_cb with clamav context %p, instance %p, fd %d, type %s)\n", context, inst, fd, type);
if(strncmp(type, "CL_TYPE_", 8) ||
(strcmp(&type[8], "BINARY_DATA") &&
@@ -1105,10 +1200,13 @@ cl_error_t postscan_cb(int fd, int result, const char *virname, void *context) {
logg("!postscan_cb called with NULL clamav context\n");
return CL_CLEAN;
}
inst = sctx->inst;
if(inst && inst->filetype)
return CL_CLEAN; /* No callback, we are just filetyping */
if(fd == sctx->entryfd)
return CL_CLEAN; /* Moved to after cl_scandesc returns due to heuristic results not being yet set in magicscan */
inst = sctx->inst;
si.cbSize = sizeof(si);
si.flags = 0;
si.scanPhase = SCAN_PHASE_POSTSCAN;