?? ntreg.c
字號(hào):
/* * ntreg.c - NT Registry Hive access library * * 2004-aug: Deep indirect index support. NT351 support. Recursive delete. * Debugged a lot in allocation routines. Still no expansion. * 2004-jan: Verbosity updates * 2003-jan: Allocation of new data, supports adding/deleting keys & stuff. * Missing is expanding the file. * 2003-jan: Seems there may be garbage pages at end of file, not zero pages * now stops enumerating at first non 'hbin' page. * * NOTE: The API is not frozen. It can and will change every release. * * Copyright (c) 1997-2004 Petter Nordahl-Hagen. * Freely distributable in source or binary for noncommercial purposes, * but I allow some exceptions to this. * Please see the COPYING file for more details on * copyrights & credits. * * THIS SOFTWARE IS PROVIDED BY PETTER NORDAHL-HAGEN `AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * */ #include <stdio.h>#include <stdlib.h>#include <ctype.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <errno.h>#include <string.h>#include <unistd.h>#include "ntreg.h"/* Set to abort() and debug on more critical errors */#define DOCORE 0const char ntreg_version[] = "ntreg lib routines, v0.92 040818, (c) Petter N Hagen";char *val_types[REG_MAX+1] = { "REG_NONE", "REG_SZ", "REG_EXPAND_SZ", "REG_BINARY", "REG_DWORD", /* 0 - 4 */ "REG_DWORD_BIG_ENDIAN", "REG_LINK", /* 5 - 6 */ "REG_MULTI_SZ", "REG_RESOUCE_LIST", "REG_FULL_RES_DESC", "REG_RES_REQ", /* 7 - 10 */};/* Utility routines */char *str_dup( const char *str ){ char *str_new; if (!str) return 0 ; CREATE( str_new, char, strlen(str) + 1 ); strcpy( str_new, str ); return str_new;}int fmyinput(char *prmpt, char *ibuf, int maxlen){ printf("%s",prmpt); fgets(ibuf,maxlen+1,stdin); ibuf[strlen(ibuf)-1] = 0; return(strlen(ibuf));}/* Print len number of hexbytes */void hexprnt(char *s, unsigned char *bytes, int len){int i; printf("%s",s); for (i = 0; i < len; i++) { printf("%02x ",bytes[i]); } printf("\n");}/* HexDump all or a part of some buffer */void hexdump(char *hbuf, int start, int stop, int ascii){ char c; int diff,i; while (start < stop ) { diff = stop - start; if (diff > 16) diff = 16; printf(":%05X ",start); for (i = 0; i < diff; i++) { printf("%02X ",(unsigned char)*(hbuf+start+i)); } if (ascii) { for (i = diff; i < 16; i++) printf(" "); for (i = 0; i < diff; i++) { c = *(hbuf+start+i); printf("%c", isprint(c) ? c : '.'); } } printf("\n"); start += 16; }}/* General search routine, find something in something else */int find_in_buf(char *buf, char *what, int sz, int len, int start){ int i; for (; start < sz; start++) { for (i = 0; i < len; i++) { if (*(buf+start+i) != *(what+i)) break; } if (i == len) return(start); } return(0);}/* Get INTEGER from memory. This is probably low-endian specific? */int get_int( char *array ){ return ((array[0]&0xff) + ((array[1]<<8)&0xff00) + ((array[2]<<16)&0xff0000) + ((array[3]<<24)&0xff000000));}/* Quick and dirty UNICODE to std. ascii */void cheap_uni2ascii(char *src, char *dest, int l){ for (; l > 0; l -=2) { *dest = *src; dest++; src +=2; } *dest = 0;}/* Quick and dirty ascii to unicode */void cheap_ascii2uni(char *src, char *dest, int l){ for (; l > 0; l--) { *dest++ = *src++; *dest++ = 0; }}void skipspace(char **c){ while( **c == ' ' ) (*c)++;}int gethex(char **c){ int value; skipspace(c); if (!(**c)) return(0); sscanf(*c,"%x",&value); while( **c != ' ' && (**c)) (*c)++; return(value);} /* Get a string of HEX bytes (space separated), * or if first char is ' get an ASCII string instead. */int gethexorstr(char **c, char *wb){ int l = 0; skipspace(c); if ( **c == '\'') { (*c)++; while ( **c ) { *(wb++) = *((*c)++); l++; } } else { do { *(wb++) = gethex(c); l++; skipspace(c); } while ( **c ); } return(l);}/* Simple buffer debugger, returns 1 if buffer dirty/edited */int debugit(char *buf, int sz){ char inbuf[100],whatbuf[100],*bp; int dirty=0,to,from,l,i,j,wlen,cofs = 0; printf("Buffer debugger. '?' for help.\n"); while (1) { l = fmyinput(".",inbuf,90); bp = inbuf; skipspace(&bp); if (l > 0 && *bp) { switch(*bp) { case 'd' : bp++; if (*bp) { from = gethex(&bp); to = gethex(&bp); } else { from = cofs; to = 0; } if (to == 0) to = from + 0x100; if (to > sz) to = sz; hexdump(buf,from,to,1); cofs = to; break; case 'a' : bp++; if (*bp) { from = gethex(&bp); to = gethex(&bp); } else { from = cofs; to = 0; } if (to == 0) to = from + 0x100; if (to > sz) to = sz; hexdump(buf,from,to,0); cofs = to; break;#if 0 case 'k' : bp++; if (*bp) { from = gethex(&bp); } else { from = cofs; } if (to > sz) to = sz; parse_block(from,1); cofs = to; break;#endif#if 0 case 'l' : bp++; if (*bp) { from = gethex(&bp); } else { from = cofs; } if (to > sz) to = sz; nk_ls(from+4,0); cofs = to; break;#endif case 'q': return(0); break; case 's': if (!dirty) printf("Buffer has not changed, no need to write..\n"); return(dirty); break; case 'h': bp++; if (*bp == 'a') { from = 0; to = sz; bp++; } else { from = gethex(&bp); to = gethex(&bp); } wlen = gethexorstr(&bp,whatbuf); if (to > sz) to = sz; printf("from: %x, to: %x, wlen: %d\n",from,to,wlen); for (i = from; i < to; i++) { for (j = 0; j < wlen; j++) { if ( *(buf+i+j) != *(whatbuf+j)) break; } if (j == wlen) printf("%06x ",i); } printf("\n"); break; case ':': bp++; if (!*bp) break; from = gethex(&bp); wlen = gethexorstr(&bp,whatbuf); printf("from: %x, wlen: %d\n",from,wlen); memcpy(buf+from,whatbuf,wlen); dirty = 1; break;#if 0 case 'p': j = 0; if (*(++bp) != 0) { from = gethex(&bp); } if (*(++bp) != 0) { j = gethex(&bp); } printf("from: %x, rid: %x\n",from,j); seek_n_destroy(from,j,500,0); break;#endif case '?': printf("d [<from>] [<to>] - dump buffer within range\n"); printf("a [<from>] [<to>] - same as d, but without ascii-part (for cut'n'paste)\n"); printf(": <offset> <hexbyte> [<hexbyte> ...] - change bytes\n"); printf("h <from> <to> <hexbyte> [<hexbyte> ...] - hunt (search) for bytes\n"); printf("ha <hexbyte> [<hexbyte] - Hunt all (whole buffer)\n"); printf("s - save & quit\n"); printf("q - quit (no save)\n"); printf(" instead of <hexbyte> etc. you may give 'string to enter/search a string\n"); break; default: printf("?\n"); break; } } }}/* ========================================================================= *//* The following routines are mostly for debugging, I used it * much during discovery. the -t command line option uses it, * also the 'st' and 's' from the editor & hexdebugger. * All offsets shown in these are unadjusted (ie you must add * headerpage (most often 0x1000) to get file offset) *//* Parse the nk datablock * vofs = offset into struct (after size linkage) */void parse_nk(struct hive *hdesc, int vofs, int blen){ struct nk_key *key; int i; printf("== nk at offset %0x\n",vofs);#define D_OFFS(o) ( (void *)&(key->o)-(void *)hdesc->buffer-vofs ) key = (struct nk_key *)(hdesc->buffer + vofs); printf("%04x type = 0x%02x %s\n", D_OFFS(type) , key->type, (key->type == KEY_ROOT ? "ROOT_KEY" : "") ); printf("%04x timestamp skipped\n", D_OFFS(timestamp) ); printf("%04x parent key offset = 0x%0lx\n", D_OFFS(ofs_parent) ,key->ofs_parent); printf("%04x number of subkeys = %ld\n", D_OFFS(no_subkeys),key->no_subkeys); printf("%04x lf-record offset = 0x%0lx\n",D_OFFS(ofs_lf),key->ofs_lf); printf("%04x number of values = %ld\n", D_OFFS(no_values),key->no_values); printf("%04x val-list offset = 0x%0lx\n",D_OFFS(ofs_vallist),key->ofs_vallist); printf("%04x sk-record offset = 0x%0lx\n",D_OFFS(ofs_sk),key->ofs_sk); printf("%04x classname offset = 0x%0lx\n",D_OFFS(ofs_classnam),key->ofs_classnam); printf("%04x *unused?* = 0x%0lx\n",D_OFFS(dummy4),key->dummy4); printf("%04x name length = %d\n", D_OFFS(len_name),key->len_name); printf("%04x classname length = %d\n", D_OFFS(len_classnam),key->len_classnam); printf("%04x Key name: <",D_OFFS(keyname) ); for(i = 0; i < key->len_name; i++) putchar(key->keyname[i]); printf(">\n== End of key info.\n");}/* Parse the vk datablock * vofs = offset into struct (after size linkage) */void parse_vk(struct hive *hdesc, int vofs, int blen){ struct vk_key *key; int i; printf("== vk at offset %0x\n",vofs); key = (struct vk_key *)(hdesc->buffer + vofs); printf("%04x name length = %d (0x%0x)\n", D_OFFS(len_name), key->len_name, key->len_name ); printf("%04x length of data = %ld (0x%0lx)\n", D_OFFS(len_data), key->len_data, key->len_data ); printf("%04x data offset = 0x%0lx\n",D_OFFS(ofs_data),key->ofs_data); printf("%04x value type = 0x%0lx %s\n", D_OFFS(val_type), key->val_type, (key->val_type <= REG_MAX ? val_types[key->val_type] : "(unknown)") ) ; printf("%04x flag = 0x%0x\n",D_OFFS(flag),key->flag); printf("%04x *unused?* = 0x%0x\n",D_OFFS(dummy1),key->dummy1); printf("%04x Key name: <",D_OFFS(keyname) ); for(i = 0; i < key->len_name; i++) putchar(key->keyname[i]); printf(">\n== End of key info.\n");}/* Parse the sk datablock * Gee, this is the security info. Who cares? *evil grin* * vofs = offset into struct (after size linkage) */void parse_sk(struct hive *hdesc, int vofs, int blen){ struct sk_key *key; /* int i; */ printf("== sk at offset %0x\n",vofs); key = (struct sk_key *)(hdesc->buffer + vofs); printf("%04x *unused?* = %d\n" , D_OFFS(dummy1), key->dummy1 ); printf("%04x Offset to prev sk = 0x%0lx\n", D_OFFS(ofs_prevsk), key->ofs_prevsk); printf("%04x Offset to next sk = 0x%0lx\n", D_OFFS(ofs_nextsk), key->ofs_nextsk); printf("%04x Usage counter = %ld (0x%0lx)\n", D_OFFS(no_usage), key->no_usage,key->no_usage); printf("%04x Security data len = %ld (0x%0lx)\n", D_OFFS(len_sk), key->len_sk,key->len_sk); printf("== End of key info.\n");}/* Parse the lf datablock (>4.0 'nk' offsets lookuptable) * vofs = offset into struct (after size linkage) */void parse_lf(struct hive *hdesc, int vofs, int blen){ struct lf_key *key; int i; printf("== lf at offset %0x\n",vofs); key = (struct lf_key *)(hdesc->buffer + vofs); printf("%04x number of keys = %d\n", D_OFFS(no_keys), key->no_keys ); for(i = 0; i < key->no_keys; i++) { printf("%04x %3d Offset: 0x%0lx - <%c%c%c%c>\n", D_OFFS(hash[i].ofs_nk), i, key->hash[i].ofs_nk, key->hash[i].name[0], key->hash[i].name[1], key->hash[i].name[2], key->hash[i].name[3] ); } printf("== End of key info.\n");}/* Parse the lh datablock (WinXP offsets lookuptable) * vofs = offset into struct (after size linkage) * The hash is most likely a base 37 conversion of the name string */void parse_lh(struct hive *hdesc, int vofs, int blen){ struct lf_key *key;
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -