@@ -624,3 +624,80 @@ func TestCommandLineRecomposition(t *testing.T) {
624
624
}
625
625
}
626
626
}
627
+
628
+ func TestWinVerifyTrust (t * testing.T ) {
629
+ system32 , err := windows .GetSystemDirectory ()
630
+ if err != nil {
631
+ t .Errorf ("unable to find system32 directory: %v" , err )
632
+ }
633
+ ntoskrnl := filepath .Join (system32 , "ntoskrnl.exe" )
634
+ ntoskrnl16 , err := windows .UTF16PtrFromString (ntoskrnl )
635
+ if err != nil {
636
+ t .Fatalf ("unable to get utf16 of ntoskrnl.exe: %v" , err )
637
+ }
638
+ data := & windows.WinTrustData {
639
+ Size : uint32 (unsafe .Sizeof (windows.WinTrustData {})),
640
+ UIChoice : windows .WTD_UI_NONE ,
641
+ RevocationChecks : windows .WTD_REVOKE_NONE , // No revocation checking, in case the tests don't have network connectivity.
642
+ UnionChoice : windows .WTD_CHOICE_FILE ,
643
+ StateAction : windows .WTD_STATEACTION_VERIFY ,
644
+ FileOrCatalogOrBlobOrSgnrOrCert : unsafe .Pointer (& windows.WinTrustFileInfo {
645
+ Size : uint32 (unsafe .Sizeof (windows.WinTrustFileInfo {})),
646
+ FilePath : ntoskrnl16 ,
647
+ }),
648
+ }
649
+ verifyErr := windows .WinVerifyTrustEx (windows .InvalidHWND , & windows .WINTRUST_ACTION_GENERIC_VERIFY_V2 , data )
650
+ data .StateAction = windows .WTD_STATEACTION_CLOSE
651
+ closeErr := windows .WinVerifyTrustEx (windows .InvalidHWND , & windows .WINTRUST_ACTION_GENERIC_VERIFY_V2 , data )
652
+ if verifyErr != nil {
653
+ t .Errorf ("ntoskrnl.exe did not verify: %v" , verifyErr )
654
+ }
655
+ if closeErr != nil {
656
+ t .Errorf ("unable to free verification resources: %v" , closeErr )
657
+ }
658
+
659
+ // Now that we've verified legitimate ntoskrnl.exe verifies, let's corrupt it and see if it correctly fails.
660
+
661
+ dir , err := ioutil .TempDir ("" , "go-build" )
662
+ if err != nil {
663
+ t .Fatalf ("failed to create temp directory: %v" , err )
664
+ }
665
+ defer os .RemoveAll (dir )
666
+ corruptedNtoskrnl := filepath .Join (dir , "ntoskrnl.exe" )
667
+ ntoskrnlBytes , err := ioutil .ReadFile (ntoskrnl )
668
+ if err != nil {
669
+ t .Fatalf ("unable to read ntoskrnl.exe bytes: %v" , err )
670
+ }
671
+ if len (ntoskrnlBytes ) > 0 {
672
+ ntoskrnlBytes [len (ntoskrnlBytes )/ 2 - 1 ]++
673
+ }
674
+ err = ioutil .WriteFile (corruptedNtoskrnl , ntoskrnlBytes , 0755 )
675
+ if err != nil {
676
+ t .Fatalf ("unable to write corrupted ntoskrnl.exe bytes: %v" , err )
677
+ }
678
+ ntoskrnl16 , err = windows .UTF16PtrFromString (corruptedNtoskrnl )
679
+ if err != nil {
680
+ t .Fatalf ("unable to get utf16 of ntoskrnl.exe: %v" , err )
681
+ }
682
+ data = & windows.WinTrustData {
683
+ Size : uint32 (unsafe .Sizeof (windows.WinTrustData {})),
684
+ UIChoice : windows .WTD_UI_NONE ,
685
+ RevocationChecks : windows .WTD_REVOKE_NONE , // No revocation checking, in case the tests don't have network connectivity.
686
+ UnionChoice : windows .WTD_CHOICE_FILE ,
687
+ StateAction : windows .WTD_STATEACTION_VERIFY ,
688
+ FileOrCatalogOrBlobOrSgnrOrCert : unsafe .Pointer (& windows.WinTrustFileInfo {
689
+ Size : uint32 (unsafe .Sizeof (windows.WinTrustFileInfo {})),
690
+ FilePath : ntoskrnl16 ,
691
+ }),
692
+ }
693
+ verifyErr = windows .WinVerifyTrustEx (windows .InvalidHWND , & windows .WINTRUST_ACTION_GENERIC_VERIFY_V2 , data )
694
+ data .StateAction = windows .WTD_STATEACTION_CLOSE
695
+ closeErr = windows .WinVerifyTrustEx (windows .InvalidHWND , & windows .WINTRUST_ACTION_GENERIC_VERIFY_V2 , data )
696
+ if verifyErr != windows .Errno (windows .TRUST_E_BAD_DIGEST ) {
697
+ t .Errorf ("ntoskrnl.exe did not fail to verify as expected: %v" , verifyErr )
698
+ }
699
+ if closeErr != nil {
700
+ t .Errorf ("unable to free verification resources: %v" , closeErr )
701
+ }
702
+
703
+ }
0 commit comments