📄 ntreg.c
字号:
if (vkkey->len_data == 0) return NULL; if (vkkey->len_data == 0x80000000) { /* Special inline case (len = 0x80000000) */ return(&vkkey->val_type); /* Data (4 bytes?) in type field */ } if (val_type && vkkey->val_type && (vkkey->val_type) != val_type) { printf("Value <%s> is not of correct type!\n",path); return NULL; } /* Negative len is inline, return ptr to offset-field which in * this case contains the data itself */ if (vkkey->len_data & 0x80000000) return(&vkkey->ofs_data); /* Normal return, return data pointer */ return(hdesc->buffer + vkkey->ofs_data + 0x1004);}/* Get and copy key data (if any) to buffer * if kv==NULL will allocate needed return struct & buffer * else will use buffer allocated for it (if it fits) * return len+data or NULL if not found (or other error) * NOTE: caller must deallocate buffer! a simple free(keyval) will suffice. */struct keyval *get_val2buf(struct hive *hdesc, struct keyval *kv, int vofs, char *path, int type ){ int l; struct keyval *kr; void *keydataptr; l = get_val_len(hdesc, vofs, path); if (l == -1) return(NULL); /* error */ if (kv && (kv->len < l)) return(NULL); /* Check for overflow of supplied buffer */ keydataptr = get_val_data(hdesc, vofs, path, type); /* if (!keydataptr) return(NULL); error */ /* Allocate space for data + header, or use supplied buffer */ if (kv) { kr = kv; } else { ALLOC(kr,1,l+sizeof(int)+4); } kr->len = l; memcpy(&(kr->data), keydataptr, l); return(kr);}/* DWORDs are so common that I make a small function to get it easily */int get_dword(struct hive *hdesc, int vofs, char *path){ struct keyval *v; int dword; v = get_val2buf(hdesc, NULL, vofs, path, REG_DWORD); if (!v) return(-1); /* well... -1 COULD BE THE STORED VALUE TOO */ dword = (int)v->data; FREE(v); return(dword); }/* Sanity checker when transferring data into a block * ofs = offset to data block, point to start of actual datablock linkage * data = data to copy * size = size of data to copy */int fill_block(struct hive *hdesc, int ofs, void *data, int size){ int blksize; blksize = get_int(hdesc->buffer + ofs); blksize = -blksize;#if 0 printf("fill_block: ofs = %x - %x, size = %x, blksize = %x\n",ofs,ofs+size,size,blksize);#endif /* if (blksize < size || ( (ofs & 0xfffff000) != ((ofs+size) & 0xfffff000) )) { */ if (blksize < size) { printf("fill_block: ERROR: block to small for data: ofs = %x, size = %x, blksize = %x\n",ofs,size,blksize); debugit(hdesc->buffer,hdesc->size); abort(); } memcpy(hdesc->buffer + ofs + 4, data, size); return(0);}/* Free actual data of a value, and update value descriptor * hdesc - hive * vofs - current key * path - path to value * we return offset of vk */int free_val_data(struct hive *hdesc, int vofs, char *path){ struct vk_key *vkkey; int vkofs, inl; vkofs = trav_path(hdesc,vofs,path,1); if (!vkofs) { return 0; } vkofs +=4; vkkey = (struct vk_key *)(hdesc->buffer + vkofs); inl = (vkkey->len_data & 0x80000000); if (!inl) { free_block(hdesc, vkkey->ofs_data + 0x1000); } vkkey->len_data = 0; vkkey->ofs_data = 0; return(vkofs);}/* Allocate data for value, realloc if it already contains stuff * hdesc - hive * vofs - current key * path - path to value * size - size of data * Returns: 0 - error, >0 pointer to actual dataspace */int alloc_val_data(struct hive *hdesc, int vofs, char *path, int size){ struct vk_key *vkkey; int vkofs, len; int datablk; vkofs = trav_path(hdesc,vofs,path,1); if (!vkofs) { return (0); } vkofs +=4; vkkey = (struct vk_key *)(hdesc->buffer + vkofs); /* Allocate space for new data */ datablk = alloc_block(hdesc, vkofs, size); if (!datablk) return(0); len = vkkey->len_data & 0x7fffffff; /* Then we dealloc if something was there before */ if (len) free_val_data(hdesc,vofs,path); /* Link in new datablock */ vkkey->ofs_data = datablk - 0x1000; vkkey->len_data = size; return(datablk + 4);}/* Add a value to a key. * Just add the metadata (empty value), to put data into it, use * put_buf2val afterwards * hdesc - hive * nkofs - current key * name - name of value * type - type of value * returns: 0 err, >0 offset to value metadata */struct vk_key *add_value(struct hive *hdesc, int nkofs, char *name, int type){ struct nk_key *nk; int oldvlist = 0, newvlist, newvkofs; struct vk_key *newvkkey; char *blank=""; if (!name || !*name) return(NULL); nk = (struct nk_key *)(hdesc->buffer + nkofs); if (nk->id != 0x6b6e) { printf("add_value: Key pointer not to 'nk' node!\n"); return(NULL); } if (trav_path(hdesc, nkofs, name, 1)) { printf("add_value: value %s already exists\n",name); return(NULL); } if (!strcmp(name,"@")) name = blank; if (nk->no_values) oldvlist = nk->ofs_vallist; newvlist = alloc_block(hdesc, nkofs, nk->no_values * 4 + 4); if (!newvlist) { printf("add_value: failed to allocate new value list!\n"); return(NULL); } if (oldvlist) { /* Copy old data if any */ memcpy(hdesc->buffer + newvlist + 4, hdesc->buffer + oldvlist + 0x1004, nk->no_values * 4 + 4); } /* Allocate value descriptor including its name */ newvkofs = alloc_block(hdesc, newvlist, sizeof(struct vk_key) + strlen(name)); if (!newvkofs) { printf("add_value: failed to allocate value descriptor\n"); free_block(hdesc, newvlist); return(NULL); } /* Success, now fill in the metadata */ newvkkey = (struct vk_key *)(hdesc->buffer + newvkofs + 4); /* Add pointer in value list */ *(int *)(hdesc->buffer + newvlist + 4 + (nk->no_values * 4)) = newvkofs - 0x1000; /* Fill in vk struct */ newvkkey->id = 0x6b76; newvkkey->len_name = strlen(name); if (type == REG_DWORD || type == REG_DWORD_BIG_ENDIAN) { newvkkey->len_data = 0x80000004; /* Prime the DWORD inline stuff */ } else { newvkkey->len_data = 0x00000000; } newvkkey->ofs_data = 0; newvkkey->val_type = type; newvkkey->flag = 1; /* Don't really know what this is */ newvkkey->dummy1 = 0; strcpy((char *)&newvkkey->keyname, name); /* And copy name */ /* Finally update the key and free the old valuelist */ nk->no_values++; nk->ofs_vallist = newvlist - 0x1000; if (oldvlist) free_block(hdesc,oldvlist + 0x1000); return(newvkkey);}/* Remove a vk-struct incl dataspace if any * Mostly for use by higher level stuff * hdesc - hive * vkofs - offset to vk */void del_vk(struct hive *hdesc, int vkofs){ struct vk_key *vk; vk = (struct vk_key *)(hdesc->buffer + vkofs); if (vk->id != 0x6b76) { printf("del_vk: Key pointer not to 'vk' node!\n"); return; } if ( !(vk->len_data & 0x80000000) && vk->ofs_data) { free_block(hdesc, vk->ofs_data + 0x1000); } free_block(hdesc, vkofs - 4);}/* Delete all values from key (used in recursive delete) * hdesc - yer usual hive * nkofs - current keyoffset */void del_allvalues(struct hive *hdesc, int nkofs){ int vlistofs, o, vkofs; long *vlistkey; struct nk_key *nk; nk = (struct nk_key *)(hdesc->buffer + nkofs); if (nk->id != 0x6b6e) { printf("del_allvalues: Key pointer not to 'nk' node!\n"); return; } if (!nk->no_values) { /* printf("del_avalues: Key has no values!\n"); */ return; } vlistofs = nk->ofs_vallist + 0x1004; vlistkey = (long *)(hdesc->buffer + vlistofs); /* Loop through index and delete all vk's */ for (o = 0; o < nk->no_values; o++) { vkofs = vlistkey[o] + 0x1004; del_vk(hdesc, vkofs); } /* Then zap the index, and update nk */ free_block(hdesc, vlistofs-4); nk->ofs_vallist = -1; nk->no_values = 0;}/* Delete single value from key * hdesc - yer usual hive * nkofs - current keyoffset * name - name of value to delete * returns: 0 - ok, 1 - failed */int del_value(struct hive *hdesc, int nkofs, char *name){ int vlistofs, slot, o, n, vkofs, newlistofs; long *vlistkey, *tmplist, *newlistkey; struct nk_key *nk; char *blank=""; if (!name || !*name) return(1); if (!strcmp(name,"@")) name = blank; nk = (struct nk_key *)(hdesc->buffer + nkofs); if (nk->id != 0x6b6e) { printf("del_value: Key pointer not to 'nk' node!\n"); return(1); } if (!nk->no_values) { printf("del_value: Key has no values!\n"); return(1); } vlistofs = nk->ofs_vallist + 0x1004; vlistkey = (long *)(hdesc->buffer + vlistofs); slot = vlist_find(hdesc, vlistofs, nk->no_values, name); if (slot == -1) { printf("del_value: value %s not found!\n",name); return(1); } /* Delete vk and data */ vkofs = vlistkey[slot] + 0x1004; del_vk(hdesc, vkofs); /* Copy out old index list */ CREATE(tmplist,long,nk->no_values); memcpy(tmplist, vlistkey, nk->no_values * sizeof(long)); free_block(hdesc,vlistofs-4); /* Get rid of old list */ nk->no_values--; if (nk->no_values) { newlistofs = alloc_block(hdesc, vlistofs, nk->no_values * sizeof(long)); if (!newlistofs) { printf("del_value: FATAL: Was not able to alloc new index list\n"); abort(); } /* Now copy over, omitting deleted entry */ newlistkey = (long *)(hdesc->buffer + newlistofs + 4); for (n = 0, o = 0; o < nk->no_values+1; o++, n++) { if (o == slot) o++; newlistkey[n] = tmplist[o]; } nk->ofs_vallist = newlistofs - 0x1000; } else { nk->ofs_vallist = -1; } return(0);}/* Add a subkey to a key * hdesc - usual.. * nkofs - offset of current nk * name - name of key to add * return: ptr to new keystruct, or NULL */#undef AKDEBUGstruct nk_key *add_key(struct hive *hdesc, int nkofs, char *name){ int slot, newlfofs = 0, oldlfofs = 0, newliofs = 0; int oldliofs = 0; int o, n, i, onkofs, newnkofs, cmp; int rimax, rislot, riofs, namlen; struct ri_key *ri = NULL; struct lf_key *newlf = NULL, *oldlf; struct li_key *newli = NULL, *oldli; struct nk_key *key, *newnk, *onk; long hash; key = (struct nk_key *)(hdesc->buffer + nkofs); if (key->id != 0x6b6e) { printf("add_key: current ptr not 'nk'\n"); return(NULL); } namlen = strlen(name); slot = -1; if (key->no_subkeys) { /* It already has subkeys */ oldlfofs = key->ofs_lf; oldliofs = key->ofs_lf; oldlf = (struct lf_key *)(hdesc->buffer + oldlfofs + 0x1004); if (oldlf->id != 0x666c && oldlf->id != 0x686c && oldlf->id != 0x696c && oldlf->id != 0x6972) { printf("add_key: index type not supported: 0x%04x\n",oldlf->id); return(NULL); } rimax = 0; ri = NULL; riofs = 0; rislot = -1; if (oldlf->id == 0x6972) { /* Indirect index 'ri', init loop */ riofs = key->ofs_lf; ri = (struct ri_key *)(hdesc->buffer + riofs + 0x1004); rimax = ri->no_lis-1;#ifdef AKDEBUG printf("add_key: entering 'ri' traverse, rimax = %d\n",rimax);#endif oldliofs = ri->hash[rislot+1].ofs_li; oldlfofs = ri->hash[rislot+1].ofs_li; } do { /* 'ri' loop, at least run once if no 'ri' deep index */ if (ri) { /* Do next 'ri' slot */ rislot++; oldliofs = ri->hash[rislot].ofs_li; oldlfofs = ri->hash[rislot].ofs_li; oldli = (struct li_key *)(hdesc->buffer + oldliofs + 0x1004); oldlf = (struct lf_key *)(hdesc->buffer + oldlfofs + 0x1004); } oldli = (struct li_key *)(hdesc->buffer + oldliofs + 0x1004); oldlf = (struct lf_key *)(hdesc->buffer + oldlfofs + 0x1004);#ifdef AKDEBUG printf("add_key: top of ri-loop: rislot = %d\n",rislot);#endif slot = -1; if (oldli->id == 0x696c) { /* li */ #ifdef AKDEBUG printf("add_key: li slot allocate\n");#endif FREE(newli); ALLOC(newli, 8 + 4*oldli->no_keys + 4, 1); newli->no_keys = oldli->no_keys; newli->id = oldli->id; /* Now copy old, checking where to insert (alphabetically) */ for (o = 0, n = 0; o < oldli->no_keys; o++,n++) { onkofs = oldli->hash[o].ofs_nk; onk = (struct nk_key *)(onkofs + hdesc->buffer + 0x1004); if (slot == -1) {#if 0 printf("add_key: cmp <%s> with <%s>\n",name,onk->keyname);#endif cmp = strncasecmp(name, onk->keyname, (namlen > onk->len_name) ? namlen : onk->len_name); if (!cmp) { printf("add_key: key %s already exists!\n",name); FREE(newli); return(NULL); } if ( cmp < 0) { slot = o; rimax = rislot; /* Cause end of 'ri' search, too */ n++;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -