Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/external/source/pxesploit/regeditor/ntreg.h
Views: 11777
/*1* ntreg.h - NT Registry Hive access library, constants & structures2*3* NOTE: defines are not frozen. It can and will change every release.4*5*****6*7* NTREG - Window registry file reader / writer library8* Copyright (c) 1997-2010 Petter Nordahl-Hagen.9*10* This library is free software; you can redistribute it and/or11* modify it under the terms of the GNU Lesser General Public12* License as published by the Free Software Foundation;13* version 2.1 of the License.14*15* This library is distributed in the hope that it will be useful,16* but WITHOUT ANY WARRANTY; without even the implied warranty of17* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU18* Lesser General Public License for more details.19* See file LGPL.txt for the full license.20*21*/222324#ifndef _INCLUDE_NTREG_H25#define _INCLUDE_NTREG_H 12627#define SZ_MAX 4096 /* Max unicode strlen before we truncate */2829#define KEY_ROOT 0x2c /* Type ID of ROOT key node */30#define KEY_NORMAL 0x20 /* Normal nk key */3132#define ABSPATHLEN 2048333435/* Datatypes of the values in the registry */3637#define REG_NONE 0 /* No value type */38#define REG_SZ 1 /* Unicode nul terminated string */39#define REG_EXPAND_SZ 2 /* Unicode nul terminated string + env */40#define REG_BINARY 3 /* Free form binary */41#define REG_DWORD 4 /* 32-bit number */42#define REG_DWORD_BIG_ENDIAN 5 /* 32-bit number */43#define REG_LINK 6 /* Symbolic Link (unicode) */44#define REG_MULTI_SZ 7 /* Multiple Unicode strings */45#define REG_RESOURCE_LIST 8 /* Resource list in the resource map */46#define REG_FULL_RESOURCE_DESCRIPTOR 9 /* Resource list in the hardware description */47#define REG_RESOURCE_REQUIREMENTS_LIST 10 /* Uh? Rait.. */48#define REG_QWORD 11 /* Quad word 64 bit, little endian */4950#define REG_MAX 12515253/* The first page of the registry file is some kind of header, lot of54* it's contents is unknown, and seems to be mostly NULLs anyway.55* Note also, that this is the only place in the registry I've been56* able to find _any_ kind of checksumming57*/5859struct regf_header {6061int32_t id; /* 0x00000000 D-Word ID: ASCII-"regf" = 0x66676572 */62int32_t unknown1; /* 0x00000004 D-Word ???? Mount count */63int32_t unknown2; /* 0x00000008 D-Word ???? Always the same value as at 0x00000004 */64char timestamp[8]; /* 0x0000000C Q-Word last modify date in WinNT date-format */65int32_t unknown3; /* 0x00000014 D-Word 1 */66int32_t unknown4; /* 0x00000018 D-Word 3 - probably version #. 2 in NT3.51 */67int32_t unknown5; /* 0x0000001C D-Word 0 */68int32_t unknown6; /* 0x00000020 D-Word 1 */69int32_t ofs_rootkey; /* 0x00000024 D-Word Offset of 1st key record */70int32_t filesize; /* 0x00000028 D-Word Size of the data-blocks (Filesize-4kb) */71int32_t unknown7; /* 0x0000002C D-Word 1 */72char name[0x1fc-0x30]; /* 0x00000030 Seems like the hive's name is buried here, max len unknown */73int32_t checksum; /* 0x000001FC D-Word Xor sum of all D-Words from 0x00000000 to 0x000001FB */74};7576/* The page header, I don't know if the 14 "dummy" bytes has a meaning,77* they seem to be mostly NULLS78*/7980struct hbin_page {8182int32_t id; /* 0x0000 D-Word ID: ASCII-"hbin" = 0x6E696268 */83int32_t ofs_from1; /* 0x0004 D-Word Offset from the 1st hbin-Block */84int32_t ofs_next; /* 0x0008 D-Word Offset to the next hbin-Block (from THIS ONE) */85char dummy1[14];86int32_t len_page; /* 0x001C D-Word Block-size??? Don't look like it,87I only use the next-offset in this program */88char data[1]; /* 0x0020 First data block starts here */8990};9192/* Minimum block size utilized at end of block93* seem to be either 8 or 16, less than this94* is only filled with garbage. (usually 0xB2 0xB2 ..)95*/96#define HBIN_ENDFILL 09798/* Security descriptor. I know how it's linked, but don't know99how the real security data is constructed, it may as well100be like the higher level security structs defined by MS in its101includes & NT docs. Currently, I have no use for it.102Note that keys sharing the exact same security settings will103most likely point to the same security descriptor, thus104saving space and making it fast to make objects inherit settings105(is inheritance supported? they speak of security inheritance as a "new"106feature in the filesystem on NT5, even though I think it was107also supported by the lower levels in the earlier versions)108*/109struct sk_key {110111short id; /* 0x0000 Word ID: ASCII-"sk" = 0x6B73 */112short dummy1; /* 0x0002 Word Unused */113int32_t ofs_prevsk; /* 0x0004 D-Word Offset of previous "sk"-Record */114int32_t ofs_nextsk; /* 0x0008 D-Word Offset of next "sk"-Record */115int32_t no_usage; /* 0x000C D-Word usage-counter */116int32_t len_sk; /* 0x0010 D-Word Size of "sk"-record in bytes */117char data[4]; /* Security data up to len_sk bytes */118119};120121/* This is the subkeylist/hash structure. NT4.0+.122* ID + count, then count number of offset/4byte "hash". (not true hash)123* Probably changed from the 3.x version to make it faster to124* traverse the registry if you're looking for a specific name125* (saves lookups in 'nk's that have the first 4 name chars different)126*/127128struct lf_key {129130short id; /* 0x0000 Word ID: ASCII-"lf" = 0x666C or "lh" = 0x686c */131short no_keys; /* 0x0002 Word number of keys */132/* 0x0004 ???? Hash-Records */133134union {135136struct lf_hash {137int32_t ofs_nk; /* 0x0000 D-Word Offset of corresponding "nk"-Record */138char name[4]; /* 0x0004 D-Word ASCII: the first 4 characters of the key-name, */139} hash[1];140141/* WinXP uses a more real hash instead (base 37 of uppercase name chars) */142/* padded with 0's. Case sensitiv! */143144struct lh_hash {145int32_t ofs_nk; /* 0x0000 D-Word Offset of corresponding "nk"-Record */146int32_t hash; /* 0x0004 D-Word ASCII: the first 4 characters of the key-name, */147} lh_hash[1];148};149150};151152/* 3.x version of the above, contains only offset table, NOT153* any start of names "hash". Thus needs 'nk' lookups for searches.154*/155struct li_key {156157short id; /* 0x0000 Word ID: ASCII-"li" = 0x696C */158short no_keys; /* 0x0002 Word number of keys */159/* 0x0004 ???? Hash-Records */160struct li_hash {161int32_t ofs_nk; /* 0x0000 D-Word Offset of corresponding "nk"-Record */162} hash[1];163};164165166/* This is a list of pointers to struct li_key, ie167* an extention record if many li's.168* This happens in NT4&5 when the lf hashlist grows larger169* than about 400-500 entries/subkeys??, then the nk_key->ofs_lf points to this170* instead of directly to an lf.171* The sub-indices this points to seems to be li (yes!) in NT4 and 2k.172* In XP and newer they point to lh which is more efficient.173* Likely to happen in HKLM\Software\classes (file extention list) and174* in SAM when many users.175*/176struct ri_key {177178short id; /* 0x0000 Word ID: ASCII-"ri" = 0x6972 */179short no_lis; /* 0x0002 Word number of pointers to li */180/* 0x0004 ???? Hash-Records */181struct ri_hash {182int32_t ofs_li; /* 0x0000 D-Word Offset of corresponding "li"-Record */183} hash[1];184};185186187/* This is the value descriptor.188* If the sign bit (31st bit) in the length field is set, the value is189* stored inline this struct, and not in a seperate data chunk -190* the data then seems to be in the type field, and maybe also191* in the flag and dummy1 field if -len > 4 bytes192* If the name size == 0, then the struct is probably cut short right193* after the val_type or flag.194* The flag meaning is rather unknown.195*/196struct vk_key {197198/* Offset Size Contents */199short id; /* 0x0000 Word ID: ASCII-"vk" = 0x6B76 */200short len_name; /* 0x0002 Word name length */201int32_t len_data; /* 0x0004 D-Word length of the data */202int32_t ofs_data; /* 0x0008 D-Word Offset of Data */203int32_t val_type; /* 0x000C D-Word Type of value */204short flag; /* 0x0010 Word Flag2050x1 ANSI encoding */206short dummy1; /* 0x0012 Word Unused (data-trash) */207char keyname[1]; /* 0x0014 ???? Name */208209};210211/* This is the key node (ie directory) descriptor, can contain subkeys and/or values.212* Note that for values, the count is stored here, but for subkeys213* there's a count both here and in the offset-table (lf or li struct).214* What happens if these mismatch is not known.215* What's the classname thingy? Can't remember seeing that used in216* anything I've looked at.217*/218struct nk_key {219220/* Offset Size Contents */221short id; /* 0x0000 Word ID: ASCII-"nk" = 0x6B6E */222short type; /* 0x0002 Word for the root-key: 0x2C, otherwise 0x202230x20 seems a flag for ANSI encoding */224char timestamp[12]; /* 0x0004 Q-Word write-date/time in windows nt notation */225int32_t ofs_parent; /* 0x0010 D-Word Offset of Owner/Parent key */226int32_t no_subkeys; /* 0x0014 D-Word number of sub-Keys */227char dummy1[4];228int32_t ofs_lf; /* 0x001C D-Word Offset of the sub-key lf-Records */229char dummy2[4];230int32_t no_values; /* 0x0024 D-Word number of values */231int32_t ofs_vallist; /* 0x0028 D-Word Offset of the Value-List */232int32_t ofs_sk; /* 0x002C D-Word Offset of the sk-Record */233int32_t ofs_classnam; /* 0x0030 D-Word Offset of the Class-Name */234char dummy3[16];235int32_t dummy4; /* 0x0044 D-Word Unused (data-trash) */236short len_name; /* 0x0048 Word name-length */237short len_classnam; /* 0x004A Word class-name length */238char keyname[1]; /* 0x004C ???? key-name */239};240241/*********************************************************************************/242243/* Structure defines for my routines */244245struct ex_data {246int nkoffs;247struct nk_key *nk;248char *name;249};250251struct vex_data {252int vkoffs;253struct vk_key *vk;254int type; /* Value type REG_??? */255int size; /* Values size (normalized, inline accounted for) */256int val; /* Actual value itself if type==REG_DWORD */257char *name;258};259260struct keyval {261int len; /* Length of databuffer */262int data; /* Data. Goes on for length of value */263};264265struct keyvala {266int len; /* Length of databuffer */267int data[1]; /* Data. Goes on for length of value */268};269270/* Types to trav_path() */271#define TPF_NK 0272#define TPF_VK 1273#define TPF_EXACT 128274#define TPF_NK_EXACT (TPF_NK | TPF_EXACT)275#define TPF_VK_EXACT (TPF_VK | TPF_EXACT)276277278/* Hive open modes */279#define HMODE_RW 0280#define HMODE_RO 0x1281#define HMODE_OPEN 0x2282#define HMODE_DIRTY 0x4283#define HMODE_NOALLOC 0x8284#define HMODE_VERBOSE 0x1000285#define HMODE_TRACE 0x2000286287/* Suggested type of hive loaded, guessed by library, but not used by it */288#define HTYPE_UNKNOWN 0289#define HTYPE_SAM 1290#define HTYPE_SYSTEM 2291#define HTYPE_SECURITY 3292#define HTYPE_SOFTWARE 4293294/* Hive definition, allocated by openHive(), dealloc by closeHive()295* contains state data, must be passed in all functions296*/297struct hive {298char *filename; /* Hives filename */299int filedesc; /* File descriptor (only valid if state == OPEN) */300int state; /* Current state of hive */301int type; /* Suggested type of hive. NOTE: Library will guess when302it loads it, but application may change it if needed */303int pages; /* Number of pages, total */304int useblk; /* Total # of used blocks */305int unuseblk; /* Total # of unused blocks */306int usetot; /* total # of bytes in useblk */307int unusetot; /* total # of bytes in unuseblk */308int size; /* Hives size (filesise) in bytes */309int rootofs; /* Offset of root-node */310short nkindextype; /* Subkey-indextype the root key uses */311char *buffer; /* Files raw contents */312};313314/***************************************************/315316/* Various nice macros */317318#define CREATE(result, type, number)\319{ \320if (!((result) = (type *) calloc ((number), sizeof(type)))) { \321perror("malloc failure"); \322abort() ; \323} \324}325#define ALLOC(result, size, number)\326{ \327if (!((result) = (void *) calloc ((number), (size)))) { \328perror("malloc failure"); \329abort() ; \330} \331}332#define FREE(p) { if (p) { free(p); (p) = 0; } }333334/* Debug / verbosity message macro */335336#define VERB(h, string) \337{ \338if ((h)->state & HMODE_VERBOSE) printf((string)); \339}340341#define VERBF(h, ...) \342{ \343if ((h)->state & HMODE_VERBOSE) printf(__VA_ARGS__); \344}345346347/******* Function prototypes **********/348349char *str_dup( const char *str );350int fmyinput(char *prmpt, char *ibuf, int maxlen);351void hexprnt(char *s, unsigned char *bytes, int len);352void hexdump(char *hbuf, int start, int stop, int ascii);353int find_in_buf(char *buf, char *what, int sz, int len, int start);354int get_int( char *array );355void cheap_uni2ascii(char *src, char *dest, int l);356void cheap_ascii2uni(char *src, char *dest, int l);357void skipspace(char **c);358int gethex(char **c);359int gethexorstr(char **c, char *wb);360int debugit(char *buf, int sz);361int parse_block(struct hive *hdesc, int vofs,int verbose);362int ex_next_n(struct hive *hdesc, int nkofs, int *count, int *countri, struct ex_data *sptr);363int ex_next_v(struct hive *hdesc, int nkofs, int *count, struct vex_data *sptr);364int get_abs_path(struct hive *hdesc, int nkofs, char *path, int maxlen);365int trav_path(struct hive *hdesc, int vofs, char *path, int type);366int get_val_type(struct hive *hdesc, int vofs, char *path, int exact);367int get_val_len(struct hive *hdesc, int vofs, char *path, int exact);368void *get_val_data(struct hive *hdesc, int vofs, char *path, int val_type, int exact);369struct keyval *get_val2buf(struct hive *hdesc, struct keyval *kv,370int vofs, char *path, int type, int exact );371int get_dword(struct hive *hdesc, int vofs, char *path, int exact);372int put_buf2val(struct hive *hdesc, struct keyval *kv,373int vofs, char *path, int type, int exact );374int put_dword(struct hive *hdesc, int vofs, char *path, int exact, int dword);375void export_key(struct hive *hdesc, int nkofs, char *name, char *filename, char *prefix);376void closeHive(struct hive *hdesc);377int writeHive(struct hive *hdesc);378struct hive *openHive(char *filename, int mode);379380void nk_ls(struct hive *hdesc, char *path, int vofs, int type);381382struct vk_key *add_value(struct hive *hdesc, int nkofs, char *name, int type);383void del_allvalues(struct hive *hdesc, int nkofs);384int del_value(struct hive *hdesc, int nkofs, char *name, int exact);385struct nk_key *add_key(struct hive *hdesc, int nkofs, char *name);386int del_key(struct hive *hdesc, int nkofs, char *name);387void rdel_keys(struct hive *hdesc, char *path, int nkofs);388struct keyval *get_class(struct hive *hdesc, int curnk, char *path);389390/* From edlib,c */391void regedit_interactive(struct hive *hive[], int no_hives);392393#endif394395396397