Exemplo n.º 1
0
void libdyninstAPI_RT_init() 
{
   static int initCalledOnce = 0;

   rtdebug_printf("%s[%d]:  DYNINSTinit:  welcome to libdyninstAPI_RT_init()\n", __FILE__, __LINE__);

   if (initCalledOnce) return;
   initCalledOnce++;

#if defined(arch_x86) || defined(arch_x86_64)
   /* Modern x86-32/x86-64 cpus have non-executable data */
   mark_heaps_exec();
#endif

   /* RTmutatedBinary_init(); */
   
   if (libdyninstAPI_RT_init_localCause != -1 && 
       libdyninstAPI_RT_init_localPid != -1 &&
       libdyninstAPI_RT_init_maxthreads != -1)
   {
      DYNINSTinit(libdyninstAPI_RT_init_localCause, libdyninstAPI_RT_init_localPid,
                  libdyninstAPI_RT_init_maxthreads, libdyninstAPI_RT_init_debug_flag);
   }

   rtdebug_printf("%s[%d]:  did DYNINSTinit\n", __FILE__, __LINE__);
}
Exemplo n.º 2
0
/*
 * Invoked by the mutator on thread exit
 */
int DYNINSTunregisterThread(dyntid_t tid) {
    unsigned hash_id, orig;
    unsigned tid_val = (unsigned long) tid;

    int retval = 1;
    rtdebug_printf("%s[%d]: Begin DYNINSTunregisterThread, tid %lu\n", __FILE__, __LINE__,
            dyn_pthread_self());

    if( tc_lock_lock(&DYNINST_index_lock) == DYNINST_DEAD_LOCK ) {
        rtdebug_printf("%s[%d]: DEADLOCK HERE tid %lu\n", __FILE__, __LINE__,
                dyn_pthread_self());
        return 0;
    }

    hash_id = tid_val % DYNINST_thread_hash_size;
    orig = hash_id;
    while(DYNINST_thread_hash_tids[hash_id] != tid) {
        hash_id++;
        if( hash_id == DYNINST_thread_hash_size ) hash_id = 0;
        if( orig == hash_id ) {
            retval = 0;
            break;
        }
    }

    if( retval ) {
        rtdebug_printf("%s[%d]: removed mapping for thread (index = %lu, tid = 0x%lx)\n",
                __FILE__, __LINE__, DYNINST_thread_hash_indices[hash_id], tid);
        DYNINST_thread_hash_indices[hash_id] = IDX_NONE;
        num_free++;
    }

    tc_lock_unlock(&DYNINST_index_lock);
    return retval;
}
Exemplo n.º 3
0
int DYNINSTwriteEvent(void *ev, size_t sz)
{
  ssize_t res;

  if (DYNINSTstaticMode)
     return 0;
  
    rtdebug_printf("%s[%d]:  welcome to DYNINSTwriteEvent: %d bytes\n", __FILE__, __LINE__, sz);
  if (-1 == async_socket)
  {
	  rtdebug_printf("%s[%d]:  failed to DYNINSTwriteEvent, no socket\n", __FILE__, __LINE__);
	  return -1;
  }

try_again:
  res = write(async_socket, ev, sz); 
  if (-1 == res) {
    if (errno == EINTR || errno == EAGAIN) 
       goto try_again;
    else {
       perror("write");
       return -1;
    }
  }
  if ((size_t)res != sz) {
    /*  maybe we need logic to handle partial writes? */
    fprintf(stderr, "%s[%d]:  partial ? write error, %zd bytes, should be %zu\n",
            __FILE__, __LINE__, res, sz);
    return -1;
  }
  return 0;
}
Exemplo n.º 4
0
/* registers the trap handler by calling AddVectoredExceptionHandler
 */
int DYNINSTinitializeTrapHandler()
{
   fake_AVEH_handle = AddVectoredExceptionHandler
      (RT_TRUE, (PVECTORED_EXCEPTION_HANDLER)dyn_trapHandler);
   rtdebug_printf("RTLIB: added vectored trap handler\n");
   return fake_AVEH_handle != 0;
}
Exemplo n.º 5
0
static struct trap_mapping_header *getStaticTrapMap(unsigned long addr)
{
   struct trap_mapping_header *header;
   int i;
   
   tc_lock_lock(&trap_mapping_lock);
   parse_libs();

