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

📄 ntreg.c

📁 The Offline NT Password Editor (c) 1997-2004 Petter Nordahl-Hagen
💻 C
📖 第 1 页 / 共 5 页
字号:
  return(size);}/* ================================================================ *//* ** Registry manipulation routines ** *//* "directory scan", return next name/pointer of a subkey on each call * nkofs = offset to directory to scan * lfofs = pointer to int to hold the current scan position, *         set position to 0 to start. * sptr  = pointer to struct to hold a single result * returns: -1 = error. 0 = end of key. 1 = more subkeys to scan * NOTE: caller must free the name-buffer (struct ex_data *name) */int ex_next_n(struct hive *hdesc, int nkofs, int *count, int *countri, struct ex_data *sptr){  struct nk_key *key, *newnkkey;  int newnkofs;  struct lf_key *lfkey;  struct li_key *likey;  struct ri_key *rikey;  if (!nkofs) return(-1);  key = (struct nk_key *)(hdesc->buffer + nkofs);  if (key->id != 0x6b6e) {    printf("ex_next error: Not a 'nk' node at 0x%0x\n",nkofs);    return(-1);  }#define EXNDEBUG 0  lfkey = (struct lf_key *)(hdesc->buffer + key->ofs_lf + 0x1004);  rikey = (struct ri_key *)(hdesc->buffer + key->ofs_lf + 0x1004);  if (rikey->id == 0x6972) {   /* Is it extended 'ri'-block? */#if EXNDEBUG    printf("%d , %d\n",*countri,*count);#endif    if (*countri < 0 || *countri >= rikey->no_lis) { /* End of ri's? */      return(0);    }    /* Get the li of lf-struct that's current based on countri */    likey = (struct li_key *)( hdesc->buffer + rikey->hash[*countri].ofs_li + 0x1004 ) ;    if (likey->id == 0x696c) {      newnkofs = likey->hash[*count].ofs_nk + 0x1000;    } else {      lfkey = (struct lf_key *)( hdesc->buffer + rikey->hash[*countri].ofs_li + 0x1004 ) ;      newnkofs = lfkey->hash[*count].ofs_nk + 0x1000;    }    /* Check if current li/lf is exhausted */#if EXNDEBUG    printf("likey->no_keys = %d\n",likey->no_keys);#endif    if (*count >= likey->no_keys-1) { /* Last legal entry in li list? */      (*countri)++;  /* Bump up ri count so we take next ri entry next time */      (*count) = -1;  /* Reset li traverse counter for next round, not used later here */    }  } else { /* Plain handler */    if (key->no_subkeys <= 0 || *count >= key->no_subkeys) {      return(0);    }    if (lfkey->id == 0x696c) {   /* Is it 3.x 'li' instead? */      likey = (struct li_key *)(hdesc->buffer + key->ofs_lf + 0x1004);      newnkofs = likey->hash[*count].ofs_nk + 0x1000;    } else {      newnkofs = lfkey->hash[*count].ofs_nk + 0x1000;    }  }  sptr->nkoffs = newnkofs;  newnkkey = (struct nk_key *)(hdesc->buffer + newnkofs + 4);  sptr->nk = newnkkey;  if (newnkkey->id != 0x6b6e) {    printf("ex_next: ERROR: not 'nk' node at 0x%0x\n",newnkofs);    return(-1);  } else {    if (newnkkey->len_name <= 0) {      printf("ex_next: nk at 0x%0x has no name!\n",newnkofs);    } else {      sptr->name = (char *)malloc(newnkkey->len_name+1);      if (!sptr->name) {	printf("FATAL! ex_next: malloc() failed! Out of memory?\n");	abort();      }      strncpy(sptr->name,newnkkey->keyname,newnkkey->len_name);      sptr->name[newnkkey->len_name] = 0;    }  } /* if */  (*count)++;  return(1);  /*  return( *count <= key->no_subkeys); */}/* "directory scan" for VALUES, return next name/pointer of a value on each call * nkofs = offset to directory to scan * lfofs = pointer to int to hold the current scan position, *         set position to 0 to start. * sptr  = pointer to struct to hold a single result * returns: -1 = error. 0 = end of key. 1 = more values to scan * NOTE: caller must free the name-buffer (struct vex_data *name) */int ex_next_v(struct hive *hdesc, int nkofs, int *count, struct vex_data *sptr){  struct nk_key *key /* , *newnkkey */ ;  int vkofs,vlistofs;  int *vlistkey;  struct vk_key *vkkey;  if (!nkofs) return(-1);  key = (struct nk_key *)(hdesc->buffer + nkofs);  if (key->id != 0x6b6e) {    printf("ex_next_v error: Not a 'nk' node at 0x%0x\n",nkofs);    return(-1);  }  if (key->no_values <= 0 || *count >= key->no_values) {    return(0);  }  vlistofs = key->ofs_vallist + 0x1004;  vlistkey = (int *)(hdesc->buffer + vlistofs);  vkofs = vlistkey[*count] + 0x1004;  vkkey = (struct vk_key *)(hdesc->buffer + vkofs);  if (vkkey->id != 0x6b76) {    printf("ex_next_v: hit non valuekey (vk) node during scan at offs 0x%0x\n",vkofs);    return(-1);  }  /*  parse_vk(hdesc, vkofs, 4); */  sptr->vk = vkkey;  sptr->vkoffs = vkofs;  sptr->name = 0;  sptr->size = (vkkey->len_data & 0x7fffffff);  if (vkkey->len_name >0) {    CREATE(sptr->name,char,vkkey->len_name+1);    memcpy(sptr->name,vkkey->keyname,vkkey->len_name);    sptr->name[vkkey->len_name] = 0;  } else {    sptr->name = str_dup("@");  }  sptr->type = vkkey->val_type;  if (sptr->size) {    if (vkkey->val_type == REG_DWORD) {      if (vkkey->len_data & 0x80000000) {	sptr->val = (int)(vkkey->ofs_data);      }    }  } else if (vkkey->len_data == 0x80000000) {     /* Data SIZE is 0, high bit set: special inline case, data is DWORD and in TYPE field!! */    /* Used a lot in SAM, and maybe in SECURITY I think */    sptr->val = (int)(vkkey->val_type);    sptr->size = 4;    sptr->type = REG_DWORD;  } else {    sptr->val = 0;    sptr->size = 0;  }  (*count)++;  return( *count <= key->no_values );}/* traceback - trace nk's back to root, * building path string as we go. * nkofs  = offset to nk-node * path   = pointer to pathstring-buffer * maxlen = max length of path-buffer * return: length of path string */int get_abs_path(struct hive *hdesc, int nkofs, char *path, int maxlen){  /* int newnkofs; */  struct nk_key *key;  char tmp[ABSPATHLEN+1];  maxlen = (maxlen < ABSPATHLEN ? maxlen : ABSPATHLEN);  key = (struct nk_key *)(hdesc->buffer + nkofs);    if (key->id != 0x6b6e) {    printf("get_abs_path: Not a 'nk' node!\n");    return(0);  }  if (key->type == KEY_ROOT) {   /* We're at the root */    return(strlen(path));  }  strncpy(tmp,path,ABSPATHLEN-1);  if ( (strlen(path) + key->len_name) >= maxlen-6) {    snprintf(path,maxlen,"(...)%s",tmp);    return(strlen(path));   /* Stop trace when string exhausted */  }  *path = '\\';  memcpy(path+1,key->keyname,key->len_name);  strncpy(path+key->len_name+1,tmp,maxlen);  return(get_abs_path(hdesc, key->ofs_parent+0x1004, path, maxlen)); /* go back one more */}/* Value index table lookup * hdesc - hive as usual * vlistofs - offset of table * name - value name to look for * returns index into table or -1 if err */int vlist_find(struct hive *hdesc, int vlistofs, int numval, char *name){  struct vk_key *vkkey;  int i,vkofs;  long *vlistkey;  vlistkey = (long *)(hdesc->buffer + vlistofs);  for (i = 0; i < numval; i++) {    vkofs = vlistkey[i] + 0x1004;    vkkey = (struct vk_key *)(hdesc->buffer + vkofs);    if (vkkey->len_name == 0 && *name == '@') { /* @ is alias for nameless value */      return(i);    }    if (!strncmp(name, vkkey->keyname, strlen(name))) { /* name match? */      return(i);    }  }  return(-1);}/* Recursevely follow 'nk'-nodes based on a path-string, * returning offset of last 'nk' or 'vk' * vofs - offset to start node * path - null-terminated pathname (relative to vofs, \ is separator) * type - type to return 0=nk 1=vk * return: offset to nk or vk (or NULL if not found) */int trav_path(struct hive *hdesc, int vofs, char *path, int type){  struct nk_key *key, *newnkkey;  struct lf_key *lfkey;  struct li_key *likey;  struct ri_key *rikey;  long *vlistkey;  int newnkofs, plen, i, lfofs, vlistofs, adjust, r, ricnt, subs;  char *buf;  char part[ABSPATHLEN+1];  char *partptr;  if (!hdesc) return(0);  buf = hdesc->buffer;  if (*path == '\\' && *(path+1) != '\\') {      /* Start from root if path starts with \ */    path++;    vofs = hdesc->rootofs+4;  }  key = (struct nk_key *)(buf + vofs);  /*  printf("check of nk at offset: 0x%0x\n",vofs); */  if (key->id != 0x6b6e) {    printf("trav_path: Error: Not a 'nk' node!\n");    return(0);  }  /* Find \ delimiter or end of string, copying to name part buffer as we go,     rewriting double \\s */  partptr = part;  for(plen = 0; path[plen] && (path[plen] != '\\' || path[plen+1] == '\\'); plen++) {    if (path[plen] == '\\' && path[plen+1] == '\\') plen++; /* Skip one if double */    *partptr++ = path[plen];  }  *partptr = '\0';  /*  printf("Name component: <%s>\n",part); */  adjust = (path[plen] == '\\' ) ? 1 : 0;  /*  printf("Checking for <%s> with len %d\n",path,plen); */  if (!plen) return(vofs-4);     /* Path has no lenght - we're there! */  if ( (plen == 1) && (*path == '.')) {     /* Handle '.' current dir */    return(trav_path(hdesc,vofs,path+plen+adjust,type));  }  if ( (plen == 2) && !strncmp("..",path,2) ) { /* Get parent key */    newnkofs = key->ofs_parent + 0x1004;    /* Return parent (or only root if at the root) */    return(trav_path(hdesc, (key->type == KEY_ROOT ? vofs : newnkofs), path+plen+adjust, type));  }  /* at last name of path, and we want vk, and the nk has values */  if (!path[plen] && type == 1 && key->no_values) {       /*    printf("VK namematch for <%s>\n",part); */    vlistofs = key->ofs_vallist + 0x1004;    vlistkey = (long *)(buf + vlistofs);    i = vlist_find(hdesc, vlistofs, key->no_values, part);    if (i != -1) {      return(vlistkey[i] + 0x1000);    }  }  if (key->no_subkeys > 0) {    /* If it has subkeys, loop through the hash */    lfofs = key->ofs_lf + 0x1004;    /* lf (hash) record */    lfkey = (struct lf_key *)(buf + lfofs);    if (lfkey->id == 0x6972) { /* ri struct need special parsing */      /* Prime loop state */      rikey = (struct ri_key *)lfkey;      ricnt = rikey->no_lis;      r = 0;      likey = (struct li_key *)( hdesc->buffer + rikey->hash[r].ofs_li + 0x1004 ) ;      subs = likey->no_keys;      if (likey->id != 0x696c) {  /* Bwah, not li anyway, XP uses lh usually which is actually smarter */	lfkey = (struct lf_key *)( hdesc->buffer + rikey->hash[r].ofs_li + 0x1004 ) ;	likey = NULL;      }    } else {      if (lfkey->id == 0x696c) { /* li? */	likey = (struct li_key *)(buf + lfofs);      } else {	likey = NULL;      }      ricnt = 0; r = 0; subs = key->no_subkeys;    }    do {      for(i = 0; i < subs; i++) {	if (likey) newnkofs = likey->hash[i].ofs_nk + 0x1004;	else newnkofs = lfkey->hash[i].ofs_nk + 0x1004;	newnkkey = (struct nk_key *)(buf + newnkofs);	if (newnkkey->id != 0x6b6e) {	  printf("ERROR: not 'nk' node! (strange?)\n");	} else {	  if (newnkkey->len_name <= 0) {	    printf("[No name]\n");	  } else {	    if (!strncmp(part,newnkkey->keyname,plen)) {	      /*	    printf("Key at 0x%0x matches! recursing!\n",newnkofs); */	      return(trav_path(hdesc, newnkofs, path+plen+adjust, type));	    }	  }	} /* if id OK */      } /* hash loop */      r++;      if (ricnt && r < ricnt) {	newnkofs = rikey->hash[r].ofs_li;	likey = (struct li_key *)( hdesc->buffer + newnkofs + 0x1004 ) ;	subs = likey->no_keys;	if (likey->id != 0x696c) {  /* Bwah, not li anyway, XP uses lh usually which is actually smarter */	  lfkey = (struct lf_key *)( hdesc->buffer + rikey->hash[r].ofs_li + 0x1004 ) ;	  likey = NULL;	}      }    } while (r < ricnt && ricnt);  } /* if subkeys */  /* Not found */  return(0);}/* ls - list a 'nk' nodes subkeys and values * vofs - offset to start of data (skipping block linkage) * type - 0 = full, 1 = keys only. 2 = values only */void nk_ls(struct hive *hdesc, char *path, int vofs, int type){  struct nk_key *key;  int nkofs;  struct ex_data ex;  struct vex_data vex;  int count = 0, countri = 0;    nkofs = trav_path(hdesc, vofs, path, 0);  if(!nkofs) {    printf("nk_ls: Key <%s> not found\n",path);    return;  }  nkofs += 4;  key = (struct nk_key *)(hdesc->buffer + nkofs);  printf("ls of node at offset 0x%0x\n",nkofs);  if (key->id != 0x6b6e) {    printf("Error: Not a 'nk' node!\n");    debugit(hdesc->buffer,hdesc->size);      }    printf("Node has %ld subkeys and %ld values",key->no_subkeys,key->no_values);  if (key->len_classnam) printf(", and class-data of %d bytes",key->len_classnam);  printf("\n");  if (key->no_subkeys) {    printf("offs          key name\n");    while ((ex_next_n(hdesc, nkofs, &count, &countri, &ex) > 0)) {      printf("[%6x]   %c  <%s>\n", ex.nkoffs, (ex.nk->len_classnam)?'*':' ',ex.name);      FREE(ex.name);    }  }  count = 0;  if (key->no_values) {    printf("offs        size      type   value name                    [value if type DWORD]\n");    while ((ex_next_v(hdesc, nkofs, &count, &vex) > 0)) {      printf("[%6x] %6d  %-16s  <%s>", vex.vkoffs, vex.size,	     (vex.type < REG_MAX ? val_types[vex.type] : "(unknown)"), vex.name);      if (vex.type == REG_DWORD) printf(" %*d [0x%x]",25-strlen(vex.name),vex.val , vex.val);      printf("\n");      FREE(vex.name);    }  }}/* Get the type of a value */int get_val_type(struct hive *hdesc, int vofs, char *path){  struct vk_key *vkkey;  int vkofs;  vkofs = trav_path(hdesc, vofs,path,1);  if (!vkofs) {    return -1;  }  vkofs +=4;  vkkey = (struct vk_key *)(hdesc->buffer + vkofs);#if 0  if (vkkey->len_data & 0x80000000) return(REG_DWORD); /* Special case of INLINE storage */#endif  return(vkkey->val_type);}/* Get len of a value, given current key + path */int get_val_len(struct hive *hdesc, int vofs, char *path){  struct vk_key *vkkey;  int vkofs;  int len;  vkofs = trav_path(hdesc, vofs,path,1);  if (!vkofs) {    return -1;  }  vkofs +=4;  vkkey = (struct vk_key *)(hdesc->buffer + vkofs);  len = vkkey->len_data & 0x7fffffff;  if ( vkkey->len_data == 0x80000000 ) {  /* Special inline case, return size of 4 (dword) */    len = 4;  }  return(len);}/* Get void-pointer to value-data, also if inline. * If val_type != 0 a check for correct value type is done * Caller must keep track of value's length (call function above to get it) */void *get_val_data(struct hive *hdesc, int vofs, char *path, int val_type){  struct vk_key *vkkey;  int vkofs;  vkofs = trav_path(hdesc,vofs,path,1);  if (!vkofs) {    return NULL;  }  vkofs +=4;  vkkey = (struct vk_key *)(hdesc->buffer + vkofs);

⌨️ 快捷键说明

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