Example #1
0
/**
 *	@brief	Does the actual analysis
 */
void perform_analysis(const std::string& path,
					  po::variables_map& vm,
					  const std::string& extraction_directory,
					  const std::vector<std::string> selected_categories,
					  const std::vector<std::string> selected_plugins,
					  const config& conf,
					  boost::shared_ptr<io::OutputFormatter> formatter)
{
	mana::PE pe(path);

	// Try to parse the PE
	if (!pe.is_valid())
	{
		PRINT_ERROR << "Could not parse " << path << "!" << std::endl;
		yara::Yara y = yara::Yara();
		// In case of failure, we try to detect the file type to inform the user.
		// Maybe they made a mistake and specified a wrong file?
		if (bfs::exists(path) &&
			!bfs::is_directory(path) &&
			y.load_rules("yara_rules/magic.yara"))
		{
			yara::const_matches m = y.scan_file(*pe.get_path());
			if (m && m->size() > 0)
			{
				std::cerr << "Detected file type(s):" << std::endl;
				for (auto it = m->begin() ; it != m->end() ; ++it) {
					std::cerr << "\t" << (*it)->operator[]("description") << std::endl;
				}
			}
		}
		std::cerr << std::endl;
		return;
	}

	if (vm.count("dump")) {
		handle_dump_option(*formatter, selected_categories, vm.count("hashes") != 0, pe);
	}
	else { // No specific info requested. Display the summary of the PE.
		dump_summary(pe, *formatter);
	}


	if (vm.count("extract")) { // Extract resources if requested
		mana::extract_resources(pe, extraction_directory);
	}

	if (vm.count("hashes")) {
		dump_hashes(pe, *formatter);
	}

	if (vm.count("plugins")) {
		handle_plugins_option(*formatter, selected_plugins, conf, pe);
	}
}
Example #2
0
int main(int argc, char **argv) {

	int i;
	char *logfile_name=NULL;
	unsigned int seed=0;
	int sample_rate,paranoid,kernel_watchdog;
	FILE *fff;
	struct utsname uname_info;
	char cpuinfo[BUFSIZ];
	int seed_specified=0;
	int c,j,missing=0;
	time_t timer;
	char buffer[26];
	struct tm* tm_info;
	struct timeval current_time;
	long long interval_start=0;
	double rate;

	/*********************************/
	/* Parse command line parameters */
	/*********************************/

	while ((c=getopt(argc, argv,"hvl:r:s:t:"))!=-1) {
		switch(c) {
			case 'h':	/* help */
				usage(argv[0],1);
				exit(0);
				break;
			case 'v':	/* version */
				usage(argv[0],0);
				exit(0);
				break;
			case 'l':	/* log */
				logging=TYPE_ALL;
				logfile_name=strdup(optarg);
				break;
			case 'r':	/* seed */
				seed=atoi(optarg);
				seed_specified=1;
				printf("Using user-specified random seed of %d\n",seed);
				break;
			case 's':	/* stop */
				stop_after=atoi(optarg);
				break;

			case 't':	/* type */
				type=0;

				for(j=0;j<strlen(optarg);j++) {
					switch(optarg[j]) {
					case 'O': type|=TYPE_OPEN; break;
					case 'C': type|=TYPE_CLOSE; break;
					case 'I': type|=TYPE_IOCTL; break;
					case 'R': type|=TYPE_READ; break;
					case 'M': type|=TYPE_MMAP; break;
					case 'F': type|=TYPE_FORK; break;
					case 'Q': type|=TYPE_TRASH_MMAP; break;
					case 'W': type|=TYPE_WRITE; break;
					case 'P': type|=TYPE_PRCTL; break;
					case 'p': type|=TYPE_POLL; break;
					case 'A': type|=TYPE_ACCESS; break;
					case 'o': type|=TYPE_OVERFLOW; break;
					case 'i': type|=TYPE_MILLION; break;
					default: printf("Unknown type %c\n",
							optarg[j]);
					}
				}
				break;
			default:
				usage(argv[0],1);
				exit(1);
				break;
		}

	}

	/****************/
	/* Open logfile */
	/****************/

	if (logging) {

		if (!strcmp(logfile_name,"-")) {
			log_fd=1;		/* stdout */
		}
		else {
			log_fd=open(logfile_name,O_WRONLY|O_CREAT,0660);
			if (log_fd<0) {
				fprintf(stderr,"Error opening %s: %s\n",
					logfile_name,strerror(errno));
				exit(1);
			}
			fprintf(stderr,"Warning! Using a named log file might disrupt determinism due to the extra file descriptor created.  Consider logging to stdout instead\n\n");
		}
	}

	/****************/
	/* Print banner */
	/****************/

	printf("\n*** perf_fuzzer %s *** by Vince Weaver\n\n",VERSION);

	/*****************/
	/* Print OS info */
	/*****************/

	uname(&uname_info);

	printf("\t%s version %s %s\n",
		uname_info.sysname,uname_info.release,uname_info.machine);

	/*****************/
	/* Print cpuinfo */
	/*****************/

	get_cpuinfo(cpuinfo);
	printf("\tProcessor: %s\n",cpuinfo);

	/*****************/
	/* Print options */
	/*****************/

	if (stop_after)	printf("\tStopping after %d\n",stop_after);
	/* TODO: Make these configurable */
	printf("\tWatchdog enabled with timeout %ds\n",WATCHDOG_TIMEOUT);
	printf("\tWill auto-exit if signal storm detected\n");

	/**********************/
	/* Print logging info */
	/**********************/
	if (logging) {
		printf("\tLogging to file: %s\n",logfile_name);
		printf("\tLogging perf_event_open() failures: %s\n",
			LOG_FAILURES?"yes":"no");
		printf("\tRunning fsync after every syscall: %s\n",
			FSYNC_EVERY?"yes":"no");
	}

	/************************************/
	/* Seed the random number generator */
	/************************************/

	/* should read /dev/urandom instead? */
	if (!seed) {
		seed=time(NULL);
		printf("\tSeeding RNG from time %d\n",seed);
	}
	else {
		printf("\tSeeding RNG with supplied seed %d\n",seed);
	}
	srand(seed);

	/* Write seed to disk so we can find it later */
	fff=fopen("last.seed","w");
	if (fff!=NULL) {
		fprintf(fff,"%d\n",seed);
		fclose(fff);
	}

	if (logging) {
		sprintf(log_buffer,"S %d\n",seed);
		write(log_fd,log_buffer,strlen(log_buffer));
	}

	/************************/
	/* setup watchdog timer */
	/************************/

	/* FIXME: make optional */
        struct sigaction watchdog;

        memset(&watchdog, 0, sizeof(struct sigaction));
        watchdog.sa_sigaction = alarm_handler;
        watchdog.sa_flags = SA_SIGINFO | SA_RESTART;

        if (sigaction( SIGALRM, &watchdog, NULL) < 0) {
                printf("Error setting up alarm handler\n");
        }

        alarm(WATCHDOG_TIMEOUT);

	/******************************/
	/* Initialize data structures */
	/******************************/

	/* Clear errnos count */
	for(i=0;i<MAX_ERRNOS;i++) {
		stats.open_errno_count[i]=0;
		stats.fork_errno_count[i]=0;
	}

	/* Clear type counts */
	for(i=0;i<MAX_OPEN_TYPE;i++) {
		stats.open_type_success[i]=0;
		stats.open_type_fail[i]=0;
	}

	/* Save our pid so we can re-map on replay */
	if (logging) {
		sprintf(log_buffer,"G %d\n",getpid());
		write(log_fd,log_buffer,strlen(log_buffer));
	}

	/* Save the content of /proc/sys/kernel/perf_event_max_sample_rate */
	/* If it has been changed, a replay might not be perfect */
	sample_rate=get_sample_rate();
	if (logging) {
		sprintf(log_buffer,"r %d\n",sample_rate);
		write(log_fd,log_buffer,strlen(log_buffer));
	}

	/* Check kernel watchdog */
	kernel_watchdog=get_kernel_watchdog_value();

	/* Check paranoid setting */
	paranoid=get_paranoid_value();

	/*******************************/
	/* Print reproduce information */
	/*******************************/

	printf("\n\tTo reproduce, try:\n");
	printf("\t\techo %d > /proc/sys/kernel/nmi_watchdog\n",
		kernel_watchdog);
	printf("\t\techo %d > /proc/sys/kernel/perf_event_paranoid\n",
		paranoid);
	printf("\t\techo %d > /proc/sys/kernel/perf_event_max_sample_rate\n",
		sample_rate);

	printf("\t\t");
	for(i=0;i<argc;i++) {
		printf("%s ",argv[i]);
	}

	if (!seed_specified) printf("-r %d",seed);

	printf("\n\n");



	/* Print what we are actually fuzzing */
	/* Sometimes I comment out code and forget */

	missing=0;

	printf("\tFuzzing the following syscalls: ");
	if (type&TYPE_MMAP)  printf("mmap "); else missing++;
	if (type&TYPE_OPEN)  printf("perf_event_open "); else missing++;
	if (type&TYPE_CLOSE) printf("close "); else missing++;
	if (type&TYPE_READ)  printf("read "); else missing++;
	if (type&TYPE_WRITE) printf("write "); else missing++;
	if (type&TYPE_IOCTL) printf("ioctl "); else missing++;
	if (type&TYPE_FORK)  printf("fork "); else missing++;
	if (type&TYPE_PRCTL) printf("prctl "); else missing++;
	if (type&TYPE_POLL)  printf("poll "); else missing++;
	printf("\n");

	if (missing) {
		printf("\t*NOT* Fuzzing the following syscalls: ");
		if (!(type&TYPE_MMAP)) printf("mmap ");
		if (!(type&TYPE_OPEN)) printf("perf_event_open ");
		if (!(type&TYPE_CLOSE)) printf("close ");
		if (!(type&TYPE_READ)) printf("read ");
		if (!(type&TYPE_WRITE)) printf("write ");
		if (!(type&TYPE_IOCTL)) printf("ioctl ");
		if (!(type&TYPE_FORK)) printf("fork ");
		if (!(type&TYPE_PRCTL)) printf("prctl ");
		if (!(type&TYPE_POLL)) printf("poll ");
		printf("\n");
	}

	missing=0;

	printf("\tAlso attempting the following: ");
	if (type&TYPE_OVERFLOW) printf("signal-handler-on-overflow "); else missing++;
	if (type&TYPE_MILLION) printf("busy-instruction-loop "); else missing++;
	if (type&TYPE_ACCESS) printf("accessing-perf-proc-and-sys-files "); else missing++;
	if (type&TYPE_TRASH_MMAP) printf("trashing-the-mmap-page "); else missing++;
	printf("\n");

	if (missing) {
		printf("\t*NOT* attempting the following: ");
		if (!(type&TYPE_OVERFLOW)) printf("signal-handler-on-overflow ");
		if (!(type&TYPE_MILLION)) printf("busy-instruction-loop ");
		if (!(type&TYPE_ACCESS)) printf("accessing-perf-proc-and-sys-files ");
		if (!(type&TYPE_TRASH_MMAP)) printf("trashing-the-mmap-page ");
		printf("\n");
	}

	if (attempt_determinism) {
		printf("\n\tAttempting more deterministic results by:\n\t");
		printf("waitpid-after-killing-child ");
		printf("disabling-overflow-signal-handler ");
		printf("\n");

		/* Disable overflows if trying for determinism */
		if (attempt_determinism) {
			type&=~TYPE_OVERFLOW;
		}
	}

	/******************************************/
	/* Set up to match trinity setup, vaguely */
	/******************************************/

	page_size=getpagesize();
	//printf("Page size=%d\n",page_size);
	num_online_cpus = sysconf(_SC_NPROCESSORS_ONLN);

	create_shm();
	create_shm_arrays();
	init_shm();

//	init_shared_pages();

	syscall_perf_event_open.init();

	/* Initialize PMU names if possible */
	/* This depends on trinity exporting the values */
	if (pmus!=NULL) {
		for(i=0;i<num_pmus;i++) {
			if (pmus[i].type<MAX_OPEN_TYPE) {
				stats_set_pmu_name(pmus[i].type,pmus[i].name);
			}
		}
	}


	/************************/
	/* Set up SIGIO handler */
	/************************/

	/* In theory we shouldn't get SIGIO as we set up SIGRT for overflow */
	/* But if the RT queue overflows we will get a SIGIO */
	memset(&sigio, 0, sizeof(struct sigaction));
	sigio.sa_sigaction = sigio_handler;
	sigio.sa_flags = SA_SIGINFO;

	if (sigaction( SIGIO, &sigio, NULL) < 0) {
		printf("Error setting up SIGIO signal handler\n");
     	}


	/* Set up SIGQUIT handler */
	memset(&sigquit, 0, sizeof(struct sigaction));
	sigquit.sa_sigaction = sigquit_handler;
	sigquit.sa_flags = SA_SIGINFO;

	if (sigaction( SIGQUIT, &sigquit, NULL) < 0) {
		printf("Error setting up SIGQUIT signal handler\n");
     	}


	/* Initialize Event Structure */
	for(i=0;i<NUM_EVENTS;i++) {
		event_data[i].active=0;
		event_data[i].fd=0;
		event_data[i].read_size=rand();
	}

	/* Sleep to make it easier to ftrace/ptrace */
	printf("\n\tPid=%d, sleeping 1s\n\n",getpid());
	sleep(1);

	/* Print start time */

	time(&timer);
	tm_info = localtime(&timer);

	strftime(buffer, 26, "%Y-%m-%d %H:%M:%S", tm_info);
	printf("==================================================\n");
	printf("Starting fuzzing at %s\n",buffer);
	printf("==================================================\n");


	gettimeofday(&current_time,NULL);
	interval_start=current_time.tv_sec;

	/****************/
	/* MAIN LOOP	*/
	/****************/

	while(1) {

		switch(rand()%11) {
			case 0:	if (type&TYPE_OPEN) {
					open_random_event(type&TYPE_MMAP,
							type&TYPE_OVERFLOW);
				}
				break;
			case 1: if (type&TYPE_CLOSE) {
//					if (rand()%3==0)
						close_random_event();
				}
				break;
			case 2: if (type&TYPE_IOCTL) {
					ioctl_random_event();
				}
				break;
			case 3: if (type&TYPE_PRCTL) {
					prctl_random_event();
				}
				break;
			case 4: if (type&TYPE_READ) {
					read_random_event();
				}
				break;
			case 5: if (type&TYPE_WRITE) {
					write_random_event();
				}
				break;
			case 6: if (type&TYPE_ACCESS) {
					access_random_file();
				}
				break;
			case 7: if (type&TYPE_FORK) {
					fork_random_event();
				}
				break;
			case 8: if (type&TYPE_POLL) {
					poll_random_event();
				}
				break;
			case 9:if (type&TYPE_MMAP) {
					mmap_random_event(type);
				}
				break;
			default:
				if (type&TYPE_MILLION) {
					run_a_million_instructions();
				}
				break;
		}

#if FSYNC_EVERY
		if (logging) fsync(log_fd);
#endif

		if (throttle_close_event) {
			printf("Closing stuck event %d\n",
				throttle_close_event);
			close_event(throttle_close_event,1);
			throttle_close_event=0;
		}

		next_overflow_refresh=rand()%2;
		next_refresh=rand_refresh();
		stats.total_iterations++;
		watchdog_counter++;

		if ((stop_after) && (stats.total_iterations>=stop_after)) {
			long long end_count;

			end_count=stats.total_iterations%
                                        STATUS_UPDATE_INTERVAL;
			if ((end_count==0) && (stats.total_iterations>0)) {
				end_count=STATUS_UPDATE_INTERVAL;
			}

			gettimeofday(&current_time,NULL);
			rate=((double)(end_count))/
				(current_time.tv_sec-interval_start);

			dump_summary(stderr,1,rate);

			/* Kill child, doesn't happen automatically? */
			if (already_forked) {
				int status;
				kill(forked_pid,SIGKILL);
				waitpid(forked_pid, &status, 0);
			}
			return 0;
		}

		/* Print status update every 10000 iterations      */
		/* Don't print if logging to stdout as it clutters */
		/* up the trace file.				   */
		if (stats.total_iterations%STATUS_UPDATE_INTERVAL==0) {

			gettimeofday(&current_time,NULL);
			rate=((double)STATUS_UPDATE_INTERVAL)/
				(current_time.tv_sec-interval_start);

			if (log_fd!=1) {
				dump_summary(stderr,1,rate);
			}
			else {
				dump_summary(stderr,0,rate);
			}

			interval_start=current_time.tv_sec;
		}
//		fsync(log_fd);
	}

	return 0;

}
int git_win32__crtdbg_stacktrace__dump(
	git_win32__crtdbg_stacktrace_options opt,
	const char *label)
{
	_CRT_REPORT_HOOK old;
	unsigned int k;
	int r = 0;

#define IS_BIT_SET(o,b) (((o) & (b)) != 0)

	bool b_set_mark         = IS_BIT_SET(opt, GIT_WIN32__CRTDBG_STACKTRACE__SET_MARK);
	bool b_leaks_since_mark = IS_BIT_SET(opt, GIT_WIN32__CRTDBG_STACKTRACE__LEAKS_SINCE_MARK);
	bool b_leaks_total      = IS_BIT_SET(opt, GIT_WIN32__CRTDBG_STACKTRACE__LEAKS_TOTAL);
	bool b_quiet            = IS_BIT_SET(opt, GIT_WIN32__CRTDBG_STACKTRACE__QUIET);

	if (b_leaks_since_mark && b_leaks_total) {
		giterr_set(GITERR_INVALID, "Cannot combine LEAKS_SINCE_MARK and LEAKS_TOTAL.");
		return GIT_ERROR;
	}
	if (!b_set_mark && !b_leaks_since_mark && !b_leaks_total) {
		giterr_set(GITERR_INVALID, "Nothing to do.");
		return GIT_ERROR;
	}

	EnterCriticalSection(&g_crtdbg_stacktrace_cs);

	if (b_leaks_since_mark || b_leaks_total) {
		/* All variables with "transient" in the name are per-dump counters
		 * and reset before each dump.  This lets us handle checkpoints.
		 */
		g_transient_count_total_leaks = 0;
		g_transient_count_dedup_leaks = 0;
		for (k = 0; k < g_cs_ins; k++) {
			g_cs_rows[k].transient_count_leaks = 0;
		}
	}

	g_transient_leaks_since_mark = b_leaks_since_mark;

	old = _CrtSetReportHook(report_hook);
	_CrtDumpMemoryLeaks();
	_CrtSetReportHook(old);

	if (b_leaks_since_mark || b_leaks_total) {
		r = g_transient_count_dedup_leaks;

		if (!b_quiet)
			dump_summary(label);
	}

	if (b_set_mark) {
		for (k = 0; k < g_cs_ins; k++) {
			g_cs_rows[k].count_allocs_at_last_checkpoint = g_cs_rows[k].count_allocs;
		}

		g_checkpoint_id++;
	}

	LeaveCriticalSection(&g_crtdbg_stacktrace_cs);

	return r;
}