⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ntreg.c

📁 The Offline NT Password Editor (c) 1997-2004 Petter Nordahl-Hagen
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * 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;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -