mirror of
				https://github.com/Cisco-Talos/clamav.git
				synced 2025-10-31 08:00:54 +00:00 
			
		
		
		
	Gather bytecode events from bytecode API.
This commit is contained in:
		
							parent
							
								
									8a8dbd59ea
								
							
						
					
					
						commit
						ae8dc8c2bc
					
				
					 1 changed files with 71 additions and 13 deletions
				
			
		|  | @ -50,6 +50,12 @@ | |||
| #include "str.h" | ||||
| #include "filetypes.h" | ||||
| 
 | ||||
| #define EV ctx->bc_events | ||||
| 
 | ||||
| #define STRINGIFY(x) #x | ||||
| #define TOSTRING(x) STRINGIFY(x) | ||||
| #define  API_MISUSE() cli_event_error_str(EV, "API misuse @" TOSTRING(__LINE__ )) | ||||
| 
 | ||||
| uint32_t cli_bcapi_test1(struct cli_bc_ctx *ctx, uint32_t a, uint32_t b) | ||||
| { | ||||
|     return (a==0xf00dbeef && b==0xbeeff00d) ? 0x12345678 : 0x55; | ||||
|  | @ -63,18 +69,24 @@ uint32_t cli_bcapi_test2(struct cli_bc_ctx *ctx, uint32_t a) | |||
| int32_t cli_bcapi_read(struct cli_bc_ctx* ctx, uint8_t *data, int32_t size) | ||||
| { | ||||
|     int n; | ||||
|     if (!ctx->fmap) | ||||
|     if (!ctx->fmap) { | ||||
| 	API_MISUSE(); | ||||
| 	return -1; | ||||
|     } | ||||
|     if (size < 0 || size > CLI_MAX_ALLOCATION) { | ||||
| 	cli_warnmsg("bytecode: negative read size: %d\n", size); | ||||
| 	API_MISUSE(); | ||||
| 	return -1; | ||||
|     } | ||||
| /*    cli_dbgmsg("read data at %d\n", ctx->off);*/ | ||||
|     n = fmap_readn(ctx->fmap, data, ctx->off, size); | ||||
|     if (n <= 0) { | ||||
| 	cli_dbgmsg("bcapi_read: fmap_readn failed\n"); | ||||
| 	cli_dbgmsg("bcapi_read: fmap_readn failed (requested %d)\n", size); | ||||
| 	cli_event_count(EV, BCEV_READ_ERR); | ||||
| 	return n; | ||||
|     } | ||||
|     cli_event_int(EV, BCEV_OFFSET, ctx->off); | ||||
|     cli_event_fastdata(EV, BCEV_READ, data, size); | ||||
|     //cli_event_data(EV, BCEV_READ, data, n);
 | ||||
|     ctx->off += n; | ||||
|     return n; | ||||
| } | ||||
|  | @ -84,6 +96,7 @@ int32_t cli_bcapi_seek(struct cli_bc_ctx* ctx, int32_t pos, uint32_t whence) | |||
|     off_t off; | ||||
|     if (!ctx->fmap) { | ||||
| 	cli_dbgmsg("bcapi_seek: no fmap\n"); | ||||
| 	API_MISUSE(); | ||||
| 	return -1; | ||||
|     } | ||||
|     switch (whence) { | ||||
|  | @ -97,6 +110,7 @@ int32_t cli_bcapi_seek(struct cli_bc_ctx* ctx, int32_t pos, uint32_t whence) | |||
| 	    off = ctx->file_size + pos; | ||||
| 	    break; | ||||
| 	default: | ||||
| 	    API_MISUSE(); | ||||
| 	    cli_dbgmsg("bcapi_seek: invalid whence value\n"); | ||||
| 	    return -1; | ||||
|     } | ||||
|  | @ -105,18 +119,21 @@ int32_t cli_bcapi_seek(struct cli_bc_ctx* ctx, int32_t pos, uint32_t whence) | |||
| 		   off, ctx->file_size); | ||||
| 	return -1; | ||||
|     } | ||||
|     cli_event_int(EV, BCEV_OFFSET, off); | ||||
|     ctx->off = off; | ||||
|     return off; | ||||
| } | ||||
| 
 | ||||
