char *resize(char *inout_begin, size_t count) {
      intptr_t size_bytes = count * data_size;

      //    cout << "resizing memory " << (void *)*inout_begin << " / " << (void *)*inout_end << " from size " <<
      // (*inout_end - *inout_begin) << " to " << size_bytes << endl;
      //    cout << "memory state before " << (void *)emb->m_memory_begin << " / " << (void *)emb->m_memory_current << "
      //    /
      // " << (void *)emb->m_memory_end << endl;
      char **inout_end = &m_memory_current;
      char *end = inout_begin + size_bytes;
      if (end <= m_memory_end) {
        // If it fits, just adjust the current allocation point
        m_memory_current = end;
        *inout_end = end;
      } else {
        // If it doesn't fit, need to copy to newly malloc'd memory
        char *old_current = inout_begin, *old_end = *inout_end;
        // Allocate memory to double the amount used so far, or the requested size, whichever is larger
        // NOTE: We're assuming malloc produces memory which has good enough alignment for anything
        append_memory(std::max(m_total_allocated_capacity, size_bytes));
        memcpy(m_memory_begin, inout_begin, *inout_end - inout_begin);
        end = m_memory_begin + size_bytes;
        m_memory_current = end;
        inout_begin = m_memory_begin;
        *inout_end = end;
        m_total_allocated_capacity -= old_end - old_current;
      }
      //    cout << "memory state after " << (void *)emb->m_memory_begin << " / " << (void *)emb->m_memory_current << "
      //    /
      // " << (void *)emb->m_memory_end << endl;

      return inout_begin;
    }
Пример #2
0
//--------------------------------------------------------------------------
ssize_t idaapi rpc_debmod_t::dbg_write_memory(ea_t ea, const void *buffer, size_t size)
{
  bytevec_t req = prepare_rpc_packet(RPC_WRITE_MEMORY);
  append_ea64(req, ea);
  append_dd(req, (uint32)size);
  append_memory(req, buffer, size);

  return process_long(req);
}
Пример #3
0
//--------------------------------------------------------------------------
ssize_t rpc_debmod_t::dbg_write_memory(ea_t ea, const void *buffer, size_t size)
{
  qstring cmd = prepare_rpc_packet(RPC_WRITE_MEMORY);
  append_ea(cmd, ea);
  append_long(cmd, (uint32)size);
  append_memory(cmd, buffer, size);

  return process_long(cmd);
}
Пример #4
0
//--------------------------------------------------------------------------
int rpc_debmod_t::dbg_del_bpt(ea_t ea, const uchar *orig_bytes, int len)
{
  qstring cmd = prepare_rpc_packet(RPC_DEL_BPT);
  append_ea(cmd, ea);
  append_long(cmd, len);
  append_memory(cmd, orig_bytes, len);

  return process_long(cmd);
}
 objectarray_memory_block(const ndt::type &dt, size_t arrmeta_size, const char *arrmeta, intptr_t stride,
                          intptr_t initial_count)
     : m_dt(dt), arrmeta_size(arrmeta_size), m_arrmeta(arrmeta), m_stride(stride), m_total_allocated_count(0),
       m_finalized(false), m_memory_handles() {
   if ((dt.get_flags() & type_flag_destructor) == 0) {
     std::stringstream ss;
     ss << "Cannot create objectarray memory block with dynd type " << dt;
     ss << " because it does not have a destructor, use a POD memory block instead";
     throw std::runtime_error(ss.str());
   }
   append_memory(initial_count);
 }
    char *resize(char *previous_allocated, size_t count) {
      memory_chunk *mc = &m_memory_handles.back();
      size_t previous_index = (previous_allocated - mc->memory) / m_stride;
      size_t previous_count = mc->used_count - previous_index;
      char *result = previous_allocated;

      if (mc->capacity_count - previous_index < count) {
        append_memory(std::max(m_total_allocated_count, count));
        memory_chunk *new_mc = &m_memory_handles.back();
        // Move the old memory to the newly allocated block
        if (previous_count > 0) {
          // Subtract the previously used memory from the old chunk's count
          mc->used_count -= previous_count;
          memcpy(new_mc->memory, previous_allocated, previous_count);
          // If the old memory only had the memory being resized,
          // free it completely.
          if (previous_allocated == mc->memory) {
            free(mc->memory);
            // Remove the second-last element of the vector
            m_memory_handles.erase(m_memory_handles.begin() + m_memory_handles.size() - 2);
          }
        }
        mc = &m_memory_handles.back();
        result = mc->memory;
        mc->used_count = count;
      } else {
        // Adjust the used count (this may mean to grow it or shrink it)
        if (count >= previous_count) {
          mc->used_count += (count - previous_count);
        } else {
          // Call the destructor on the elements no longer used
          m_dt.extended()->data_destruct_strided(m_arrmeta + arrmeta_size, previous_allocated + m_stride * count,
                                                 m_stride, previous_count - count);
          mc->used_count -= (previous_count - count);
        }
      }

      if ((m_dt.get_flags() & type_flag_zeroinit) != 0) {
        // Zero-init the new memory
        intptr_t new_count = count - (intptr_t)previous_count;
        if (new_count > 0) {
          memset(mc->memory + m_stride * previous_count, 0, m_stride * new_count);
        }
      } else {
        // TODO: Add a default data constructor to base_type
        //       as well, with a flag for it
        std::stringstream ss;
        ss << "Expected objectarray data to be zeroinit, but is not with dynd type " << m_dt;
        throw std::runtime_error(ss.str());
      }
      return result;
    }
