HiddenReg.cpp
上传用户:shouhua
上传日期:2014-12-06
资源大小:5685k
文件大小:65k
源码类别:

杀毒

开发平台:

Visual C++

  1. // HiddenReg.cpp: implementation of the CHiddenReg class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. /*****************************************
  5. Author: Petter Nordahl-Hagen
  6. http://home.eunet.no/~pnordahl/ntpasswd/
  7. *****************************************/
  8. //n0bele 修改
  9. #include "stdafx.h"
  10. #include "..AntiEvilTools.h"
  11. #include "HiddenReg.h"
  12. #include <io.h>
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <ctype.h>
  16. #include <fcntl.h>
  17. #include <errno.h>
  18. #include <string.h>
  19. #define DOCORE 0
  20. #ifdef _DEBUG
  21. #undef THIS_FILE
  22. static char THIS_FILE[]=__FILE__;
  23. #define new DEBUG_NEW
  24. #endif
  25. const char ntreg_version[] = "ntreg lib routines, v0.92 040818, (c) Petter N Hagen";
  26. char *val_types[REG_MAX+1] = {
  27. "REG_NONE", "REG_SZ", "REG_EXPAND_SZ", "REG_BINARY", "REG_DWORD",       /* 0 - 4 */
  28. "REG_DWORD_BIG_ENDIAN", "REG_LINK",                                     /* 5 - 6 */
  29. "REG_MULTI_SZ", "REG_RESOUCE_LIST", "REG_FULL_RES_DESC", "REG_RES_REQ", /* 7 - 10 */
  30. };
  31. //////////////////////////////////////////////////////////////////////
  32. // Construction/Destruction
  33. //////////////////////////////////////////////////////////////////////
  34. CHiddenReg::CHiddenReg()
  35. {
  36. }
  37. CHiddenReg::~CHiddenReg()
  38. {
  39. }
  40. /* 工具程序 */
  41. // 复制(倾印)
  42. char *CHiddenReg::str_dup( const char *str )
  43. {
  44.     char *str_new;
  45.     if (!str)
  46.         return 0 ;
  47.     CREATE( str_new, char, strlen(str) + 1 );
  48.     strcpy( str_new, str );
  49.     return str_new;
  50. }
  51. // 提示用户,并得到用户的输入内容。
  52. // 返回值:得到用户输入的内容的长度。
  53. int CHiddenReg::fmyinput(char *prmpt, char *ibuf, int maxlen)
  54. {
  55. printf("%s",prmpt);
  56. fgets(ibuf,maxlen+1,stdin);
  57. ibuf[strlen(ibuf)-1] = 0;
  58. return(strlen(ibuf));
  59. }
  60. // 十六进制显示 
  61. void CHiddenReg::hexprnt(char *s, unsigned char *bytes, int len)
  62. {
  63. int i;
  64. printf("%s",s);
  65. for (i = 0; i < len; i++) {
  66. printf("%02x ",bytes[i]);
  67. }
  68. printf("n");
  69. }
  70. void CHiddenReg::hexdump(char *hbuf, int start, int stop, int ascii)
  71. {
  72. char c;
  73. int diff,i;
  74. while (start < stop ) {
  75. diff = stop - start;
  76. if (diff > 16) diff = 16;
  77. printf(":%05X  ",start);
  78. for (i = 0; i < diff; i++) {
  79. printf("%02X ",(unsigned char)*(hbuf+start+i));
  80. }
  81. if (ascii) {
  82. for (i = diff; i < 16; i++) printf("   ");
  83. for (i = 0; i < diff; i++) {
  84. c = *(hbuf+start+i);
  85. printf("%c", isprint(c) ? c : '.');
  86. }
  87. }
  88. printf("n");
  89. start += 16;
  90. }
  91. }
  92. int CHiddenReg::find_in_buf(char *buf, char *what, int sz, int len, int start)
  93. {
  94. int i;
  95. for (; start < sz; start++) {
  96. for (i = 0; i < len; i++) {
  97. if (*(buf+start+i) != *(what+i)) break;
  98. }
  99. if (i == len) return(start);
  100. }
  101. return(0);
  102. }
  103. int CHiddenReg::get_int( char *array )
  104. {
  105. return ((array[0]&0xff) + ((array[1]<<8)&0xff00) +
  106. ((array[2]<<16)&0xff0000) +
  107. ((array[3]<<24)&0xff000000));
  108. }
  109. void CHiddenReg::cheap_uni2ascii(char *src, char *dest, int l)
  110. {
  111. for (; l > 0; l -=2) {
  112. *dest = *src;
  113. dest++; src +=2;
  114. }
  115. *dest = 0;
  116. }
  117. void CHiddenReg::cheap_ascii2uni(char *src, char *dest, int l)
  118. {
  119. for (; l > 0; l--) 
  120. {
  121. *dest++ = *src++;
  122. *dest++ = 0;
  123. }
  124. }
  125. void CHiddenReg::skipspace(char **c)
  126. {
  127. while( **c == ' ' ) (*c)++;
  128. }
  129. int CHiddenReg::gethex(char **c)
  130. {
  131. int value;
  132. skipspace(c);
  133. if (!(**c)) return(0);
  134. sscanf(*c,"%x",&value);
  135. while( **c != ' ' && (**c)) (*c)++;
  136. return(value);
  137. }
  138. int CHiddenReg::gethexorstr(char **c, char *wb)
  139. {
  140. int l = 0;
  141. skipspace(c);
  142. if ( **c == ''') {
  143. (*c)++;
  144. while ( **c ) {
  145. *(wb++) = *((*c)++);
  146. l++;
  147. }
  148. } else {
  149. do {
  150. *(wb++) = gethex(c);
  151. l++;
  152. skipspace(c);
  153. } while ( **c );
  154. }
  155. return(l);
  156. }
  157. int CHiddenReg::debugit(char *buf, int sz)
  158. {
  159. char inbuf[100],whatbuf[100],*bp;
  160. int dirty=0,to,from,l,i,j,wlen,cofs = 0;
  161. printf("Buffer debugger. '?' for help.n");
  162. while (1) {
  163. l = fmyinput(".",inbuf,90);
  164. bp = inbuf;
  165. skipspace(&bp);
  166. if (l > 0 && *bp) {
  167. switch(*bp) {
  168. case 'd' :
  169. bp++;
  170. if (*bp) {
  171. from = gethex(&bp);
  172. to   = gethex(&bp);
  173. } else {
  174. from = cofs; to = 0;
  175. }
  176. if (to == 0) to = from + 0x100;
  177. if (to > sz) to = sz;
  178. hexdump(buf,from,to,1);
  179. cofs = to;
  180. break;
  181. case 'a' :
  182. bp++;
  183. if (*bp) {
  184. from = gethex(&bp);
  185. to   = gethex(&bp);
  186. } else {
  187. from = cofs; to = 0;
  188. }
  189. if (to == 0) to = from + 0x100;
  190. if (to > sz) to = sz;
  191. hexdump(buf,from,to,0);
  192. cofs = to;
  193. break;
  194. #if 0
  195. case 'k' :
  196. bp++;
  197. if (*bp) {
  198. from = gethex(&bp);
  199. } else {
  200. from = cofs;
  201. }
  202. if (to > sz) to = sz;
  203. parse_block(from,1);
  204. cofs = to;
  205. break;
  206. #endif
  207. #if 0
  208. case 'l' :
  209. bp++;
  210. if (*bp) {
  211. from = gethex(&bp);
  212. } else {
  213. from = cofs;
  214. }
  215. if (to > sz) to = sz;
  216. nk_ls(from+4,0);
  217. cofs = to;
  218. break;
  219. #endif
  220. case 'q':
  221. return(0);
  222. break;
  223. case 's':
  224. if (!dirty) printf("Buffer has not changed, no need to write..n");
  225. return(dirty);
  226. break;
  227. case 'h':
  228. bp++;
  229. if (*bp == 'a') {
  230. from = 0;
  231. to = sz;
  232. bp++;
  233. } else {
  234. from = gethex(&bp);
  235. to   = gethex(&bp);
  236. }
  237. wlen = gethexorstr(&bp,whatbuf);
  238. if (to > sz) to = sz;
  239. printf("from: %x, to: %x, wlen: %dn",from,to,wlen);
  240. for (i = from; i < to; i++) {
  241. for (j = 0; j < wlen; j++) {
  242. if ( *(buf+i+j) != *(whatbuf+j)) break;
  243. }
  244. if (j == wlen) printf("%06x ",i);
  245. }
  246. printf("n");
  247. break;
  248. case ':':
  249. bp++;
  250. if (!*bp) break;
  251. from = gethex(&bp);
  252. wlen = gethexorstr(&bp,whatbuf);
  253. printf("from: %x, wlen: %dn",from,wlen);
  254. memcpy(buf+from,whatbuf,wlen);
  255. dirty = 1;
  256. break;
  257. #if 0
  258. case 'p':
  259. j = 0;
  260. if (*(++bp) != 0) {
  261. from = gethex(&bp);
  262. }
  263. if (*(++bp) != 0) {
  264. j = gethex(&bp);
  265. }
  266. printf("from: %x, rid: %xn",from,j);
  267. seek_n_destroy(from,j,500,0);
  268. break;
  269. #endif
  270. case '?':
  271. printf("d [<from>] [<to>] - dump buffer within rangen");
  272. printf("a [<from>] [<to>] - same as d, but without ascii-part (for cut'n'paste)n");
  273. printf(": <offset> <hexbyte> [<hexbyte> ...] - change bytesn");
  274. printf("h <from> <to> <hexbyte> [<hexbyte> ...] - hunt (search) for bytesn");
  275. printf("ha <hexbyte> [<hexbyte] - Hunt all (whole buffer)n");
  276. printf("s - save & quitn");
  277. printf("q - quit (no save)n");
  278. printf("  instead of <hexbyte> etc. you may give 'string to enter/search a stringn");
  279. break;
  280. default:
  281. printf("?n");
  282. break;
  283.  }
  284.       }
  285.    }
  286. }
  287. void CHiddenReg::parse_nk(struct hive *hdesc, int vofs, int blen)
  288. {
  289. struct nk_key *key;
  290. int i;
  291. printf("== nk at offset %0xn",vofs);
  292. #define D_OFFS(o) ( (int *)&(key->o)-(int *)hdesc->buffer-vofs )
  293. key = (struct nk_key *)(hdesc->buffer + vofs);
  294. printf("%04x   type              = 0x%02x %sn", D_OFFS(type)  , key->type,
  295. (key->type == KEY_ROOT ? "ROOT_KEY" : "") );
  296. printf("%04x   timestamp skippedn", D_OFFS(timestamp) );
  297. printf("%04x   parent key offset = 0x%0lxn", D_OFFS(ofs_parent) ,key->ofs_parent);
  298. printf("%04x   number of subkeys = %ldn", D_OFFS(no_subkeys),key->no_subkeys);
  299. printf("%04x   lf-record offset  = 0x%0lxn",D_OFFS(ofs_lf),key->ofs_lf);
  300. printf("%04x   number of values  = %ldn", D_OFFS(no_values),key->no_values);
  301. printf("%04x   val-list offset   = 0x%0lxn",D_OFFS(ofs_vallist),key->ofs_vallist);
  302. printf("%04x   sk-record offset  = 0x%0lxn",D_OFFS(ofs_sk),key->ofs_sk);
  303. printf("%04x   classname offset  = 0x%0lxn",D_OFFS(ofs_classnam),key->ofs_classnam);
  304. printf("%04x   *unused?*         = 0x%0lxn",D_OFFS(dummy4),key->dummy4);
  305. printf("%04x   name length       = %dn", D_OFFS(len_name),key->len_name);
  306. printf("%04x   classname length  = %dn", D_OFFS(len_classnam),key->len_classnam);
  307. printf("%04x   Key name: <",D_OFFS(keyname) );
  308. for(i = 0; i < key->len_name; i++) putchar(key->keyname[i]);
  309. printf(">n== End of key info.n");
  310. }
  311. void CHiddenReg::parse_vk(struct hive *hdesc, int vofs, int blen)
  312. {
  313. struct vk_key *key;
  314. int i;
  315. printf("== vk at offset %0xn",vofs);
  316. key = (struct vk_key *)(hdesc->buffer + vofs);
  317. printf("%04x   name length       = %d (0x%0x)n", D_OFFS(len_name),
  318. key->len_name, key->len_name  );
  319. printf("%04x   length of data    = %ld (0x%0lx)n", D_OFFS(len_data),
  320. key->len_data, key->len_data  );
  321. printf("%04x   data offset       = 0x%0lxn",D_OFFS(ofs_data),key->ofs_data);
  322. printf("%04x   value type        = 0x%0lx  %sn", D_OFFS(val_type), key->val_type,
  323. (key->val_type <= REG_MAX ? val_types[key->val_type] : "(unknown)") ) ;
  324. printf("%04x   flag              = 0x%0xn",D_OFFS(flag),key->flag);
  325. printf("%04x   *unused?*         = 0x%0xn",D_OFFS(dummy1),key->dummy1);
  326. printf("%04x   Key name: <",D_OFFS(keyname) );
  327. for(i = 0; i < key->len_name; i++) putchar(key->keyname[i]);
  328. printf(">n== End of key info.n");
  329. }
  330. void CHiddenReg::parse_sk(struct hive *hdesc, int vofs, int blen)
  331. {
  332. struct sk_key *key;
  333. /* int i; */
  334. printf("== sk at offset %0xn",vofs);
  335. key = (struct sk_key *)(hdesc->buffer + vofs);
  336. printf("%04x   *unused?*         = %dn"   , D_OFFS(dummy1),     key->dummy1    );
  337. printf("%04x   Offset to prev sk = 0x%0lxn", D_OFFS(ofs_prevsk), key->ofs_prevsk);
  338. printf("%04x   Offset to next sk = 0x%0lxn", D_OFFS(ofs_nextsk), key->ofs_nextsk);
  339. printf("%04x   Usage counter     = %ld (0x%0lx)n", D_OFFS(no_usage),
  340. key->no_usage,key->no_usage);
  341. printf("%04x   Security data len = %ld (0x%0lx)n", D_OFFS(len_sk),
  342. key->len_sk,key->len_sk);
  343. printf("== End of key info.n");
  344. }
  345. void CHiddenReg::parse_lf(struct hive *hdesc, int vofs, int blen)
  346. {
  347. struct lf_key *key;
  348. int i;
  349. printf("== lf at offset %0xn",vofs);
  350. key = (struct lf_key *)(hdesc->buffer + vofs);
  351. printf("%04x   number of keys    = %dn", D_OFFS(no_keys), key->no_keys  );
  352. for(i = 0; i < key->no_keys; i++) {
  353. printf("%04x      %3d   Offset: 0x%0lx  - <%c%c%c%c>n", 
  354. D_OFFS(hash[i].ofs_nk), i,
  355. key->hash[i].ofs_nk,
  356. key->hash[i].name[0],
  357. key->hash[i].name[1],
  358. key->hash[i].name[2],
  359. key->hash[i].name[3] );
  360. }
  361. printf("== End of key info.n");
  362. }
  363. void CHiddenReg::parse_lh(struct hive *hdesc, int vofs, int blen)
  364. {
  365. struct lf_key *key;
  366. int i;
  367. printf("== lh at offset %0xn",vofs);
  368. key = (struct lf_key *)(hdesc->buffer + vofs);
  369. printf("%04x   number of keys    = %dn", D_OFFS(no_keys), key->no_keys  );
  370. for(i = 0; i < key->no_keys; i++) 
  371. {
  372. //    printf("%04x      %3d   Offset: 0x%0lx  - <hash: %08lx>n", 
  373. //    D_OFFS(lh_hash[i].ofs_nk), i,
  374. //    key->lh_hash[i].ofs_nk,
  375. //         key->lh_hash[i].hash );
  376. }
  377. printf("== End of key info.n");
  378. }
  379. void CHiddenReg::parse_li(struct hive *hdesc, int vofs, int blen)
  380. {
  381. struct li_key *key;
  382. int i;
  383. printf("== li at offset %0xn",vofs);
  384. #define D_OFFS(o) ( (int *)&(key->o)-(int *)hdesc->buffer-vofs )
  385. key = (struct li_key *)(hdesc->buffer + vofs);
  386. printf("%04x   number of keys    = %dn", D_OFFS(no_keys), key->no_keys  );
  387. for(i = 0; i < key->no_keys; i++) {
  388. printf("%04x      %3d   Offset: 0x%0lxn", 
  389. D_OFFS(hash[i].ofs_nk), i,
  390. key->hash[i].ofs_nk);
  391. }
  392. printf("== End of key info.n");
  393. }
  394. void CHiddenReg::parse_ri(struct hive *hdesc, int vofs, int blen)
  395. {
  396. struct ri_key *key;
  397. int i;
  398. printf("== ri at offset %0xn",vofs);
  399. #define D_OFFS(o) ( (int *)&(key->o)-(int *)hdesc->buffer-vofs )
  400. key = (struct ri_key *)(hdesc->buffer + vofs);
  401. printf("%04x   number of subindices = %dn", D_OFFS(no_lis), key->no_lis  );
  402. for(i = 0; i < key->no_lis; i++) {
  403. printf("%04x      %3d   Offset: 0x%0lxn", 
  404. D_OFFS(hash[i].ofs_li), i,
  405. key->hash[i].ofs_li);
  406. }
  407. printf("== End of key info.n");
  408. }
  409. void CHiddenReg::bzero(void *s,int n)
  410. {     
  411. memset(s,0,n);
  412. }
  413. int CHiddenReg::strncasecmp(const char *s1, const char *s2, size_t n)
  414. {
  415. return _stricmp(s1,s2);
  416. }
  417. int CHiddenReg::parse_block(struct hive *hdesc, int vofs,int verbose)
  418. {
  419. unsigned short id;
  420. int seglen;
  421. seglen = get_int(hdesc->buffer+vofs);  
  422. if (verbose || seglen == 0) {
  423. printf("** Block at offset %0xn",vofs);
  424. printf("seglen: %d, %u, 0x%0xn",seglen,seglen,seglen);
  425. }
  426. if (seglen == 0) {
  427. printf("Whoops! FATAL! Zero data block size! (not registry or corrupt file?)n");
  428. debugit(hdesc->buffer,hdesc->size);
  429. return(0);
  430. }
  431. if (seglen < 0) {
  432. seglen = -seglen;
  433. hdesc->usetot += seglen;
  434. hdesc->useblk++;
  435. if (verbose) {
  436. printf("USED BLOCK: %d, 0x%0xn",seglen,seglen);
  437. /*      hexdump(hdesc->buffer,vofs,vofs+seglen+4,1); */
  438. }
  439. } else {
  440. hdesc->unusetot += seglen;
  441. hdesc->unuseblk++;
  442. bzero(hdesc->buffer+vofs+4,seglen-4);
  443. if (verbose) {
  444. printf("FREE BLOCK!n"); 
  445. /*      hexdump(hdesc->buffer,vofs,vofs+seglen+4,1); */
  446. }
  447. }
  448. /*  printf("Seglen: 0x%02xn",seglen & 0xff ); */
  449. vofs += 4;
  450. id = (*(hdesc->buffer + vofs)<<8) + *(hdesc->buffer+vofs+1);
  451. if (verbose) {
  452. switch (id) {
  453. case 0x6e6b: /* nk */
  454. parse_nk(hdesc, vofs, seglen);
  455. break;
  456. case 0x766b: /* vk */
  457. parse_vk(hdesc, vofs, seglen);
  458. break;
  459. case 0x6c66: /* lf */
  460. parse_lf(hdesc, vofs, seglen);
  461. break;
  462. case 0x6c68: /* lh */
  463. parse_lh(hdesc, vofs, seglen);
  464. break;
  465. case 0x6c69: /* li */
  466. parse_li(hdesc, vofs, seglen);
  467. break;
  468. case 0x736b: /* sk */
  469. parse_sk(hdesc, vofs, seglen);
  470. break;
  471. case 0x7269: /* ri */
  472. parse_ri(hdesc, vofs, seglen);
  473. break;
  474. default:
  475. printf("value data, or not handeled yet!n");
  476. break;
  477. }
  478. }
  479. return(seglen);
  480. }
  481. int CHiddenReg::find_page_start(struct hive *hdesc, int vofs)
  482. {
  483. int r,prev;
  484. struct hbin_page *h;
  485. /* Again, assume start at 0x1000 */
  486. r = 0x1000;
  487. while (r < hdesc->size) {
  488. prev = r;
  489. h = (struct hbin_page *)(hdesc->buffer + r);
  490. if (h->id != 0x6E696268) return(0);
  491. if (h->ofs_next == 0) {
  492. printf("find_page_start: zero len or ofs_next found in page at 0x%xn",r);
  493. return(0);
  494. }
  495. r += h->ofs_next;
  496. if (r > vofs) return (prev);
  497. }
  498. return(0);
  499. }
  500. #define FB_DEBUG 0
  501. int CHiddenReg::find_free_blk(struct hive *hdesc, int pofs, int size)
  502. {
  503. int vofs = pofs + 0x20;
  504. int seglen;
  505. struct hbin_page *p;
  506. p = (struct hbin_page *)(hdesc->buffer + pofs);
  507. while (vofs-pofs < (p->ofs_next - HBIN_ENDFILL)) {
  508. seglen = get_int(hdesc->buffer+vofs);  
  509. #if FB_DEBUG
  510. printf("** Block at offset %0xn",vofs);
  511. printf("seglen: %d, %u, 0x%0xn",seglen,seglen,seglen);
  512. #endif
  513. if (seglen == 0) {
  514. printf("find_free_blk: FATAL! Zero data block size! (not registry or corrupt file?)n");
  515. debugit(hdesc->buffer,hdesc->size);
  516. return(0);
  517. }
  518. if (seglen < 0) {
  519. seglen = -seglen;
  520. #if FB_DEBUG
  521. printf("USED BLOCK: %d, 0x%0xn",seglen,seglen);
  522. #endif
  523. /*      hexdump(hdesc->buffer,vofs,vofs+seglen+4,1); */
  524. } else {
  525. #if FB_DEBUG
  526. printf("FREE BLOCK!n"); 
  527. #endif
  528. /*      hexdump(hdesc->buffer,vofs,vofs+seglen+4,1); */
  529. if (seglen >= size) {
  530. #if FB_DEBUG
  531. printf("find_free_blk: found size %d block at 0x%xn",seglen,vofs);
  532. #endif
  533. #if 0
  534. if (vofs == 0x19fb8) {
  535. printf("find_free_blk: vofs = %x, seglen = %xn",vofs,seglen);
  536. debugit(hdesc->buffer,hdesc->size);
  537. abort();
  538. }
  539. #endif
  540. return(vofs);
  541. }
  542. }
  543. vofs += seglen;
  544. }
  545. return(0);
  546. }
  547. #undef FB_DEBUG
  548. int CHiddenReg::find_free(struct hive *hdesc, int size)
  549. {
  550. int r,blk;
  551. struct hbin_page *h;
  552. /* Align to 8 byte boundary */
  553. if (size & 7) size += (8 - (size & 7));
  554. /* Again, assume start at 0x1000 */
  555. r = 0x1000;
  556. while (r < hdesc->size) {
  557. h = (struct hbin_page *)(hdesc->buffer + r);
  558. if (h->id != 0x6E696268) return(0);
  559. if (h->ofs_next == 0) {
  560. printf("find_free: zero len or ofs_next found in page at 0x%xn",r);
  561. return(0);
  562. }
  563. blk = find_free_blk(hdesc,r,size);
  564. if (blk) return (blk);
  565. r += h->ofs_next;
  566. }
  567. return(0);
  568. }
  569. int CHiddenReg::alloc_block(struct hive *hdesc, int ofs, int size)
  570. {
  571. int pofs = 0;
  572. int blk = 0;
  573. int trail, trailsize, oldsz;
  574. if (hdesc->state & HMODE_NOALLOC) {
  575. printf("alloc_block: ERROR: Hive %s is in no allocation safe mode,"
  576. "new space not allocated. Operation will fail!n", hdesc->filename);
  577. return(0);
  578. }
  579. size += 4;  /* Add linkage */
  580. if (size & 7) size += (8 - (size & 7));
  581. /* Check current page first */
  582. if (ofs) {
  583. pofs = find_page_start(hdesc,ofs);
  584. blk = find_free_blk(hdesc,pofs,size);
  585. }
  586. /* Then check whole hive */
  587. if (!blk) {
  588. blk = find_free(hdesc,size);
  589. }
  590. if (blk) {  /* Got the space */
  591. oldsz = get_int(hdesc->buffer+blk);
  592. #if 0
  593. printf("Block at         : %xn",blk);
  594. printf("Old block size is: %xn",oldsz);
  595. printf("New block size is: %xn",size);
  596. #endif
  597. trailsize = oldsz - size;
  598. if (trailsize == 4) {
  599. trailsize = 0;
  600. size += 4;
  601. }
  602. #if 1
  603. if (trailsize & 7) { /* Trail must be 8 aligned */
  604. trailsize -= (8 - (trailsize & 7));
  605. size += (8 - (trailsize & 7));
  606. }
  607. if (trailsize == 4) {
  608. trailsize = 0;
  609. size += 4;
  610. }
  611. #endif
  612. #if 0
  613. printf("trail after comp: %xn",trailsize);
  614. printf("size  after comp: %xn",size);
  615. #endif
  616. /* Now change pointers on this to reflect new size */
  617. *(int *)((hdesc->buffer)+blk) = -(size);
  618. /* If the fit was exact (unused block was same size as wee need)
  619. * there is no need for more, else make free block after end
  620. * of newly allocated one */
  621. hdesc->useblk++;
  622. hdesc->unuseblk--;
  623. hdesc->usetot += size;
  624. hdesc->unusetot -= size;
  625. if (trailsize) {
  626. trail = blk + size;
  627. *(int *)((hdesc->buffer)+trail) = (int)trailsize;
  628. hdesc->useblk++;    /* This will keep blockcount */
  629. hdesc->unuseblk--;
  630. hdesc->usetot += 4; /* But account for more linkage bytes */
  631. hdesc->unusetot -= 4;
  632. }  
  633. /* Clear the block data, makes it easier to debug */
  634. bzero( (void *)(hdesc->buffer+blk+4), size-4);
  635. hdesc->state |= HMODE_DIRTY;
  636. return(blk);
  637. } else {
  638. printf("alloc_block: failed to alloc %d bytes, and hive expansion not implemented yet!n",size);
  639. }
  640. return(0);
  641. }
  642. #define FB_DEBUG 1
  643. int CHiddenReg::free_block(struct hive *hdesc, int blk)
  644. {
  645. int pofs,vofs,seglen,prev,next,nextsz,prevsz,size;
  646. struct hbin_page *p;
  647. if (hdesc->state & HMODE_NOALLOC) {
  648. printf("free_block: ERROR: Hive %s is in no allocation safe mode,"
  649. "space not freed. Operation will fail!n", hdesc->filename);
  650. return(0);
  651. }
  652. size = get_int(hdesc->buffer+blk);
  653. if (size >= 0) {
  654. printf("free_block: trying to free already free block!n");
  655. #ifdef DOCORE
  656. printf("blk = %xn",blk);
  657. debugit(hdesc->buffer,hdesc->size);
  658. abort();
  659. #endif
  660. return(0);
  661. }
  662. size = -size;
  663. /* So, we must find start of the block BEFORE us */
  664. pofs = find_page_start(hdesc,blk);
  665. if (!pofs) return(0);
  666. p = (struct hbin_page *)(hdesc->buffer + pofs);
  667. vofs = pofs + 0x20;
  668. prevsz = -32;
  669. if (vofs != blk) {  /* Block is not at start of page? */
  670. while (vofs-pofs < (p->ofs_next - HBIN_ENDFILL) ) {
  671. seglen = get_int(hdesc->buffer+vofs);  
  672. if (seglen == 0) {
  673. printf("free_block: EEEK! Zero data block size! (not registry or corrupt file?)n");
  674. debugit(hdesc->buffer,hdesc->size);
  675. return(0);
  676. }
  677. if (seglen < 0) {
  678. seglen = -seglen;
  679. /*      hexdump(hdesc->buffer,vofs,vofs+seglen+4,1); */
  680. prev = vofs;
  681. vofs += seglen;
  682. if (vofs == blk) break;
  683. }
  684. if (vofs != blk) {
  685. printf("free_block: ran off end of page!?!? Error in chains?n");
  686. #ifdef DOCORE
  687. printf("vofs = %x, pofs = %x, blk = %xn",vofs,pofs,blk);
  688. debugit(hdesc->buffer,hdesc->size);
  689. abort();
  690. #endif
  691. return(0);
  692. }
  693. prevsz = get_int(hdesc->buffer+prev);
  694. }
  695. /* We also need details on next block (unless at end of page) */
  696. next = blk + size;
  697. nextsz = 0;
  698. if (next-pofs < (p->ofs_next - HBIN_ENDFILL) ) nextsz = get_int(hdesc->buffer+next);
  699. #if 0
  700. printf("offset prev : %x , blk: %x , next: %xn",prev,blk,next);
  701. printf("size   prev : %x , blk: %x , next: %xn",prevsz,size,nextsz);
  702. #endif
  703. /* Now check if next block is free, if so merge it with the one to be freed */
  704. if ( nextsz > 0) {
  705. #if 0
  706. printf("Swallow nextn");
  707. #endif
  708. size += nextsz;   /* Swallow it in current block */
  709. hdesc->useblk--;
  710. hdesc->usetot -= 4;
  711. hdesc->unusetot -= 4;
  712. }
  713. /* Now free the block (possibly with ajusted size as above) */
  714. bzero( (void *)(hdesc->buffer+blk), size);
  715. *(int *)((hdesc->buffer)+blk) = (int)size;
  716. hdesc->usetot -= size;
  717. hdesc->unusetot -= size;
  718. hdesc->unuseblk--;
  719. hdesc->state |= HMODE_DIRTY;
  720. /* Check if previous block is also free, if so, merge.. */
  721. if (prevsz > 0) {
  722. #if 0
  723. printf("Swallow prevn");
  724. #endif
  725. hdesc->usetot -= prevsz;
  726. hdesc->unusetot += prevsz;
  727. prevsz += size;
  728. /* And swallow current.. */
  729. bzero( (void *)(hdesc->buffer+prev), prevsz);
  730. *(int *)((hdesc->buffer)+prev) = (int)prevsz;
  731. hdesc->useblk--;
  732. return(prevsz);
  733. }
  734. return(size);
  735. }
  736. int CHiddenReg::ex_next_n(struct hive *hdesc, int nkofs, int *count, int *countri, struct ex_data *sptr)
  737. {
  738. struct nk_key *key, *newnkkey;
  739. int newnkofs;
  740. struct lf_key *lfkey;
  741. struct li_key *likey;
  742. struct ri_key *rikey;
  743. if (!nkofs) return(-1);
  744. key = (struct nk_key *)(hdesc->buffer + nkofs);
  745. if (key->id != 0x6b6e) {
  746. printf("ex_next error: Not a 'nk' node at 0x%0xn",nkofs);
  747. return(-1);
  748. }
  749. #define EXNDEBUG 0
  750. lfkey = (struct lf_key *)(hdesc->buffer + key->ofs_lf + 0x1004);
  751. rikey = (struct ri_key *)(hdesc->buffer + key->ofs_lf + 0x1004);
  752. if (rikey->id == 0x6972) {   /* Is it extended 'ri'-block? */
  753. #if EXNDEBUG
  754. printf("%d , %dn",*countri,*count);
  755. #endif
  756. if (*countri < 0 || *countri >= rikey->no_lis) { /* End of ri's? */
  757. return(0);
  758. }
  759. /* Get the li of lf-struct that's current based on countri */
  760. likey = (struct li_key *)( hdesc->buffer + rikey->hash[*countri].ofs_li + 0x1004 ) ;
  761. if (likey->id == 0x696c) {
  762. newnkofs = likey->hash[*count].ofs_nk + 0x1000;
  763. } else {
  764. lfkey = (struct lf_key *)( hdesc->buffer + rikey->hash[*countri].ofs_li + 0x1004 ) ;
  765. newnkofs = lfkey->hash[*count].ofs_nk + 0x1000;
  766. }
  767. /* Check if current li/lf is exhausted */
  768. #if EXNDEBUG
  769. printf("likey->no_keys = %dn",likey->no_keys);
  770. #endif
  771. if (*count >= likey->no_keys-1) { /* Last legal entry in li list? */
  772. (*countri)++;  /* Bump up ri count so we take next ri entry next time */
  773. (*count) = -1;  /* Reset li traverse counter for next round, not used later here */
  774. }
  775. } else { /* Plain handler */
  776. if (key->no_subkeys <= 0 || *count >= key->no_subkeys) {
  777. return(0);
  778. }
  779. if (lfkey->id == 0x696c) {   /* Is it 3.x 'li' instead? */
  780. likey = (struct li_key *)(hdesc->buffer + key->ofs_lf + 0x1004);
  781. newnkofs = likey->hash[*count].ofs_nk + 0x1000;
  782. } else {
  783. newnkofs = lfkey->hash[*count].ofs_nk + 0x1000;
  784. }
  785. }
  786. sptr->nkoffs = newnkofs;
  787. newnkkey = (struct nk_key *)(hdesc->buffer + newnkofs + 4);
  788. sptr->nk = newnkkey;
  789. if (newnkkey->id != 0x6b6e) {
  790. printf("ex_next: ERROR: not 'nk' node at 0x%0xn",newnkofs);
  791. return(-1);
  792. } else {
  793. if (newnkkey->len_name <= 0) {
  794. printf("ex_next: nk at 0x%0x has no name!n",newnkofs);
  795. } else {
  796. sptr->name = (char *)malloc(newnkkey->len_name+1);
  797. if (!sptr->name) {
  798. printf("FATAL! ex_next: malloc() failed! Out of memory?n");
  799. abort();
  800. }
  801. strncpy(sptr->name,newnkkey->keyname,newnkkey->len_name);
  802. sptr->name[newnkkey->len_name] = 0;
  803. }
  804. } /* if */
  805. (*count)++;
  806. return(1);
  807. /*  return( *count <= key->no_subkeys); */
  808. }
  809. int CHiddenReg::ex_next_v(struct hive *hdesc, int nkofs, int *count, struct vex_data *sptr)
  810. {
  811. struct nk_key *key /* , *newnkkey */ ;
  812. int vkofs,vlistofs;
  813. int *vlistkey;
  814. struct vk_key *vkkey;
  815. if (!nkofs) return(-1);
  816. key = (struct nk_key *)(hdesc->buffer + nkofs);
  817. if (key->id != 0x6b6e) {
  818. printf("ex_next_v error: Not a 'nk' node at 0x%0xn",nkofs);
  819. return(-1);
  820. }
  821. if (key->no_values <= 0 || *count >= key->no_values) {
  822. return(0);
  823. }
  824. vlistofs = key->ofs_vallist + 0x1004;
  825. vlistkey = (int *)(hdesc->buffer + vlistofs);
  826. vkofs = vlistkey[*count] + 0x1004;
  827. vkkey = (struct vk_key *)(hdesc->buffer + vkofs);
  828. if (vkkey->id != 0x6b76) {
  829. printf("ex_next_v: hit non valuekey (vk) node during scan at offs 0x%0xn",vkofs);
  830. return(-1);
  831. }
  832. /*  parse_vk(hdesc, vkofs, 4); */
  833. sptr->vk = vkkey;
  834. sptr->vkoffs = vkofs;
  835. sptr->name = 0;
  836. sptr->size = (vkkey->len_data & 0x7fffffff);
  837. if (vkkey->len_name >0) {
  838. CREATE(sptr->name,char,vkkey->len_name+1);
  839. memcpy(sptr->name,vkkey->keyname,vkkey->len_name);
  840. sptr->name[vkkey->len_name] = 0;
  841. } else {
  842. sptr->name = str_dup("@");
  843. }
  844. sptr->type = vkkey->val_type;
  845. if (sptr->size) {
  846. if (vkkey->val_type == REG_DWORD) {
  847. if (vkkey->len_data & 0x80000000) {
  848. sptr->val = (int)(vkkey->ofs_data);
  849. }
  850. }
  851. } else if (vkkey->len_data == 0x80000000) { 
  852. /* Data SIZE is 0, high bit set: special inline case, data is DWORD and in TYPE field!! */
  853. /* Used a lot in SAM, and maybe in SECURITY I think */
  854. sptr->val = (int)(vkkey->val_type);
  855. sptr->size = 4;
  856. sptr->type = REG_DWORD;
  857. } else {
  858. sptr->val = 0;
  859. sptr->size = 0;
  860. }
  861. (*count)++;
  862. return( *count <= key->no_values );
  863. }
  864. int CHiddenReg::get_abs_path(struct hive *hdesc, int nkofs, char *path, int maxlen)
  865. {
  866. /* int newnkofs; */
  867. struct nk_key *key;
  868. char tmp[ABSPATHLEN+1];
  869. maxlen = (maxlen < ABSPATHLEN ? maxlen : ABSPATHLEN);
  870. key = (struct nk_key *)(hdesc->buffer + nkofs);
  871. if (key->id != 0x6b6e) {
  872. printf("get_abs_path: Not a 'nk' node!n");
  873. return(0);
  874. }
  875. if (key->type == KEY_ROOT) {   /* We're at the root */
  876. return(strlen(path));
  877. }
  878. strncpy(tmp,path,ABSPATHLEN-1);
  879. if ( (strlen(path) + key->len_name) >= maxlen-6) {
  880. _snprintf(path,maxlen,"(...)%s",tmp);
  881. return(strlen(path));   /* Stop trace when string exhausted */
  882. }
  883. *path = '\';
  884. memcpy(path+1,key->keyname,key->len_name);
  885. strncpy(path+key->len_name+1,tmp,maxlen);
  886. return(get_abs_path(hdesc, key->ofs_parent+0x1004, path, maxlen)); /* go back one more */
  887. }
  888. int CHiddenReg::vlist_find(struct hive *hdesc, int vlistofs, int numval, char *name)
  889. {
  890. struct vk_key *vkkey;
  891. int i,vkofs;
  892. long *vlistkey;
  893. vlistkey = (long *)(hdesc->buffer + vlistofs);
  894. for (i = 0; i < numval; i++) {
  895. vkofs = vlistkey[i] + 0x1004;
  896. vkkey = (struct vk_key *)(hdesc->buffer + vkofs);
  897. if (vkkey->len_name == 0 && *name == '@') { /* @ is alias for nameless value */
  898. return(i);
  899. }
  900. if (!strncmp(name, vkkey->keyname, strlen(name))) { /* name match? */
  901. return(i);
  902. }
  903. }
  904. return(-1);
  905. }
  906. int CHiddenReg::trav_path(struct hive *hdesc, int vofs, char *path, int type)
  907. {
  908. struct nk_key *key, *newnkkey;
  909. struct lf_key *lfkey;
  910. struct li_key *likey;
  911. struct ri_key *rikey;
  912. long *vlistkey;
  913. int newnkofs, plen, i, lfofs, vlistofs, adjust, r, ricnt, subs;
  914. char *buf;
  915. char part[ABSPATHLEN+1];
  916. char *partptr;
  917. if (!hdesc) return(0);
  918. buf = hdesc->buffer;
  919. if (*path == '\' && *(path+1) != '\') {      /* Start from root if path starts with  */
  920. path++;
  921. vofs = hdesc->rootofs+4;
  922. }
  923. key = (struct nk_key *)(buf + vofs);
  924. /*  printf("check of nk at offset: 0x%0xn",vofs); */
  925. if (key->id != 0x6b6e) {
  926. printf("trav_path: Error: Not a 'nk' node!n");
  927. return(0);
  928. }
  929. /* Find  delimiter or end of string, copying to name part buffer as we go,
  930. rewriting double \s */
  931. partptr = part;
  932. for(plen = 0; path[plen] && (path[plen] != '\' || path[plen+1] == '\'); plen++) {
  933. if (path[plen] == '\' && path[plen+1] == '\') plen++; /* Skip one if double */
  934. *partptr++ = path[plen];
  935. }
  936. *partptr = '';
  937. /*  printf("Name component: <%s>n",part); */
  938. adjust = (path[plen] == '\' ) ? 1 : 0;
  939. /*  printf("Checking for <%s> with len %dn",path,plen); */
  940. if (!plen) return(vofs-4);     /* Path has no lenght - we're there! */
  941. if ( (plen == 1) && (*path == '.')) {     /* Handle '.' current dir */
  942. return(trav_path(hdesc,vofs,path+plen+adjust,type));
  943. }
  944. if ( (plen == 2) && !strncmp("..",path,2) ) { /* Get parent key */
  945. newnkofs = key->ofs_parent + 0x1004;
  946. /* Return parent (or only root if at the root) */
  947. return(trav_path(hdesc, (key->type == KEY_ROOT ? vofs : newnkofs), path+plen+adjust, type));
  948. }
  949. /* at last name of path, and we want vk, and the nk has values */
  950. if (!path[plen] && type == 1 && key->no_values) {   
  951. /*    printf("VK namematch for <%s>n",part); */
  952. vlistofs = key->ofs_vallist + 0x1004;
  953. vlistkey = (long *)(buf + vlistofs);
  954. i = vlist_find(hdesc, vlistofs, key->no_values, part);
  955. if (i != -1) {
  956. return(vlistkey[i] + 0x1000);
  957. }
  958. }
  959. if (key->no_subkeys > 0) {    /* If it has subkeys, loop through the hash */
  960. lfofs = key->ofs_lf + 0x1004;    /* lf (hash) record */
  961. lfkey = (struct lf_key *)(buf + lfofs);
  962. if (lfkey->id == 0x6972) { /* ri struct need special parsing */
  963. /* Prime loop state */
  964. rikey = (struct ri_key *)lfkey;
  965. ricnt = rikey->no_lis;
  966. r = 0;
  967. likey = (struct li_key *)( hdesc->buffer + rikey->hash[r].ofs_li + 0x1004 ) ;
  968. subs = likey->no_keys;
  969. if (likey->id != 0x696c) {  /* Bwah, not li anyway, XP uses lh usually which is actually smarter */
  970. lfkey = (struct lf_key *)( hdesc->buffer + rikey->hash[r].ofs_li + 0x1004 ) ;
  971. likey = NULL;
  972. }
  973. } else {
  974. if (lfkey->id == 0x696c) { /* li? */
  975. likey = (struct li_key *)(buf + lfofs);
  976. } else {
  977. likey = NULL;
  978. }
  979. ricnt = 0; r = 0; subs = key->no_subkeys;
  980. }
  981. do {
  982. for(i = 0; i < subs; i++) {
  983. if (likey) newnkofs = likey->hash[i].ofs_nk + 0x1004;
  984. else newnkofs = lfkey->hash[i].ofs_nk + 0x1004;
  985. newnkkey = (struct nk_key *)(buf + newnkofs);
  986. if (newnkkey->id != 0x6b6e) {
  987. printf("ERROR: not 'nk' node! (strange?)n");
  988. } else {
  989. if (newnkkey->len_name <= 0) {
  990. printf("[No name]n");
  991. } else {
  992. if (!strncmp(part,newnkkey->keyname,plen)) {
  993. /*     printf("Key at 0x%0x matches! recursing!n",newnkofs); */
  994. return(trav_path(hdesc, newnkofs, path+plen+adjust, type));
  995. }
  996. }
  997. } /* if id OK */
  998. } /* hash loop */
  999. r++;
  1000. if (ricnt && r < ricnt) {
  1001. newnkofs = rikey->hash[r].ofs_li;
  1002. likey = (struct li_key *)( hdesc->buffer + newnkofs + 0x1004 ) ;
  1003. subs = likey->no_keys;
  1004. if (likey->id != 0x696c) {  /* Bwah, not li anyway, XP uses lh usually which is actually smarter */
  1005. lfkey = (struct lf_key *)( hdesc->buffer + rikey->hash[r].ofs_li + 0x1004 ) ;
  1006. likey = NULL;
  1007. }
  1008. }
  1009. } while (r < ricnt && ricnt);
  1010. } /* if subkeys */
  1011. /* Not found */
  1012. return(0);
  1013. }
  1014. void CHiddenReg::nk_ls(struct hive *hdesc, char *path, int vofs, int type)
  1015. {
  1016. struct nk_key *key;
  1017. int nkofs;
  1018. struct ex_data ex;
  1019. struct vex_data vex;
  1020. int count = 0, countri = 0;
  1021. nkofs = trav_path(hdesc, vofs, path, 0);
  1022. if(!nkofs) {
  1023. printf("nk_ls: Key <%s> not foundn",path);
  1024. return;
  1025. }
  1026. nkofs += 4;
  1027. key = (struct nk_key *)(hdesc->buffer + nkofs);
  1028. printf("ls of node at offset 0x%0xn",nkofs);
  1029. if (key->id != 0x6b6e) {
  1030. printf("Error: Not a 'nk' node!n");
  1031. debugit(hdesc->buffer,hdesc->size);
  1032. }
  1033. printf("Node has %ld subkeys and %ld values",key->no_subkeys,key->no_values);
  1034. if (key->len_classnam) printf(", and class-data of %d bytes",key->len_classnam);
  1035. printf("n");
  1036. if (key->no_subkeys) {
  1037. printf("offs          key namen");
  1038. while ((ex_next_n(hdesc, nkofs, &count, &countri, &ex) > 0)) {
  1039. printf("[%6x]   %c  <%s>n", ex.nkoffs, (ex.nk->len_classnam)?'*':' ',ex.name);
  1040. FREE(ex.name);
  1041. }
  1042. }
  1043. count = 0;
  1044. if (key->no_values) {
  1045. printf("offs        size      type   value name                    [value if type DWORD]n");
  1046. while ((ex_next_v(hdesc, nkofs, &count, &vex) > 0)) {
  1047. printf("[%6x] %6d  %-16s  <%s>", vex.vkoffs, vex.size,
  1048. (vex.type < REG_MAX ? val_types[vex.type] : "(unknown)"), vex.name);
  1049. if (vex.type == REG_DWORD) printf(" %*d [0x%x]",25-strlen(vex.name),vex.val , vex.val);
  1050. printf("n");
  1051. FREE(vex.name);
  1052. }
  1053. }
  1054. }
  1055. int CHiddenReg::get_val_type(struct hive *hdesc, int vofs, char *path)
  1056. {
  1057. struct vk_key *vkkey;
  1058. int vkofs;
  1059. vkofs = trav_path(hdesc, vofs,path,1);
  1060. if (!vkofs) {
  1061. return -1;
  1062. }
  1063. vkofs +=4;
  1064. vkkey = (struct vk_key *)(hdesc->buffer + vkofs);
  1065. #if 0
  1066. if (vkkey->len_data & 0x80000000) return(REG_DWORD); /* Special case of INLINE storage */
  1067. #endif
  1068. return(vkkey->val_type);
  1069. }
  1070. int CHiddenReg::get_val_len(struct hive *hdesc, int vofs, char *path)
  1071. {
  1072. struct vk_key *vkkey;
  1073. int vkofs;
  1074. int len;
  1075. vkofs = trav_path(hdesc, vofs,path,1);
  1076. if (!vkofs) {
  1077. return -1;
  1078. }
  1079. vkofs +=4;
  1080. vkkey = (struct vk_key *)(hdesc->buffer + vkofs);
  1081. len = vkkey->len_data & 0x7fffffff;
  1082. if ( vkkey->len_data == 0x80000000 ) {  /* Special inline case, return size of 4 (dword) */
  1083. len = 4;
  1084. }
  1085. return(len);
  1086. }
  1087. void *CHiddenReg::get_val_data(struct hive *hdesc, int vofs, char *path, int val_type)
  1088. {
  1089. struct vk_key *vkkey;
  1090. int vkofs;
  1091. vkofs = trav_path(hdesc,vofs,path,1);
  1092. if (!vkofs) {
  1093. return NULL;
  1094. }
  1095. vkofs +=4;
  1096. vkkey = (struct vk_key *)(hdesc->buffer + vkofs);
  1097. if (vkkey->len_data == 0) return NULL;
  1098. if (vkkey->len_data == 0x80000000) {  /* Special inline case (len = 0x80000000) */
  1099. return(&vkkey->val_type); /* Data (4 bytes?) in type field */
  1100. }    
  1101. if (val_type && vkkey->val_type && (vkkey->val_type) != val_type) {
  1102. printf("Value <%s> is not of correct type!n",path);
  1103. return NULL;
  1104. }
  1105. /* Negative len is inline, return ptr to offset-field which in
  1106. * this case contains the data itself
  1107. */
  1108. if (vkkey->len_data & 0x80000000) return(&vkkey->ofs_data);
  1109. /* Normal return, return data pointer */
  1110. return(hdesc->buffer + vkkey->ofs_data + 0x1004);
  1111. }
  1112. struct keyval *CHiddenReg::get_val2buf(struct hive *hdesc, struct keyval *kv,
  1113.    int vofs, char *path, int type )
  1114. {
  1115. int l;
  1116. struct keyval *kr;
  1117. void *keydataptr;
  1118. l = get_val_len(hdesc, vofs, path);
  1119. if (l == -1) return(NULL);  /* error */
  1120. if (kv && (kv->len < l)) return(NULL); /* Check for overflow of supplied buffer */
  1121. keydataptr = get_val_data(hdesc, vofs, path, type);
  1122. /*  if (!keydataptr) return(NULL); error */
  1123. /* Allocate space for data + header, or use supplied buffer */
  1124. if (kv) {
  1125. kr = kv;
  1126. } else {
  1127. //    ALLOC(kr,1,l+sizeof(int)+4);                          修改过
  1128. kr = (keyval *)malloc(1+sizeof(int)+4);
  1129. memset(kr, 0, (1+sizeof(int)+4));
  1130. }
  1131. kr->len = l;
  1132. memcpy(&(kr->data), keydataptr, l);
  1133. return(kr);
  1134. }
  1135. int CHiddenReg::get_dword(struct hive *hdesc, int vofs, char *path)
  1136. {
  1137. struct keyval *v;
  1138. int dword;
  1139. v = get_val2buf(hdesc, NULL, vofs, path, REG_DWORD);
  1140. if (!v) return(-1); /* well... -1 COULD BE THE STORED VALUE TOO */
  1141. dword = (int)v->data;
  1142. FREE(v);
  1143. return(dword);
  1144. }
  1145. int CHiddenReg::fill_block(struct hive *hdesc, int ofs, void *data, int size)
  1146. {
  1147. int blksize;
  1148. blksize = get_int(hdesc->buffer + ofs);
  1149. blksize = -blksize;
  1150. #if 0
  1151. printf("fill_block: ofs = %x - %x, size = %x, blksize = %xn",ofs,ofs+size,size,blksize);
  1152. #endif
  1153. /*  if (blksize < size || ( (ofs & 0xfffff000) != ((ofs+size) & 0xfffff000) )) { */
  1154. if (blksize < size) {
  1155. printf("fill_block: ERROR: block to small for data: ofs = %x, size = %x, blksize = %xn",ofs,size,blksize);
  1156. debugit(hdesc->buffer,hdesc->size);
  1157. abort();
  1158. }
  1159. memcpy(hdesc->buffer + ofs + 4, data, size);
  1160. return(0);
  1161. }
  1162. int CHiddenReg::free_val_data(struct hive *hdesc, int vofs, char *path)
  1163. {
  1164. struct vk_key *vkkey;
  1165. int vkofs, inl;
  1166. vkofs = trav_path(hdesc,vofs,path,1);
  1167. if (!vkofs) {
  1168. return 0;
  1169. }
  1170. vkofs +=4;
  1171. vkkey = (struct vk_key *)(hdesc->buffer + vkofs);
  1172. inl = (vkkey->len_data & 0x80000000);
  1173. if (!inl) {
  1174. free_block(hdesc, vkkey->ofs_data + 0x1000);
  1175. }
  1176. vkkey->len_data = 0;
  1177. vkkey->ofs_data = 0;
  1178. return(vkofs);
  1179. }
  1180. int CHiddenReg::alloc_val_data(struct hive *hdesc, int vofs, char *path, int size)
  1181. {
  1182. struct vk_key *vkkey;
  1183. int vkofs, len;
  1184. int datablk;
  1185. vkofs = trav_path(hdesc,vofs,path,1);
  1186. if (!vkofs) {
  1187. return (0);
  1188. }
  1189. vkofs +=4;
  1190. vkkey = (struct vk_key *)(hdesc->buffer + vkofs);
  1191. /* Allocate space for new data */
  1192. datablk = alloc_block(hdesc, vkofs, size);
  1193. if (!datablk) return(0);
  1194. len = vkkey->len_data & 0x7fffffff;
  1195. /* Then we dealloc if something was there before */
  1196. if (len) free_val_data(hdesc,vofs,path);
  1197. /* Link in new datablock */
  1198. vkkey->ofs_data = datablk - 0x1000;
  1199. vkkey->len_data = size;
  1200. return(datablk + 4);
  1201. }
  1202. struct vk_key *CHiddenReg::add_value(struct hive *hdesc, int nkofs, char *name, int type)
  1203. {
  1204. struct nk_key *nk;
  1205. int oldvlist = 0, newvlist, newvkofs;
  1206. struct vk_key *newvkkey;
  1207. char *blank="";
  1208. if (!name || !*name) return(NULL);
  1209. nk = (struct nk_key *)(hdesc->buffer + nkofs);
  1210. if (nk->id != 0x6b6e) {
  1211. printf("add_value: Key pointer not to 'nk' node!n");
  1212. return(NULL);
  1213. }
  1214. if (trav_path(hdesc, nkofs, name, 1)) {
  1215. printf("add_value: value %s already existsn",name);
  1216. return(NULL);
  1217. }
  1218. if (!strcmp(name,"@")) name = blank;
  1219. if (nk->no_values) oldvlist = nk->ofs_vallist;
  1220. newvlist = alloc_block(hdesc, nkofs, nk->no_values * 4 + 4);
  1221. if (!newvlist) {
  1222. printf("add_value: failed to allocate new value list!n");
  1223. return(NULL);
  1224. }
  1225. if (oldvlist) {   /* Copy old data if any */
  1226. memcpy(hdesc->buffer + newvlist + 4, hdesc->buffer + oldvlist + 0x1004, nk->no_values * 4 + 4);
  1227. }
  1228. /* Allocate value descriptor including its name */
  1229. newvkofs = alloc_block(hdesc, newvlist, sizeof(struct vk_key) + strlen(name));
  1230. if (!newvkofs) {
  1231. printf("add_value: failed to allocate value descriptorn");
  1232. free_block(hdesc, newvlist);
  1233. return(NULL);
  1234. }
  1235. /* Success, now fill in the metadata */
  1236. newvkkey = (struct vk_key *)(hdesc->buffer + newvkofs + 4);
  1237. /* Add pointer in value list */
  1238. *(int *)(hdesc->buffer + newvlist + 4 + (nk->no_values * 4)) = newvkofs - 0x1000;
  1239. /* Fill in vk struct */
  1240. newvkkey->id = 0x6b76;
  1241. newvkkey->len_name = strlen(name);
  1242. if (type == REG_DWORD || type == REG_DWORD_BIG_ENDIAN) {
  1243. newvkkey->len_data = 0x80000004;  /* Prime the DWORD inline stuff */
  1244. } else {
  1245. newvkkey->len_data = 0x00000000;
  1246. }
  1247. newvkkey->ofs_data = 0;
  1248. newvkkey->val_type = type;
  1249. newvkkey->flag     = 1;   /* Don't really know what this is */
  1250. newvkkey->dummy1   = 0;
  1251. strcpy((char *)&newvkkey->keyname, name);  /* And copy name */
  1252. /* Finally update the key and free the old valuelist */
  1253. nk->no_values++;
  1254. nk->ofs_vallist = newvlist - 0x1000;
  1255. if (oldvlist) free_block(hdesc,oldvlist + 0x1000);
  1256. return(newvkkey);
  1257. }
  1258. void CHiddenReg::del_vk(struct hive *hdesc, int vkofs)
  1259. {
  1260. struct vk_key *vk;
  1261. vk = (struct vk_key *)(hdesc->buffer + vkofs);
  1262. if (vk->id != 0x6b76) {
  1263. printf("del_vk: Key pointer not to 'vk' node!n");
  1264. return;
  1265. }
  1266. if ( !(vk->len_data & 0x80000000) && vk->ofs_data)
  1267. {
  1268. free_block(hdesc, vk->ofs_data + 0x1000);
  1269. }
  1270. free_block(hdesc, vkofs - 4);
  1271. }
  1272. void CHiddenReg::del_allvalues(struct hive *hdesc, int nkofs)
  1273. {
  1274. int vlistofs, o, vkofs;
  1275. long *vlistkey;
  1276. struct nk_key *nk;
  1277. nk = (struct nk_key *)(hdesc->buffer + nkofs);
  1278. if (nk->id != 0x6b6e) {
  1279. printf("del_allvalues: Key pointer not to 'nk' node!n");
  1280. return;
  1281. }
  1282. if (!nk->no_values) {
  1283. /*    printf("del_avalues: Key has no values!n"); */
  1284. return;
  1285. }
  1286. vlistofs = nk->ofs_vallist + 0x1004;
  1287. vlistkey = (long *)(hdesc->buffer + vlistofs);
  1288. /* Loop through index and delete all vk's */
  1289. for (o = 0; o < nk->no_values; o++) {
  1290. vkofs = vlistkey[o] + 0x1004;
  1291. del_vk(hdesc, vkofs);
  1292. }
  1293. /* Then zap the index, and update nk */
  1294. free_block(hdesc, vlistofs-4);
  1295. nk->ofs_vallist = -1;
  1296. nk->no_values = 0;
  1297. }
  1298. int CHiddenReg::del_value(struct hive *hdesc, int nkofs, char *name)
  1299. {
  1300. int vlistofs, slot, o, n, vkofs, newlistofs;
  1301. long *vlistkey, *tmplist, *newlistkey;
  1302. struct nk_key *nk;
  1303. char *blank="";
  1304. if (!name || !*name) return(1);
  1305. if (!strcmp(name,"@")) name = blank;
  1306. nk = (struct nk_key *)(hdesc->buffer + nkofs);
  1307. if (nk->id != 0x6b6e) {
  1308. printf("del_value: Key pointer not to 'nk' node!n");
  1309. return(1);
  1310. }
  1311. if (!nk->no_values) {
  1312. printf("del_value: Key has no values!n");
  1313. return(1);
  1314. }
  1315. vlistofs = nk->ofs_vallist + 0x1004;
  1316. vlistkey = (long *)(hdesc->buffer + vlistofs);
  1317. slot = vlist_find(hdesc, vlistofs, nk->no_values, name);
  1318. if (slot == -1) {
  1319. printf("del_value: value %s not found!n",name);
  1320. return(1);
  1321. }
  1322. /* Delete vk and data */
  1323. vkofs = vlistkey[slot] + 0x1004;
  1324. del_vk(hdesc, vkofs);
  1325. /* Copy out old index list */
  1326. CREATE(tmplist,long,nk->no_values);
  1327. memcpy(tmplist, vlistkey, nk->no_values * sizeof(long));
  1328. free_block(hdesc,vlistofs-4);  /* Get rid of old list */
  1329. nk->no_values--;
  1330. if (nk->no_values) {
  1331. newlistofs = alloc_block(hdesc, vlistofs, nk->no_values * sizeof(long));
  1332. if (!newlistofs) {
  1333. printf("del_value: FATAL: Was not able to alloc new index listn");
  1334. abort();
  1335. }
  1336. /* Now copy over, omitting deleted entry */
  1337. newlistkey = (long *)(hdesc->buffer + newlistofs + 4);
  1338. for (n = 0, o = 0; o < nk->no_values+1; o++, n++) {
  1339. if (o == slot) o++;
  1340. newlistkey[n] = tmplist[o];
  1341. }
  1342. nk->ofs_vallist = newlistofs - 0x1000;
  1343. } else {
  1344. nk->ofs_vallist = -1;
  1345. }
  1346. return(0);
  1347. }
  1348. #undef AKDEBUG
  1349. struct nk_key *CHiddenReg::add_key(struct hive *hdesc, int nkofs, char *name)
  1350. {
  1351. int slot, newlfofs = 0, oldlfofs = 0, newliofs = 0;
  1352. int oldliofs = 0;
  1353. int o, n, i, onkofs, newnkofs, cmp;
  1354. int rimax, rislot, riofs, namlen;
  1355. struct ri_key *ri = NULL;
  1356. struct lf_key *newlf = NULL, *oldlf;
  1357. struct li_key *newli = NULL, *oldli;
  1358. struct nk_key *key, *newnk, *onk;
  1359. long hash;
  1360. key = (struct nk_key *)(hdesc->buffer + nkofs);
  1361. if (key->id != 0x6b6e) {
  1362. printf("add_key: current ptr not 'nk'n");
  1363. return(NULL);
  1364. }
  1365. namlen = strlen(name);
  1366. slot = -1;
  1367. if (key->no_subkeys) {   /* It already has subkeys */    
  1368. oldlfofs = key->ofs_lf;
  1369. oldliofs = key->ofs_lf;   
  1370. oldlf = (struct lf_key *)(hdesc->buffer + oldlfofs + 0x1004);
  1371. if (oldlf->id != 0x666c && oldlf->id != 0x686c && oldlf->id != 0x696c && oldlf->id != 0x6972)  {
  1372. printf("add_key: index type not supported: 0x%04xn",oldlf->id);
  1373. return(NULL);
  1374. }
  1375. rimax = 0; ri = NULL; riofs = 0; rislot = -1;
  1376. if (oldlf->id == 0x6972) {  /* Indirect index 'ri', init loop */
  1377. riofs = key->ofs_lf;
  1378. ri = (struct ri_key *)(hdesc->buffer + riofs + 0x1004);
  1379. rimax = ri->no_lis-1;
  1380. #ifdef AKDEBUG
  1381. printf("add_key: entering 'ri' traverse, rimax = %dn",rimax);
  1382. #endif
  1383. oldliofs = ri->hash[rislot+1].ofs_li;
  1384. oldlfofs = ri->hash[rislot+1].ofs_li;
  1385. }
  1386. do {   /* 'ri' loop, at least run once if no 'ri' deep index */
  1387. if (ri) { /* Do next 'ri' slot */
  1388. rislot++;
  1389. oldliofs = ri->hash[rislot].ofs_li;
  1390. oldlfofs = ri->hash[rislot].ofs_li;
  1391. oldli = (struct li_key *)(hdesc->buffer + oldliofs + 0x1004);
  1392. oldlf = (struct lf_key *)(hdesc->buffer + oldlfofs + 0x1004);
  1393. }
  1394. oldli = (struct li_key *)(hdesc->buffer + oldliofs + 0x1004);
  1395. oldlf = (struct lf_key *)(hdesc->buffer + oldlfofs + 0x1004);
  1396. #ifdef AKDEBUG
  1397. printf("add_key: top of ri-loop: rislot = %dn",rislot);
  1398. #endif
  1399. slot = -1;
  1400. if (oldli->id == 0x696c) {  /* li */
  1401. #ifdef AKDEBUG
  1402. printf("add_key: li slot allocaten");
  1403. #endif
  1404. FREE(newli);
  1405. // ALLOC(newli, 8 + 4*oldli->no_keys + 4, 1);          修改过
  1406. newli = (li_key *)malloc(8+4*oldli->no_keys+4);
  1407. memset(newli, 0, (88+4*oldli->no_keys+4));
  1408. newli->no_keys = oldli->no_keys;
  1409. newli->id = oldli->id;
  1410. /* Now copy old, checking where to insert (alphabetically) */
  1411. for (o = 0, n = 0; o < oldli->no_keys; o++,n++) {
  1412. onkofs = oldli->hash[o].ofs_nk;
  1413. onk = (struct nk_key *)(onkofs + hdesc->buffer + 0x1004);
  1414. if (slot == -1) {
  1415. #if 0
  1416. printf("add_key: cmp <%s> with <%s>n",name,onk->keyname);
  1417. #endif
  1418. cmp = strncasecmp(name, onk->keyname, (namlen > onk->len_name) ? namlen : onk->len_name);
  1419. if (!cmp) {
  1420. printf("add_key: key %s already exists!n",name);
  1421. FREE(newli);
  1422. return(NULL);
  1423. }
  1424. if ( cmp < 0) {
  1425. slot = o;
  1426. rimax = rislot; /* Cause end of 'ri' search, too */
  1427. n++;
  1428. #ifdef AKDEBUG
  1429. printf("add_key: li-match: slot = %dn",o);
  1430. #endif
  1431. }
  1432. }
  1433. newli->hash[n].ofs_nk = oldli->hash[o].ofs_nk;
  1434. }
  1435. if (slot == -1) slot = oldli->no_keys;
  1436. } else { /* lf or lh */
  1437. oldlf = (struct lf_key *)(hdesc->buffer + oldlfofs + 0x1004);
  1438. FREE(newlf);
  1439. // ALLOC(newlf, 8 + 8*oldlf->no_keys + 8, 1);         修改过
  1440. newlf = (lf_key*)malloc(8+8*oldlf->no_keys);
  1441. memset(newlf, 0, (8+8*oldlf->no_keys));
  1442. newlf->no_keys = oldlf->no_keys;
  1443. newlf->id = oldlf->id;
  1444. #ifdef AKDEBUG
  1445. printf("add_key: new lf/lh no_keys: %dn",newlf->no_keys);
  1446. #endif
  1447. /* Now copy old, checking where to insert (alphabetically) */
  1448. for (o = 0, n = 0; o < oldlf->no_keys; o++,n++) {
  1449. onkofs = oldlf->hash[o].ofs_nk;
  1450. onk = (struct nk_key *)(onkofs + hdesc->buffer + 0x1004);
  1451. if (slot == -1) {
  1452. #if 0
  1453. printf("add_key: cmp <%s> with <%s>n",name,onk->keyname);
  1454. #endif
  1455. cmp = strncasecmp(name, onk->keyname, (namlen > onk->len_name) ? namlen : onk->len_name);
  1456. if (!cmp) {
  1457. printf("add_key: key %s already exists!n",name);
  1458. FREE(newlf);
  1459. return(NULL);
  1460. }
  1461. if ( cmp < 0) {
  1462. slot = o;
  1463. rimax = rislot;  /* Cause end of 'ri' search, too */
  1464. n++;
  1465. #ifdef AKDEBUG
  1466. printf("add_key: lf-match: slot = %dn",o);
  1467. #endif
  1468. }
  1469. }
  1470. newlf->hash[n].ofs_nk = oldlf->hash[o].ofs_nk;
  1471. newlf->hash[n].name[0] = oldlf->hash[o].name[0];
  1472. newlf->hash[n].name[1] = oldlf->hash[o].name[1];
  1473. newlf->hash[n].name[2] = oldlf->hash[o].name[2];
  1474. newlf->hash[n].name[3] = oldlf->hash[o].name[3];
  1475. }
  1476. if (slot == -1) slot = oldlf->no_keys;
  1477. } /* li else check */
  1478. } while ( (rislot < rimax) );  /* 'ri' wrapper loop */
  1479.   } else { /* Parent was empty, make new index block */
  1480. #ifdef AKDEBUG
  1481.   printf("add_key: new index!n");
  1482. #endif
  1483.   //    ALLOC(newlf, 8 + 8, 1);                           //修改过
  1484.   newlf = (lf_key *)malloc(16);
  1485.   memset(newlf, 0, 16);
  1486.   newlf->no_keys = 1;
  1487.   /* Use ID (lf, lh or li) we fetched from root node, so we use same as rest of hive */
  1488.   newlf->id = hdesc->nkindextype;
  1489.   slot = 0;
  1490.   } /* if has keys before */
  1491.   /* Make and fill in new nk */
  1492.   newnkofs = alloc_block(hdesc, nkofs, sizeof(struct nk_key) + strlen(name));
  1493.   if (!newnkofs) {
  1494.   printf("add_key: unable to allocate space for new key descriptor for %s!n",name);
  1495.   FREE(newlf);
  1496.   FREE(newli);
  1497.   return(NULL);
  1498.   }
  1499.   newnk = (struct nk_key *)(hdesc->buffer + newnkofs + 4);  
  1500.   newnk->id            = 0x6b6e;
  1501.   newnk->type          = KEY_NORMAL;
  1502.   newnk->ofs_parent    = nkofs - 0x1004;
  1503.   newnk->no_subkeys    = 0;
  1504.   newnk->ofs_lf        = 0;
  1505.   newnk->no_values     = 0;
  1506.   newnk->ofs_vallist   = -1;
  1507.   newnk->ofs_sk        = key->ofs_sk; /* Get parents for now. 0 or -1 here crashes XP */
  1508.   newnk->ofs_classnam  = -1;
  1509.   newnk->len_name      = strlen(name);
  1510.   newnk->len_classnam  = 0;
  1511.   strcpy(newnk->keyname, name); 
  1512.   if (newli) {  /* Handle li */
  1513. #if AKDEBUG
  1514.   printf("add_key: li fill at slot: %dn",slot);
  1515. #endif
  1516.   /* And put its offset into parents index list */
  1517.   newli->hash[slot].ofs_nk = newnkofs - 0x1000;
  1518.   newli->no_keys++;    
  1519.   /* Allocate space for our new li list and copy it into reg */
  1520.   newliofs = alloc_block(hdesc, nkofs, 8 + 4*newli->no_keys);
  1521.   if (!newliofs) {
  1522.   printf("add_key: unable to allocate space for new index table for %s!n",name);
  1523.   FREE(newli);
  1524.   free_block(hdesc,newnkofs);
  1525.   return(NULL);
  1526.   }
  1527.   /*    memcpy(hdesc->buffer + newliofs + 4, newli, 8 + 4*newli->no_keys); */
  1528.   fill_block(hdesc, newliofs, newli, 8 + 4*newli->no_keys);
  1529.   } else {  /* lh or lf */
  1530. #ifdef AKDEBUG
  1531.   printf("add_key: lf/lh fill at slot: %d, rislot: %dn",slot,rislot);
  1532. #endif
  1533.   /* And put its offset into parents index list */
  1534.   newlf->hash[slot].ofs_nk = newnkofs - 0x1000;
  1535.   newlf->no_keys++;
  1536.   if (newlf->id == 0x666c) {        /* lf hash */
  1537.   newlf->hash[slot].name[0] = 0;
  1538.   newlf->hash[slot].name[1] = 0;
  1539.   newlf->hash[slot].name[2] = 0;
  1540.   newlf->hash[slot].name[3] = 0;
  1541.   strncpy(newlf->hash[slot].name, name, 4);
  1542.   } else if (newlf->id == 0x686c) {  /* lh. XP uses this. hashes whole name */
  1543.   for (i = 0,hash = 0; i < strlen(name); i++) {
  1544.   hash *= 37;
  1545.   hash += toupper(name[i]);
  1546.   }
  1547.      //   newlf->lh_hash[slot].hash = hash;            //   修改过
  1548.   }   
  1549.   /* Allocate space for our new lf list and copy it into reg */
  1550.   newlfofs = alloc_block(hdesc, nkofs, 8 + 8*newlf->no_keys);
  1551.   if (!newlfofs) {
  1552.   printf("add_key: unable to allocate space for new index table for %s!n",name);
  1553.   FREE(newlf);
  1554.   free_block(hdesc,newnkofs);
  1555.   return(NULL);
  1556.   }
  1557.   /*    memcpy(hdesc->buffer + newlfofs + 4, newlf, 8 + 8*newlf->no_keys); */
  1558.   fill_block(hdesc, newlfofs, newlf, 8 + 8*newlf->no_keys);    
  1559.   } /* li else */
  1560.   /* Update parent, and free old lf list */
  1561.   key->no_subkeys++;
  1562.   if (ri) {  /* ri index */
  1563.   ri->hash[rislot].ofs_li = (newlf ? newlfofs : newliofs) - 0x1000;
  1564.   } else { /* Parent key */
  1565.   key->ofs_lf = (newlf ? newlfofs : newliofs) - 0x1000;
  1566.   }
  1567.   if (newlf && oldlfofs) free_block(hdesc,oldlfofs + 0x1000);
  1568.   if (newli && oldliofs) free_block(hdesc,oldliofs + 0x1000);
  1569.   FREE(newlf);
  1570.   FREE(newli);
  1571.   return(newnk);
  1572. }
  1573. #undef DKDEBUG
  1574. int CHiddenReg::del_key(struct hive *hdesc, int nkofs, char *name)
  1575. {
  1576. int slot = 0, newlfofs = 0, oldlfofs = 0, o, n, onkofs,  delnkofs;
  1577. int oldliofs = 0, no_keys = 0, newriofs = 0;
  1578. int namlen;
  1579. int rimax, riofs, rislot;
  1580. struct ri_key *ri, *newri = NULL;
  1581. struct lf_key *newlf = NULL, *oldlf = NULL;
  1582. struct li_key *newli = NULL, *oldli = NULL;
  1583. struct nk_key *key, *onk, *delnk;
  1584. char fullpath[501];
  1585. key = (struct nk_key *)(hdesc->buffer + nkofs);
  1586. namlen = strlen(name);
  1587. if (key->id != 0x6b6e) {
  1588. printf("add_key: current ptr not nkn");
  1589. return(1);
  1590. }
  1591. slot = -1;
  1592. if (!key->no_subkeys) {
  1593. printf("del_key: key has no subkeys!n");
  1594. return(1);
  1595. }
  1596. oldlfofs = key->ofs_lf;
  1597. oldliofs = key->ofs_lf;
  1598. oldlf = (struct lf_key *)(hdesc->buffer + oldlfofs + 0x1004);
  1599. if (oldlf->id != 0x666c && oldlf->id != 0x686c && oldlf->id != 0x696c && oldlf->id != 0x6972)  {
  1600. printf("del_key: index other than 'lf', 'li' or 'lh' not supported yet. 0x%04xn",oldlf->id);
  1601. return(1);
  1602. }
  1603. rimax = 0; ri = NULL; riofs = 0; rislot = 0;
  1604. if (oldlf->id == 0x6972) {  /* Indirect index 'ri', init loop */
  1605. riofs = key->ofs_lf;
  1606. ri = (struct ri_key *)(hdesc->buffer + riofs + 0x1004);
  1607. rimax = ri->no_lis-1;
  1608. #ifdef DKDEBUG
  1609. printf("del_key: entering 'ri' traverse, rimax = %dn",rimax);
  1610. #endif
  1611. oldliofs = ri->hash[rislot+1].ofs_li;
  1612. oldlfofs = ri->hash[rislot+1].ofs_li;
  1613. }
  1614. do {   /* 'ri' loop, at least run once if no 'ri' deep index */
  1615. if (ri) { /* Do next 'ri' slot */
  1616. rislot++;
  1617. oldliofs = ri->hash[rislot].ofs_li;
  1618. oldlfofs = ri->hash[rislot].ofs_li;
  1619. oldli = (struct li_key *)(hdesc->buffer + oldliofs + 0x1004);
  1620. oldlf = (struct lf_key *)(hdesc->buffer + oldlfofs + 0x1004);
  1621. }
  1622. oldli = (struct li_key *)(hdesc->buffer + oldliofs + 0x1004);
  1623. oldlf = (struct lf_key *)(hdesc->buffer + oldlfofs + 0x1004);
  1624. #ifdef DKDEBUG
  1625. printf("del_key: top of ri-loop: rislot = %dn",rislot);
  1626. #endif
  1627. slot = -1;
  1628. if (oldlf->id == 0x696c) {   /* 'li' handler */
  1629. #ifdef DKDEBUG      
  1630. printf("del_key: li handlern");
  1631. #endif
  1632. FREE(newli);
  1633. //      ALLOC(newli, 8 + 4*oldli->no_keys - 4, 1);           修改过
  1634. newli = (li_key*)malloc(8+4*oldli->no_keys-4);
  1635. memset(newli, 0, 8+4*oldli->no_keys-4);
  1636. newli->no_keys = oldli->no_keys - 1; no_keys = newli->no_keys;
  1637. newli->id = oldli->id;
  1638. /* Now copy old, checking where to delete */
  1639. for (o = 0, n = 0; o < oldli->no_keys; o++,n++) {
  1640. onkofs = oldli->hash[o].ofs_nk;
  1641. onk = (struct nk_key *)(onkofs + hdesc->buffer + 0x1004);
  1642. if (slot == -1 && onk->len_name == namlen && !strncmp(name, onk->keyname, (onk->len_name > namlen) ? onk->len_name : namlen)) {
  1643. slot = o;
  1644. delnkofs = onkofs; delnk = onk;
  1645. rimax = rislot;
  1646. o++;
  1647. }
  1648. newli->hash[n].ofs_nk = oldli->hash[o].ofs_nk;
  1649. }
  1650. } else { /* 'lf' or 'lh' are similar */
  1651. #ifdef DKDEBUG
  1652. printf("del_key: lf or lh handlern");
  1653. #endif
  1654. FREE(newlf);
  1655. //      ALLOC(newlf, 8 + 8*oldlf->no_keys - 8, 1);        修改过
  1656. newlf = (lf_key *)malloc(8+8*oldlf->no_keys-8);
  1657. memset(newlf, 0, 8+8*oldlf->no_keys-8);
  1658. newlf->no_keys = oldlf->no_keys - 1; no_keys = newlf->no_keys;
  1659. newlf->id = oldlf->id;
  1660. /* Now copy old, checking where to delete */
  1661. for (o = 0, n = 0; o < oldlf->no_keys; o++,n++) {
  1662. onkofs = oldlf->hash[o].ofs_nk;
  1663. onk = (struct nk_key *)(onkofs + hdesc->buffer + 0x1004);
  1664. if (slot == -1 && (onk->len_name == namlen) && !strncmp(name, onk->keyname, onk->len_name)) {
  1665. slot = o;
  1666. delnkofs = onkofs; delnk = onk;
  1667. rimax = rislot;
  1668. o++;
  1669. }
  1670. newlf->hash[n].ofs_nk = oldlf->hash[o].ofs_nk;
  1671. newlf->hash[n].name[0] = oldlf->hash[o].name[0];
  1672. newlf->hash[n].name[1] = oldlf->hash[o].name[1];
  1673. newlf->hash[n].name[2] = oldlf->hash[o].name[2];
  1674. newlf->hash[n].name[3] = oldlf->hash[o].name[3];
  1675. }
  1676. } /* else lh or lf */
  1677. } while (rislot < rimax);  /* ri traverse loop */
  1678. if (slot == -1) {
  1679. printf("del_key: subkey %s not found!n",name);
  1680. FREE(newlf);
  1681. FREE(newli);
  1682. return(1);
  1683. }
  1684. #ifdef DKDEBUG
  1685. printf("del_key: key found at slot %dn",slot);
  1686. #endif
  1687. if (delnk->no_values || delnk->no_subkeys) {
  1688. printf("del_key: subkey %s has subkeys or values. Not deleted.n",name);
  1689. FREE(newlf);
  1690. FREE(newli);
  1691. return(1);
  1692. }
  1693. /* Allocate space for our new lf list and copy it into reg */
  1694. if ( no_keys && (newlf || newli) ) {
  1695. newlfofs = alloc_block(hdesc, nkofs, 8 + (newlf ? 8 : 4) * no_keys);
  1696. #ifdef DKDEBUG
  1697. printf("del_key: alloc_block for index returns: %xn",newlfofs);
  1698. #endif
  1699. if (!newlfofs) {
  1700. printf("del_key: WARNING: unable to allocate space for new key descriptor for %s! Not deletedn",name);
  1701. FREE(newlf);
  1702. return(1);
  1703. }
  1704. /*    memcpy(hdesc->buffer + newlfofs + 4,
  1705. ((void *)newlf ? (void *)newlf : (void *)newli), 8 + (newlf ? 8 : 4) * no_keys);
  1706. */
  1707. fill_block(hdesc, newlfofs,
  1708. ((void *)newlf ? (void *)newlf : (void *)newli), 8 + (newlf ? 8 : 4) * no_keys);
  1709. } else {  /* Last deleted, will throw away index */
  1710. newlfofs = 0xfff;  /* We subtract 0x1000 later */
  1711. }
  1712. if (newlfofs < 0xfff) {
  1713. printf("del_key: ERROR: newlfofs = %xn",newlfofs);
  1714. debugit(hdesc->buffer,hdesc->size);
  1715. abort();
  1716. }
  1717. /* Check for CLASS data, if so, deallocate it too */
  1718. if (delnk->len_classnam) {
  1719. free_block(hdesc, delnk->ofs_classnam + 0x1000);
  1720. }
  1721. /* Now it's safe to zap the nk */
  1722. free_block(hdesc, delnkofs + 0x1000);
  1723. /* And the old index list */
  1724. free_block(hdesc, (oldlfofs ? oldlfofs : oldliofs) + 0x1000);
  1725. /* Update parent */
  1726. key->no_subkeys--;
  1727. if (ri) {
  1728. if (newlfofs == 0xfff) {
  1729. *fullpath = 0;
  1730. get_abs_path(hdesc, nkofs, fullpath, 480);
  1731. printf("del_key: need to delete ri-entry! %x - %sn",nkofs,fullpath);
  1732. if (ri->no_lis > 1) {  /* We have subindiceblocks left? */
  1733. /* Delete from array */
  1734. // ALLOC(newri, 8 + 4*ri->no_lis - 4, 1);              修改过
  1735. newri = (ri_key *)malloc(8+4*ri->no_lis-4);
  1736. memset(newri, 0, 8+4*ri->no_lis-4);
  1737. newri->no_lis = ri->no_lis - 1;
  1738. newri->id = ri->id;
  1739. for (o = 0, n = 0; o < ri->no_lis; o++,n++) {
  1740. if (n == rislot) o++;
  1741. newri->hash[n].ofs_li = ri->hash[o].ofs_li;
  1742. }
  1743. newriofs = alloc_block(hdesc, nkofs, 8 + newri->no_lis*4 );
  1744. printf("del_key: alloc_block for ri-block returns: %xn",newriofs);
  1745. if (!newriofs) {
  1746. printf("del_key: WARNING: unable to allocate space for ri-index for %s! Not deletedn",name);
  1747. FREE(newlf);
  1748. FREE(newri);
  1749. return(1);
  1750. }
  1751. fill_block(hdesc, newriofs, newri, 8 + newri->no_lis * 4);
  1752. free_block(hdesc, riofs + 0x1000);
  1753. key->ofs_lf = newriofs - 0x1000;
  1754. FREE(newri);
  1755. } else { /* Last entry in ri was deleted, get rid of it, key is empty */
  1756. printf("del_key: last ri deleted for %xn",nkofs);
  1757. free_block(hdesc, riofs + 0x1000);
  1758. key->ofs_lf = -1;
  1759. }
  1760. } else {
  1761. ri->hash[rislot].ofs_li = newlfofs - 0x1000; 
  1762. }
  1763. } else {
  1764. key->ofs_lf = newlfofs - 0x1000;
  1765. }
  1766. FREE(newlf);
  1767. return(0);
  1768. }
  1769. void CHiddenReg::rdel_keys(struct hive *hdesc, char *path, int vofs)
  1770. {
  1771. struct nk_key *key;
  1772. int nkofs;
  1773. struct ex_data ex;
  1774. int count = 0, countri = 0;
  1775. if (!path || !*path) return;
  1776. nkofs = trav_path(hdesc, vofs, path, 0);
  1777. if(!nkofs) {
  1778. printf("rdel_keys: Key <%s> not foundn",path);
  1779. return;
  1780. }
  1781. nkofs += 4;
  1782. key = (struct nk_key *)(hdesc->buffer + nkofs);
  1783. #if 0
  1784. printf("rdel of node at offset 0x%0xn",nkofs);
  1785. #endif
  1786. if (key->id != 0x6b6e) {
  1787. printf("Error: Not a 'nk' node!n");
  1788. debugit(hdesc->buffer,hdesc->size);
  1789. }
  1790. #if 0
  1791. printf("Node has %ld subkeys and %ld valuesn",key->no_subkeys,key->no_values);
  1792. #endif
  1793. if (key->no_subkeys) {
  1794. while ((ex_next_n(hdesc, nkofs, &count, &countri, &ex) > 0)) {
  1795. #if 0
  1796. printf("%sn",ex.name);
  1797. #endif
  1798. rdel_keys(hdesc, ex.name, nkofs);
  1799. count = 0;
  1800. countri = 0;
  1801. FREE(ex.name);
  1802. }
  1803. }
  1804. del_allvalues(hdesc, nkofs);
  1805. del_key(hdesc, key->ofs_parent+0x1004, path);
  1806. }
  1807. struct keyval *CHiddenReg::get_class(struct hive *hdesc,
  1808.  int curnk, char *path)
  1809. {
  1810. int clen = 0, dofs = 0, nkofs;
  1811. struct nk_key *key;
  1812. struct keyval *data;
  1813. void *classdata;
  1814. if (!path && !curnk) return(NULL);
  1815. nkofs = trav_path(hdesc, curnk, path, 0);
  1816. if(!nkofs) {
  1817. printf("get_class: Key <%s> not foundn",path);
  1818. return(NULL);
  1819. }
  1820. nkofs += 4;
  1821. key = (struct nk_key *)(hdesc->buffer + nkofs);
  1822. clen = key->len_classnam;
  1823. if (!clen) {
  1824. printf("get_class: Key has no class data.n");
  1825. return(NULL);
  1826. }
  1827. dofs = key->ofs_classnam;
  1828. classdata = (void *)(hdesc->buffer + dofs + 0x1004);
  1829. #if 0
  1830. printf("get_class: len_classnam = %dn",clen);
  1831. printf("get_class: ofs_classnam = 0x%xn",dofs);
  1832. #endif
  1833. //  ALLOC(data, sizeof(struct keyval) + clen,1);         修改过
  1834. data = (keyval *)malloc(sizeof(struct keyval)+clen);
  1835. memset(data, 0, sizeof(struct keyval)+clen);
  1836. data->len = clen;
  1837. memcpy(&data->data, classdata, clen);
  1838. return(data);
  1839. }
  1840. int CHiddenReg::put_buf2val(struct hive *hdesc, struct keyval *kv,
  1841. int vofs, char *path, int type )
  1842. {
  1843. int l;
  1844. void *keydataptr;
  1845. if (!kv) return(0);
  1846. l = get_val_len(hdesc, vofs, path);
  1847. if (l == -1) return(0);  /* error */
  1848. if (kv->len != l) {  /* Realloc data block if not same size as existing */
  1849. if (!alloc_val_data(hdesc, vofs, path, kv->len)) {
  1850. printf("put_buf2val: %s : alloc_val_data failed!n",path);
  1851. return(0);
  1852. }
  1853. }
  1854. keydataptr = get_val_data(hdesc, vofs, path, type);
  1855. if (!keydataptr) return(0); /* error */
  1856. memcpy(keydataptr, &kv->data, kv->len);
  1857. hdesc->state |= HMODE_DIRTY;
  1858. return(kv->len);
  1859. }
  1860. int CHiddenReg::put_dword(struct hive *hdesc, int vofs, char *path, int dword)
  1861. {
  1862. struct keyval *kr;
  1863. int r;
  1864. //  ALLOC(kr,1,sizeof(int)+sizeof(int));            修改过
  1865. kr = (keyval *)malloc(sizeof(int)*2);
  1866. memset(kr, 0, sizeof(int)*2);
  1867. // kr = (keyval*)malloc(sizeof(int)*2);
  1868. kr->len = sizeof(int);
  1869. (int)kr->data = dword;
  1870. r = put_buf2val(hdesc, kr, vofs, path, REG_DWORD);
  1871. FREE(kr);
  1872. return(r);
  1873. }
  1874. void CHiddenReg::closeHive(struct hive *hdesc)
  1875. {
  1876. printf("closing hive %sn",hdesc->filename);
  1877. if (hdesc->state & HMODE_OPEN) 
  1878. {
  1879. //   CFile::Close(hdesc->filedesc);
  1880. close(hdesc->filedesc);
  1881. }
  1882. FREE(hdesc->filename);
  1883. FREE(hdesc->buffer);
  1884. FREE(hdesc);
  1885. }
  1886. int CHiddenReg::writeHive(struct hive *hdesc)
  1887. {
  1888. int len;
  1889. if (hdesc->state & HMODE_RO) return(0);
  1890. if ( !(hdesc->state & HMODE_DIRTY)) return(0);
  1891. if ( !(hdesc->state & HMODE_OPEN)) { /* File has been closed */
  1892. if (!(hdesc->filedesc = open(hdesc->filename,O_RDWR))) {
  1893. fprintf(stderr,"writeHive: open(%s) failed: %s, FILE NOT WRITTEN!n",hdesc->filename,strerror(errno));
  1894. return(1);
  1895. }
  1896. hdesc->state |= HMODE_OPEN;
  1897. }  
  1898. /* Seek back to begginning of file (in case it's already open) */
  1899. lseek(hdesc->filedesc, 0, SEEK_SET);
  1900. len = write(hdesc->filedesc, hdesc->buffer, hdesc->size);
  1901. if (len != hdesc->size) {
  1902. fprintf(stderr,"writeHive: write of %s failed: %s.n",hdesc->filename,strerror(errno));
  1903. return(1);
  1904. }
  1905. hdesc->state &= (~HMODE_DIRTY);
  1906. return(0);
  1907. }
  1908. struct hive *CHiddenReg::openHive(char *filename, int mode)
  1909. {
  1910. struct hive *hdesc;
  1911. int fmode,r,vofs;
  1912. //  struct stat sbuf;
  1913. unsigned long pofs;
  1914. /* off_t l; */
  1915. char *c;
  1916. struct hbin_page *p;
  1917. struct regf_header *hdr;
  1918. struct nk_key *nk;
  1919. struct ri_key *rikey;
  1920. int verbose = (mode & HMODE_VERBOSE);
  1921. CREATE(hdesc,struct hive,1);
  1922. hdesc->filename = str_dup(filename);
  1923. hdesc->state = 0;
  1924. hdesc->size = 0;
  1925. hdesc->buffer = NULL;
  1926. if ( (mode & HMODE_RO) ) {
  1927. fmode = O_RDONLY;
  1928. } else {
  1929. fmode = O_RDWR;
  1930. }
  1931. hdesc->filedesc = open(hdesc->filename,fmode);
  1932. if (hdesc->filedesc < 0) {
  1933. fprintf(stderr,"openHive(%s) failed: %s, trying read-onlyn",hdesc->filename,strerror(errno));
  1934. fmode = O_RDONLY;
  1935. mode |= HMODE_RO;
  1936. hdesc->filedesc = open(hdesc->filename,fmode);
  1937. if (hdesc->filedesc < 0) {
  1938. fprintf(stderr,"openHive(%s) in fallback RO-mode failed: %sn",hdesc->filename,strerror(errno));
  1939. closeHive(hdesc);
  1940. return(NULL);
  1941. }
  1942. }
  1943. // if ( fstat(hdesc->filedesc,&sbuf) ) {           //        修改过
  1944. //     perror("stat()");
  1945. //     exit(1);
  1946. //   }
  1947. // hdesc->size = sbuf.st_size;
  1948. // hdesc->state = mode | HMODE_OPEN;
  1949. /*  fprintf(stderr,"hiveOpen(%s) successfuln",hdesc->filename); */ 
  1950. /* Read the whole file */
  1951. //  ALLOC(hdesc->buffer,1,hdesc->size);                修改过
  1952. hdesc->buffer = (char *)malloc(hdesc->size);
  1953. memset(hdesc->buffer, 0, hdesc->size);
  1954. r = read(hdesc->filedesc,hdesc->buffer,hdesc->size);
  1955. if (r < hdesc->size) 
  1956. {
  1957. fprintf(stderr,"Could not read file, got %d bytes while expecting %dn",
  1958. r, hdesc->size);
  1959. closeHive(hdesc);
  1960. return(NULL);
  1961. }
  1962. pofs = 0x1000;
  1963. hdr = (struct regf_header *)hdesc->buffer;
  1964. if (hdr->id != 0x66676572) {
  1965. printf("openHive(%s): File does not seem to be a registry hive!n",filename);
  1966. return(hdesc);
  1967. }
  1968. printf("Hive's name (from header): <");
  1969. for (c = hdr->name; *c && (c < hdr->name + 64); c += 2) putchar(*c);
  1970. hdesc->rootofs = hdr->ofs_rootkey + 0x1000;
  1971. printf(">nROOT KEY at offset: 0x%06x * ",hdesc->rootofs);
  1972. /* Cache the roots subkey index type (li,lf,lh) so we can use the correct
  1973.     * one when creating the first subkey in a key */   
  1974. nk = (struct nk_key *)(hdesc->buffer + hdesc->rootofs + 4);
  1975. if (nk->id == 0x6b6e) {
  1976. rikey = (struct ri_key *)(hdesc->buffer + nk->ofs_lf + 0x1004);
  1977. hdesc->nkindextype = rikey->id;
  1978. if (hdesc->nkindextype == 0x6972) {  /* Gee, big root, must check indirectly */
  1979. printf("load_hive: DEBUG: BIG ROOT!n");
  1980. rikey = (struct ri_key *)(hdesc->buffer + rikey->hash[0].ofs_li + 0x1004);
  1981. hdesc->nkindextype = rikey->id;
  1982. }
  1983. if (hdesc->nkindextype != 0x666c &&
  1984. hdesc->nkindextype != 0x686c &&
  1985. hdesc->nkindextype != 0x696c) {
  1986. hdesc->nkindextype = 0x666c;
  1987. }
  1988. printf("Subkey indexing type is: %04x <%c%c>n",
  1989. hdesc->nkindextype,
  1990. hdesc->nkindextype & 0xff,
  1991. hdesc->nkindextype >> 8);
  1992. } else {
  1993. printf("load_hive: WARNING: ROOT key does not seem to be a key! (not type == nk)n");
  1994. }
  1995. while (pofs < hdesc->size) {
  1996. #ifdef LOAD_DEBUG
  1997. if (verbose) hexdump(hdesc->buffer,pofs,pofs+0x20,1);
  1998. #endif
  1999. p = (struct hbin_page *)(hdesc->buffer + pofs);
  2000. if (p->id != 0x6E696268) {
  2001. printf("Page at 0x%lx is not 'hbin', assuming file contains garbage at end",pofs);
  2002. break;
  2003. }
  2004. hdesc->pages++;
  2005. #ifdef LOAD_DEBUG
  2006. if (verbose) printf("n###### Page at 0x%0lx has size 0x%0lx, next at 0x%0lx ######n",pofs,p->len_page,p->ofs_next);
  2007. #endif
  2008. if (p->ofs_next == 0) {
  2009. #ifdef LOAD_DEBUG
  2010. if (verbose) printf("openhive debug: bailing out.. pagesize zero!n");
  2011. #endif
  2012. return(hdesc);
  2013. }
  2014. #if 0
  2015. if (p->len_page != p->ofs_next) {
  2016. #ifdef LOAD_DEBUG
  2017. if (verbose) printf("openhive debug: len & ofs not same. HASTA!n");
  2018. #endif
  2019. exit(0);
  2020. }
  2021. #endif
  2022. vofs = pofs + 0x20; /* Skip page header */
  2023. #if 1
  2024. while (vofs-pofs < p->ofs_next) {
  2025. vofs += parse_block(hdesc,vofs,verbose);
  2026. }
  2027. #endif
  2028. pofs += p->ofs_next;
  2029. }
  2030. printf("nFile size %d [%x] bytes, containing %d pages (+ 1 headerpage)n",hdesc->size,hdesc->size, hdesc->pages);
  2031. printf("Used for data: %d/%d blocks/bytes, unused: %d/%d blocks/bytes.n",
  2032. hdesc->useblk,hdesc->usetot,hdesc->unuseblk,hdesc->unusetot);
  2033. /* So, let's guess what kind of hive this is, based on keys in its root */
  2034. hdesc->type = HTYPE_UNKNOWN;
  2035. if (trav_path(hdesc, 0, "\SAM", 0)) hdesc->type = HTYPE_SAM;
  2036. else if (trav_path(hdesc, 0, "\ControlSet", 0)) hdesc->type = HTYPE_SYSTEM;
  2037. else if (trav_path(hdesc, 0, "\Policy", 0)) hdesc->type = HTYPE_SECURITY;
  2038. else if (trav_path(hdesc, 0, "\Microsoft", 0)) hdesc->type = HTYPE_SOFTWARE;
  2039. return(hdesc);
  2040. }