Exemplo n.º 1
0
/*
 * syscall enter notification (analysis function)
 *
 * save the system call context and invoke the pre-syscall callback
 * function (if registered)
 *
 * @tid:	thread id
 * @ctx:	CPU context
 * @std:	syscall standard (e.g., Linux IA-32, IA-64, etc)
 * @v:		callback value
 */
static void
sysenter_save(THREADID tid, CONTEXT *ctx, SYSCALL_STANDARD std, VOID *v)
{
	/* get the thread context */
	thread_ctx_t *thread_ctx = (thread_ctx_t *)
		PIN_GetContextReg(ctx, thread_ctx_ptr);

	/* get the syscall number */
	size_t syscall_nr = PIN_GetSyscallNumber(ctx, std);

	/* unknown syscall; optimized branch */
	if (unlikely(syscall_nr >= SYSCALL_MAX)) {
		LOG(string(__func__) + ": unknown syscall (num=" +
				decstr(syscall_nr) + ")\n");
		/* syscall number is set to -1; hint for the sysexit_save() */
		thread_ctx->syscall_ctx.nr = -1;
		/* no context save and no pre-syscall callback invocation */
		return;
	}

	/* pass the system call number to sysexit_save() */
	thread_ctx->syscall_ctx.nr = syscall_nr;

	/*
	 * check if we need to save the arguments for that syscall
	 *
	 * we save only when we have a callback registered or the syscall
	 * returns a value in the arguments
	 */
	if (syscall_desc[syscall_nr].save_args |
		syscall_desc[syscall_nr].retval_args) {
		/*
		 * dump only the appropriate number of arguments
		 * or yet another lame way to avoid a loop (vpk)
		 */
		switch (syscall_desc[syscall_nr].nargs) {
			/* 6 */
			case SYSCALL_ARG5 + 1:
				thread_ctx->syscall_ctx.arg[SYSCALL_ARG5] =
					PIN_GetSyscallArgument(ctx,
								std,
								SYSCALL_ARG5);
			/* 5 */
			case SYSCALL_ARG4 + 1:
				thread_ctx->syscall_ctx.arg[SYSCALL_ARG4] =
					PIN_GetSyscallArgument(ctx,
								std,
								SYSCALL_ARG4);
			/* 4 */
			case SYSCALL_ARG3 + 1:
				thread_ctx->syscall_ctx.arg[SYSCALL_ARG3] =
					PIN_GetSyscallArgument(ctx,
								std,
								SYSCALL_ARG3);
			/* 3 */
			case SYSCALL_ARG2 + 1:
				thread_ctx->syscall_ctx.arg[SYSCALL_ARG2] =
					PIN_GetSyscallArgument(ctx,
								std,
								SYSCALL_ARG2);
			/* 2 */
			case SYSCALL_ARG1 + 1:
				thread_ctx->syscall_ctx.arg[SYSCALL_ARG1] =
					PIN_GetSyscallArgument(ctx,
								std,
								SYSCALL_ARG1);
			/* 1 */
			case SYSCALL_ARG0 + 1:
				thread_ctx->syscall_ctx.arg[SYSCALL_ARG0] =
					PIN_GetSyscallArgument(ctx,
								std,
								SYSCALL_ARG0);
			/* default */
			default:
				/* nothing to do */
				break;
		}

		/*
		 * dump the architectural state of the processor;
		 * saved as "auxiliary" data
		 */
		thread_ctx->syscall_ctx.aux = ctx;

		/* call the pre-syscall callback (if any) */
		if (syscall_desc[syscall_nr].pre != NULL)
			syscall_desc[syscall_nr].pre(&thread_ctx->syscall_ctx);
	}
}
Exemplo n.º 2
0
int whiteList_init(struct whiteList* list, const char* file_name){
	FILE* 	file = NULL;
	long 	size;
	int 	i;
	int 	n;

	list->buffer = NULL;

	if ((file = fopen(file_name, "rb")) == NULL){
		LOG("ERROR: unable to open file: ");
		LOG(file_name);
		LOG("\n");
		goto error;
	}

	if (fseek(file, 0, SEEK_END)){
		LOG("ERROR: unable to fseek\n");
		goto error;
	}
	
	size = ftell(file);
	rewind(file);

	if ((list->buffer = (char*)malloc(size + 1)) == NULL){
		LOG("ERROR: unable to allocate memory\n");
		goto error;
	}

	if (fread(list->buffer, 1, size, file) != (size_t)size){
		LOG("ERROR: unable to read file\n");
		goto error;
	}

	fclose(file);
	file = NULL;

	list->buffer[size] = '\0';
	for (i = size; i > 0; ){
		i --;
		if (list->buffer[i] == '\0' || list->buffer[i] == '\n'){
			list->buffer[i] = '\0';
		}
		else{
			break;
		}
	}

	for (i = 0, list->nb_entry = 1; i < size; i++){
		if (list->buffer[i] == '\n'){
			list->nb_entry ++;
			list->buffer[i] = '\0';
		}
	}

	if ((list->entries = (char**)malloc(sizeof(char*)*list->nb_entry)) == NULL){
		LOG("ERROR: unable to allocate memory\n");
		goto error;
	}

	list->entries[0] = list->buffer;
	for (n = 1, i = 0; n < list->nb_entry; n++){
		while ((i < size) && (list->buffer[i] != '\0')){
			i++;
		}
		if (i >= size){
			LOG("ERROR: searching for end of line fails at line " + decstr(n) + ":" + decstr(list->nb_entry) + "\n");
			list->entries[n] = list->entries[n-1];
		}
		else{
			i++;
			list->entries[n] = list->buffer + i;
		}
	}

	qsort(list->entries, list->nb_entry, sizeof(char*), whiteList_compare);	

	return 0;

	error:
	if (file != NULL){
		fclose(file);
	}
	if (list->buffer != NULL){
		free(list->buffer);
	}

	return -1;
}
Exemplo n.º 3
0
void post_write_hook(syscall_ctx_t *ctx) {
	/* ignore write() on not watched fd */
	if (unlikely(fdset.find(_FD) == fdset.end()))
		return;

	/* write() was not successful; optimized branch; errno message may be incorrect */
	if (unlikely(_N_WRITTEN < 0)) {
		LOG("ERROR " _CALL_LOG_STR + " (" + strerror(errno) + ")\n");
		return;
	}

	LOG("OK    " _CALL_LOG_STR + "\n");

	const ufd_t ufd = ufdmap.get(_FD);
	off_t write_begin;
	range_map_t ranges;
	range_map_t ranges_prev;

	/* calculate begining of write */
	if (IS_STDFD(_FD)) {
		write_begin = stdcount[_FD];
		stdcount[_FD] += _N_WRITTEN;
	}
	else {
		write_begin = lseek(_FD, 0, SEEK_CUR) - _N_WRITTEN;
		if ( unlikely(write_begin < 0) ){
			LOG("Error on L" + decstr(__LINE__) + " lseek-ing on fd" + decstr(_FD) + ": " + strerror(errno) + "\n");
			return;
		}
	}

	for(ssize_t i=0; i<_N_WRITTEN; i++) { //loop through memory locations
		tag_t tag = tagmap_getb(_BUF+i);

#ifdef __DEBUG_SYSCALL_WRITE
		LOG("---------------------- " + std::string((char *)(_BUF+i), 1) + "\n");
		LOG("RANGES " + __RANGE2STR(ranges) + "\n");
		LOG("RANGES_PREV " + __RANGE2STR(ranges_prev) + "\n");
#endif

		for (auto & tm : tag) { //loop taint marks for specific location

			// check if a single taint mark from the input is repeated in the output
			auto rlookup = tm;
			auto range_it = ranges_prev.find(rlookup);
			if (range_it != ranges_prev.end()) {
				// LOG("C1\n");
				auto range_last = (*range_it).first;
				auto range_info = (*range_it).second;

				switch(range_info.type) {
					case range_info_t::SEQ:
						// adjust SEQ range
						range_last.second--;
						range_info.length--;
						ranges_prev.insert(range_it, std::make_pair(range_last, range_info));
						ranges_prev.erase(range_it);

						// add a new REP range to next range set
						ranges.insert(std::make_pair(tm, (range_info_t){range_info_t::REP, i-1, 2}));
						continue;

					case range_info_t::NONE:
						// set range type to REP
						range_info.type = range_info_t::REP;

					case range_info_t::REP:
						// add info to next range set
						range_info.length++;
						ranges.insert(std::make_pair(tm, range_info));

						// remove info from previous range set
						ranges_prev.erase(range_it);
						continue;
				}
			}

			// check if a sequence of taint marks from the input also appears in the output
			rlookup = tm;
			rlookup.second -= 1;
			range_it = ranges_prev.find(rlookup);
			if (range_it != ranges_prev.end()) {
				// LOG("C2\n");
				auto range_info = (*range_it).second;

				switch(range_info.type) {
					case range_info_t::REP:
						// start a new range - we won't touch the old one
						ranges.insert(std::make_pair(tm, (range_info_t){range_info_t::NONE, i, 1}));
						continue;

					case range_info_t::NONE:
						// set range type to SEQ
						range_info.type = range_info_t::SEQ;
				
					case range_info_t::SEQ:
						// add info to next range set
						range_info.length++;
						ranges.insert(std::make_pair(tm, range_info));

						// remove info from previous range set
						ranges_prev.erase(range_it);
						continue;		
				}
			}

			// add taint mark as a new range
			// LOG("C3\n");
			rlookup = tm;
			ranges.insert(std::make_pair(rlookup, (range_info_t){range_info_t::NONE, i, 1}));

		} //loop taint marks

#ifdef __DEBUG_SYSCALL_WRITE
		LOG("~~~~~~~~~~~~~~\n");
		LOG("RANGES " + __RANGE2STR(ranges) + "\n");
		LOG("RANGES_PREV " + __RANGE2STR(ranges_prev) + "\n");
#endif

		//dump output for pattern sequences that were broken
		for (auto &tm : ranges_prev)
			PROVLOG_WRITE_RANGE(ufd, write_begin, tm.first, tm.second);

		// swap the two range sets and clear the ranges for next iteration
		ranges.swap(ranges_prev);
		ranges.clear();

	} //loop memory locations

	//dump the remaining pattern sequences
	for (auto &tm : ranges_prev)
		PROVLOG_WRITE_RANGE(ufd, write_begin, tm.first, tm.second);
}
Exemplo n.º 4
0
VOID trace_instrument(TRACE trace, VOID *v){
  for (BBL bbl = TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl)){ 
    /* iterate over all basic blocks */
    
    string codelet_string = "";
    // this writes disassembly 
    char codelet_buffer[65536*2]; int cbs = 0;
    INS head = BBL_InsHead(bbl);
    INS tail = BBL_InsTail(bbl);
    
    ADDRINT stage_entry = INS_Address( head );
    ADDRINT target = 0;
    if (INS_IsCall(tail)){
      if( INS_IsDirectBranchOrCall(tail)){
        target = INS_DirectBranchOrCallTargetAddress(tail);}}

    INS cur ;
    int branch_id = slp_count;
      
    /* If compression is turned off (default), only output the addresses of
     * the BBL once
     */
    if (!KnobNoCompress){
      /* Instrument the head instruction right before it is called, but also
       * before we instrument the instructions in the basic block 
       */
      string msg_pre  = "\n@@BBL(" + decstr( branch_id ) + ") STAGE " + Target2String(stage_entry)->c_str() + "\n" ;
      INS_InsertCall(head, IPOINT_BEFORE, AFUNPTR(string_report),
		     IARG_PTR, new string(msg_pre),
		     IARG_END);
    }
   
    /* Walk the list of instructions inside the BBL. Disassemble each, and add
     * it to the codelet string. Also, instrument each instruction at the
     * point before it is called with the do_count function.
     */
    for ( cur = head; INS_Valid( cur ); cur = INS_Next(cur ) ){
      cbs += sprintf( codelet_buffer + cbs , "\n\t@%llx\t%s", INS_Address( cur ), INS_Disassemble( cur ).c_str() );
      INS_InsertCall(cur, IPOINT_BEFORE, (AFUNPTR)do_count, IARG_ADDRINT, INS_Address( cur ), IARG_END);
    }

    /* Finish off the codelet assembly string with an out message and
     * address ranges of the BBL
     */
    cbs += sprintf( codelet_buffer + cbs , "\n\t}BBL.OUT [%d] %llx - %llx\n", branch_id, INS_Address( head ), INS_Address( tail ));
  
    /* If compression is turned on, output the codelet every single time we
     * hit the same block.
     */
    if(KnobNoCompress){
      INS_InsertCall(tail, IPOINT_BEFORE, AFUNPTR(string_report),
		     IARG_PTR, new string(codelet_buffer),
		     IARG_END);
      slp_count ++;
    }
    else{
      /* add the mapped BBL to output */
      TraceFile.write(codelet_buffer, cbs);	
 
      /* Instrument the tail instruction by inserting just before it is called
      */
      string msg_post = "+@@BBL(" + decstr( branch_id ) + ") ACHIEVE : GOTO " + Target2String(target)->c_str();
      INS_InsertCall(tail, IPOINT_BEFORE, AFUNPTR(string_report),
		     IARG_PTR, new string(msg_post),
		     IARG_END);

      slp_count ++;
    }
  }
}
Exemplo n.º 5
0
string nocrypt(u_char* nocipher)
{
    string decstr(reinterpret_cast<const char*>(nocipher));
    return decstr;
}