コード例 #1
0
ファイル: rtf.c プロジェクト: CyberIntelMafia/clamav-devel
static int push_state(struct stack* stack,struct rtf_state* state)
{
	int toplevel;
	size_t defelements;

	stack->elements++;
	if( compare_state(state,&base_state)) { 
		state->default_elements++;
		return 0;/* this is default state, don't push it, we'll know when we pop it that it was the default one,
			  we store in the state how many default elements we have on the stack */
	}
	if(stack->stack_cnt >= stack->stack_size) {
		/* grow stack */
		struct rtf_state *states;
		stack->stack_size += 128;
		states = cli_realloc2(stack->states, stack->stack_size*sizeof(*stack->states));
		if(!states)
			return CL_EMEM;
		stack->states = states;
	}
	stack->states[stack->stack_cnt++] = *state;
	toplevel = state->encounteredTopLevel;
	defelements = state->default_elements;

	*state = base_state;

	state->encounteredTopLevel = toplevel;
	state->default_elements = defelements;
	return 0; 
}
コード例 #2
0
ファイル: events.c プロジェクト: Distrotech/clamav
void cli_event_data(cli_events_t *ctx, unsigned id, const void *data, uint32_t len)
{
    struct cli_event *ev = get_event(ctx, id);
    if (!ev)
	return;
    if (ev->type != ev_data) {
	cli_event_error_str(ctx, "cli_event_string must be called with ev_data type");
	return;
    }
    switch (ev->multiple) {
	case multiple_last:
	    {
		void *v_data = cli_realloc2(ev->u.v_data, len);
		if (v_data) {
		    ev->u.v_data = v_data;
		    memcpy(v_data, data, len);
		    ev->count = len;
		} else {
		    cli_event_error_oom(ctx, len);
		}
		break;
	    }
	case multiple_concat:
	    {
		void *v_data = cli_realloc2(ev->u.v_data, ev->count + len);
		if (v_data) {
		    ev->u.v_data = v_data;
		    memcpy((char*)v_data + ev->count, data, len);
		    ev->count += len;
		} else {
		    cli_event_error_oom(ctx, ev->count + len);
		}
		break;
	    }
    }
}
コード例 #3
0
ファイル: macho.c プロジェクト: badania/clamav-devel
int cli_scanmacho(cli_ctx *ctx, struct cli_exe_info *fileinfo)
{
	struct macho_hdr hdr;
	struct macho_load_cmd load_cmd;
	struct macho_segment_cmd segment_cmd;
	struct macho_segment_cmd64 segment_cmd64;
	struct macho_section section;
	struct macho_section64 section64;
	unsigned int i, j, sect = 0, conv, m64, nsects, matcher = 0;
	unsigned int arch = 0, ep = 0, err;
	struct cli_exe_section *sections = NULL;
	char name[16];
	fmap_t *map = *ctx->fmap;
	ssize_t at;

    if(fileinfo)
	matcher = 1;

    if(fmap_readn(map, &hdr, 0, sizeof(hdr)) != sizeof(hdr)) {
	cli_dbgmsg("cli_scanmacho: Can't read header\n");
	return matcher ? -1 : CL_EFORMAT;
    }
    at = sizeof(hdr);

    if(hdr.magic == 0xfeedface) {
	conv = 0;
	m64 = 0;
    } else if(hdr.magic == 0xcefaedfe) {
	conv = 1;
	m64 = 0;
    } else if(hdr.magic == 0xfeedfacf) {
	conv = 0;
	m64 = 1;
    } else if(hdr.magic == 0xcffaedfe) {
	conv = 1;
	m64 = 1;
    } else {
	cli_dbgmsg("cli_scanmacho: Incorrect magic\n");
	return matcher ? -1 : CL_EFORMAT;
    }

    switch(EC32(hdr.cpu_type, conv)) {
	case 7:
	    if(!matcher)
		cli_dbgmsg("MACHO: CPU Type: Intel 32-bit\n");
	    arch = 1;
	    break;
	case 7 | 0x1000000:
	    if(!matcher)
		cli_dbgmsg("MACHO: CPU Type: Intel 64-bit\n");
	    break;
	case 12:
	    if(!matcher)
		cli_dbgmsg("MACHO: CPU Type: ARM\n");
	    break;
	case 14:
	    if(!matcher)
		cli_dbgmsg("MACHO: CPU Type: SPARC\n");
	    break;
	case 18:
	    if(!matcher)
		cli_dbgmsg("MACHO: CPU Type: POWERPC 32-bit\n");
	    arch = 2;
	    break;
	case 18 | 0x1000000:
	    if(!matcher)
		cli_dbgmsg("MACHO: CPU Type: POWERPC 64-bit\n");
	    arch = 3;
	    break;
	default:
	    if(!matcher)
		cli_dbgmsg("MACHO: CPU Type: ** UNKNOWN ** (%u)\n", EC32(hdr.cpu_type, conv));
	    break;
    }

    if(!matcher) switch(EC32(hdr.filetype, conv)) {
	case 0x1: /* MH_OBJECT */
	    cli_dbgmsg("MACHO: Filetype: Relocatable object file\n");
	    break;
	case 0x2: /* MH_EXECUTE */
	    cli_dbgmsg("MACHO: Filetype: Executable\n");
	    break;
	case 0x3: /* MH_FVMLIB */
	    cli_dbgmsg("MACHO: Filetype: Fixed VM shared library file\n");
	    break;
	case 0x4: /* MH_CORE */
	    cli_dbgmsg("MACHO: Filetype: Core file\n");
	    break;
	case 0x5: /* MH_PRELOAD */
	    cli_dbgmsg("MACHO: Filetype: Preloaded executable file\n");
	    break;
	case 0x6: /* MH_DYLIB */
	    cli_dbgmsg("MACHO: Filetype: Dynamically bound shared library\n");
	    break;
	case 0x7: /* MH_DYLINKER */
	    cli_dbgmsg("MACHO: Filetype: Dynamic link editor\n");
	    break;
	case 0x8: /* MH_BUNDLE */
	    cli_dbgmsg("MACHO: Filetype: Dynamically bound bundle file\n");
	    break;
	case 0x9: /* MH_DYLIB_STUB */
	    cli_dbgmsg("MACHO: Filetype: Shared library stub for static\n");
	    break;
	default:
	    cli_dbgmsg("MACHO: Filetype: ** UNKNOWN ** (0x%x)\n", EC32(hdr.filetype, conv));
    }

    if(!matcher) {
	cli_dbgmsg("MACHO: Number of load commands: %u\n", EC32(hdr.ncmds, conv));
	cli_dbgmsg("MACHO: Size of load commands: %u\n", EC32(hdr.sizeofcmds, conv));
    }

    if(m64)
	at += 4;

    hdr.ncmds = EC32(hdr.ncmds, conv);
    if(!hdr.ncmds || hdr.ncmds > 1024) {
	cli_dbgmsg("cli_scanmacho: Invalid number of load commands (%u)\n", hdr.ncmds);
	RETURN_BROKEN;
    }

    for(i = 0; i < hdr.ncmds; i++) {
	if(fmap_readn(map, &load_cmd, at, sizeof(load_cmd)) != sizeof(load_cmd)) {
	    cli_dbgmsg("cli_scanmacho: Can't read load command\n");
	    free(sections);
	    RETURN_BROKEN;
	}
	at += sizeof(load_cmd);
	/*
	if((m64 && EC32(load_cmd.cmdsize, conv) % 8) || (!m64 && EC32(load_cmd.cmdsize, conv) % 4)) {
	    cli_dbgmsg("cli_scanmacho: Invalid command size (%u)\n", EC32(load_cmd.cmdsize, conv));
	    free(sections);
	    RETURN_BROKEN;
	}
	*/
	load_cmd.cmd = EC32(load_cmd.cmd, conv);
	if((m64 && load_cmd.cmd == 0x19) || (!m64 && load_cmd.cmd == 0x01)) { /* LC_SEGMENT */
	    if(m64) {
		if(fmap_readn(map, &segment_cmd64, at, sizeof(segment_cmd64)) != sizeof(segment_cmd64)) {
		    cli_dbgmsg("cli_scanmacho: Can't read segment command\n");
		    free(sections);
		    RETURN_BROKEN;
		}
		at += sizeof(segment_cmd64);
		nsects = EC32(segment_cmd64.nsects, conv);
		strncpy(name, segment_cmd64.segname, sizeof(name));
        name[sizeof(name)-1] = '\0';
	    } else {
		if(fmap_readn(map, &segment_cmd, at, sizeof(segment_cmd)) != sizeof(segment_cmd)) {
		    cli_dbgmsg("cli_scanmacho: Can't read segment command\n");
		    free(sections);
		    RETURN_BROKEN;
		}
		at += sizeof(segment_cmd);
		nsects = EC32(segment_cmd.nsects, conv);
		strncpy(name, segment_cmd.segname, sizeof(name));
	    }
	    if(!matcher) {
		name[sizeof(name)-1] = '\0';
		cli_dbgmsg("MACHO: Segment name: %s\n", name);
		cli_dbgmsg("MACHO: Number of sections: %u\n", nsects);
	    }
	    if(nsects > 255) {
		cli_dbgmsg("cli_scanmacho: Invalid number of sections\n");
		free(sections);
		RETURN_BROKEN;
	    }
	    if(!nsects) {
		if(!matcher)
		    cli_dbgmsg("MACHO: ------------------\n");
		continue;
	    }
	    sections = (struct cli_exe_section *) cli_realloc2(sections, (sect + nsects) * sizeof(struct cli_exe_section));
	    if(!sections) {
		cli_errmsg("cli_scanmacho: Can't allocate memory for 'sections'\n");
		return matcher ? -1 : CL_EMEM;
	    }

	    for(j = 0; j < nsects; j++) {
		if(m64) {
		    if(fmap_readn(map, &section64, at, sizeof(section64)) != sizeof(section64)) {
			cli_dbgmsg("cli_scanmacho: Can't read section\n");
			free(sections);
			RETURN_BROKEN;
		    }
		    at += sizeof(section64);
		    sections[sect].rva = EC64(section64.addr, conv);
		    sections[sect].vsz = EC64(section64.size, conv);
		    sections[sect].raw = EC32(section64.offset, conv);
		    section64.align = 1 << EC32(section64.align, conv);
		    sections[sect].rsz = sections[sect].vsz + (section64.align - (sections[sect].vsz % section64.align)) % section64.align; /* most likely we can assume it's the same as .vsz */
		    strncpy(name, section64.sectname, sizeof(name));
		} else {
		    if(fmap_readn(map, &section, at, sizeof(section)) != sizeof(section)) {
			cli_dbgmsg("cli_scanmacho: Can't read section\n");
			free(sections);
			RETURN_BROKEN;
		    }
		    at += sizeof(section);
		    sections[sect].rva = EC32(section.addr, conv);
		    sections[sect].vsz = EC32(section.size, conv);
		    sections[sect].raw = EC32(section.offset, conv);
		    section.align = 1 << EC32(section.align, conv);
		    sections[sect].rsz = sections[sect].vsz + (section.align - (sections[sect].vsz % section.align)) % section.align;
		    strncpy(name, section.sectname, sizeof(name));
		}
		if(!matcher) {
		    name[sizeof(name)-1] = '\0';
		    cli_dbgmsg("MACHO: --- Section %u ---\n", sect);
		    cli_dbgmsg("MACHO: Name: %s\n", name);
		    cli_dbgmsg("MACHO: Virtual address: 0x%x\n", (unsigned int) sections[sect].rva);
		    cli_dbgmsg("MACHO: Virtual size: %u\n", (unsigned int) sections[sect].vsz);
		    cli_dbgmsg("MACHO: Raw size: %u\n", (unsigned int) sections[sect].rsz);
		    if(sections[sect].raw)
			cli_dbgmsg("MACHO: File offset: %u\n", (unsigned int) sections[sect].raw);
		}
		sect++;
	    }
	    if(!matcher)
		cli_dbgmsg("MACHO: ------------------\n");

	} else if(arch && (load_cmd.cmd == 0x4 || load_cmd.cmd == 0x5)) { /* LC_(UNIX)THREAD */
	    at += 8;
	    switch(arch) {
		case 1: /* x86 */
		{
			struct macho_thread_state_x86 thread_state_x86;

		    if(fmap_readn(map, &thread_state_x86, at, sizeof(thread_state_x86)) != sizeof(thread_state_x86)) {
			cli_dbgmsg("cli_scanmacho: Can't read thread_state_x86\n");
			free(sections);
			RETURN_BROKEN;
		    }
		    at += sizeof(thread_state_x86);
		    break;
		}

		case 2: /* PPC */
		{
			struct macho_thread_state_ppc thread_state_ppc;

		    if(fmap_readn(map, &thread_state_ppc, at, sizeof(thread_state_ppc)) != sizeof(thread_state_ppc)) {
			cli_dbgmsg("cli_scanmacho: Can't read thread_state_ppc\n");
			free(sections);
			RETURN_BROKEN;
		    }
		    at += sizeof(thread_state_ppc);
		    ep = EC32(thread_state_ppc.srr0, conv);
		    break;
		}

		case 3: /* PPC64 */
		{
			struct macho_thread_state_ppc64 thread_state_ppc64;

		    if(fmap_readn(map, &thread_state_ppc64, at, sizeof(thread_state_ppc64)) != sizeof(thread_state_ppc64)) {
			cli_dbgmsg("cli_scanmacho: Can't read thread_state_ppc64\n");
			free(sections);
			RETURN_BROKEN;
		    }
		    at += sizeof(thread_state_ppc64);
		    ep = EC64(thread_state_ppc64.srr0, conv);
		    break;
		}
		default:
		    cli_errmsg("cli_scanmacho: Invalid arch setting!\n");
		    free(sections);
		    return matcher ? -1 : CL_EARG;
	    }
	} else {
	    if(EC32(load_cmd.cmdsize, conv) > sizeof(load_cmd))
		at += EC32(load_cmd.cmdsize, conv) - sizeof(load_cmd);
	}
    }

    if(ep) {
	if(!matcher)
	    cli_dbgmsg("Entry Point: 0x%x\n", ep);
	if(sections) {
	    ep = cli_rawaddr(ep, sections, sect, &err);
	    if(err) {
		cli_dbgmsg("cli_scanmacho: Can't calculate EP offset\n");
		free(sections);
		return matcher ? -1 : CL_EFORMAT;
	    }
	    if(!matcher)
		cli_dbgmsg("Entry Point file offset: %u\n", ep);
	}
    }

    if(matcher) {
	fileinfo->ep = ep;
	fileinfo->nsections = sect;
	fileinfo->section = sections;
	return 0;
    } else {
	free(sections);
	return CL_SUCCESS;
    }
}