WMI - List AntiVirus

Started by stanl, September 04, 2020, 01:27:10 AM

Previous topic - Next topic

stanl

I'm nor sure the Hex conversions are correct given the number of Anti-Virus products. But anyone with a better mousetrap please chip in.
Code (WINBATCH) Select


;Winbatch 2020A - List AntiVirus in WMI
;=============================================================================
IntControl(73,1,0,0,0)
Gosub udf
strComputer = "."
oWMI = GetObject( "winmgmts:\\" : strComputer : "\root\SecurityCenter2")
WQL =  "SELECT * FROM AntivirusProduct"
oP= oWMI.ExecQuery(WQL)
cProcess=""
ForEach P In oP   
   cName = P.displayName
   cP = P.pathToSignedProductExe
   cS = dec2hex(P.productState)
   state=""
   If StrSub(cs,2,2)=='10' Then state=state:"enabled"
   If StrSub(cs,2,2)=='00' Then state=state:"disabled"
   If StrSub(cs,4,2)=='00' Then state=state:"/up to date"
   If StrSub(cs,4,2)=='10' Then state=state:"/outdated"
   cTS = P.timestamp
   cProcess = cProcess:"Display Name: ":cName:@LF
   cProcess = cProcess:"Path        : ":cP:@LF
   cProcess = cProcess:"Produt State: ":"[":cS:"] ":state:@LF
   cProcess = cProcess:"Time Stamp  : ":cTS:@LF:@LF:@LF
Next
Message("Current AntiVirus Installed",cProcess)
oWMI=0
Exit


:WBERRORHANDLER
oWMI=0
wberroradditionalinfo = wberrorarray[6]
lasterr = wberrorarray[0]
handlerline = wberrorarray[1]
textstring = wberrorarray[5]
linenumber = wberrorarray[8]
errmsg = "Error: ":lasterr:@LF:textstring:@LF:"Line (":linenumber:")":@LF:wberroradditionalinfo
Message("Error",errmsg)
Exit


:udf
#DefineFunction Dec2Hex(Dec)
   IsZero=@TRUE
   str="0123456789ABCDEF"
   hex=""
   
   for x=7 to 0 by -1
       nibble= (dec >> (x*4)) & 15
       if nibble==0 && IsZero==@TRUE then continue
       IsZero=@FALSE
       hex=strcat(hex,Strsub(str,nibble+1,1))
   next
   return(hex)
#EndFunction
Return
;=======================================================================================







kdmoyers

The mind is everything; What you think, you become.

td

Yes, a nice WMI class and example.  The only small change I might suggest is perhaps using bitwise operators instead of converting to hexadecimal.  It appears that the "productState" property is a bitmap with some bits having a specific meaning.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

stanl

Quote from: td on September 04, 2020, 07:42:14 AM
Yes, a nice WMI class and example.  The only small change I might suggest is perhaps using bitwise operators instead of converting to hexadecimal.  It appears that the "productState" property is a bitmap with some bits having a specific meaning.


Even Microsoft uses hex substrings: I increased my If's and got better results - had my Windows Defender as disabled, which it was.


Code (WINBATCH) Select


   If StrSub(cs,2,2)=='10' Then state=state:"enabled"
   If StrSub(cs,2,2)=='00' Then state=state:"disabled"
   If StrSub(cs,2,2)=='01' Then state=state:"expired"
   If StrSub(cs,2,2)=='11' Then state=state:"snoozed"
   If StrSub(cs,4,2)=='00' Then state=state:"/up to date"
   If StrSub(cs,4,2)=='10' Then state=state:"/outdated"



td

Quote

Even Microsoft uses hex substrings: I increased my If's and got better results - had my Windows Defender as disabled, which it was.


That may be the case for their examples but since when is MSFT the accepted authority on WIL coding standards and bitwise operators are much more efficient.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

stanl

OK... and'ng or or'ing or just using hex, I think the issue may come down to individual anti-virus products and some standard for productState, which is obviously used for more than just this particular WMI. Updated script to show decimal, hex, binary for each productState, but still uses Hex o interpret. If there is secret sauce with WIL bitwise I'm all ears:
Code (WINBATCH) Select


;Winbatch 2020A - List AntiVirus in WMI
;=============================================================================
IntControl(73,1,0,0,0)
Gosub udf
strComputer = "."
oWMI = GetObject( "winmgmts:\\" : strComputer : "\root\SecurityCenter2")
WQL =  "SELECT * FROM AntivirusProduct"
oP= oWMI.ExecQuery(WQL)
cProcess=""
ForEach P In oP   
   cName = P.displayName
   cP = P.pathToSignedProductExe
   ps = P.productState
   cS = dec2hex(ps)
   cBin = dec2Binary(ps)
   state=""
   If StrSub(cs,2,2)=='10' Then state=state:"enabled"
   If StrSub(cs,2,2)=='00' Then state=state:"disabled"
   If StrSub(cs,2,2)=='01' Then state=state:"expired"
   If StrSub(cs,2,2)=='11' Then state=state:"snoozed"
   If StrSub(cs,4,2)=='00' Then state=state:"/up to date"
   If StrSub(cs,4,2)=='10' Then state=state:"/outdated"
   cTS = P.timestamp
   cProcess = cProcess:"Display Name: ":cName:@LF
   cProcess = cProcess:"Path        : ":cP:@LF
   cProcess = cProcess:"Produt State: ":"[":ps:"/":cS:"/":cBin:"] ":state:@LF
   cProcess = cProcess:"Time Stamp  : ":cTS:@LF:@LF:@LF
