Browse code

sigtool: --decode-sigs; decode .db entries (bb#1246)

Tomasz Kojm authored on 2009/11/24 07:18:59
Showing 3 changed files
... ...
@@ -1,3 +1,7 @@
1
+Mon Nov 23 23:15:38 CET 2009 (tk)
2
+---------------------------------
3
+ * sigtool: --decode-sigs; decode .db entries (bb#1246)
4
+
1 5
 Thu Nov 19 14:10:17 CET 2009 (tk)
2 6
 ---------------------------------
3 7
  * sigtool/sigtool.c: handle .ign2 files (bb#1625)
... ...
@@ -107,6 +107,7 @@ const struct clam_option __clam_options[] = {
107 107
     { NULL, "info", 'i', TYPE_STRING, NULL, -1, NULL, 0, OPT_SIGTOOL, "", "" },
108 108
     { NULL, "list-sigs", 'l', TYPE_STRING, NULL, -1, DATADIR, 0, OPT_SIGTOOL, "", "" },
109 109
     { NULL, "find-sigs", 'f', TYPE_STRING, NULL, -1, DATADIR, FLAG_REQUIRED, OPT_SIGTOOL, "", "" },
110
+    { NULL, "decode-sigs", 0, TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_SIGTOOL, "", "" },
110 111
     { NULL, "vba", 0, TYPE_STRING, NULL, -1, NULL, 0, OPT_SIGTOOL, "", "" },
111 112
     { NULL, "vba-hex", 0, TYPE_STRING, NULL, -1, NULL, 0, OPT_SIGTOOL, "", "" },
112 113
     { NULL, "diff", 'd', TYPE_STRING, NULL, -1, NULL, 0, OPT_SIGTOOL, "", "" },
... ...
@@ -1043,7 +1043,6 @@ static int listdb(const char *filename, const regex_t *regex)
1043 1043
 	FILE *fh;
1044 1044
 	char *buffer, *pt, *start, *dir;
1045 1045
 	unsigned int line = 0;
1046
-	const char *tmpdir;
1047 1046
 
1048 1047
 
1049 1048
     if((fh = fopen(filename, "rb")) == NULL) {
... ...
@@ -1628,7 +1627,7 @@ static int verifydiff(const char *diff, const char *cvd, const char *incdir)
1628 1628
     return ret;
1629 1629
 }
1630 1630
 
1631
-static char *decodesubhex(const char *hex)
1631
+static char *decodehexstr(const char *hex)
1632 1632
 {
1633 1633
 	uint16_t *str16;
1634 1634
 	char *decoded;
... ...
@@ -1642,44 +1641,53 @@ static char *decodesubhex(const char *hex)
1642 1642
 	if(str16[i] & CLI_MATCH_WILDCARD)
1643 1643
 	    wildcard++;
1644 1644
 
1645
-    decoded = calloc(len + wildcard * 32, sizeof(char));
1645
+    decoded = calloc(len + 1 + wildcard * 32, sizeof(char));
1646 1646
 
1647 1647
     for(i = 0; i < len; i++) {
1648 1648
 	if(str16[i] & CLI_MATCH_WILDCARD) {
1649 1649
 	    switch(str16[i] & CLI_MATCH_WILDCARD) {
1650 1650
 		case CLI_MATCH_IGNORE:
1651
+		    p += sprintf(decoded + p, "{WILDCARD_IGNORE@%u}", i);
1652
+		    break;
1653
+
1651 1654
 		case CLI_MATCH_SPECIAL:
1655
+		    p += sprintf(decoded + p, "{WILDCARD_SPECIAL@%u:<!TODO!>}", i);
1656
+		    break;
1657
+
1652 1658
 		case CLI_MATCH_NIBBLE_HIGH:
1659
+		    p += sprintf(decoded + p, "{WILDCARD_NIBBLE_HIGH@%u:0x%x}", i, str16[i] & 0x00f0);
1660
+		    break;
1661
+
1653 1662
 		case CLI_MATCH_NIBBLE_LOW:
1654
-		    /* TODO */        
1655
-		    strcat(decoded, "<WILDCARD>");
1656
-		    p += 10;
1663
+		    p += sprintf(decoded + p, "{WILDCARD_NIBBLE_LOW@%u:0x%x}", i, str16[i] & 0x000f);
1664
+		    break;
1665
+
1657 1666
 		default:
1658
-		    mprintf("!decodesubhex: Unknown wildcard\n");
1667
+		    mprintf("!decodehexstr: Unknown wildcard (0x%x)\n", str16[i] & CLI_MATCH_WILDCARD);
1659 1668
 		    free(decoded);
1660 1669
 		    return NULL;
1661 1670
 	    }
1662 1671
 	} else {
1663 1672
 	    decoded[p] = str16[i];
1673
+	    p++;
1664 1674
 	}
1665 1675
     }
1666 1676
 
1667 1677
     return decoded;
1668 1678
 }
1669 1679
 
1670
-static char *decodehex(const char *hexsig)
1680
+static int decodehex(const char *hexsig)
1671 1681
 {
1672 1682
 	char *pt, *hexcpy, *start, *n;
1673
-	int ret, asterisk = 0;
1683
+	int asterisk = 0;
1674 1684
 	unsigned int i, j, hexlen, parts = 0;
1675 1685
 	int mindist = 0, maxdist = 0, error = 0;
1676
-	char *decoded = NULL;
1677 1686
 
1678 1687
 
1679 1688
     hexlen = strlen(hexsig);
1680 1689
     if(strchr(hexsig, '{')) {
1681 1690
 	if(!(hexcpy = cli_strdup(hexsig)))
1682
-	    return NULL;
1691
+	    return -1;
1683 1692
 
1684 1693
 	for(i = 0; i < hexlen; i++)
1685 1694
 	    if(hexsig[i] == '{' || hexsig[i] == '*')
... ...
@@ -1706,13 +1714,24 @@ static char *decodehex(const char *hexsig)
1706 1706
 		*pt++ = 0;
1707 1707
 	    }
1708 1708
 
1709
-	    /* if(mindist) MINDIST if(maxdist) MAXDIST */
1710
-	    mprintf("%s ", decodesubhex(start));
1711
-	    /* if(asterisk) <ANY-BYTES> */
1709
+	    if(mindist && maxdist) {
1710
+		if(mindist == maxdist)
1711
+		    mprintf("{WILDCARD_ANY_STRING(LENGTH==%u)}", mindist);
1712
+		else
1713
+		    mprintf("{WILDCARD_ANY_STRING(LENGTH>=%u&&<=%u)}", mindist, maxdist);
1714
+	    } else if(mindist)
1715
+		mprintf("{WILDCARD_ANY_STRING(LENGTH>=%u)}", mindist);
1716
+	    else if(maxdist)
1717
+		mprintf("{WILDCARD_ANY_STRING(LENGTH<=%u)}", maxdist);
1718
+
1719
+	    mprintf("%s", decodehexstr(start));
1712 1720
 
1713 1721
 	    if(i == parts)
1714 1722
 		break;
1715 1723
 
1724
+	    if(asterisk)
1725
+		mprintf("{WILDCARD_ANY_STRING}");
1726
+
1716 1727
 	    mindist = maxdist = 0;
1717 1728
 
1718 1729
 	    if(asterisk) {
... ...
@@ -1765,7 +1784,7 @@ static char *decodehex(const char *hexsig)
1765 1765
 
1766 1766
 	free(hexcpy);
1767 1767
 	if(error)
1768
-	    return NULL;
1768
+	    return -1;
1769 1769
 
1770 1770
     } else if(strchr(hexsig, '*')) {
1771 1771
 	for(i = 0; i < hexlen; i++)
... ...
@@ -1778,24 +1797,25 @@ static char *decodehex(const char *hexsig)
1778 1778
 	for(i = 1; i <= parts; i++) {
1779 1779
 	    if((pt = cli_strtok(hexsig, i - 1, "*")) == NULL) {
1780 1780
 		mprintf("!Can't extract part %u of partial signature\n", i);
1781
-		return NULL;
1781
+		return -1;
1782 1782
 	    }
1783
-
1784
-	    mprintf("%s ", decodesubhex(pt));
1785
-	    /* if(i < parts) printf("<MATCH-ANY-STRING>") */
1783
+	    mprintf("%s", decodehexstr(pt));
1784
+	    if(i < parts)
1785
+		mprintf("{WILDCARD_ANY_STRING}");
1786 1786
 	    free(pt);
1787 1787
 	}
1788 1788
 
1789 1789
     } else {
1790
-	mprintf("%s ", decodesubhex(hexsig));
1790
+	mprintf("%s", decodehexstr(hexsig));
1791 1791
     }
1792 1792
 
1793
-    return decoded;
1793
+    mprintf("\n");
1794
+    return 0;
1794 1795
 }
1795 1796
 
1796
-static int decodesig(const char *sig)
1797
+static int decodesig(char *sig)
1797 1798
 {
1798
-	const char *pt;
1799
+	char *pt;
1799 1800
 
1800 1801
     if(strchr(sig, ';')) { /* lsig */
1801 1802
 	mprintf("decodesig: Not supported signature format (yet)\n");
... ...
@@ -1804,11 +1824,31 @@ static int decodesig(const char *sig)
1804 1804
 	mprintf("decodesig: Not supported signature format (yet)\n");
1805 1805
 	return -1;
1806 1806
     } else if((pt = strchr(sig, '='))) {
1807
-	mprintf("%s\n", decodehex(pt + 1));
1807
+	*pt++ = 0;
1808
+	mprintf("VIRUS NAME: %s\n", sig);
1809
+	mprintf("DECODED SIGNATURE:\n");
1810
+	decodehex(pt);
1808 1811
     } else {
1809 1812
 	mprintf("decodesig: Not supported signature format\n");
1810 1813
 	return -1;
1811 1814
     }
1815
+
1816
+    return 0;
1817
+}
1818
+
1819
+static int decodesigs(void)
1820
+{
1821
+	char buffer[32769];
1822
+
1823
+    fflush(stdin);
1824
+    while(fgets(buffer, sizeof(buffer), stdin)) {
1825
+	cli_chomp(buffer);
1826
+	if(!strlen(buffer))
1827
+	    break;
1828
+	if(decodesig(buffer) == -1)
1829
+	    return -1;
1830
+    }
1831
+    return 0;
1812 1832
 }
1813 1833
 
1814 1834
 static int diffdirs(const char *old, const char *new, const char *patch)
... ...
@@ -2016,6 +2056,7 @@ static void help(void)
2016 2016
     mprintf("    --unpack-current=SHORTNAME             Unpack local CVD/CLD into cwd\n");
2017 2017
     mprintf("    --list-sigs[=FILE]     -l[FILE]        List signature names\n");
2018 2018
     mprintf("    --find-sigs=REGEX      -fREGEX         Find signatures matching REGEX\n");
2019
+    mprintf("    --decode-sigs                          Decode signatures from stdin\n");
2019 2020
     mprintf("    --vba=FILE                             Extract VBA/Word6 macro code\n");
2020 2021
     mprintf("    --vba-hex=FILE                         Extract Word6 macro code with hex values\n");
2021 2022
     mprintf("    --diff=OLD NEW         -d OLD NEW      Create diff for OLD and NEW CVDs\n");
... ...
@@ -2081,6 +2122,8 @@ int main(int argc, char **argv)
2081 2081
 	ret = listsigs(opts, 0);
2082 2082
     else if(optget(opts, "find-sigs")->active)
2083 2083
 	ret = listsigs(opts, 1);
2084
+    else if(optget(opts, "decode-sigs")->active)
2085
+	ret = decodesigs();
2084 2086
     else if(optget(opts, "vba")->enabled || optget(opts, "vba-hex")->enabled)
2085 2087
 	ret = vbadump(opts);
2086 2088
     else if(optget(opts, "diff")->enabled)