📄 ntreg.c
字号:
} /* 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; } } 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); abort(); 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 %d subkeys and %d values\n",key->no_subkeys,key->no_values); if (key->no_subkeys) { printf("offs key name\n"); while ((ex_next_n(hdesc, nkofs, &count, &countri, &ex) > 0)) { printf("[%6x] <%s>\n", ex.nkoffs, 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 (vkkey->len_data & 0x80000000) return(REG_DWORD); /* Special case of INLINE storage */ 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 ( !len ) { /* 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); if (vkkey->len_data == 0) return NULL; if (!(vkkey->len_data & 0x7fffffff)) { /* 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); }/* Write to registry value. Only permits writes in-place, ie * excact writes to overwrite an existing value, since allocation * of new stuff not implemented yet * Pass inn buffer with data len as first DWORD (as routines above) * returns: 0 - error, len - OK (len of data) */int put_buf2val(struct hive *hdesc, struct keyval *kv, int vofs, char *path, int type ){ int l; void *keydataptr; l = get_val_len(hdesc, vofs, path); if (l == -1) return(0); /* error */ if (!kv || (kv->len != l)) return(0); /* Check for exact match of supplied buffer */ keydataptr = get_val_data(hdesc, vofs, path, type); if (!keydataptr) return(0); /* error */ memcpy(keydataptr, &kv->data, l); hdesc->state |= HMODE_DIRTY; return(l);}/* And, yer basic DWORD write */int put_dword(struct hive *hdesc, int vofs, char *path, int dword){ struct keyval *kr; int r; ALLOC(kr,1,sizeof(int)+sizeof(int)); kr->len = sizeof(int); (int)kr->data = dword; r = put_buf2val(hdesc, kr, vofs, path, REG_DWORD); FREE(kr); return(r);}/* ================================================================ *//* Hive control (load/save/close) etc */void closeHive(struct hive *hdesc){ printf("closing hive %s\n",hdesc->filename); FREE(hdesc->filename); FREE(hdesc->buffer); FREE(hdesc);}/* Write the hive back to disk (only if dirty & not readonly */int writeHive(struct hive *hdesc){ int len; if (hdesc->state & HMODE_RO) return(0); if ( !(hdesc->state & HMODE_DIRTY)) return(0); if ( !(hdesc->state & HMODE_OPEN)) { /* File has been closed */ if (!(hdesc->filedesc = open(hdesc->filename,O_RDWR))) { fprintf(stderr,"writeHive: open(%s) failed: %s, FILE NOT WRITTEN!\n",hdesc->filename,strerror(errno)); return(1); } hdesc->state |= HMODE_OPEN; } /* Seek back to begginning of file (in case it's already open) */ lseek(hdesc->filedesc, 0, SEEK_SET); len = write(hdesc->filedesc, hdesc->buffer, hdesc->size); if (len != hdesc->size) { fprintf(stderr,"writeHive: write of %s failed: %s.\n",hdesc->filename,strerror(errno)); return(1); } hdesc->state &= (~HMODE_DIRTY); return(0);}struct hive *openHive(char *filename, int mode){ struct hive *hdesc; int fmode,r,vofs; struct stat sbuf; unsigned long pofs; off_t l; char *c; struct hbin_page *p; struct regf_header *hdr; int verbose = (mode & HMODE_VERBOSE); CREATE(hdesc,struct hive,1); hdesc->filename = str_dup(filename); hdesc->state = 0; hdesc->size = 0; hdesc->buffer = NULL; if ( (mode & HMODE_RO) ) { fmode = O_RDONLY; } else { fmode = O_RDWR; } hdesc->filedesc = open(hdesc->filename,fmode); if (!(hdesc->filedesc)) { fprintf(stderr,"openHive(%s) failed: %s, trying read-only\n",hdesc->filename,strerror(errno)); fmode = O_RDONLY; mode |= HMODE_RO; hdesc->filedesc = open(hdesc->filename,fmode); if (!(hdesc->filedesc)) { fprintf(stderr,"openHive(%s) in fallback RO-mode failed: %s\n",hdesc->filename,strerror(errno)); closeHive(hdesc); return(NULL); } } if ( fstat(hdesc->filedesc,&sbuf) ) { perror("stat()"); exit(1); } hdesc->size = sbuf.st_size; hdesc->state = mode | HMODE_OPEN; /* fprintf(stderr,"hiveOpen(%s) successful\n",hdesc->filename); */ /* Read the whole file */ ALLOC(hdesc->buffer,1,hdesc->size); r = read(hdesc->filedesc,hdesc->buffer,hdesc->size); if (r < hdesc->size) { fprintf(stderr,"Could not read file, got %d bytes while expecting %d\n", r, hdesc->size); closeHive(hdesc); return(NULL); } /* Now run through file, tallying all pages */ /* NOTE/KLUDGE: Assume first page starts at offset 0x1000 */ pofs = 0x1000; hdr = (struct regf_header *)hdesc->buffer; if (hdr->id != 0x66676572) { printf("openHive(%s): File does not seem to be a registry hive!\n",filename); return(hdesc); } printf("Hive's name (from header): <"); for (c = hdr->name; *c && (c < hdr->name + 64); c += 2) putchar(*c); hdesc->rootofs = hdr->ofs_rootkey + 0x1000; /* printf(">\nROOT KEY at offset: 0x%06x\n",hdesc->rootofs); */ while (pofs < hdesc->size) { if (verbose) hexdump(hdesc->buffer,pofs,pofs+0x20,1); p = (struct hbin_page *)(hdesc->buffer + pofs); hdesc->pages++; if (verbose) printf("\n###### Page at 0x%0x has size 0x%0x, next at 0x%0x ######\n",pofs,p->len_page,p->ofs_next); if (p->len_page == 0 || p->ofs_next == 0) { if (verbose) printf("openhive debug: bailing out.. pagesize zero!\n"); break; } vofs = pofs + 0x20; /* Skip page header */ while (vofs-pofs < p->ofs_next) { vofs += parse_block(hdesc,vofs,verbose); } pofs += p->ofs_next; } printf(">\nFile size %d [%x] bytes, containing %d pages (+ 1 headerpage)\n",hdesc->size,hdesc->size, hdesc->pages); printf("Used for data: %d/%d blocks/bytes, unused: %d/%d blocks/bytes.\n", hdesc->useblk,hdesc->usetot,hdesc->unuseblk,hdesc->unusetot); return(hdesc);}#if 0int main(void){ int d = 0; int val = 0; struct hive *hd; int nk; char p[ABSPATHLEN]; hd = openHive("system.wrks",HMODE_RO); printf("Loaded..\n"); /* d = debugit(hd->buffer,hd->size); printf("Buffer was %s\n", d ? "dirty" : "clean"); */ val = get_dword(hd, 0, "\\Select\\Current"); printf("old value: %d [%x]\n",val,val); val = 0xabcd1234; printf("Changig value to %d, returned err=%d\n",val, put_dword(hd,0,"\\Select\\Cgurrent",val)); val = get_dword(hd, 0, "\\Select\\Current"); printf("new value: %u [%x]\n",val,val); nk_ls(hd, "\\ControlSet001\\Services\\Xga",0,0); printf("Gurba\n"); nk = trav_path(hd, 0, "\\ControlSet001\\Services\\Xga",0); p[0] = 0; printf("get_abs_path returns: %d\n",get_abs_path(hd, nk+4, p, 50)); printf("And path = %s\n",p); closeHive(hd); return(0);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -