Changeset 159
- Timestamp:
- 12/06/09 15:09:01 (15 years ago)
- Location:
- trunk
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Makefile
r147 r159 11 11 12 12 CC=gcc 13 OPTS=-std=gnu 89 -pedantic -Wall -ggdb14 #OPTS=-std=gnu 89 -pedantic -Wall13 OPTS=-std=gnu99 -pedantic -Wall -ggdb 14 #OPTS=-std=gnu99 -pedantic -Wall 15 15 INC:=-I$(PWD)/include -I/usr/local/include 16 16 LIB=-L/usr/local/lib -lm -
trunk/include/regfi.h
r158 r159 45 45 #include <unistd.h> 46 46 #include <assert.h> 47 #include <iconv.h> 47 48 48 49 #include "talloc.h" … … 250 251 251 252 253 typedef struct _regfi_data 254 { 255 uint32 type; 256 257 /* Length of the raw data. */ 258 uint32 size; 259 260 /* This is always present, representing the raw data cell contents. */ 261 uint8* raw; 262 263 /* Represents the length of the interpreted value. Meaning is type-specific.*/ 264 uint32 interpreted_size; 265 266 /* These items represent interpreted versions of the raw attribute above. 267 * Only use the appropriate member according to the type field. 268 * In the event of an unknown type, use only the raw field. 269 */ 270 union _regfi_data_interpreted 271 { 272 uint8* none; /* */ 273 uint8* string; 274 uint8* expand_string; 275 uint8* binary; /* */ 276 uint32 dword; 277 uint32 dword_be; 278 uint8* link; 279 uint8** multiple_string; 280 uint64 qword; 281 282 /* The following are treated as binary currently, but this may change in 283 * the future as the formats become better understood. 284 */ 285 uint8* resource_list; 286 uint8* full_resource_descriptor; 287 uint8* resource_requirements_list; 288 } interpreted; 289 } REGFI_DATA; 290 291 252 292 /* Value record */ 253 293 typedef struct … … 256 296 uint32 cell_size; /* ((start_offset - end_offset) & 0xfffffff8) */ 257 297 258 uint8* data; 298 REGFI_DATA* data; /* XXX: deprecated */ 299 259 300 char* valuename; 260 301 uint16 name_length; 261 302 uint32 hbin_off; /* offset from beginning of this hbin block */ 262 303 263 uint32 data_size; 264 uint32 data_off; /* offset of data cell (virtual) */ 304 uint32 data_size; /* As reported in the VK record. May be different than 305 * That obtained while parsing the data cell itself. */ 306 uint32 data_off; /* Offset of data cell (virtual) */ 265 307 uint32 type; 266 308 uint8 magic[REGFI_CELL_MAGIC_SIZE]; … … 423 465 void_stack* key_positions; 424 466 REGFI_NK_REC* cur_key; 467 const char* string_encoding; 425 468 uint32 cur_subkey; 426 469 uint32 cur_value; … … 446 489 447 490 491 448 492 /******************************************************************************/ 449 493 /* Main iterator API */ … … 462 506 */ 463 507 char* regfi_get_messages(REGFI_FILE* file); 508 464 509 void regfi_set_message_mask(REGFI_FILE* file, uint16 mask); 465 510 466 REGFI_ITERATOR* regfi_iterator_new(REGFI_FILE* fh); 511 512 /* regfi_iterator_new: Creates a new iterator for the provided registry file. 513 * 514 * Arguments: 515 * file -- The opened registry file the iterator should be 516 * created for. 517 * output_encoding -- An integer representing the output string encoding. 518 * These integers currently map to a specific set of 519 * iconv(3) encodings. 520 * The following values are currently accepted: 521 * 0 - default (currently US-ASCII//TRANSLIT) 522 * 1 - US-ASCII//TRANSLIT 523 * 2 - UTF-8//TRANSLIT 524 * 525 * XXX: This encoding only applies to specific data 526 * strings currently, but should apply to key 527 * names and value names in the future. 528 * 529 * Returns: 530 * A newly allocated REGFI_ITERATOR. Must be free()d with regfi_iterator_free. 531 */ 532 REGFI_ITERATOR* regfi_iterator_new(REGFI_FILE* file, 533 uint32 output_encoding); 467 534 void regfi_iterator_free(REGFI_ITERATOR* i); 468 535 bool regfi_iterator_down(REGFI_ITERATOR* i); … … 487 554 const char* value_name); 488 555 489 REGFI_DATA* regfi_iterator_cur_data(REGFI_ITERATOR* i); 556 REGFI_DATA* regfi_iterator_fetch_data(REGFI_ITERATOR* i, 557 const REGFI_VK_REC* value); 490 558 491 559 … … 512 580 range_list* used_ranges, 513 581 bool strict); 582 bool regfi_interpret_data(REGFI_FILE* file, 583 const char* string_encoding, 584 uint32 type, REGFI_DATA* data); 585 void regfi_free_data(REGFI_DATA* data); 514 586 515 587 /* These are cached so return values don't need to be freed. */ … … 599 671 REGFI_VK_REC* regfi_copy_vk(const REGFI_VK_REC* vk); 600 672 int32 regfi_calc_maxsize(REGFI_FILE* file, uint32 offset); 673 int32 regfi_conv_charset(const char* output_charset, 674 uint8* input, char* output, 675 uint32 input_len, uint32 output_max); 676 REGFI_DATA* regfi_buffer_to_data(REGFI_BUFFER raw_data); 601 677 602 678 #endif /* _REGFI_H */ -
trunk/lib/regfi.c
r158 r159 958 958 { 959 959 REGFI_VK_REC* ret_val = NULL; 960 REGFI_BUFFER data;961 960 int32 max_size; 962 961 … … 969 968 return NULL; 970 969 971 if(ret_val->data_size == 0) 972 ret_val->data = NULL; 973 else 974 { 975 data = regfi_load_data(file, ret_val->data_off, ret_val->data_size, 976 ret_val->data_in_offset, strict); 977 ret_val->data = data.buf; 978 ret_val->data_size = data.len; 979 980 if(ret_val->data == NULL) 981 { 982 regfi_add_message(file, REGFI_MSG_WARN, "Could not parse data record" 983 " while parsing VK record at offset 0x%.8X.", 984 ret_val->offset, ret_val->valuename); 985 } 986 else 987 talloc_steal(ret_val, ret_val->data); 988 } 970 /* XXX: convert valuename to proper encoding if necessary */ 989 971 990 972 return ret_val; … … 1189 1171 while(cur_offset < hbin_end) 1190 1172 { 1191 fprintf(stderr, "DEBUG: trying cell offset 0x%.8X\n", cur_offset);1192 1173 if(!regfi_parse_cell(file->fd, cur_offset, NULL, 0, &cell_length, &unalloc)) 1193 1174 { … … 1383 1364 /****************************************************************************** 1384 1365 *****************************************************************************/ 1385 REGFI_ITERATOR* regfi_iterator_new(REGFI_FILE* f h)1366 REGFI_ITERATOR* regfi_iterator_new(REGFI_FILE* file, uint32 output_encoding) 1386 1367 { 1387 1368 REGFI_NK_REC* root; … … 1390 1371 return NULL; 1391 1372 1392 root = regfi_rootkey(f h);1373 root = regfi_rootkey(file); 1393 1374 if(root == NULL) 1394 1375 { … … 1405 1386 talloc_steal(ret_val, ret_val->key_positions); 1406 1387 1407 ret_val->f = f h;1388 ret_val->f = file; 1408 1389 ret_val->cur_key = root; 1409 1390 ret_val->cur_subkey = 0; 1410 1391 ret_val->cur_value = 0; 1411 1392 1393 switch (output_encoding) 1394 { 1395 case 0: 1396 case 1: 1397 ret_val->string_encoding = "US-ASCII//TRANSLIT"; 1398 break; 1399 case 2: 1400 ret_val->string_encoding = "UTF-8//TRANSLIT"; 1401 break; 1402 default: 1403 talloc_free(ret_val); 1404 return NULL; 1405 } 1406 1412 1407 return ret_val; 1413 1408 } … … 1688 1683 1689 1684 1685 /****************************************************************************** 1686 *****************************************************************************/ 1687 REGFI_DATA* regfi_iterator_fetch_data(REGFI_ITERATOR* i, 1688 const REGFI_VK_REC* value) 1689 { 1690 REGFI_DATA* ret_val = NULL; 1691 REGFI_BUFFER raw_data; 1692 1693 if(value->data_size != 0) 1694 { 1695 raw_data = regfi_load_data(i->f, value->data_off, value->data_size, 1696 value->data_in_offset, true); 1697 if(raw_data.buf == NULL) 1698 { 1699 regfi_add_message(i->f, REGFI_MSG_WARN, "Could not parse data record" 1700 " while parsing VK record at offset 0x%.8X.", 1701 value->offset); 1702 } 1703 else 1704 { 1705 ret_val = regfi_buffer_to_data(raw_data); 1706 1707 if(ret_val == NULL) 1708 { 1709 regfi_add_message(i->f, REGFI_MSG_WARN, "Error occurred in converting" 1710 " data buffer to data structure while interpreting " 1711 "data for VK record at offset 0x%.8X.", 1712 value->offset); 1713 talloc_free(raw_data.buf); 1714 return NULL; 1715 } 1716 1717 if(!regfi_interpret_data(i->f, i->string_encoding, value->type, ret_val)) 1718 { 1719 regfi_add_message(i->f, REGFI_MSG_INFO, "Error occurred while" 1720 " interpreting data for VK record at offset 0x%.8X.", 1721 value->offset); 1722 } 1723 } 1724 } 1725 1726 return ret_val; 1727 } 1728 1729 1730 /****************************************************************************** 1731 *****************************************************************************/ 1732 void regfi_free_data(REGFI_DATA* data) 1733 { 1734 talloc_free(data); 1735 } 1736 1737 1738 /****************************************************************************** 1739 *****************************************************************************/ 1740 REGFI_DATA* regfi_buffer_to_data(REGFI_BUFFER raw_data) 1741 { 1742 REGFI_DATA* ret_val; 1743 1744 if(raw_data.buf == NULL) 1745 return NULL; 1746 1747 ret_val = talloc(NULL, REGFI_DATA); 1748 if(ret_val == NULL) 1749 return NULL; 1750 1751 talloc_steal(ret_val, raw_data.buf); 1752 ret_val->raw = raw_data.buf; 1753 ret_val->size = raw_data.len; 1754 ret_val->interpreted_size = 0; 1755 ret_val->interpreted.qword = 0; 1756 1757 return ret_val; 1758 } 1759 1760 1761 /****************************************************************************** 1762 *****************************************************************************/ 1763 bool regfi_interpret_data(REGFI_FILE* file, const char* string_encoding, 1764 uint32 type, REGFI_DATA* data) 1765 { 1766 uint8** tmp_array; 1767 uint8* tmp_str; 1768 int32 tmp_size; 1769 uint32 i, j, array_size; 1770 1771 if(data == NULL) 1772 return false; 1773 1774 switch (type) 1775 { 1776 case REG_SZ: 1777 case REG_EXPAND_SZ: 1778 /* REG_LINK is a symbolic link, stored as a unicode string. */ 1779 case REG_LINK: 1780 tmp_str = talloc_array(NULL, uint8, data->size); 1781 if(tmp_str == NULL) 1782 { 1783 data->interpreted.string = NULL; 1784 data->interpreted_size = 0; 1785 return false; 1786 } 1787 1788 tmp_size = regfi_conv_charset(string_encoding, 1789 data->raw, (char*)tmp_str, 1790 data->size, data->size); 1791 if(tmp_size < 0) 1792 { 1793 regfi_add_message(file, REGFI_MSG_INFO, "Error occurred while" 1794 " converting data of type %d to %s. Error message: %s", 1795 type, string_encoding, strerror(-tmp_size)); 1796 talloc_free(tmp_str); 1797 data->interpreted.string = NULL; 1798 data->interpreted_size = 0; 1799 return false; 1800 } 1801 1802 tmp_str = talloc_realloc(NULL, tmp_str, uint8, tmp_size); 1803 data->interpreted.string = tmp_str; 1804 data->interpreted_size = tmp_size; 1805 talloc_steal(data, tmp_str); 1806 break; 1807 1808 case REG_DWORD: 1809 if(data->size < 4) 1810 { 1811 data->interpreted.dword = 0; 1812 data->interpreted_size = 0; 1813 return false; 1814 } 1815 data->interpreted.dword = IVAL(data->raw, 0); 1816 data->interpreted_size = 4; 1817 break; 1818 1819 case REG_DWORD_BE: 1820 if(data->size < 4) 1821 { 1822 data->interpreted.dword_be = 0; 1823 data->interpreted_size = 0; 1824 return false; 1825 } 1826 data->interpreted.dword_be = RIVAL(data->raw, 0); 1827 data->interpreted_size = 4; 1828 break; 1829 1830 case REG_QWORD: 1831 if(data->size < 8) 1832 { 1833 data->interpreted.qword = 0; 1834 data->interpreted_size = 0; 1835 return false; 1836 } 1837 data->interpreted.qword = 1838 (uint64)IVAL(data->raw, 0) + (((uint64)IVAL(data->raw, 4))<<32); 1839 data->interpreted_size = 8; 1840 break; 1841 1842 case REG_MULTI_SZ: 1843 tmp_str = talloc_array(NULL, uint8, data->size); 1844 if(tmp_str == NULL) 1845 { 1846 data->interpreted.multiple_string = NULL; 1847 data->interpreted_size = 0; 1848 return false; 1849 } 1850 1851 /* Attempt to convert entire string from UTF-16LE to output encoding, 1852 * then parse and quote fields individually. 1853 */ 1854 tmp_size = regfi_conv_charset(string_encoding, 1855 data->raw, (char*)tmp_str, 1856 data->size, data->size); 1857 if(tmp_size < 0) 1858 { 1859 regfi_add_message(file, REGFI_MSG_INFO, "Error occurred while" 1860 " converting data of type %d to %s. Error message: %s", 1861 type, string_encoding, strerror(-tmp_size)); 1862 talloc_free(tmp_str); 1863 data->interpreted.multiple_string = NULL; 1864 data->interpreted_size = 0; 1865 return false; 1866 } 1867 1868 array_size = tmp_size+1; 1869 tmp_array = talloc_array(NULL, uint8*, array_size); 1870 if(tmp_array == NULL) 1871 { 1872 talloc_free(tmp_str); 1873 data->interpreted.string = NULL; 1874 data->interpreted_size = 0; 1875 return false; 1876 } 1877 1878 tmp_array[0] = tmp_str; 1879 for(i=0,j=1; i < tmp_size && j < array_size-1; i++) 1880 { 1881 if(tmp_str[i] == '\0' && (i+1 < tmp_size)) 1882 tmp_array[j++] = tmp_str+i+1; 1883 } 1884 tmp_array[j] = NULL; 1885 tmp_array = talloc_realloc(NULL, tmp_array, uint8*, j+1); 1886 data->interpreted.multiple_string = tmp_array; 1887 /* XXX: how meaningful is this? should we store number of strings instead? */ 1888 data->interpreted_size = tmp_size; 1889 talloc_steal(tmp_array, tmp_str); 1890 talloc_steal(data, tmp_array); 1891 break; 1892 1893 /* XXX: Dont know how to interpret these yet, just treat as binary */ 1894 case REG_NONE: 1895 data->interpreted.none = data->raw; 1896 data->interpreted_size = data->size; 1897 break; 1898 1899 case REG_RESOURCE_LIST: 1900 data->interpreted.resource_list = data->raw; 1901 data->interpreted_size = data->size; 1902 break; 1903 1904 case REG_FULL_RESOURCE_DESCRIPTOR: 1905 data->interpreted.full_resource_descriptor = data->raw; 1906 data->interpreted_size = data->size; 1907 break; 1908 1909 case REG_RESOURCE_REQUIREMENTS_LIST: 1910 data->interpreted.resource_requirements_list = data->raw; 1911 data->interpreted_size = data->size; 1912 break; 1913 1914 case REG_BINARY: 1915 data->interpreted.binary = data->raw; 1916 data->interpreted_size = data->size; 1917 break; 1918 1919 default: 1920 data->interpreted.qword = 0; 1921 data->interpreted_size = 0; 1922 return false; 1923 } 1924 1925 data->type = type; 1926 return true; 1927 } 1928 1929 1930 1931 /******************************************************************* 1932 * Convert from UTF-16LE to specified character set. 1933 * On error, returns a negative errno code. 1934 *******************************************************************/ 1935 int32 regfi_conv_charset(const char* output_charset, 1936 uint8* input, char* output, 1937 uint32 input_len, uint32 output_max) 1938 { 1939 iconv_t conv_desc; 1940 char* inbuf = (char*)input; 1941 char* outbuf = output; 1942 size_t in_len = (size_t)input_len; 1943 size_t out_len = (size_t)(output_max-1); 1944 int ret; 1945 1946 /* Set up conversion descriptor. */ 1947 conv_desc = iconv_open(output_charset, "UTF-16LE"); 1948 1949 ret = iconv(conv_desc, &inbuf, &in_len, &outbuf, &out_len); 1950 if(ret == -1) 1951 { 1952 iconv_close(conv_desc); 1953 return -errno; 1954 } 1955 *outbuf = '\0'; 1956 1957 iconv_close(conv_desc); 1958 return output_max-out_len-1; 1959 } 1960 1961 1962 1690 1963 /******************************************************************* 1691 1964 * Computes the checksum of the registry file header. 1692 * buffer must be at least the size of a nregf header (4096 bytes).1965 * buffer must be at least the size of a regf header (4096 bytes). 1693 1966 *******************************************************************/ 1694 1967 static uint32 regfi_compute_header_checksum(uint8* buffer) … … 2187 2460 * 2188 2461 ******************************************************************************/ 2189 REGFI_BUFFER regfi_load_data(REGFI_FILE* file, uint32 voffset, 2462 REGFI_BUFFER regfi_load_data(REGFI_FILE* file, uint32 voffset, 2190 2463 uint32 length, bool data_in_offset, 2191 2464 bool strict) … … 2196 2469 bool unalloc; 2197 2470 2471 /* Microsoft's documentation indicates that "available memory" is 2472 * the limit on value sizes. Annoying. We limit it to 1M which 2473 * should rarely be exceeded, unless the file is corrupt or 2474 * malicious. For more info, see: 2475 * http://msdn2.microsoft.com/en-us/library/ms724872.aspx 2476 */ 2477 /* 2478 XXX 2479 if(size > REGFI_VK_MAX_DATA_LENGTH) 2480 { 2481 *error_msg = (char*)malloc(82); 2482 if(*error_msg == NULL) 2483 return NULL; 2484 2485 sprintf(*error_msg, "WARN: value data size %d larger than " 2486 "%d, truncating...", size, REGFI_VK_MAX_DATA_LENGTH); 2487 size = REGFI_VK_MAX_DATA_LENGTH; 2488 } 2489 2490 */ 2491 2198 2492 if(data_in_offset) 2199 2493 return regfi_parse_little_data(file, voffset, length, strict); … … 2289 2583 } 2290 2584 2291 if((ret_val.buf = talloc_array(NULL, uint8 _t, length)) == NULL)2585 if((ret_val.buf = talloc_array(NULL, uint8, length)) == NULL) 2292 2586 return ret_val; 2293 2587 ret_val.len = length; … … 2329 2623 } 2330 2624 2331 if((ret_val.buf = talloc_array(NULL, uint8 _t, length)) == NULL)2625 if((ret_val.buf = talloc_array(NULL, uint8, length)) == NULL) 2332 2626 return ret_val; 2333 2627 ret_val.len = length; -
trunk/src/common.c
r154 r159 160 160 int ret; 161 161 162 /* Set up conversion descriptor. */163 162 conv_desc = iconv_open("US-ASCII//TRANSLIT", "UTF-16LE"); 164 163 … … 229 228 * value, and a non-NULL (*error_msg). 230 229 */ 231 /* XXX: Part of this function's logic should be pushed into the regfi API. 232 * The structures should be parsed and stored with VK records and only 233 * escaped/encoded later in reglookup and reglookup-recover. 234 */ 235 static char* data_to_ascii(unsigned char* datap, uint32 len, uint32 type, 236 char** error_msg) 237 { 238 char* asciip; 239 char* ascii; 240 char* ascii_tmp; 230 static char* data_to_ascii(REGFI_DATA* data, char** error_msg) 231 { 232 char* ret_val; 241 233 char* cur_quoted; 242 char* tmp_err = NULL; 243 const char* delim; 244 uint32 i; 245 uint32 cur_str_len; 246 uint32 ascii_max; 247 uint32 str_rem, alen; 248 int ret_err; 249 250 if(datap == NULL) 251 { 252 *error_msg = (char*)malloc(24); 253 if(*error_msg == NULL) 254 return NULL; 255 strcpy(*error_msg, "Data pointer was NULL."); 234 char* tmp_ptr; 235 char* delim; 236 uint32 ret_val_left, i, tmp_len; 237 238 if(data == NULL || data->size == 0) 239 { 240 *error_msg = (char*)malloc(37); 241 if(*error_msg == NULL) 242 return NULL; 243 strcpy(*error_msg, "Data pointer was NULL or size was 0."); 256 244 return NULL; 257 245 } 258 246 *error_msg = NULL; 259 247 260 switch (type) 248 249 if(data->interpreted_size == 0) 250 { 251 *error_msg = (char*)malloc(51); 252 if(*error_msg == NULL) 253 return NULL; 254 strcpy(*error_msg, "Data could not be interpreted, quoting raw buffer."); 255 return quote_buffer(data->raw, data->size, common_special_chars); 256 } 257 258 switch (data->type) 261 259 { 262 260 case REG_SZ: 261 ret_val = quote_string((char*)data->interpreted.string, common_special_chars); 262 if(ret_val == NULL && (*error_msg = (char*)malloc(49)) != NULL) 263 strcpy(*error_msg, "Buffer could not be quoted due to unknown error."); 264 265 return ret_val; 266 break; 267 268 263 269 case REG_EXPAND_SZ: 264 /* REG_LINK is a symbolic link, stored as a unicode string. */ 270 ret_val = quote_string((char*)data->interpreted.expand_string, 271 common_special_chars); 272 if(ret_val == NULL && (*error_msg = (char*)malloc(49)) != NULL) 273 strcpy(*error_msg, "Buffer could not be quoted due to unknown error."); 274 275 return ret_val; 276 break; 277 265 278 case REG_LINK: 266 /* Sometimes values have binary stored in them. If the unicode 267 * conversion fails, just quote it raw. 279 ret_val = quote_string((char*)data->interpreted.link, common_special_chars); 280 if(ret_val == NULL && (*error_msg = (char*)malloc(49)) != NULL) 281 strcpy(*error_msg, "Buffer could not be quoted due to unknown error."); 282 283 return ret_val; 284 break; 285 286 case REG_DWORD: 287 ret_val = malloc(sizeof(char)*(8+2+1)); 288 if(ret_val == NULL) 289 return NULL; 290 291 sprintf(ret_val, "0x%.8X", data->interpreted.dword); 292 return ret_val; 293 break; 294 295 case REG_DWORD_BE: 296 ret_val = malloc(sizeof(char)*(8+2+1)); 297 if(ret_val == NULL) 298 return NULL; 299 300 sprintf(ret_val, "0x%.8X", data->interpreted.dword_be); 301 return ret_val; 302 break; 303 304 case REG_QWORD: 305 ret_val = malloc(sizeof(char)*(16+2+1)); 306 if(ret_val == NULL) 307 return NULL; 308 309 sprintf(ret_val, "0x%.16llX", 310 (long long unsigned int)data->interpreted.qword); 311 return ret_val; 312 break; 313 314 case REG_MULTI_SZ: 315 ret_val_left = data->interpreted_size*4+1; 316 ret_val = malloc(ret_val_left); 317 if(ret_val == NULL) 318 return NULL; 319 320 tmp_ptr = ret_val; 321 tmp_ptr[0] = '\0'; 322 delim = ""; 323 for(i=0; data->interpreted.multiple_string[i] != NULL; i++) 324 { 325 cur_quoted = quote_string((char*)data->interpreted.multiple_string[i], 326 subfield_special_chars); 327 if(cur_quoted != NULL && cur_quoted[0] != '\0') 328 { 329 tmp_len = snprintf(tmp_ptr, ret_val_left, "%s%s",delim, cur_quoted); 330 tmp_ptr += tmp_len; 331 ret_val_left -= tmp_len; 332 free(cur_quoted); 333 } 334 delim = "|"; 335 } 336 337 return ret_val; 338 break; 339 340 341 case REG_NONE: 342 return quote_buffer(data->interpreted.none, data->interpreted_size, 343 common_special_chars); 344 345 break; 346 347 case REG_RESOURCE_LIST: 348 return quote_buffer(data->interpreted.resource_list, data->interpreted_size, 349 common_special_chars); 350 351 break; 352 353 case REG_FULL_RESOURCE_DESCRIPTOR: 354 return quote_buffer(data->interpreted.full_resource_descriptor, 355 data->interpreted_size, common_special_chars); 356 357 break; 358 359 case REG_RESOURCE_REQUIREMENTS_LIST: 360 return quote_buffer(data->interpreted.resource_requirements_list, 361 data->interpreted_size, common_special_chars); 362 363 break; 364 365 case REG_BINARY: 366 return quote_buffer(data->interpreted.binary, data->interpreted_size, 367 common_special_chars); 368 369 break; 370 371 default: 372 /* This shouldn't happen, since the regfi routines won't interpret 373 * unknown types, but just as a safety measure against library changes... 268 374 */ 269 cur_quoted = quote_unicode(datap, len, common_special_chars, &tmp_err);270 if(cur_quoted == NULL)271 {272 if(tmp_err == NULL && (*error_msg = (char*)malloc(49)) != NULL)273 strcpy(*error_msg, "Buffer could not be quoted due to unknown error.");274 else if((*error_msg = (char*)malloc(42+strlen(tmp_err))) != NULL)275 {276 sprintf(*error_msg, "Buffer could not be quoted due to error: %s",277 tmp_err);278 free(tmp_err);279 }280 }281 else if (tmp_err != NULL)282 *error_msg = tmp_err;283 return cur_quoted;284 break;285 286 case REG_DWORD:287 ascii_max = sizeof(char)*(8+2+1);288 ascii = malloc(ascii_max);289 if(ascii == NULL)290 return NULL;291 292 snprintf(ascii, ascii_max, "0x%.2X%.2X%.2X%.2X",293 datap[3], datap[2], datap[1], datap[0]);294 return ascii;295 break;296 297 case REG_DWORD_BE:298 ascii_max = sizeof(char)*(8+2+1);299 ascii = malloc(ascii_max);300 if(ascii == NULL)301 return NULL;302 303 snprintf(ascii, ascii_max, "0x%.2X%.2X%.2X%.2X",304 datap[0], datap[1], datap[2], datap[3]);305 return ascii;306 break;307 308 case REG_QWORD:309 ascii_max = sizeof(char)*(16+2+1);310 ascii = malloc(ascii_max);311 if(ascii == NULL)312 return NULL;313 314 snprintf(ascii, ascii_max, "0x%.2X%.2X%.2X%.2X%.2X%.2X%.2X%.2X",315 datap[7], datap[6], datap[5], datap[4],316 datap[3], datap[2], datap[1], datap[0]);317 return ascii;318 break;319 320 case REG_MULTI_SZ:321 ascii_max = sizeof(char)*(len*4+1);322 ascii_tmp = malloc(ascii_max);323 if(ascii_tmp == NULL)324 return NULL;325 326 /* Attempt to convert entire string from UTF-16LE to ASCII,327 * then parse and quote fields individually.328 * If this fails, simply quote entire buffer as binary.329 */330 ret_err = uni_to_ascii(datap, ascii_tmp, len, ascii_max);331 if(ret_err < 0)332 {333 tmp_err = strerror(-ret_err);334 *error_msg = (char*)malloc(61+strlen(tmp_err));335 if(*error_msg == NULL)336 {337 free(ascii_tmp);338 return NULL;339 }340 341 sprintf(*error_msg, "MULTI_SZ unicode conversion"342 " failed with '%s'. Quoting as binary.", tmp_err);343 ascii = quote_buffer(datap, len, subfield_special_chars);344 }345 else346 {347 ascii = malloc(ascii_max);348 if(ascii == NULL)349 {350 free(ascii_tmp);351 return NULL;352 }353 asciip = ascii;354 asciip[0] = '\0';355 str_rem = ascii_max;356 delim = "";357 for(i=0; i<ret_err; i+=cur_str_len+1)358 {359 cur_str_len = strlen(ascii_tmp+i);360 if(ascii_tmp[i] != '\0')361 {362 cur_quoted = quote_string(ascii_tmp+i, subfield_special_chars);363 if(cur_quoted != NULL)364 {365 alen = snprintf(asciip, str_rem, "%s%s", delim, cur_quoted);366 asciip += alen;367 str_rem -= alen;368 free(cur_quoted);369 }370 }371 delim = "|";372 }373 }374 375 free(ascii_tmp);376 return ascii;377 break;378 379 /* XXX: Dont know what to do with these yet, just print as binary... */380 default:381 375 *error_msg = (char*)malloc(65); 382 376 if(*error_msg == NULL) … … 384 378 sprintf(*error_msg, 385 379 "Unrecognized registry data type (0x%.8X); quoting as binary.", 386 type); 380 data->type); 381 return quote_buffer(data->raw, data->size, common_special_chars); 382 } 387 383 388 case REG_NONE:389 case REG_RESOURCE_LIST:390 case REG_FULL_RESOURCE_DESCRIPTOR:391 case REG_RESOURCE_REQUIREMENTS_LIST:392 393 case REG_BINARY:394 return quote_buffer(datap, len, common_special_chars);395 break;396 }397 398 384 return NULL; 399 385 } -
trunk/src/reglookup-recover.c
r157 r159 111 111 char* conv_error = NULL; 112 112 const char* str_type = NULL; 113 uint32 size = vk->data_size; 114 115 /* Microsoft's documentation indicates that "available memory" is 116 * the limit on value sizes. Annoying. We limit it to 1M which 117 * should rarely be exceeded, unless the file is corrupt or 118 * malicious. For more info, see: 119 * http://msdn2.microsoft.com/en-us/library/ms724872.aspx 120 */ 121 /* XXX: Should probably do something different here for this tool. 122 * Also, It would be really nice if this message somehow included the 123 * name of the current value we're having trouble with, since 124 * stderr/stdout don't always sync nicely. 125 */ 126 if(size > REGFI_VK_MAX_DATA_LENGTH) 127 { 128 fprintf(stderr, "WARN: value data size %d larger than " 129 "%d, truncating...\n", size, REGFI_VK_MAX_DATA_LENGTH); 130 size = REGFI_VK_MAX_DATA_LENGTH; 131 } 132 113 133 114 quoted_name = quote_string(vk->valuename, key_special_chars); 134 115 if (quoted_name == NULL) … … 144 125 quoted_name[0] = '\0'; 145 126 } 146 147 quoted_value = data_to_ascii(vk->data, size, vk->type, &conv_error); 127 /* XXX: Add command line option to choose output encoding */ 128 if(vk->data != NULL 129 && !regfi_interpret_data(f, "US-ASCII//TRANSLIT", vk->type, vk->data)) 130 { 131 fprintf(stderr, "WARN: Error occurred while interpreting data for VK record" 132 " at offset 0x%.8X.\n", vk->offset); 133 } 134 printMsgs(f); 135 136 quoted_value = data_to_ascii(vk->data, &conv_error); 148 137 if(quoted_value == NULL) 149 138 { … … 469 458 return 10; 470 459 460 data.buf = NULL; 461 data.len = 0; 471 462 for(i=0; i<range_list_size(unalloc_values); i++) 472 463 { … … 571 562 } 572 563 } 573 574 vk->data = data.buf; 575 vk->data_size = data.len; 564 /* XXX: Need to come up with a different way to link these so the 565 * vk->data item can be removed from the structure. 566 */ 567 vk->data = regfi_buffer_to_data(data); 568 talloc_steal(vk, vk->data); 576 569 } 577 570 } -
trunk/src/reglookup.c
r158 r159 50 50 51 51 52 void printValue(const REGFI_VK_REC* vk, char* prefix) 53 { 52 void printValue(REGFI_ITERATOR* iter, const REGFI_VK_REC* vk, char* prefix) 53 { 54 REGFI_DATA* data; 54 55 char* quoted_value = NULL; 55 56 char* quoted_name = NULL; 56 57 char* conv_error = NULL; 57 58 const char* str_type = NULL; 58 uint32 size = vk->data_size; 59 60 /* Microsoft's documentation indicates that "available memory" is 61 * the limit on value sizes. Annoying. We limit it to 1M which 62 * should rarely be exceeded, unless the file is corrupt or 63 * malicious. For more info, see: 64 * http://msdn2.microsoft.com/en-us/library/ms724872.aspx 65 */ 66 if(size > REGFI_VK_MAX_DATA_LENGTH) 67 { 68 fprintf(stderr, "WARN: value data size %d larger than " 69 "%d, truncating...\n", size, REGFI_VK_MAX_DATA_LENGTH); 70 size = REGFI_VK_MAX_DATA_LENGTH; 71 } 72 59 73 60 quoted_name = quote_string(vk->valuename, key_special_chars); 74 61 if (quoted_name == NULL) … … 84 71 quoted_name[0] = '\0'; 85 72 } 86 87 if(vk->data == NULL) 88 { 89 if(print_verbose) 90 fprintf(stderr, "INFO: While quoting value for '%s/%s', " 91 "data pointer was NULL.\n", prefix, quoted_name); 92 } 93 else 94 { 95 quoted_value = data_to_ascii(vk->data, size, vk->type, &conv_error); 73 74 data = regfi_iterator_fetch_data(iter, vk); 75 76 printMsgs(iter->f); 77 if(data != NULL) 78 { 79 quoted_value = data_to_ascii(data, &conv_error); 96 80 if(quoted_value == NULL) 97 81 { … … 103 87 "Returned error: %s\n", prefix, quoted_name, conv_error); 104 88 } 105 else if(conv_error != NULL && print_verbose)106 fprintf(stderr, " INFO: While quoting value for '%s/%s', "89 else if(conv_error != NULL) 90 fprintf(stderr, "WARN: While quoting value for '%s/%s', " 107 91 "warning returned: %s\n", prefix, quoted_name, conv_error); 92 regfi_free_data(data); 108 93 } 109 94 … … 281 266 { 282 267 if(!type_filter_enabled || (value->type == type_filter)) 283 printValue( value, prefix);268 printValue(iter, value, prefix); 284 269 regfi_free_value(value); 285 270 value = regfi_iterator_next_value(iter); … … 511 496 512 497 if(!type_filter_enabled || (value->type == type_filter)) 513 printValue( value, tmp_path_joined);498 printValue(iter, value, tmp_path_joined); 514 499 515 500 regfi_free_value(value); … … 632 617 regfi_set_message_mask(f, REGFI_MSG_INFO|REGFI_MSG_WARN|REGFI_MSG_ERROR); 633 618 634 iter = regfi_iterator_new(f); 619 /* XXX: add command line option to choose output encoding */ 620 iter = regfi_iterator_new(f, 0); 635 621 if(iter == NULL) 636 622 {
Note: See TracChangeset
for help on using the changeset viewer.