Changeset 205


Ignore:
Timestamp:
08/23/10 11:51:56 (14 years ago)
Author:
tim
Message:

wrapper data structures and part of iterator interface

Location:
trunk/python/pyregfi
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/python/pyregfi/__init__.py

    r204 r205  
    66import ctypes
    77import ctypes.util
    8 from ctypes import c_char,c_char_p,c_int,POINTER
     8from ctypes import c_char,c_char_p,c_int,c_uint16,c_bool,POINTER
    99
    1010regfi = ctypes.CDLL(ctypes.util.find_library('regfi'), use_errno=True)
     
    1717regfi.regfi_alloc_cb.restype = POINTER(REGFI_FILE)
    1818
     19regfi.regfi_free.argtypes = [POINTER(REGFI_FILE)]
     20regfi.regfi_free.restype = None
     21
    1922regfi.regfi_log_get_str.argtypes = []
    2023regfi.regfi_log_get_str.restype = c_char_p
     24
     25regfi.regfi_log_set_mask.argtypes = [c_uint16]
     26regfi.regfi_log_set_mask.restype = c_bool
     27
     28regfi.regfi_free_record.argtypes = [c_void_p]
     29regfi.regfi_free_record.restype = None
     30
     31regfi.regfi_iterator_new.argtypes = [POINTER(REGFI_FILE), REGFI_ENCODING]
     32regfi.regfi_iterator_new.restype = POINTER(REGFI_ITERATOR)
     33
     34regfi.regfi_iterator_free.argtypes = [POINTER(REGFI_ITERATOR)]
     35regfi.regfi_iterator_free.restype = None
     36
     37regfi.regfi_iterator_down.argtypes = [POINTER(REGFI_ITERATOR)]
     38regfi.regfi_iterator_down.restype = c_bool
     39
     40regfi.regfi_iterator_up.argtypes = [POINTER(REGFI_ITERATOR)]
     41regfi.regfi_iterator_up.restype = c_bool
     42
     43regfi.regfi_iterator_to_root.argtypes = [POINTER(REGFI_ITERATOR)]
     44regfi.regfi_iterator_to_root.restype = c_bool
     45
     46regfi.regfi_iterator_walk_path.argtypes = [POINTER(REGFI_ITERATOR)]
     47regfi.regfi_iterator_walk_path.restype = c_bool
     48
     49regfi.regfi_iterator_cur_key.argtypes = [POINTER(REGFI_ITERATOR)]
     50regfi.regfi_iterator_cur_key.restype = POINTER(REGFI_NK)
     51
     52regfi.regfi_iterator_cur_sk.argtypes = [POINTER(REGFI_ITERATOR)]
     53regfi.regfi_iterator_cur_sk.restype = POINTER(REGFI_SK)
     54
     55regfi.regfi_iterator_first_subkey.argtypes = [POINTER(REGFI_ITERATOR)]
     56regfi.regfi_iterator_first_subkey.restype = c_bool
     57
     58regfi.regfi_iterator_cur_subkey.argtypes = [POINTER(REGFI_ITERATOR)]
     59regfi.regfi_iterator_cur_subkey.restype = POINTER(REGFI_NK)
     60
     61regfi.regfi_iterator_next_subkey.argtypes = [POINTER(REGFI_ITERATOR)]
     62regfi.regfi_iterator_next_subkey.restype = c_bool
     63
     64regfi.regfi_iterator_find_subkey.argtypes = [POINTER(REGFI_ITERATOR), c_char_p]
     65regfi.regfi_iterator_find_subkey.restype = c_bool
     66
     67regfi.regfi_iterator_first_value.argtypes = [POINTER(REGFI_ITERATOR)]
     68regfi.regfi_iterator_first_value.restype = c_bool
     69
     70regfi.regfi_iterator_cur_value.argtypes = [POINTER(REGFI_ITERATOR)]
     71regfi.regfi_iterator_cur_value.restype = POINTER(REGFI_VK)
     72
     73regfi.regfi_iterator_next_value.argtypes = [POINTER(REGFI_ITERATOR)]
     74regfi.regfi_iterator_next_value.restype = c_bool
     75
     76regfi.regfi_iterator_find_value.argtypes = [POINTER(REGFI_ITERATOR), c_char_p]
     77regfi.regfi_iterator_find_value.restype = c_bool
     78
     79# XXX: possibly move REGFI_ENCODING to file object and eliminate need for ITERATOR here.
     80regfi.regfi_iterator_fetch_classname.argtypes = [POINTER(REGFI_ITERATOR), POINTER(REGFI_NK)]
     81regfi.regfi_iterator_fetch_classname.restype = POINTER(REGFI_CLASSNAME)
     82
     83regfi.regfi_iterator_fetch_data.argtypes = [POINTER(REGFI_ITERATOR), POINTER(REGFI_VK)]
     84regfi.regfi_iterator_fetch_data.restype = POINTER(REGFI_DATA)
     85
    2186
    2287regfi.regfi_init.argtypes = []
     
    2590
    2691
    27 class Hive(ctypes.Structure):
    28    
     92def GetLogMessages():
     93    return regfi.regfi_log_get_str()
     94
     95
     96class Hive():   
    2997    file = None
    3098    raw_file = None
    3199   
    32100    def __init__(self, fh):
     101        # The fileno method may not exist, or it may thrown an exception
     102        # when called if the file isn't backed with a descriptor.
     103        try:
     104            if hasattr(fh, 'fileno'):
     105                self.file = regfi.regfi_alloc(fh.fileno())
     106                return
     107        except:
     108            pass
    33109       
    34         if hasattr(fh, 'fileno') and 1==0:
    35             self.file = regfi.regfi_alloc(fh.fileno())
    36         else:
    37             self.raw_file = structures.REGFI_RAW_FILE()
    38             self.raw_file.fh = fh
    39             self.raw_file.seek = seek_cb_type(self.raw_file.cb_seek)
    40             self.raw_file.read = read_cb_type(self.raw_file.cb_read)
    41             self.file = regfi.regfi_alloc_cb(self.raw_file)
    42             print(regfi.regfi_log_get_str())
     110        self.raw_file = structures.REGFI_RAW_FILE()
     111        self.raw_file.fh = fh
     112        self.raw_file.seek = seek_cb_type(self.raw_file.cb_seek)
     113        self.raw_file.read = read_cb_type(self.raw_file.cb_read)
     114        self.file = regfi.regfi_alloc_cb(self.raw_file)
    43115
    44116    def __getattr__(self, name):
    45117        return getattr(self.file.contents, name)
     118   
     119    def __del__(self):   
     120        regfi.regfi_free(self.file)
     121        if self.raw_file != None:
     122            regfi.regfi_free(self.file)
     123           
    46124
    47     def test(self):
    48         print(self.magic)
    49         print(self.sequence1)
    50         print(self.sequence2)
     125    def __iter__(self):
     126        return HiveIterator(self)
    51127
     128
     129class HiveIterator():
     130    hive = None
     131    iter = None
     132    root_traversed = False
     133
     134    def __init__(self, hive):
     135        # REGFI_ENCODING_UTF8==1
     136        self.iter = regfi.regfi_iterator_new(hive.file, 1)
     137        if self.iter == None:
     138            raise Exception("Could not create iterator.  Current log:\n"
     139                            + GetLogMessages())
     140        self.hive = hive
     141       
     142    def __getattr__(self, name):
     143        return getattr(self.file.contents, name)
     144
     145    def __del__(self):   
     146        regfi.regfi_iterator_free(self.iter)       
     147
     148    def __iter__(self):
     149        return self
     150
     151    def __next__(self):
     152        if self.root_traversed:
     153            self.root_traversed = True
     154           
     155        elif not regfi.regfi_iterator_down(self.iter):
     156            up_ret = regfi.regfi_iterator_up(self.iter)
     157            while up_ret and not regfi.regfi_iterator_next_subkey(self.iter):
     158                up_ret = regfi.regfi_iterator_up(self.iter)
     159
     160            if not up_ret:
     161                raise StopIteration('')
     162           
     163            if not regfi.regfi_iterator_down(self.iter):
     164                raise Exception('Error traversing iterator downward.'+
     165                                ' Current log:\n'+ GetLogMessages())
     166
     167        regfi.regfi_iterator_first_subkey(self.iter)
     168        print(regfi.regfi_iterator_cur_key(self.iter).contents.keyname)
     169        return regfi.regfi_iterator_cur_key(self.iter)
     170
  • trunk/python/pyregfi/structures.py

    r204 r205  
    66import ctypes
    77import ctypes.util
    8 from ctypes import c_char,c_int,c_uint8,c_uint16,c_uint32,c_uint64,c_int64,POINTER,c_void_p,c_char_p
    9 
    10 
    11 class REGFI_RAW_FILE(ctypes.Structure):
     8from ctypes import *
     9
     10# XXX: can we always be sure enums are this size?
     11REGFI_ENCODING = c_uint32
     12REGFI_DATA_TYPE = c_uint32
     13
     14
     15# Prototype everything first so we don't have to worry about reference order
     16class REGFI_NTTIME(Structure):
     17    pass
     18
     19class REGFI_VK(Structure):
     20    pass
     21
     22class REGFI_SK(Structure):
     23    pass
     24
     25class REGFI_SUBKEY_LIST(Structure):
     26    pass
     27
     28class REGFI_VALUE_LIST(Structure):
     29    pass
     30
     31class REGFI_CLASSNAME(Structure):
     32    pass
     33
     34class REGFI_DATA(Structure):
     35    pass
     36
     37class REGFI_NK(Structure):
     38    pass
     39
     40class REGFI_ITERATOR(Structure):
     41    pass
     42
     43class REGFI_FILE(Structure):
     44    pass
     45
     46class REGFI_RAW_FILE(Structure):
    1247    fh = None
    1348   
     
    1853            traceback.print_exc()
    1954            # XXX: os.EX_IOERR may not be available on Windoze
    20             ctypes.set_errno(os.EX_IOERR)
     55            set_errno(os.EX_IOERR)
    2156            return -1
    2257
     
    2863            # XXX: anyway to do a readinto() here?
    2964            tmp = self.fh.read(count)
    30             ctypes.memmove(buf,tmp,len(tmp))
     65            memmove(buf,tmp,len(tmp))
    3166
    3267        except Exception:
    3368            traceback.print_exc()
    3469            # XXX: os.EX_IOERR may not be available on Windoze
    35             ctypes.set_errno(os.EX_IOERR)
     70            set_errno(os.EX_IOERR)
    3671            return -1
    3772        return len(tmp)
    3873
    3974
    40 
    4175# XXX: how can we know for sure the size of off_t and size_t?
    42 seek_cb_type = ctypes.CFUNCTYPE(c_int64, POINTER(REGFI_RAW_FILE), c_uint64, c_int, use_errno=True)
    43 read_cb_type = ctypes.CFUNCTYPE(c_int64, POINTER(REGFI_RAW_FILE), POINTER(c_char), c_uint64, use_errno=True)
     76seek_cb_type = CFUNCTYPE(c_int64, POINTER(REGFI_RAW_FILE), c_uint64, c_int, use_errno=True)
     77read_cb_type = CFUNCTYPE(c_int64, POINTER(REGFI_RAW_FILE), POINTER(c_char), c_uint64, use_errno=True)
     78
     79
     80REGFI_NTTIME._fields_ = [('low', c_uint32),
     81                         ('high', c_uint32)]
     82
     83REGFI_VK._fields_ = [('offset', c_uint32),
     84                     ('cell_size', c_uint32),
     85                     ('valuename', c_char_p),
     86                     ('valuename_raw', POINTER(c_char)),
     87                     ('name_length', c_uint16),
     88                     ('hbin_off', c_uint32),
     89                     ('data_size', c_uint32),
     90                     ('data_off', c_uint32),
     91                     ('type', REGFI_DATA_TYPE),
     92                     ('magic', c_char * 2),
     93                     ('flags', c_uint16),
     94                     ('unknown1', c_uint16),
     95                     ('data_in_offset', c_bool),
     96                     ]
     97
     98
     99REGFI_SK._fields_ = [('offset', c_uint32),
     100                     ('cell_size', c_uint32),
     101                     ('sec_desc', c_void_p), #XXX
     102                     ('hbin_off', c_uint32),
     103                     ('prev_sk_off', c_uint32),
     104                     ('next_sk_off', c_uint32),
     105                     ('ref_count', c_uint32),
     106                     ('desc_size', c_uint32),
     107                     ('unknown_tag', c_uint16),
     108                     ('magic', c_char * 2),
     109                     ]
     110
     111
     112REGFI_NK._fields_ = [('offset', c_uint32),
     113                     ('cell_size', c_uint32),
     114                     ('values', POINTER(REGFI_VALUE_LIST)),
     115                     ('subkeys', POINTER(REGFI_SUBKEY_LIST)),
     116                     ('flags', c_uint16),
     117                     ('magic', c_char * 2),
     118                     ('mtime', REGFI_NTTIME),
     119                     ('name_length', c_uint16),
     120                     ('classname_length', c_uint16),
     121                     ('keyname', c_char_p),
     122                     ('keyname_raw', POINTER(c_char)),
     123                     ('parent_off', c_uint32),
     124                     ('classname_off', c_uint32),
     125                     ('max_bytes_subkeyname', c_uint32),
     126                     ('max_bytes_subkeyclassname', c_uint32),
     127                     ('max_bytes_valuename', c_uint32),
     128                     ('max_bytes_value', c_uint32),
     129                     ('unknown1', c_uint32),
     130                     ('unknown2', c_uint32),
     131                     ('unknown3', c_uint32),
     132                     ('unk_index', c_uint32),
     133                     ('num_subkeys', c_uint32),
     134                     ('subkeys_off', c_uint32),
     135                     ('num_values', c_uint32),
     136                     ('values_off', c_uint32),
     137                     ('sk_off', c_uint32),
     138                     ]
     139
     140
     141REGFI_SUBKEY_LIST._fields_ = [('offset', c_uint32),
     142                              ('cell_size', c_uint32),
     143                              ('num_children', c_uint32),
     144                              ('num_keys', c_uint32),
     145                              ('elements', c_void_p),
     146                              ('magic', c_char * 2),
     147                              ('recursive_type', c_bool),
     148                              ]
     149
     150
     151REGFI_VALUE_LIST._fields_ = [('offset', c_uint32),
     152                             ('cell_size', c_uint32),
     153                             ('num_children', c_uint32),
     154                             ('num_values', c_uint32),
     155                             ('elements', c_void_p),
     156                             ]
     157
     158REGFI_CLASSNAME._fields_ = [('offset', c_uint32),
     159                            ('interpreted', c_char_p),
     160                            ('raw', POINTER(c_char)),
     161                            ('size', c_uint16),
     162                            ]
     163
     164
     165class REGFI_DATA__interpreted(Union):
     166    _fields_ = [('none',POINTER(c_char)),
     167                ('string', c_char_p),
     168                ('expand_string', c_char_p),
     169                ('binary',POINTER(c_char)),
     170                ('dword', c_uint32),
     171                ('dword_be', c_uint32),
     172                ('link', c_char_p),
     173                ('multiple_string', POINTER(c_char_p)),
     174                ('qword', c_uint64),
     175                ('resource_list',POINTER(c_char)),
     176                ('full_resource_descriptor',POINTER(c_char)),
     177                ('resource_requirements_list',POINTER(c_char)),
     178                ]   
     179REGFI_DATA._fields_ = [('offset', c_uint32),
     180                       ('type', REGFI_DATA_TYPE),
     181                       ('size', c_uint32),
     182                       ('raw', POINTER(c_char)),
     183                       ('interpreted_size', c_uint32),
     184                       ('interpreted', REGFI_DATA__interpreted),
     185                       ]
     186
     187   
     188REGFI_FILE._fields_ = [('magic', c_char * 4),
     189                       ('sequence1', c_uint32),
     190                       ('sequence2', c_uint32),
     191                       ('mtime', REGFI_NTTIME),
     192                       ('major_version', c_uint32),
     193                       ('minor_version', c_uint32),
     194                       ('type', c_uint32),
     195                       ('format', c_uint32),
     196                       ('root_cell', c_uint32),
     197                       ('last_block', c_uint32),
     198                       ('cluster', c_uint32),
     199                       ]
    44200
    45201
     
    50206                           ('state', c_void_p),
    51207                           ]
    52 
    53 
    54 class REGFI_FILE(ctypes.Structure):
    55     _fields_ = [('magic', c_char * 4),
    56                 ('sequence1', c_uint32),
    57                 ('sequence2', c_uint32),
    58                 ('mtime', c_uint64),
    59                 ('major_version', c_uint32),
    60                 ('minor_version', c_uint32),
    61                 ('type', c_uint32),
    62                 ('format', c_uint32),
    63                 ('root_cell', c_uint32),
    64                 ('last_block', c_uint32),
    65                 ('cluster', c_uint32),
    66                 ]
    67 
    68 
    69 
Note: See TracChangeset for help on using the changeset viewer.