Beispiel #1
0
/**
 * gum_list_insert:
 * @list: a pointer to a #GumList
 * @data: the data for the new element
 * @position: the position to insert the element. If this is
 *     negative, or is larger than the number of elements in the
 *     list, the new element is added on to the end of the list.
 *
 * Inserts a new element into the list at the given position.
 *
 * Returns: the new start of the #GumList
 */
GumList*
gum_list_insert (GumList	*list,
                 gpointer	 data,
                 gint	 position)
{
    GumList *new_list;
    GumList *tmp_list;

    if (position < 0)
        return gum_list_append (list, data);
    else if (position == 0)
        return gum_list_prepend (list, data);

    tmp_list = gum_list_nth (list, position);
    if (!tmp_list)
        return gum_list_append (list, data);

    new_list = _gum_list_alloc ();
    new_list->data = data;
    new_list->prev = tmp_list->prev;
    if (tmp_list->prev)
        tmp_list->prev->next = new_list;
    new_list->next = tmp_list;
    tmp_list->prev = new_list;

    if (tmp_list == list)
        return new_list;
    else
        return list;
}
GumCodeSlice *
gum_code_allocator_new_slice_near (GumCodeAllocator * self,
                                   gpointer address)
{
  GumList * walk;
  GumCodePage * cp;
  GumCodeSlice * slice;

  for (walk = self->pages; walk != NULL; walk = walk->next)
  {
    GumCodePage * page = (GumCodePage *) walk->data;

    if (gum_code_page_is_near (page, address))
    {
      guint slice_idx;

      for (slice_idx = 0; slice_idx != self->slices_per_page; slice_idx++)
      {
        slice = &page->slice[slice_idx];

        if (gum_code_slice_is_free (slice))
        {
          if (!gum_query_is_rwx_supported ())
            gum_mprotect (page, self->page_size, GUM_PAGE_RW);
          gum_code_slice_mark_taken (slice);
          return slice;
        }
      }
    }
  }

  cp = gum_code_allocator_new_page_near (self, address);
  self->pages = gum_list_prepend (self->pages, cp);

  slice = &cp->slice[0];
  gum_code_slice_mark_taken (slice);
  return slice;
}