CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/external/source/pxesploit/regeditor/ntreg.h
Views: 11777
1
/*
2
* ntreg.h - NT Registry Hive access library, constants & structures
3
*
4
* NOTE: defines are not frozen. It can and will change every release.
5
*
6
*****
7
*
8
* NTREG - Window registry file reader / writer library
9
* Copyright (c) 1997-2010 Petter Nordahl-Hagen.
10
*
11
* This library is free software; you can redistribute it and/or
12
* modify it under the terms of the GNU Lesser General Public
13
* License as published by the Free Software Foundation;
14
* version 2.1 of the License.
15
*
16
* This library is distributed in the hope that it will be useful,
17
* but WITHOUT ANY WARRANTY; without even the implied warranty of
18
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19
* Lesser General Public License for more details.
20
* See file LGPL.txt for the full license.
21
*
22
*/
23
24
25
#ifndef _INCLUDE_NTREG_H
26
#define _INCLUDE_NTREG_H 1
27
28
#define SZ_MAX 4096 /* Max unicode strlen before we truncate */
29
30
#define KEY_ROOT 0x2c /* Type ID of ROOT key node */
31
#define KEY_NORMAL 0x20 /* Normal nk key */
32
33
#define ABSPATHLEN 2048
34
35
36
/* Datatypes of the values in the registry */
37
38
#define REG_NONE 0 /* No value type */
39
#define REG_SZ 1 /* Unicode nul terminated string */
40
#define REG_EXPAND_SZ 2 /* Unicode nul terminated string + env */
41
#define REG_BINARY 3 /* Free form binary */
42
#define REG_DWORD 4 /* 32-bit number */
43
#define REG_DWORD_BIG_ENDIAN 5 /* 32-bit number */
44
#define REG_LINK 6 /* Symbolic Link (unicode) */
45
#define REG_MULTI_SZ 7 /* Multiple Unicode strings */
46
#define REG_RESOURCE_LIST 8 /* Resource list in the resource map */
47
#define REG_FULL_RESOURCE_DESCRIPTOR 9 /* Resource list in the hardware description */
48
#define REG_RESOURCE_REQUIREMENTS_LIST 10 /* Uh? Rait.. */
49
#define REG_QWORD 11 /* Quad word 64 bit, little endian */
50
51
#define REG_MAX 12
52
53
54
/* The first page of the registry file is some kind of header, lot of
55
* it's contents is unknown, and seems to be mostly NULLs anyway.
56
* Note also, that this is the only place in the registry I've been
57
* able to find _any_ kind of checksumming
58
*/
59
60
struct regf_header {
61
62
int32_t id; /* 0x00000000 D-Word ID: ASCII-"regf" = 0x66676572 */
63
int32_t unknown1; /* 0x00000004 D-Word ???? Mount count */
64
int32_t unknown2; /* 0x00000008 D-Word ???? Always the same value as at 0x00000004 */
65
char timestamp[8]; /* 0x0000000C Q-Word last modify date in WinNT date-format */
66
int32_t unknown3; /* 0x00000014 D-Word 1 */
67
int32_t unknown4; /* 0x00000018 D-Word 3 - probably version #. 2 in NT3.51 */
68
int32_t unknown5; /* 0x0000001C D-Word 0 */
69
int32_t unknown6; /* 0x00000020 D-Word 1 */
70
int32_t ofs_rootkey; /* 0x00000024 D-Word Offset of 1st key record */
71
int32_t filesize; /* 0x00000028 D-Word Size of the data-blocks (Filesize-4kb) */
72
int32_t unknown7; /* 0x0000002C D-Word 1 */
73
char name[0x1fc-0x30]; /* 0x00000030 Seems like the hive's name is buried here, max len unknown */
74
int32_t checksum; /* 0x000001FC D-Word Xor sum of all D-Words from 0x00000000 to 0x000001FB */
75
};
76
77
/* The page header, I don't know if the 14 "dummy" bytes has a meaning,
78
* they seem to be mostly NULLS
79
*/
80
81
struct hbin_page {
82
83
int32_t id; /* 0x0000 D-Word ID: ASCII-"hbin" = 0x6E696268 */
84
int32_t ofs_from1; /* 0x0004 D-Word Offset from the 1st hbin-Block */
85
int32_t ofs_next; /* 0x0008 D-Word Offset to the next hbin-Block (from THIS ONE) */
86
char dummy1[14];
87
int32_t len_page; /* 0x001C D-Word Block-size??? Don't look like it,
88
I only use the next-offset in this program */
89
char data[1]; /* 0x0020 First data block starts here */
90
91
};
92
93
/* Minimum block size utilized at end of block
94
* seem to be either 8 or 16, less than this
95
* is only filled with garbage. (usually 0xB2 0xB2 ..)
96
*/
97
#define HBIN_ENDFILL 0
98
99
/* Security descriptor. I know how it's linked, but don't know
100
how the real security data is constructed, it may as well
101
be like the higher level security structs defined by MS in its
102
includes & NT docs. Currently, I have no use for it.
103
Note that keys sharing the exact same security settings will
104
most likely point to the same security descriptor, thus
105
saving space and making it fast to make objects inherit settings
106
(is inheritance supported? they speak of security inheritance as a "new"
107
feature in the filesystem on NT5, even though I think it was
108
also supported by the lower levels in the earlier versions)
109
*/
110
struct sk_key {
111
112
short id; /* 0x0000 Word ID: ASCII-"sk" = 0x6B73 */
113
short dummy1; /* 0x0002 Word Unused */
114
int32_t ofs_prevsk; /* 0x0004 D-Word Offset of previous "sk"-Record */
115
int32_t ofs_nextsk; /* 0x0008 D-Word Offset of next "sk"-Record */
116
int32_t no_usage; /* 0x000C D-Word usage-counter */
117
int32_t len_sk; /* 0x0010 D-Word Size of "sk"-record in bytes */
118
char data[4]; /* Security data up to len_sk bytes */
119
120
};
121
122
/* This is the subkeylist/hash structure. NT4.0+.
123
* ID + count, then count number of offset/4byte "hash". (not true hash)
124
* Probably changed from the 3.x version to make it faster to
125
* traverse the registry if you're looking for a specific name
126
* (saves lookups in 'nk's that have the first 4 name chars different)
127
*/
128
129
struct lf_key {
130
131
short id; /* 0x0000 Word ID: ASCII-"lf" = 0x666C or "lh" = 0x686c */
132
short no_keys; /* 0x0002 Word number of keys */
133
/* 0x0004 ???? Hash-Records */
134
135
union {
136
137
struct lf_hash {
138
int32_t ofs_nk; /* 0x0000 D-Word Offset of corresponding "nk"-Record */
139
char name[4]; /* 0x0004 D-Word ASCII: the first 4 characters of the key-name, */
140
} hash[1];
141
142
/* WinXP uses a more real hash instead (base 37 of uppercase name chars) */
143
/* padded with 0's. Case sensitiv! */
144
145
struct lh_hash {
146
int32_t ofs_nk; /* 0x0000 D-Word Offset of corresponding "nk"-Record */
147
int32_t hash; /* 0x0004 D-Word ASCII: the first 4 characters of the key-name, */
148
} lh_hash[1];
149
};
150
151
};
152
153
/* 3.x version of the above, contains only offset table, NOT
154
* any start of names "hash". Thus needs 'nk' lookups for searches.
155
*/
156
struct li_key {
157
158
short id; /* 0x0000 Word ID: ASCII-"li" = 0x696C */
159
short no_keys; /* 0x0002 Word number of keys */
160
/* 0x0004 ???? Hash-Records */
161
struct li_hash {
162
int32_t ofs_nk; /* 0x0000 D-Word Offset of corresponding "nk"-Record */
163
} hash[1];
164
};
165
166
167
/* This is a list of pointers to struct li_key, ie
168
* an extention record if many li's.
169
* This happens in NT4&5 when the lf hashlist grows larger
170
* than about 400-500 entries/subkeys??, then the nk_key->ofs_lf points to this
171
* instead of directly to an lf.
172
* The sub-indices this points to seems to be li (yes!) in NT4 and 2k.
173
* In XP and newer they point to lh which is more efficient.
174
* Likely to happen in HKLM\Software\classes (file extention list) and
175
* in SAM when many users.
176
*/
177
struct ri_key {
178
179
short id; /* 0x0000 Word ID: ASCII-"ri" = 0x6972 */
180
short no_lis; /* 0x0002 Word number of pointers to li */
181
/* 0x0004 ???? Hash-Records */
182
struct ri_hash {
183
int32_t ofs_li; /* 0x0000 D-Word Offset of corresponding "li"-Record */
184
} hash[1];
185
};
186
187
188
/* This is the value descriptor.
189
* If the sign bit (31st bit) in the length field is set, the value is
190
* stored inline this struct, and not in a seperate data chunk -
191
* the data then seems to be in the type field, and maybe also
192
* in the flag and dummy1 field if -len > 4 bytes
193
* If the name size == 0, then the struct is probably cut short right
194
* after the val_type or flag.
195
* The flag meaning is rather unknown.
196
*/
197
struct vk_key {
198
199
/* Offset Size Contents */
200
short id; /* 0x0000 Word ID: ASCII-"vk" = 0x6B76 */
201
short len_name; /* 0x0002 Word name length */
202
int32_t len_data; /* 0x0004 D-Word length of the data */
203
int32_t ofs_data; /* 0x0008 D-Word Offset of Data */
204
int32_t val_type; /* 0x000C D-Word Type of value */
205
short flag; /* 0x0010 Word Flag
206
0x1 ANSI encoding */
207
short dummy1; /* 0x0012 Word Unused (data-trash) */
208
char keyname[1]; /* 0x0014 ???? Name */
209
210
};
211
212
/* This is the key node (ie directory) descriptor, can contain subkeys and/or values.
213
* Note that for values, the count is stored here, but for subkeys
214
* there's a count both here and in the offset-table (lf or li struct).
215
* What happens if these mismatch is not known.
216
* What's the classname thingy? Can't remember seeing that used in
217
* anything I've looked at.
218
*/
219
struct nk_key {
220
221
/* Offset Size Contents */
222
short id; /* 0x0000 Word ID: ASCII-"nk" = 0x6B6E */
223
short type; /* 0x0002 Word for the root-key: 0x2C, otherwise 0x20
224
0x20 seems a flag for ANSI encoding */
225
char timestamp[12]; /* 0x0004 Q-Word write-date/time in windows nt notation */
226
int32_t ofs_parent; /* 0x0010 D-Word Offset of Owner/Parent key */
227
int32_t no_subkeys; /* 0x0014 D-Word number of sub-Keys */
228
char dummy1[4];
229
int32_t ofs_lf; /* 0x001C D-Word Offset of the sub-key lf-Records */
230
char dummy2[4];
231
int32_t no_values; /* 0x0024 D-Word number of values */
232
int32_t ofs_vallist; /* 0x0028 D-Word Offset of the Value-List */
233
int32_t ofs_sk; /* 0x002C D-Word Offset of the sk-Record */
234
int32_t ofs_classnam; /* 0x0030 D-Word Offset of the Class-Name */
235
char dummy3[16];
236
int32_t dummy4; /* 0x0044 D-Word Unused (data-trash) */
237
short len_name; /* 0x0048 Word name-length */
238
short len_classnam; /* 0x004A Word class-name length */
239
char keyname[1]; /* 0x004C ???? key-name */
240
};
241
242
/*********************************************************************************/
243
244
/* Structure defines for my routines */
245
246
struct ex_data {
247
int nkoffs;
248
struct nk_key *nk;
249
char *name;
250
};
251
252
struct vex_data {
253
int vkoffs;
254
struct vk_key *vk;
255
int type; /* Value type REG_??? */
256
int size; /* Values size (normalized, inline accounted for) */
257
int val; /* Actual value itself if type==REG_DWORD */
258
char *name;
259
};
260
261
struct keyval {
262
int len; /* Length of databuffer */
263
int data; /* Data. Goes on for length of value */
264
};
265
266
struct keyvala {
267
int len; /* Length of databuffer */
268
int data[1]; /* Data. Goes on for length of value */
269
};
270
271
/* Types to trav_path() */
272
#define TPF_NK 0
273
#define TPF_VK 1
274
#define TPF_EXACT 128
275
#define TPF_NK_EXACT (TPF_NK | TPF_EXACT)
276
#define TPF_VK_EXACT (TPF_VK | TPF_EXACT)
277
278
279
/* Hive open modes */
280
#define HMODE_RW 0
281
#define HMODE_RO 0x1
282
#define HMODE_OPEN 0x2
283
#define HMODE_DIRTY 0x4
284
#define HMODE_NOALLOC 0x8
285
#define HMODE_VERBOSE 0x1000
286
#define HMODE_TRACE 0x2000
287
288
/* Suggested type of hive loaded, guessed by library, but not used by it */
289
#define HTYPE_UNKNOWN 0
290
#define HTYPE_SAM 1
291
#define HTYPE_SYSTEM 2
292
#define HTYPE_SECURITY 3
293
#define HTYPE_SOFTWARE 4
294
295
/* Hive definition, allocated by openHive(), dealloc by closeHive()
296
* contains state data, must be passed in all functions
297
*/
298
struct hive {
299
char *filename; /* Hives filename */
300
int filedesc; /* File descriptor (only valid if state == OPEN) */
301
int state; /* Current state of hive */
302
int type; /* Suggested type of hive. NOTE: Library will guess when
303
it loads it, but application may change it if needed */
304
int pages; /* Number of pages, total */
305
int useblk; /* Total # of used blocks */
306
int unuseblk; /* Total # of unused blocks */
307
int usetot; /* total # of bytes in useblk */
308
int unusetot; /* total # of bytes in unuseblk */
309
int size; /* Hives size (filesise) in bytes */
310
int rootofs; /* Offset of root-node */
311
short nkindextype; /* Subkey-indextype the root key uses */
312
char *buffer; /* Files raw contents */
313
};
314
315
/***************************************************/
316
317
/* Various nice macros */
318
319
#define CREATE(result, type, number)\
320
{ \
321
if (!((result) = (type *) calloc ((number), sizeof(type)))) { \
322
perror("malloc failure"); \
323
abort() ; \
324
} \
325
}
326
#define ALLOC(result, size, number)\
327
{ \
328
if (!((result) = (void *) calloc ((number), (size)))) { \
329
perror("malloc failure"); \
330
abort() ; \
331
} \
332
}
333
#define FREE(p) { if (p) { free(p); (p) = 0; } }
334
335
/* Debug / verbosity message macro */
336
337
#define VERB(h, string) \
338
{ \
339
if ((h)->state & HMODE_VERBOSE) printf((string)); \
340
}
341
342
#define VERBF(h, ...) \
343
{ \
344
if ((h)->state & HMODE_VERBOSE) printf(__VA_ARGS__); \
345
}
346
347
348
/******* Function prototypes **********/
349
350
char *str_dup( const char *str );
351
int fmyinput(char *prmpt, char *ibuf, int maxlen);
352
void hexprnt(char *s, unsigned char *bytes, int len);
353
void hexdump(char *hbuf, int start, int stop, int ascii);
354
int find_in_buf(char *buf, char *what, int sz, int len, int start);
355
int get_int( char *array );
356
void cheap_uni2ascii(char *src, char *dest, int l);
357
void cheap_ascii2uni(char *src, char *dest, int l);
358
void skipspace(char **c);
359
int gethex(char **c);
360
int gethexorstr(char **c, char *wb);
361
int debugit(char *buf, int sz);
362
int parse_block(struct hive *hdesc, int vofs,int verbose);
363
int ex_next_n(struct hive *hdesc, int nkofs, int *count, int *countri, struct ex_data *sptr);
364
int ex_next_v(struct hive *hdesc, int nkofs, int *count, struct vex_data *sptr);
365
int get_abs_path(struct hive *hdesc, int nkofs, char *path, int maxlen);
366
int trav_path(struct hive *hdesc, int vofs, char *path, int type);
367
int get_val_type(struct hive *hdesc, int vofs, char *path, int exact);
368
int get_val_len(struct hive *hdesc, int vofs, char *path, int exact);
369
void *get_val_data(struct hive *hdesc, int vofs, char *path, int val_type, int exact);
370
struct keyval *get_val2buf(struct hive *hdesc, struct keyval *kv,
371
int vofs, char *path, int type, int exact );
372
int get_dword(struct hive *hdesc, int vofs, char *path, int exact);
373
int put_buf2val(struct hive *hdesc, struct keyval *kv,
374
int vofs, char *path, int type, int exact );
375
int put_dword(struct hive *hdesc, int vofs, char *path, int exact, int dword);
376
void export_key(struct hive *hdesc, int nkofs, char *name, char *filename, char *prefix);
377
void closeHive(struct hive *hdesc);
378
int writeHive(struct hive *hdesc);
379
struct hive *openHive(char *filename, int mode);
380
381
void nk_ls(struct hive *hdesc, char *path, int vofs, int type);
382
383
struct vk_key *add_value(struct hive *hdesc, int nkofs, char *name, int type);
384
void del_allvalues(struct hive *hdesc, int nkofs);
385
int del_value(struct hive *hdesc, int nkofs, char *name, int exact);
386
struct nk_key *add_key(struct hive *hdesc, int nkofs, char *name);
387
int del_key(struct hive *hdesc, int nkofs, char *name);
388
void rdel_keys(struct hive *hdesc, char *path, int nkofs);
389
struct keyval *get_class(struct hive *hdesc, int curnk, char *path);
390
391
/* From edlib,c */
392
void regedit_interactive(struct hive *hive[], int no_hives);
393
394
#endif
395
396
397