   i = -1;
   for (;;) {
      i = get_next_set_bitmask(all_headers_current, i);
      assert(i >= 0 && i <= NUM_LIBRARIES);
      if (i == NUM_LIBRARIES) {
         header = NULL;
         rtdebug_printf("%s[%d]:  getStaticTrapMap: returning NULL\n", __FILE__, __LINE__);
         goto done;
      }
      header = all_headers[i];
      if (addr >= header->low_entry && addr <= header->high_entry) {
         goto done;
      }
   }  
 done:
   tc_lock_unlock(&trap_mapping_lock);
   return header;
}
Exemplo n.º 6
0
/**
 * A guaranteed-if-there index lookup 
 **/
unsigned DYNINSTthreadIndexSLOW(dyntid_t tid) {
    unsigned hash_id, orig;
    unsigned retval = DYNINST_NOT_IN_HASHTABLE;
    int index, result;
    unsigned long tid_val = (unsigned long) tid;
    rtdebug_printf("%s[%d]: getting dyninst index lock\n", __FILE__, __LINE__);
    result = tc_lock_lock(&DYNINST_index_lock);
    if (result == DYNINST_DEAD_LOCK) {
        rtdebug_printf("%s[%d]:  DEADLOCK HERE tid %lu \n", __FILE__, __LINE__,
                       dyn_pthread_self());
        /* We specifically return DYNINST_max_num_threads so that instrumentation
         * has someplace safe to scribble in case of an error. */

        /* DO NOT USE print statements here. That's horribly unsafe if we've instrumented
           the output functions, as we'll infinite recurse and die */
        return DYNINST_max_num_threads;
    }
    rtdebug_printf("%s[%d]: got dyninst index lock\n", __FILE__, __LINE__);

    /**
     * Search the hash table
     **/
    if (!DYNINST_thread_hash_size) {
        //Uninitialized tramp guard.
        tc_lock_unlock(&DYNINST_index_lock);
        return DYNINST_max_num_threads;
    }

    hash_id = tid_val % DYNINST_thread_hash_size;
    orig = hash_id;
    for (;;) {
        index = DYNINST_thread_hash_indices[hash_id];
        if (index != IDX_NONE && DYNINST_thread_hash_tids[hash_id] == tid) {
            retval = index;
            break;
        }

        hash_id++;
        if (hash_id == DYNINST_thread_hash_size)
            hash_id = 0;
        if (orig == hash_id)
            break;
    }

    tc_lock_unlock(&DYNINST_index_lock);
    return retval;
}
Exemplo n.º 7
0
// Find the target IP and substitute. Leave everything else untouched.
LONG dyn_trapHandler(PEXCEPTION_POINTERS e)
{
   void *trap_to=0;
   void *trap_addr = (void*) ((unsigned char*)e->ExceptionRecord->ExceptionAddress);
   unsigned long zero = 0;
   unsigned long one = 1;
   unsigned long loadAddr = 0;
   struct trap_mapping_header *hdr = NULL;
   trapMapping_t *mapping = NULL;
   rtdebug_printf("RTLIB: In dyn_trapHandler for exception type 0x%lx at 0x%lx\n",
           e->ExceptionRecord->ExceptionCode, trap_addr);
 
   assert(DYNINSTstaticMode && "detach on the fly not implemented on Windows");

   if (EXCEPTION_BREAKPOINT != e->ExceptionRecord->ExceptionCode) {
      fprintf(stderr,"RTLIB: dyn_trapHandler exiting early, exception "
              "type = 0x%lx triggered at %p is not breakpoint %s[%d]\n",
              e->ExceptionRecord->ExceptionCode, trap_addr, __FILE__,__LINE__);
      return EXCEPTION_CONTINUE_SEARCH;
   }

   hdr = getStaticTrapMap((unsigned long) trap_addr, &loadAddr);
   assert(hdr);
   mapping = &(hdr->traps[0]);

   rtdebug_printf("RTLIB: calling dyninstTrapTranslate(\n\t0x%lx, \n\t"
           "0x%lx, \n\t0x%lx, \n\t0x%lx, \n\t0x%lx)\n", 
           (unsigned long)trap_addr - loadAddr + 1, 
           hdr->num_entries, zero, mapping, one);

   trap_to = dyninstTrapTranslate((void*)((unsigned long)trap_addr - loadAddr + 1),
                                  (unsigned long *) &hdr->num_entries,
                                  &zero, 
                                  (volatile trapMapping_t **) &mapping,
                                  &one);

#ifdef _WIN64
    rtdebug_printf("RTLIB: changing Rip from trap at 0x%lx to 0x%lx\n",
	   e->ContextRecord->Rip, (long)trap_to + loadAddr);
   e->ContextRecord->Rip = (long)trap_to + loadAddr;
#else
   rtdebug_printf("RTLIB: changing Eip from trap at 0x%lx to 0x%lx\n", 
           e->ContextRecord->Eip, (long)trap_to + loadAddr);
   e->ContextRecord->Eip = (long) trap_to + loadAddr;
#endif
   return EXCEPTION_CONTINUE_EXECUTION;
}
Exemplo n.º 8
0
/**
 * Translate a tid given by pthread_self into an index.  Called by 
 * basetramps everywhere.
 **/
