Browse code

Yara hex string parsing, phase 2: Stuff the strings.

Shawn Webb authored on 2014/10/28 08:01:01
Showing 1 changed files
... ...
@@ -2654,7 +2654,7 @@ static char **parse_yara_hex_string(YR_STRING *string)
2654 2654
     char **res=NULL, **tres;
2655 2655
     size_t nres=1, tnres, slen, *ssizes=NULL, *tssizes;
2656 2656
     char *str, *p1, *p2, *p3;
2657
-    size_t i;
2657
+    size_t i, j;
2658 2658
     unsigned long m, n;
2659 2659
 
2660 2660
     if (!(string) || !(string->string))
... ...
@@ -2663,7 +2663,7 @@ static char **parse_yara_hex_string(YR_STRING *string)
2663 2663
     if (!STRING_IS_HEX(string))
2664 2664
         return NULL;
2665 2665
 
2666
-    str = string->string;
2666
+    str = (char *)(string->string);
2667 2667
     slen = strlen(str);
2668 2668
 
2669 2669
     /* First calculate how many strings we need and how long each string needs to be */
... ...
@@ -2721,7 +2721,7 @@ static char **parse_yara_hex_string(YR_STRING *string)
2721 2721
 
2722 2722
             if (n - m == 0) {
2723 2723
                 for (i=0; i < nres; i++)
2724
-                    ssizes[nres] += m * 2;
2724
+                    ssizes[nres]++; /* [n-n] behaves as a match-all wildcard (*) */
2725 2725
                 p1 = p3;
2726 2726
                 break;
2727 2727
             }
... ...
@@ -2768,9 +2768,73 @@ static char **parse_yara_hex_string(YR_STRING *string)
2768 2768
         p1++;
2769 2769
     }
2770 2770
 
2771
+    /* Allocate the space needed for the strings */
2772
+    res = cli_calloc(nres+1, sizeof(char **)); /* +1 for terminating NULL */
2773
+    if (!(res))
2774
+        goto err;
2775
+
2776
+    for (i=0; i<nres; i++) {
2777
+        res[i] = cli_calloc(ssizes[i]+1, 1);
2778
+        if (!(res[i]))
2779
+            goto err;
2780
+    }
2781
+
2782
+    /* Copy over the strings */
2783
+    tnres=1;
2784
+    p1 = strchr(str, '{')+1;
2785
+    while ((size_t)(p1 - str) < slen-1) {
2786
+        switch (*p1) {
2787
+        case ' ':
2788
+        case '\n':
2789
+        case '\r':
2790
+        case '\t':
2791
+            break;
2792
+        case '[':
2793
+            p2 = p1+1;
2794
+            for (p2 = p1+1; (size_t)(p2 - str) < slen; p2++)
2795
+                if (*p2 == ']')
2796
+                    break;
2797
+
2798
+            for (p3 = p1+1; p3 < p2; p3++)
2799
+                if (*p3 == '-')
2800
+                    break;
2801
+
2802
+            m = strtoul(p1+1, &p3, 10);
2803
+            if (m == 0 && errno == ERANGE)
2804
+                goto err;
2805
+
2806
+            n = strtoul(p3+1, &p3, 10);
2807
+
2808
+            if (m > n)
2809
+                goto err;
2810
+
2811
+            if (n - m == 0) {
2812
+                for (i=0; i < nres; i++)
2813
+                    res[i][strlen(res[i])-1] = '*';
2814
+                p1 = p3;
2815
+                break;
2816
+            }
2817
+
2818
+            tnres += n - m;
2819
+            for (i=1; i <= tnres; i++) {
2820
+                for (j=0; j<i; j++)
2821
+                    sprintf(res[i-1]+strlen(res[i-1]), "??");
2822
+            }
2823
+
2824
+            p1=p3;
2825
+            break;
2826
+        default:
2827
+            for (i=0; i < nres; i++)
2828
+                res[i][strlen(res[i])] = *p1;
2829
+            break;
2830
+        }
2831
+
2832
+        p1++;
2833
+    }
2834
+
2771 2835
     cli_errmsg("Yara string \"%s\" has %zu substrings\n", str, nres);
2772 2836
     for (i = 0; i < nres; i++) {
2773
-        cli_errmsg("    len(substring[%zu]) = %zu\n", i, ssizes[i]);
2837
+        cli_errmsg("    substring[%zu] (%zu:%zu): \"%s\"\n", i, ssizes[i], strlen(res[i]), res[i]);
2774 2838
     }
2775 2839
 
2776 2840
     return NULL;