Loading...
Searching...
No Matches
regfi.h
Go to the documentation of this file.
/*
* Copyright (C) 2005-2011 Timothy D. Morgan
* Copyright (C) 2010 Michael Cohen
* Copyright (C) 2005 Gerald (Jerry) Carter
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id$
*/
#ifndef _REGFI_H
#define _REGFI_H
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <errno.h>
#include <time.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <iconv.h>
#include <pthread.h>
#include <talloc.h>
/* regfi headers */
#include "compat.h"
#include "byteorder.h"
#include "winsec.h"
#include "void_stack.h"
#include "range_list.h"
#include "lru_cache.h"
/******************************************************************************/
/* Constants for use while interacting with the library */
/******************************************************************************/
/* regfi library error message types */
#define REGFI_LOG_INFO 0x0001
#define REGFI_LOG_WARN 0x0004
#define REGFI_LOG_ERROR 0x0010
#define REGFI_DEFAULT_LOG_MASK REGFI_LOG_ERROR|REGFI_LOG_WARN
/* regfi library supported character encodings */
/* UTF16LE is not supported for output */
typedef enum {
REGFI_ENCODING_DEFAULT = 0,
REGFI_ENCODING_ASCII = 0,
REGFI_ENCODING_UTF8 = 1,
REGFI_ENCODING_UTF16LE = 2,
REGFI_NUM_ENCODINGS = 3
} REGFI_ENCODING;
/* Registry data types */
typedef enum {
REG_NONE = 0,
REG_SZ = 1,
REG_EXPAND_SZ = 2,
REG_BINARY = 3,
REG_DWORD = 4,
REG_DWORD_LE = 4 , /* DWORD, little endian */
REG_DWORD_BE = 5 , /* DWORD, big endian */
REG_LINK = 6,
REG_MULTI_SZ = 7,
REG_RESOURCE_LIST = 8,
REG_FULL_RESOURCE_DESCRIPTOR= 9,
REG_RESOURCE_REQUIREMENTS_LIST= 10,
REG_QWORD = 11, /* 64-bit little endian */
/* XXX: Has MS defined a REG_QWORD_BE? */
/* Not a real type in the registry */
REG_KEY = 0x7FFFFFFF
} REGFI_DATA_TYPE;
#define REGFI_OFFSET_NONE 0xffffffff
/******************************************************************************/
/* Various resource limits and related constants */
/******************************************************************************/
/* Flags determining how many records to cache internally */
#define REGFI_CACHE_SK_MAX 64
#define REGFI_CACHE_NK_MAX 1024
/* This maximum depth is described here:
* http://msdn.microsoft.com/en-us/library/ms724872%28VS.85%29.aspx
*/
#define REGFI_MAX_DEPTH 512
/* This limit defines the maximum number of levels deep that ri subkey list
* trees can go.
*/
/* XXX: This is totally arbitrary right now.
* The actual limit may need to be discovered by experimentation.
*/
#define REGFI_MAX_SUBKEY_DEPTH 255
/******************************************************************************/
/* Symbols for internal use */
/******************************************************************************/
/* Global thread-local storage key */
pthread_key_t regfi_log_key;
/* Header sizes and magic number lengths for various records */
#define REGFI_HBIN_ALLOC 0x1000 /* Minimum allocation unit for HBINs */
#define REGFI_REGF_SIZE 0x1000 /* "regf" header block size */
#define REGFI_REGF_MAGIC_SIZE 4
#define REGFI_REGF_NAME_SIZE 64
#define REGFI_REGF_RESERVED1_SIZE 340
#define REGFI_REGF_RESERVED2_SIZE 3528
#define REGFI_HBIN_MAGIC_SIZE 4
#define REGFI_CELL_MAGIC_SIZE 2
#define REGFI_HBIN_HEADER_SIZE 0x20
#define REGFI_NK_MIN_LENGTH 0x4C
#define REGFI_VK_MIN_LENGTH 0x14
#define REGFI_SK_MIN_LENGTH 0x14
#define REGFI_SUBKEY_LIST_MIN_LEN 0x4
#define REGFI_BIG_DATA_MIN_LENGTH 0xC
/* Constants used for validation */
/* XXX: Can we add clock resolution validation as well as range? It has
* been reported that Windows timestamps are never more than a
* certain granularity (250ms?), which could be used to help
* eliminate false positives. Would need to verify this and
* perhaps conservatively implement a check.
*/
/* Minimum time is Jan 1, 1990 00:00:00 */
#define REGFI_MTIME_MIN 0x01B41E6D00000000L
/* Maximum time is Jan 1, 2290 00:00:00
* (We hope no one is using Windows by then...)
*/
#define REGFI_MTIME_MAX 0x0304754300000000L
/* Flags for the vk records */
#define REGFI_VK_FLAG_ASCIINAME 0x0001
#define REGFI_VK_DATA_IN_OFFSET 0x80000000
#define REGFI_VK_MAX_DATA_LENGTH 1024*1024 /* XXX: This is arbitrary */
/* Known key flags */
/*******************/
/* These next two show up on normal-seeming keys in Vista and W2K3 registries */
#define REGFI_NK_FLAG_UNKNOWN1 0x4000
#define REGFI_NK_FLAG_UNKNOWN2 0x1000
/* This next one shows up in some Vista "software" registries */
/* XXX: This shows up in the following two SOFTWARE keys in Vista:
* /Wow6432Node/Microsoft
* /Wow6432Node/Microsoft/Cryptography
*
* It comes along with UNKNOWN2 and ASCIINAME for a total flags value of 0x10A0
*/
#define REGFI_NK_FLAG_UNKNOWN3 0x0080
/* Predefined handle. Rumor has it that the valuelist count for this key is
* where the handle is stored.
* http://msdn.microsoft.com/en-us/library/ms724836(VS.85).aspx
*/
#define REGFI_NK_FLAG_PREDEF_KEY 0x0040
/* The name will be in ASCII if this next bit is set, otherwise UTF-16LE */
#define REGFI_NK_FLAG_ASCIINAME 0x0020
/* Symlink key.
* See: http://www.codeproject.com/KB/system/regsymlink.aspx
*/
#define REGFI_NK_FLAG_LINK 0x0010
/* This key cannot be deleted */
#define REGFI_NK_FLAG_NO_RM 0x0008
/* Root of a hive */
#define REGFI_NK_FLAG_ROOT 0x0004
/* Mount point of another hive. NULL/(default) value indicates which hive
* and where in the hive it points to.
*/
#define REGFI_NK_FLAG_HIVE_LINK 0x0002
/* These keys shouldn't be stored on disk, according to:
* http://geekswithblogs.net/sdorman/archive/2007/12/24/volatile-registry-keys.aspx
*/
#define REGFI_NK_FLAG_VOLATILE 0x0001
/* Useful for identifying unknown flag types */
#define REGFI_NK_KNOWN_FLAGS (REGFI_NK_FLAG_PREDEF_KEY\
| REGFI_NK_FLAG_ASCIINAME\
| REGFI_NK_FLAG_LINK\
| REGFI_NK_FLAG_NO_RM\
| REGFI_NK_FLAG_ROOT\
| REGFI_NK_FLAG_HIVE_LINK\
| REGFI_NK_FLAG_VOLATILE\
| REGFI_NK_FLAG_UNKNOWN1\
| REGFI_NK_FLAG_UNKNOWN2\
| REGFI_NK_FLAG_UNKNOWN3)
#ifndef CHAR_BIT
#define CHAR_BIT 8
#endif
#define TIME_T_MIN ((time_t)0 < (time_t) -1 ? (time_t) 0 \
: ~ (time_t) 0 << (sizeof (time_t) * CHAR_BIT - 1))
#define TIME_T_MAX (~ (time_t) 0 - TIME_T_MIN)
#define REGFI_TIME_FIXUP (369.0*365.25*24*60*60-(3.0*24*60*60+6.0*60*60))
/******************************************************************************/
/* Structures */
/******************************************************************************/
typedef uint64_t REGFI_NTTIME;
typedef struct _regfi_log
{
/* Error/warning/info messages returned by lower layer functions */
char* messages;
/* Mask for error message types that will be stored. */
uint16_t msg_mask;
} REGFI_LOG;
typedef struct _regfi_hbin
{
uint32_t file_off;
uint32_t ref_count;
uint32_t first_hbin_off;
uint32_t block_size;
uint32_t next_block;
uint8_t magic[REGFI_HBIN_MAGIC_SIZE];
} REGFI_HBIN;
/* Subkey List -- list of key offsets and hashed names for consistency */
typedef struct
{
/* Virtual offset of NK record or additional subkey list,
* depending on this list's type.
*/
uint32_t offset;
uint32_t hash;
} REGFI_SUBKEY_LIST_ELEM;
typedef struct _regfi_subkey_list
{
/* Real offset of this record's cell in the file */
uint32_t offset;
uint32_t cell_size;
/* Number of immediate children */
uint32_t num_children;
/* Total number of keys referenced by this list and its children */
uint32_t num_keys;
REGFI_SUBKEY_LIST_ELEM* elements;
uint8_t magic[REGFI_CELL_MAGIC_SIZE];
/* Set if the magic indicates this subkey list points to child subkey lists */
bool recursive_type;
} REGFI_SUBKEY_LIST;
typedef uint32_t REGFI_VALUE_LIST_ELEM;
typedef struct _regfi_value_list
{
/* Real offset of this record's cell in the file */
uint32_t offset;
uint32_t cell_size;
/* Actual number of values referenced by this list.
* May differ from parent key's num_values if there were parsing errors.
*/
uint32_t num_values;
REGFI_VALUE_LIST_ELEM* elements;
} REGFI_VALUE_LIST;
typedef struct _regfi_classname
{
uint32_t offset;
char* interpreted;
uint8_t* raw;
uint16_t size;
} REGFI_CLASSNAME;
typedef struct _regfi_data
{
/* XXX: this isn't populated yet. Should set it to start of data cell
* or big data cell.
*/
uint32_t offset;
REGFI_DATA_TYPE type;
uint32_t size;
uint8_t* raw;
uint32_t interpreted_size;
union _regfi_data_interpreted
{
uint8_t* none;
uint8_t* string;
uint8_t* expand_string;
uint8_t* binary;
uint32_t dword;
uint32_t dword_be;
uint8_t* link;
uint8_t** multiple_string;
uint64_t qword;
/* The following are treated as binary currently, but this may change in
* the future as the formats become better understood.
*/
uint8_t* resource_list;
uint8_t* full_resource_descriptor;
uint8_t* resource_requirements_list;
} interpreted;
} REGFI_DATA;
typedef struct _regfi_vk
{
uint32_t offset;
uint32_t cell_size;
char* name;
uint8_t* name_raw;
uint16_t name_length;
uint32_t hbin_off;
uint32_t data_size;
uint32_t data_off;
REGFI_DATA_TYPE type;
uint8_t magic[REGFI_CELL_MAGIC_SIZE];
uint16_t flags;
/* XXX: A 2-byte field of unknown purpose stored in the VK record */
uint16_t unknown1;
bool data_in_offset;
/* XXX: deprecated */
REGFI_DATA* data;
} REGFI_VK;
/* Key Security */
struct _regfi_sk;
typedef struct _regfi_sk
{
uint32_t offset;
uint32_t cell_size;
WINSEC_DESC* sec_desc;
uint32_t hbin_off;
uint32_t prev_sk_off;
uint32_t next_sk_off;
uint32_t ref_count;
uint32_t desc_size;
/* XXX: A 2-byte field of unknown purpose */
uint16_t unknown_tag;
uint8_t magic[REGFI_CELL_MAGIC_SIZE];
} REGFI_SK;
typedef struct _regfi_nk
{
uint32_t offset;
uint32_t cell_size;
REGFI_VALUE_LIST* values;
REGFI_SUBKEY_LIST* subkeys;
uint16_t flags;
uint8_t magic[REGFI_CELL_MAGIC_SIZE];
REGFI_NTTIME mtime;
uint16_t name_length;
uint16_t classname_length;
char* name;
uint8_t* name_raw;
uint32_t parent_off;
uint32_t classname_off;
/* XXX: max subkey name * 2 */
uint32_t max_bytes_subkeyname;
/* XXX: max subkey classname length (as if) */
uint32_t max_bytes_subkeyclassname;
/* XXX: max value name * 2 */
uint32_t max_bytes_valuename;
/* XXX: max value data size */
uint32_t max_bytes_value;
/* XXX: Fields of unknown purpose */
uint32_t unknown1;
uint32_t unknown2;
uint32_t unknown3;
uint32_t unk_index; /* nigel says run time index ? */
uint32_t num_subkeys;
uint32_t subkeys_off;
uint32_t num_values;
uint32_t values_off;
uint32_t sk_off;
} REGFI_NK;
typedef struct _regfi_raw_file
{
int64_t (* seek)(); /* (REGFI_RAW_FILE* self, uint64_t offset, int whence) */
ssize_t (* read)(); /* (REGFI_RAW_FILE* self, void* buf, size_t count) */
uint64_t cur_off;
uint64_t size;
void* state;
} REGFI_RAW_FILE;
typedef struct _regfi_file
{
/* Data parsed from file header */
/********************************/
uint8_t magic[REGFI_REGF_MAGIC_SIZE];/* "regf" */
/* These sequence numbers should match if
* the hive was properly synced to disk.
*/
uint32_t sequence1;
uint32_t sequence2;
REGFI_NTTIME mtime;
uint32_t major_version; /* Set to 1 in all known hives */
uint32_t minor_version; /* Set to 3 or 5 in all known hives */
uint32_t type; /* XXX: Unverified. Set to 0 in all known hives */
uint32_t format; /* XXX: Unverified. Set to 1 in all known hives */
uint32_t root_cell; /* Offset to root cell in the first (or any?) hbin block */
uint32_t last_block; /* Offset to last hbin block in file */
uint32_t cluster; /* XXX: Unverified. Set to 1 in all known hives */
/* Matches hive's base file name. Stored in UTF-16LE */
uint8_t file_name[REGFI_REGF_NAME_SIZE];
WINSEC_UUID* rm_id; /* XXX: Unverified. */
WINSEC_UUID* log_id; /* XXX: Unverified. */
WINSEC_UUID* tm_id; /* XXX: Unverified. */
uint32_t flags; /* XXX: Unverified. */
uint32_t guid_signature; /* XXX: Unverified. */
uint32_t checksum; /* Stored checksum from file */
uint32_t computed_checksum; /* Our own calculation of the checksum.
* (XOR of bytes 0x0000 - 0x01FB) */
WINSEC_UUID* thaw_tm_id; /* XXX: Unverified. */
WINSEC_UUID* thaw_rm_id; /* XXX: Unverified. */
WINSEC_UUID* thaw_log_id; /* XXX: Unverified. */
uint32_t boot_type; /* XXX: Unverified. */
uint32_t boot_recover; /* XXX: Unverified. */
/* This seems to include random junk. Possibly unsanitized memory left over
* from when header block was written. For instance, chunks of nk records
* can be found, though often it's all 0s. */
uint8_t reserved1[REGFI_REGF_RESERVED1_SIZE];
/* This is likely reserved and unusued currently. (Should be all 0s.)
* Included here for easier access in looking for hidden data
* or doing research. */
uint8_t reserved2[REGFI_REGF_RESERVED2_SIZE];
/* Run-time information */
/************************/
/* For sanity checking (not part of the registry header) */
uint32_t file_length;
REGFI_ENCODING string_encoding;
/* Functions for accessing the file */
REGFI_RAW_FILE* cb;
/* Mutex for all cb access. This is done to prevent one thread from moving
* the file offset while another thread is in the middle of a multi-read
* parsing transaction */
pthread_mutex_t cb_lock;
/* Metadata about hbins */
range_list* hbins;
/* Multiple read access allowed, write access is exclusive */
pthread_rwlock_t hbins_lock;
/* Small number of SK records cached */
lru_cache* sk_cache;
/* Need exclusive access for LRUs, since lookups make changes */
pthread_mutex_t sk_lock;
/* Limited number of keys cached */
lru_cache* nk_cache;
/* Need exclusive access for LRUs, since lookups make changes */
pthread_mutex_t nk_lock;
/* Needed to protect various talloc calls */
pthread_mutex_t mem_lock;
} REGFI_FILE;
typedef struct _regfi_iter_position
{
/* key offset */
uint32_t offset;
/* Index of the current subkey */
uint32_t cur_subkey;
/* Index of the current value */
uint32_t cur_value;
/* The number of subkeys of this key */
uint32_t num_subkeys;
/* The number of values of this key */
uint32_t num_values;
} REGFI_ITER_POSITION;
typedef struct _regfi_iterator
{
REGFI_FILE* f;
void_stack* key_positions;
REGFI_ITER_POSITION* cur;
} REGFI_ITERATOR;
typedef struct _regfi_buffer
{
uint8_t* buf;
uint32_t len;
} REGFI_BUFFER;
/******************************************************************************/
/******************************************************************************/
_EXPORT()
const char* regfi_version();
_EXPORT()
REGFI_FILE* regfi_alloc(int fd, REGFI_ENCODING output_encoding);
_EXPORT()
REGFI_FILE* regfi_alloc_cb(REGFI_RAW_FILE* file_cb,
REGFI_ENCODING output_encoding);
_EXPORT()
void regfi_free(REGFI_FILE* file);
_EXPORT()
char* regfi_log_get_str();
_EXPORT()
bool regfi_log_set_mask(uint16_t mask);
_EXPORT()
const REGFI_NK* regfi_get_rootkey(REGFI_FILE* file);
_EXPORT()
void regfi_free_record(REGFI_FILE* file, const void* record);
_EXPORT()
const void* regfi_reference_record(REGFI_FILE* file, const void* record);
_EXPORT()
uint32_t regfi_fetch_num_subkeys(const REGFI_NK* key);
_EXPORT()
uint32_t regfi_fetch_num_values(const REGFI_NK* key);
_EXPORT()
const REGFI_CLASSNAME* regfi_fetch_classname(REGFI_FILE* file,
const REGFI_NK* key);
_EXPORT()
const REGFI_SK* regfi_fetch_sk(REGFI_FILE* file, const REGFI_NK* key);
_EXPORT()
const REGFI_SK* regfi_next_sk(REGFI_FILE* file, const REGFI_SK* sk);
_EXPORT()
const REGFI_SK* regfi_prev_sk(REGFI_FILE* file, const REGFI_SK* sk);
_EXPORT()
const REGFI_DATA* regfi_fetch_data(REGFI_FILE* file,
const REGFI_VK* value);
_EXPORT()
bool regfi_find_subkey(REGFI_FILE* file, const REGFI_NK* key,
const char* name, uint32_t* index);
_EXPORT()
bool regfi_find_value(REGFI_FILE* file, const REGFI_NK* key,
const char* name, uint32_t* index);
_EXPORT()
const REGFI_NK* regfi_get_subkey(REGFI_FILE* file, const REGFI_NK* key,
uint32_t index);
_EXPORT()
const REGFI_VK* regfi_get_value(REGFI_FILE* file, const REGFI_NK* key,
uint32_t index);
_EXPORT()
const REGFI_NK* regfi_get_parentkey(REGFI_FILE* file, const REGFI_NK* key);
/******************************************************************************/
/******************************************************************************/
_EXPORT()
REGFI_ITERATOR* regfi_iterator_new(REGFI_FILE* file);
_EXPORT()
void regfi_iterator_free(REGFI_ITERATOR* i);
_EXPORT()
bool regfi_iterator_down(REGFI_ITERATOR* i);
_EXPORT()
bool regfi_iterator_up(REGFI_ITERATOR* i);
_EXPORT()
bool regfi_iterator_to_root(REGFI_ITERATOR* i);
_EXPORT()
bool regfi_iterator_descend(REGFI_ITERATOR* i, const char** path);
_EXPORT()
const REGFI_NK* regfi_iterator_cur_key(REGFI_ITERATOR* i);
_EXPORT()
bool regfi_iterator_first_subkey(REGFI_ITERATOR* i);
_EXPORT()
const REGFI_NK* regfi_iterator_cur_subkey(REGFI_ITERATOR* i);
_EXPORT()
bool regfi_iterator_next_subkey(REGFI_ITERATOR* i);
_EXPORT()
bool regfi_iterator_find_subkey(REGFI_ITERATOR* i, const char* name);
_EXPORT()
bool regfi_iterator_first_value(REGFI_ITERATOR* i);
_EXPORT()
const REGFI_VK* regfi_iterator_cur_value(REGFI_ITERATOR* i);
_EXPORT()
bool regfi_iterator_next_value(REGFI_ITERATOR* i);
_EXPORT()
bool regfi_iterator_find_value(REGFI_ITERATOR* i, const char* name);
_EXPORT()
const REGFI_NK** regfi_iterator_ancestry(REGFI_ITERATOR* i);
/******************************************************************************/
/******************************************************************************/
_EXPORT()
REGFI_NK* regfi_load_key(REGFI_FILE* file, uint32_t offset,
bool strict);
_EXPORT()
REGFI_VK* regfi_load_value(REGFI_FILE* file, uint32_t offset,
bool strict);
_EXPORT()
REGFI_SUBKEY_LIST* regfi_load_subkeylist(REGFI_FILE* file, uint32_t offset,
uint32_t num_keys, uint32_t max_size,
bool strict);
_EXPORT()
REGFI_VALUE_LIST* regfi_load_valuelist(REGFI_FILE* file, uint32_t offset,
uint32_t num_values, uint32_t max_size,
bool strict);
_EXPORT()
REGFI_BUFFER regfi_load_data(REGFI_FILE* file, uint32_t voffset,
uint32_t length, bool data_in_offset,
bool strict);
_EXPORT()
REGFI_BUFFER regfi_load_big_data(REGFI_FILE* file, uint32_t offset,
uint32_t data_length,uint32_t cell_length,
range_list* used_ranges,
bool strict);
_EXPORT()
bool regfi_interpret_data(REGFI_FILE* file,
uint32_t type, REGFI_DATA* data);
/* These are cached so return values don't need to be freed. */
_EXPORT()
const REGFI_SK* regfi_load_sk(REGFI_FILE* file, uint32_t offset,
bool strict);
_EXPORT()
const REGFI_HBIN* regfi_lookup_hbin(REGFI_FILE* file, uint32_t offset);
/******************************************************************************/
/******************************************************************************/
_EXPORT()
REGFI_FILE* regfi_parse_regf(REGFI_RAW_FILE* file_cb, bool strict);
_EXPORT()
REGFI_HBIN* regfi_parse_hbin(REGFI_FILE* file, uint32_t offset,
bool strict);
_EXPORT()
REGFI_NK* regfi_parse_nk(REGFI_FILE* file, uint32_t offset,
uint32_t max_size, bool strict);
_EXPORT()
REGFI_SUBKEY_LIST* regfi_parse_subkeylist(REGFI_FILE* file, uint32_t offset,
uint32_t max_size, bool strict);
_EXPORT()
REGFI_VK* regfi_parse_vk(REGFI_FILE* file, uint32_t offset,
uint32_t max_size, bool strict);
_EXPORT()
REGFI_SK* regfi_parse_sk(REGFI_FILE* file, uint32_t offset,
uint32_t max_size, bool strict);
_EXPORT()
range_list* regfi_parse_unalloc_cells(REGFI_FILE* file);
_EXPORT()
bool regfi_parse_cell(REGFI_RAW_FILE* file_cb, uint32_t offset,
uint8_t* hdr, uint32_t hdr_len,
uint32_t* cell_length, bool* unalloc);
_EXPORT()
uint8_t* regfi_parse_classname(REGFI_FILE* file, uint32_t offset,
uint16_t* name_length,
uint32_t max_size, bool strict);
_EXPORT()
REGFI_BUFFER regfi_parse_data(REGFI_FILE* file, uint32_t offset,
uint32_t length, bool strict);
_EXPORT()
REGFI_BUFFER regfi_parse_little_data(REGFI_FILE* file, uint32_t voffset,
uint32_t length, bool strict);
/******************************************************************************/
/* Private (and undocumented) Functions */
/******************************************************************************/
int64_t regfi_raw_seek(REGFI_RAW_FILE* self,
uint64_t offset, int whence);
ssize_t regfi_raw_read(REGFI_RAW_FILE* self,
void* buf, size_t count);
_EXPORT()
uint64_t regfi_seek(REGFI_RAW_FILE* file_cb,
uint64_t offset, int whence);
_EXPORT()
uint32_t regfi_read(REGFI_RAW_FILE* file_cb,
uint8_t* buf, uint32_t* length);
_EXPORT()
const char* regfi_type_val2str(unsigned int val);
_EXPORT()
int regfi_type_str2val(const char* str);
_EXPORT()
char* regfi_get_sacl(WINSEC_DESC* sec_desc);
_EXPORT()
char* regfi_get_dacl(WINSEC_DESC* sec_desc);
_EXPORT()
char* regfi_get_owner(WINSEC_DESC* sec_desc);
_EXPORT()
char* regfi_get_group(WINSEC_DESC* sec_desc);
REGFI_SUBKEY_LIST* regfi_merge_subkeylists(uint16_t num_lists,
REGFI_SUBKEY_LIST** lists,
bool strict);
REGFI_SUBKEY_LIST* regfi_load_subkeylist_aux(REGFI_FILE* file, uint32_t offset,
uint32_t max_size, bool strict,
uint8_t depth_left);
void regfi_add_message(REGFI_FILE* file, uint16_t msg_type,
const char* fmt, ...);
REGFI_NK* regfi_copy_nk(const REGFI_NK* nk);
REGFI_VK* regfi_copy_vk(const REGFI_VK* vk);
_EXPORT()
int32_t regfi_calc_maxsize(REGFI_FILE* file, uint32_t offset);
REGFI_BUFFER regfi_conv_charset(const char* input_charset, const char* output_charset,
uint8_t* input, uint32_t input_len);
_EXPORT()
REGFI_DATA* regfi_buffer_to_data(REGFI_BUFFER raw_data);
/* XXX: move to base API and document */
_EXPORT()
REGFI_NTTIME regfi_unix2nt_time(time_t t);
_EXPORT()
double regfi_nt2unix_time(REGFI_NTTIME nt);
_EXPORT()
void regfi_interpret_keyname(REGFI_FILE* file, REGFI_NK* nk, bool strict);
_EXPORT()
void regfi_interpret_valuename(REGFI_FILE* file, REGFI_VK* vk, bool strict);
_EXPORT()
void regfi_init();
#endif /* _REGFI_H */
byteorder.h
This file implements macros for machine independent short and int manipulation.
regfi_free_record
void regfi_free_record(REGFI_FILE *file, const void *record)
Frees a record previously returned by one of the API functions.
Definition regfi.c:1775
regfi_log_set_mask
bool regfi_log_set_mask(uint16_t mask)
Set the verbosity level of messages generated by the library for the current thread.
Definition regfi.c:194
regfi_free
void regfi_free(REGFI_FILE *file)
Frees a hive's data structures without closing the underlying file.
Definition regfi.c:1720
regfi_find_subkey
bool regfi_find_subkey(REGFI_FILE *file, const REGFI_NK *key, const char *name, uint32_t *index)
Locates a specific subkey of a given key.
Definition regfi.c:2344
regfi_fetch_num_subkeys
uint32_t regfi_fetch_num_subkeys(const REGFI_NK *key)
Retrieves number of subkeys referenced by this key.
Definition regfi.c:1804
regfi_log_get_str
char * regfi_log_get_str()
Get errors, warnings, and/or verbose information relating to processing of the given registry file.
Definition regfi.c:178
regfi_fetch_classname
const REGFI_CLASSNAME * regfi_fetch_classname(REGFI_FILE *file, const REGFI_NK *key)
Retrieves classname for a given key.
Definition regfi.c:2238
regfi_fetch_sk
const REGFI_SK * regfi_fetch_sk(REGFI_FILE *file, const REGFI_NK *key)
Returns the SK (security) record referenced by the supplied key.
Definition regfi.c:2052
regfi_next_sk
const REGFI_SK * regfi_next_sk(REGFI_FILE *file, const REGFI_SK *sk)
Returns the next SK (security) record referenced by the supplied SK record.
Definition regfi.c:2064
regfi_fetch_num_values
uint32_t regfi_fetch_num_values(const REGFI_NK *key)
Retrieves number of values referenced by this key.
Definition regfi.c:1827
regfi_alloc
REGFI_FILE * regfi_alloc(int fd, REGFI_ENCODING output_encoding)
Parses file headers of an already open registry hive file and allocates related structures for furthe...
Definition regfi.c:1546
regfi_alloc_cb
REGFI_FILE * regfi_alloc_cb(REGFI_RAW_FILE *file_cb, REGFI_ENCODING output_encoding)
Parses file headers returned by supplied callback functions.
Definition regfi.c:1595
regfi_version
const char * regfi_version()
Returns the current regfi library version.
Definition regfi.c:58
regfi_get_parentkey
const REGFI_NK * regfi_get_parentkey(REGFI_FILE *file, const REGFI_NK *key)
Uses a key's parent_off reference to retrieve it's parent.
Definition regfi.c:2455
regfi_get_rootkey
const REGFI_NK * regfi_get_rootkey(REGFI_FILE *file)
Fetches a hive's root key.
Definition regfi.c:1731
regfi_get_subkey
const REGFI_NK * regfi_get_subkey(REGFI_FILE *file, const REGFI_NK *key, uint32_t index)
Retrieves a specific subkey of a given key.
Definition regfi.c:2422
regfi_get_value
const REGFI_VK * regfi_get_value(REGFI_FILE *file, const REGFI_NK *key, uint32_t index)
Retrieves a specific value of a given key.
Definition regfi.c:2438
regfi_reference_record
const void * regfi_reference_record(REGFI_FILE *file, const void *record)
Increments reference count on record.
Definition regfi.c:1788
regfi_fetch_data
const REGFI_DATA * regfi_fetch_data(REGFI_FILE *file, const REGFI_VK *value)
Retrieves data for a given value.
Definition regfi.c:2298
regfi_prev_sk
const REGFI_SK * regfi_prev_sk(REGFI_FILE *file, const REGFI_SK *sk)
Returns the previous SK (security) record referenced by the supplied SK record.
Definition regfi.c:2075
regfi_find_value
bool regfi_find_value(REGFI_FILE *file, const REGFI_NK *key, const char *name, uint32_t *index)
Locates a specific value of a given key.
Definition regfi.c:2385
regfi_load_subkeylist
REGFI_SUBKEY_LIST * regfi_load_subkeylist(REGFI_FILE *file, uint32_t offset, uint32_t num_keys, uint32_t max_size, bool strict)
Loads a logical subkey list in its entirety which may span multiple records.
Definition regfi.c:714
regfi_load_sk
const REGFI_SK * regfi_load_sk(REGFI_FILE *file, uint32_t offset, bool strict)
Loads an "sk" security record at the specified offset.
Definition regfi.c:1437
regfi_load_value
REGFI_VK * regfi_load_value(REGFI_FILE *file, uint32_t offset, bool strict)
Loads a value at a given file offset alng with associated data structures.
Definition regfi.c:1224
regfi_load_data
REGFI_BUFFER regfi_load_data(REGFI_FILE *file, uint32_t voffset, uint32_t length, bool data_in_offset, bool strict)
Loads a data record which may be contained in the virtual offset, in a single cell,...
Definition regfi.c:3259
regfi_load_valuelist
REGFI_VALUE_LIST * regfi_load_valuelist(REGFI_FILE *file, uint32_t offset, uint32_t num_values, uint32_t max_size, bool strict)
Loads a valuelist.
Definition regfi.c:1246
regfi_load_key
REGFI_NK * regfi_load_key(REGFI_FILE *file, uint32_t offset, bool strict)
Loads a key and associated data structures given a file offset.
Definition regfi.c:1317
regfi_interpret_data
bool regfi_interpret_data(REGFI_FILE *file, uint32_t type, REGFI_DATA *data)
Given raw data, attempts to interpret the data based on a specified registry data type.
Definition regfi.c:2491
regfi_lookup_hbin
const REGFI_HBIN * regfi_lookup_hbin(REGFI_FILE *file, uint32_t offset)
Retrieves the HBIN data structure stored at the specified offset.
Definition regfi.c:690
regfi_load_big_data
REGFI_BUFFER regfi_load_big_data(REGFI_FILE *file, uint32_t offset, uint32_t data_length, uint32_t cell_length, range_list *used_ranges, bool strict)
Loads the data associated with a big data record at the specified offset.
Definition regfi.c:3625
regfi_iterator_new
REGFI_ITERATOR * regfi_iterator_new(REGFI_FILE *file)
Creates a new iterator for the provided registry file.
Definition regfi.c:1850
regfi_iterator_descend
bool regfi_iterator_descend(REGFI_ITERATOR *i, const char **path)
Traverse down multiple levels in the registry hive.
Definition regfi.c:2014
regfi_iterator_up
bool regfi_iterator_up(REGFI_ITERATOR *i)
Traverse up to the current key's parent key.
Definition regfi.c:1955
regfi_iterator_to_root
bool regfi_iterator_to_root(REGFI_ITERATOR *i)
Traverse up to the root key of the hive.
Definition regfi.c:1977
regfi_iterator_cur_value
const REGFI_VK * regfi_iterator_cur_value(REGFI_ITERATOR *i)
Returns the currently indexed value.
Definition regfi.c:2160
regfi_iterator_down
bool regfi_iterator_down(REGFI_ITERATOR *i)
Traverse deeper into the registry tree at the current subkey.
Definition regfi.c:1912
regfi_iterator_next_subkey
bool regfi_iterator_next_subkey(REGFI_ITERATOR *i)
Increments the internal subkey index to the next key in the subkey-list.
Definition regfi.c:2116
regfi_iterator_first_subkey
bool regfi_iterator_first_subkey(REGFI_ITERATOR *i)
Sets the internal subkey index to the first subkey referenced by the current key.
Definition regfi.c:2086
regfi_iterator_ancestry
const REGFI_NK ** regfi_iterator_ancestry(REGFI_ITERATOR *i)
Returns the current key and all parent keys as a list of NK records.
Definition regfi.c:2192
regfi_iterator_first_value
bool regfi_iterator_first_value(REGFI_ITERATOR *i)
Sets the internal value index to the first value referenced by the current key.
Definition regfi.c:2151
regfi_iterator_next_value
bool regfi_iterator_next_value(REGFI_ITERATOR *i)
Increments the internal value index to the next value in the value-list.
Definition regfi.c:2181
regfi_iterator_cur_subkey
const REGFI_NK * regfi_iterator_cur_subkey(REGFI_ITERATOR *i)
Returns the currently indexed subkey.
Definition regfi.c:2095
regfi_iterator_find_value
bool regfi_iterator_find_value(REGFI_ITERATOR *i, const char *name)
Searches for a value with a given name under the current key.
Definition regfi.c:2125
regfi_iterator_cur_key
const REGFI_NK * regfi_iterator_cur_key(REGFI_ITERATOR *i)
Returns the currently referenced key.
Definition regfi.c:2041
regfi_iterator_free
void regfi_iterator_free(REGFI_ITERATOR *i)
Frees a registry file iterator previously created by regfi_iterator_new.
Definition regfi.c:1903
regfi_iterator_find_subkey
bool regfi_iterator_find_subkey(REGFI_ITERATOR *i, const char *name)
Searches for a subkey with a given name under the current key.
Definition regfi.c:1988
regfi_parse_data
REGFI_BUFFER regfi_parse_data(REGFI_FILE *file, uint32_t offset, uint32_t length, bool strict)
Parses a single-cell data record.
Definition regfi.c:3373
regfi_parse_classname
uint8_t * regfi_parse_classname(REGFI_FILE *file, uint32_t offset, uint16_t *name_length, uint32_t max_size, bool strict)
Parses a classname cell.
Definition regfi.c:3061
regfi_parse_subkeylist
REGFI_SUBKEY_LIST * regfi_parse_subkeylist(REGFI_FILE *file, uint32_t offset, uint32_t max_size, bool strict)
Parses a single cell containing a subkey-list record.
Definition regfi.c:795
regfi_parse_unalloc_cells
range_list * regfi_parse_unalloc_cells(REGFI_FILE *file)
Retrieves information on all cells in the registry hive which are currently in the unallocated status...
Definition regfi.c:3757
regfi_parse_nk
REGFI_NK * regfi_parse_nk(REGFI_FILE *file, uint32_t offset, uint32_t max_size, bool strict)
Parses an NK record at the specified offset.
Definition regfi.c:2918
regfi_parse_little_data
REGFI_BUFFER regfi_parse_little_data(REGFI_FILE *file, uint32_t voffset, uint32_t length, bool strict)
Parses a "little data" record which is stored entirely within the provided virtual offset.
Definition regfi.c:3424
regfi_parse_cell
bool regfi_parse_cell(REGFI_RAW_FILE *file_cb, uint32_t offset, uint8_t *hdr, uint32_t hdr_len, uint32_t *cell_length, bool *unalloc)
Helper function to parse a cell.
Definition regfi.c:628
regfi_parse_sk
REGFI_SK * regfi_parse_sk(REGFI_FILE *file, uint32_t offset, uint32_t max_size, bool strict)
Parses an SK (security) record at the specified offset.
Definition regfi.c:974
regfi_parse_vk
REGFI_VK * regfi_parse_vk(REGFI_FILE *file, uint32_t offset, uint32_t max_size, bool strict)
Parses a VK (value) record at the specified offset.
Definition regfi.c:3138
lru_cache.h
A data structure which approximates a least recently used (LRU) cache.
range_list.h
A data structure which stores a list of address ranges.
REGFI_BUFFER
General purpose buffer with stored length.
Definition regfi.h:858
REGFI_CLASSNAME
Class name structure (used in storing SysKeys)
Definition regfi.h:368
REGFI_CLASSNAME::offset
uint32_t offset
Real offset of this record's cell in the file.
Definition regfi.h:370
REGFI_CLASSNAME::raw
uint8_t * raw
Represents raw buffer read from classname cell.
Definition regfi.h:379
REGFI_CLASSNAME::size
uint16_t size
Length of the raw data.
Definition regfi.h:385
REGFI_CLASSNAME::interpreted
char * interpreted
As converted to requested REGFI_ENCODING.
Definition regfi.h:373
REGFI_DATA
Data record structure.
Definition regfi.h:393
REGFI_DATA::raw
uint8_t * raw
This is always present, representing the raw data cell contents.
Definition regfi.h:406
REGFI_DATA::size
uint32_t size
Length of the raw data.
Definition regfi.h:403
REGFI_DATA::interpreted_size
uint32_t interpreted_size
Represents the length of the interpreted value.
Definition regfi.h:411
REGFI_DATA::type
REGFI_DATA_TYPE type
Data type of this data, as indicated by the referencing VK record.
Definition regfi.h:400
REGFI_FILE
Registry hive file data structure.
Definition regfi.h:725
REGFI_FILE::string_encoding
REGFI_ENCODING string_encoding
The encoding that all strings are converted to during interpretation.
Definition regfi.h:784
REGFI_HBIN
HBIN block information.
Definition regfi.h:284
REGFI_HBIN::next_block
uint32_t next_block
Relative offset to next block.
Definition regfi.h:301
REGFI_HBIN::block_size
uint32_t block_size
Block size of this block Should be a multiple of 4096 (0x1000)
Definition regfi.h:295
REGFI_HBIN::ref_count
uint32_t ref_count
Number of active records pointing to this block (not used currently)
Definition regfi.h:289
REGFI_HBIN::file_off
uint32_t file_off
Offset of this HBIN in the registry file.
Definition regfi.h:286
REGFI_HBIN::first_hbin_off
uint32_t first_hbin_off
Offset from first hbin block.
Definition regfi.h:292
REGFI_ITERATOR
Registry hive iterator.
Definition regfi.h:842
REGFI_ITERATOR::f
REGFI_FILE * f
The registry hive this iterator is associated with.
Definition regfi.h:844
REGFI_ITERATOR::key_positions
void_stack * key_positions
All current parent keys and associated iterator positions.
Definition regfi.h:847
REGFI_ITER_POSITION
Definition regfi.h:819
REGFI_LOG
Definition regfi.h:270
REGFI_NK
Key structure.
Definition regfi.h:607
REGFI_NK::cell_size
uint32_t cell_size
Actual or estimated length of the cell.
Definition regfi.h:614
REGFI_NK::classname_off
uint32_t classname_off
Virtual offset of classname key.
Definition regfi.h:661
REGFI_NK::parent_off
uint32_t parent_off
Virtual offset of parent key.
Definition regfi.h:658
REGFI_NK::num_values
uint32_t num_values
Number of values for this key.
Definition regfi.h:688
REGFI_NK::offset
uint32_t offset
Real offset of this record's cell in the file.
Definition regfi.h:609
REGFI_NK::name_length
uint16_t name_length
Length of name_raw.
Definition regfi.h:639
REGFI_NK::values
REGFI_VALUE_LIST * values
Preloaded value-list for this key.
Definition regfi.h:620
REGFI_NK::values_off
uint32_t values_off
Virtual offset of value-list.
Definition regfi.h:691
REGFI_NK::mtime
REGFI_NTTIME mtime
Key's last modification time.
Definition regfi.h:636
REGFI_NK::classname_length
uint16_t classname_length
Length of referenced classname.
Definition regfi.h:642
REGFI_NK::name_raw
uint8_t * name_raw
The raw key name.
Definition regfi.h:655
REGFI_NK::num_subkeys
uint32_t num_subkeys
Number of subkeys.
Definition regfi.h:682
REGFI_NK::name
char * name
The name of this key converted to desired REGFI_ENCODING.
Definition regfi.h:649
REGFI_NK::subkeys
REGFI_SUBKEY_LIST * subkeys
Preloaded subkey-list for this key.
Definition regfi.h:627
REGFI_NK::subkeys_off
uint32_t subkeys_off
Virtual offset of subkey-list.
Definition regfi.h:685
REGFI_NK::sk_off
uint32_t sk_off
Virtual offset of SK record.
Definition regfi.h:694
REGFI_NK::flags
uint16_t flags
Key flags.
Definition regfi.h:630
REGFI_RAW_FILE
Definition regfi.h:699
REGFI_SK
Security structure.
Definition regfi.h:570
REGFI_SK::hbin_off
uint32_t hbin_off
Offset of this record from beginning of this hbin block.
Definition regfi.h:581
REGFI_SK::desc_size
uint32_t desc_size
Size of security descriptor (sec_desc)
Definition regfi.h:593
REGFI_SK::sec_desc
WINSEC_DESC * sec_desc
The stored Windows security descriptor for this SK record.
Definition regfi.h:578
REGFI_SK::prev_sk_off
uint32_t prev_sk_off
Offset of the previous SK record in the linked list of SK records.
Definition regfi.h:584
REGFI_SK::cell_size
uint32_t cell_size
((start_offset - end_offset) & 0xfffffff8)
Definition regfi.h:575
REGFI_SK::ref_count
uint32_t ref_count
Number of keys referencing this SK record.
Definition regfi.h:590
REGFI_SK::offset
uint32_t offset
Real file offset of this record.
Definition regfi.h:572
REGFI_SK::next_sk_off
uint32_t next_sk_off
Offset of the next SK record in the linked list of SK records.
Definition regfi.h:587
REGFI_SUBKEY_LIST_ELEM
Definition regfi.h:310
REGFI_SUBKEY_LIST
Subkey-list structure.
Definition regfi.h:324
REGFI_VALUE_LIST
Value-list structure.
Definition regfi.h:349
REGFI_VK
Value structure.
Definition regfi.h:504
REGFI_VK::cell_size
uint32_t cell_size
((start_offset - end_offset) & 0xfffffff8)
Definition regfi.h:509
REGFI_VK::name
char * name
The name of this value converted to desired REGFI_ENCODING.
Definition regfi.h:516
REGFI_VK::flags
uint16_t flags
VK record flags.
Definition regfi.h:546
REGFI_VK::data_off
uint32_t data_off
Virtual offset of data cell.
Definition regfi.h:537
REGFI_VK::type
REGFI_DATA_TYPE type
Value's data type.
Definition regfi.h:540
REGFI_VK::name_length
uint16_t name_length
Length of name_raw.
Definition regfi.h:525
REGFI_VK::hbin_off
uint32_t hbin_off
Offset from beginning of this hbin block.
Definition regfi.h:528
REGFI_VK::offset
uint32_t offset
Real offset of this record's cell in the file.
Definition regfi.h:506
REGFI_VK::data_size
uint32_t data_size
Size of the value's data as reported in the VK record.
Definition regfi.h:534
REGFI_VK::name_raw
uint8_t * name_raw
The raw value name.
Definition regfi.h:522
REGFI_VK::data_in_offset
bool data_in_offset
Whether or not the data record is stored in the VK record's data_off field.
Definition regfi.h:555
WINSEC_DESC
XXX: document this.
Definition winsec.h:172
WINSEC_UUID
XXX: document this.
Definition winsec.h:79
lru_cache
XXX: document this.
Definition lru_cache.h:58
range_list
XXX: document this.
Definition range_list.h:52
void_stack
XXX: document this.
Definition void_stack.h:40
REGFI_DATA::_regfi_data_interpreted
These items represent interpreted versions of the REGFI_DATA::raw field.
Definition regfi.h:419
REGFI_DATA::_regfi_data_interpreted::link
uint8_t * link
REG_LINK.
Definition regfi.h:459
REGFI_DATA::_regfi_data_interpreted::none
uint8_t * none
REG_NONE.
Definition regfi.h:425
REGFI_DATA::_regfi_data_interpreted::multiple_string
uint8_t ** multiple_string
REG_MULTI_SZ.
Definition regfi.h:467
REGFI_DATA::_regfi_data_interpreted::dword
uint32_t dword
REG_DWORD.
Definition regfi.h:449
REGFI_DATA::_regfi_data_interpreted::resource_requirements_list
uint8_t * resource_requirements_list
REG_RESOURCE_REQUIREMENTS_LIST.
Definition regfi.h:495
REGFI_DATA::_regfi_data_interpreted::qword
uint64_t qword
REG_QWORD.
Definition regfi.h:470
REGFI_DATA::_regfi_data_interpreted::string
uint8_t * string
REG_SZ.
Definition regfi.h:432
REGFI_DATA::_regfi_data_interpreted::expand_string
uint8_t * expand_string
REG_EXPAND_SZ.
Definition regfi.h:439
REGFI_DATA::_regfi_data_interpreted::binary
uint8_t * binary
REG_BINARY.
Definition regfi.h:446
REGFI_DATA::_regfi_data_interpreted::dword_be
uint32_t dword_be
REG_DWORD_BE.
Definition regfi.h:452
REGFI_DATA::_regfi_data_interpreted::resource_list
uint8_t * resource_list
REG_RESOURCE_LIST.
Definition regfi.h:481
REGFI_DATA::_regfi_data_interpreted::full_resource_descriptor
uint8_t * full_resource_descriptor
REG_FULL_RESOURCE_DESCRIPTOR.
Definition regfi.h:488
void_stack.h
This is a very simple implementation of a stack which stores chunks of memory of any type.
winsec.h
A small library for interpreting Windows Security Descriptors.