| uint32_t cli_bcapi_debug_print_str(struct cli_bc_ctx *ctx, const uint8_t *str, uint32_t len) | ||||
| { | ||||
|     cli_event_fastdata(EV, BCEV_DBG_STR, str, strlen(str)); | ||||
|     cli_dbgmsg("bytecode debug: %s\n", str); | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| uint32_t cli_bcapi_debug_print_uint(struct cli_bc_ctx *ctx, uint32_t a) | ||||
| { | ||||
|     cli_event_int(EV, BCEV_DBG_INT, a); | ||||
|     if (!cli_debug_flag) | ||||
| 	return 0; | ||||
|     return fprintf(stderr, "%d", a); | ||||
|  | @ -136,8 +153,10 @@ uint32_t cli_bcapi_disasm_x86(struct cli_bc_ctx *ctx, struct DISASM_RESULT *res, | |||
|     int n; | ||||
|     const unsigned char *buf; | ||||
|     const unsigned char* next; | ||||
|     if (!res || !ctx->fmap || ctx->off >= ctx->fmap->len) | ||||
|     if (!res || !ctx->fmap || ctx->off >= ctx->fmap->len) { | ||||
| 	API_MISUSE(); | ||||
| 	return -1; | ||||
|     } | ||||
|     /* 32 should be longest instr we support decoding.
 | ||||
|      * When we'll support mmx/sse instructions this should be updated! */ | ||||
|     n = MIN(32, ctx->fmap->len - ctx->off); | ||||
|  | @ -145,6 +164,7 @@ uint32_t cli_bcapi_disasm_x86(struct cli_bc_ctx *ctx, struct DISASM_RESULT *res, | |||
|     next = cli_disasm_one(buf, n, res, 0); | ||||
|     if (!next) { | ||||
| 	cli_dbgmsg("bcapi_disasm: failed\n"); | ||||
| 	cli_event_count(EV, BCEV_DISASM_FAIL); | ||||
| 	return -1; | ||||
|     } | ||||
|     return ctx->off + next - buf; | ||||
|  | @ -156,33 +176,42 @@ uint32_t cli_bcapi_disasm_x86(struct cli_bc_ctx *ctx, struct DISASM_RESULT *res, | |||
|  * override the limit if we need it in a special situation */ | ||||
| int32_t cli_bcapi_write(struct cli_bc_ctx *ctx, uint8_t*data, int32_t len) | ||||
| { | ||||
|     char err[128]; | ||||
|     int32_t res; | ||||
| 
 | ||||
|     cli_ctx *cctx = (cli_ctx*)ctx->ctx; | ||||
|     if (len < 0) { | ||||
| 	cli_warnmsg("Bytecode API: called with negative length!\n"); | ||||
| 	API_MISUSE(); | ||||
| 	return -1; | ||||
|     } | ||||
|     if (!ctx->outfd) { | ||||
| 	ctx->tempfile = cli_gentemp(cctx ? cctx->engine->tmpdir : NULL); | ||||
| 	if (!ctx->tempfile) { | ||||
| 	    cli_dbgmsg("Bytecode API: Unable to allocate memory for tempfile\n"); | ||||
| 	    cli_event_error_oom(EV, 0); | ||||
| 	    return -1; | ||||
| 	} | ||||
| 	ctx->outfd = open(ctx->tempfile, O_RDWR|O_CREAT|O_EXCL|O_TRUNC|O_BINARY, 0600); | ||||
| 	if (ctx->outfd == -1) { | ||||
| 	    ctx->outfd = 0; | ||||
| 	    cli_warnmsg("Bytecode API: Can't create file %s\n", ctx->tempfile); | ||||
| 	    cli_warnmsg("Bytecode API: Can't create file %s: %s\n", ctx->tempfile, cli_strerror(errno, err, sizeof(err))); | ||||
| 	    cli_event_error_str(EV, "cli_bcapi_write: Can't create temporary file"); | ||||
| 	    free(ctx->tempfile); | ||||
| 	    return -1; | ||||
| 	} | ||||
| 	cli_dbgmsg("bytecode opened new tempfile: %s\n", ctx->tempfile); | ||||
|     } | ||||
| 
 | ||||
|     cli_event_fastdata(ctx->bc_events, BCEV_WRITE, data, len); | ||||
|     if (cli_checklimits("bytecode api", cctx, ctx->written + len, 0, 0)) | ||||
| 	return -1; | ||||
|     res = cli_writen(ctx->outfd, data, len); | ||||
|     if (res > 0) ctx->written += res; | ||||
|     if (res == -1) | ||||
| 	cli_dbgmsg("Bytecode API: write failed: %d\n", errno); | ||||
|     if (res == -1) { | ||||
| 	cli_warnmsg("Bytecode API: write failed: %s\n", cli_strerror(errno, err, sizeof(err))); | ||||
| 	cli_event_error_str(EV, "cli_bcapi_write: write failed"); | ||||
|     } | ||||
|     return res; | ||||
| } | ||||
| 
 | ||||
|  | @ -306,8 +335,9 @@ static inline const char* cli_memmem(const char *haystack, unsigned hlen, | |||
| { | ||||
|     const char *p; | ||||
|     unsigned char c; | ||||
|     if (!needle || !haystack) | ||||
|     if (!needle || !haystack) { | ||||
| 	return NULL; | ||||
|     } | ||||
|     c = *needle++; | ||||
|     if (nlen == 1) | ||||
| 	return memchr(haystack, c, hlen); | ||||
|  | @ -331,6 +361,7 @@ int32_t cli_bcapi_file_find(struct cli_bc_ctx *ctx, const uint8_t* data, uint32_ | |||
|     fmap_t *map = ctx->fmap; | ||||
|     if (!map || len <= 0) { | ||||
| 	cli_dbgmsg("bcapi_file_find preconditions not met\n"); | ||||
| 	API_MISUSE(); | ||||
| 	return -1; | ||||
|     } | ||||
|     return cli_bcapi_file_find_limit(ctx, data, len, map->len); | ||||
|  | @ -345,8 +376,12 @@ int32_t cli_bcapi_file_find_limit(struct cli_bc_ctx *ctx , const uint8_t* data, | |||
| 
 | ||||
|     if (!map || len > sizeof(buf)/4 || len <= 0 || limit <= 0) { | ||||
| 	cli_dbgmsg("bcapi_file_find_limit preconditions not met\n"); | ||||
| 	API_MISUSE(); | ||||
| 	return -1; | ||||
|     } | ||||
| 
 | ||||
|     cli_event_int(EV, BCEV_OFFSET, off); | ||||
|     cli_event_fastdata(EV, BCEV_FIND, data, len); | ||||
|     for (;;) { | ||||
| 	const char *p; | ||||
| 	int32_t readlen = sizeof(buf); | ||||
|  | @ -373,6 +408,7 @@ int32_t cli_bcapi_file_byteat(struct cli_bc_ctx *ctx, uint32_t off) | |||
| 	cli_dbgmsg("bcapi_file_byteat: no fmap\n"); | ||||
| 	return -1; | ||||
|     } | ||||
|     cli_event_int(EV, BCEV_OFFSET, off); | ||||
|     if (fmap_readn(ctx->fmap, &c, off, 1) != 1) { | ||||
| 	cli_dbgmsg("bcapi_file_byteat: fmap_readn failed at %u\n", off); | ||||
| 	return -1; | ||||
|  | @ -382,20 +418,25 @@ int32_t cli_bcapi_file_byteat(struct cli_bc_ctx *ctx, uint32_t off) | |||
| 
 | ||||
| uint8_t* cli_bcapi_malloc(struct cli_bc_ctx *ctx, uint32_t size) | ||||
| { | ||||
|     void *v; | ||||
| #if USE_MPOOL | ||||
|     if (!ctx->mpool) { | ||||
| 	ctx->mpool = mpool_create(); | ||||
| 	if (!ctx->mpool) { | ||||
| 	    cli_dbgmsg("bytecode: mpool_create failed!\n"); | ||||
| 	    cli_event_error_oom(EV, 0); | ||||
| 	    return NULL; | ||||
| 	} | ||||
|     } | ||||
|     return mpool_malloc(ctx->mpool, size); | ||||
|     v = mpool_malloc(ctx->mpool, size); | ||||
| #else | ||||
|     /* TODO: implement using a list of pointers we allocated! */ | ||||
|     cli_errmsg("cli_bcapi_malloc not implemented for systems without mmap yet!\n"); | ||||
|     return cli_malloc(size); | ||||
|     v = cli_malloc(size); | ||||
| #endif | ||||
|     if (!v) | ||||
| 	cli_event_error_oom(EV, size); | ||||
|     return v; | ||||
| } | ||||
| 
 | ||||
| int32_t cli_bcapi_get_pe_section(struct cli_bc_ctx *ctx, struct cli_exe_section* section, uint32_t num) | ||||
|  | @ -414,16 +455,19 @@ int32_t cli_bcapi_fill_buffer(struct cli_bc_ctx *ctx, uint8_t* buf, | |||
|     int32_t res, remaining, tofill; | ||||
|     if (!buf || !buflen || buflen > CLI_MAX_ALLOCATION || filled > buflen) { | ||||
| 	cli_dbgmsg("fill_buffer1\n"); | ||||
| 	API_MISUSE(); | ||||
| 	return -1; | ||||
|     } | ||||
|     if (ctx->off >= ctx->file_size) { | ||||
| 	cli_dbgmsg("fill_buffer2\n"); | ||||
| 	API_MISUSE(); | ||||
| 	return 0; | ||||
|     } | ||||
|     remaining = filled - pos; | ||||
|     if (remaining) { | ||||
| 	if (!CLI_ISCONTAINED(buf, buflen, buf+pos, remaining)) { | ||||
| 	    cli_dbgmsg("fill_buffer3\n"); | ||||
| 	    API_MISUSE(); | ||||
| 	    return -1; | ||||
| 	} | ||||
| 	memmove(buf, buf+pos, remaining); | ||||
|  | @ -431,11 +475,13 @@ int32_t cli_bcapi_fill_buffer(struct cli_bc_ctx *ctx, uint8_t* buf, | |||
|     tofill = buflen - remaining; | ||||
|     if (!CLI_ISCONTAINED(buf, buflen, buf+remaining, tofill)) { | ||||
| 	cli_dbgmsg("fill_buffer4\n"); | ||||
| 	API_MISUSE(); | ||||
| 	return -1; | ||||
|     } | ||||
|     res = cli_bcapi_read(ctx, buf+remaining, tofill); | ||||
|     if (res <= 0) { | ||||
| 	cli_dbgmsg("fill_buffer5\n"); | ||||
| 	API_MISUSE(); | ||||
| 	return res; | ||||
|     } | ||||
|     return remaining + res; | ||||
|  | @ -445,6 +491,8 @@ int32_t cli_bcapi_extract_new(struct cli_bc_ctx *ctx, int32_t id) | |||
| { | ||||
|     cli_ctx *cctx; | ||||
|     int res = -1; | ||||
| 
 | ||||
|     cli_event_count(EV, BCEV_EXTRACTED); | ||||
|     cli_dbgmsg("previous tempfile had %u bytes\n", ctx->written); | ||||
|     if (!ctx->written) | ||||
| 	return 0; | ||||
|  | @ -489,6 +537,7 @@ int32_t cli_bcapi_read_number(struct cli_bc_ctx *ctx, uint32_t radix) | |||
| 
 | ||||
|     if ((radix != 10 && radix != 16) || !ctx->fmap) | ||||
| 	return -1; | ||||
|     cli_event_int(EV, BCEV_OFFSET, ctx->off); | ||||
|     while ((p = fmap_need_off_once(ctx->fmap, ctx->off, BUF))) { | ||||
| 	for (i=0;i<BUF;i++) { | ||||
| 	    if (p[i] >= '0' && p[i] <= '9') { | ||||
|  | @ -510,8 +559,10 @@ int32_t cli_bcapi_hashset_new(struct cli_bc_ctx *ctx ) | |||
| { | ||||
|     unsigned  n = ctx->nhashsets+1; | ||||
|     struct cli_hashset *s = cli_realloc(ctx->hashsets, sizeof(*ctx->hashsets)*n); | ||||
|     if (!s) | ||||
|     if (!s) { | ||||
| 	cli_event_error_oom(EV, 0); | ||||
| 	return -1; | ||||
|     } | ||||
|     ctx->hashsets = s; | ||||
|     ctx->nhashsets = n; | ||||
|     s = &s[n-1]; | ||||
|  | @ -521,8 +572,10 @@ int32_t cli_bcapi_hashset_new(struct cli_bc_ctx *ctx ) | |||
| 
 | ||||
| static struct cli_hashset *get_hashset(struct cli_bc_ctx *ctx, int32_t id) | ||||
| { | ||||
|     if (id < 0 || id >= ctx->nhashsets || !ctx->hashsets) | ||||
|     if (id < 0 || id >= ctx->nhashsets || !ctx->hashsets) { | ||||
| 	API_MISUSE(); | ||||
| 	return NULL; | ||||
|     } | ||||
|     return &ctx->hashsets[id]; | ||||
| } | ||||
| 
 | ||||
|  | @ -991,8 +1044,12 @@ int32_t cli_bcapi_memstr(struct cli_bc_ctx *ctx, const uint8_t* h, int32_t hs, | |||
| 			 const uint8_t*n, int32_t ns) | ||||
| { | ||||
|     const uint8_t *s; | ||||
|     if (!h || !n || hs < 0 || ns < 0) | ||||
|     if (!h || !n || hs < 0 || ns < 0) { | ||||
| 	API_MISUSE(); | ||||
| 	return -1; | ||||
|     } | ||||
|     cli_event_fastdata(EV, BCEV_MEM_1, h, hs); | ||||
|     cli_event_fastdata(EV, BCEV_MEM_2, n, ns); | ||||
|     s = (const uint8_t*) cli_memstr((const char*)h, hs, (const char*)n, ns); | ||||
|     if (!s) | ||||
| 	return -1; | ||||
|  | @ -1035,6 +1092,7 @@ uint32_t cli_bcapi_debug_print_str_start(struct cli_bc_ctx *ctx , const uint8_t* | |||
| { | ||||
|     if (!s || len <= 0) | ||||
| 	return -1; | ||||
|     cli_event_fastdata(EV, BCEV_DBG_STR, s, len); | ||||
|     cli_dbgmsg("bytecode debug: %.*s", len, s); | ||||
|     return 0; | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Török Edvin
						Török Edvin