📄 ntreg.c
字号:
printf("%04x Offset to prev sk = 0x%0x\n", D_OFFS(ofs_prevsk), key->ofs_prevsk); printf("%04x Offset to next sk = 0x%0x\n", D_OFFS(ofs_nextsk), key->ofs_nextsk); printf("%04x Usage counter = %d (0x%0x)\n", D_OFFS(no_usage), key->no_usage,key->no_usage); printf("%04x Security data len = %d (0x%0x)\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%0x - <%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 li datablock (3.x 'nk' offsets list) * vofs = offset into struct (after size linkage) */void parse_li(struct hive *hdesc, int vofs, int blen){ struct li_key *key; int i; printf("== li at offset %0x\n",vofs);#define D_OFFS(o) ( (void *)&(key->o)-(void *)hdesc->buffer-vofs ) key = (struct li_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%0x\n", D_OFFS(hash[i].ofs_nk), i, key->hash[i].ofs_nk); } printf("== End of key info.\n");}/* Parse the datablock * vofs = offset into struct (after size linkage) */int parse_block(struct hive *hdesc, int vofs,int verbose){ unsigned short id; int seglen; seglen = get_int(hdesc->buffer+vofs); if (verbose || seglen == 0) { printf("** Block at offset %0x\n",vofs); printf("seglen: %d, %u, 0x%0x\n",seglen,seglen,seglen); } if (seglen == 0) { printf("Whoops! FATAL! Zero data block size! (not registry or corrupt file?)\n"); debugit(hdesc->buffer,hdesc->size); return(0); } if (seglen < 0) { seglen = -seglen; hdesc->usetot += seglen; hdesc->useblk++; if (verbose) { printf("USED BLOCK: %d, 0x%0x\n",seglen,seglen); hexdump(hdesc->buffer,vofs,vofs+seglen+4,1); } } else { hdesc->unusetot += seglen; hdesc->unuseblk++; if (verbose) { printf("FREE BLOCK!\n"); hexdump(hdesc->buffer,vofs,vofs+seglen+4,1); } } vofs += 4; id = (*(hdesc->buffer + vofs)<<8) + *(hdesc->buffer+vofs+1); if (verbose) { switch (id) { case 0x6e6b: /* nk */ parse_nk(hdesc, vofs, seglen); break; case 0x766b: /* vk */ parse_vk(hdesc, vofs, seglen); break; case 0x6c66: /* lf */ parse_lf(hdesc, vofs, seglen); break; case 0x6c69: /* li */ parse_li(hdesc, vofs, seglen); break; case 0x736b: /* sk */ parse_sk(hdesc, vofs, seglen); break; default: printf("Not handeled yet!\n"); break; } } return(seglen);}/* ================================================================ *//* ** 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); }#undef EXNDEBUG 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-struct that's current based on countri */ likey = (struct li_key *)( hdesc->buffer + rikey->hash[*countri].ofs_li + 0x1004 ) ; newnkofs = likey->hash[*count].ofs_nk + 0x1000; /* Check if current li 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 { /* Data SIZE is 0, special inline case, data is DWORD and in TYPE field!! */ sptr->val = sptr->type; sptr->type = REG_DWORD; sptr->size = 4; } (*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 */}/* 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 vk_key *vkkey; struct ri_key *rikey; long *vlistkey; int newnkofs, plen, i, lfofs, vkofs, vlistofs, adjust, r, ricnt, subs; char *buf; buf = hdesc->buffer; if (*path == '\\') { /* 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); } for(plen = 0; path[plen] && path[plen] != '\\'; plen++) ; 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) { vlistofs = key->ofs_vallist + 0x1004; vlistkey = (long *)(buf + vlistofs); for (i = 0; i < key->no_values; i++) { vkofs = vlistkey[i] + 0x1004; vkkey = (struct vk_key *)(buf + vkofs); if (vkkey->len_name == 0 && *path == '@') { /* @ is alias for nameless value */ return(vkofs-4); } if (!strncmp(path, vkkey->keyname, plen)) { /* name match? */ return(vkofs-4); } } } 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; } 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(path,newnkkey->keyname,plen)) { /* printf("Key at 0x%0x matches! recursing!\n",newnkofs); */ return(trav_path(hdesc, newnkofs, path+plen+adjust, type)); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -