📄 chntpw.c
字号:
printf("[%2d]: %s\n",n,origstring+i); i += strlen(origstring+i) + 1; n++; } printf("\nNow enter new strings, one by one.\n"); printf("Enter nothing to keep old.\n"); if (type == REG_MULTI_SZ) { printf("'--n' to quit (remove rest of strings)\n"); printf("'--i' insert new string at this point\n"); printf("'--q' to quit (leaving remaining strings as is)\n"); printf("'--Q' to quit and discard all changes\n"); printf("'--e' for empty string in this position\n"); } n = 0; i = 0; in = 0; go = 0; done = 0; /* Now this one is RATHER UGLY :-} */ while (i < (len>>1)-1 || !done) { printf("[%2d]: %s\n",n, insert == 1 ? "[INSERT]" : ((i < (len>>1)-1 ) ? origstring+i : "[NEW]")); if (insert) insert++; if (!go) fmyinput("-> ",inbuf, 500); else *inbuf = 0; if (*inbuf && strcmp("--q", inbuf)) { if (!strcmp("--n", inbuf) || !strcmp("--Q", inbuf)) { /* Zap rest */ i = (len>>1) ; done = 1; } else if (strcmp("--i", inbuf)) { /* Copy out given string */ if (!strcmp("--e",inbuf)) *inbuf = '\0'; if (newstring) newstring = realloc(newstring, in+strlen(inbuf)+1); else newstring = malloc(in+strlen(inbuf)+1); strcpy(newstring+in, inbuf); in += strlen(inbuf)+1; } else { insert = 1; } } else { /* Copy out default string */ if (newstring) newstring = realloc(newstring, in+strlen(origstring+i)+1); else newstring = malloc(in + strlen(origstring+i) + 1); strcpy(newstring+in, origstring+i); in += strlen(origstring+i)+1; if (!strcmp("--q", inbuf)) { go = 1; done = 1; if (!(i < (len>>1)-1 )) { in--; /* remove last empty if in NEW-mode */ } } } if (!insert) i += strlen(origstring+i) + 1; if (insert != 1) n++; if (insert == 2) insert = 0; if (type != REG_MULTI_SZ) { i = (len<<1); done = 1; } } if (strcmp("--Q", inbuf)) { /* We didn't bail out */ if (newstring) newstring = realloc(newstring, in+1); else newstring = malloc(in+1); if (type == REG_MULTI_SZ) { in++; *(newstring+in) = '\0'; /* Must add null termination */ } ALLOC(newkv,1,(in<<1)+sizeof(int)); newkv->len = in<<1; printf("newkv->len: %d\n",newkv->len); cheap_ascii2uni(newstring, (char *)&(newkv->data), in); d = 1; FREE(kv); kv = newkv; } break; default: printf("Type not handeled (yet), invoking hex editor on data!\n"); case REG_BINARY: fmyinput("New length (ENTER to keep same): ",inbuf,90); if (*inbuf) { newsize = atoi(inbuf); ALLOC(newkv,1,newsize+sizeof(int)+4); bzero(newkv,newsize+sizeof(int)+4); memcpy(newkv, kv, (len < newsize) ? (len) : (newsize) +sizeof(int)); FREE(kv); kv = newkv; kv->len = newsize; } d = debugit((char *)&kv->data, kv->len); break; } if (d) { if (!(put_buf2val(h, kv, nkofs, path, type))) { printf("Failed to set value!?\n"); } } FREE(kv);}/* look up command in array */int parsecmd(char **s, struct cmds *cmd){ /* char temp[10]; */ int /* i, */ l = 0; while ((*s)[l] && ((*s)[l] != ' ')) { l++; } while (cmd->cmd_num) { if (!strncmp(*s, cmd->cmd_str, l)) { *s += l; return(cmd->cmd_num); } cmd++; } return(0);}/* Simple interactive command-parser * Main loop for manually looking through the registry */void mainloop(void){ struct hive *hdesc; int cdofs, newofs; struct nk_key *cdkey; char inbuf[100], /* whatbuf[100], */ *bp; char path[1000]; int l, vkofs, nh; int usehive = 0; struct keyval *kv;#if ALLOC_DEBUG int pagestart; int freetest;#endif hdesc = hive[usehive]; cdofs = hdesc->rootofs; printf("Simple registry editor. ? for help.\n"); while (1) { cdkey = (struct nk_key *)(hdesc->buffer + cdofs); *path = 0; get_abs_path(hdesc,cdofs+4, path, 50);#if ALLOC_DEBUG pagestart = find_page_start(hdesc,cdofs); printf("find_page_start: 0x%x\n",pagestart); freetest = find_free_blk(hdesc,pagestart,10); printf("find_free_blk: 0x%x\n",freetest);#endif printf("\n[%0x] %s> ",cdofs,path); l = fmyinput("",inbuf,90); bp = inbuf; skipspace(&bp); if (l > 0 && *bp) { switch(parsecmd(&bp,maincmds)) { case MCMD_HELP: printf("Simple registry editor:\n"); printf("hive [<n>] - list loaded hives or switch to hive numer n'\n"); printf("cd <key> - change key\nls | dir [<key>] - show subkeys & values,\n"); printf("cat | type <value> - show key value\nhex <value> - hexdump of value data\nst [<hexaddr>] - show struct info\n"); /* printf("pw | passwd [<hexaddr>] - try the password routine on struct at <hexaddr>\n"); */ printf("ck [<keyname>] - Show keys class data, if it has any\n"); printf("nk <keyname> - add key\n"); printf("dk <keyname> - delete key (must be empty. recursion not supported yet)\n"); printf("ed <value> - Edit value\n"); printf("nv <type> <valuename> - Add value\n"); printf("dv <valuename> - Delete value\n"); printf("delallv - Delete all values in current key\n"); printf("rdel <keyname> - Recursively delete key & subkeys\n"); printf("debug - enter buffer hexeditor\nq - quit\n"); break; case MCMD_DELKEY : bp++; skipspace(&bp); del_key(hdesc, cdofs + 4, bp); break; case MCMD_NEWKEY : bp++; skipspace(&bp); add_key(hdesc, cdofs + 4, bp); break; case MCMD_DELVALL : bp++; skipspace(&bp); del_allvalues(hdesc, cdofs + 4); break; case MCMD_DELV : bp++; skipspace(&bp); del_value(hdesc, cdofs + 4, bp); break; case MCMD_ADDV : bp++; skipspace(&bp); nh = gethex(&bp); skipspace(&bp); add_value(hdesc, cdofs+4, bp, nh); break;#ifdef ALLOC_DEBUG case MCMD_FREE : bp++; skipspace(&bp); nh = gethex(&bp); free_block(hdesc, nh); break; case MCMD_ALLOC : bp++; skipspace(&bp); nh = gethex(&bp); alloc_block(hdesc, cdofs+4, nh); break;#endif case MCMD_LS : bp++; skipspace(&bp); nk_ls(hdesc, bp, cdofs+4, 0); break; case MCMD_CK : bp++; skipspace(&bp); kv = get_class(hdesc, cdofs+4, bp); if (kv) { hexdump((char *)&kv->data, 0, kv->len, 1); FREE(kv); } break; case MCMD_RDEL : bp++; skipspace(&bp); rdel_keys(hdesc, bp, cdofs+4); break; case MCMD_EDIT : bp++; skipspace(&bp); edit_val(hdesc, cdofs+4, bp); break; case MCMD_HIVE : bp++; skipspace(&bp); if (*bp) { nh = gethex(&bp); if (nh >= 0 && nh < no_hives) { usehive = nh; printf("Switching to hive #%d, named <%s>, size %d [0x%x]\n", usehive, hive[usehive]->filename, hive[usehive]->size, hive[usehive]->size); hdesc = hive[usehive]; cdofs = hdesc->rootofs; } } else { for (nh = 0; nh < no_hives; nh++) { printf("%c %c %2d %9d 0x%08x <%s>\n", (nh == usehive) ? '*' : ' ', (hive[nh]->state & HMODE_DIRTY) ? 'D' : ' ', nh, hive[nh]->size, hive[nh]->size, hive[nh]->filename); } } break; case MCMD_CD : bp++; skipspace(&bp); newofs = trav_path(hdesc, cdofs+4,bp,0); if (newofs) cdofs = newofs; else printf("Key %s not found!\n",bp); break; case MCMD_CAT: bp++; skipspace(&bp); cat_vk(hdesc,cdofs+4,bp,0); break; case MCMD_CATHEX: bp++; skipspace(&bp); cat_vk(hdesc,cdofs+4,bp,1); break; case MCMD_STRUCT: bp++; skipspace(&bp); vkofs = cdofs; if (*bp) { vkofs = gethex(&bp); } parse_block(hdesc,vkofs,1); break; case MCMD_DEBUG: if (debugit(hdesc->buffer,hdesc->size)) hdesc->state |= HMODE_DIRTY; break; case MCMD_QUIT: return; break; default: printf("Unknown command: %s\n",bp); break; } } }}/* List users in SAM file * pageit - hmm.. forgot this one for this release.. */int list_users(int pageit){ char s[200]; struct keyval *v; int nkofs /* ,vkofs */ ; int rid; int count = 0, countri = 0; struct ex_data ex; if (H_SAM < 0) return(1); nkofs = trav_path(hive[H_SAM], 0,"\\SAM\\Domains\\Account\\Users\\Names\\",0); if (!nkofs) { printf("Cannot find usernames in registry! (is this a SAM-hive?)\n"); return(1); } while ((ex_next_n(hive[H_SAM], nkofs+4, &count, &countri, &ex) > 0)) { /* Extract the value out of the username-key, value is RID */ snprintf(s,180,"\\SAM\\Domains\\Account\\Users\\Names\\%s\\@",ex.name); rid = get_dword(hive[H_SAM], 0, s); if (rid == 500) strncpy(admuser,ex.name,128); /* Copy out admin-name */ /* printf("name: %s, rid: %d (0x%0x)\n", ex.name, rid, rid); */ /* Now that we have the RID, build the path to, and get the V-value */ snprintf(s,180,"\\SAM\\Domains\\Account\\Users\\%08X\\V",rid); v = get_val2buf(hive[H_SAM], NULL, 0, s, REG_BINARY); if (!v) { printf("Cannot find value <%s>\n",s); return(1); } if (v->len < 0xcc) { printf("Value <%s> is too short (only %d bytes) to be a SAM user V-struct!\n", s, v->len); } else { change_pw( (char *)&v->data , rid, v->len, 1); } FREE(v); FREE(ex.name); } return(0);}/* Find a username in the SAM registry, then get it's V-value, * and feed it to the password changer. */void find_n_change(char *username){ char s[200]; struct vk_key *vkkey; struct keyval *v; int rid = 0; if ((H_SAM < 0) || (!username)) return; if (*username == '0' && *(username+1) == 'x') sscanf(username,"%i",&rid); if (!rid) { /* Look up username */ /* Extract the unnamed value out of the username-key, value is RID */ snprintf(s,180,"\\SAM\\Domains\\Account\\Users\\Names\\%s\\@",username); rid = get_dword(hive[H_SAM],0,s); if (rid == -1) { printf("Cannot find value <%s>\n",s); return; } } /* printf("Username: %s, RID = %d (0x%0x)\n",username,rid,rid); */ /* Now that we have the RID, build the path to, and get the V-value */ snprintf(s,180,"\\SAM\\Domains\\Account\\Users\\%08X\\V",rid); v = get_val2buf(hive[H_SAM], NULL, 0, s, REG_BINARY); if (!v) { printf("Cannot find value <%s>\n",s); return; } if (v->len < 0xcc) { printf("Value <%s> is too short (only %ld bytes) to be a SAM user V-struct!\n", s, vkkey->len_data); } else { change_pw( (char *)&v->data , rid, v->len, 0); if (dirty) { if (!(put_buf2val(hive[H_SAM], v, 0, s, REG_BINARY))) { printf("Failed to write updated <%s> to registry! Password change not completed!\n",s); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -