Example #1
0
int64_t
do_hivex_node_parent (int64_t nodeh)
{
  int64_t r;

  NEED_HANDLE (-1);

  r = hivex_node_parent (h, nodeh);
  if (r == 0) {
    reply_with_perror ("failed");
    return -1;
  }

  return r;
}
Example #2
0
static PyObject *
py_hivex_node_parent (PyObject *self, PyObject *args)
{
  PyObject *py_r;
  hive_node_h r;
  hive_h *h;
  PyObject *py_h;
  long node;

  if (!PyArg_ParseTuple (args, (char *) "Ol:hivex_node_parent", &py_h, &node))
    return NULL;
  h = get_handle (py_h);
  r = hivex_node_parent (h, node);
  if (r == 0) {
    PyErr_SetString (PyExc_RuntimeError,
                     strerror (errno));
    return NULL;
  }

  py_r = PyLong_FromLongLong (r);
  return py_r;
}
Example #3
0
int
hivex_node_delete_child (hive_h *h, hive_node_h node)
{
  CHECK_WRITABLE (-1);

  if (!IS_VALID_BLOCK (h, node) || !block_id_eq (h, node, "nk")) {
    SET_ERRNO (EINVAL, "invalid block or not an 'nk' block");
    return -1;
  }

  if (node == hivex_root (h)) {
    SET_ERRNO (EINVAL, "cannot delete root node");
    return -1;
  }

  hive_node_h parent = hivex_node_parent (h, node);
  if (parent == 0)
    return -1;

  /* Delete node and all its children and values recursively. */
  static const struct hivex_visitor visitor = { .node_end = delete_node };
  if (hivex_visit_node (h, node, &visitor, sizeof visitor, NULL, 0) == -1)
    return -1;

  /* Delete the link from parent to child.  We need to find the lf/lh
   * record which contains the offset and remove the offset from that
   * record, then decrement the element count in that record, and
   * decrement the overall number of subkeys stored in the parent
   * node.
   */
  hive_node_h *unused;
  size_t *blocks;
  if (_hivex_get_children (h, parent,
                           &unused, &blocks, GET_CHILDREN_NO_CHECK_NK)== -1)
    return -1;
  free (unused);

  size_t i, j;
  for (i = 0; blocks[i] != 0; ++i) {
    struct ntreg_hbin_block *block =
      (struct ntreg_hbin_block *) ((char *) h->addr + blocks[i]);

    if (block->id[0] == 'l' && (block->id[1] == 'f' || block->id[1] == 'h')) {
      struct ntreg_lf_record *lf = (struct ntreg_lf_record *) block;

      size_t nr_subkeys_in_lf = le16toh (lf->nr_keys);

      for (j = 0; j < nr_subkeys_in_lf; ++j)
        if (le32toh (lf->keys[j].offset) + 0x1000 == node) {
          for (; j < nr_subkeys_in_lf - 1; ++j)
            memcpy (&lf->keys[j], &lf->keys[j+1], sizeof (lf->keys[j]));
          lf->nr_keys = htole16 (nr_subkeys_in_lf - 1);
          goto found;
        }
    }
  }
  free (blocks);
  SET_ERRNO (ENOTSUP, "could not find parent to child link");
  return -1;

 found:;
  free (blocks);

  struct ntreg_nk_record *nk =
    (struct ntreg_nk_record *) ((char *) h->addr + parent);
  size_t nr_subkeys_in_nk = le32toh (nk->nr_subkeys);
  nk->nr_subkeys = htole32 (nr_subkeys_in_nk - 1);

  DEBUG (2, "updating nr_subkeys in parent 0x%zx to %zu",
         parent, nr_subkeys_in_nk);

  return 0;
}