github.com/saferwall/pe@v1.5.2/resource_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 TestRsrcDir struct { 13 Level1ImgRsrcDir ImageResourceDirectory 14 Level2Index int 15 Level2ImgRsrcDir ImageResourceDirectory 16 Level3Index int 17 Level3ImgRsrcDir ImageResourceDirectory 18 Level3RsrcDirEntry ResourceDirectoryEntry 19 Level4Index int 20 Level4RsrcDirEntry ResourceDirectoryEntry 21 } 22 23 func TestParseResourceDirectory(t *testing.T) { 24 25 tests := []struct { 26 in string 27 out TestRsrcDir 28 }{ 29 { 30 getAbsoluteFilePath("test/putty.exe"), 31 TestRsrcDir{ 32 Level1ImgRsrcDir: ImageResourceDirectory{ 33 Characteristics: 0x0, 34 TimeDateStamp: 0x0, 35 MajorVersion: 0x0, 36 MinorVersion: 0x0, 37 NumberOfNamedEntries: 0x0, 38 NumberOfIDEntries: 0x6, 39 }, 40 Level2Index: 0x3, 41 Level2ImgRsrcDir: ImageResourceDirectory{ 42 Characteristics: 0x0, 43 TimeDateStamp: 0x0, 44 MajorVersion: 0x0, 45 MinorVersion: 0x0, 46 NumberOfNamedEntries: 0x0, 47 NumberOfIDEntries: 0x1, 48 }, 49 Level3Index: 0x0, 50 Level3ImgRsrcDir: ImageResourceDirectory{ 51 Characteristics: 0x0, 52 TimeDateStamp: 0x0, 53 MajorVersion: 0x0, 54 MinorVersion: 0x0, 55 NumberOfNamedEntries: 0x0, 56 NumberOfIDEntries: 0x1, 57 }, 58 Level4Index: 0x0, 59 Level4RsrcDirEntry: ResourceDirectoryEntry{ 60 Struct: ImageResourceDirectoryEntry{ 61 Name: 0x409, 62 OffsetToData: 0x460, 63 }, 64 Name: "", 65 ID: 0x409, 66 IsResourceDir: false, 67 Data: ResourceDataEntry{ 68 Lang: 0x9, 69 SubLang: 0x1, 70 Struct: ImageResourceDataEntry{ 71 OffsetToData: 0x124838, 72 Size: 0x324, 73 CodePage: 0x0, 74 Reserved: 0x0, 75 }, 76 }, 77 }, 78 }, 79 }, 80 } 81 82 for _, tt := range tests { 83 t.Run(tt.in, func(t *testing.T) { 84 ops := Options{Fast: true} 85 file, err := New(tt.in, &ops) 86 if err != nil { 87 t.Fatalf("New(%s) failed, reason: %v", tt.in, err) 88 } 89 90 err = file.Parse() 91 if err != nil { 92 t.Fatalf("Parse(%s) failed, reason: %v", tt.in, err) 93 } 94 95 var va, size uint32 96 if file.Is64 { 97 oh64 := file.NtHeader.OptionalHeader.(ImageOptionalHeader64) 98 dirEntry := oh64.DataDirectory[ImageDirectoryEntryResource] 99 va = dirEntry.VirtualAddress 100 size = dirEntry.Size 101 } else { 102 oh32 := file.NtHeader.OptionalHeader.(ImageOptionalHeader32) 103 dirEntry := oh32.DataDirectory[ImageDirectoryEntryResource] 104 va = dirEntry.VirtualAddress 105 size = dirEntry.Size 106 } 107 108 err = file.parseResourceDirectory(va, size) 109 if err != nil { 110 t.Fatalf("parseResourceDirectory(%s) failed, reason: %v", tt.in, err) 111 } 112 113 rsrc := file.Resources 114 if rsrc.Struct != tt.out.Level1ImgRsrcDir { 115 t.Fatalf("level 1 resource directory assertion failed, got %v, want %v", 116 rsrc.Struct, tt.out.Level1ImgRsrcDir) 117 } 118 119 rsrcDirLevel2 := rsrc.Entries[tt.out.Level2Index].Directory 120 if rsrcDirLevel2.Struct != tt.out.Level2ImgRsrcDir { 121 t.Fatalf("level 2 resource directory assertion failed, got %v, want %v", 122 rsrc.Struct, tt.out.Level2ImgRsrcDir) 123 } 124 125 rsrcDirLevel3 := rsrcDirLevel2.Entries[tt.out.Level3Index].Directory 126 if rsrcDirLevel3.Struct != tt.out.Level3ImgRsrcDir { 127 t.Fatalf("level 3 resource directory assertion failed, got %v, want %v", 128 rsrc.Struct, tt.out.Level3ImgRsrcDir) 129 } 130 131 rsrcDirEntry := rsrcDirLevel3.Entries[tt.out.Level4Index] 132 if !reflect.DeepEqual(rsrcDirEntry, tt.out.Level4RsrcDirEntry) { 133 t.Fatalf("level 3 resource directory entry assertion failed, got %v, want %v", 134 rsrc.Struct, tt.out.Level3ImgRsrcDir) 135 } 136 }) 137 } 138 } 139 140 func TestResourceTypeString(t *testing.T) { 141 142 tests := []struct { 143 in ResourceType 144 out string 145 }{ 146 { 147 RTCursor, 148 "Cursor", 149 }, 150 { 151 ResourceType(0xff), 152 "?", 153 }, 154 } 155 156 for _, tt := range tests { 157 t.Run(tt.out, func(t *testing.T) { 158 159 rsrcTypeString := tt.in.String() 160 if rsrcTypeString != tt.out { 161 t.Fatalf("resource type string conversion failed, got %v, want %v", 162 rsrcTypeString, tt.out) 163 } 164 }) 165 } 166 } 167 168 func TestResourceLangString(t *testing.T) { 169 170 tests := []struct { 171 in ResourceLang 172 out string 173 }{ 174 { 175 176 LangArabic, 177 "Arabic (ar)", 178 }, 179 { 180 ResourceLang(0xffff), 181 "?", 182 }, 183 } 184 185 for _, tt := range tests { 186 t.Run(tt.out, func(t *testing.T) { 187 188 rsrcLangString := tt.in.String() 189 if rsrcLangString != tt.out { 190 t.Fatalf("resource language string conversion failed, got %v, want %v", 191 rsrcLangString, tt.out) 192 } 193 }) 194 } 195 } 196 197 func TestResourceSubLangString(t *testing.T) { 198 199 tests := []struct { 200 in ResourceSubLang 201 out string 202 }{ 203 { 204 205 SubLangArabicMorocco, 206 "Arabic Morocco (ar-MA)", 207 }, 208 { 209 ResourceSubLang(0xffff), 210 "?", 211 }, 212 } 213 214 for _, tt := range tests { 215 t.Run(tt.out, func(t *testing.T) { 216 217 rsrcSubLangString := tt.in.String() 218 if rsrcSubLangString != tt.out { 219 t.Fatalf("resource sub-language string conversion failed, got %v, want %v", 220 rsrcSubLangString, tt.out) 221 } 222 }) 223 } 224 } 225 226 func TestPrettyResourceLang(t *testing.T) { 227 228 type resourceLang struct { 229 lang ResourceLang 230 subLang int 231 } 232 233 tests := []struct { 234 in resourceLang 235 out string 236 }{ 237 { 238 resourceLang{ 239 lang: LangEnglish, 240 subLang: 0x1, 241 }, 242 "English United States (en-US)", 243 }, 244 { 245 resourceLang{ 246 lang: ResourceLang(0xff), 247 subLang: 0x1, 248 }, 249 "?", 250 }, 251 } 252 253 for _, tt := range tests { 254 t.Run(tt.out, func(t *testing.T) { 255 256 prettyRsrcLang := PrettyResourceLang(tt.in.lang, tt.in.subLang) 257 if prettyRsrcLang != tt.out { 258 t.Fatalf("pretty resource language failed, got %v, want %v", 259 prettyRsrcLang, tt.out) 260 } 261 }) 262 } 263 }