...
|
...
|
@@ -86,6 +86,9 @@
|
86
|
86
|
#define UPX_LZMA1 "\x56\x83\xc3\x04\x53\x50\xc7\x03\x03\x00\x02\x00\x90\x90\x90\x55\x57\x56\x53\x83"
|
87
|
87
|
#define UPX_LZMA2 "\x56\x83\xc3\x04\x53\x50\xc7\x03\x03\x00\x02\x00\x90\x90\x90\x90\x90\x55\x57\x56"
|
88
|
88
|
|
|
89
|
+#define PE_MAXNAMESIZE 256
|
|
90
|
+#define PE_MAXIMPORTS 1024
|
|
91
|
+
|
89
|
92
|
#define EC32(x) ((uint32_t)cli_readint32(&(x))) /* Convert little endian to host */
|
90
|
93
|
#define EC16(x) ((uint16_t)cli_readint16(&(x)))
|
91
|
94
|
/* lower and upper bondary alignment (size vs offset) */
|
...
|
...
|
@@ -2164,8 +2167,6 @@ static char *pe_ordinal(char *dll, uint16_t ord)
|
2164
|
2164
|
return cli_strdup(name);
|
2165
|
2165
|
}
|
2166
|
2166
|
|
2167
|
|
-#define PE_MAXIMPORTS 1024
|
2168
|
|
-#define PE_MAXNAMESIZE 256
|
2169
|
2167
|
static inline int scan_pe_impfuncs(cli_ctx *ctx, void *md5ctx, 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) {
|
2170
|
2168
|
uint32_t toff, offset;
|
2171
|
2169
|
fmap_t *map = *ctx->fmap;
|
...
|
...
|
@@ -2228,8 +2229,6 @@ static inline int scan_pe_impfuncs(cli_ctx *ctx, void *md5ctx, struct pe_image_i
|
2228
|
2228
|
char *fname;
|
2229
|
2229
|
size_t funclen;
|
2230
|
2230
|
|
2231
|
|
- //cli_dbgmsg("IMPTBL: FUNC: %s\n", funcname);
|
2232
|
|
-
|
2233
|
2231
|
if (dlllen == 0) {
|
2234
|
2232
|
char* ext = strstr(dllname, ".");
|
2235
|
2233
|
|
...
|
...
|
@@ -2257,7 +2256,6 @@ static inline int scan_pe_impfuncs(cli_ctx *ctx, void *md5ctx, struct pe_image_i
|
2257
|
2257
|
for (i = 0; i < funclen; i++, j++)
|
2258
|
2258
|
fname[j] = tolower(funcname[i]);
|
2259
|
2259
|
|
2260
|
|
- /* JSON TOMFOOLERY */
|
2261
|
2260
|
#if HAVE_JSON
|
2262
|
2261
|
if (imptbl) {
|
2263
|
2262
|
char *jname = *first ? fname : fname+1;
|
...
|
...
|
@@ -2265,8 +2263,6 @@ static inline int scan_pe_impfuncs(cli_ctx *ctx, void *md5ctx, struct pe_image_i
|
2265
|
2265
|
}
|
2266
|
2266
|
#endif
|
2267
|
2267
|
|
2268
|
|
- cli_dbgmsg("%u %s\n", strlen(fname), fname);
|
2269
|
|
-
|
2270
|
2268
|
cl_update_hash(md5ctx, fname, strlen(fname));
|
2271
|
2269
|
|
2272
|
2270
|
*first = 0;
|
...
|
...
|
@@ -2308,9 +2304,6 @@ static inline int scan_pe_impfuncs(cli_ctx *ctx, void *md5ctx, struct pe_image_i
|
2308
|
2308
|
char *fname;
|
2309
|
2309
|
size_t funclen;
|
2310
|
2310
|
|
2311
|
|
- /* JSON TOMFOOLERY */
|
2312
|
|
- //cli_dbgmsg("IMPTBL: FUNC: %s\n", funcname);
|
2313
|
|
-
|
2314
|
2311
|
if (dlllen == 0) {
|
2315
|
2312
|
char* ext = strstr(dllname, ".");
|
2316
|
2313
|
|
...
|
...
|
@@ -2332,18 +2325,22 @@ static inline int scan_pe_impfuncs(cli_ctx *ctx, void *md5ctx, struct pe_image_i
|
2332
|
2332
|
j = 0;
|
2333
|
2333
|
if (!*first)
|
2334
|
2334
|
fname[j++] = ',';
|
2335
|
|
- else
|
2336
|
|
- *first = 0;
|
2337
|
2335
|
for (i = 0; i < dlllen; i++, j++)
|
2338
|
2336
|
fname[j] = tolower(dllname[i]);
|
2339
|
2337
|
fname[j++] = '.';
|
2340
|
2338
|
for (i = 0; i < funclen; i++, j++)
|
2341
|
2339
|
fname[j] = tolower(funcname[i]);
|
2342
|
2340
|
|
2343
|
|
- cli_dbgmsg("%u %s\n", strlen(fname), fname);
|
|
2341
|
+#if HAVE_JSON
|
|
2342
|
+ if (imptbl) {
|
|
2343
|
+ char *jname = *first ? fname : fname+1;
|
|
2344
|
+ cli_jsonstr(imptbl, NULL, jname);
|
|
2345
|
+ }
|
|
2346
|
+#endif
|
2344
|
2347
|
|
2345
|
2348
|
cl_update_hash(md5ctx, fname, strlen(fname));
|
2346
|
2349
|
|
|
2350
|
+ *first = 0;
|
2347
|
2351
|
free(fname);
|
2348
|
2352
|
free(funcname);
|
2349
|
2353
|
}
|
...
|
...
|
@@ -2363,7 +2360,6 @@ static int scan_pe_imptbl(cli_ctx *ctx, struct pe_image_data_dir *dirs, struct c
|
2363
|
2363
|
const char *impdes, *buffer, *virname;
|
2364
|
2364
|
void *md5ctx;
|
2365
|
2365
|
uint8_t digest[16] = {0};
|
2366
|
|
- char *dstr;
|
2367
|
2366
|
int i, err, ret = CL_SUCCESS, num_imports = 0, first = 1;
|
2368
|
2367
|
|
2369
|
2368
|
if (datadir->VirtualAddress == 0 || datadir->Size == 0) {
|
...
|
...
|
@@ -2380,7 +2376,7 @@ static int scan_pe_imptbl(cli_ctx *ctx, struct pe_image_data_dir *dirs, struct c
|
2380
|
2380
|
impdes = fmap_need_off(map, impoff, datadir->Size);
|
2381
|
2381
|
if (impdes == NULL) {
|
2382
|
2382
|
cli_dbgmsg("IMPTBL: failed to acquire fmap buffer\n");
|
2383
|
|
- return CL_SUCCESS; /* real error: CL_EMAP? */
|
|
2383
|
+ return CL_EREAD;
|
2384
|
2384
|
}
|
2385
|
2385
|
left = datadir->Size;
|
2386
|
2386
|
|
...
|
...
|
@@ -2399,29 +2395,26 @@ static int scan_pe_imptbl(cli_ctx *ctx, struct pe_image_data_dir *dirs, struct c
|
2399
|
2399
|
offset = cli_rawaddr(image->Name, exe_sections, nsections, &err, fsize, hdr_size);
|
2400
|
2400
|
if (err || offset > fsize) {
|
2401
|
2401
|
cli_dbgmsg("IMPTBL: invalid rva for dll name\n");
|
2402
|
|
- /* ignore or return? */
|
|
2402
|
+ /* TODO: ignore or return? */
|
2403
|
2403
|
/*
|
2404
|
2404
|
image++;
|
2405
|
2405
|
continue;
|
2406
|
2406
|
*/
|
2407
|
2407
|
cl_hash_destroy(md5ctx);
|
2408
|
|
- return CL_SUCCESS; /* error value? continue? */
|
|
2408
|
+ return CL_SUCCESS; /* CL_EFORMAT? */
|
2409
|
2409
|
}
|
2410
|
2410
|
|
2411
|
2411
|
if ((buffer = fmap_need_off_once(map, offset, MIN(PE_MAXNAMESIZE, fsize-offset))) != NULL) {
|
2412
|
|
- /* sanitize dllname? */
|
|
2412
|
+ /* TODO - sanitize dllname */
|
2413
|
2413
|
dllname = strndup(buffer, MIN(PE_MAXNAMESIZE, fsize-offset));
|
2414
|
2414
|
if (dllname == NULL) {
|
2415
|
2415
|
cli_dbgmsg("IMPTBL: cannot duplicate dll name\n");
|
2416
|
2416
|
cl_hash_destroy(md5ctx);
|
2417
|
2417
|
return CL_EMEM;
|
2418
|
2418
|
}
|
2419
|
|
-
|
2420
|
|
- //cli_dbgmsg("IMPTBL: DLL: %s\n", dllname);
|
2421
|
|
- /* JSON TOMFOOLERY */
|
2422
|
2419
|
}
|
2423
|
2420
|
|
2424
|
|
- /* DLL function handling - inline function TODO - dconf this */
|
|
2421
|
+ /* DLL function handling - inline function */
|
2425
|
2422
|
ret = scan_pe_impfuncs(ctx, md5ctx, image, dllname, exe_sections, nsections, hdr_size, pe_plus, &first);
|
2426
|
2423
|
if (dllname)
|
2427
|
2424
|
free(dllname);
|
...
|
...
|
@@ -2435,15 +2428,24 @@ static int scan_pe_imptbl(cli_ctx *ctx, struct pe_image_data_dir *dirs, struct c
|
2435
|
2435
|
|
2436
|
2436
|
fmap_unneed_off(map, impoff, datadir->Size);
|
2437
|
2437
|
|
2438
|
|
- /* send off for md5 comparison - use ret */
|
2439
|
2438
|
cl_finish_hash(md5ctx, digest);
|
2440
|
|
- dstr = cli_str2hex(digest, sizeof(digest));
|
2441
|
|
- cli_dbgmsg("IMPHASH: %s\n", (char *)dstr);
|
|
2439
|
+
|
|
2440
|
+#if HAVE_JSON
|
|
2441
|
+ if (cli_debug_flag || ctx->wrkproperty) {
|
|
2442
|
+#else
|
|
2443
|
+ if (cli_debug_flag) {
|
|
2444
|
+#endif
|
|
2445
|
+ char *dstr = cli_str2hex(digest, sizeof(digest));
|
|
2446
|
+ cli_dbgmsg("IMPHASH: %s\n", dstr ? (char *)dstr : "(NULL)");
|
2442
|
2447
|
#if HAVE_JSON
|
2443
|
|
- if (ctx->wrkproperty)
|
2444
|
|
- cli_jsonstr(ctx->wrkproperty, "Imphash", dstr);
|
|
2448
|
+ if (ctx->wrkproperty)
|
|
2449
|
+ cli_jsonstr(ctx->wrkproperty, "Imphash", dstr ? dstr : "(NULL)");
|
2445
|
2450
|
#endif
|
2446
|
|
- free(dstr);
|
|
2451
|
+ if (dstr)
|
|
2452
|
+ free(dstr);
|
|
2453
|
+ }
|
|
2454
|
+
|
|
2455
|
+ /* TODO: size-dependent hash scans, what should the size value be? */
|
2447
|
2456
|
|
2448
|
2457
|
if (ith && (ret = cli_hm_scan_wild(digest, &virname, ith, CLI_HASH_MD5)) == CL_VIRUS)
|
2449
|
2458
|
cli_append_virus(ctx, virname);
|
...
|
...
|
@@ -3361,9 +3363,15 @@ int cli_scanpe(cli_ctx *ctx)
|
3361
|
3361
|
|
3362
|
3362
|
/* Attempt to run scans on import table */
|
3363
|
3363
|
/* Run if there are existing signatures and/or preclassing */
|
3364
|
|
- if (ctx->dconf->pe & PE_CONF_IMPTBL) {
|
|
3364
|
+#if HAVE_JSON
|
|
3365
|
+ if (DCONF & PE_CONF_IMPTBL && (ctx->engine->hm_ith || ctx->wrkproperty)) {
|
|
3366
|
+#else
|
|
3367
|
+ if (DCONF & PE_CONF_IMPTBL && ctx->engine->hm_ith) {
|
|
3368
|
+#endif
|
3365
|
3369
|
ret = scan_pe_imptbl(ctx, dirs, exe_sections, nsections, hdr_size, pe_plus);
|
3366
|
3370
|
switch (ret) {
|
|
3371
|
+ case CL_SUCCESS:
|
|
3372
|
+ break;
|
3367
|
3373
|
case CL_ENULLARG:
|
3368
|
3374
|
cli_warnmsg("cli_scanpe: NULL argument supplied\n");
|
3369
|
3375
|
break;
|
...
|
...
|
@@ -3374,6 +3382,9 @@ int cli_scanpe(cli_ctx *ctx)
|
3374
|
3374
|
case CL_BREAK:
|
3375
|
3375
|
free(exe_sections);
|
3376
|
3376
|
return ret == CL_VIRUS ? CL_VIRUS : CL_CLEAN;
|
|
3377
|
+ default:
|
|
3378
|
+ free(exe_sections);
|
|
3379
|
+ return ret;
|
3377
|
3380
|
}
|
3378
|
3381
|
}
|
3379
|
3382
|
/* Attempt to detect some popular polymorphic viruses */
|