Changeset 202


Ignore:
Timestamp:
06/06/10 20:36:27 (14 years ago)
Author:
tim
Message:

began implementing independent python subkey and value iterators

Files:
6 edited

Legend:

Unmodified
Added
Removed
  • test/pyregfi-smoketest.py

    r200 r202  
    77
    88
    9 def iter_values(iter):
     9def iter_values(key):
    1010    i = 0
    11     for value in iter.list_values():
     11    for value in key.values():
    1212        i += 1
    1313       
     
    1717for f in files:
    1818    rf = pyregfi.RegistryFile(f)
    19     iter = rf.get_key()
     19    iter = rf.TreeIterator()
    2020
    2121    num_keys = 0
     
    2323    # The iterator now walks the entire registry hive, depth-first
    2424    for key in iter:
    25         #print key.keyname
     25        print key.key.keyname
    2626        num_keys +=1
    27         num_values += iter_values(iter)
     27        num_values += iter_values(key)
    2828
    2929    print "keys: %d" % num_keys
  • trunk/include/regfi.h

    r201 r202  
    340340 
    341341  /* Number of immediate children */
    342   uint32_t num_children; 
    343 
    344   /* Total number of keys referenced by this list and it's children */
    345   uint32_t num_keys;     
     342  uint32_t num_children;
     343
     344  /* Total number of keys referenced by this list and its children */
     345  uint32_t num_keys;
    346346
    347347  REGFI_SUBKEY_LIST_ELEM* elements;
     
    349349
    350350  /* Set if the magic indicates this subkey list points to child subkey lists */
    351   bool recursive_type; 
     351  bool recursive_type;
    352352} REGFI_SUBKEY_LIST;
    353353
     
    708708 * also stores a list of warnings and error messages generated while parsing
    709709 * the registry hive.  These can be tuned using @ref regfi_set_message_mask. 
    710  * Messages may be retrieved using @ref regfi_get_messages.
     710 * Messages may be retrieved using @ref regfi_log_get_str.
    711711 *
    712712 * @note If the message mask is set to record any messages, dependent code
    713  *       must use @ref regfi_get_messages periodically to clear the message
     713 *       must use @ref regfi_log_get_str periodically to clear the message
    714714 *       queue. Otherwise, this structure will grow in size over time as
    715715 *       messages queue up.
     
    15301530                               REGFI_ENCODING output_encoding, bool strict);
    15311531
     1532_EXPORT
     1533void regfi_init();
     1534
    15321535
    15331536#endif  /* _REGFI_H */
  • trunk/lib/regfi.c

    r200 r202  
    6767void regfi_init()
    6868{
    69 fprintf(stderr, "regfi_init called\n");
    7069  int err;
    7170  if((err = pthread_key_create(&regfi_log_key, regfi_log_free)) != 0)
     
    13201319 *
    13211320 ******************************************************************************/
    1322 REGFI_NK_REC* regfi_load_key(REGFI_FILE* file, uint32_t offset, 
     1321REGFI_NK_REC* regfi_load_key(REGFI_FILE* file, uint32_t offset,
    13231322                             REGFI_ENCODING output_encoding, bool strict)
    13241323{
  • trunk/python2/SConstruct

    r199 r202  
    2929nenv.config = config
    3030if config.DEBUG:
    31     nenv.Append(CFLAGS = "-ggdb -O0 -pedantic -Wall -std=gnu99")
     31    nenv.Append(CFLAGS = "-std=gnu99 -pedantic -Wall -fPIC -ggdb -O0")
    3232    nenv.Append(CPPPATH=['../include', 'include'])
    3333    nenv.python_cppflags = '-I/usr/include/python2.5_d'
    3434else:
    35     nenv.Append(CFLAGS = "-ggdb -pedantic -Wall")
     35    nenv.Append(CFLAGS = "-std=gnu99 -pedantic -Wall -fPIC")
    3636    nenv.Append(CPPPATH=['../include', 'include'])
    3737   
    3838nenv.Append(LIBPATH="../lib")
    3939nenv.Append(LINKFLAGS="")
     40# XXX: why should I need to call regfi_init() when it should be called only once automatically?
    4041nenv.Command('regfi/pyregfi.c', BOUND_FILES, partial(build_python_bindings,
    41                                                      initialization='pyregfi_init();'))
     42                                                     initialization='pyregfi_init();regfi_init();'))
    4243nenv.Depends('regfi/pyregfi.c', 'class_parser.py')
    4344
  • trunk/python2/regfi/pyregfi.h

    r200 r202  
    11/*
    2 ** regfi.h
    3 **
    4 ** Made by mic
    5 ** Login   <mic@laptop>
    6 **
    7 ** Started on  Fri Apr 30 02:06:43 2010 mic
    8 ** Last update Fri Apr 30 02:06:43 2010 mic
    9 */
     2 * Top-level definitions for pyregfi to be processed by Michael Cohen's
     3 * automated Python bindings generator.
     4 *
     5 * Copyright (C) 2010 Michael I. Cohen
     6 * Copyright (C) 2010 Timothy D. Morgan
     7 *
     8 * This program is free software; you can redistribute it and/or modify
     9 * it under the terms of the GNU General Public License as published by
     10 * the Free Software Foundation; version 3 of the License.
     11 *
     12 * This program is distributed in the hope that it will be useful,
     13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 * GNU General Public License for more details.
     16 *
     17 * You should have received a copy of the GNU General Public License
     18 * along with this program; if not, write to the Free Software
     19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
     20 *
     21 * $Id: $
     22 *
     23 */
    1024
    1125#ifndef         PYREGFI_H_
    1226# define        PYREGFI_H_
     27
    1328#include "class.h"
    1429#include "aff4_errors.h"
    1530#include "regfi.h"
    1631
    17 /** Forward declerations */
     32/** Forward declarations */
    1833struct RegistryFile_t;
     34struct RegistryKey_t;
     35struct SubkeyIterator_t;
    1936struct ValueIterator_t;
     37struct TreeIterator_t;
    2038
    2139BIND_STRUCT(REGFI_NK_REC)
     
    4664END_CLASS
    4765
    48 /** This is an iterator for reading keys from the registry */
    49 CLASS(KeyIterator, Object)
     66/** This is an iterator for traversing an entire registry hive */
     67CLASS(TreeIterator, Object)
    5068     PRIVATE REGFI_ITERATOR *iter;
     69     PRIVATE struct RegistryFile_t *file;
    5170     PRIVATE bool root_traversed;
    5271
    53      KeyIterator METHOD(KeyIterator, Con, struct RegistryFile_t *file, char **path,
    54                         REGFI_ENCODING encoding);
     72     struct TreeIterator_t *METHOD(TreeIterator, Con, struct RegistryFile_t *file,
     73                                   char **path, REGFI_ENCODING encoding);
    5574
    56      struct ValueIterator_t *METHOD(KeyIterator, list_values);
     75/*     struct ValueIterator_t *METHOD(TreeIterator, list_values);*/
    5776
    58      void METHOD(KeyIterator, __iter__);
    59      BORROWED REGFI_NK_REC *METHOD(KeyIterator, iternext);
     77     void METHOD(TreeIterator, __iter__);
     78     struct RegistryKey_t *METHOD(TreeIterator, iternext);
    6079
    61      int METHOD(KeyIterator, down);
    62      int METHOD(KeyIterator, up);
     80     int METHOD(TreeIterator, down);
     81     int METHOD(TreeIterator, up);
    6382END_CLASS
     83
     84
     85/** XXX */
     86CLASS(RegistryKey, Object)
     87     struct RegistryFile_t *file;
     88     const REGFI_NK_REC *key;      /* XXX: temporary */
     89
     90     struct RegistryKey_t *METHOD(RegistryKey, Con,
     91                                  struct RegistryFile_t *file, REGFI_NK_REC *base_key);
     92
     93     struct SubkeyIterator_t *METHOD(RegistryKey, subkeys);
     94     struct ValueIterator_t *METHOD(RegistryKey, values);
     95
     96END_CLASS
     97
     98
     99/** This is an iterator for reading keys from the registry */
     100CLASS(SubkeyIterator, Object)
     101     struct RegistryFile_t *file;
     102     PRIVATE const REGFI_SUBKEY_LIST *list;
     103     PRIVATE uint32_t cur;
     104     
     105     SubkeyIterator METHOD(SubkeyIterator, Con,
     106                           struct RegistryFile_t *file, REGFI_NK_REC *key);
     107
     108     void METHOD(SubkeyIterator, __iter__);
     109     RegistryKey METHOD(SubkeyIterator, iternext);
     110END_CLASS
     111
     112
    64113
    65114/** This is an iterator for reading values from the registry */
    66115CLASS(ValueIterator, Object)
    67      PRIVATE REGFI_ITERATOR *iter;
    68      PRIVATE bool first_called;
     116     struct RegistryFile_t *file;
     117     PRIVATE const REGFI_VALUE_LIST *list;
     118     PRIVATE uint32_t cur;
    69119     
    70      ValueIterator METHOD(ValueIterator, Con, KeyIterator key);
     120     ValueIterator METHOD(ValueIterator, Con,
     121                          struct RegistryFile_t *file, REGFI_NK_REC *key);
    71122
    72123     void METHOD(ValueIterator, __iter__);
    73124     REGFI_VK_REC *METHOD(ValueIterator, iternext);
    74125END_CLASS
     126
     127
    75128
    76129CLASS(RegistryFile, Object)
     
    83136     specified.
    84137
     138     XXX: can we switch to UTF-8 and have Python properly import that?
     139
    85140     DEFAULT(path) == NULL;
    86141     DEFAULT(encoding) = REGFI_ENCODING_ASCII;
    87142  */
    88   KeyIterator METHOD(RegistryFile, get_key, char **path, REGFI_ENCODING encoding);
     143  TreeIterator METHOD(RegistryFile, TreeIterator, char **path, REGFI_ENCODING encoding);
    89144
    90145  /** Set the verbosity level of messages generated by the library for the
  • trunk/python2/regfi/regfi.c

    r200 r202  
    11/*
    2 ** regfi.c
    3 **
    4 ** Made by (mic)
    5 ** Login   <mic@laptop>
    6 **
    7 ** Started on  Fri Apr 30 02:06:28 2010 mic
    8 ** Last update Sun May 12 01:17:25 2002 Speed Blue
    9 */
     2 * pyregfi/libregfi glue code
     3 *
     4 * Copyright (C) 2010 Michael I. Cohen
     5 * Copyright (C) 2010 Timothy D. Morgan
     6 *
     7 * This program is free software; you can redistribute it and/or modify
     8 * it under the terms of the GNU General Public License as published by
     9 * the Free Software Foundation; version 3 of the License.
     10 *
     11 * This program is distributed in the hope that it will be useful,
     12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14 * GNU General Public License for more details.
     15 *
     16 * You should have received a copy of the GNU General Public License
     17 * along with this program; if not, write to the Free Software
     18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
     19 *
     20 * $Id: $
     21 */
    1022
    1123#include "pyregfi.h"
    1224
    13 static int RegistryFile_dest(void *self) {
     25static int RegistryFile_dest(void *self)
     26{
    1427  RegistryFile this = (RegistryFile)self;
    1528
     
    2033}
    2134
    22 static RegistryFile RegistryFile_Con(RegistryFile self, char *filename) {
     35static RegistryFile RegistryFile_Con(RegistryFile self, char *filename)
     36{
    2337  self->fd = open(filename, O_RDONLY);
    24   if(self->fd < 0) {
     38  if(self->fd < 0)
     39  {
    2540    RaiseError(EIOError, "Unable to open %s", filename);
    2641    goto error;
     
    2944  self->reg = regfi_alloc(self->fd);
    3045
    31   if(!self->reg) {
     46  if(!self->reg)
     47  {
    3248    RaiseError(ERuntimeError, "REGFI Error: %s", regfi_log_get_str());
    3349    /*char* e = regfi_log_get_str();*/
     
    4460}
    4561
    46 static KeyIterator RegistryFile_get_key(RegistryFile self, char **path, REGFI_ENCODING encoding) {
    47   return CONSTRUCT(KeyIterator, KeyIterator, Con, NULL, self, path, encoding);
     62static TreeIterator RegistryFile_TreeIterator(RegistryFile self, char **path, REGFI_ENCODING encoding)
     63{
     64  return CONSTRUCT(TreeIterator, TreeIterator, Con, NULL, self, path, encoding);
    4865}
    4966
     
    5168VIRTUAL(RegistryFile, Object) {
    5269  VMETHOD(Con) = RegistryFile_Con;
    53   VMETHOD(get_key) = RegistryFile_get_key;
    54 } END_VIRTUAL
    55 
    56 static int KeyIterator_dest(void *self) {
    57   KeyIterator this = (KeyIterator)self;
     70  VMETHOD(TreeIterator) = RegistryFile_TreeIterator;
     71} END_VIRTUAL
     72
     73
     74static int RegistryKey_dest(void *self)
     75{
     76  RegistryKey this = (RegistryKey)self;
     77
     78  talloc_unlink(this, (void*)this->key);
     79
     80  return 0;
     81}
     82
     83static RegistryKey RegistryKey_Con(RegistryKey self,
     84                                   RegistryFile file, REGFI_NK_REC* base_key)
     85{
     86  if(base_key == NULL)
     87    goto error;
     88
     89  self->key = base_key;
     90  self->file = file;
     91  talloc_reference(self, self->key);
     92  talloc_set_destructor((void *)self, RegistryKey_dest);
     93
     94  return self;
     95
     96 error:
     97  talloc_free(self);
     98  return NULL;
     99}
     100
     101/* XXX: would be nice to change this into a property, rather than a function,
     102 *      but that would require a custom __getattr__.  Can that be done? */
     103static SubkeyIterator RegistryKey_subkeys(RegistryKey self)
     104{
     105  return CONSTRUCT(SubkeyIterator, SubkeyIterator, Con, NULL, self->file, self->key);
     106}
     107
     108/* XXX: would be nice to change this into a property, rather than a function,
     109 *      but that would require a custom __getattr__.  Can that be done? */
     110static SubkeyIterator RegistryKey_values(RegistryKey self)
     111{
     112  return CONSTRUCT(ValueIterator, ValueIterator, Con, NULL, self->file, self->key);
     113}
     114
     115
     116VIRTUAL(RegistryKey, Object) {
     117  VMETHOD(Con) = RegistryKey_Con;
     118  VMETHOD(subkeys) = RegistryKey_subkeys;
     119  VMETHOD(values) = RegistryKey_values;
     120} END_VIRTUAL
     121
     122
     123static int TreeIterator_dest(void *self)
     124{
     125  TreeIterator this = (TreeIterator)self;
    58126
    59127  regfi_iterator_free(this->iter);
     
    61129}
    62130
    63 static KeyIterator KeyIterator_Con(KeyIterator self,
    64                                    RegistryFile file,
    65                                    char **path,
    66                                    REGFI_ENCODING encoding)
     131static TreeIterator TreeIterator_Con(TreeIterator self,
     132                                     RegistryFile file,
     133                                     char **path,
     134                                     REGFI_ENCODING encoding)
    67135{
    68136  self->iter = regfi_iterator_new(file->reg, encoding);
    69 
    70   if(!self->iter) {
     137  self->file = file;
     138
     139  if(!self->iter)
     140  {
    71141    RaiseError(ERuntimeError, "Error: %s", regfi_log_get_str());
    72142    goto error;
    73143  }
    74144
    75   talloc_set_destructor((void*)self, KeyIterator_dest);
     145  talloc_set_destructor((void*)self, TreeIterator_dest);
    76146
    77147  /* Traverse to the path */
    78   if(path[0]) {
    79     if(!regfi_iterator_walk_path(self->iter, (const char **)path)) {
     148  if(path[0])
     149  {
     150    if(!regfi_iterator_walk_path(self->iter, (const char **)path))
     151    {
    80152      RaiseError(ERuntimeError, "Unable to walk down key path");
    81153      goto error;
     
    90162}
    91163
    92 static void KeyIterator__iter__(KeyIterator self)
     164static void TreeIterator__iter__(TreeIterator self)
    93165{
    94166  return;
     
    96168
    97169
    98 static const REGFI_NK_REC *KeyIterator_next(KeyIterator self)
     170static RegistryKey TreeIterator_next(TreeIterator self)
    99171{
    100172  if(!self->root_traversed)
     
    115187
    116188  regfi_iterator_first_subkey(self->iter);
    117   return regfi_iterator_cur_key(self->iter);
    118 }
    119 
    120 
    121 static int KeyIterator_down(KeyIterator self) {
     189  return CONSTRUCT(RegistryKey, RegistryKey, Con, NULL, self->file,
     190                   regfi_iterator_cur_key(self->iter));
     191}
     192
     193
     194static int TreeIterator_down(TreeIterator self)
     195{
    122196  int result = regfi_iterator_down(self->iter);
    123197  regfi_iterator_first_subkey(self->iter);
     
    126200}
    127201
    128 static int KeyIterator_up(KeyIterator self) {
     202static int TreeIterator_up(TreeIterator self)
     203{
    129204  return regfi_iterator_up(self->iter);
    130205}
    131206
    132 static ValueIterator KeyIterator_list_values(KeyIterator self) {
     207/*
     208static ValueIterator TreeIterator_list_values(TreeIterator self)
     209{
    133210  return CONSTRUCT(ValueIterator, ValueIterator, Con, NULL, self);
    134211}
    135 
    136 VIRTUAL(KeyIterator, Object) {
    137   VMETHOD(Con) = KeyIterator_Con;
    138   VMETHOD(iternext) = KeyIterator_next;
    139   VMETHOD(down) = KeyIterator_down;
    140   VMETHOD(up) = KeyIterator_up;
    141   VMETHOD(__iter__) = KeyIterator__iter__;
    142   VMETHOD(list_values) = KeyIterator_list_values;
    143 } END_VIRTUAL
    144 
    145 static int ValueIterator_dest(void *self) {
     212*/
     213
     214VIRTUAL(TreeIterator, Object) {
     215  VMETHOD(Con) = TreeIterator_Con;
     216  VMETHOD(iternext) = TreeIterator_next;
     217  VMETHOD(down) = TreeIterator_down;
     218  VMETHOD(up) = TreeIterator_up;
     219  VMETHOD(__iter__) = TreeIterator__iter__;
     220  /*  VMETHOD(list_values) = TreeIterator_list_values;*/
     221} END_VIRTUAL
     222
     223
     224
     225static int SubkeyIterator_dest(void *self)
     226{
     227  SubkeyIterator this = (SubkeyIterator)self;
     228
     229  talloc_unlink(this, (void*)this->list);
     230
     231  return 0;
     232}
     233
     234static SubkeyIterator SubkeyIterator_Con(SubkeyIterator self,
     235                                         struct RegistryFile_t* file,
     236                                         REGFI_NK_REC* key)
     237{
     238  /* XXX: add a talloc reference? */
     239  self->file = file;
     240
     241  /* Add a reference to the list */
     242  self->list = key->subkeys;
     243  talloc_reference(self, self->list);
     244
     245  self->cur = 0;
     246  talloc_set_destructor((void *)self, SubkeyIterator_dest);
     247
     248  return self;
     249}
     250
     251static void SubkeyIterator__iter__(SubkeyIterator self)
     252{
     253  return;
     254}
     255
     256static RegistryKey SubkeyIterator_iternext(SubkeyIterator self)
     257{
     258  const REGFI_NK_REC* nk;
     259
     260  if(self->cur < self->list->num_keys)
     261  {
     262    /* XXX: can we switch to UTF-8 and have Python properly import that? */
     263    nk = regfi_load_key(self->file->reg,
     264                        self->list->elements[self->cur].offset+REGFI_REGF_SIZE,
     265                        REGFI_ENCODING_ASCII, true);
     266    self->cur++;
     267    return CONSTRUCT(RegistryKey, RegistryKey, Con, NULL, self->file, nk);
     268  }
     269
     270  return NULL;
     271}
     272
     273VIRTUAL(SubkeyIterator, Object) {
     274  VMETHOD(Con) = SubkeyIterator_Con;
     275  VMETHOD(__iter__) = SubkeyIterator__iter__;
     276  VMETHOD(iternext) = SubkeyIterator_iternext;
     277} END_VIRTUAL
     278
     279
     280
     281static int ValueIterator_dest(void *self)
     282{
    146283  ValueIterator this = (ValueIterator)self;
    147284
    148   talloc_unlink(this, this->iter);
    149 
    150   return 0;
    151 }
    152 
    153 static ValueIterator ValueIterator_Con(ValueIterator self, KeyIterator key) {
    154   // Take a copy of the iterator
    155   self->iter = key->iter;
    156   talloc_reference(self, self->iter);
     285  if(this->list != NULL)
     286    talloc_unlink(this, (void*)this->list);
     287
     288  return 0;
     289}
     290
     291static ValueIterator ValueIterator_Con(ValueIterator self,
     292                                       struct RegistryFile_t* file,
     293                                       REGFI_NK_REC* key)
     294{
     295  /* XXX: add a talloc reference? */
     296  self->file = file;
     297  self->cur = 0;
     298
     299  /* Add a reference to the list */
     300  self->list = key->values;
     301  if(self->list != NULL)
     302    talloc_reference(self, self->list);
    157303
    158304  talloc_set_destructor((void *)self, ValueIterator_dest);
     
    161307}
    162308
    163 static void ValueIterator__iter__(ValueIterator self) {
     309static void ValueIterator__iter__(ValueIterator self)
     310{
    164311  return;
    165312}
    166313
    167 static REGFI_VK_REC* ValueIterator_iternext(ValueIterator self) {
    168   RawData result;
    169   const REGFI_DATA* data;
    170   const REGFI_VK_REC* rec;
    171 
    172   if(!self->first_called)
    173   {
    174     regfi_iterator_first_value(self->iter);
    175     self->first_called = true;
    176   }
    177   else
    178     regfi_iterator_next_value(self->iter);
    179 
    180   rec = regfi_iterator_cur_value(self->iter);
    181 
    182   return rec;
    183 
    184   if(!rec) return NULL;
     314static REGFI_VK_REC* ValueIterator_iternext(ValueIterator self)
     315{
     316  const REGFI_VK_REC* vk;
     317
     318  if(self->list != NULL && self->cur < self->list->num_values)
     319  {
     320    /* XXX: can we switch to UTF-8 and have Python properly import that? */
     321    vk = regfi_load_value(self->file->reg,
     322                          self->list->elements[self->cur]+REGFI_REGF_SIZE,
     323                          REGFI_ENCODING_ASCII, true);
     324    self->cur++;
     325    /*return CONSTRUCT(RegistryKey, RegistryKey, Con, NULL, vk);    */
     326    return vk;
     327  }
     328
     329  return NULL;
     330
    185331
    186332  /* XXX: shouldn't parse data here every time we walk over a value. 
     
    209355    break;
    210356  }
    211   */
    212357
    213358  return result;
     
    215360  talloc_free(self);
    216361  return NULL;
     362  */
    217363}
    218364
     
    223369} END_VIRTUAL
    224370
    225 static int RawData_dest(void *self) {
     371
     372
     373static int RawData_dest(void *self)
     374{
    226375  RawData this = (RawData)self;
    227376
     
    237386}
    238387
    239 static RawData RawData_Con(RawData self, REGFI_DATA *data, REGFI_VK_REC *record) {
     388static RawData RawData_Con(RawData self, REGFI_DATA *data, REGFI_VK_REC *record)
     389{
    240390  self->rec = record;
    241391  self->data = data;
     
    246396}
    247397
    248 static int RawData_get_value(RawData self, char *buff, int len) {
     398static int RawData_get_value(RawData self, char *buff, int len)
     399{
    249400  int available_to_read = min(len, self->data->interpreted_size);
    250401
     
    259410} END_VIRTUAL
    260411
    261 static char* DataString_get_value(DataString self) {
     412static char* DataString_get_value(DataString self)
     413{
    262414  RawData this = (RawData)self;
    263415
     
    269421} END_VIRTUAL
    270422
    271 static uint64_t DWORDData_get_value(DWORDData self) {
     423static uint64_t DWORDData_get_value(DWORDData self)
     424{
    272425  RawData this = (RawData)self;
    273426
     
    279432} END_VIRTUAL
    280433
    281 void pyregfi_init() {
    282   regfi_init();
     434void pyregfi_init()
     435{
    283436  INIT_CLASS(RegistryFile);
    284437}
Note: See TracChangeset for help on using the changeset viewer.