Changeset 215


Ignore:
Timestamp:
03/27/11 21:46:11 (13 years ago)
Author:
tim
Message:

improvements to smoketest script, additional test case
added a function to get a key's parent in both regfi and pyregfi
bug fixes

Files:
5 edited

Legend:

Unmodified
Added
Removed
  • test/pyregfi-smoketest.py

    r214 r215  
    33import sys
    44import gc
     5import time
    56import pyregfi
    67
    78def usage():
    89    sys.stderr.write("USAGE: pyregfi-smoketest.py hive1 [hive2 ...]\n")
     10
     11
     12# helper function
     13def getCurrentPath(key):
     14    if key == None:
     15        return ''
     16    path = []
     17    p = key
     18    while p != None:
     19        path.append(p.name)
     20        if p.is_root():
     21            break
     22        else:
     23            p = p.get_parent()
     24    path.reverse()
     25    del path[0]
     26
     27    return path
    928
    1029
     
    3958
    4059
     60# For each key in the hive, this traverses the parent links up to the root,
     61# recording the path as it goes, and then uses the subtree/descend method
     62# to find the same key again, verifying it is the same.  This test is currently
     63# very slow because no key caching is used.
     64def iterParentWalk(hive):
     65    i = 1
     66    for k in hive:
     67        path = getCurrentPath(k)
     68        try:
     69            hive_iter = hive.subtree(path)
     70            if hive_iter.current_key() != k:
     71                print("WARNING: k != current_key for path '%s'." % path)
     72            else:
     73                i += 1
     74        except Exception as e:
     75            print("WARNING: Could not decend to path '%s'.\nError:\n %s\n%s" % (path,e.args,e))
     76    print("   Successfully tested paths on %d keys." % i)
     77
    4178
    4279if len(sys.argv) < 2:
     
    4481    sys.exit(1)
    4582
     83
     84tests = [("iterTally",iterTally),("iterParentWalk",iterParentWalk),]
     85
    4686files = []
    4787for f in sys.argv[1:]:
    4888    files.append((f, open(f,"r+b")))
    4989
    50 tests = [("iterTally",iterTally),]
    5190
     91start_time = time.time()
    5292for hname,fh in files:
    5393    hive = pyregfi.Hive(fh)
    5494    for tname,t in tests:
     95        teststart = time.time()
    5596        tstr = "'%s' on '%s'" % (tname,hname)
    5697        print("##BEGIN %s:" % tstr)
    5798        t(hive)
    58         print("##END %s; messages:" % tstr)
     99        print("##END %s; runtime=%f; messages:" % (tstr, time.time() - teststart))
    59100        print(pyregfi.GetLogMessages())
    60101        print
    61     hive = None
     102        sys.stdout.flush()
    62103
     104hive = None
    63105files = None
    64106tests = None
    65107gc.collect()
     108print("### Tests Completed, runtime: %f ###" % (time.time() -  start_time))
    66109#print(gc.garbage)
  • trunk/include/regfi.h

    r209 r215  
    666666  uint8_t* name_raw;
    667667
    668   /** Virutal offset of parent key */
     668  /** Virtual offset of parent key */
    669669  uint32_t parent_off;
    670670
    671   /** Virutal offset of classname key */
     671  /** Virtual offset of classname key */
    672672  uint32_t classname_off;
    673673 
     
    952952
    953953
    954 /* Dispose of previously parsed records */
     954/** Fetches a hive's root key.
     955 *
     956 * @return Returns the root key or NULL on failure.  Key must be freed using
     957 *         @ref regfi_free_record.
     958 *
     959 * @ingroup regfiBase
     960 */
     961_EXPORT
     962const REGFI_NK*       regfi_get_rootkey(REGFI_FILE* file);
     963
    955964
    956965/** Frees a record previously returned by one of the API functions.
     
    962971 * convenience.  Since records returned previously must not be modified by users
    963972 * of the API due to internal caching, these are returned as const, so this
    964  * function is const to make passing back in easy.
     973 * function is const to make passing those records back easy.
    965974 *
    966975 * @ingroup regfiBase
     
    11101119                                uint32_t index);
    11111120
     1121
     1122
     1123/** Uses a key's parent_off reference to retrieve it's parent.
     1124 *
     1125 * @param file  the file from which key is derived
     1126 * @param key   the key whose parent is desired
     1127 *
     1128 * @return the requested subkey or NULL on error.
     1129 *
     1130 * @ingroup regfiBase
     1131 */
     1132_EXPORT
     1133const REGFI_NK* regfi_get_parentkey(REGFI_FILE* file, const REGFI_NK* key);
    11121134
    11131135
     
    13451367/******************************************************************************/
    13461368
    1347 /** Loads a key at a given file offset along with associated data structures.
     1369/** Loads a key and associated data structures given a file offset.
    13481370 *
    13491371 * XXX: finish documenting
     
    13531375_EXPORT
    13541376REGFI_NK* regfi_load_key(REGFI_FILE* file, uint32_t offset,
    1355                              REGFI_ENCODING output_encoding,
    1356                              bool strict);
     1377                         REGFI_ENCODING output_encoding,
     1378                         bool strict);
    13571379
    13581380
     
    15841606
    15851607/******************************************************************************/
    1586 /*    Private Functions                                                       */
    1587 /******************************************************************************/
    1588 REGFI_NK*             regfi_rootkey(REGFI_FILE* file);
    1589 
     1608/*    Private (and undocumented) Functions                                    */
     1609/******************************************************************************/
    15901610off_t                 regfi_raw_seek(REGFI_RAW_FILE* self,
    15911611                                     off_t offset, int whence);
  • trunk/lib/regfi.c

    r213 r215  
    16701670 * rest of the file if that fails.
    16711671 ******************************************************************************/
    1672 REGFI_NK* regfi_rootkey(REGFI_FILE* file)
     1672const REGFI_NK* regfi_get_rootkey(REGFI_FILE* file)
    16731673{
    16741674  REGFI_NK* nk = NULL;
     
    16951695   */
    16961696 
    1697   if(!regfi_read_lock(file, &file->hbins_lock, "regfi_rootkey"))
     1697  if(!regfi_read_lock(file, &file->hbins_lock, "regfi_get_rootkey"))
    16981698    return NULL;
    16991699
     
    17051705  }
    17061706
    1707   if(!regfi_rw_unlock(file, &file->hbins_lock, "regfi_rootkey"))
     1707  if(!regfi_rw_unlock(file, &file->hbins_lock, "regfi_get_rootkey"))
    17081708    return NULL;
    17091709
     
    17271727{
    17281728  uint32_t num_in_list = 0;
     1729  if(key == NULL)
     1730    return 0;
     1731
    17291732  if(key->subkeys != NULL)
    17301733    num_in_list = key->subkeys->num_keys;
     
    17471750{
    17481751  uint32_t num_in_list = 0;
     1752  if(key == NULL)
     1753    return 0;
     1754
    17491755  if(key->values != NULL)
    17501756    num_in_list = key->values->num_values;
     
    17731779    return NULL;
    17741780
    1775   root = regfi_rootkey(file);
     1781  root = (REGFI_NK*)regfi_get_rootkey(file);
    17761782  if(root == NULL)
    17771783  {
     
    19061912
    19071913  if(path[x] == NULL)
     1914  {
    19081915    return true;
    1909  
     1916  }
     1917
    19101918  /* XXX: is this the right number of times? */
    19111919  for(; x > 0; x--)
     
    22122220
    22132221
    2214 
    22152222/******************************************************************************
    22162223 *****************************************************************************/
     
    22272234  return NULL; 
    22282235}
     2236
     2237
     2238
     2239/******************************************************************************
     2240 *****************************************************************************/
     2241const REGFI_NK* regfi_get_parentkey(REGFI_FILE* file, const REGFI_NK* key)
     2242{
     2243  if(key != NULL && key->parent_off != REGFI_OFFSET_NONE)
     2244  {
     2245    /*    fprintf(stderr, "key->parent_off=%.8X\n", key->parent_off);*/
     2246    return regfi_load_key(file,
     2247                          key->parent_off+REGFI_REGF_SIZE,
     2248                          file->string_encoding, true);
     2249  }
     2250 
     2251  return NULL;
     2252}
     2253
    22292254
    22302255
  • trunk/python/pyregfi/__init__.py

    r214 r215  
    3131regfi.regfi_log_set_mask.restype = c_bool
    3232
     33regfi.regfi_get_rootkey.argtypes = [POINTER(REGFI_FILE)]
     34regfi.regfi_get_rootkey.restype = POINTER(REGFI_NK)
     35
    3336regfi.regfi_free_record.argtypes = [c_void_p]
    3437regfi.regfi_free_record.restype = None
     
    6467                                   c_uint32]
    6568regfi.regfi_get_value.restype = POINTER(REGFI_VK)
     69
     70regfi.regfi_get_parentkey.argtypes = [POINTER(REGFI_FILE), POINTER(REGFI_NK)]
     71regfi.regfi_get_parentkey.restype = POINTER(REGFI_NK)
    6672
    6773regfi.regfi_iterator_new.argtypes = [POINTER(REGFI_FILE), REGFI_ENCODING]
     
    122128    if msgs == None:
    123129        return ''
    124     return msgs.decode('ascii')
     130    return msgs.decode('utf-8')
    125131
    126132
     
    132138    for i in range(0,length):
    133139        ret_val[i] = char_pointer[i][0]
     140
     141    return ret_val
     142
     143
     144def _strlist2charss(str_list):
     145    ret_val = []
     146    for s in str_list:
     147        ret_val.append(s.encode('utf-8', 'replace'))
     148
     149    ret_val = (c_char_p*(len(str_list)+1))(*ret_val)
     150    # Terminate the char** with a NULL pointer
     151    ret_val[-1] = 0
    134152
    135153    return ret_val
     
    155173
    156174    def __init__(self, hive, base):
     175        if not hive:
     176            raise Exception("Could not create _StructureWrapper,"
     177                            + " hive is NULL.  Current log:\n"
     178                            + GetLogMessages())
     179        if not base:
     180            raise Exception("Could not create _StructureWrapper,"
     181                            + " base is NULL.  Current log:\n"
     182                            + GetLogMessages())
    157183        self._hive = hive
    158         # XXX: check for NULL here, throw an exception if so.
    159184        self._base = base
    160185
    161186    def __del__(self):
    162187        regfi.regfi_free_record(self._base)
    163         hive = None
    164188
    165189    def __getattr__(self, name):
     
    172196        return (not self.__eq__(other))
    173197
    174 ## Registry key
    175198class Key(_StructureWrapper):
    176199    pass
     
    248271
    249272        elem = self._get_element(self._hive.file, self._key._base,
    250                                 c_uint32(self._current))
     273                                 c_uint32(self._current))
    251274        self._current += 1
    252275        return self._constructor(self._hive, elem)
     
    268291
    269292
     293## Registry key
    270294class Key(_StructureWrapper):
    271295    values = None
     
    295319    def fetch_security(self):
    296320        return Security(self._hive,
    297                         regfi.regfi_fetch_sk(self._hive.file, self.base))
     321                        regfi.regfi_fetch_sk(self._hive.file, self._base))
     322
     323    def get_parent(self):
     324        parent_base = regfi.regfi_get_parentkey(self._hive.file, self._base)
     325        if parent_base:
     326            return Key(self._hive, parent_base)
     327
     328        return None
     329
     330    def is_root(self):
     331        # This is quicker than retrieving the root key for comparison and
     332        # is more trustworthy than trusting the key's flags.
     333        return ((self._hive.root_cell+REGFI_REGF_SIZE) == self.offset)
    298334
    299335
     
    402438        return HiveIterator(self)
    403439
     440    def get_root(self):
     441        return Key(self, regfi.regfi_get_rootkey(self.file))
     442
     443
    404444    ## Creates a @ref HiveIterator initialized at the specified path in
    405445    #  the hive.
     
    479519
    480520    def descend(self, path):
    481         #set up generator
    482         cpath = (bytes(p,'ascii') for p in path)
    483 
    484         # evaluate generator and create char* array
    485         apath = (c_char_p*len(path))(*cpath)
     521        cpath = _strlist2charss(path)
    486522
    487523        # XXX: Use non-generic exception
    488         if not regfi.regfi_iterator_walk_path(self.iter,apath):
     524        if not regfi.regfi_iterator_walk_path(self.iter, cpath):
    489525            raise Exception('Could not locate path.\n'+GetLogMessages())
    490526
  • trunk/python/pyregfi/structures.py

    r213 r215  
    1313
    1414REGFI_DATA_TYPE = c_uint32
     15REGFI_REGF_SIZE = 0x1000
    1516
    1617# Registry value data types
Note: See TracChangeset for help on using the changeset viewer.