@@ -34,9 +34,9 @@ PH_CALLBACK_REGISTRATION ProcessMenuInitializingCallbackRegistration;
34
34
PH_CALLBACK_REGISTRATION ModuleMenuInitializingCallbackRegistration ;
35
35
PH_CALLBACK_REGISTRATION TreeNewMessageCallbackRegistration ;
36
36
PH_CALLBACK_REGISTRATION ProcessTreeNewInitializingCallbackRegistration ;
37
+ PH_CALLBACK_REGISTRATION ModulesTreeNewInitializingCallbackRegistration ;
37
38
38
39
BOOLEAN VirusTotalScanningEnabled = FALSE;
39
- HWND ProcessTreeNewHandle = NULL ;
40
40
ULONG ProcessesUpdatedCount = 0 ;
41
41
LIST_ENTRY ProcessListHead = { & ProcessListHead , & ProcessListHead };
42
42
PH_QUEUED_LOCK ProcessesListLock = PH_QUEUED_LOCK_INIT ;
@@ -47,28 +47,45 @@ VOID ProcessesUpdatedCallback(
47
47
)
48
48
{
49
49
#ifdef VIRUSTOTAL_API
50
+ static ULONG ProcessesUpdatedCount = 0 ;
50
51
PLIST_ENTRY listEntry ;
51
52
52
53
if (!VirusTotalScanningEnabled )
53
54
return ;
54
55
56
+ ProcessesUpdatedCount ++ ;
57
+
58
+ if (ProcessesUpdatedCount < 2 )
59
+ return ;
60
+
55
61
listEntry = ProcessListHead .Flink ;
56
62
57
63
while (listEntry != & ProcessListHead )
58
64
{
59
65
PPROCESS_EXTENSION extension ;
60
- PPH_PROCESS_ITEM processItem ;
61
66
62
67
extension = CONTAINING_RECORD (listEntry , PROCESS_EXTENSION , ListEntry );
63
- processItem = extension -> ProcessItem ;
64
68
65
- if (!PH_IS_FAKE_PROCESS_ID (processItem -> ProcessId ) && !PhIsNullOrEmptyString (processItem -> FileName ))
69
+ PPH_STRING filePath = NULL ;
70
+ PPH_PROCESS_ITEM processItem = extension -> ProcessItem ;
71
+ PPH_MODULE_ITEM moduleItem = extension -> ModuleItem ;
72
+
73
+ if (processItem )
74
+ {
75
+ filePath = processItem -> FileName ;
76
+ }
77
+ else if (moduleItem )
78
+ {
79
+ filePath = moduleItem -> FileName ;
80
+ }
81
+
82
+ if (!PhIsNullOrEmptyString (filePath )) // !PH_IS_FAKE_PROCESS_ID(processItem->ProcessId)
66
83
{
67
84
if (!extension -> ResultValid )
68
85
{
69
86
PPROCESS_DB_OBJECT object ;
70
87
71
- if (object = FindProcessDbObject (& processItem -> FileName -> sr ))
88
+ if (object = FindProcessDbObject (& filePath -> sr ))
72
89
{
73
90
extension -> Stage1 = TRUE;
74
91
extension -> ResultValid = TRUE;
@@ -80,9 +97,9 @@ VOID ProcessesUpdatedCallback(
80
97
81
98
if (!extension -> Stage1 )
82
99
{
83
- if (!VirusTotalGetCachedResult (processItem -> FileName ))
100
+ if (!VirusTotalGetCachedResult (filePath ))
84
101
{
85
- VirusTotalAddCacheResult (processItem , extension );
102
+ VirusTotalAddCacheResult (filePath , extension );
86
103
}
87
104
88
105
extension -> Stage1 = TRUE;
@@ -274,8 +291,7 @@ VOID NTAPI ModuleMenuInitializingCallback(
274
291
}
275
292
}
276
293
277
-
278
- LONG NTAPI VirusTotalNodeSortFunction (
294
+ LONG NTAPI VirusTotalProcessNodeSortFunction (
279
295
_In_ PVOID Node1 ,
280
296
_In_ PVOID Node2 ,
281
297
_In_ ULONG SubId ,
@@ -290,6 +306,21 @@ LONG NTAPI VirusTotalNodeSortFunction(
290
306
return PhCompareStringWithNull (extension1 -> VirusTotalResult , extension2 -> VirusTotalResult , TRUE);
291
307
}
292
308
309
+ LONG NTAPI VirusTotalModuleNodeSortFunction (
310
+ _In_ PVOID Node1 ,
311
+ _In_ PVOID Node2 ,
312
+ _In_ ULONG SubId ,
313
+ _In_ PVOID Context
314
+ )
315
+ {
316
+ PPH_MODULE_NODE node1 = Node1 ;
317
+ PPH_MODULE_NODE node2 = Node2 ;
318
+ PPROCESS_EXTENSION extension1 = PhPluginGetObjectExtension (PluginInstance , node1 -> ModuleItem , EmModuleItemType );
319
+ PPROCESS_EXTENSION extension2 = PhPluginGetObjectExtension (PluginInstance , node2 -> ModuleItem , EmModuleItemType );
320
+
321
+ return PhCompareStringWithNull (extension1 -> VirusTotalResult , extension2 -> VirusTotalResult , TRUE);
322
+ }
323
+
293
324
VOID NTAPI ProcessTreeNewInitializingCallback (
294
325
_In_opt_ PVOID Parameter ,
295
326
_In_opt_ PVOID Context
@@ -298,14 +329,32 @@ VOID NTAPI ProcessTreeNewInitializingCallback(
298
329
PPH_PLUGIN_TREENEW_INFORMATION info = Parameter ;
299
330
PH_TREENEW_COLUMN column ;
300
331
301
- * (HWND * )Context = info -> TreeNewHandle ;
332
+ //*(HWND*)Context = info->TreeNewHandle;
333
+
334
+ memset (& column , 0 , sizeof (PH_TREENEW_COLUMN ));
335
+ column .Text = L"VirusTotal" ;
336
+ column .Width = 140 ;
337
+ column .Alignment = PH_ALIGN_CENTER ;
338
+ column .CustomDraw = TRUE;
339
+ PhPluginAddTreeNewColumn (PluginInstance , info -> CmData , & column , NETWORK_COLUMN_ID_VIUSTOTAL , NULL , VirusTotalProcessNodeSortFunction );
340
+ }
341
+
342
+ VOID NTAPI ModuleTreeNewInitializingCallback (
343
+ _In_opt_ PVOID Parameter ,
344
+ _In_opt_ PVOID Context
345
+ )
346
+ {
347
+ PPH_PLUGIN_TREENEW_INFORMATION info = Parameter ;
348
+ PH_TREENEW_COLUMN column ;
349
+
350
+ //*(HWND*)Context = info->TreeNewHandle;
302
351
303
352
memset (& column , 0 , sizeof (PH_TREENEW_COLUMN ));
304
353
column .Text = L"VirusTotal" ;
305
354
column .Width = 140 ;
306
355
column .Alignment = PH_ALIGN_CENTER ;
307
356
column .CustomDraw = TRUE;
308
- PhPluginAddTreeNewColumn (PluginInstance , info -> CmData , & column , NETWORK_COLUMN_ID_VIUSTOTAL , NULL , VirusTotalNodeSortFunction );
357
+ PhPluginAddTreeNewColumn (PluginInstance , info -> CmData , & column , NETWORK_COLUMN_ID_VIUSTOTAL_MODULE , NULL , VirusTotalModuleNodeSortFunction );
309
358
}
310
359
311
360
VOID NTAPI TreeNewMessageCallback (
@@ -319,87 +368,110 @@ VOID NTAPI TreeNewMessageCallback(
319
368
{
320
369
case TreeNewGetCellText :
321
370
{
322
- if (message -> TreeNewHandle == ProcessTreeNewHandle )
371
+ PPH_TREENEW_GET_CELL_TEXT getCellText = message -> Parameter1 ;
372
+
373
+ switch (message -> SubId )
323
374
{
324
- PPH_TREENEW_GET_CELL_TEXT getCellText = message -> Parameter1 ;
325
- PPH_PROCESS_NODE processNode = (PPH_PROCESS_NODE )getCellText -> Node ;
326
- PPROCESS_EXTENSION extension = PhPluginGetObjectExtension (PluginInstance , processNode -> ProcessItem , EmProcessItemType );
375
+ case NETWORK_COLUMN_ID_VIUSTOTAL :
376
+ {
377
+ PPH_PROCESS_NODE processNode = (PPH_PROCESS_NODE )getCellText -> Node ;
378
+ PPROCESS_EXTENSION extension = PhPluginGetObjectExtension (PluginInstance , processNode -> ProcessItem , EmProcessItemType );
327
379
328
- switch (message -> SubId )
380
+ getCellText -> Text = PhGetStringRef (extension -> VirusTotalResult );
381
+ }
382
+ break ;
383
+ case NETWORK_COLUMN_ID_VIUSTOTAL_MODULE :
329
384
{
330
- case NETWORK_COLUMN_ID_VIUSTOTAL :
331
- {
332
- getCellText -> Text = PhGetStringRef (extension -> VirusTotalResult );
333
- }
334
- break ;
385
+ PPH_MODULE_NODE processNode = (PPH_MODULE_NODE )getCellText -> Node ;
386
+ PPROCESS_EXTENSION extension = PhPluginGetObjectExtension (PluginInstance , processNode -> ModuleItem , EmModuleItemType );
387
+
388
+ getCellText -> Text = PhGetStringRef (extension -> VirusTotalResult );
335
389
}
390
+ break ;
336
391
}
337
392
}
338
393
break ;
339
394
case TreeNewCustomDraw :
340
395
{
341
- if (message -> TreeNewHandle == ProcessTreeNewHandle )
342
- {
343
- PPH_TREENEW_CUSTOM_DRAW customDraw = message -> Parameter1 ;
344
- PPH_PROCESS_NODE processNode = (PPH_PROCESS_NODE )customDraw -> Node ;
345
- PPROCESS_EXTENSION extension = PhPluginGetObjectExtension (PluginInstance , processNode -> ProcessItem , EmProcessItemType );
346
- PH_STRINGREF text ;
347
- SIZE textSize ;
348
-
349
- if (!VirusTotalScanningEnabled )
350
- {
351
- static PH_STRINGREF disabledText = PH_STRINGREF_INIT (L"VirusTotal disabled" );
352
-
353
- GetTextExtentPoint32 (
354
- customDraw -> Dc ,
355
- disabledText .Buffer ,
356
- (ULONG )disabledText .Length / 2 ,
357
- & textSize
358
- );
396
+ PPH_TREENEW_CUSTOM_DRAW customDraw = message -> Parameter1 ;
397
+ PPROCESS_EXTENSION extension = NULL ;
398
+ PH_STRINGREF text ;
399
+ SIZE textSize ;
359
400
360
- DrawText (
361
- customDraw -> Dc ,
362
- disabledText .Buffer ,
363
- (ULONG )disabledText .Length / 2 ,
364
- & customDraw -> CellRect ,
365
- DT_CENTER | DT_VCENTER | DT_END_ELLIPSIS | DT_SINGLELINE
366
- );
367
-
368
- return ;
369
- }
370
-
371
- if (extension -> Positives )
372
- {
373
- //fontHandle = CommonCreateFont(-14, FW_BOLD, NULL);
374
- SetTextColor (customDraw -> Dc , RGB (0xff , 0 , 0 ));
375
- }
376
- else
377
- {
378
- //fontHandle = CommonDuplicateFont((HFONT)SendMessage(ProcessTreeNewHandle, WM_GETFONT, 0, 0));
379
- SetTextColor (customDraw -> Dc , RGB (0x64 , 0x64 , 0x64 ));
380
- }
381
-
382
- // originalFont = SelectObject(customDraw->Dc, fontHandle);
383
- text = PhGetStringRef (extension -> VirusTotalResult );
401
+ if (!VirusTotalScanningEnabled )
402
+ {
403
+ static PH_STRINGREF disabledText = PH_STRINGREF_INIT (L"VirusTotal disabled" );
384
404
385
405
GetTextExtentPoint32 (
386
- customDraw -> Dc ,
387
- text .Buffer ,
388
- (ULONG )text .Length / 2 ,
406
+ customDraw -> Dc ,
407
+ disabledText .Buffer ,
408
+ (ULONG )disabledText .Length / 2 ,
389
409
& textSize
390
410
);
391
411
392
412
DrawText (
393
413
customDraw -> Dc ,
394
- text .Buffer ,
395
- (ULONG )text .Length / 2 ,
414
+ disabledText .Buffer ,
415
+ (ULONG )disabledText .Length / 2 ,
396
416
& customDraw -> CellRect ,
397
417
DT_CENTER | DT_VCENTER | DT_END_ELLIPSIS | DT_SINGLELINE
398
418
);
399
419
400
- //SelectObject(customDraw->Dc, originalFont);
401
- //DeleteObject(fontHandle);
420
+ return ;
402
421
}
422
+
423
+ switch (message -> SubId )
424
+ {
425
+ case NETWORK_COLUMN_ID_VIUSTOTAL :
426
+ {
427
+ PPH_PROCESS_NODE processNode = (PPH_PROCESS_NODE )customDraw -> Node ;
428
+
429
+ extension = PhPluginGetObjectExtension (PluginInstance , processNode -> ProcessItem , EmProcessItemType );
430
+ }
431
+ break ;
432
+ case NETWORK_COLUMN_ID_VIUSTOTAL_MODULE :
433
+ {
434
+ PPH_MODULE_NODE processNode = (PPH_MODULE_NODE )customDraw -> Node ;
435
+
436
+ extension = PhPluginGetObjectExtension (PluginInstance , processNode -> ModuleItem , EmModuleItemType );
437
+ }
438
+ break ;
439
+ }
440
+
441
+ if (!extension )
442
+ break ;
443
+
444
+ if (extension -> Positives )
445
+ {
446
+ //fontHandle = CommonCreateFont(-14, FW_BOLD, NULL);
447
+ SetTextColor (customDraw -> Dc , RGB (0xff , 0 , 0 ));
448
+ }
449
+ else
450
+ {
451
+ //fontHandle = CommonDuplicateFont((HFONT)SendMessage(ProcessTreeNewHandle, WM_GETFONT, 0, 0));
452
+ SetTextColor (customDraw -> Dc , RGB (0x64 , 0x64 , 0x64 ));
453
+ }
454
+
455
+ // originalFont = SelectObject(customDraw->Dc, fontHandle);
456
+ text = PhGetStringRef (extension -> VirusTotalResult );
457
+
458
+ GetTextExtentPoint32 (
459
+ customDraw -> Dc ,
460
+ text .Buffer ,
461
+ (ULONG )text .Length / 2 ,
462
+ & textSize
463
+ );
464
+
465
+ DrawText (
466
+ customDraw -> Dc ,
467
+ text .Buffer ,
468
+ (ULONG )text .Length / 2 ,
469
+ & customDraw -> CellRect ,
470
+ DT_CENTER | DT_VCENTER | DT_END_ELLIPSIS | DT_SINGLELINE
471
+ );
472
+
473
+ //SelectObject(customDraw->Dc, originalFont);
474
+ //DeleteObject(fontHandle);
403
475
}
404
476
break ;
405
477
}
@@ -440,6 +512,41 @@ VOID NTAPI ProcessItemDeleteCallback(
440
512
PhReleaseQueuedLockExclusive (& ProcessesListLock );
441
513
}
442
514
515
+ VOID NTAPI ModuleItemCreateCallback (
516
+ _In_ PVOID Object ,
517
+ _In_ PH_EM_OBJECT_TYPE ObjectType ,
518
+ _In_ PVOID Extension
519
+ )
520
+ {
521
+ PPH_MODULE_ITEM moduleItem = Object ;
522
+ PPROCESS_EXTENSION extension = Extension ;
523
+
524
+ memset (extension , 0 , sizeof (PROCESS_EXTENSION ));
525
+
526
+ extension -> ModuleItem = moduleItem ;
527
+ extension -> VirusTotalResult = PhReferenceEmptyString ();
528
+
529
+ PhAcquireQueuedLockExclusive (& ProcessesListLock );
530
+ InsertTailList (& ProcessListHead , & extension -> ListEntry );
531
+ PhReleaseQueuedLockExclusive (& ProcessesListLock );
532
+ }
533
+
534
+ VOID NTAPI ModuleItemDeleteCallback (
535
+ _In_ PVOID Object ,
536
+ _In_ PH_EM_OBJECT_TYPE ObjectType ,
537
+ _In_ PVOID Extension
538
+ )
539
+ {
540
+ PPH_MODULE_ITEM processItem = Object ;
541
+ PPROCESS_EXTENSION extension = Extension ;
542
+
543
+ PhClearReference (& extension -> VirusTotalResult );
544
+
545
+ PhAcquireQueuedLockExclusive (& ProcessesListLock );
546
+ RemoveEntryList (& extension -> ListEntry );
547
+ PhReleaseQueuedLockExclusive (& ProcessesListLock );
548
+ }
549
+
443
550
LOGICAL DllMain (
444
551
_In_ HINSTANCE Instance ,
445
552
_In_ ULONG Reason ,
@@ -514,9 +621,16 @@ LOGICAL DllMain(
514
621
PhRegisterCallback (
515
622
PhGetGeneralCallback (GeneralCallbackProcessTreeNewInitializing ),
516
623
ProcessTreeNewInitializingCallback ,
517
- & ProcessTreeNewHandle ,
624
+ NULL ,
518
625
& ProcessTreeNewInitializingCallbackRegistration
519
626
);
627
+ PhRegisterCallback (
628
+ PhGetGeneralCallback (GeneralCallbackModuleTreeNewInitializing ),
629
+ ModuleTreeNewInitializingCallback ,
630
+ NULL ,
631
+ & ModulesTreeNewInitializingCallbackRegistration
632
+ );
633
+
520
634
PhRegisterCallback (
521
635
PhGetPluginCallback (PluginInstance , PluginCallbackTreeNewMessage ),
522
636
TreeNewMessageCallback ,
@@ -532,6 +646,14 @@ LOGICAL DllMain(
532
646
ProcessItemDeleteCallback
533
647
);
534
648
649
+ PhPluginSetObjectExtension (
650
+ PluginInstance ,
651
+ EmModuleItemType ,
652
+ sizeof (PROCESS_EXTENSION ),
653
+ ModuleItemCreateCallback ,
654
+ ModuleItemDeleteCallback
655
+ );
656
+
535
657
PhAddSettings (settings , ARRAYSIZE (settings ));
536
658
}
537
659
break ;
0 commit comments