Пример #7
0
//--------------------------------------------------------------------------
int idaapi rpc_debmod_t::dbg_update_lowcnds(const lowcnd_t *lowcnds, int nlowcnds)
{
  ea_t ea = 0;
  bytevec_t req = prepare_rpc_packet(RPC_UPDATE_LOWCNDS);
  append_dd(req, nlowcnds);
  const lowcnd_t *lc = lowcnds;
  for ( int i=0; i < nlowcnds; i++, lc++ )
  {
    append_ea64(req, lc->ea-ea); ea = lc->ea;
    append_str(req, lc->cndbody);
    if ( !lc->cndbody.empty() )
    {
      append_dd(req, lc->type);
      if ( lc->type != BPT_SOFT )
        append_dd(req, lc->size);
      append_db(req, lc->orgbytes.size());
      append_memory(req, lc->orgbytes.begin(), lc->orgbytes.size());
      append_ea64(req, lc->cmd.ea);
      if ( lc->cmd.ea != BADADDR )
        append_memory(req, &lc->cmd, sizeof(lc->cmd));
    }
  }
  return process_long(req);
}
    char *alloc(size_t count) {
      //    cout << "allocating " << size_bytes << " of memory with alignment " << alignment << endl;
      // Allocate new POD memory of the requested size and alignment
      memory_chunk *mc = &m_memory_handles.back();
      if (mc->capacity_count - mc->used_count < count) {
        append_memory(std::max(m_total_allocated_count, count));
        mc = &m_memory_handles.back();
      }

      char *result = mc->memory + m_stride * mc->used_count;
      mc->used_count += count;
      if ((m_dt.get_flags() & type_flag_zeroinit) != 0) {
        memset(result, 0, m_stride * count);
      } else {
        // TODO: Add a default data constructor to base_type
        //       as well, with a flag for it
        std::stringstream ss;
        ss << "Expected objectarray data to be zeroinit, but is not with dynd type " << m_dt;
        throw std::runtime_error(ss.str());
      }
      return result;
    }
Пример #9
0
//--------------------------------------------------------------------------
ssize_t idaapi rpc_debmod_t::dbg_write_file(int fn, uint32 off, const void *buf, size_t size)
{
  bytevec_t req = prepare_rpc_packet(RPC_WRITE_FILE);
  append_dd(req, fn);
  append_dd(req, off);
  append_dd(req, (uint32)size);
  append_memory(req, buf, size);

  rpc_packet_t *rp = process_request(req);
  if ( rp == NULL )
    return -1;

  const uchar *answer = (uchar *)(rp+1);
  const uchar *end = answer + rp->length;

  int32 rsize = extract_long(&answer, end);
  if ( size != rsize )
    qerrcode(extract_long(&answer, end));

  qfree(rp);
  return rsize;
}
Пример #10
0
//--------------------------------------------------------------------------
int rpc_debmod_t::dbg_read_registers(thid_t tid, int clsmask, regval_t *values)
{
  qstring cmd = prepare_rpc_packet(RPC_READ_REGS);
  append_long(cmd, tid);
  append_long(cmd, clsmask);
  // append additional information about the class structure
  bytevec_t regmap;
  int nregs = calc_regmap(&regmap, clsmask);
  append_long(cmd, nregs);
  append_memory(cmd, regmap.begin(), regmap.size());

  rpc_packet_t *rp = process_request(cmd);
  if ( rp == NULL )
    return -1;
  const uchar *answer = (uchar *)(rp+1);
  const uchar *end = answer + rp->length;

  int result = extract_long(&answer, end);
  if ( result )
    extract_regvals(&answer, end, values, nregs, regmap.begin());
  qfree(rp);
  return result;
}
    char *alloc(size_t count) {
      intptr_t size_bytes = count * data_size;

      //    cout << "allocating " << size_bytes << " of memory with alignment " << alignment << endl;
      // Allocate new POD memory of the requested size and alignment
      char *begin = reinterpret_cast<char *>((reinterpret_cast<uintptr_t>(m_memory_current) + data_alignment - 1) &
                                             ~(data_alignment - 1));
      char *end = begin + size_bytes;
      if (end > m_memory_end) {
        m_total_allocated_capacity -= m_memory_end - m_memory_current;
        // Allocate memory to double the amount used so far, or the requested size, whichever is larger
        // NOTE: We're assuming malloc produces memory which has good enough alignment for anything
        append_memory(std::max(m_total_allocated_capacity, size_bytes));
        begin = m_memory_begin;
        end = begin + size_bytes;
      }

      // Indicate where to allocate the next memory
      m_memory_current = end;

      // Return the allocated memory
      return begin;
      //    cout << "allocated at address " << (void *)begin << endl;
    }