Next
Message("Current AntiVirus Installed",cProcess)
oWMI=0
Exit


:WBERRORHANDLER
oWMI=0
wberroradditionalinfo = wberrorarray[6]
lasterr = wberrorarray[0]
handlerline = wberrorarray[1]
textstring = wberrorarray[5]
linenumber = wberrorarray[8]
errmsg = "Error: ":lasterr:@LF:textstring:@LF:"Line (":linenumber:")":@LF:wberroradditionalinfo
Message("Error",errmsg)
Exit


:udf
#DefineFunction Dec2Hex(Dec)
   IsZero=@TRUE
   str="0123456789ABCDEF"
   hex=""
   
   for x=7 to 0 by -1
       nibble= (dec >> (x*4)) & 15
       if nibble==0 && IsZero==@TRUE then continue
       IsZero=@FALSE
       hex=strcat(hex,Strsub(str,nibble+1,1))
   next
   return(hex)
#EndFunction


#DefineFunction Dec2Binary(number)
   binarray = ArrDimension(10)
   ArrInitialize (binarray, "")
   count = 0
   While(number!=0) ; keep looping until we cannot do any more calculations
      binarray[count] = number mod 2
      number=number/2
      count=count+1
   EndWhile
   binary = ""
   size = ArrInfo(binarray, 1)-1
   For x = size To 0 By -1
      binary = binary : binarray[x]
   Next
   Return binary
#EndFunction


Return
;=======================================================================================






 

stanl

Not giving up on the bitwise suggestion. I picked up some bit masks from a Powershell enum. The code below is a test based on product state values of both Defender and Avast. Using a bitwise 'and' they both give the same values which would indicate they are "on"  "out of date" "windows is the owner".  The owner was not part of the original script. I'm obviously doing something wrong but then bitwise is not my forte :'(
Code (WINBATCH) Select


;testing bitwise results for AntiVirus Product State
;bit masks
;SignatureStatus = 0x00F0 [240]
;ProductOwner    = 0x0F00 [3840]
;ProductState    = 0xF000 [61440]




Status = 240
Owner = 3840
State = 61440
;Defender_ProdState = 393472  ;windows defender
Defender_ProdState = 266240  ;Avast AntiVirus




v1 = Defender_ProdState && Owner
v2 = Defender_ProdState && Status
v3 = Defender_ProdState && State


;Message("Windows Defender","Owner:":v1:@LF:"Status:":v2:@LF:"State:":v3)
Message("AVAST AntiVirus","Owner:":v1:@LF:"Status:":v2:@LF:"State:":v3)
Exit

td

Modified snippet from your original script:
Code (winbatch) Select
   If (ps&4352) == 4096 Then state=state:"enabled"     
   If (ps&4352) == 0  Then state=state:"disabled"     
   If (ps&4352) == 256   Then state=state:"expired"   
   If (ps&4352) == 4352 Then state=state:"snoozed"   
   If (ps&17) == 0    Then state=state:"/up to date"
   If (ps&16) == 16   Then state=state:"/outdated"   


It could be optimized and made easier to read but it does illustrate the idea of using bitmasks to interperate state values.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

stanl

Like I said, six of one.... I get the same output using hex on my system. Without some preamble for how the bitwise masks are determined or the outcomes parsed, I'd probably just stick with the hex.

td

Not sure what you mean by "preamble" but the bitmap approach is straight forward enough if you understand bitwise operators and it is very efficient. The only documentation I was thinking of adding was a comment showing which of MSFT's hex string byte value each bitwise operation represented.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

stanl

Yeah, figured it out and see what you mean. Just dumb to test with && instead of & .....  :o

stanl

Either for more clarity or sticking my foot further in my mouth. If I use the 'masks' I gleaned from Powershell, I get the same output as yours
Code (WINBATCH) Select


Status = 240
Owner  = 3840
_State  = 61440  ;note to stupid use _State, not State or get cannot convert error

   ;If (ps&4352) == 4096 Then state=state:"enabled"     
   ;If (ps&4352) == 0  Then state=state:"disabled"     
   ;If (ps&4352) == 256   Then state=state:"expired"   
   ;If (ps&4352) == 4352 Then state=state:"snoozed"   
   ;If (ps&17) == 0    Then state=state:"/up to date"
   ;If (ps&16) == 16   Then state=state:"/outdated"   



   If (ps&_State) == 4096 Then state=state:"enabled"     
   If (ps&_State) == 0  Then state=state:"disabled"     
   If (ps&_State) == 256   Then state=state:"expired"   
   If (ps&_State) == 4352 Then state=state:"snoozed"   
   If (ps&Status) == 0    Then state=state:"/up to date"
   If (ps&Status) == 16   Then state=state:"/outdated"   





for both Defender and Avast. Maybe luck of the draw. Curious also why apps like SpyBot or MalwareBytes don't show up.


This is been fun once again, and I apologize for some stupid typo errors on my part extending the discussion.




td

Your _State value works because all of the state values are stored in the second byte of the doubleword. I originally did it that way but that approach could fail if MSFT decided to use other bits of the byte's two nibbles for other flags.  If MSFT is doing it that way, it is safe to assume it is okay and I agree that it is a bit cleaner.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade