github.com/saferwall/pe@v1.5.2/exports_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 "testing" 9 ) 10 11 type TestExport struct { 12 entryCount int 13 entryIndex int 14 name string 15 imgExpDir ImageExportDirectory 16 expFunc ExportFunction 17 } 18 19 func TestExportDirectory(t *testing.T) { 20 21 tests := []struct { 22 in string 23 out TestExport 24 }{ 25 { 26 getAbsoluteFilePath("test/kernel32.dll"), 27 TestExport{ 28 entryCount: 1633, 29 entryIndex: 0, 30 name: "KERNEL32.dll", 31 imgExpDir: ImageExportDirectory{ 32 TimeDateStamp: 0x38B369C4, 33 Name: 0x0009E1D2, 34 Base: 0x1, 35 NumberOfFunctions: 0x661, 36 NumberOfNames: 0x661, 37 AddressOfFunctions: 0x0009A208, 38 AddressOfNames: 0x0009BB8C, 39 AddressOfNameOrdinals: 0x0009D510, 40 }, 41 expFunc: ExportFunction{ 42 Ordinal: 0x1, 43 FunctionRVA: 0x0009E1F7, 44 NameRVA: 0x0009E1DF, 45 Name: "AcquireSRWLockExclusive", 46 Forwarder: "NTDLL.RtlAcquireSRWLockExclusive", 47 ForwarderRVA: 0x9CBF7, 48 }, 49 }, 50 }, 51 { 52 getAbsoluteFilePath("test/mfc140u.dll"), 53 TestExport{ 54 entryCount: 14103, 55 entryIndex: 0, 56 name: "KERNEL32.dll", 57 imgExpDir: ImageExportDirectory{ 58 TimeDateStamp: 0x5b8f7bca, 59 Name: 0x3e2e0c, 60 Base: 0x100, 61 NumberOfFunctions: 0x371d, 62 AddressOfFunctions: 0x3d5198, 63 }, 64 expFunc: ExportFunction{ 65 Ordinal: 0x100, 66 FunctionRVA: 0x275fa0, 67 }, 68 }, 69 }, 70 // { 71 // // TODO: ThreadSanitizer failed to allocate 0x000048000000 (1207959552) in Github CI 72 // getAbsoluteFilePath("test/0b1d3d3664915577ab9a32188d29bbf3542b86c7b9ce333e245496c3018819f1"), 73 // TestExport{ 74 // entryCount: 7728638, 75 // entryIndex: 0, 76 // name: "", 77 // imgExpDir: ImageExportDirectory{ 78 // Characteristics: 0xac0000, 79 // TimeDateStamp: 0xac0000, 80 // MinorVersion: 0xac, 81 // Name: 0xac0000, 82 // Base: 0xac0000, 83 // NumberOfFunctions: 0xac0000, 84 // NumberOfNames: 0xac0000, 85 // AddressOfFunctions: 0xac0000, 86 // AddressOfNames: 0xac0000, 87 // AddressOfNameOrdinals: 0xac0000, 88 // }, 89 // expFunc: ExportFunction{ 90 // Ordinal: 0xac0000, 91 // FunctionRVA: 0xac0000, 92 // NameRVA: 0xac0000, 93 // }, 94 // }, 95 // }, 96 } 97 98 for _, tt := range tests { 99 t.Run(tt.in, func(t *testing.T) { 100 ops := Options{Fast: true} 101 file, err := New(tt.in, &ops) 102 if err != nil { 103 t.Fatalf("New(%s) failed, reason: %v", tt.in, err) 104 } 105 106 err = file.Parse() 107 if err != nil { 108 t.Fatalf("Parse(%s) failed, reason: %v", tt.in, err) 109 } 110 111 var va, size uint32 112 113 if file.Is64 { 114 oh64 := file.NtHeader.OptionalHeader.(ImageOptionalHeader64) 115 dirEntry := oh64.DataDirectory[ImageDirectoryEntryExport] 116 va = dirEntry.VirtualAddress 117 size = dirEntry.Size 118 } else { 119 oh32 := file.NtHeader.OptionalHeader.(ImageOptionalHeader32) 120 dirEntry := oh32.DataDirectory[ImageDirectoryEntryExport] 121 va = dirEntry.VirtualAddress 122 size = dirEntry.Size 123 } 124 125 err = file.parseExportDirectory(va, size) 126 if err != nil { 127 t.Fatalf("parseExportDirectory(%s) failed, reason: %v", tt.in, err) 128 } 129 130 export := file.Export 131 if len(export.Functions) != tt.out.entryCount { 132 t.Fatalf("export functions count assertion failed, got %v, want %v", 133 len(export.Functions), tt.out.entryCount) 134 } 135 136 imgExpDir := export.Struct 137 if imgExpDir != tt.out.imgExpDir { 138 t.Fatalf("image export directory assertion failed, got %v, want %v", 139 imgExpDir, tt.out.imgExpDir) 140 } 141 142 if len(export.Functions) > 0 { 143 expFunc := export.Functions[tt.out.entryIndex] 144 if expFunc != tt.out.expFunc { 145 t.Fatalf("export entry assertion failed, got %v, want %v", expFunc, tt.out.expFunc) 146 } 147 } 148 }) 149 } 150 }