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