int DYNINSTthreadIndex() {
    dyntid_t tid;
    unsigned curr_index;

    rtdebug_printf("%s[%d]:  welcome to DYNINSTthreadIndex()\n", __FILE__, __LINE__);
    if (!DYNINSThasInitialized) {
      rtdebug_printf("%s[%d]: dyninst not initialized, ret false\n", __FILE__, __LINE__);
      return 0;
    }

    tid = (dyntid_t) ((unsigned long)dyn_pthread_self());
    rtdebug_printf("%s[%d]:  DYNINSTthreadIndex(): tid = %lu\n", __FILE__, __LINE__,
                   (unsigned long) tid);
    if (tid == (dyntid_t) DYNINST_SINGLETHREADED) return 0;
    rtdebug_printf("%s[%d]: calling thread index slow (modified)\n", __FILE__, __LINE__);
    curr_index = DYNINSTthreadIndexSLOW(tid);
    rtdebug_printf("%s[%d]: back from thread index slow\n", __FILE__, __LINE__);
    /* While DYNINST_max_num_threads is an error return for
       DYNINSTthreadIndexSLOW(), there's not really anything we
       can do about it at the moment, so just return it
       and let the mutatee scribble into the so-allocated memory. */
    if ( curr_index == DYNINST_NOT_IN_HASHTABLE ) {
        rtdebug_printf("%s[%d]:  DYNINSTthreadIndex(): failed to find index for %lu\n",
                __FILE__, __LINE__, tid);
        curr_index = DYNINST_max_num_threads;
    }

    rtdebug_printf("%s[%d]:  DYNINSTthreadIndex(): returning index: %d\n",
                   __FILE__, __LINE__, curr_index);
    return curr_index;
}
Exemplo n.º 9
0
/*
 * Invoked by the mutator on thread creation
 */
unsigned long DYNINSTregisterThread(dyntid_t tid, unsigned index) {
    unsigned hash_id, orig;
    unsigned long tid_val = (unsigned long) tid;

    unsigned long retval = (unsigned long)dyn_pthread_self();
    assert(retval != 0 );
    rtdebug_printf("%s[%d]: Begin DYNINSTregisterThread, tid %lu\n", __FILE__, __LINE__,
            dyn_pthread_self());

    if( tid_val != retval ) {
        tid_val = retval;
    }

    if( tc_lock_lock(&DYNINST_index_lock) == DYNINST_DEAD_LOCK ) {
       rtdebug_printf("%s[%d]:  DEADLOCK HERE tid %lu \n", __FILE__, __LINE__, 
               dyn_pthread_self());
        return 0;
    }

    hash_id = tid_val % DYNINST_thread_hash_size;
    orig = hash_id;
    while(DYNINST_thread_hash_indices[hash_id] != IDX_NONE) {
        hash_id++;
        if( hash_id == DYNINST_thread_hash_size ) hash_id = 0;
        if( orig == hash_id ) {
            retval = 0;
            break;
        }
    }

    if( retval ) {
        DYNINST_thread_hash_indices[hash_id] = index;
        DYNINST_thread_hash_tids[hash_id] = tid;
        num_free--;
        rtdebug_printf("%s[%d]: created mapping for thread (index = %lu, tid = 0x%lx)\n",
                __FILE__, __LINE__, index, tid);
    }

    tc_lock_unlock(&DYNINST_index_lock);
    return retval;
}
Exemplo n.º 10
0
int DYNINSTasyncDisconnect()
{
   if (DYNINSTstaticMode)
      return 0;
   rtdebug_printf("%s[%d]:  welcome to DYNINSTasyncDisconnect\n", __FILE__, __LINE__);
   if (needToDisconnect) {
      close (async_socket);
      needToDisconnect = 0;
   }
   async_socket = -1;
   return 0;
}
Exemplo n.º 11
0
static int parse_libs()
{
   struct link_map *l_current;

   l_current = _r_debug.r_map;
   if (!l_current) {
        rtdebug_printf("%s[%d]:  parse_libs: _r_debug.r_map was not set\n", __FILE__, __LINE__);
       return -1;
   }

   clear_bitmask(all_headers_current);
   while (l_current) {
      parse_link_map(l_current);
      l_current = l_current->l_next;
   }
   clear_unloaded_libs();

   return 0;
}
Exemplo n.º 12
0
// Check that the address is backed by a file,
// get the binary's load address,
// get the PE header, assuming there is one,
// see if the last section has been tagged with "DYNINST_REWRITE"
// get trap-table header from last binary section's end - label - size
// sets allocBase to the binary's load address
static struct trap_mapping_header *getStaticTrapMap(unsigned long addr, unsigned long *allocBase)
{
   struct trap_mapping_header *header = NULL;
   char fileName[ERROR_STRING_LENGTH];
   DWORD actualNameLen = 0;
   MEMORY_BASIC_INFORMATION memInfo;
   int numSections = 0;
   PIMAGE_NT_HEADERS peHdr = NULL;
   IMAGE_SECTION_HEADER curSecn;
   int sidx=0;
   char *str=NULL;

