github.com/saferwall/pe@v1.5.2/reloc_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 func TestParseRelocDirectoryData(t *testing.T) { 12 13 type TestRelocData struct { 14 imgBaseRelocation ImageBaseRelocation 15 relocEntriesCount int 16 relocDataIndex int 17 } 18 19 tests := []struct { 20 in string 21 out TestRelocData 22 }{ 23 { 24 getAbsoluteFilePath("test/putty.exe"), 25 TestRelocData{ 26 imgBaseRelocation: ImageBaseRelocation{ 27 VirtualAddress: 0xd8000, SizeOfBlock: 0xc}, 28 relocEntriesCount: 18, 29 relocDataIndex: 17, 30 }, 31 }, 32 } 33 34 for _, tt := range tests { 35 t.Run(tt.in, func(t *testing.T) { 36 ops := Options{Fast: true} 37 file, err := New(tt.in, &ops) 38 if err != nil { 39 t.Fatalf("New(%s) failed, reason: %v", tt.in, err) 40 } 41 42 err = file.Parse() 43 if err != nil { 44 t.Fatalf("Parse(%s) failed, reason: %v", tt.in, err) 45 } 46 47 var va, size uint32 48 switch file.Is64 { 49 case true: 50 oh64 := file.NtHeader.OptionalHeader.(ImageOptionalHeader64) 51 dirEntry := oh64.DataDirectory[ImageDirectoryEntryBaseReloc] 52 va = dirEntry.VirtualAddress 53 size = dirEntry.Size 54 case false: 55 oh32 := file.NtHeader.OptionalHeader.(ImageOptionalHeader32) 56 dirEntry := oh32.DataDirectory[ImageDirectoryEntryBaseReloc] 57 va = dirEntry.VirtualAddress 58 size = dirEntry.Size 59 } 60 61 err = file.parseRelocDirectory(va, size) 62 if err != nil { 63 t.Fatalf("parseRelocDirectory(%s) failed, reason: %v", tt.in, err) 64 } 65 relocs := file.Relocations 66 if len(relocs) != tt.out.relocEntriesCount { 67 t.Errorf("relocations entries count assertion failed, got %v, want %v", 68 len(relocs), tt.out.relocEntriesCount) 69 } 70 71 imgBaseRelocation := relocs[tt.out.relocDataIndex].Data 72 if imgBaseRelocation != tt.out.imgBaseRelocation { 73 t.Errorf("reloc data assertion failed, got %v, want %v", 74 imgBaseRelocation, tt.out.imgBaseRelocation) 75 } 76 }) 77 } 78 } 79 80 func TestParseRelocDirectoryEntry(t *testing.T) { 81 82 type TestRelocEntry struct { 83 imgBaseRelocationEntry ImageBaseRelocationEntry 84 relocEntriesCount int 85 relocDataIndex int 86 relocEntryIndex int 87 relocTypeMeaning string 88 } 89 90 tests := []struct { 91 in string 92 out TestRelocEntry 93 }{ 94 { 95 getAbsoluteFilePath("test/putty.exe"), 96 TestRelocEntry{ 97 imgBaseRelocationEntry: ImageBaseRelocationEntry{ 98 Data: 0xab00, 99 Offset: 0xb00, 100 Type: 0xa, 101 }, 102 relocDataIndex: 0x1, 103 relocEntriesCount: 154, 104 relocEntryIndex: 17, 105 relocTypeMeaning: "DIR64", 106 }, 107 }, 108 { 109 getAbsoluteFilePath("test/arp.dll"), 110 TestRelocEntry{ 111 imgBaseRelocationEntry: ImageBaseRelocationEntry{ 112 Data: 0x8004, 113 Offset: 0x4, 114 Type: 0x8, 115 }, 116 relocDataIndex: 3, 117 relocEntriesCount: 204, 118 relocEntryIndex: 1, 119 relocTypeMeaning: "RISC-V Low12s", 120 }, 121 }, 122 } 123 124 for _, tt := range tests { 125 t.Run(tt.in, func(t *testing.T) { 126 ops := Options{Fast: true} 127 file, err := New(tt.in, &ops) 128 if err != nil { 129 t.Fatalf("New(%s) failed, reason: %v", tt.in, err) 130 } 131 132 err = file.Parse() 133 if err != nil { 134 t.Fatalf("Parse(%s) failed, reason: %v", tt.in, err) 135 } 136 137 var va, size uint32 138 switch file.Is64 { 139 case true: 140 oh64 := file.NtHeader.OptionalHeader.(ImageOptionalHeader64) 141 dirEntry := oh64.DataDirectory[ImageDirectoryEntryBaseReloc] 142 va = dirEntry.VirtualAddress 143 size = dirEntry.Size 144 case false: 145 oh32 := file.NtHeader.OptionalHeader.(ImageOptionalHeader32) 146 dirEntry := oh32.DataDirectory[ImageDirectoryEntryBaseReloc] 147 va = dirEntry.VirtualAddress 148 size = dirEntry.Size 149 } 150 151 err = file.parseRelocDirectory(va, size) 152 if err != nil { 153 t.Fatalf("parseRelocDirectory(%s) failed, reason: %v", tt.in, err) 154 } 155 156 reloc := file.Relocations[tt.out.relocDataIndex] 157 if len(reloc.Entries) != tt.out.relocEntriesCount { 158 t.Errorf("relocations entries count assertion failed, got %v, want %v", 159 len(reloc.Entries), tt.out.relocEntriesCount) 160 } 161 162 relocEntry := reloc.Entries[tt.out.relocEntryIndex] 163 if relocEntry != tt.out.imgBaseRelocationEntry { 164 t.Errorf("reloc image base relocation entry assertion failed, got %v, want %v", 165 relocEntry, tt.out.imgBaseRelocationEntry) 166 } 167 168 relocType := relocEntry.Type.String(file) 169 if relocType != tt.out.relocTypeMeaning { 170 t.Errorf("pretty reloc type assertion failed, got %v, want %v", relocType, 171 tt.out.relocTypeMeaning) 172 } 173 174 }) 175 } 176 }