github.com/saferwall/pe@v1.5.2/boundimports_test.go (about)

     1  // Copyright 2018 Saferwall. All rights reserved.
     2  // Use of this source code is governed by Apache v2 license
     3  // license that can be found in the LICENSE file.
     4  
     5  package pe
     6  
     7  import (
     8  	"reflect"
     9  	"testing"
    10  )
    11  
    12  type TestBoundImportEntry struct {
    13  	entryCount     int
    14  	entryIndex     int
    15  	entry          BoundImportDescriptorData
    16  	errOutOfBounds error
    17  }
    18  
    19  func TestBoundImportDirectory(t *testing.T) {
    20  
    21  	tests := []struct {
    22  		in  string
    23  		out TestBoundImportEntry
    24  	}{
    25  		{
    26  			getAbsoluteFilePath("test/mfc40u.dll"),
    27  			TestBoundImportEntry{
    28  				entryCount: 4,
    29  				entryIndex: 0,
    30  				entry: BoundImportDescriptorData{
    31  					Struct: ImageBoundImportDescriptor{
    32  						TimeDateStamp:               0x31CB50F3,
    33  						OffsetModuleName:            0x38,
    34  						NumberOfModuleForwarderRefs: 0x1,
    35  					},
    36  					Name: "MSVCRT40.dll",
    37  					ForwardedRefs: []BoundForwardedRefData{
    38  						{
    39  							Struct: ImageBoundForwardedRef{
    40  								TimeDateStamp:    0x3B7DFE0E,
    41  								OffsetModuleName: 0x45,
    42  								Reserved:         0x0,
    43  							},
    44  							Name: "msvcrt.DLL",
    45  						},
    46  					},
    47  				},
    48  				errOutOfBounds: nil,
    49  			},
    50  		},
    51  		{
    52  			// fake bound imports directory
    53  			getAbsoluteFilePath("test/0044e1870806c048a7558082d4482d1650dcd3ea73152ed2218a554983130721"),
    54  			TestBoundImportEntry{
    55  				errOutOfBounds: ErrOutsideBoundary,
    56  			},
    57  		},
    58  	}
    59  
    60  	for _, tt := range tests {
    61  		t.Run(tt.in, func(t *testing.T) {
    62  			ops := Options{Fast: true}
    63  			file, err := New(tt.in, &ops)
    64  			if err != nil {
    65  				t.Fatalf("New(%s) failed, reason: %v", tt.in, err)
    66  			}
    67  
    68  			err = file.Parse()
    69  			if err != nil {
    70  				t.Fatalf("Parse(%s) failed, reason: %v", tt.in, err)
    71  			}
    72  
    73  			var va, size uint32
    74  
    75  			if file.Is64 {
    76  				oh64 := file.NtHeader.OptionalHeader.(ImageOptionalHeader64)
    77  				dirEntry := oh64.DataDirectory[ImageDirectoryEntryBoundImport]
    78  				va = dirEntry.VirtualAddress
    79  				size = dirEntry.Size
    80  			} else {
    81  				oh32 := file.NtHeader.OptionalHeader.(ImageOptionalHeader32)
    82  				dirEntry := oh32.DataDirectory[ImageDirectoryEntryBoundImport]
    83  				va = dirEntry.VirtualAddress
    84  				size = dirEntry.Size
    85  			}
    86  
    87  			err = file.parseBoundImportDirectory(va, size)
    88  			if err != tt.out.errOutOfBounds {
    89  				t.Fatalf("parseBoundImportDirectory(%s) failed, reason: %v", tt.in, err)
    90  			}
    91  			got := file.BoundImports
    92  			if len(got) != tt.out.entryCount {
    93  				t.Errorf("bound imports entry count assertion failed, got %v, want %v", len(got), tt.out.entryCount)
    94  			}
    95  
    96  			if len(file.BoundImports) > 0 {
    97  				boundImportEntry := file.BoundImports[tt.out.entryIndex]
    98  				if !reflect.DeepEqual(boundImportEntry, tt.out.entry) {
    99  					t.Errorf("bound import entry assertion failed, got %v, want %v", boundImportEntry, tt.out.entry)
   100  				}
   101  			}
   102  		})
   103  	}
   104  }