- Timestamp:
- 12/06/09 15:09:01 (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
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;
Note: See TracChangeset
for help on using the changeset viewer.