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

📄 ntreg.c

📁 The Offline NT Password Editor (c) 1997-2004 Petter Nordahl-Hagen
💻 C
📖 第 1 页 / 共 5 页
字号:
  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 + -