... | ... |
@@ -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) |