github.com/saferwall/pe@v1.5.2/imports_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 TestImportEntry struct {
    13  	entryCount int
    14  	entryIndex int
    15  	entry      Import
    16  }
    17  
    18  func TestImportDirectory(t *testing.T) {
    19  
    20  	tests := []struct {
    21  		in  string
    22  		out TestImportEntry
    23  	}{
    24  		{
    25  			getAbsoluteFilePath("test/kernel32.dll"),
    26  			TestImportEntry{
    27  				entryCount: 96,
    28  				entryIndex: 34,
    29  				entry: Import{
    30  					Offset: 0xa6d94,
    31  					Name:   "api-ms-win-core-namedpipe-l1-2-1.dll",
    32  					Descriptor: ImageImportDescriptor{
    33  						OriginalFirstThunk: 0xa9a38,
    34  						TimeDateStamp:      0x0,
    35  						ForwarderChain:     0x0,
    36  						Name:               0xaeeb8,
    37  						FirstThunk:         0x82978,
    38  					},
    39  					Functions: []ImportFunction{
    40  						{
    41  							Name:               "GetNamedPipeHandleStateW",
    42  							Hint:               0x6,
    43  							ByOrdinal:          false,
    44  							Ordinal:            0x0,
    45  							OriginalThunkValue: 0xaee00,
    46  							ThunkValue:         0xaee00,
    47  							ThunkRVA:           0x82978,
    48  							OriginalThunkRVA:   0xa9a38,
    49  						},
    50  					},
    51  				},
    52  			},
    53  		},
    54  		{
    55  			getAbsoluteFilePath("test/impbyord.exe"),
    56  			TestImportEntry{
    57  				entryCount: 2,
    58  				entryIndex: 1,
    59  				entry: Import{
    60  					Offset: 0x284,
    61  					Name:   "impbyord.exe",
    62  					Descriptor: ImageImportDescriptor{
    63  						OriginalFirstThunk: 0x10b4,
    64  						TimeDateStamp:      0x0,
    65  						ForwarderChain:     0x0,
    66  						Name:               0x10d0,
    67  						FirstThunk:         0x1058,
    68  					},
    69  					Functions: []ImportFunction{
    70  						{
    71  							Name:               "#35",
    72  							Hint:               0x0,
    73  							ByOrdinal:          true,
    74  							Ordinal:            0x23,
    75  							OriginalThunkValue: 0x80000023,
    76  							ThunkValue:         0x10b4,
    77  							ThunkRVA:           0x1058,
    78  							OriginalThunkRVA:   0x10b4,
    79  						},
    80  					},
    81  				},
    82  			},
    83  		},
    84  	}
    85  
    86  	for _, tt := range tests {
    87  		t.Run(tt.in, func(t *testing.T) {
    88  			ops := Options{Fast: true}
    89  			file, err := New(tt.in, &ops)
    90  			if err != nil {
    91  				t.Fatalf("New(%s) failed, reason: %v", tt.in, err)
    92  			}
    93  
    94  			err = file.Parse()
    95  			if err != nil {
    96  				t.Fatalf("Parse(%s) failed, reason: %v", tt.in, err)
    97  			}
    98  
    99  			var va, size uint32
   100  
   101  			if file.Is64 {
   102  				oh64 := file.NtHeader.OptionalHeader.(ImageOptionalHeader64)
   103  				dirEntry := oh64.DataDirectory[ImageDirectoryEntryImport]
   104  				va = dirEntry.VirtualAddress
   105  				size = dirEntry.Size
   106  			} else {
   107  				oh32 := file.NtHeader.OptionalHeader.(ImageOptionalHeader32)
   108  				dirEntry := oh32.DataDirectory[ImageDirectoryEntryImport]
   109  				va = dirEntry.VirtualAddress
   110  				size = dirEntry.Size
   111  			}
   112  
   113  			err = file.parseImportDirectory(va, size)
   114  			if err != nil {
   115  				t.Fatalf("parseImportDirectory(%s) failed, reason: %v", tt.in, err)
   116  			}
   117  			got := file.Imports
   118  			if len(got) != tt.out.entryCount {
   119  				t.Errorf("imports entry count assertion failed, got %v, want %v", len(got), tt.out.entryCount)
   120  			}
   121  
   122  			impFunc := file.Imports[tt.out.entryIndex]
   123  			if !reflect.DeepEqual(impFunc, tt.out.entry) {
   124  				t.Errorf("import function entry assertion failed, got %v, want %v", impFunc, tt.out.entry)
   125  			}
   126  		})
   127  	}
   128  }
   129  
   130  func TestImpHash(t *testing.T) {
   131  	for _, tt := range []struct {
   132  		in  string
   133  		out string
   134  	}{
   135  		{getAbsoluteFilePath("test/putty.exe"), "2e3215acc61253e5fa73a840384e9720"},
   136  		{getAbsoluteFilePath("test/01008963d32f5cc17b64c31446386ee5b36a7eab6761df87a2989ba9394d8f3d"), "431cb9bbc479c64cb0d873043f4de547"},
   137  		{getAbsoluteFilePath("test/0103daa751660333b7ae5f098795df58f07e3031563e042d2eb415bffa71fe7a"), "8b58a51c1fff9c4a944265c1fe0fab74"},
   138  		{getAbsoluteFilePath("test/0585495341e0ffaae1734acb78708ff55cd3612d844672d37226ef63d12652d0"), "e4290fa6afc89d56616f34ebbd0b1f2c"},
   139  	} {
   140  		t.Run(tt.in, func(t *testing.T) {
   141  			file, err := New(tt.in, &Options{})
   142  			if err != nil {
   143  				t.Fatalf("New(%s) failed, reason: %v", tt.in, err)
   144  			}
   145  			if err := file.Parse(); err != nil {
   146  				t.Fatalf("Parse(%s) failed, reason: %v", tt.in, err)
   147  			}
   148  			impHash, err := file.ImpHash()
   149  			if err != nil {
   150  				t.Fatalf("ImpHash(%s) failed, reason: %v", tt.in, err)
   151  			}
   152  			if impHash != tt.out {
   153  				t.Errorf("ImpHash(%s) got %v, want %v", tt.in, impHash, tt.out)
   154  			}
   155  		})
   156  	}
   157  }