Browse code

imphash: refactor code for scanning and sigtool usage

Kevin Lin authored on 2016/07/01 06:29:49
Showing 3 changed files
... ...
@@ -232,6 +232,10 @@ int cli_hm_have_wild(const struct cli_matcher *root, enum CLI_HASH_TYPE type) {
232 232
     return (root && root->hwild.hashes[type].items);
233 233
 }
234 234
 
235
+int cli_hm_have_any(const struct cli_matcher *root, enum CLI_HASH_TYPE type) {
236
+    return (root && (root->hwild.hashes[type].items || root->hm.sizehashes[type].capacity));
237
+}
238
+
235 239
 /* cli_hm_scan will scan only size-specific hashes, if any */
236 240
 static int hm_scan(const unsigned char *digest, const char **virname, const struct cli_sz_hash *szh, enum CLI_HASH_TYPE type) {
237 241
     unsigned int keylen;
... ...
@@ -64,6 +64,7 @@ int cli_hm_scan(const unsigned char *digest, uint32_t size, const char **virname
64 64
 int cli_hm_scan_wild(const unsigned char *digest, const char **virname, const struct cli_matcher *root, enum CLI_HASH_TYPE type);
65 65
 int cli_hm_have_size(const struct cli_matcher *root, enum CLI_HASH_TYPE type, uint32_t size);
66 66
 int cli_hm_have_wild(const struct cli_matcher *root, enum CLI_HASH_TYPE type);
67
+int cli_hm_have_any(const struct cli_matcher *root, enum CLI_HASH_TYPE type);
67 68
 void hm_free(struct cli_matcher *root);
68 69
 
69 70
 #endif
... ...
@@ -2172,8 +2172,6 @@ static int validate_impname(const char *name, uint32_t length, int dll)
2172 2172
     uint32_t i = 0;
2173 2173
     const char *c = name;
2174 2174
 
2175
-    cli_dbgmsg("%s\n", name);
2176
-
2177 2175
     if (!name || length == 0)
2178 2176
         return CL_SUCCESS;
2179 2177
 
... ...
@@ -2193,23 +2191,25 @@ static int validate_impname(const char *name, uint32_t length, int dll)
2193 2193
     return CL_SUCCESS;
2194 2194
 }
2195 2195
 
2196
-static inline int scan_pe_impfuncs(cli_ctx *ctx, void *md5ctx, uint32_t *itsz, struct pe_image_import_descriptor *image, char *dllname, struct cli_exe_section *exe_sections, uint16_t nsections, uint32_t hdr_size, int pe_plus, int *first){
2197
-    uint32_t toff, offset;
2196
+static inline int hash_impfns(cli_ctx *ctx, void **hashctx, uint32_t *impsz, struct pe_image_import_descriptor *image, char *dllname, struct cli_exe_section *exe_sections, uint16_t nsections, uint32_t hdr_size, int pe_plus, int *first)
2197
+{
2198
+    uint32_t thuoff, offset;
2198 2199
     fmap_t *map = *ctx->fmap;
2199 2200
     size_t dlllen = 0, fsize = map->len;
2200
-    int i, j, err, num_funcs = 0;
2201
+    int i, j, err, num_fns = 0;
2201 2202
     const char *buffer;
2203
+    enum CLI_HASH_TYPE type;
2202 2204
 #if HAVE_JSON
2203 2205
     json_object *imptbl = NULL;
2204 2206
 #else
2205 2207
     void *imptbl = NULL;
2206 2208
 #endif
2207 2209
 
2208
-    toff = cli_rawaddr(image->u.OriginalFirstThunk, exe_sections, nsections, &err, fsize, hdr_size);
2210
+    thuoff = cli_rawaddr(image->u.OriginalFirstThunk, exe_sections, nsections, &err, fsize, hdr_size);
2209 2211
     if (err)
2210
-        toff = cli_rawaddr(image->FirstThunk, exe_sections, nsections, &err, fsize, hdr_size);
2212
+        thuoff = cli_rawaddr(image->FirstThunk, exe_sections, nsections, &err, fsize, hdr_size);
2211 2213
     if (err) {
2212
-        cli_dbgmsg("IMPTBL: invalid rva for image first thunk\n");
2214
+        cli_dbgmsg("scan_pe: invalid rva for image first thunk\n");
2213 2215
         return CL_SUCCESS;
2214 2216
     }
2215 2217
 
... ...
@@ -2217,13 +2217,13 @@ static inline int scan_pe_impfuncs(cli_ctx *ctx, void *md5ctx, uint32_t *itsz, s
2217 2217
     if (ctx->wrkproperty) {
2218 2218
         imptbl = cli_jsonarray(ctx->wrkproperty, "ImportTable");
2219 2219
         if (!imptbl) {
2220
-            cli_dbgmsg("IMPTBL: cannot allocate import table json object\n");
2220
+            cli_dbgmsg("scan_pe: cannot allocate import table json object\n");
2221 2221
             return CL_EMEM;
2222 2222
         }
2223 2223
     }
2224 2224
 #endif
2225 2225
 
2226
-#define update_hash()                                                   \
2226
+#define update_imphash()                                                \
2227 2227
     if (funcname) {                                                     \
2228 2228
         char *fname;                                                    \
2229 2229
         size_t funclen;                                                 \
... ...
@@ -2245,7 +2245,7 @@ static inline int scan_pe_impfuncs(cli_ctx *ctx, void *md5ctx, uint32_t *itsz, s
2245 2245
                                                                         \
2246 2246
         fname = cli_calloc(funclen + dlllen + 3, sizeof(char));         \
2247 2247
         if (fname == NULL) {                                            \
2248
-            cli_dbgmsg("IMPTBL: cannot allocate memory for imphash string\n"); \
2248
+            cli_dbgmsg("scan_pe: cannot allocate memory for imphash string\n"); \
2249 2249
             return CL_EMEM;                                             \
2250 2250
         }                                                               \
2251 2251
         j = 0;                                                          \
... ...
@@ -2262,8 +2262,9 @@ static inline int scan_pe_impfuncs(cli_ctx *ctx, void *md5ctx, uint32_t *itsz, s
2262 2262
             cli_jsonstr(imptbl, NULL, jname);                           \
2263 2263
         }                                                               \
2264 2264
                                                                         \
2265
-        cl_update_hash(md5ctx, fname, strlen(fname));                   \
2266
-        *itsz += strlen(fname);                                         \
2265
+        for(type = CLI_HASH_MD5; type < CLI_HASH_AVAIL_TYPES; type++)   \
2266
+            cl_update_hash(hashctx[type], fname, strlen(fname));        \
2267
+        *impsz += strlen(fname);                                        \
2267 2268
                                                                         \
2268 2269
         *first = 0;                                                     \
2269 2270
         free(fname);                                                    \
... ...
@@ -2273,10 +2274,9 @@ static inline int scan_pe_impfuncs(cli_ctx *ctx, void *md5ctx, uint32_t *itsz, s
2273 2273
     if (!pe_plus) {
2274 2274
         struct pe_image_thunk32 thunk32;
2275 2275
 
2276
-        while (fmap_readn(map, &thunk32, toff, sizeof(struct pe_image_thunk32)) == sizeof(struct pe_image_thunk32) &&
2277
-               thunk32.u.Ordinal != 0 && num_funcs < PE_MAXIMPORTS) {
2276
+        while ((num_fns < PE_MAXIMPORTS) && (fmap_readn(map, &thunk32, thuoff, sizeof(struct pe_image_thunk32)) == sizeof(struct pe_image_thunk32)) && (thunk32.u.Ordinal != 0)) {
2278 2277
             char *funcname = NULL;
2279
-            toff += sizeof(struct pe_image_thunk32);
2278
+            thuoff += sizeof(struct pe_image_thunk32);
2280 2279
 
2281 2280
             if (!(thunk32.u.Ordinal & IMAGE_ORDINAL_FLAG32)) {
2282 2281
                 offset = cli_rawaddr(thunk32.u.Function, exe_sections, nsections, &err, fsize, hdr_size);
... ...
@@ -2286,7 +2286,7 @@ static inline int scan_pe_impfuncs(cli_ctx *ctx, void *md5ctx, uint32_t *itsz, s
2286 2286
                     if ((buffer = fmap_need_off_once(map, offset+sizeof(uint16_t), MIN(PE_MAXNAMESIZE, fsize-offset))) != NULL) {
2287 2287
                         funcname = strndup(buffer, MIN(PE_MAXNAMESIZE, fsize-offset));
2288 2288
                         if (funcname == NULL) {
2289
-                            cli_dbgmsg("IMPTBL: cannot duplicate function name\n");
2289
+                            cli_dbgmsg("scan_pe: cannot duplicate function name\n");
2290 2290
                             return CL_EMEM;
2291 2291
                         }
2292 2292
                     }
... ...
@@ -2295,20 +2295,19 @@ static inline int scan_pe_impfuncs(cli_ctx *ctx, void *md5ctx, uint32_t *itsz, s
2295 2295
                 /* ordinal lookup */
2296 2296
                 funcname = pe_ordinal(dllname, thunk32.u.Ordinal & 0xFFFF);
2297 2297
                 if (funcname == NULL) {
2298
-                    cli_dbgmsg("IMPTBL: cannot duplicate function name\n");
2298
+                    cli_dbgmsg("scan_pe: cannot duplicate function name\n");
2299 2299
                     return CL_EMEM;
2300 2300
                 }
2301 2301
             }
2302 2302
 
2303
-            update_hash();
2303
+            update_imphash();
2304 2304
         }
2305 2305
     } else {
2306 2306
         struct pe_image_thunk64 thunk64;
2307 2307
 
2308
-        while (fmap_readn(map, &thunk64, toff, sizeof(struct pe_image_thunk64)) == sizeof(struct pe_image_thunk64) &&
2309
-               thunk64.u.Ordinal != 0 && num_funcs < PE_MAXIMPORTS) {
2308
+        while ((num_fns < PE_MAXIMPORTS) && (fmap_readn(map, &thunk64, thuoff, sizeof(struct pe_image_thunk64)) == sizeof(struct pe_image_thunk64)) && (thunk64.u.Ordinal != 0)) {
2310 2309
             char *funcname = NULL;
2311
-            toff += sizeof(struct pe_image_thunk64);
2310
+            thuoff += sizeof(struct pe_image_thunk64);
2312 2311
 
2313 2312
             if (!(thunk64.u.Ordinal & IMAGE_ORDINAL_FLAG32)) {
2314 2313
                 offset = cli_rawaddr(thunk64.u.Function, exe_sections, nsections, &err, fsize, hdr_size);
... ...
@@ -2318,7 +2317,7 @@ static inline int scan_pe_impfuncs(cli_ctx *ctx, void *md5ctx, uint32_t *itsz, s
2318 2318
                     if ((buffer = fmap_need_off_once(map, offset+sizeof(uint16_t), MIN(PE_MAXNAMESIZE, fsize-offset))) != NULL) {
2319 2319
                         funcname = strndup(buffer, MIN(PE_MAXNAMESIZE, fsize-offset));
2320 2320
                         if (funcname == NULL) {
2321
-                            cli_dbgmsg("IMPTBL: cannot duplicate function name\n");
2321
+                            cli_dbgmsg("scan_pe: cannot duplicate function name\n");
2322 2322
                             return CL_EMEM;
2323 2323
                         }
2324 2324
                     }
... ...
@@ -2327,89 +2326,108 @@ static inline int scan_pe_impfuncs(cli_ctx *ctx, void *md5ctx, uint32_t *itsz, s
2327 2327
                 /* ordinal lookup */
2328 2328
                 funcname = cli_strdup(pe_ordinal(dllname, thunk64.u.Ordinal & 0xFFFF));
2329 2329
                 if (funcname == NULL) {
2330
-                    cli_dbgmsg("IMPTBL: cannot duplicate function name\n");
2330
+                    cli_dbgmsg("scan_pe: cannot duplicate function name\n");
2331 2331
                     return CL_EMEM;
2332 2332
                 }
2333 2333
             }
2334 2334
 
2335
-            update_hash();
2335
+            update_imphash();
2336 2336
         }
2337 2337
     }
2338 2338
 
2339 2339
     return CL_SUCCESS;
2340 2340
 }
2341 2341
 
2342
-static int scan_pe_imptbl(cli_ctx *ctx, struct pe_image_data_dir *dirs, struct cli_exe_section *exe_sections, uint16_t nsections, uint32_t hdr_size, int pe_plus) {
2343
-    struct cli_matcher *imp = ctx->engine->hm_imp;
2344
-    struct pe_image_data_dir *datadir = &(dirs[1]);
2342
+static unsigned int hash_imptbl(cli_ctx *ctx, unsigned char **digest, uint32_t *impsz, int *genhash, struct pe_image_data_dir *datadir, struct cli_exe_section *exe_sections, uint16_t nsections, uint32_t hdr_size, int pe_plus)
2343
+{
2345 2344
     struct pe_image_import_descriptor *image;
2346 2345
     fmap_t *map = *ctx->fmap;
2347 2346
     size_t left, fsize = map->len;
2348
-    uint32_t impoff, offset, itsz = 0;
2349
-    const char *impdes, *buffer, *virname;
2350
-    void *md5ctx;
2351
-    uint8_t digest[16] = {0};
2352
-    int i, err, ret = CL_SUCCESS, num_imports = 0, first = 1;
2353
-
2354
-    if (datadir->VirtualAddress == 0 || datadir->Size == 0) {
2355
-        cli_dbgmsg("IMPTBL: import table data directory does not exist\n");
2347
+    uint32_t impoff, offset;
2348
+    const char *impdes, *buffer;
2349
+    void *hashctx[CLI_HASH_AVAIL_TYPES];
2350
+    enum CLI_HASH_TYPE type;
2351
+    int ret, err, nimps = 0;
2352
+    int first = 1;
2353
+
2354
+    if(datadir->VirtualAddress == 0 || datadir->Size == 0) {
2355
+        cli_errmsg("scan_pe: import table data directory does not exist\n");
2356 2356
         return CL_SUCCESS;
2357 2357
     }
2358 2358
 
2359 2359
     impoff = cli_rawaddr(datadir->VirtualAddress, exe_sections, nsections, &err, fsize, hdr_size);
2360
-    if (err || impoff + datadir->Size > fsize) {
2361
-        cli_dbgmsg("IMPTBL: invalid rva for import table data\n");
2360
+    if(err || impoff + datadir->Size > fsize) {
2361
+        cli_dbgmsg("scan_pe: invalid rva for import table data\n");
2362 2362
         return CL_SUCCESS;
2363 2363
     }
2364 2364
 
2365 2365
     impdes = fmap_need_off(map, impoff, datadir->Size);
2366
-    if (impdes == NULL) {
2367
-        cli_dbgmsg("IMPTBL: failed to acquire fmap buffer\n");
2366
+    if(impdes == NULL) {
2367
+        cli_dbgmsg("scan_pe: failed to acquire fmap buffer\n");
2368 2368
         return CL_EREAD;
2369 2369
     }
2370 2370
     left = datadir->Size;
2371 2371
 
2372
-    md5ctx = cl_hash_init("md5");
2373
-    if (md5ctx == NULL)
2374
-        return CL_EMEM;
2372
+    memset(hashctx, 0, sizeof(hashctx));
2373
+    if(genhash[CLI_HASH_MD5]) {
2374
+        hashctx[CLI_HASH_MD5] = cl_hash_init("md5");
2375
+        if (hashctx[CLI_HASH_MD5] == NULL)
2376
+            return CL_EMEM;
2377
+    }
2378
+    if(genhash[CLI_HASH_SHA1]) {
2379
+        hashctx[CLI_HASH_SHA1] = cl_hash_init("sha1");
2380
+        if (hashctx[CLI_HASH_SHA1] == NULL)
2381
+            return CL_EMEM;
2382
+    }
2383
+    if(genhash[CLI_HASH_SHA256]) {
2384
+        hashctx[CLI_HASH_SHA256] = cl_hash_init("sha256");
2385
+        if (hashctx[CLI_HASH_SHA256] == NULL)
2386
+            return CL_EMEM;
2387
+    }
2375 2388
 
2376 2389
     image = (struct pe_image_import_descriptor *)impdes;
2377
-    while(image->Name != 0 && num_imports < PE_MAXIMPORTS && left > sizeof(struct pe_image_import_descriptor)) {
2390
+    while(image->Name != 0 && nimps < PE_MAXIMPORTS && left > sizeof(struct pe_image_import_descriptor)) {
2378 2391
         char *dllname = NULL;
2379 2392
 
2380 2393
         left -= sizeof(struct pe_image_import_descriptor);
2381
-        num_imports++;
2394
+        nimps++;
2382 2395
 
2383 2396
         /* DLL name aquisition */
2384 2397
         offset = cli_rawaddr(image->Name, exe_sections, nsections, &err, fsize, hdr_size);
2385
-        if (err || offset > fsize) {
2386
-            cli_dbgmsg("IMPTBL: invalid rva for dll name\n");
2398
+        if(err || offset > fsize) {
2399
+            cli_dbgmsg("scan_pe: invalid rva for dll name\n");
2387 2400
             /* TODO: ignore or return? */
2388 2401
             /*
2389 2402
               image++;
2390 2403
               continue;
2391 2404
              */
2392
-            cl_hash_destroy(md5ctx);
2405
+            fmap_unneed_off(map, impoff, datadir->Size);
2406
+            for(type = CLI_HASH_MD5; type < CLI_HASH_AVAIL_TYPES; type++)
2407
+                cl_hash_destroy(hashctx[type]);
2393 2408
             return CL_SUCCESS; /* CL_EFORMAT? */
2394 2409
         }
2395 2410
 
2396
-        if ((buffer = fmap_need_off_once(map, offset, MIN(PE_MAXNAMESIZE, fsize-offset))) != NULL) {
2411
+        if((buffer = fmap_need_off_once(map, offset, MIN(PE_MAXNAMESIZE, fsize-offset))) != NULL) {
2397 2412
             if (validate_impname(dllname, MIN(PE_MAXNAMESIZE, fsize-offset), 1) != CL_SUCCESS)
2398 2413
                 break;
2399 2414
             dllname = strndup(buffer, MIN(PE_MAXNAMESIZE, fsize-offset));
2400 2415
             if (dllname == NULL) {
2401
-                cli_dbgmsg("IMPTBL: cannot duplicate dll name\n");
2402
-                cl_hash_destroy(md5ctx);
2416
+                cli_dbgmsg("scan_pe: cannot duplicate dll name\n");
2417
+                fmap_unneed_off(map, impoff, datadir->Size);
2418
+                for(type = CLI_HASH_MD5; type < CLI_HASH_AVAIL_TYPES; type++)
2419
+                    cl_hash_destroy(hashctx[type]);
2403 2420
                 return CL_EMEM;
2404 2421
             }
2405 2422
         }
2406 2423
 
2407 2424
         /* DLL function handling - inline function */
2408
-        ret = scan_pe_impfuncs(ctx, md5ctx, &itsz, image, dllname, exe_sections, nsections, hdr_size, pe_plus, &first);
2425
+        ret = hash_impfns(ctx, hashctx, impsz, image, dllname, exe_sections, nsections, hdr_size, pe_plus, &first);
2409 2426
         if (dllname)
2410 2427
             free(dllname);
2411 2428
         if (ret != CL_SUCCESS) {
2412
-            cl_hash_destroy(md5ctx);
2429
+            fmap_unneed_off(map, impoff, datadir->Size);
2430
+            for(type = CLI_HASH_MD5; type < CLI_HASH_AVAIL_TYPES; type++)
2431
+                cl_hash_destroy(hashctx[type]);
2413 2432
             return ret;
2414 2433
         }
2415 2434
 
... ...
@@ -2417,16 +2435,61 @@ static int scan_pe_imptbl(cli_ctx *ctx, struct pe_image_data_dir *dirs, struct c
2417 2417
     }
2418 2418
 
2419 2419
     fmap_unneed_off(map, impoff, datadir->Size);
2420
+    for(type = CLI_HASH_MD5; type < CLI_HASH_AVAIL_TYPES; type++)
2421
+        cl_finish_hash(hashctx[type], digest[type]);
2420 2422
 
2421
-    cl_finish_hash(md5ctx, digest);
2423
+    return CL_SUCCESS;
2424
+}
2422 2425
 
2426
+static int scan_pe_imp(cli_ctx *ctx, struct pe_image_data_dir *dirs, struct cli_exe_section *exe_sections, uint16_t nsections, uint32_t hdr_size, int pe_plus)
2427
+{
2428
+    struct cli_matcher *imp = ctx->engine->hm_imp;
2429
+    unsigned char *hashset[CLI_HASH_AVAIL_TYPES];
2430
+    const char *virname = NULL;
2431
+    int genhash[CLI_HASH_AVAIL_TYPES];
2432
+    uint32_t impsz = 0;
2433
+    enum CLI_HASH_TYPE type;
2434
+    int ret = CL_CLEAN;
2435
+
2436
+    /* pick hashtypes to generate */
2437
+    for(type = CLI_HASH_MD5; type < CLI_HASH_AVAIL_TYPES; type++) {
2438
+        genhash[type] = cli_hm_have_any(imp, type);
2439
+        hashset[type] = cli_malloc(hashlen[type]);
2440
+        if(!hashset[type]) {
2441
+            cli_errmsg("scan_pe: cli_malloc failed!\n");
2442
+            for(; type > 0;)
2443
+                free(hashset[--type]);
2444
+            return CL_EMEM;
2445
+        }
2446
+    }
2447
+
2448
+    /* Force md5 hash generation for debug and preclass */
2449
+#if HAVE_JSON
2450
+    if ((cli_debug_flag || ctx->wrkproperty) && !genhash[CLI_HASH_MD5]) {
2451
+#else
2452
+    if (cli_debug_flag && !genhash[CLI_HASH_MD5]) {
2453
+#endif
2454
+        genhash[CLI_HASH_MD5] = 1;
2455
+        hashset[CLI_HASH_MD5] = cli_malloc(hashlen[CLI_HASH_MD5]);
2456
+        if(!hashset[CLI_HASH_MD5]) {
2457
+            cli_errmsg("scan_pe: cli_malloc failed!\n");
2458
+            for(; type > 0;)
2459
+                free(hashset[--type]);
2460
+            return CL_EMEM;
2461
+        }
2462
+    }
2463
+
2464
+    /* Generate hashes */
2465
+    hash_imptbl(ctx, hashset, &impsz, genhash, &dirs[1], exe_sections, nsections, hdr_size, pe_plus);
2466
+
2467
+    /* Print hash */
2423 2468
 #if HAVE_JSON
2424 2469
     if (cli_debug_flag || ctx->wrkproperty) {
2425 2470
 #else
2426 2471
     if (cli_debug_flag) {
2427 2472
 #endif
2428
-        char *dstr = cli_str2hex(digest, sizeof(digest));
2429
-        cli_dbgmsg("IMPHASH: %s(%u)\n", dstr ? (char *)dstr : "(NULL)", itsz);
2473
+        char *dstr = cli_str2hex(hashset[CLI_HASH_MD5], hashlen[CLI_HASH_MD5]);
2474
+        cli_dbgmsg("IMP: %s:%u\n", dstr ? (char *)dstr : "(NULL)", impsz);
2430 2475
 #if HAVE_JSON
2431 2476
         if (ctx->wrkproperty)
2432 2477
             cli_jsonstr(ctx->wrkproperty, "Imphash", dstr ? dstr : "(NULL)");
... ...
@@ -2435,13 +2498,25 @@ static int scan_pe_imptbl(cli_ctx *ctx, struct pe_image_data_dir *dirs, struct c
2435 2435
             free(dstr);
2436 2436
     }
2437 2437
 
2438
-    if (imp) {
2439
-        if ((ret = cli_hm_scan(digest, itsz, &virname, imp, CLI_HASH_MD5)) == CL_VIRUS)
2438
+    /* Do scans */
2439
+    for(type = CLI_HASH_MD5; type < CLI_HASH_AVAIL_TYPES; type++) {
2440
+        if(cli_hm_scan(hashset[type], impsz, &virname, imp, type) == CL_VIRUS) {
2440 2441
             cli_append_virus(ctx, virname);
2441
-        else if ((ret = cli_hm_scan_wild(digest, &virname, imp, CLI_HASH_MD5)) == CL_VIRUS)
2442
+            ret = CL_VIRUS;
2443
+            if(!SCAN_ALL)
2444
+                break;
2445
+       }
2446
+       if(cli_hm_scan_wild(hashset[type], &virname, imp, type) == CL_VIRUS) {
2442 2447
             cli_append_virus(ctx, virname);
2448
+            ret = CL_VIRUS;
2449
+            if(!SCAN_ALL)
2450
+                break;
2451
+       }
2443 2452
     }
2444 2453
 
2454
+end:
2455
+    for(type = CLI_HASH_AVAIL_TYPES; type > 0;)
2456
+        free(hashset[--type]);
2445 2457
     return ret;
2446 2458
 }
2447 2459
 
... ...
@@ -3360,7 +3435,7 @@ int cli_scanpe(cli_ctx *ctx)
3360 3360
 #else
3361 3361
     if (DCONF & PE_CONF_IMPTBL && ctx->engine->hm_imp) {
3362 3362
 #endif
3363
-        ret = scan_pe_imptbl(ctx, dirs, exe_sections, nsections, hdr_size, pe_plus);
3363
+        ret = scan_pe_imp(ctx, dirs, exe_sections, nsections, hdr_size, pe_plus);
3364 3364
         switch (ret) {
3365 3365
             case CL_SUCCESS:
3366 3366
                 break;
... ...
@@ -5464,6 +5539,10 @@ int cli_genhash_pe(cli_ctx *ctx, unsigned int class, int type)
5464 5464
     struct pe_image_data_dir *dirs;
5465 5465
     fmap_t *map = *ctx->fmap;
5466 5466
 
5467
+    unsigned char *hash, *hashset[CLI_HASH_AVAIL_TYPES];
5468
+    int genhash[CLI_HASH_AVAIL_TYPES];
5469
+    int hlen = 0;
5470
+
5467 5471
     if (class >= CL_GENHASH_PE_CLASS_LAST)
5468 5472
         return CL_EARG;
5469 5473
 
... ...
@@ -5574,60 +5653,59 @@ int cli_genhash_pe(cli_ctx *ctx, unsigned int class, int type)
5574 5574
 
5575 5575
     cli_qsort(exe_sections, nsections, sizeof(*exe_sections), sort_sects);
5576 5576
 
5577
-    if (class == CL_GENHASH_PE_CLASS_SECTION) {
5578
-        unsigned char *hash, *hashset[CLI_HASH_AVAIL_TYPES], hstr[2*CLI_HASHLEN_MAX+1];
5579
-        int foundsize[CLI_HASH_AVAIL_TYPES];
5580
-        int foundwild[CLI_HASH_AVAIL_TYPES];
5581
-        int hlen = 0;
5582
-        int ret = CL_CLEAN;
5583
-
5584
-        /* pick hashtypes to generate */
5585
-        memset(foundsize, 0, sizeof(foundsize));
5586
-        memset(foundwild, 0, sizeof(foundwild));
5587
-        switch(type) {
5588
-        case 1:
5589
-            foundsize[CLI_HASH_MD5] = 1;
5590
-            hash = hashset[CLI_HASH_MD5] = cli_malloc(hashlen[CLI_HASH_MD5]);
5591
-            hlen = hashlen[CLI_HASH_MD5];
5592
-            break;
5593
-        case 2:
5594
-            foundsize[CLI_HASH_SHA1] = 1;
5595
-            hash = hashset[CLI_HASH_SHA1] = cli_malloc(hashlen[CLI_HASH_SHA1]);
5596
-            hlen = hashlen[CLI_HASH_SHA1];
5597
-            break;
5598
-        default:
5599
-            foundsize[CLI_HASH_SHA256] = 1;
5600
-            hash = hashset[CLI_HASH_SHA256] = cli_malloc(hashlen[CLI_HASH_SHA256]);
5601
-            hlen = hashlen[CLI_HASH_SHA256];
5602
-            break;
5603
-        }
5577
+    /* pick hashtypes to generate */
5578
+    memset(genhash, 0, sizeof(genhash));
5579
+    switch(type) {
5580
+    case 1:
5581
+        genhash[CLI_HASH_MD5] = 1;
5582
+        hash = hashset[CLI_HASH_MD5] = cli_malloc(hashlen[CLI_HASH_MD5]);
5583
+        hlen = hashlen[CLI_HASH_MD5];
5584
+        break;
5585
+    case 2:
5586
+        genhash[CLI_HASH_SHA1] = 1;
5587
+        hash = hashset[CLI_HASH_SHA1] = cli_malloc(hashlen[CLI_HASH_SHA1]);
5588
+        hlen = hashlen[CLI_HASH_SHA1];
5589
+        break;
5590
+    default:
5591
+        genhash[CLI_HASH_SHA256] = 1;
5592
+        hash = hashset[CLI_HASH_SHA256] = cli_malloc(hashlen[CLI_HASH_SHA256]);
5593
+        hlen = hashlen[CLI_HASH_SHA256];
5594
+        break;
5595
+    }
5604 5596
 
5605
-        if(!hash) {
5606
-            cli_errmsg("cli_genhash_pe: cli_malloc failed!\n");
5607
-            free(exe_sections);
5608
-            return CL_EMEM;
5609
-        }
5597
+    if(!hash) {
5598
+        cli_errmsg("cli_genhash_pe: cli_malloc failed!\n");
5599
+        free(exe_sections);
5600
+        return CL_EMEM;
5601
+    }
5602
+
5603
+    if (class == CL_GENHASH_PE_CLASS_SECTION) {
5604
+        char *dstr;
5610 5605
 
5611 5606
         for (i = 0; i < nsections; i++) {
5612 5607
             /* Generate hashes */
5613
-            cli_hashsect(*ctx->fmap, &exe_sections[i], hashset, foundsize, foundwild);
5614
-            for (j = 0; j < hlen; j++)
5615
-                snprintf(hstr+(2*j), sizeof(hstr)-(2*j), "%02x", hash[j]);
5616
-            hstr[j] = '\0';
5617
-            cli_dbgmsg("Section{%u}: %u:%s\n", i, exe_sections[i].rsz, hstr);
5618
-
5619
-            cli_dbgmsg("Section{%u}: %u:%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n",
5620
-                       i, exe_sections[i].rsz, hash[0], hash[1], hash[2], hash[3], hash[4], hash[5], hash[6], hash[7],
5621
-                       hash[8], hash[9], hash[10], hash[11], hash[12], hash[13], hash[14], hash[15]);
5608
+            cli_hashsect(*ctx->fmap, &exe_sections[i], hashset, genhash, genhash);
5609
+            dstr = cli_str2hex(hash, hlen);
5610
+            cli_dbgmsg("Section{%u}: %u:%s\n", i, exe_sections[i].rsz, dstr ? (char *)dstr : "(NULL)");
5611
+            if (dstr)
5612
+                free(dstr);
5622 5613
         }
5623
-
5624
-        free(hash);
5625 5614
     } else if (class == CL_GENHASH_PE_CLASS_IMPTBL) {
5626
-        /* TODO */
5615
+        char *dstr;
5616
+        uint32_t impsz = 0;
5617
+
5618
+        /* Generate hash */
5619
+        hash_imptbl(ctx, hashset, &impsz, genhash, &dirs[1], exe_sections, nsections, hdr_size, pe_plus);
5620
+        dstr = cli_str2hex(hash, hlen);
5621
+        cli_dbgmsg("Imphash: %s:%u\n", dstr ? (char *)dstr : "(NULL)", impsz);
5622
+        if (dstr)
5623
+            free(dstr);
5627 5624
     } else {
5628 5625
         cli_dbgmsg("cli_genhash_pe: unknown pe genhash class: %u\n", class);
5629 5626
     }
5630 5627
 
5628
+    if (hash)
5629
+        free(hash);
5631 5630
     free(exe_sections);
5632 5631
     return CL_SUCCESS;
5633 5632
 }