Пример #12
0
//--------------------------------------------------------------------------
int idaapi rpc_debmod_t::dbg_update_bpts(update_bpt_info_t *ubpts, int nadd, int ndel)
{
  int skipped = 0;
  update_bpt_info_t *b;
  update_bpt_info_t *bend = ubpts + nadd;
  for ( b=ubpts; b != bend; b++ )
    if ( b->code != BPT_OK )
      skipped++;
  if ( skipped == nadd && ndel == 0 )
    return 0; // no bpts to update

  bytevec_t req = prepare_rpc_packet(RPC_UPDATE_BPTS);
  append_dd(req, nadd-skipped);
  append_dd(req, ndel);
  ea_t ea = 0;
  for ( b=ubpts; b != bend; b++ )
  {
    if ( b->code == BPT_OK )
    {
      append_ea64(req, b->ea-ea); ea = b->ea;
      append_dd(req, b->size);
      append_dd(req, b->type);
    }
  }

  ea = 0;
  bend += ndel;
  for ( ; b != bend; b++ )
  {
    append_ea64(req, b->ea-ea); ea = b->ea;
    append_db(req, b->orgbytes.size());
    append_memory(req, b->orgbytes.begin(), b->orgbytes.size());
    append_dd(req, b->type);
  }

  rpc_packet_t *rp = process_request(req);
  if ( rp == NULL )
    return -1;

  const uchar *ptr = (uchar *)(rp+1);
  const uchar *end = ptr + rp->length;

  int ret = extract_long(&ptr, end);
  bend = ubpts + nadd;
  for ( b=ubpts; b != bend; b++ )
  {
    if ( b->code == BPT_OK )
    {
      b->code = extract_byte(&ptr, end);
      if ( b->code == BPT_OK && b->type == BPT_SOFT )
      {
        uchar len = extract_byte(&ptr, end);
        b->orgbytes.resize(len);
        extract_memory(&ptr, end, b->orgbytes.begin(), len);
      }
    }
  }

  bend += ndel;
  for ( ; b != bend; b++ )
    b->code = extract_byte(&ptr, end);

  return ret;
}
Пример #13
0
//-------------------------------------------------------------------------
bool varser_t::serialize(bytevec_t &out, const VARIANT &var)
{
  append_dw(out, var.vt);
  if ( (var.vt & VT_BYREF) == VT_BYREF
    || (var.vt & VT_ARRAY) == VT_ARRAY )
  {
    return false;
  }

  const size_t sz_before = out.size();
  switch ( var.vt )
  {
    case VT_EMPTY: // = 0x0000,
    case VT_NULL: // = 0x0001,
      break;
    case VT_I2: // = 0x0002,
    case VT_UI2: // = 0x0012,
      append_dw(out, var.uiVal);
      break;
    case VT_I4: // = 0x0003,
    case VT_UI4: // = 0x0013,
      append_dd(out, var.ulVal);
      break;
    case VT_R4: // = 0x0004,
      append_dd(out, *(uint32*)&var.fltVal);
      break;
    case VT_R8: // = 0x0005,
      append_dq(out, *(uint64*)&var.dblVal);
      break;
    case VT_CY: // = 0x0006,
    case VT_DATE: // = 0x0007,
      break;
    case VT_BSTR: // = 0x0008,
      {
        uint8 *ptr = (uint8*) var.bstrVal;
        ptr -= 4;
        uint32 bcnt = * (uint32*) ptr;
        append_dd(out, bcnt);
        append_memory(out, ptr + 4, bcnt);
      }
      break;
    case VT_DISPATCH: // = 0x0009,
    case VT_ERROR: // = 0x000A,
    case VT_BOOL: // = 0x000B,
    case VT_VARIANT: // = 0x000C,
    case VT_UNKNOWN: // = 0x000D,
    case VT_DECIMAL: // = 0x000E,
    case VT_I1: // = 0x0010,
    case VT_UI1: // = 0x0011,
      append_db(out, var.bVal);
      break;
    case VT_I8: // = 0x0014,
    case VT_UI8: // = 0x0015,
      append_dq(out, var.ullVal);
      break;
    case VT_INT: // = 0x0016,
    case VT_UINT: // = 0x0017,
    case VT_HRESULT: // = 0x0019,
      append_dd(out, var.uintVal);
      break;
    case VT_VOID: // = 0x0018,
    case VT_PTR: // = 0x001A,
    case VT_SAFEARRAY: // = 0x001B,
    case VT_CARRAY: // = 0x001C,
    case VT_USERDEFINED: // = 0x001D,
    case VT_LPSTR: // = 0x001E,
    case VT_LPWSTR: // = 0x001F,
    case VT_RECORD: // = 0x0024,
    case VT_INT_PTR: // = 0x0025,
    case VT_UINT_PTR: // = 0x0026,
      break;
    default: break;
  }
  return out.size() > sz_before;
}
Пример #14
0
//--------------------------------------------------------------------------
// requests received from the server.
// here the client handles certain server -> client requests
qstring rpc_client_t::perform_request(const rpc_packet_t *rp)
{
  const uchar *ptr = (const uchar *)(rp + 1);
  const uchar *end = ptr + rp->length;
  qstring cmd = prepare_rpc_packet(RPC_OK);

  switch ( rp->code )
  {
    case RPC_SET_DEBUG_NAMES:
      {
        int qty = extract_long(&ptr, end);
        ea_t *addrs = new ea_t[qty];
        if ( addrs == NULL )
          goto nomem;

        char **names = new char *[qty];
        if ( names == NULL )
        {
          delete [] addrs;
          goto nomem;
        }
        char name[MAXSTR];
        ea_t old = 0;
        name[0] = '\0';
        for ( int i=0; i < qty; i++ )
        {
          adiff_t o2 = extract_ea(&ptr, end);
          if ( extract_long(&ptr, end) )
            o2 = -o2;
          old += o2;
          addrs[i] = old;
          int oldlen = extract_long(&ptr, end);
          qstrncpy(&name[oldlen], extract_str(&ptr, end), sizeof(name)-oldlen);
          names[i] = qstrdup(name);
        }
        int result = set_debug_names(addrs, names, qty);
        verb(("set_debug_name(qty=%d) => %d\n", qty, result));
        append_long(cmd, result);
        for ( int i=0; i < qty; i++ )
          qfree(names[i]);
        delete [] addrs;
        delete [] names;
      }
      break;

    case RPC_HANDLE_DEBUG_EVENT:
      {
        debug_event_t ev;
        extract_debug_event(&ptr, end, &ev);
        int rqflags = extract_long(&ptr, end);
        int code = send_debug_event_to_ida(&ev, rqflags);
        append_long(cmd, code);
      }
      break;

    case RPC_SYNC_STUB:
      {
        char *fname = extract_str(&ptr, end);
        uint32 crc = extract_long(&ptr, end);
        size_t size = 0;
        uchar *contents = sync_stub(fname, crc, &size);
        append_long(cmd, (uint32)size);
        if ( contents != NULL )
        {
          append_memory(cmd, contents, size);
          qfree(contents);
        }
      }
      break;

    case RPC_ERROR:
    case RPC_MSG:
    case RPC_WARNING:
      {
        char *str = extract_str(&ptr, end);
        if ( rp->code == RPC_MSG)
          msg("%s", str);
        else if ( rp->code == RPC_ERROR )
          error("%s", str);
        else
          warning("%s", str);
      }
      break;

    case RPC_EVENT:
      {
        extract_debug_event(&ptr, end, &pending_event);
        has_pending_event = true;
        cmd = prepare_rpc_packet(RPC_EVOK);
        verbev(("got event, storing it and sending RPC_EVOK\n"));
      }
      break;

    case RPC_IOCTL:
      {
        int code = handle_ioctl_packet(cmd, ptr, end);
        if ( code != RPC_OK )
          return prepare_rpc_packet((uchar)code);
      }
      break;

    default:
      return prepare_rpc_packet(RPC_UNK);
nomem:
      return prepare_rpc_packet(RPC_MEM);
  }
  return cmd;
}
 pod_memory_block(size_t data_size, intptr_t data_alignment, intptr_t initial_capacity_bytes = 2048)
     : data_size(data_size), data_alignment(data_alignment), m_total_allocated_capacity(0), m_memory_handles() {
   append_memory(initial_capacity_bytes);
 }
Пример #16
0
 zeroinit_memory_block(size_t data_size, intptr_t data_alignment, intptr_t initial_capacity_bytes)
     : memory_block_data(1, zeroinit_memory_block_type), data_size(data_size), data_alignment(data_alignment),
       m_total_allocated_capacity(0), m_memory_handles()
 {
   append_memory(initial_capacity_bytes);
 }