   //check that the address is backed by a file
   actualNameLen = GetMappedFileName(GetCurrentProcess(), 
                                     (LPVOID)addr, 
                                     fileName, 
                                     ERROR_STRING_LENGTH);
   if (!actualNameLen) {
      fileName[0] = '\0';
      goto done; // no file mapped at trap address
   }
   fileName[ERROR_STRING_LENGTH-1] = '\0';

   // get the binary's load address, size
   if (!VirtualQuery((LPCVOID)addr, &memInfo, sizeof(memInfo)) 
       || MEM_COMMIT != memInfo.State) 
   {
      fprintf(stderr, "ERROR IN RTLIB: getStaticTrapMap %s[%d]\n", __FILE__,__LINE__);
      goto done; // shouldn't be possible given previous query, but hey
   }
   *allocBase = (unsigned long) memInfo.AllocationBase;

   rtdebug_printf("RTLIB: getStaticTrapMap addr=%lx meminfo.BaseAddress=%lx "
                  "meminfo.AllocationBase = %lx, memInfo.RegionSize = %lx, "
                  "%s[%d]\n", addr, memInfo.BaseAddress, 
                  memInfo.AllocationBase, memInfo.RegionSize, 
                  __FILE__,__LINE__);

   // get the PE header, assuming there is one
   peHdr = ImageNtHeader( memInfo.AllocationBase );
   if (!peHdr) {
      fprintf(stderr, "ERROR IN RTLIB: getStaticTrapMap %s[%d]\n", __FILE__,__LINE__);
      goto done; // no pe header
   }

   // see if the last section has been tagged with "DYNINST_REWRITE"
   numSections = peHdr->FileHeader.NumberOfSections;
   curSecn = *(PIMAGE_SECTION_HEADER)
            (((unsigned char*)peHdr) 
            + sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER) 
            + peHdr->FileHeader.SizeOfOptionalHeader
            + sizeof(IMAGE_SECTION_HEADER)*(numSections-1));

   //fprintf(stderr, "RTLIB: PE section header address = %lx\n", curSecn);
   //fprintf(stderr, "curSecn.chars = %lx %s[%d]\n",curSecn.Characteristics, __FILE__,__LINE__);
   if ((sizeof(void*) + 16) > curSecn.SizeOfRawData) {
      fprintf(stderr, "ERROR IN RTLIB: getStaticTrapMap %s[%d]\n", __FILE__,__LINE__);
      goto done; // last section is uninitialized, doesn't have trap table
   }

   //fprintf(stderr, "RTLIB %s[%d]\n", __FILE__,__LINE__);
   //fprintf(stderr, "RTLIB mi.ab =%lx cs.va =%lx cs.srd=%lx %s[%d]\n", memInfo.AllocationBase, curSecn.VirtualAddress, curSecn.SizeOfRawData, __FILE__,__LINE__);
   str = (char*)((long)memInfo.AllocationBase 
                 + curSecn.VirtualAddress 
                 + curSecn.SizeOfRawData 
                 - 16);
   if (0 != strncmp("DYNINST_REWRITE", str, 15)) {
      fprintf(stderr, "ERROR IN RTLIB: getStaticTrapMap found bad string [%s] at %lx %s[%d]\n", 
              str, str, __FILE__,__LINE__);
      goto done; // doesn't have DYNINST_REWRITE label
   }

   // get trap-table header
   header = (struct trap_mapping_header*) 
       ( (unsigned long)memInfo.AllocationBase + *((unsigned long*)(str - sizeof(void*))) );

done: 
   if (header) {
       rtdebug_printf( "RTLIB: found trap map header at %lx: [%lx %lx]\n", 
              (unsigned long) header, header->low_entry, header->high_entry);
   } else {
      rtdebug_printf( "ERROR: didn't find trap table\n");
   }
   return header;
}
Exemplo n.º 13
0
int DYNINSTasyncConnect(int pid)
{
   if (DYNINSTstaticMode)
      return 0;
#if defined (os_vxworks)
   return 1;

#elif defined (cap_async_events)
  int sock_fd;
  struct sockaddr_un sadr;
   int res;
   int mutatee_pid;
   uid_t euid;

   rtdebug_printf("%s[%d]:  DYNINSTasyncConnnect:  entry\n", __FILE__, __LINE__);
   rtdebug_printf("%s[%d]:  DYNINSTinit:  before geteuid\n", __FILE__, __LINE__);

   euid = geteuid();
   passwd_info = getpwuid(euid);
   assert(passwd_info);

  if (async_socket != -1)
  {
	  fprintf(stderr, "%s[%d]: - DYNINSTasyncConnect already initialized\n",
			  __FILE__, __LINE__);

     rtdebug_printf("%s[%d]:  DYNINSTasyncConnnect:  already connected\n", 
			 __FILE__, __LINE__);
     return 0;
  }

  rtdebug_printf("%s[%d]:  DYNINSTasyncConnnect:  before socket 2\n", __FILE__, __LINE__);
  mutatee_pid = getpid();

  snprintf(socket_path, (size_t) 255, "%s/dyninstAsync.%s.%d.%d", 
		  P_tmpdir, passwd_info->pw_name, pid, mutatee_pid);

  rtdebug_printf("%s[%d]:  DYNINSTasyncConnnect:  before socket: %s\n", __FILE__, __LINE__, socket_path);

  errno = 0;

  sock_fd = socket(PF_UNIX, SOCK_STREAM, 0);

  if (sock_fd < 0) 
  {
    fprintf(stderr, "%s[%d]: DYNINSTasyncConnect() socket(%s): %s\n", 
			__FILE__, __LINE__, socket_path, strerror(errno));
    abort();
  }

  rtdebug_printf("%s[%d]:  DYNINSTasyncConnnect:  after socket\n", __FILE__, __LINE__);

  sadr.sun_family = PF_UNIX;
  strcpy(sadr.sun_path, socket_path);

  rtdebug_printf("%s[%d]:  DYNINSTasyncConnnect:  before connect\n", __FILE__, __LINE__);
  res = 0;
  errno = 0;

  res = connect(sock_fd, (struct sockaddr *) &sadr, sizeof(sadr)); 

  if (res < 0)
  {
    perror("DYNINSTasyncConnect() connect()");
  }

  rtdebug_printf("%s[%d]:  DYNINSTasyncConnnect:  after connect to %s, res = %d, -- %s\n", 
		  __FILE__, __LINE__, socket_path, res, strerror(errno));

  /* maybe need to do fcntl to set nonblocking writes on this fd */

  if (async_socket == -1)
  {
	  rtdebug_printf("%s[%d]:  WARN:  async socket has not been reset!!\n", __FILE__, __LINE__);
  }

  async_socket = sock_fd;

  needToDisconnect = 1;

 /* atexit(exit_func); */
  rtdebug_printf("%s[%d]:  leaving DYNINSTasyncConnect\n", __FILE__, __LINE__);
  return 1; 
#else
  fprintf(stderr, "%s[%d]:  called DYNINSTasyncConect when async_events disabled\n",
		  __FILE__, __LINE__);
  return 0;
#endif
}