?? ntreg.c
字號:
int i; printf("== lh 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 - <hash: %08lx>\n", D_OFFS(lh_hash[i].ofs_nk), i, key->lh_hash[i].ofs_nk, key->lh_hash[i].hash ); } 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%0lx\n", D_OFFS(hash[i].ofs_nk), i, key->hash[i].ofs_nk); } printf("== End of key info.\n");}/* Parse the ri subindex-datablock * (Used to list li/lf/lh's when ~>500keys) * vofs = offset into struct (after size linkage) */void parse_ri(struct hive *hdesc, int vofs, int blen){ struct ri_key *key; int i; printf("== ri at offset %0x\n",vofs);#define D_OFFS(o) ( (void *)&(key->o)-(void *)hdesc->buffer-vofs ) key = (struct ri_key *)(hdesc->buffer + vofs); printf("%04x number of subindices = %d\n", D_OFFS(no_lis), key->no_lis ); for(i = 0; i < key->no_lis; i++) { printf("%04x %3d Offset: 0x%0lx\n", D_OFFS(hash[i].ofs_li), i, key->hash[i].ofs_li); } 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++; bzero(hdesc->buffer+vofs+4,seglen-4); if (verbose) { printf("FREE BLOCK!\n"); /* hexdump(hdesc->buffer,vofs,vofs+seglen+4,1); */ } } /* printf("Seglen: 0x%02x\n",seglen & 0xff ); */ 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 0x6c68: /* lh */ parse_lh(hdesc, vofs, seglen); break; case 0x6c69: /* li */ parse_li(hdesc, vofs, seglen); break; case 0x736b: /* sk */ parse_sk(hdesc, vofs, seglen); break; case 0x7269: /* ri */ parse_ri(hdesc, vofs, seglen); break; default: printf("value data, or not handeled yet!\n"); break; } } return(seglen);}/* ================================================================ *//* Scan and allocation routines *//* Find start of page given a current pointer into the buffer * hdesc = hive * vofs = offset pointer into buffer * returns: offset to start of page (and page header) */int find_page_start(struct hive *hdesc, int vofs){ int r,prev; struct hbin_page *h; /* Again, assume start at 0x1000 */ r = 0x1000; while (r < hdesc->size) { prev = r; h = (struct hbin_page *)(hdesc->buffer + r); if (h->id != 0x6E696268) return(0); if (h->ofs_next == 0) { printf("find_page_start: zero len or ofs_next found in page at 0x%x\n",r); return(0); } r += h->ofs_next; if (r > vofs) return (prev); } return(0);}/* Find free space in page * size = requested size in bytes * pofs = offset to start of actual page header * returns: offset to free block, or 0 for error */#define FB_DEBUG 0int find_free_blk(struct hive *hdesc, int pofs, int size){ int vofs = pofs + 0x20; int seglen; struct hbin_page *p; p = (struct hbin_page *)(hdesc->buffer + pofs); while (vofs-pofs < (p->ofs_next - HBIN_ENDFILL)) { seglen = get_int(hdesc->buffer+vofs); #if FB_DEBUG printf("** Block at offset %0x\n",vofs); printf("seglen: %d, %u, 0x%0x\n",seglen,seglen,seglen);#endif if (seglen == 0) { printf("find_free_blk: FATAL! Zero data block size! (not registry or corrupt file?)\n"); debugit(hdesc->buffer,hdesc->size); return(0); } if (seglen < 0) { seglen = -seglen;#if FB_DEBUG printf("USED BLOCK: %d, 0x%0x\n",seglen,seglen);#endif /* hexdump(hdesc->buffer,vofs,vofs+seglen+4,1); */ } else {#if FB_DEBUG printf("FREE BLOCK!\n"); #endif /* hexdump(hdesc->buffer,vofs,vofs+seglen+4,1); */ if (seglen >= size) {#if FB_DEBUG printf("find_free_blk: found size %d block at 0x%x\n",seglen,vofs);#endif#if 0 if (vofs == 0x19fb8) { printf("find_free_blk: vofs = %x, seglen = %x\n",vofs,seglen); debugit(hdesc->buffer,hdesc->size); abort(); }#endif return(vofs); } } vofs += seglen; } return(0); }#undef FB_DEBUG/* Search pages from start to find free block * hdesc - hive * size - space requested, in bytes * returns: offset to free block, 0 if not found or error */int find_free(struct hive *hdesc, int size){ int r,blk; struct hbin_page *h; /* Align to 8 byte boundary */ if (size & 7) size += (8 - (size & 7)); /* Again, assume start at 0x1000 */ r = 0x1000; while (r < hdesc->size) { h = (struct hbin_page *)(hdesc->buffer + r); if (h->id != 0x6E696268) return(0); if (h->ofs_next == 0) { printf("find_free: zero len or ofs_next found in page at 0x%x\n",r); return(0); } blk = find_free_blk(hdesc,r,size); if (blk) return (blk); r += h->ofs_next; } return(0);}/* Allocate a block of requested size if possible * hdesc - hive * pofs - If >0 will try this page first (ptr may be inside page) * size - number of bytes to allocate * returns: 0 - failed, else pointer to allocated block. * This function WILL CHANGE THE HIVE (change block linkage) if it * succeeds. */int alloc_block(struct hive *hdesc, int ofs, int size){ int pofs = 0; int blk = 0; int trail, trailsize, oldsz; if (hdesc->state & HMODE_NOALLOC) { printf("alloc_block: ERROR: Hive %s is in no allocation safe mode," "new space not allocated. Operation will fail!\n", hdesc->filename); return(0); } size += 4; /* Add linkage */ if (size & 7) size += (8 - (size & 7)); /* Check current page first */ if (ofs) { pofs = find_page_start(hdesc,ofs); blk = find_free_blk(hdesc,pofs,size); } /* Then check whole hive */ if (!blk) { blk = find_free(hdesc,size); } if (blk) { /* Got the space */ oldsz = get_int(hdesc->buffer+blk);#if 0 printf("Block at : %x\n",blk); printf("Old block size is: %x\n",oldsz); printf("New block size is: %x\n",size);#endif trailsize = oldsz - size; if (trailsize == 4) { trailsize = 0; size += 4; } #if 1 if (trailsize & 7) { /* Trail must be 8 aligned */ trailsize -= (8 - (trailsize & 7)); size += (8 - (trailsize & 7)); } if (trailsize == 4) { trailsize = 0; size += 4; }#endif#if 0 printf("trail after comp: %x\n",trailsize); printf("size after comp: %x\n",size);#endif /* Now change pointers on this to reflect new size */ *(int *)((hdesc->buffer)+blk) = -(size); /* If the fit was exact (unused block was same size as wee need) * there is no need for more, else make free block after end * of newly allocated one */ hdesc->useblk++; hdesc->unuseblk--; hdesc->usetot += size; hdesc->unusetot -= size; if (trailsize) { trail = blk + size; *(int *)((hdesc->buffer)+trail) = (int)trailsize; hdesc->useblk++; /* This will keep blockcount */ hdesc->unuseblk--; hdesc->usetot += 4; /* But account for more linkage bytes */ hdesc->unusetot -= 4; } /* Clear the block data, makes it easier to debug */ bzero( (void *)(hdesc->buffer+blk+4), size-4); hdesc->state |= HMODE_DIRTY; return(blk); } else { printf("alloc_block: failed to alloc %d bytes, and hive expansion not implemented yet!\n",size); } return(0);}/* Free a block in registry * hdesc - hive * blk - offset of block, MUST POINT TO THE LINKAGE! * returns bytes freed (incl linkage bytes) or 0 if fail * Will CHANGE HIVE IF SUCCESSFUL (changes linkage) */#define FB_DEBUG 1int free_block(struct hive *hdesc, int blk){ int pofs,vofs,seglen,prev,next,nextsz,prevsz,size; struct hbin_page *p; if (hdesc->state & HMODE_NOALLOC) { printf("free_block: ERROR: Hive %s is in no allocation safe mode," "space not freed. Operation will fail!\n", hdesc->filename); return(0); } size = get_int(hdesc->buffer+blk); if (size >= 0) { printf("free_block: trying to free already free block!\n");#ifdef DOCORE printf("blk = %x\n",blk); debugit(hdesc->buffer,hdesc->size); abort();#endif return(0); } size = -size; /* So, we must find start of the block BEFORE us */ pofs = find_page_start(hdesc,blk); if (!pofs) return(0); p = (struct hbin_page *)(hdesc->buffer + pofs); vofs = pofs + 0x20; prevsz = -32; if (vofs != blk) { /* Block is not at start of page? */ while (vofs-pofs < (p->ofs_next - HBIN_ENDFILL) ) { seglen = get_int(hdesc->buffer+vofs); if (seglen == 0) { printf("free_block: EEEK! Zero data block size! (not registry or corrupt file?)\n"); debugit(hdesc->buffer,hdesc->size); return(0); } if (seglen < 0) { seglen = -seglen; /* hexdump(hdesc->buffer,vofs,vofs+seglen+4,1); */ } prev = vofs; vofs += seglen; if (vofs == blk) break; } if (vofs != blk) { printf("free_block: ran off end of page!?!? Error in chains?\n");#ifdef DOCORE printf("vofs = %x, pofs = %x, blk = %x\n",vofs,pofs,blk); debugit(hdesc->buffer,hdesc->size); abort();#endif return(0); } prevsz = get_int(hdesc->buffer+prev); } /* We also need details on next block (unless at end of page) */ next = blk + size; nextsz = 0; if (next-pofs < (p->ofs_next - HBIN_ENDFILL) ) nextsz = get_int(hdesc->buffer+next);#if 0 printf("offset prev : %x , blk: %x , next: %x\n",prev,blk,next); printf("size prev : %x , blk: %x , next: %x\n",prevsz,size,nextsz);#endif /* Now check if next block is free, if so merge it with the one to be freed */ if ( nextsz > 0) {#if 0 printf("Swallow next\n");#endif size += nextsz; /* Swallow it in current block */ hdesc->useblk--; hdesc->usetot -= 4; hdesc->unusetot -= 4; } /* Now free the block (possibly with ajusted size as above) */ bzero( (void *)(hdesc->buffer+blk), size); *(int *)((hdesc->buffer)+blk) = (int)size; hdesc->usetot -= size; hdesc->unusetot -= size; hdesc->unuseblk--; hdesc->state |= HMODE_DIRTY; /* Check if previous block is also free, if so, merge.. */ if (prevsz > 0) {#if 0 printf("Swallow prev\n");#endif hdesc->usetot -= prevsz; hdesc->unusetot += prevsz; prevsz += size; /* And swallow current.. */ bzero( (void *)(hdesc->buffer+prev), prevsz); *(int *)((hdesc->buffer)+prev) = (int)prevsz; hdesc->useblk--; return(prevsz); }
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -